summaryrefslogtreecommitdiffstats
path: root/src/ppe
diff options
context:
space:
mode:
authormbroyles <mbroyles@us.ibm.com>2015-08-03 14:02:47 -0500
committerWilliam A. Bryan <wilbryan@us.ibm.com>2015-08-03 15:24:17 -0500
commitadade8c8ef30ed519322674c762d95663009c5d4 (patch)
treeb1c773b88ec7c896c0185482c869d841b5322d76 /src/ppe
parente304743c292e7161db5e2412d18a28c1b6f37a75 (diff)
downloadtalos-occ-adade8c8ef30ed519322674c762d95663009c5d4.tar.gz
talos-occ-adade8c8ef30ed519322674c762d95663009c5d4.zip
new ppe dir
Change-Id: I43d54c18ac4f3bce90a4f26510e443a55c446bba Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/19509 Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Tested-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/ppe')
-rw-r--r--src/ppe/LAYOUT16
-rw-r--r--src/ppe/hwp/cache/Makefile54
-rw-r--r--src/ppe/hwp/cache/cachehcdfiles.mk65
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache.H54
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_arrayinit.C170
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_arrayinit.H62
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.C140
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.C313
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.H62
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.C282
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.C110
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_initf.C99
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_initf.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.C93
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_poweron.C84
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_poweron.H66
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.C171
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_repair_initf.C87
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_repair_initf.H64
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_runinit.C73
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_runinit.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_scomcust.C93
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_scomcust.H62
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_scominit.C130
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_scominit.H63
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_startclocks.C275
-rw-r--r--src/ppe/hwp/cache/p9_hcd_cache_startclocks.H63
-rw-r--r--src/ppe/hwp/core/Makefile54
-rw-r--r--src/ppe/hwp/core/corehcdfiles.mk65
-rw-r--r--src/ppe/hwp/core/p9_hcd_core.H54
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_arrayinit.C156
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_arrayinit.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_chiplet_init.C136
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_chiplet_init.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_chiplet_reset.C196
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_chiplet_reset.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.C112
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.H62
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_initf.C95
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_initf.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.C94
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.H64
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_pcb_arb.C83
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_pcb_arb.H62
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_poweron.C84
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_poweron.H67
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.C165
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_repair_initf.C89
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_repair_initf.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_runinit.C75
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_runinit.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_scomcust.C83
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_scomcust.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_scominit.C160
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_scominit.H63
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_startclocks.C97
-rw-r--r--src/ppe/hwp/core/p9_hcd_core_startclocks.H62
-rw-r--r--src/ppe/hwp/lib/Makefile54
-rw-r--r--src/ppe/hwp/lib/libcommonfiles.mk53
-rw-r--r--src/ppe/hwp/lib/p9_common_poweronoff.C71
-rw-r--r--src/ppe/hwp/lib/p9_common_poweronoff.H68
-rw-r--r--src/ppe/hwp/lib/p9_common_pro_epi_log.C70
-rw-r--r--src/ppe/hwp/lib/p9_common_pro_epi_log.H68
-rw-r--r--src/ppe/hwp/nest/.empty0
-rw-r--r--src/ppe/hwp/perv/.empty0
-rw-r--r--src/ppe/hwp/perv/Makefile54
-rw-r--r--src/ppe/hwp/perv/p9_sbe_attr_setup.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_attr_setup.H61
-rw-r--r--src/ppe/hwp/perv/p9_sbe_check_master.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_check_master.H61
-rw-r--r--src/ppe/hwp/perv/p9_sbe_enable_seeprom.C53
-rw-r--r--src/ppe/hwp/perv/p9_sbe_enable_seeprom.H67
-rw-r--r--src/ppe/hwp/perv/p9_sbe_lpc_init.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_lpc_init.H65
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_arrayinit.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_arrayinit.H62
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.H61
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.H61
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.H61
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_initf.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_initf.H61
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_startclocks.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_nest_startclocks.H68
-rw-r--r--src/ppe/hwp/perv/p9_sbe_npll_initf.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_npll_initf.H64
-rw-r--r--src/ppe/hwp/perv/p9_sbe_npll_setup.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_npll_setup.H73
-rw-r--r--src/ppe/hwp/perv/p9_sbe_select_ex.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_select_ex.H66
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_arrayinit.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_arrayinit.H63
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.H65
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.H62
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.H68
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.H62
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.H62
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_initf.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_initf.H65
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_ld_image.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_ld_image.H65
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_switch_gears.C52
-rw-r--r--src/ppe/hwp/perv/p9_sbe_tp_switch_gears.H61
-rw-r--r--src/ppe/hwp/perv/p9_select_boot_master.C52
-rw-r--r--src/ppe/hwp/perv/p9_select_boot_master.H61
-rw-r--r--src/ppe/hwp/perv/p9_select_clock_mux.C52
-rw-r--r--src/ppe/hwp/perv/p9_select_clock_mux.H62
-rw-r--r--src/ppe/hwp/perv/p9_set_fsi_gp_shadow.C52
-rw-r--r--src/ppe/hwp/perv/p9_set_fsi_gp_shadow.H61
-rw-r--r--src/ppe/hwp/perv/p9_setup_clock_term.C52
-rw-r--r--src/ppe/hwp/perv/p9_setup_clock_term.H62
-rw-r--r--src/ppe/hwp/perv/p9_setup_sbe_config.C52
-rw-r--r--src/ppe/hwp/perv/p9_setup_sbe_config.H61
-rw-r--r--src/ppe/hwp/perv/p9_start_cbs.C52
-rw-r--r--src/ppe/hwp/perv/p9_start_cbs.H65
-rw-r--r--src/ppe/hwp/perv/pervasive_attributes.xml149
-rw-r--r--src/ppe/hwp/perv/pervfiles.mk74
-rw-r--r--src/ppe/hwp/utils/.empty0
-rwxr-xr-xsrc/ppe/hwpf/fapi/.empty0
-rwxr-xr-xsrc/ppe/hwpf/fapi/docs/Doxyfile2355
-rwxr-xr-xsrc/ppe/hwpf/fapi/docs/README6
-rwxr-xr-xsrc/ppe/hwpf/fapi/docs/topics/DEPRECATED.md81
-rwxr-xr-xsrc/ppe/hwpf/fapi/docs/topics/Examples.md246
-rwxr-xr-xsrc/ppe/hwpf/fapi/docs/topics/Ffdc.md149
-rwxr-xr-xsrc/ppe/hwpf/fapi/docs/topics/README.md166
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/buffer.H423
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/buffer_base.H331
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/buffer_parameters.H65
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/buffer_traits.H232
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/collect_reg_ffdc.H80
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/error_info.H854
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/error_scope.H104
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/ffdc.H193
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/hw_access.H720
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/plat_trace.H64
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/return_code.H180
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/target.H337
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/target_types.H105
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/utils.H59
-rwxr-xr-xsrc/ppe/hwpf/fapi/include/variable_buffer.H663
-rwxr-xr-xsrc/ppe/hwpf/fapi/src/error_info.C412
-rwxr-xr-xsrc/ppe/hwpf/fapi/src/ffdc.C59
-rwxr-xr-xsrc/ppe/hwpf/fapi/src/plat_utils.C119
-rwxr-xr-xsrc/ppe/hwpf/fapi/tools/parseErrorInfo.pl1479
-rwxr-xr-xsrc/ppe/hwpf/fapi/xml/buffer_errors.xml40
-rwxr-xr-xsrc/ppe/hwpf/plat/.empty0
-rw-r--r--src/ppe/hwpf/plat/include/array.H174
-rw-r--r--src/ppe/hwpf/plat/include/buffer.H423
-rw-r--r--src/ppe/hwpf/plat/include/buffer_parameters.H65
-rw-r--r--src/ppe/hwpf/plat/include/buffer_traits.H238
-rw-r--r--src/ppe/hwpf/plat/include/error_scope.H147
-rw-r--r--src/ppe/hwpf/plat/include/fapi2.H76
-rw-r--r--src/ppe/hwpf/plat/include/fapi2Structs.H133
-rw-r--r--src/ppe/hwpf/plat/include/hw_access.H606
-rw-r--r--src/ppe/hwpf/plat/include/plat_hw_access.H102
-rw-r--r--src/ppe/hwpf/plat/include/plat_includes.H40
-rw-r--r--src/ppe/hwpf/plat/include/plat_target.H43
-rw-r--r--src/ppe/hwpf/plat/include/plat_target_definitions.H112
-rw-r--r--src/ppe/hwpf/plat/include/plat_target_parms.H62
-rw-r--r--src/ppe/hwpf/plat/include/plat_trace.H70
-rw-r--r--src/ppe/hwpf/plat/include/return_code.H187
-rw-r--r--src/ppe/hwpf/plat/include/target.H553
-rw-r--r--src/ppe/hwpf/plat/include/target_types.H132
-rw-r--r--src/ppe/hwpf/plat/include/utils.H56
-rw-r--r--src/ppe/hwpf/plat/include/variable_buffer.H670
-rw-r--r--src/ppe/hwpf/plat/src/Makefile45
-rw-r--r--src/ppe/hwpf/plat/src/array.C145
-rw-r--r--src/ppe/hwpf/plat/src/error_info.C412
-rw-r--r--src/ppe/hwpf/plat/src/fapi2ppefiles.mk51
-rw-r--r--src/ppe/hwpf/plat/src/ffdc.C59
-rw-r--r--src/ppe/hwpf/plat/src/plat_utils.C137
-rw-r--r--src/ppe/hwpf/plat/src/target.C35
-rwxr-xr-xsrc/ppe/hwpf/plat/target_map49
-rw-r--r--src/ppe/import/.empty0
-rwxr-xr-xsrc/ppe/include/ppe_compiler.mk83
-rw-r--r--src/ppe/include/proc_hcd_common.H44
-rw-r--r--src/ppe/lib/.empty0
-rw-r--r--src/ppe/ops/.empty0
-rw-r--r--src/ppe/pk/.empty0
-rw-r--r--src/ppe/pk/README8
-rw-r--r--src/ppe/pk/gpe/Makefile74
-rw-r--r--src/ppe/pk/gpe/gpe.h59
-rw-r--r--src/ppe/pk/gpe/gpe_common.h89
-rw-r--r--src/ppe/pk/gpe/gpe_init.c146
-rw-r--r--src/ppe/pk/gpe/gpe_irq.h271
-rw-r--r--src/ppe/pk/gpe/gpe_irq_init.c130
-rw-r--r--src/ppe/pk/gpe/gpe_scom_handler.S122
-rw-r--r--src/ppe/pk/gpe/gpe_timebase.h64
-rw-r--r--src/ppe/pk/gpe/pk_port.h40
-rw-r--r--src/ppe/pk/gpe/pkgpefiles.mk57
-rw-r--r--src/ppe/pk/kernel/.empty0
-rw-r--r--src/ppe/pk/kernel/Makefile50
-rw-r--r--src/ppe/pk/kernel/pk.h149
-rw-r--r--src/ppe/pk/kernel/pk_api.h1026
-rw-r--r--src/ppe/pk/kernel/pk_bh_core.c53
-rw-r--r--src/ppe/pk/kernel/pk_core.c103
-rw-r--r--src/ppe/pk/kernel/pk_debug_ptrs.c77
-rw-r--r--src/ppe/pk/kernel/pk_debug_ptrs.h63
-rw-r--r--src/ppe/pk/kernel/pk_init.c220
-rw-r--r--src/ppe/pk/kernel/pk_kernel.h270
-rw-r--r--src/ppe/pk/kernel/pk_macros.h134
-rw-r--r--src/ppe/pk/kernel/pk_semaphore_core.c342
-rw-r--r--src/ppe/pk/kernel/pk_semaphore_init.c106
-rw-r--r--src/ppe/pk/kernel/pk_stack_init.c109
-rw-r--r--src/ppe/pk/kernel/pk_thread.h80
-rw-r--r--src/ppe/pk/kernel/pk_thread_core.c597
-rw-r--r--src/ppe/pk/kernel/pk_thread_init.c158
-rw-r--r--src/ppe/pk/kernel/pk_thread_util.c315
-rw-r--r--src/ppe/pk/kernel/pk_timer_core.c425
-rw-r--r--src/ppe/pk/kernel/pk_timer_init.c86
-rw-r--r--src/ppe/pk/kernel/pkkernelfiles.mk56
-rw-r--r--src/ppe/pk/ppe/Makefile74
-rw-r--r--src/ppe/pk/ppe/pk_port.h41
-rw-r--r--src/ppe/pk/ppe/pkppefiles.mk57
-rw-r--r--src/ppe/pk/ppe/ppe.h46
-rw-r--r--src/ppe/pk/ppe/ppe_common.h73
-rw-r--r--src/ppe/pk/ppe/ppe_init.c49
-rw-r--r--src/ppe/pk/ppe/ppe_timebase.h52
-rw-r--r--src/ppe/pk/ppe42/.empty0
-rw-r--r--src/ppe/pk/ppe42/Makefile50
-rw-r--r--src/ppe/pk/ppe42/div64.S272
-rw-r--r--src/ppe/pk/ppe42/pk_port_types.h65
-rw-r--r--src/ppe/pk/ppe42/pkppe42files.mk70
-rw-r--r--src/ppe/pk/ppe42/ppe42.h853
-rw-r--r--src/ppe/pk/ppe42/ppe42_asm.h632
-rw-r--r--src/ppe/pk/ppe42/ppe42_boot.S193
-rw-r--r--src/ppe/pk/ppe42/ppe42_cache.h126
-rw-r--r--src/ppe/pk/ppe42/ppe42_context.h225
-rw-r--r--src/ppe/pk/ppe42/ppe42_core.c150
-rw-r--r--src/ppe/pk/ppe42/ppe42_exceptions.S521
-rw-r--r--src/ppe/pk/ppe42/ppe42_gcc.c329
-rw-r--r--src/ppe/pk/ppe42/ppe42_gcc.h96
-rw-r--r--src/ppe/pk/ppe42/ppe42_init.c101
-rw-r--r--src/ppe/pk/ppe42/ppe42_irq.h242
-rw-r--r--src/ppe/pk/ppe42/ppe42_irq_core.c71
-rw-r--r--src/ppe/pk/ppe42/ppe42_msr.h112
-rwxr-xr-xsrc/ppe/pk/ppe42/ppe42_scom.c101
-rwxr-xr-xsrc/ppe/pk/ppe42/ppe42_scom.h160
-rw-r--r--src/ppe/pk/ppe42/ppe42_spr.h197
-rw-r--r--src/ppe/pk/ppe42/ppe42_thread_init.S134
-rw-r--r--src/ppe/pk/ppe42/ppe42_timebase.S140
-rw-r--r--src/ppe/pk/std/Makefile74
-rw-r--r--src/ppe/pk/std/pk_port.h41
-rw-r--r--src/ppe/pk/std/pkstdfiles.mk57
-rw-r--r--src/ppe/pk/std/std.h44
-rw-r--r--src/ppe/pk/std/std_common.h78
-rw-r--r--src/ppe/pk/std/std_init.c74
-rw-r--r--src/ppe/pk/std/std_irq.h110
-rw-r--r--src/ppe/pk/std/std_irq_config.h165
-rw-r--r--src/ppe/pk/std/std_irq_init.c129
-rw-r--r--src/ppe/pk/std/std_register_addresses.h73
-rw-r--r--src/ppe/pk/std/std_timebase.h66
-rw-r--r--src/ppe/pk/trace/Makefile50
-rw-r--r--src/ppe/pk/trace/pk_trace.h303
-rw-r--r--src/ppe/pk/trace/pk_trace_big.c116
-rw-r--r--src/ppe/pk/trace/pk_trace_binary.c115
-rw-r--r--src/ppe/pk/trace/pk_trace_core.c140
-rw-r--r--src/ppe/pk/trace/pktracefiles.mk63
-rw-r--r--src/ppe/sbe/.empty0
-rw-r--r--src/ppe/sbe/image/Makefile222
-rw-r--r--src/ppe/sbe/image/base_main.C91
-rw-r--r--src/ppe/sbe/image/base_ppe_demo.c44
-rw-r--r--src/ppe/sbe/image/base_ppe_demo.h43
-rw-r--r--src/ppe/sbe/image/base_ppe_header.S220
-rw-r--r--src/ppe/sbe/image/fapi_sbe_common.H71
-rw-r--r--src/ppe/sbe/image/img_defs.mk336
-rw-r--r--src/ppe/sbe/image/link.cmd115
-rw-r--r--src/ppe/sbe/image/p9_sbe.H53
-rw-r--r--src/ppe/sbe/image/proc_sbe_fixed.H189
-rw-r--r--src/ppe/sbe/image/sbe_common.H601
-rw-r--r--src/ppe/sbe/image/sbe_link.H77
-rw-r--r--src/ppe/sbe/image/sbe_xip_image.h1786
-rw-r--r--src/ppe/sbe/image/topfiles.mk35
-rw-r--r--src/ppe/sbe/sample/Makefile100
-rw-r--r--src/ppe/sbe/sample/img_defs.mk265
-rw-r--r--src/ppe/sbe/sample/link.cmd92
-rw-r--r--src/ppe/sbe/sample/pk_scom.c236
-rw-r--r--src/ppe/sbe/sample/pk_scom.h67
-rw-r--r--src/ppe/sbe/sample/pk_trace_wrap.c33
-rw-r--r--src/ppe/sbe/sample/pk_trace_wrap.h31
-rw-r--r--src/ppe/sbe/sample/sample_main.C123
-rw-r--r--src/ppe/sbe/sample/topfiles.mk30
-rw-r--r--src/ppe/tools/PowerPCtoPPE/Makefile47
-rwxr-xr-xsrc/ppe/tools/PowerPCtoPPE/p2p-test-gen.py171
-rw-r--r--src/ppe/tools/PowerPCtoPPE/p2pfiles.mk38
-rwxr-xr-xsrc/ppe/tools/PowerPCtoPPE/ppc-ppe-pcp.py1007
-rw-r--r--src/ppe/tools/PowerPCtoPPE/ppe42_divw.S232
-rw-r--r--src/ppe/tools/PowerPCtoPPE/ppe42_divwu.S208
-rw-r--r--src/ppe/tools/PowerPCtoPPE/ppe42_mulhw.S217
-rw-r--r--src/ppe/tools/PowerPCtoPPE/ppe42_mulhwu.S226
-rw-r--r--src/ppe/tools/PowerPCtoPPE/ppe42_mullw.S198
-rw-r--r--src/ppe/tools/ppetracepp/Makefile36
-rwxr-xr-xsrc/ppe/tools/ppetracepp/fsp-tracebin0 -> 52248 bytes
-rwxr-xr-xsrc/ppe/tools/ppetracepp/jhash.h167
-rwxr-xr-xsrc/ppe/tools/ppetracepp/ppe2fspbin0 -> 19306 bytes
-rwxr-xr-xsrc/ppe/tools/ppetracepp/ppe2fsp.c534
-rw-r--r--src/ppe/tools/ppetracepp/ppe2fsp.h34
-rw-r--r--src/ppe/tools/ppetracepp/ppe2fsp_cmd.c139
-rwxr-xr-xsrc/ppe/tools/ppetracepp/ppetraceppbin0 -> 321115 bytes
-rwxr-xr-xsrc/ppe/tools/ppetracepp/ppetracepp.C946
-rwxr-xr-xsrc/ppe/tools/ppetracepp/trac_interface.h370
-rwxr-xr-xsrc/ppe/tools/ppetracepp/tracehash.pl897
315 files changed, 46975 insertions, 0 deletions
diff --git a/src/ppe/LAYOUT b/src/ppe/LAYOUT
new file mode 100644
index 0000000..38abdf6
--- /dev/null
+++ b/src/ppe/LAYOUT
@@ -0,0 +1,16 @@
+================================================================================
+-----------------------------PPE DIRECTORY STRUCTURE----------------------------
+================================================================================
+
+sbe/ - FAPI-Lite SBE code to IPL the chip without the core and cache routine.
+ - May contain some PPE assembler files/functions.
+
+corecache/ - Core routines will also land in the CME image while cache routine will also land in the STOP GPE image.
+ - FAPI-Lite Hcode that initializes the core and cache chiplets.
+pgpe/ - PState GPE code
+ops/ - SBE chipOps -- may be delivered from the FW team but may have some early engineering forms
+lib/ - FAPI-Lite Common PPE code routines (startclocks, arrayinit, etc)
+pk/ - PPE Kernel
+ kernel/ - Base kernel
+ ppe42/ - Emulation function that don't exist in the PPE42 (div64, ppe_scom)
+import/ - place for information about what needs to be mirrored into ppe build. \ No newline at end of file
diff --git a/src/ppe/hwp/cache/Makefile b/src/ppe/hwp/cache/Makefile
new file mode 100644
index 0000000..115a69a
--- /dev/null
+++ b/src/ppe/hwp/cache/Makefile
@@ -0,0 +1,54 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/cache/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# This Makefile compiles all of the cache hardware procedure code. See the
+# "cachehcdfiles.mk" file in this directory.
+
+#all generated files from this makefile will end up in obj/cache
+export SUB_OBJDIR = /cache
+
+include img_defs.mk
+include cachehcdfiles.mk
+
+
+OBJS := $(addprefix $(OBJDIR)/, $(CACHE_OBJECTS))
+
+libcache.a: cache
+ $(AR) crs $(OBJDIR)/libcache.a $(OBJDIR)/*.o
+
+.PHONY: clean cache
+cache: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/hwp/cache/cachehcdfiles.mk b/src/ppe/hwp/cache/cachehcdfiles.mk
new file mode 100644
index 0000000..28e36e7
--- /dev/null
+++ b/src/ppe/hwp/cache/cachehcdfiles.mk
@@ -0,0 +1,65 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/cache/cachehcdfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file cachehcdfiles.mk
+#
+# @brief mk for including cache hcode object files
+#
+# @page ChangeLogs Change Logs
+# @section cachehcdfiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+CACHE-CPP-SOURCES += p9_hcd_cache_arrayinit.C
+CACHE-CPP-SOURCES += p9_hcd_cache_chiplet_init.C
+CACHE-CPP-SOURCES += p9_hcd_cache_chiplet_reset.C
+CACHE-CPP-SOURCES += p9_hcd_cache_dpll_setup.C
+CACHE-CPP-SOURCES += p9_hcd_cache_gptr_time_initf.C
+CACHE-CPP-SOURCES += p9_hcd_cache_initf.C
+CACHE-CPP-SOURCES += p9_hcd_cache_occ_runtime_scom.C
+CACHE-CPP-SOURCES += p9_hcd_cache_poweron.C
+CACHE-CPP-SOURCES += p9_hcd_cache_ras_runtime_scom.C
+CACHE-CPP-SOURCES += p9_hcd_cache_repair_initf.C
+CACHE-CPP-SOURCES += p9_hcd_cache_runinit.C
+CACHE-CPP-SOURCES += p9_hcd_cache_scomcust.C
+CACHE-CPP-SOURCES += p9_hcd_cache_scominit.C
+CACHE-CPP-SOURCES += p9_hcd_cache_startclocks.C
+
+CACHE-C-SOURCES +=
+CACHE-S-SOURCES +=
+
+CACHE_OBJECTS += $(CACHE-CPP-SOURCES:.C=.o)
+CACHE_OBJECTS += $(CACHE-C-SOURCES:.c=.o)
+CACHE_OBJECTS += $(CACHE-S-SOURCES:.S=.o)
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache.H b/src/ppe/hwp/cache/p9_hcd_cache.H
new file mode 100644
index 0000000..6550690
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache.H
@@ -0,0 +1,54 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache.H
+/// @brief Cache Chiplet Procedure Includes
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_H__
+#define __P9_HCD_CACHE_H__
+
+#include <p9_hcd_cache_arrayinit.H>
+#include <p9_hcd_cache_chiplet_init.H>
+#include <p9_hcd_cache_chiplet_reset.H>
+#include <p9_hcd_cache_dpll_setup.H>
+#include <p9_hcd_cache_gptr_time_initf.H>
+#include <p9_hcd_cache_initf.H>
+#include <p9_hcd_cache_occ_runtime_scom.H>
+#include <p9_hcd_cache_poweron.H>
+#include <p9_hcd_cache_ras_runtime_scom.H>
+#include <p9_hcd_cache_repair_initf.H>
+#include <p9_hcd_cache_runinit.H>
+#include <p9_hcd_cache_scomcust.H>
+#include <p9_hcd_cache_scominit.H>
+#include <p9_hcd_cache_startclocks.H>
+
+#endif // __P9_HCD_CACHE_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_arrayinit.C b/src/ppe/hwp/cache/p9_hcd_cache_arrayinit.C
new file mode 100644
index 0000000..465b413
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_arrayinit.C
@@ -0,0 +1,170 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_arrayinit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_arrayinit.C
+/// @brief EX Initialize arrays
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Use ABIST engine to zero out all arrays
+/// Upon completion, scan0 flush all rings
+/// except Vital, Repair, GPTR, TIME and DPLL
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_arrayinit.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Procedure: Initialize Cache Arrays
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_arrayinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+ uint32_t scan;
+ uint32_t loop;
+
+ // Procedure Prereq : P0 is pointing to the targeted EX chiplet
+ // submodules:
+ // seeprom_array_init_module
+ // ex_scan0
+
+ FAPI_INF("<p9_hcd_cache_arrayinit> : \
+ *** Array Init and Scan0 Cleanup for EX Chiplets ***");
+
+ // SBE Address Base Register Setups
+ // Setup PRV_BASE_ADDR1; points to selected EX chiplet
+ // - mr P1, P0
+ FAPI_INF("<p9_hcd_cache_arrayinit> : \
+ Copy selected EX info from P0 to P1");
+
+ // Step 1: Array Init for selected EX chiplet
+ // ARRAY INIT module -> see p9_sbe_tp_array_init.S
+ //
+ // At entry:
+ //
+ // P1 : The chiplet ID/Multicast Group
+ // D1 : Clock Regions for Array Init
+ //
+ // At exit:
+ //
+ // P0, D0, D1, CTR : destroyed
+ // P1, A0, A1 : maintained
+ //
+ FAPI_INF("<p9_hcd_cache_arrayinit> : \
+ Calling Array Init Subroutine");
+
+ // >>> IPL/Winkle
+ // \bug Need to exclude DPLL ring for IPL
+ // li D1, SCAN_ALLREGIONEXVITAL
+ // = li D1, SCAN_CLK_ALLEXDPLL
+ scan = SCAN_CLK_ALLEXDPLL;
+
+ // Execute the array init
+ // = bsr seeprom_array_init_module
+ seeprom_array_init_module(scan);
+
+ // Restore P0 with selected EX chiplet info
+ // - mr P0, P1
+ FAPI_INF("<p9_hcd_cache_arrayinit> : \
+ Copy selected EX info back from P1 to P0");
+
+ // Step 2: Scan0 for selected EX chiplet except PRV, GPTR, TIME and DPLL
+ FAPI_INF("<p9_hcd_cache_arrayinit> : \
+ Calling Scan0 Subroutine");
+
+ // taken from p9_sbe_ex_chiplet_init
+
+ // >>> IPL/Winkle scan flush - all except vital
+
+ // Hook to bypass in Sim
+ // - hooki 0, 0xFF02
+ // - ifslwcntlbitset P9_SLW_SKIP_FLUSH,1f
+
+ FAPI_DBG("EX Init: Scan0 Module executed: \
+ Scan all except vital, DPL, GPTR, and TIME scan chains");
+
+ // Each scan0 will rotate the ring 8191 latches (2**13 - 1) and the
+ // the longest ring is defined by P9_SCAN0_FUNC_REPEAT. When the design
+ // ALWAYS has all stumps less than 8191, the repeat (eg .rept) can be
+ // removed.
+ // Implementation note: this is not done in a loop (or included in the
+ // ex_scan0_module itself) as the D0 and D1 registers are used in
+ // ex_scan0_module and there is no convenient place to temporaily store
+ // the 2-64b values values. Argueably, PIBMEM could be used for this
+ // but was not utilized.
+
+ // \bug remove DPLL ring
+ // ex_scan0 SCAN_ALL_BUT_VITALDPLLGPTRTIME, SCAN_CLK_ALL
+ // = .rept P9_SCAN0_FUNC_REPEAT
+ // = ex_scan0 SCAN_ALL_BUT_VITALDPLLGPTRTIME, SCAN_CLK_ALLEXDPLL
+ // = .endr
+ for(loop=0;loop<P9_SCAN0_FUNC_REPEAT;loop++)
+ {
+ ex_scan0(SCAN_ALL_BUT_VITALDPLLGPTRTIME,SCAN_CLK_ALLEXDPLL);
+ }
+ // - 1:
+
+ FAPI_INF("<p9_hcd_cache_arrayinit> : \
+ *** End of Procedure ***");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_arrayinit.H b/src/ppe/hwp/cache/p9_hcd_cache_arrayinit.H
new file mode 100644
index 0000000..530c4db
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_arrayinit.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_arrayinit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_arrayinit.H
+/// @brief EX Initialize arrays
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_ARRAYINIT_H__
+#define __P9_HCD_CACHE_ARRAYINIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_arrayinit_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_arrayinit_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+/// @brief EX Initialize arrays
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_arrayinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_ARRAYINIT_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.C b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.C
new file mode 100644
index 0000000..a73ad42
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.C
@@ -0,0 +1,140 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_chiplet_init.C
+/// @brief EX Flush/Initialize
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Scan0 flush all configured chiplet rings except Vital, GPTR, TIME and DPLL
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_chiplet_init.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+//#define SIM_PLL
+//#define SIM_SPEEDUP
+////#define SCAN0_DISABLE
+//#define STEP_CHIPLET_INIT_0 0x0 // Resetting DPLL
+//#define STEP_CHIPLET_INIT_1 0x1 // Core+ECO glmux switch (IPL/Winkle)
+//#define STEP_CHIPLET_INIT_2 0x2 // Core glmux switch (Sleep)
+//#define STEP_CHIPLET_INIT_3 0x3 // Before Func flush for IPL/Winkle
+//#define STEP_CHIPLET_INIT_4 0x4 // After Func flush for IPL/Winkle
+//#define STEP_CHIPLET_INIT_5 0x5 // After Func flush for IPL/Winkle
+//#define STEP_CHIPLET_INIT_6 0x6 // Before Core GPTR flush for Sleep
+//#define STEP_CHIPLET_INIT_7 0x7 // After Core GPTR flush for Sleep
+//#define STEP_CHIPLET_INIT_8 0x8 // Before Core Func flush for Sleep
+//#define STEP_CHIPLET_INIT_9 0x9 // After Core Func flush for Sleep
+//#define STEP_CHIPLET_INIT_A 0xA // Before Core Func flush for Sleep
+//#define STEP_CHIPLET_INIT_B 0xB // After Core Func flush for Sleep
+//#define PORE_REFCLK_CYCLES 1 // \todo need real value for hdw
+//#define DPLL_LOCK_DELAY 8192*PORE_REFCLK_CYCLES
+
+//-----------------------------------------------------------------------------
+// Procedure: EX Flush/Initialize
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_chiplet_init(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+ uint32_t loop;
+
+ // Procedure Prereq:
+ // p9_sbe_ex_chiplet_reset, p9_sbe_ex_dpll_initf, p9_sbe_ex_pll_initf
+
+ FAPI_INF("<p9_hcd_cache_chiplet_init>: Entering procedure");
+
+ // Look for PSCOM error on any chip, fail if we find one
+ // scan0 flush all configured chiplet rings except EX DPLL
+ // call ex_scan0_module( )
+
+ // >>> IPL/Winkle scan flush - all except vital
+
+ // Hook to bypass in Sim
+ // - hooki 0, 0xFF02
+ // - ifslwcntlbitset P9_SLW_SKIP_FLUSH,1f
+
+ FAPI_DBG("EX Init: Scan0 Module executed: \
+ Scan all except vital, DPL, GPTR, and TIME scan chains");
+ // - updatestep STEP_CHIPLET_INIT_6, D0, P1
+
+ // Each scan0 will rotate the ring 8191 latches (2**13 - 1) and the
+ // the longest ring is defined by P9_SCAN0_FUNC_REPEAT. When the design
+ // ALWAYS has all stumps less than 8191, the repeat (eg .rept) can be
+ // removed.
+ // Implementation note: this is not done in a loop (or included in the
+ // ex_scan0_module itself) as the D0 and D1 registers are used in
+ // ex_scan0_module and there is no convenient place to temporaily store
+ // the 2-64b values values. Argueably, PIBMEM could be used for this
+ // but was not utilized.
+ // = .rept P9_SCAN0_FUNC_REPEAT
+ // = ex_scan0 SCAN_ALL_BUT_VITALDPLLGPTRTIME, SCAN_CLK_ALLEXDPLL
+ // = .endr
+ for(loop=0;loop<P9_SCAN0_FUNC_REPEAT;loop++)
+ {
+ ex_scan0(SCAN_ALL_BUT_VITALDPLLGPTRTIME,SCAN_CLK_ALLEXDPLL);
+ }
+ // - updatestep STEP_CHIPLET_INIT_7, D0, P1
+ // - 1:
+
+ FAPI_INF("<p9_hcd_cache_chiplet_init>: Exiting procedure");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.H b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.H
new file mode 100644
index 0000000..8dfacbc
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_chiplet_init.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_chiplet_init.H
+/// @brief EX Flush/Initialize
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_CHIPLET_INIT_H__
+#define __P9_HCD_CACHE_CHIPLET_INIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_chiplet_init_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_chiplet_init_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>&);
+
+
+/// @brief EX Flush/Initialize
+///
+/// @param [in] i_target TARGET_TYPE_EQ target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_chiplet_init(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_CHIPLET_INIT_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.C b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.C
new file mode 100644
index 0000000..a4fa4ce
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.C
@@ -0,0 +1,313 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_chiplet_reset.C
+/// @brief Cache Chiplet Reset
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Reset quad chiplet logic
+/// Scan0 flush entire cache chiplet
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_chiplet_reset.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+// GP3 Bits
+// 1 - PCB_EP_RESET
+// 2 - GLMMUX Reset
+// 3 - PLL_TEST Enable
+// 4 - PLLRST - PLL Reset
+// 5 - PLL Bypass
+// 11 - D_MODE for Vital
+// 13 - MPW2 for Vital
+// 14 - PMW1 for Vital
+// 18 - FENCE_EN for chiplet
+// 22 - Resonant Clock disable
+// 23:24 - Glitchless Mux Sel
+// 25: - ?? (set because System Pervasive flow does this)
+// Background: system pervasive as the following setting in their tests:
+// 7C1623C000000000
+// Bits set:
+// 1, 2, 3, 4, 5, 11, 13, 14, 18, 22, 23, 24, 25
+//#define GP3_INIT_VECTOR (BITS(1,5)|BIT(11)|BIT(13)|BIT(14)|BIT(18)|BIT(22)|BIT(23)|BIT(24)|BIT(25))
+
+// hang counter inits
+//#define HANG_P1_INIT 0x0400000000000000
+//#define PCB_SL_ERROR_REG_RESET 0xFFFFFFFFFFFFFFFF
+//#define STEP_CHIPLET_RESET_1 0x1 // After start of vital clocks
+//#define STEP_CHIPLET_RESET_2 0x2 // After fence drop
+//#define STEP_CHIPLET_RESET_3 0x3 // Before GPTR flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_4 0x4 // After GPTR flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_5 0x5 // Before Func flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_6 0x6 // After Func flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_7 0x7 // Before GPTR flush for Sleep
+//#define STEP_CHIPLET_RESET_8 0x8 // After GPTR flush for Sleep
+
+//------------------------------------------------------------------------------
+// Procedure: Cache Chiplet Reset
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_chiplet_reset(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target)
+{
+
+#if 0
+ uint32_t loop;
+
+ /////////////////////////////////////////////////////////////////
+ // repeat some init steps of chiplet_init
+ /////////////////////////////////////////////////////////////////
+
+ // If there is a unused, powered-off EX chiplet which needs to be
+ // configured in the following steps to setup the PCB endpoint.
+
+ // Skip the PCB endpoint config steps for sleep so that fences don't
+ // get dropped (eg by dropping chiplet_enable (GP3(0)).
+
+ FAPI_INF("<p9_hcd_cache_chiplet_reset>: \
+ Repeat dedicated pervasive init steps for EX ");
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Reset GP3 for EX chiplet, step needed for hotplug");
+ // = sti GENERIC_GP3_0x000F0012,P0,GP3_INIT_VECTOR
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_0x000F0012,
+ fapi2:buffer<uint64_t>(23452345)));
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Drop aync reset to Glitchless Mux");
+ // = sti GENERIC_GP3_AND_0x000F0013,P0,~BIT(2)
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_AND_0x000F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<2>()));
+
+ // 19:21 PM_PI_DECODE needs to be 010 for functional operation(set bit 20)
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Put DPLL in functional mode");
+ // = sti GENERIC_GP3_OR_0x000F0014,P0, BIT(20)
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_OR_0x000F0014,
+ fapi2::buffer<uint64_t>().setBit<20>()));
+
+ // - updatestep STEP_CHIPLET_RESET_1, D0, P1
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Release endpoint reset for PCB");
+ // = sti GENERIC_GP3_AND_0x000F0013,P0,~BIT(1)
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_AND_0x000F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<1>()));
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Partial good setting");
+ // = sti GENERIC_GP3_OR_0x000F0014,P0,BIT(0)
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_OR_0x000F0014,
+ fapi2::buffer<uint64_t>().setBit<0>()));
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ PCB slave error reg reset");
+ // = sti MASTER_PCB_ERR_0x000F001F,P0,PCB_SL_ERROR_REG_RESET
+ FAPI_TRY(putScom(i_target, MASTER_PCB_ERR_0x000F001F,
+ fapi2:buffer<uint64_t>(643564)));
+
+ FAPI_DBG("Use timer mode for DPLL lock when enabled");
+ // = sti EX_PMGP0_OR_0x100F0102, P0, BIT(7)
+ FAPI_TRY(putScom(i_target, EX_PMGP0_OR_0x100F0102,
+ fapi2::buffer<uint64_t>().setBit<7>()));
+
+ // Set the DPLL Timer value for waiting on DPLL HOLDs in 35:36
+ // 00 = 1024 cycles <----
+ // 01 = 512 cycles
+ // 10 = 256 cycles
+ // 11 = 128 cycles
+ FAPI_DBG("Set the timer value for waiting on DPLL THOLDs");
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(35)|BIT(36))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().insertFromRight<35,2>(0)));
+
+ // Only perform the disablement of PCBS-PM for the IPL work-around when
+ // doing IPL (eg skip if winkle; this whole section is skipped for sleep)
+ // >>> IPL
+ // FAPI_DBG("Disable the PCBS-PM as part of winkle enablement");
+ // = sti EX_PMGP0_OR_0x100F0102, P0, BIT(0)
+ FAPI_TRY(putScom(i_target, EX_PMGP0_OR_0x100F0102,
+ fapi2:buffer<uint64_t>().setBit<0>()));
+
+ // The following is performed for both IPL/Winkle and Sleep
+
+ // Note: These are executed for sleep as well as these fences will have
+ // already been dropped
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Remove pervasive ECO fence;");
+ // ECO Fence in 22
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(22))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<22>()));
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Remove winkle mode before scan0 on EX chiplets is executed");
+ // PM Exit States: WINKLE_EXIT_DROP_ELEC_FENCE
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Remove logical pervasive/pcbs-pm fence");
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(39))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<39>()));
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Remove PB Winkle Electrical Fence GP3(27)");
+ // = sti EX_GP3_AND_0x100F0013,P0,~(BIT(27))
+ FAPI_TRY(putScom(i_target, EX_GP3_AND_0x100F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<27>()));
+
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Configuring chiplet hang counters") ;
+ // = sti EX_HANG_P1_0x100F0021,P0,HANG_P1_INIT
+ data = 34654; // HANG_P1_INIT
+ FAPI_TRY(putScom(i_target, EX_HANG_P1_0x100F0021,
+ fapi2:buffer<uint64_t>(34654)));
+ // - updatestep STEP_CHIPLET_RESET_2, D0, P1
+
+ //////////////////////////////////////////////////////////////
+ // perform scan0 module for pervasive chiplet (GPTR_TIME_REPR)
+ //////////////////////////////////////////////////////////////
+
+ // >>> IPL/Winkle scan flush - core and EX
+
+ // Hook to bypass in sim while providing a trace
+ // - hooki 0, 0xFF01
+ // - ifslwcntlbitset P9_SLW_SKIP_FLUSH,1f
+
+ // \todo WORKAROUND UNTIL LOGIC CHANGES
+ // Drop the core2cache and cache2core fences to allow for L2 scanning
+ FAPI_DBG("<p9_hcd_cache_chiplet_reset>: \
+ Remove pervasive ECO fence;");
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(20) | BIT(21))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().insertFromRight<20,2>(0)));
+
+ FAPI_DBG("EX Reset: Scan0 Module executed: \
+ Scan the GPTR/TIME/REP rings");
+ // - updatestep STEP_CHIPLET_RESET_3, D0, P1
+
+ // = .rept P9_SCAN0_GPTR_REPEAT
+ // = ex_scan0 SCAN_GPTR_TIME_REP, SCAN_CLK_ALL
+ // = .endr
+ for(loop=0;loop<P9_SCAN0_GPTR_REPEAT;loop++)
+ {
+ ex_scan0(SCAN_GPTR_TIME_REP, SCAN_CLK_ALL);
+ }
+
+ // - updatestep STEP_CHIPLET_RESET_4, D0, P1
+
+ // - 1:
+ // Hook to bypass in sim while providing a trace
+ // - hooki 0, 0xFF02
+ // - ifslwcntlbitset P9_SLW_SKIP_FLUSH,1f
+
+ FAPI_DBG("EX Reset: Scan0 Module executed: \
+ Scan the all but GPTR/TIME/REP rings");
+ // - updatestep STEP_CHIPLET_RESET_5, D0, P1
+
+ // Each scan0 will rotate the ring 8191 latches (2**13 - 1) and the
+ // the longest ring is defined by P9_SCAN0_FUNC_REPEAT. When the design
+ // ALWAYS has all stumps less than 8191, the repeat (eg .rept) can be
+ // removed.
+ // Implementation note: this is not done in a loop (or included in the
+ // ex_scan0_module itself) as the D0 and D1 registers are used in
+ // ex_scan0_module and there is no convenient place to temporarily store
+ // the 2-64b values values. Argueably, PIBMEM could be used for this
+ // but was not utilized.
+ // = .rept P9_SCAN0_FUNC_REPEAT
+ // = ex_scan0 SCAN_ALL_BUT_GPTRTIMEREP, SCAN_CLK_ALL
+ // = .endr
+ for(loop=0;loop<P9_SCAN0_FUNC_REPEAT;loop++)
+ {
+ ex_scan0(SCAN_ALL_BUT_GPTRTIMEREP, SCAN_CLK_ALL);
+ }
+
+ // - updatestep STEP_CHIPLET_RESET_6, D0, P1
+
+ // Ensure CC interrupts are disabled before starting clock domains and dpll
+ // But only do it for Murano-DD1.x!
+ // - lpcs P1, STBY_CHIPLET_0x00000000
+ // - ldandi D0, PCBMS_DEVICE_ID_0x000F000F, P1, BITS(0, 32)
+ // - andi D0, D0, CFAM_CHIP_ID_CHIP_MAJOR_MASK
+ // - cmpibrane D0, 1f, CFAM_CHIP_ID_MURANO_1
+
+ // - mr A0, P0
+ // - mr D1, ETR
+ // - ls P0, CHIPLET0
+ // - ls CTR, MAX_CORES
+ // - bra end_core_loop
+
+ // - begin_core_loop:
+ // Inspect presence of current ex chiplet
+ // - andi D0, D1, BIT(32)
+ // - braz D0, continue_core
+ // Disable CC interrupts.
+ // - ld D0, EX_SYNC_CONFIG_0x10030000, P0
+ // - ori D0, D0, BIT(6)
+ // - std D0, EX_SYNC_CONFIG_0x10030000, P0
+
+ // - continue_core:
+ // - adds P0, P0, 1 //Increment ex chiplet
+ // - rols D1, D1, 1 //Shift ex chiplet mask left
+
+ // - end_core_loop:
+ // - loop begin_core_loop
+ // - mr P0, A0
+ // - 1:
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.H b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.H
new file mode 100644
index 0000000..8dc6167
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_chiplet_reset.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_chiplet_reset.H
+/// @brief Cache Chiplet Reset
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_CHIPLET_RESET_H__
+#define __P9_HCD_CACHE_CHIPLET_RESET_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_chiplet_reset_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_chiplet_reset_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>&);
+
+/// @brief Cache Chiplet Reset
+///
+/// @param [in] i_target TARGET_TYPE_EQ target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_chiplet_reset(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_CHIPLET_RESET_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.C b/src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.C
new file mode 100644
index 0000000..0175c98
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.C
@@ -0,0 +1,282 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_dpll_setup.C
+/// @brief Quad DPLL Setup
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Initfiles in procedure defined on VBU ENGD wiki (TODO add link)
+/// DPLL tune bits are not dependent on frequency
+/// Put DPLL into bypass
+/// Set DPLL syncmux sel
+/// Set clock controller scan ratio to 1:1 as this is done at refclk speeds
+/// Load the EX DPLL scan ring
+/// Set clock controller scan ratio to 8:1 for future scans
+/// Frequency is controlled by the Quad PPM
+/// Actual frequency value for boot is stored into the Quad PPM by
+/// p9_hcd_setup_evid.C in istep 2
+/// In real cache STOP exit, the frequency value is persistent
+/// Enable the DPLL in the correct mode
+/// non-dynamic
+/// Slew rate established per DPLL team
+/// Take the cache glitchless mux out of reset
+/// (TODO: is there still a reset on P9?)
+/// Remove DPLL bypass
+/// Drop DPLL Tholds
+/// Check for DPLL lock
+/// Timeout: 200us
+/// Switch cache glitchless mux to use the DPLL
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_dpll_setup.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//#define DPLL_LOCK_BIT, 50
+//#define DPLL_LOCK_MAX_POLL_LOOPS, 0x1600
+//#define DPLL_LOCK_DELAY_CYCLES, 0x10
+//#define STEP_SBE_DPLL_SETUP_LOCK, 1
+//#define STEP_SBE_DPLL_GMUX_SET, 2
+//#define STEP_SBE_DPLL_SETUP_COMPLETE, 3
+
+// For a 2000GHz nest (500MHz Pervasive), 2ns clocks exists
+// For a DPLL lock time of >150us from power on, 150000/2 = 75000
+// d75000 => 0x124F8 ----> round up to 0x15000
+
+// For a 2400GHz nest (600MHz Pervasive), 1.667ns clocks exists
+// For a DPLL lock time of >150us from power on, 150000/1.667 = 89982
+// d90000 => 0x15f90 ----> round up to 0x16000
+
+//#define DPLL_LOCK_DELAY 0x10
+//#define DPLL_LOCK_LOOP_NUMBER 0x1600
+
+//#define ex_dpll_lock_delay_mult 0x1600
+//#define ex_glsmux_post_delay_mult 0x1
+
+//-----------------------------------------------------------------------------
+// Procedure: Quad DPLL Setup
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_dpll_setup(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ FAPI_INF("EX Chiplet -> Start DPLL setup" )
+
+ // The setup of P0 happens external to this procedure
+ // P0 is set to point to either a single EX core, or to multiple EX
+ // cores using multicast
+ FAPI_DBG("EX Chiplet dpll_setup P0 -> 0x%02llx" , io_pore.p0.read())
+
+ // Skip DPLL and Glitchless mux setup for Sleep
+ // Glitchless mux change for the core (Sleep) done in
+ // p9_sbe_ex_chiplet_reset.
+
+ // - ifsleep D0, glm_end
+ // >>> IPL/WINKLE
+
+ // - dpll_start:
+
+ // - setp1_mcreadand D0
+
+ FAPI_INF("Set up CPM PARM register for DPLL")
+ // = ld D0, EX_DPLL_CPM_PARM_REG_0x100F0152, P1
+ FAPI_TRY(getScom(i_target, EX_DPLL_CPM_PARM_REG_0x100F0152, data));
+
+ // ----- Make sure that ff_bypass is set to "1" -----
+ // This is necessary to ensure that the DPLL is in Mode 1. If not,
+ // the lock times will go from ~30us to 3-5ms
+ // Set bit 11 of DPLL Mode register 0x150F0152
+
+ FAPI_DBG("Put DPLL into Mode 1 by asserting ff_bypass.")
+ FAPI_DBG(">>> Work around <<<<: Also disabling ping-pong synchronizer" )
+ // = ori D0, D0, (BIT(11)|BIT(32))
+ data.setBit<11>().setBit<32>();
+
+ FAPI_DBG("Clear bits 15,16,18-23 and set bit 17 of DPLL reg 0x10F0152")
+ // = andi D0, D0, 0xFFFE00FFFFFFFFFF
+ // = ori D0, D0, BIT(17)
+ data.insertFromRight<15,9>(0x40);
+
+ FAPI_DBG("Set slew rate to a modest value")
+ // = ori D0, D0, 0x8000000000000000
+ // = std D0, EX_DPLL_CPM_PARM_REG_0x100F0152, P0
+ data.setBit<0>();
+ FAPI_TRY(putScom(i_target, EX_DPLL_CPM_PARM_REG_0x100F0152, data));
+
+ // ----- Clear dpllclk_muxsel (syncclk_muxsel) to "0" -----
+ FAPI_INF("Reset syncclk_muxsel or dpllclk_muxsel")
+ // = sti GENERIC_GP0_AND_0x00000004, P0, ~BIT(1)
+ FAPI_TRY(putScom(i_target, GENERIC_GP0_AND_0x00000004,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<1>()));
+
+ // = sti EX_PMGP0_AND_0x100F0101, P0, ~(BIT(11))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<11>()));
+
+ // ----- Take DPLL out of bypass -----
+ // Clear bit 5 of EX GP3 Register
+ FAPI_INF("EX Chiplet -> Take DPLL out of bypass" )
+ // = sti EX_GP3_AND_0x100F0013, P0, ~(BIT(5))
+ FAPI_TRY(putScom(i_target, EX_GP3_AND_0x100F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<5>()));
+
+ // ----- Drop DPLL tholds -----
+ // Clear bit 3 of EX PMGP0 Register
+ FAPI_INF("EX Chiplet -> Drop internal DPLL THOLD" )
+ // = sti EX_PMGP0_AND_0x100F0101, P0, ~(BIT(3))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<3>()));
+
+ // ----- Delay to wait for DPLL to lock -----
+ // TODO: Determine whether or not we should POLL instead of put delay here.
+ // Wait for >150us
+
+ FAPI_INF("Wait for DPLL to lock" )
+ // - waits DPLL_LOCK_LOOP_NUMBER*DPLL_LOCK_DELAY
+
+ // Check for lock
+ // - ldandi D0, EX_PMGP0_0x100F0100, P1, BIT(DPLL_LOCK_BIT)
+ // - braz D0, dpll_nolock
+
+ // ----- Recycle DPLL in and out of bypass -----
+ // Clear bit 5 of EX GP3 Register
+ FAPI_INF("EX Chiplet -> Recycle DPLL in and out of bypass" )
+ // = sti EX_GP3_OR_0x100F0014, P0, BIT(5)
+ FAPI_TRY(putScom(i_target, EX_GP3_OR_0x100F0014,
+ fapi2:buffer<uint64_t>().setBit<5>()));
+
+ // = sti EX_GP3_AND_0x100F0013, P0, ~(BIT(5))
+ FAPI_TRY(putScom(i_target, EX_GP3_AND_0x100F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<5>()));
+
+ FAPI_INF("EX Chiplet -> EX DPLL is locked" )
+ // - updatestep STEP_SBE_DPLL_SETUP_LOCK, D0, P1
+
+ // - glm_start:
+
+ // ----- Set Glitch-Less MUXes for IPL/Winkle case ----
+ // For Sleep, the core glitchless mux is change earlier as the DPLL
+ // was already up and locked.
+ //
+ // Set various gl muxes to pass the output of the DPLLs to the clock grid.
+
+ // Read-modify-write (vs sti AND and sti OR) is done so that glitchless
+ // mux change field change is atomic (eg 1 store)
+ // - setp1_mcreadand D1
+
+ // = ld D1,EX_PMGP0_0x100F0100,P1
+ FAPI_TRY(getScom(i_target, EX_PMGP0_0x100F0100, data));
+
+ // IPL/Winkle - Switch glitchless mux primary source to 001 = DPLL for bits
+ // 27:29
+
+ // Note: GLM async reset occured in p9_sbe_ex_chiplet_reset.
+
+ // Set tp_clkglm_sel_dc to "001" (EX PM GP0 bits 27-29)
+ FAPI_INF("EX Chiplet -> Set glitchless mux select for primary chiplet clock source to 001 ")
+ // Set tp_clkglm_eco_sel_dc to "0" (EX PM GP0 bit 30)
+ // Set the core glitchless mux to use the primary input (b00).
+ // EX PM GP0 bits 32-33)
+ FAPI_INF("EX Chiplet -> Set glitchless mux select for core and eco domain to 0 ")
+ // = andi D1, D1, ~(BIT(27)|BIT(28)|BIT(30)|BIT(32)|BIT(33))
+ // = ori D1, D1, (BIT(29))
+ data.insertFromRight<27,4>(0x2).inerstFromRight<32,2>(0x0);
+
+ // Store the final result to the hardware
+ // = std D1,EX_PMGP0_0x100F0100,P0
+ FAPI_TRY(putScom(i_target, EX_PMGP0_0x100F0100, data));
+
+ // - glm_end:
+
+ // - updatestep STEP_SBE_DPLL_GMUX_SET, D0, P1
+
+ // ----- Drop ff_bypass to enable slewing -----
+ // ----- (Change from Mode 1 to mode 2) -----
+ // Clear bit 11 of DPLL Mode register 0x150F0152
+ // CMO20131125-Further, drop the pp synchronizer bit32.
+ // CMO20131219-Keep the pp sync bit32 asserted to avoid x-leakage(HW276931).
+ FAPI_INF("EX Chiplet -> Clear ff_bypass to switch into slew-controlled mode")
+ // - setp1_mcreadand D1
+ // = ld D1, EX_DPLL_CPM_PARM_REG_0x100F0152, P1
+ // = andi D1, D1, ~(BIT(11))
+ // = std D1, EX_DPLL_CPM_PARM_REG_0x100F0152, P0
+ FAPI_TRY(getScom(i_target, EX_DPLL_CPM_PARM_REG_0x100F0152, data));
+ data.clearBit<11>();
+ FAPI_TRY(putScom(i_target, EX_DPLL_CPM_PARM_REG_0x100F0152, data));
+
+ // ----- Drop other tholds -----
+ // Clear bit 3 of EX PM GP0 Register
+ // FAPI_INF("EX Chiplet -> Drop DPLL thold" )
+ // sti EX_PMGP0_AND_0x100F0101,P0, ~(BIT(3))
+
+ // - updatestep STEP_SBE_DPLL_SETUP_COMPLETE, D0, P1
+ FAPI_INF("EX Chiplet -> DPLL setup completed" )
+
+ // DEBUG only
+ // - setp1_mcreadand D1
+ // = ld D0,EX_GP0_0x10000000,P1
+ FAPI_TRY(getScom(i_target, EX_GP0_0x10000000, data));
+
+ // - dpll_nolock:
+ FAPI_ERR("EX_DPLL -> Failed to lock");
+ // - reqhalt RC_SBE_DPLL_SETUP_NOLOCK
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.H b/src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.H
new file mode 100644
index 0000000..df13cf0
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_dpll_setup.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_dpll_setup.H
+/// @brief Quad DPLL Setup
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_DPLL_SETUP_H__
+#define __P9_HCD_CACHE_DPLL_SETUP_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_dpll_setup_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_dpll_setup_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>&);
+
+/// @brief Quad DPLL Setup
+///
+/// @param [in] i_target TARGET_TYPE_EQ target
+///
+/// @attr
+/// @attritem ATTR_DPLL_REPAIR_RING - EQ target, uint32
+/// repair dpll ring content<br>
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_dpll_setup(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_DPLL_SETUP_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.C b/src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.C
new file mode 100644
index 0000000..498ae79
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.C
@@ -0,0 +1,110 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_gptr_time_initf.C
+/// @brief Load GPTR and Time for EX non-core
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Initfiles in procedure defined on VBU ENGD wiki (TODO add link)
+/// to produce #G VPD contents
+/// Check for the presence of core override GPTR ring from image
+/// (this is new fvor P9)
+/// if found, apply; if not, apply core GPTR from image
+/// Check for the presence of core override TIME ring from image;
+/// if found, apply; if not, apply core base TIME from image
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_gptr_time_initf.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure: Load GPTR and Time for EX non-core
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_gptr_time_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target)
+{
+
+#if 0
+
+ // Set EX scan ratio to 1:1 as EX is still at refclock
+ FAPI_INF("<p9_sbe_ex_gptr_time_initf> : Set EX scan ratio to 1:1 ...");
+ // = sti EX_OPCG_CNTL0_0x10030002, P0, 0x0
+ FAPI_TRY(fapi2::putScom(i_target, EX_OPCG_CNTL0_0x10030002, 0x0));
+
+ // scan ring content shared among all chiplets
+ FAPI_DBG("Scanning EX GPTR rings...")
+ // - load_ring ex_gptr_perv skipoverride=1
+ // - load_ring ex_gptr_dpll skipoverride=1
+ // - load_ring ex_gptr_l3 skipoverride=1
+ // - load_ring ex_gptr_l3refr skipoverride=1
+
+ // scan chiplet specific ring content
+ FAPI_DBG("Scanning EX TIME rings...")
+ // - load_ring_vec_ex ex_time_eco
+
+
+ // Set EX scan ratio back to 8:1
+ FAPI_INF("<p9_sbe_ex_gptr_time_initf> : Set EX scan ratio to 8:1 ...");
+ // Inputs: A1 and P0 and D0, destroys D0 & D1
+ // - .pibmem_port (PORE_SPACE_PIBMEM & 0xf)
+ // - lpcs P1, PIBMEM0_0x00080000
+ // - ld D0, ex_scan_ratio_override, P1
+ // - bsr set_scan_ratio_d0
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.H b/src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.H
new file mode 100644
index 0000000..17d001f
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_gptr_time_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_gptr_time_initf.H
+/// @brief Load GPTR and Time for EX non-core
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_GPTR_TIME_INIT_H__
+#define __P9_HCD_CACHE_GPTR_TIME_INIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_gptr_time_initf_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_gptr_time_initf_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>&);
+
+/// @brief Load GPTR and Time for EX non-core
+///
+/// @param [in] i_target TARGET_TYPE_EQ target
+///
+/// @attr
+/// @attritem ATTR_CACHE_GPTR_TIME_RING - EX target, uint32
+/// pointer to RS4 content.<br>
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_gptr_time_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_GPTR_TIME_INIT_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_initf.C b/src/ppe/hwp/cache/p9_hcd_cache_initf.C
new file mode 100644
index 0000000..630940b
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_initf.C
@@ -0,0 +1,99 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_initf.C
+/// @brief EX (non-core) scan init
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Initfiles in procedure defined on VBU ENGD wiki (TODO add link)
+/// Check for the presence of cache FUNC override rings from image;
+/// if found, apply; if not, apply cache base FUNC rings from image
+/// Note: FASTINIT ring (eg CMSK ring) is setup at this point to limit the
+/// stumps that participate in FUNC ring scanning (this is new for P9).
+/// (TODO to make sure the image build support is in place)
+/// Note: all caches that are in the Cache Multicast group will be
+/// initialized to the same values via multicast scans
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_initf.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure: EX (non-core) scan init
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ // - load_ring ex_lbst_eco conditional_override=1
+ // - load_ring ex_abfa_eco conditional_override=1
+ // - load_ring ex_cmsk_eco conditional_override=1
+ // - load_ring ex_func_perv conditional_override=1
+ // - load_ring ex_func_l3 conditional_override=1
+ // - load_ring ex_func_l3refr conditional_override=1
+
+ //Sim Speedup for L3 refresh cycles
+ // - load_ring ex_regf_l3 conditional_override=1
+ // - load_ring ex_regf_l3refr conditional_override=1
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_initf.H b/src/ppe/hwp/cache/p9_hcd_cache_initf.H
new file mode 100644
index 0000000..9f7ffdc
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_initf.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_initf.H
+/// @brief EX (non-core) scan init
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_INITF_H__
+#define __P9_HCD_CACHE_INITF_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_initf_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_initf_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+/// @brief EX (non-core) scan init
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem ATTR_CACHE_L2_FUNC_RING - EX target, uint32
+/// @attritem ATTR_CACHE_L3_FUNC_RING - EX target, uint32
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_INITF_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.C b/src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.C
new file mode 100644
index 0000000..8e1c82e
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.C
@@ -0,0 +1,93 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_occ_runtime_scom.C
+/// @brief EX OCC runtime scoms
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Run-time updates from OCC code that are put somewhere TBD
+/// (TODO . revisit with OCC FW team)
+/// OCC FW sets up value in the TBD SCOM section
+/// This was not leverage in P8 with the demise of CPMs
+/// Placeholder at this point
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_occ_runtime_scom.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+#define host_runtime_scom 0
+
+//------------------------------------------------------------------------------
+// Procedure: EX OCC runtime SCOMS
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_occ_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ // Run the SCOM sequence if the SCOM procedure is defined
+ // - la A0, occ_runtime_scom
+ // - ld D0, 0, A0
+ // - braz D0, 1f
+ FAPI_INF("Launching OCC Runtime SCOM routine")
+ // - bsrd D0
+ // - 1:
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.H b/src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.H
new file mode 100644
index 0000000..e82b6b2
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_occ_runtime_scom.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_occ_runtime_scom.H
+/// @brief EX OCC runtime scoms
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_OCC_RUNTIME_SCOM_H__
+#define __P9_HCD_CACHE_OCC_RUNTIME_SCOM_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_occ_runtime_scom_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_occ_runtime_scom_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+
+/// @brief EX OCC runtime scoms
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem ATTR_CACHE_OCC_SCOM_LOC - EX target, uint32
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_occ_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_OCC_RUNTIME_SCOM_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_poweron.C b/src/ppe/hwp/cache/p9_hcd_cache_poweron.C
new file mode 100644
index 0000000..0aa81a1
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_poweron.C
@@ -0,0 +1,84 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_poweron.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_poweron.C
+/// @brief Cache Chiplet Power-on
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Command the cache PFET controller to power-on
+/// Check for valid power on completion
+/// Polled Timeout: 100us
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_poweron.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure: Cache Chiplet Power-on
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_poweron(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
+ const uint32_t i_operation)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_poweron.H b/src/ppe/hwp/cache/p9_hcd_cache_poweron.H
new file mode 100644
index 0000000..89bcffc
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_poweron.H
@@ -0,0 +1,66 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_poweron.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_poweron.H
+/// @brief Cache Chiplet Power-on
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_POWERON_H__
+#define __P9_HCD_CACHE_POWERON_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_poweron_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_poweron_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>&,
+ const uint32_t);
+
+
+/// @brief Cache Chiplet Power-on
+///
+/// @param [in] i_target TARGET_TYPE_EQ target
+/// @param [in] i_operation ENUM(ON,OFF)
+///
+/// @attr
+/// @attritem ATTR_PFET_*
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_poweron(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
+ const uint32_t i_operation);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_POWERON_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.C b/src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.C
new file mode 100644
index 0000000..88a0518
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.C
@@ -0,0 +1,171 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_ras_runtime_scom.C
+/// @brief EX FSP/Host runtime scoms
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Run-time updates by FSP/Host(including HostServices and Hypervisors)
+/// that are put on the cache image by STOP API calls
+/// Dynamically built pointer where a NULL is checked before execution
+/// If NULL (the SBE case), return
+/// Else call the function at the pointer; pointer is filled in by
+/// STOP image build
+/// Powerbus (MCD) and L3 BAR settings
+/// Runtime FIR mask updates from PRD
+/// L2/L3 Repairs
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_ras_runtime_scom.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+#define host_runtime_scom 0
+
+//------------------------------------------------------------------------------
+// Procedure: EX FSP/HOST runtime scoms
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_ras_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ // Run the SCOM sequence if the SCOM procedure is defined
+ // - la A0, sp_runtime_scom
+ // - ld D0, 0, A0
+ // - braz D0, 1f
+ //FAPI_INF("Launching SP Runtime SCOM routine")
+ // - bsrd D0
+ // - 1:
+ //
+
+ // Run the SCOM sequence if the SCOM procedure is defined.
+ // - la A0, host_runtime_scom
+ // - ld D1, 0, A0
+ // - braz D1, 1f
+
+ // Prep P1
+ // - setp1_mcreadand D0
+
+#if 0
+ // Disable the AISS to allow the override
+ // = ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // = andi D0, D0, ~(BIT(1))
+ // = std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ // Drop PSCOM fence to allow SCOM and set pm_wake-up to PC to accepts
+ // RAMs (SCOMs actually) in the IPL "Nap" state
+ // = ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // = ori D0, D0, (BIT(15))
+ // = andi D0, D0, ~(BIT(21))
+ // = std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+#endif
+
+ // Branch to sub_slw_runtime_scom()
+ FAPI_INF("Launching Host Runtime SCOM routine")
+ // - bsrd D1
+
+ // Prep P1
+ // - setp1_mcreadand D0
+
+#if 0
+ // Clear regular wake-up and restore PSCOM fence in OHA
+ // These were established in p9_sbe_ex_scominit.S
+ // = ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // = andi D0, D0, ~(BIT(15))
+ // = ori D0, D0, BIT(21)
+ // = std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+ // Enable the AISS to allow further operation
+ // = ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // = ori D0, D0, (BIT(1))
+ // = std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+#endif
+
+ // - bra 2f
+ // - 1:
+
+ // To accomodate IPL flow, where sub_slw_runtime_scom() is skipped
+ // - setp1_mcreadand D0
+
+#if 0
+ // Clear regular wake-up and restore PSCOM fence in OHA
+ // These were established in p9_sbe_ex_scominit.S
+ // = ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // = andi D0, D0, ~BIT(1)
+ // = std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ // = ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // = andi D0, D0, ~(BIT(15))
+ // = ori D0, D0, BIT(21)
+ // = std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+ // Enable the AISS to allow further operation
+ // = ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // = ori D0, D0, (BIT(1))
+ // = std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+#endif
+ // - 2:
+
+ // If using cv_multicast, we need to set the magic istep number here
+ // - la A0, p9_sbe_select_ex_control
+ // - ldandi D0, 0, A0, P9_CONTROL_INIT_ALL_EX
+ // - braz D0, 3f
+ FAPI_DBG("Setting istep num to magic number because cv_multicast is set")
+ // - lpcs P1, MBOX_SBEVITAL_0x0005001C
+ // - sti MBOX_SBEVITAL_0x0005001C, P1, (P9_SBE_EX_RAS_RUNTIME_SCOM_MAGIC_ISTEP_NUM << (4+32))
+ // - 3:
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.H b/src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.H
new file mode 100644
index 0000000..ec9a389
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_ras_runtime_scom.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_ras_runtime_scom.H
+/// @brief EX FSP/Host runtime scoms
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CACHE_RAS_RUNTIME_SCOM_H__
+#define __P9_HCD_CACHE_RAS_RUNTIME_SCOM_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_ras_runtime_scom_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_ras_runtime_scom_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+/// @brief EX FSP/Host runtime scoms
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem ATTR_CACHE_RAS_SCOM_LOC - EX target, uint32
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_ras_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_RAS_RUNTIME_SCOM_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_repair_initf.C b/src/ppe/hwp/cache/p9_hcd_cache_repair_initf.C
new file mode 100644
index 0000000..e986a81
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_repair_initf.C
@@ -0,0 +1,87 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_repair_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_repair_initf.C
+/// @brief Load Repair ring for EX non-core
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Load cache ring images from MVPD
+/// These rings must contain ALL chip customization data.
+/// This includes the following: Repair Power headers, and DTS
+/// Historically this was stored in MVPD keywords are #R, #G. Still stored in /// MVPD, but SBE image is customized with rings for booting cores
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_repair_initf.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure: Load Repair ring for cache
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_repair_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ // scan chiplet specific ring content
+ FAPI_DBG("Scanning EX REPAIR rings...")
+ // - load_ring_vec_ex ex_repr_eco
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_repair_initf.H b/src/ppe/hwp/cache/p9_hcd_cache_repair_initf.H
new file mode 100644
index 0000000..ab8484f
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_repair_initf.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_repair_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_repair_initf.H
+/// @brief Load Repair ring for EX non-core
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_REPAIR_INITF_H__
+#define __P9_HCD_CACHE_REPAIR_INITF_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_repair_initf_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_repair_initf_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+
+/// @brief Load Repair ring for EX non-core
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem ATTR_CACHE_REPAIR_RING - EX target, uint32
+/// pointer to RS4 content, VPD #R Keyword content(RS4)<br>
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_repair_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_REPAIR_INITF_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_runinit.C b/src/ppe/hwp/cache/p9_hcd_cache_runinit.C
new file mode 100644
index 0000000..eb6f5fe
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_runinit.C
@@ -0,0 +1,73 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_runinit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_runinit.C
+/// @brief execute all cache init procedures
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_runinit.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions:
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure:
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_runinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+
+#if 0
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+#endif
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_runinit.H b/src/ppe/hwp/cache/p9_hcd_cache_runinit.H
new file mode 100644
index 0000000..2b22d35
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_runinit.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_runinit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_runinit.H
+/// @brief execute all cache init procedures
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_RUNINIT_H__
+#define __P9_HCD_CACHE_RUNINIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_runinit_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_runinit_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
+
+
+/// @brief execute all cache init procedures
+///
+/// @param [in] i_target TARGET_TYPE_PROC_CHIP target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_runinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_RUNINIT_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_scomcust.C b/src/ppe/hwp/cache/p9_hcd_cache_scomcust.C
new file mode 100644
index 0000000..789f954
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_scomcust.C
@@ -0,0 +1,93 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_scomcust.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_scomcust.C
+/// @brief Core Chiplet PCB Arbitration
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// If CME, request PCB Mux.
+/// Poll for PCB Mux grant
+/// Else (SBE)
+/// Nop (as the CME is not running in bringing up the first Core)
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_scomcust.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions: Core Chiplet PCB Arbitration
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_scomcust(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ //Dynamically built (and installed) routine that is inserted by the .XIP
+ //Customization. process. (New for P9)
+ //(TODO: this part of the process is a placeholder at this point)
+ //Dynamically built pointer where a NULL is checked before execution
+ //If NULL (a potential early value); return
+ //Else call the function at the pointer;
+ //pointer is filled in by XIP Customization
+ //Customization items:
+ //Epsilon settings scan flush to super safe
+ //Customize Epsilon settings for system config
+ //LCO setup (chiplet specific)
+ //FW setups up based victim caches
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_scomcust.H b/src/ppe/hwp/cache/p9_hcd_cache_scomcust.H
new file mode 100644
index 0000000..9837513
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_scomcust.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_scomcust.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_scomcust.H
+/// @brief Core Chiplet PCB Arbitration
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_SCOMCUST_H__
+#define __P9_HCD_CACHE_SCOMCUST_H__
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_scomcust_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_scomcust_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+
+/// @brief Core Chiplet PCB Arbitration
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_scomcust(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_SCOMCUST_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_scominit.C b/src/ppe/hwp/cache/p9_hcd_cache_scominit.C
new file mode 100644
index 0000000..869de65
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_scominit.C
@@ -0,0 +1,130 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_scominit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_scominit.C
+/// @brief Cache Customization SCOMs
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Apply any SCOM initialization to the cache
+/// Stop L3 configuration mode
+/// Configure Trace Stop on Xstop
+/// DTS Initialization sequense
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_scominit.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure: Cache Customization SCOMs
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_scominit(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ ///////
+ // NCU
+ ///////
+
+ ///////
+ // L3
+ ///////
+
+ FAPI_DBG("Configuring L3 disable");
+ // - l3_setup L3_SETUP_ACTION_DISABLE, L3_SETUP_UNIT_L3
+
+ ///////
+ // OHA
+ ///////
+
+ FAPI_DBG("Enable OHA to accept idle operations \
+ by removing idle state override");
+ // - setp1_mcreadand D1
+ // = ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ FAPI_TRY(getScom(i_target, EX_OHA_MODE_REG_RWx1002000D, data));
+
+ //FAPI_DBG("Read OHA_MODE value: 0x%16llx", io_pore.d0.read());
+ // = andi D0, D0, ~BIT(6)
+ data.clearBit<6>();
+
+ //FAPI_DBG("Updated OHA_MODE value: 0x%16llx", io_pore.d0.read());
+ // = std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ FAPI_TRY(putScom(i_target, EX_OHA_MODE_REG_RWx1002000D, data));
+
+ // set trace stop on checkstop
+ // Get the ECID to apply trace setup to only Murano DD2+ / Venice
+ // - lpcs P1, STBY_CHIPLET_0x00000000
+ // - ldandi D0, PCBMS_DEVICE_ID_0x000F000F, P1, (CFAM_CHIP_ID_CHIP_MASK | CFAM_CHIP_ID_MAJOR_EC_MASK)
+ // - cmpibraeq D0, 1f, (CFAM_CHIP_ID_MURANO | CFAM_CHIP_ID_MAJOR_EC_1 )
+
+ FAPI_DBG("Configuring EX chiplet trace arrays \
+ to stop on checkstop/recoverable errors")
+ // = sti GENERIC_DBG_MODE_REG_0x000107C0, P0, BIT(7) | BIT(8)
+ FAPI_TRY(putScom(i_target, GENERIC_DBG_MODE_REG_0x000107C0,
+ fapi2:buffer<uint64_t>().insertFromRight<7,2>(0x3)));
+
+ // = sti GENERIC_DBG_TRACE_REG2_0x000107CB, P0, BIT(17)
+ FAPI_TRY(putScom(i_target, GENERIC_DBG_TRACE_REG2_0x000107CB,
+ fapi2:buffer<uint64_t>().setBit<17>()));
+ // - 1:
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_scominit.H b/src/ppe/hwp/cache/p9_hcd_cache_scominit.H
new file mode 100644
index 0000000..0fd37c6
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_scominit.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_scominit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_scominit.H
+/// @brief Cache Customization SCOMs
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CACHE_SCOMINIT_H__
+#define __P9_HCD_CACHE_SCOMINIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_scominit_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_scominit_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+
+/// @brief Cache Customization SCOMs
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_scominit(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_SCOMINIT_H__
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_startclocks.C b/src/ppe/hwp/cache/p9_hcd_cache_startclocks.C
new file mode 100644
index 0000000..3731f2e
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_startclocks.C
@@ -0,0 +1,275 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_startclocks.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_startclocks.C
+/// @brief Quad Clock Start
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Set (to be sure they are set under all conditions) core logical fences
+/// (new for P9)
+/// Drop pervasive thold
+/// Setup L3 EDRAM/LCO
+/// Drop pervasive fence
+/// Reset abst clock muxsel, sync muxsel
+/// Set fabric node/chip ID from the nest version
+/// Clear clock controller scan register before start
+/// Start arrays + nsl regions
+/// Start sl + refresh clock regions
+/// Check for clocks started
+/// If not, error
+/// Clear force align
+/// Clear flush mode
+/// Drop the chiplet fence to allow PowerBus traffic
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_cache_startclocks.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+#define STEP_EX_START_CLOCKS_NSL 0x1
+#define STEP_EX_START_CLOCKS_SL 0x2
+#define STEP_EX_START_CLOCKS_RUNNING 0x3
+#define STEP_EX_START_CLOCKS_SUCCESS 0x4
+
+
+//------------------------------------------------------------------------------
+// Procedure: Quad Clock Start
+//------------------------------------------------------------------------------
+
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_cache_startclocks(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ FAPI_INF("<p9_hcd_cache_startclocks>: \
+ P8 Start EX-Clocks started");
+
+ // Drop the Pervasive THOLD
+ // PM Exit States: WINKLE_EXIT_DROP_PERV_THOLD
+ // = sti EX_PMGP0_AND_0x100F0101,P0, ~(BIT(4))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<4>()));
+
+ FAPI_DBG("Enabling L3 EDRAM/LCO setup");
+ // - l3_setup L3_SETUP_ACTION_ENABLE, L3_SETUP_UNIT_L3_EDRAM
+
+ // Drop perv fence GP0.63 multicast scomreg write
+ // = sti GENERIC_GP0_AND_0x00000004, P0, ~BIT(63)
+ FAPI_TRY(putScom(i_target, GENERIC_GP0_AND_0x00000004,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<63>()));
+
+ // Reset abstclk_muxsel, synclk_muxsel (io_clk_sel)
+ // = sti GENERIC_GP0_AND_0x00000004, P0, ~BITS(0,2)
+ FAPI_TRY(putScom(i_target, GENERIC_GP0_AND_0x00000004,
+ fapi2:buffer<uint64_t>().flush<1>().insertFromRight<0,2>(0x0)));
+
+ // Set ABIST_MODE_DC for core chiplets (core recovery)
+ // = sti GENERIC_GP0_OR_0x00000005, P0, BIT(11)|BIT(13)
+ FAPI_TRY(putScom(i_target, GENERIC_GP0_OR_0x00000005,
+ fapi2:buffer<uint64_t>().setBit<11>().setBit<13>()));
+
+ // set fabric node/chip ID values (read from nest chiplet)
+ // read from nest chiplet
+ // - lpcs P1, NEST_CHIPLET_0x02000000
+ // - ldandi D0, NEST_GP0_0x02000000, P1, BITS(40, 6)
+ // = std D0, GENERIC_GP0_OR_0x00000005, P0
+ //FAPI_TRY(putScom(i_target, GENERIC_GP0_OR_0x00000005, data));
+
+ // Write ClockControl, Scan Region Register,
+ // set all bits to zero prior clock start
+ // = sti GENERIC_CLK_SCANSEL_0x00030007, P0, 0x0000000000000000
+ FAPI_TRY(putScom(i_target, GENERIC_CLK_SCANSEL_0x00030007, 0x0));
+
+ // Write ClockControl, Clock Region Register, Clock Start command
+ // (arrays + nsl only, not refresh clock region) EX Chiplet
+ // = sti GENERIC_CLK_REGION_0x00030006, P0, 0x4FF0060000000000
+ FAPI_TRY(putScom(i_target, GENERIC_CLK_REGION_0x00030006,
+ fapi2:buffer<uint64_t>(0x4FF0060000000000)));
+ // - updatestep STEP_EX_START_CLOCKS_NSL, D0, P1
+
+ // Write ClockControl, Clock Region Register, Clock Start command
+ // (sl + refresh clock region) EX Chiplet
+ // = sti GENERIC_CLK_REGION_0x00030006, P0, 0x4FF00E0000000000
+ FAPI_TRY(putScom(i_target, GENERIC_CLK_REGION_0x00030006,
+ fapi2:buffer<uint64_t>(0x4FF00E0000000000)));
+ // - updatestep STEP_EX_START_CLOCKS_SL, D0, P1
+
+ // Read Clock Status Register (EX chiplet)
+ // check for bits 27:29 eq. zero, no tholds on
+ // 27 ROX CLOCK_STATUS_DPLL_FUNC_SL status of dpll_func_sl_thold
+ // 28 ROX CLOCK_STATUS_DPLL_FUNC_NSL status of dpll_func_nsl_thold
+ // output not used
+ // 29 ROX CLOCK_STATUS_DPLL_ARY_NSL status of dpll_ary_nsl_thold
+ // output not used
+
+ // Needed to resolve SLW reading using a multicast group
+ // Get P1 setup for the chiplets to be targeted.
+ // - setp1_mcreadand D0
+
+ // = ld D0, GENERIC_CLK_STATUS_0x00030008, P1
+ FAPI_TRY(getScom(i_target, GENERIC_CLK_STATUS_0x00030008, data));
+ // - xori D0, D0, 0x00000003FFFFFFFF
+ // - branz D0, error_clock_start
+
+ FAPI_DBG("<p9_hcd_cache_startclocks>: \
+ EX clock running now");
+ // - updatestep STEP_EX_START_CLOCKS_RUNNING, D0, P1
+
+ // Read the Global Checkstop FIR of dedicated EX chiplet
+ // - setp1_mcreador D0
+ // = ld D0, GENERIC_XSTOP_0x00040000, P1
+ FAPI_TRY(getScom(i_target, GENERIC_XSTOP_0x00040000, data));
+ // - branz D0, error_checkstop_fir
+
+ FAPI_DBG("<p9_hcd_cache_startclocks>: \
+ All checkstop FIRs on initialized EX are zero");
+
+ // Clear force_align in all Chiplet GP0
+ // = sti GENERIC_GP0_AND_0x00000004, P0, ~BIT(3)
+ FAPI_TRY(putScom(i_target, GENERIC_GP0_AND_0x00000004,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<3>()));
+
+ // Clear flushmode_inhibit in Chiplet GP0
+ // Can't do this on Murano & Venice DD1.x due to a logic bug in L3 HW250462
+ // - lpcs P1, PCBMS_DEVICE_ID_0x000F000F
+ // - ldandi D0, PCBMS_DEVICE_ID_0x000F000F, P1, CFAM_CHIP_ID_MAJOR_EC_MASK
+ // - cmpibraeq D0, 1f, CFAM_CHIP_ID_MAJOR_EC_1
+ // = sti GENERIC_GP0_AND_0x00000004, P0, ~BIT(2)
+ FAPI_TRY(putScom(i_target, GENERIC_GP0_AND_0x00000004,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<2>()));
+ // - 1:
+
+ // Clear core2cache and cache2core fences. Necessary for Sleep,
+ // redundant (already clear) but not harmful for IPL/Winkle
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(20)|BIT(21))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().insertFromRight<20,2>(0x0)));
+
+ // Disable PM and DPLL override
+ FAPI_INF("<p9_hcd_cache_startclocks>: \
+ Disable PM and DPLL override");
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(0)|BIT(3))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().insertFromRight<0,4>(0x6)));
+
+ // PM Exit States: WINKLE_EXIT_WAIT_ON_OHA
+ // Drop fence GP3.18 to unfence the chiplet
+ // CMO-20130516: First clear the pbus purge request bit(14) from AISS
+ // - setp1_mcreador D0
+ // = ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // = andi D0, D0, ~BIT(1)
+ // = std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ FAPI_TRY(getScom(i_target, EX_OHA_MODE_REG_RWx1002000D, data));
+ data.clearBit<1>();
+ FAPI_TRY(putScom(i_target, EX_OHA_MODE_REG_RWx1002000D, data));
+ // = ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // = andi D0, D0, ~BIT(14)
+ // = std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+ FAPI_TRY(getScom(i_target, EX_OHA_AISS_IO_REG_0x10020014, data));
+ data.clearBit<14>();
+ FAPI_TRY(putScom(i_target, EX_OHA_AISS_IO_REG_0x10020014, data));
+ // = ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // = ori D0, D0, BIT(1)
+ // = std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ FAPI_TRY(getScom(i_target, EX_OHA_MODE_REG_RWx1002000D, data));
+ data.setBit<1>();
+ FAPI_TRY(putScom(i_target, EX_OHA_MODE_REG_RWx1002000D, data));
+ // Now drop pb fence bit(18)
+ // = sti GENERIC_GP3_AND_0x000F0013,P0, ~BIT(18)
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_AND_0x000F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<18>()));
+
+ // Drop fence GP3.26 to allow PCB operations to the chiplet
+ // = sti GENERIC_GP3_AND_0x000F0013,P0, ~BIT(26)
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_AND_0x000F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<26>()));
+ // - updatestep STEP_EX_START_CLOCKS_SUCCESS, D0, P1
+ FAPI_INF("<p9_hcd_cache_startclocks>: \
+ Exiting procedure successfully");
+
+ // - ifidle D0, 1f
+ //Not idle Check secure mode
+ // - ifbitclrscom D1, D1, OTPC_M_SECURITY_SWITCH_0x00010005, P1, 1, 1f
+ //Trusted boot is set, set core trusted boot.
+ // = sti EX_TRUSTED_BOOT_EN_0x10013C03, P0, BIT(0)
+ FAPI_TRY(putScom(i_target, GENERIC_GP3_AND_0x000F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<0>()));
+ // - 1:
+
+//------------------------------------------------------------------------------
+// ERROR -- Clocks failed to start
+//------------------------------------------------------------------------------
+error_clock_start:
+ FAPI_ERR("<p9_hcd_cache_startclocks>: \
+ Clock Start Error on EX detected");
+ // - reqhalt RC_SBE_EX_STARTCLOCKS_CLOCKS_NOT_STARTED
+
+//------------------------------------------------------------------------------
+// ERROR -- Checkstop detected
+//------------------------------------------------------------------------------
+error_checkstop_fir:
+ FAPI_ERR("<p9_hcd_cache_startclocks>: \
+ Checkstop FIR on initialized EX is not zero, \
+ VITAL register was updated");
+ // - reqhalt RC_SBE_EX_STARTCLOCKS_CHIP_XSTOPPED
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
+
+
diff --git a/src/ppe/hwp/cache/p9_hcd_cache_startclocks.H b/src/ppe/hwp/cache/p9_hcd_cache_startclocks.H
new file mode 100644
index 0000000..a6aa1d6
--- /dev/null
+++ b/src/ppe/hwp/cache/p9_hcd_cache_startclocks.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/cache/p9_hcd_cache_startclocks.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_cache_startclocks.H
+/// @brief Quad Clock Start
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Sangeetha T S <sangeet2@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CACHE_STARTCLOCKS_H__
+#define __P9_HCD_CACHE_STARTCLOCKS_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_cache_startclocks_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_cache_startclocks_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>&);
+
+/// @brief Quad Clock Start
+///
+/// @param [in] i_target TARGET_TYPE_EX target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_cache_startclocks(
+ const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CACHE_STARTCLOCKS_H__
diff --git a/src/ppe/hwp/core/Makefile b/src/ppe/hwp/core/Makefile
new file mode 100644
index 0000000..9842d1f
--- /dev/null
+++ b/src/ppe/hwp/core/Makefile
@@ -0,0 +1,54 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/core/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# This Makefile compiles all of the core hardware procedure code. See the
+# "corehcdfiles.mk" file in this directory.
+
+#all generated files from this makefile will end up in obj/cache
+export SUB_OBJDIR = /core
+
+include img_defs.mk
+include corehcdfiles.mk
+
+
+OBJS := $(addprefix $(OBJDIR)/, $(CACHE_OBJECTS))
+
+libcore.a: core
+ $(AR) crs $(OBJDIR)/libcore.a $(OBJDIR)/*.o
+
+.PHONY: clean core
+core: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/hwp/core/corehcdfiles.mk b/src/ppe/hwp/core/corehcdfiles.mk
new file mode 100644
index 0000000..364de0c
--- /dev/null
+++ b/src/ppe/hwp/core/corehcdfiles.mk
@@ -0,0 +1,65 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/core/corehcdfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file corehcdfiles.mk
+#
+# @brief mk for including core hcode object files
+#
+# @page ChangeLogs Change Logs
+# @section corehcdfiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+CACHE-CPP-SOURCES += p9_hcd_core_arrayinit.C
+CACHE-CPP-SOURCES += p9_hcd_core_chiplet_init.C
+CACHE-CPP-SOURCES += p9_hcd_core_chiplet_reset.C
+CACHE-CPP-SOURCES += p9_hcd_core_gptr_time_initf.C
+CACHE-CPP-SOURCES += p9_hcd_core_initf.C
+CACHE-CPP-SOURCES += p9_hcd_core_occ_runtime_scom.C
+CACHE-CPP-SOURCES += p9_hcd_core_pcb_arb.C
+CACHE-CPP-SOURCES += p9_hcd_core_poweron.C
+CACHE-CPP-SOURCES += p9_hcd_core_ras_runtime_scom.C
+CACHE-CPP-SOURCES += p9_hcd_core_repair_initf.C
+CACHE-CPP-SOURCES += p9_hcd_core_runinit.C
+CACHE-CPP-SOURCES += p9_hcd_core_scomcust.C
+CACHE-CPP-SOURCES += p9_hcd_core_scominit.C
+CACHE-CPP-SOURCES += p9_hcd_core_startclocks.C
+
+CACHE-C-SOURCES +=
+CACHE-S-SOURCES +=
+
+CACHE_OBJECTS += $(CACHE-CPP-SOURCES:.C=.o)
+CACHE_OBJECTS += $(CACHE-C-SOURCES:.c=.o)
+CACHE_OBJECTS += $(CACHE-S-SOURCES:.S=.o)
+
diff --git a/src/ppe/hwp/core/p9_hcd_core.H b/src/ppe/hwp/core/p9_hcd_core.H
new file mode 100644
index 0000000..a96280f
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core.H
@@ -0,0 +1,54 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core.H
+/// @brief Core Chiplet Procedure Includes
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_H__
+#define __P9_HCD_CORE_H__
+
+#include <p9_hcd_core_arrayinit.H>
+#include <p9_hcd_core_chiplet_init.H>
+#include <p9_hcd_core_chiplet_reset.H>
+#include <p9_hcd_core_gptr_time_initf.H>
+#include <p9_hcd_core_initf.H>
+#include <p9_hcd_core_occ_runtime_scom.H>
+#include <p9_hcd_core_pcb_arb.H>
+#include <p9_hcd_core_poweron.H>
+#include <p9_hcd_core_ras_runtime_scom.H>
+#include <p9_hcd_core_repair_initf.H>
+#include <p9_hcd_core_runinit.H>
+#include <p9_hcd_core_scomcust.H>
+#include <p9_hcd_core_scominit.H>
+#include <p9_hcd_core_startclocks.H>
+
+#endif // __P9_HCD_CORE_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_arrayinit.C b/src/ppe/hwp/core/p9_hcd_core_arrayinit.C
new file mode 100644
index 0000000..58c6ecc
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_arrayinit.C
@@ -0,0 +1,156 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_arrayinit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_arrayinit.C
+/// @brief Core Initialize arrays
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Use ABIST engine to zero out all arrays
+/// Upon completion, scan0 flush all rings except Vital,Repair,GPTR,and TIME
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_arrayinit.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure: Core Initialize arrays
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_arrayinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ // Procedure Prereq : P0 is pointing to the targeted EX chiplet
+ // submodules:
+ // seeprom_array_init_module
+ // ex_scan0
+
+ FAPI_INF("<p9_hcd_core_arrayinit> : \
+ *** Array Init and Scan0 Cleanup for EX Chiplets ***");
+
+ // SBE Address Base Register Setups
+ // Setup PRV_BASE_ADDR1; points to selected EX chiplet
+ // - mr P1, P0
+ FAPI_INF("<p9_hcd_core_arrayinit> : \
+ Copy selected EX info from P0 to P1");
+
+ // Step 1: Array Init for selected EX chiplet
+ // ARRAY INIT module -> see p9_sbe_tp_array_init.S
+ //
+ // At entry:
+ //
+ // P1 : The chiplet ID/Multicast Group
+ // D1 : Clock Regions for Array Init
+ //
+ // At exit:
+ //
+ // P0, D0, D1, CTR : destroyed
+ // P1, A0, A1 : maintained
+ //
+ FAPI_INF("<p9_hcd_core_arrayinit> : \
+ Calling Array Init Subroutine");
+
+ // >>> Sleep
+ // - li D1, SCAN_CLK_CORE_ONLY
+
+ // Execute the array init
+ // - bsr seeprom_array_init_module
+
+ // Restore P0 with selected EX chiplet info
+ // - mr P0, P1
+ FAPI_INF("<p9_hcd_core_arrayinit> : \
+ Copy selected EX info back from P1 to P0");
+
+ // Step 2: Scan0 for selected EX chiplet except PRV, GPTR, TIME and DPLL
+ FAPI_INF("<p9_hcd_core_arrayinit> : \
+ Calling Scan0 Subroutine");
+
+ // taken from p9_sbe_ex_chiplet_init
+
+ // >>> Sleep scan flush - core only
+
+ // Hook to bypass in Sim
+ // - hooki 0, 0xFF04
+ // - ifslwcntlbitset P9_SLW_SKIP_FLUSH,2f
+
+ FAPI_DBG("EX ArrayInit: Scan0 Module executed: \
+ Scan all core chains except GPTR and TIME");
+
+ // Each scan0 will rotate the ring 8191 latches (2**13 - 1) and the
+ // the longest ring is defined by P9_SCAN0_FUNC_REPEAT. When the design
+ // ALWAYS has all stumps less than 8191, the repeat (eg .rept) can be
+ // removed.
+ // Implementation note: this is not done in a loop (or included in the
+ // ex_scan0_module itself) as the D0 and D1 registers are used in
+ // ex_scan0_module and there is no convenient place to temporaily store
+ // the 2-64b values values. Argueably, PIBMEM could be used for this
+ // but was not utilized.
+
+ // - .rept P9_SCAN0_FUNC_REPEAT
+ // - ex_scan0 SCAN_CORE_ALL_BUT_GPTRTIMEREP, SCAN_CLK_CORE_ONLY
+ // - .endr
+ // - 2:
+
+ FAPI_INF("<p9_hcd_core_arrayinit> : \
+ *** End of Procedure ***");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+clean_up:
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_arrayinit.H b/src/ppe/hwp/core/p9_hcd_core_arrayinit.H
new file mode 100644
index 0000000..b0eeb5e
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_arrayinit.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_arrayinit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_arrayinit.H
+/// @brief Core Initialize arrays
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CORE_ARRAYINIT_H__
+#define __P9_HCD_CORE_ARRAYINIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_arrayinit_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_arrayinit_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+/// @brief Core Initialize arrays
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_arrayinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_ARRAYINIT_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_chiplet_init.C b/src/ppe/hwp/core/p9_hcd_core_chiplet_init.C
new file mode 100644
index 0000000..3d3763a
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_chiplet_init.C
@@ -0,0 +1,136 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_chiplet_init.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_chiplet_init.C
+/// @brief Core Flush/Initialize
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Switch the core glitchless mux to allow DPLL clocks on the clock grid
+/// Scan0 flush all chiplet rings except VITAL, GPTR and TIME
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_chiplet_init.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+//#define SIM_PLL
+//#define SIM_SPEEDUP
+////#define SCAN0_DISABLE
+//#define STEP_CHIPLET_INIT_0 0x0 // Resetting DPLL
+//#define STEP_CHIPLET_INIT_1 0x1 // Core+ECO glmux switch (IPL/Winkle)
+//#define STEP_CHIPLET_INIT_2 0x2 // Core glmux switch (Sleep)
+//#define STEP_CHIPLET_INIT_3 0x3 // Before Func flush for IPL/Winkle
+//#define STEP_CHIPLET_INIT_4 0x4 // After Func flush for IPL/Winkle
+//#define STEP_CHIPLET_INIT_5 0x5 // After Func flush for IPL/Winkle
+//#define STEP_CHIPLET_INIT_6 0x6 // Before Core GPTR flush for Sleep
+//#define STEP_CHIPLET_INIT_7 0x7 // After Core GPTR flush for Sleep
+//#define STEP_CHIPLET_INIT_8 0x8 // Before Core Func flush for Sleep
+//#define STEP_CHIPLET_INIT_9 0x9 // After Core Func flush for Sleep
+//#define STEP_CHIPLET_INIT_A 0xA // Before Core Func flush for Sleep
+//#define STEP_CHIPLET_INIT_B 0xB // After Core Func flush for Sleep
+//#define PORE_REFCLK_CYCLES 1 // \todo need real value for hdw
+//#define DPLL_LOCK_DELAY 8192*PORE_REFCLK_CYCLES
+
+//------------------------------------------------------------------------------
+// Procedure: Core Flush/Initialize
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_chiplet_init(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ // Procedure Prereq:
+ // p9_sbe_ex_chiplet_reset, p9_sbe_ex_dpll_initf, p9_sbe_ex_pll_initf
+
+ FAPI_INF("<p9_hcd_cache_chiplet_init>: Entering procedure");
+
+ // Look for PSCOM error on any chip, fail if we find one
+ // scan0 flush all configured chiplet rings except EX DPLL
+ // call ex_scan0_module( )
+
+ // >>> Sleep GPTR flush - core only
+ // This is done after the swing of the Glitchless Mux above
+ // Hook to bypass in sim while providing a trace
+
+ // Hook to bypass in sim while providing a trace
+ // - hooki 0, 0xFF04
+ // - ifslwcntlbitset P9_SLW_SKIP_FLUSH,1f
+
+ FAPI_DBG("EX Reset: Scan0 Module executed for Sleep: \
+ Scan the all but GPTR/TIME/REP rings");
+
+ // Each scan0 will rotate the ring 8191 latches (2**13 - 1) and the
+ // the longest ring is defined by P9_SCAN0_FUNC_REPEAT. When the design
+ // ALWAYS has all stumps less than 8191, the repeat (eg .rept) can be
+ // removed.
+ // Implementation note: this is not done in a loop (or included in the
+ // ex_scan0_module itself) as the D0 and D1 registers are used in
+ // ex_scan0_module and there is no convenient place to temporaily store
+ // the 2-64b values values. Argueably, PIBMEM could be used for this
+ // but was not utilized.
+ // - updatestep STEP_CHIPLET_INIT_A, D0, P1
+ // - .rept P9_SCAN0_FUNC_REPEAT
+ // - ex_scan0 SCAN_CORE_ALL_BUT_GPTRTIMEREP, SCAN_CLK_CORE_ONLY
+ // - .endr
+ // - updatestep STEP_CHIPLET_INIT_B, D0, P1
+ // - 1:
+
+ FAPI_INF("<p9_hcd_cache_chiplet_init>: Exiting procedure");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_chiplet_init.H b/src/ppe/hwp/core/p9_hcd_core_chiplet_init.H
new file mode 100644
index 0000000..be081ef
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_chiplet_init.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_chiplet_init.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_chiplet_init.H
+/// @brief Core Flush/Initialize
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_CHIPLET_INIT_H__
+#define __P9_HCD_CORE_CHIPLET_INIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_chiplet_init_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_chiplet_init_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief Core Flush/Initialize
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_chiplet_init(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_CHIPLET_INIT_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_chiplet_reset.C b/src/ppe/hwp/core/p9_hcd_core_chiplet_reset.C
new file mode 100644
index 0000000..1874f0f
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_chiplet_reset.C
@@ -0,0 +1,196 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_chiplet_reset.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_chiplet_reset.C
+/// @brief Core Chiplet Reset
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Reset chiplet logic
+/// (TODO: check with Andreas on the effect of a CME based Endpoint reset
+/// relative to the CorePPM path)
+/// Scan0 flush entire core chiplet
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_chiplet_reset.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions
+//------------------------------------------------------------------------------
+
+// GP3 Bits
+// 1 - PCB_EP_RESET
+// 2 - GLMMUX Reset
+// 3 - PLL_TEST Enable
+// 4 - PLLRST - PLL Reset
+// 5 - PLL Bypass
+// 11 - D_MODE for Vital
+// 13 - MPW2 for Vital
+// 14 - PMW1 for Vital
+// 18 - FENCE_EN for chiplet
+// 22 - Resonant Clock disable
+// 23:24 - Glitchless Mux Sel
+// 25: - ?? (set because System Pervasive flow does this)
+// Background: system pervasive as the following setting in their tests:
+// 7C1623C000000000
+// Bits set:
+// 1, 2, 3, 4, 5, 11, 13, 14, 18, 22, 23, 24, 25
+//#define GP3_INIT_VECTOR (BITS(1,5)|BIT(11)|BIT(13)|BIT(14)|BIT(18)|BIT(22)|BIT(23)|BIT(24)|BIT(25))
+
+// hang counter inits
+//#define HANG_P1_INIT 0x0400000000000000
+//#define PCB_SL_ERROR_REG_RESET 0xFFFFFFFFFFFFFFFF
+//#define STEP_CHIPLET_RESET_1 0x1 // After start of vital clocks
+//#define STEP_CHIPLET_RESET_2 0x2 // After fence drop
+//#define STEP_CHIPLET_RESET_3 0x3 // Before GPTR flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_4 0x4 // After GPTR flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_5 0x5 // Before Func flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_6 0x6 // After Func flush for IPL/Winkle
+//#define STEP_CHIPLET_RESET_7 0x7 // Before GPTR flush for Sleep
+//#define STEP_CHIPLET_RESET_8 0x8 // After GPTR flush for Sleep
+
+//------------------------------------------------------------------------------
+// Procedure: Core Chiplet Reset
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_chiplet_reset(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ /////////////////////////////////////////////////////////////////
+ // repeat some init steps of chiplet_init
+ /////////////////////////////////////////////////////////////////
+
+ // If there is a unused, powered-off EX chiplet which needs to be
+ // configured in the following steps to setup the PCB endpoint.
+
+ // Skip the PCB endpoint config steps for sleep so that fences don't
+ // get dropped (eg by dropping chiplet_enable (GP3(0)).
+
+ // The following is performed for both IPL/Winkle and Sleep
+
+ // Note: These are executed for sleep as well as these fences will have
+ // already been dropped
+
+ FAPI_DBG("<p9_hcd_core_chiplet_reset>: \
+ Remove pervasive ECO fence;");
+ // ECO Fence in 22
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(22))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<22>()));
+
+ FAPI_DBG("<p9_hcd_core_chiplet_reset>: \
+ Remove winkle mode before scan0 on EX chiplets is executed");
+ // PM Exit States: WINKLE_EXIT_DROP_ELEC_FENCE
+
+ FAPI_DBG("<p9_hcd_core_chiplet_reset>: \
+ Remove logical pervasive/pcbs-pm fence");
+ // = sti EX_PMGP0_AND_0x100F0101,P0,~(BIT(39))
+ FAPI_TRY(putScom(i_target, EX_PMGP0_AND_0x100F0101,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<39>()));
+
+ FAPI_DBG("<p9_hcd_core_chiplet_reset>: \
+ Remove PB Winkle Electrical Fence GP3(27)");
+ // = sti EX_GP3_AND_0x100F0013,P0,~(BIT(27))
+ FAPI_TRY(putScom(i_target, EX_GP3_AND_0x100F0013,
+ fapi2:buffer<uint64_t>().flush<1>().clearBit<27>()));
+
+ FAPI_DBG("<p9_hcd_core_chiplet_reset>: \
+ Configuring chiplet hang counters") ;
+ // = sti EX_HANG_P1_0x100F0021,P0,HANG_P1_INIT
+ FAPI_TRY(putScom(i_target, EX_HANG_P1_0x100F0021, HANG_P1_INIT));
+ // - updatestep STEP_CHIPLET_RESET_2, D0, P1
+
+ //////////////////////////////////////////////////////////////
+ // perform scan0 module for pervasive chiplet (GPTR_TIME_REPR)
+ //////////////////////////////////////////////////////////////
+
+ // For the Sleep case, the DPLL is running but the core mesh is force to
+ // the "constant" or "off" state. In order to flush or scan, the mesh must
+ // be reenabled via the Glitchless Mux.
+
+ // Read-modify-write (vs sti AND and sti OR) is done so that glitchless
+ // mux change field change is atomic (eg 1 store)
+ // - setp1_mcreadand D1
+ // = ld D1,EX_PMGP0_0x100F0100,P1
+ FAPI_TRY(fapi2::getScom(i_target, EX_PMGP0_0x100F0100, data));
+
+ // Set the core glitchless mux to use the primary input (b00).
+ // Upon Sleep entry, hardware will switch the glitchless mux to 0b10
+ // (constant). EX PM GP0 bits 32-33)
+ FAPI_INF("EX Chiplet -> Set glitchless mux select for core domain to 00 ")
+ // = andi D1, D1, ~(BIT(32)|BIT(33))
+
+ // Store the final result to the hardware
+ // = std D1,EX_PMGP0_0x100F0100,P0
+ data.insertFromRight<32,2>(0x0);
+ FAPI_TRY(putScom(i_target, EX_PMGP0_0x100F0100, data));
+ // - updatestep STEP_CHIPLET_RESET_7, D0, P1
+
+ // Hook to bypass in sim while providing a trace
+ // - hooki 0, 0xFF03
+ // - ifslwcntlbitset P9_SLW_SKIP_FLUSH,1f
+
+ FAPI_DBG("EX Reset: Scan0 Module executed for Sleep: \
+ Scan the GPTR/TIME/REP rings");
+
+ // - .rept P9_SCAN0_GPTR_REPEAT
+ // - ex_scan0 SCAN_CORE_GPTR_TIME_REP, SCAN_CLK_CORE_ONLY
+ // - .endr
+ // - 1:
+ // - updatestep STEP_CHIPLET_RESET_8, D0, P1
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_chiplet_reset.H b/src/ppe/hwp/core/p9_hcd_core_chiplet_reset.H
new file mode 100644
index 0000000..6d95c93
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_chiplet_reset.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_chiplet_reset.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_chiplet_reset.H
+/// @brief Core Chiplet Reset
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_CHIPLET_RESET_H__
+#define __P9_HCD_CORE_CHIPLET_RESET_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_chiplet_reset_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_chiplet_reset_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief Core Chiplet Reset
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_chiplet_reset(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_CHIPLET_RESET_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.C b/src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.C
new file mode 100644
index 0000000..e6b54ed
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.C
@@ -0,0 +1,112 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_gptr_time_initf.C
+/// @brief Load Core GPTR and Time rings
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// initfiles in procedure defined on VBU ENGD wiki (TODO add link)
+/// to produce #G VPD contents
+/// Check for the presence of core override GPTR ring from image
+/// (this is new for P9)
+/// if found, apply; if not, apply core GPTR from image
+/// Check for the presence of core override TIME ring from image;
+/// if found, apply; if not, apply core base TIME from image
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_gptr_time_initf.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Procedure: Load Core GPTR and Time rings
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_gptr_time_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ // >>> For sleep, bypass the pull back of the scan ratio
+ // - ifsleep D0, 1f
+ // Set EX scan ratio to 1:1 as EX is still at refclock
+ FAPI_INF("<p9_hcd_core_gptr_time_initf> : \
+ Set EX scan ratio to 1:1 ...")
+ // = sti EX_OPCG_CNTL0_0x10030002, P0, 0x0
+ FAPI_TRY(fapi2::putScom(i_target, EX_OPCG_CNTL0_0x10030002, 0x0));
+ // - 1:
+
+ // scan ring content shared among all chiplets
+ FAPI_DBG("Scanning EX core GPTR rings...")
+ // - load_ring ex_gptr_core skipoverride=1
+ // - load_ring ex_gptr_l2 skipoverride=1
+
+ // scan chiplet specific ring content
+ FAPI_DBG("Scanning EX core TIME rings...")
+ // - load_ring_vec_ex ex_time_core
+
+ // Set EX scan ratio back to 8:1
+ FAPI_INF("<p9_hcd_core_gptr_time_initf> : \
+ Set EX scan ratio to 8:1 ...")
+ //Inputs: A1 and P0 and D0, destroys D0 & D1
+ // - .pibmem_port (PORE_SPACE_PIBMEM & 0xf)
+ // - lpcs P1, PIBMEM0_0x00080000
+ // - ld D0, ex_scan_ratio_override, P1
+ // - bsr set_scan_ratio_d0
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.H b/src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.H
new file mode 100644
index 0000000..881f493
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_gptr_time_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_gptr_time_initf.H
+/// @brief Load Core GPTR and Time rings
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_GPTR_TIME_INIT_H__
+#define __P9_HCD_CORE_GPTR_TIME_INIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_gptr_time_initf_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_gptr_time_initf_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+/// @brief Load Core GPTR and Time rings
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+/// @attr
+/// @attritem ATTR_CORE_GPTR_TIME_RING - EC target, uint32
+/// pointer to RS4 content<br>
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_gptr_time_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_GPTR_TIME_INIT_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_initf.C b/src/ppe/hwp/core/p9_hcd_core_initf.C
new file mode 100644
index 0000000..fad2046
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_initf.C
@@ -0,0 +1,95 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_initf.C
+/// @brief Core scan init
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Initfiles in procedure defined on VBU ENGD wiki (TODO add link)
+/// Check for the presence of core FUNC override rings from image;
+/// if found, apply; if not, apply core base FUNC rings from image
+/// Note: FASTINIT ring (eg CMSK ring) is setup at this point to limit the
+/// stumps that participate in FUNC ring scanning (this is new for P9).
+/// (TODO to make sure the image build support is in place)
+/// Note : if in fused mode, both core rings will be initialized to the same
+/// values via multicast scans
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_initf.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Procedure: Core scan init
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ // - load_ring ex_func_core conditional_override=1
+ // - load_ring ex_regf_core conditional_override=1
+ // - load_ring ex_fary_l2 conditional_override=1
+ // - load_ring ex_lbst_core conditional_override=1
+ // - load_ring ex_abfa_core conditional_override=1
+ // - load_ring ex_cmsk_core conditional_override=1
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_initf.H b/src/ppe/hwp/core/p9_hcd_core_initf.H
new file mode 100644
index 0000000..7a9682d
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_initf.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_initf.H
+/// @brief Core scan init
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_INITF_H__
+#define __P9_HCD_CORE_INITF_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_initf_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_initf_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief Core scan init
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+/// @attr
+/// @attritem ATTR_CORE_FUNC_RING - EC target, uint32
+/// pointer to RS4 content<br>
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_INITF_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.C b/src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.C
new file mode 100644
index 0000000..ccc4c0e
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.C
@@ -0,0 +1,94 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_occ_runtime_scom.C
+/// @brief Core OCC runtime SCOMS
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Run-time updates from OCC code that are put somewhere TBD
+/// (TODO . revisit with OCC FW team)
+/// OCC FW sets up value in the TBD SCOM section
+/// This was not leverage in P8 with the demise of CPMs
+/// Placeholder at this point
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_occ_runtime_scom.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+#define host_runtime_scom 0
+
+//-----------------------------------------------------------------------------
+// Procedure: Core OCC runtime SCOMS
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_occ_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ // Run the SCOM sequence if the SCOM procedure is defined
+ // - la A0, occ_runtime_scom
+ // - ld D0, 0, A0
+ // - braz D0, 1f
+ //FAPI_INF("Launching OCC Runtime SCOM routine")
+ // - bsrd D0
+ // - 1:
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.H b/src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.H
new file mode 100644
index 0000000..0221370
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_occ_runtime_scom.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_occ_runtime_scom.H
+/// @brief Core OCC runtime SCOMS
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CORE_OCC_RUNTIME_SCOM_H__
+#define __P9_HCD_CORE_OCC_RUNTIME_SCOM_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_occ_runtime_scom_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_occ_runtime_scom_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief Core OCC runtime SCOMS
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+///
+/// @attr
+/// @attritem ATTR_CORE_OCC_SCOM_LOC - EC target, uint32
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_occ_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_OCC_RUNTIME_SCOM_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_pcb_arb.C b/src/ppe/hwp/core/p9_hcd_core_pcb_arb.C
new file mode 100644
index 0000000..4dbf22e
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_pcb_arb.C
@@ -0,0 +1,83 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_pcb_arb.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_pcb_arb.C
+/// @brief Core Chiplet PCB Arbitration
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// If CME,
+/// 1.Request PCB Mux, via write to PCB_MUX_REQ_C0 @ CCSCR_OR
+/// - setBit(5) @ CME_LOCAL_CORE_STOP_CONTROL_REGISTER_OR_0510
+/// 2.Poll for PCB Mux grant, via read from
+/// Polled Timeout: ns
+/// - getBit() @
+/// Else (SBE),
+/// Nop (as the CME is not running in bringing up the first Core)
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_pcb_arb.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions: Core Chiplet PCB Arbitration
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_pcb_arb(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_pcb_arb.H b/src/ppe/hwp/core/p9_hcd_core_pcb_arb.H
new file mode 100644
index 0000000..4029514
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_pcb_arb.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_pcb_arb.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_pcb_arb.H
+/// @brief Core Chiplet PCB Arbitration
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CORE_PCB_ARB_H__
+#define __P9_HCD_CORE_PCB_ARB_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_pcb_arb_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_pcb_arb_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+/// @brief Core Chiplet PCB Arbitration
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_pcb_arb(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_PCB_ARB_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_poweron.C b/src/ppe/hwp/core/p9_hcd_core_poweron.C
new file mode 100644
index 0000000..e215c27
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_poweron.C
@@ -0,0 +1,84 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_poweron.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_poweron.C
+/// @brief Core Chiplet Power-on
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// 1.Command the core PFET controller to power-on, via putscom to CPPM
+/// -
+/// 2.Check for valid power on completion, via getscom from CPPM
+/// Polled Timeout: 100us
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_poweron.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Procedure: Core Chiplet Power-on
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_poweron(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
+ const uint32_t i_operation)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_poweron.H b/src/ppe/hwp/core/p9_hcd_core_poweron.H
new file mode 100644
index 0000000..970d1e4
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_poweron.H
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_poweron.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_poweron.H
+/// @brief Core Chiplet Power-on
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CORE_POWERON_H__
+#define __P9_HCD_CORE_POWERON_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_poweron_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_poweron_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&,
+ const uint32_t);
+
+
+/// @brief Core Chiplet Power-on
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+/// @param [in] i_operation ENUM(ON,OFF)
+///
+/// @attr
+/// @attritem ATTR_PFET_*
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_poweron(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
+ const uint32_t i_operation);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_POWERON_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.C b/src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.C
new file mode 100644
index 0000000..654e24e
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.C
@@ -0,0 +1,165 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_ras_runtime_scom.C
+/// @brief FSP/Host run-time SCOMS
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Run-time updates from FSP based PRD, etc that are put on the core image
+/// by STOP API calls
+/// Dynamically built pointer where a NULL is checked before execution
+/// If NULL (the SBE case), return
+/// Else call the function at the pointer;
+/// pointer is filled in by STOP image build
+/// Run-time updates from Host code that are put on the core image by
+/// STOP API calls
+/// Restore Hypervisor, Host PRD, etc. SCOMs
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_ras_runtime_scom.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+#define host_runtime_scom 0
+
+//-----------------------------------------------------------------------------
+// Procedure: FSP/Host run-time SCOMS
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_ras_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ // Run the SCOM sequence if the SCOM procedure is defined
+ // - la A0, sp_runtime_scom
+ // - ld D0, 0, A0
+ // - braz D0, 1f
+ //FAPI_INF("Launching SP Runtime SCOM routine")
+ // - bsrd D0
+ // - 1:
+ //
+
+ // Run the SCOM sequence if the SCOM procedure is defined.
+ // - la A0, host_runtime_scom
+ // - ld D1, 0, A0
+ // - braz D1, 1f
+
+ // Prep P1
+ // - setp1_mcreadand D0
+#if 0
+ // Disable the AISS to allow the override
+ // - ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // - andi D0, D0, ~(BIT(1))
+ // - std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ // Drop PSCOM fence to allow SCOM and set pm_wake-up to PC to accepts
+ // RAMs (SCOMs actually) in the IPL "Nap" state
+ // - ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // - ori D0, D0, (BIT(15))
+ // - andi D0, D0, ~(BIT(21))
+ // - std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+#endif
+ // Branch to sub_slw_runtime_scom()
+ FAPI_INF("Launching Host Runtime SCOM routine")
+ // - bsrd D1
+
+ // Prep P1
+ // - setp1_mcreadand D0
+#if 0
+ // Clear regular wake-up and restore PSCOM fence in OHA
+ // These were established in p9_sbe_ex_scominit.S
+ // - ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // - andi D0, D0, ~(BIT(15))
+ // - ori D0, D0, BIT(21)
+ // - std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+ // Enable the AISS to allow further operation
+ // - ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // - ori D0, D0, (BIT(1))
+ // - std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+#endif
+ // - bra 2f
+ // - 1:
+ // To accomodate IPL flow, where sub_slw_runtime_scom() is skipped
+ // - setp1_mcreadand D0
+#if 0
+ // Clear regular wake-up and restore PSCOM fence in OHA
+ // These were established in p9_sbe_ex_scominit.S
+ // - ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // - andi D0, D0, ~BIT(1)
+ // - std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ // - ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // - andi D0, D0, ~(BIT(15))
+ // - ori D0, D0, BIT(21)
+ // - std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+ // Enable the AISS to allow further operation
+ // - ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // - ori D0, D0, (BIT(1))
+ // - std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+#endif
+ // - 2:
+
+ // If using cv_multicast, we need to set the magic istep number here
+ // - la A0, p9_sbe_select_ex_control
+ // - ldandi D0, 0, A0, P9_CONTROL_INIT_ALL_EX
+ // - braz D0, 3f
+ FAPI_DBG("Setting istep num to magic number because cv_multicast is set")
+ // - lpcs P1, MBOX_SBEVITAL_0x0005001C
+ // - sti MBOX_SBEVITAL_0x0005001C, P1, (P9_SBE_EX_RAS_RUNTIME_SCOM_MAGIC_ISTEP_NUM << (4+32))
+ // - 3:
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.H b/src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.H
new file mode 100644
index 0000000..aca5bc2
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_ras_runtime_scom.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_ras_runtime_scom.H
+/// @brief FSP/Host run-time SCOMS
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_RAS_RUNTIME_SCOM_H__
+#define __P9_HCD_CORE_RAS_RUNTIME_SCOM_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_ras_runtime_scom_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_ras_runtime_scom_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief FSP/Host run-time SCOMS
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+//
+/// @attr
+/// @attritem ATTR_CORE_RAS_SCOM_LOC - EC target, uint32
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_ras_runtime_scom(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_RAS_RUNTIME_SCOM_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_repair_initf.C b/src/ppe/hwp/core/p9_hcd_core_repair_initf.C
new file mode 100644
index 0000000..167c84e
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_repair_initf.C
@@ -0,0 +1,89 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_repair_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_repair_initf.C
+/// @brief Load Repair ring for core
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Load core ring images from that came from MVPD into the image
+/// These rings must contain ALL chip customization data. This includes the
+/// following: Array Repair and DTS calibration settings
+/// Historically this was stored in MVPD keywords are #R, #G. Still stored
+/// in MVPD, but SBE image is customized with rings for booting cores
+/// at build time
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_repair_initf.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Procedure: Load Repair ring for core
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_repair_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ // scan chiplet specific ring content
+ //FAPI_DBG("Scanning EX core REPAIR rings...")
+ // - load_ring_vec_ex ex_repr_core
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_repair_initf.H b/src/ppe/hwp/core/p9_hcd_core_repair_initf.H
new file mode 100644
index 0000000..7c9b831
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_repair_initf.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_repair_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_repair_initf.H
+/// @brief Load Repair ring for core
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_REPAIR_INITF_H__
+#define __P9_HCD_CORE_REPAIR_INITF_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_repair_initf_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_repair_initf_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief Load Repair ring for core
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+/// @attr
+/// @attritem ATTR_CORE_REPAIR_RING - EC target, uint32
+/// pointer to RS4 content
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_repair_initf(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_REPAIR_INITF_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_runinit.C b/src/ppe/hwp/core/p9_hcd_core_runinit.C
new file mode 100644
index 0000000..eedc0fe
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_runinit.C
@@ -0,0 +1,75 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_runinit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_runinit.C
+/// @brief execute all core init procedures
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_runinit.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions:
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure:
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_runinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+
+#if 0
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_runinit.H b/src/ppe/hwp/core/p9_hcd_core_runinit.H
new file mode 100644
index 0000000..09881a8
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_runinit.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_runinit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_runinit.H
+/// @brief execute all core init procedures
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_RUNINIT_H__
+#define __P9_HCD_CORE_RUNINIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_runinit_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_runinit_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
+
+
+/// @brief Core Customization SCOMs
+///
+/// @param [in] i_target TARGET_TYPE_PROC_CHIP target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_runinit(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_RUNINIT_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_scomcust.C b/src/ppe/hwp/core/p9_hcd_core_scomcust.C
new file mode 100644
index 0000000..11a1c15
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_scomcust.C
@@ -0,0 +1,83 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_scomcust.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_scomcust.C
+/// @brief Core Customization SCOMs
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Dynamically built (and installed) routine that is inserted by the .XIP
+/// Customization. process. (New for P9) (TODO: this part of the process is
+/// a placeholder at this point)
+/// Dynamically built pointer where a NULL is checked before execution
+/// If NULL (a potential early value); return
+/// Else call the function at the pointer;
+/// pointer is filled in by XIP Customization
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_scomcust.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions: Core Customization SCOMs
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_scomcust(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_scomcust.H b/src/ppe/hwp/core/p9_hcd_core_scomcust.H
new file mode 100644
index 0000000..b9643c6
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_scomcust.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_scomcust.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_scomcust.H
+/// @brief Core Customization SCOMs
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CORE_SCOMCUST_H__
+#define __P9_HCD_CORE_SCOMCUST_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_scomcust_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_scomcust_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief Core Customization SCOMs
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_scomcust(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+} // extern C
+
+#endif // __P9_HCD_CORE_SCOMCUST_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_scominit.C b/src/ppe/hwp/core/p9_hcd_core_scominit.C
new file mode 100644
index 0000000..3d4030d
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_scominit.C
@@ -0,0 +1,160 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_scominit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_scominit.C
+/// @brief Core SCOM Inits
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Apply any coded SCOM initialization to core
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_scominit.H"
+
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Procedure: Core SCOM Inits
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_scominit(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+ fapi2::buffer<uint64_t> data;
+
+ ///////////////////
+ // Core
+ ///////////////////
+
+ // Force the hardware to think we're in special wakeup so the SCOMs will
+ // succeed to the core due to the init state of Nap. This does NOT
+ // influence the PM state machines; only the wire indicating special
+ // wake-up using the override in PMGP1
+ // Bit 6 enables/disables override; bit 8 controls the Special Wake-up
+ // = sti EX_PMGP1_OR_0x100F0105, P0, BIT(6) | BIT(8)
+ FAPI_TRY(putScom(i_target, EX_PMGP1_OR_0x100F0105,
+ fapi2:buffer<uint64_t>().insertFromRight<6,3>(0x5)));
+ // - setp1_mcreadand D0
+#if 0
+ // Disable the AISS to allow the override
+ // - ld D0, EX_OHA_MODE_REG_RWx1002000D, P1
+ // - andi D0, D0, ~(BIT(1))
+ // - std D0, EX_OHA_MODE_REG_RWx1002000D, P0
+ // Drop PSCOM fence to allow SCOM and set pm_wake-up to PC to accepts
+ // RAMs (SCOMs actually) in the IPL "Nap" state
+ // - ld D0, EX_OHA_AISS_IO_REG_0x10020014, P1
+ // - ori D0, D0, (BIT(15))
+ // - andi D0, D0, ~(BIT(21))
+ // - std D0, EX_OHA_AISS_IO_REG_0x10020014, P0
+#endif
+ //CMO-> Should prob reenable AISS here. But carefully...
+
+ // These are dropped in p9_sbe_ex_host_runtime_scom.S
+
+ ///////////////////
+ // Clock Controller
+ ///////////////////
+
+ // Set the OPCG_PAD_VALUE to be fast enough to not allow overrun by the
+ // OHA in for Deep Sleep Exit. Set for 32 cycles (2 x 16) -> 0b010
+ FAPI_INF("Setup OPCG_PAD_VALUE for Deep Sleep scanning ...")
+ // - ld D1, EX_OPCG_CNTL2_0x10030004, P1
+ // - andi D1, D1, ~(BITS(49,3))
+ // - ori D1, D1, BIT(50)
+ // - std D1, EX_OPCG_CNTL2_0x10030004, P0
+ FAPI_TRY(getScom(i_target, EX_OPCG_CNTL2_0x10030004, data));
+ data.insertFromRight<49,3>(0x2);
+ FAPI_TRY(putScom(i_target, EX_OPCG_CNTL2_0x10030004, data));
+
+ ///////////////////
+ // L2
+ ///////////////////
+
+ // set L2 inits to force single member mode if required
+ FAPI_DBG("Configuring L2 single member mode ...");
+ // - l2_single_member
+
+ // set L2 inits to disable L3 if required
+ FAPI_DBG("Configuring L3 disable ...");
+ // - l3_setup L3_SETUP_ACTION_DISABLE, L3_SETUP_UNIT_L2
+
+ ///////////////////
+ // DTS
+ ///////////////////
+
+ // As this routine get runs for IPL, Winkle and Sleep, all Digital
+ // Thermal Sensor setup is done here.
+ // For the case of Sleep where the L3 DTS is still active, the
+ // initialization is redone anyway as, while this operation is going on,
+ // the atomic lock prevents other entities (eg OCC) from accessing it.
+ // This keep the flows the same.
+
+ // - setp1_mcreadand D0
+ FAPI_INF("Initialize DTS function ...")
+
+ // Enable DTS sampling - bit 5
+ // Sample Pulse Count - bits(6:9) set to a small number for sim
+ // Enable loop 1 DTSs (20:22); loop 2 DTSs (24)
+ // = ld D1, EX_THERM_MODE_REG_0x1005000F, P1
+ // = ori D1, D1, (BIT(5)|BITS(6, 4)|BITS(20,3)|BIT(24))
+ // = std D1, EX_THERM_MODE_REG_0x1005000F, P0
+ FAPI_TRY(getScom(i_target, EX_THERM_MODE_REG_0x1005000F, data));
+ data.insertFromRight<5,5>(0x1F).insertFromRight<20,3>(0xF).setBit<24>();
+ FAPI_TRY(putScom(i_target, EX_THERM_MODE_REG_0x1005000F, data));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_scominit.H b/src/ppe/hwp/core/p9_hcd_core_scominit.H
new file mode 100644
index 0000000..9cb570a
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_scominit.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_scominit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_scominit.H
+/// @brief Core SCOM Inits
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+
+#ifndef __P9_HCD_CORE_SCOMINIT_H__
+#define __P9_HCD_CORE_SCOMINIT_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_scominit_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_scominit_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+
+/// @brief Core SCOM Inits
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_scominit(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_SCOMINIT_H__
diff --git a/src/ppe/hwp/core/p9_hcd_core_startclocks.C b/src/ppe/hwp/core/p9_hcd_core_startclocks.C
new file mode 100644
index 0000000..012f533
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_startclocks.C
@@ -0,0 +1,97 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_startclocks.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_startclocks.C
+/// @brief Core Clock Start
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+/// Drop pervasive thold
+/// Drop pervasive fence
+/// Reset abst clock muxsel, sync muxsel
+/// Clear clock controller scan register before start
+/// Start arrays + nsl regions
+/// Start sl + refresh clock regions
+/// Check for clocks started
+/// If not, error
+/// Check for core xstop (TODO: need for this (?) and then FIR structure in
+/// for P9. Note: CME can NOT read Cache FIR)
+/// If so, error
+/// Clear force align
+/// Clear flush mode
+/// Check security switch and set trusted boot en bit
+/// (TODO: still needed for P9?)
+/// Drop the core to cache logical fence
+///
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_hcd_core_startclocks.H"
+
+//-----------------------------------------------------------------------------
+// Constant Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Procedure: Core Clock Start
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_hcd_core_startclocks(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target)
+{
+
+#if 0
+
+ fapi2::buffer<uint64_t> data;
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_CLEANUP();
+ return fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+
+#endif
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
+
diff --git a/src/ppe/hwp/core/p9_hcd_core_startclocks.H b/src/ppe/hwp/core/p9_hcd_core_startclocks.H
new file mode 100644
index 0000000..38b6fbd
--- /dev/null
+++ b/src/ppe/hwp/core/p9_hcd_core_startclocks.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/core/p9_hcd_core_startclocks.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_hcd_core_startclocks.H
+/// @brief Core Clock Start
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_HCD_CORE_STARTCLOCKS_H__
+#define __P9_HCD_CORE_STARTCLOCKS_H__
+
+extern "C"
+{
+
+/// @typedef p9_hcd_core_startclocks_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_hcd_core_startclocks_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>&);
+
+/// @brief Core Clock Start
+///
+/// @param [in] i_target TARGET_TYPE_CORE target
+///
+/// @attr
+/// @attritem NONE
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_hcd_core_startclocks(
+ const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target);
+
+
+} // extern C
+
+#endif // __P9_HCD_CORE_STARTCLOCKS_H__
diff --git a/src/ppe/hwp/lib/Makefile b/src/ppe/hwp/lib/Makefile
new file mode 100644
index 0000000..360d012
--- /dev/null
+++ b/src/ppe/hwp/lib/Makefile
@@ -0,0 +1,54 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/lib/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# This Makefile compiles all of the common library hardware procedure code.
+# See the "libcommonfiles.mk" file in this directory.
+
+#all generated files from this makefile will end up in obj/lib
+export SUB_OBJDIR = /lib
+
+include img_defs.mk
+include libcommonfiles.mk
+
+
+OBJS := $(addprefix $(OBJDIR)/, $(LIB_OBJECTS))
+
+libcommon.a: lib
+ $(AR) crs $(OBJDIR)/libcommon.a $(OBJDIR)/*.o
+
+.PHONY: clean lib
+lib: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/hwp/lib/libcommonfiles.mk b/src/ppe/hwp/lib/libcommonfiles.mk
new file mode 100644
index 0000000..854d71b
--- /dev/null
+++ b/src/ppe/hwp/lib/libcommonfiles.mk
@@ -0,0 +1,53 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/lib/libcommonfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file libcommonfiles.mk
+#
+# @brief mk for including library common object files
+#
+# @page ChangeLogs Change Logs
+# @section libcommonfiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+LIB-CPP-SOURCES += p9_common_poweronoff.C
+LIB-CPP-SOURCES += p9_common_pro_epi_log.C
+
+LIB-C-SOURCES +=
+LIB-S-SOURCES +=
+
+LIB_OBJECTS += $(LIB-CPP-SOURCES:.C=.o)
+LIB_OBJECTS += $(LIB-C-SOURCES:.c=.o)
+LIB_OBJECTS += $(LIB-S-SOURCES:.S=.o)
+
diff --git a/src/ppe/hwp/lib/p9_common_poweronoff.C b/src/ppe/hwp/lib/p9_common_poweronoff.C
new file mode 100644
index 0000000..cd5e6f8
--- /dev/null
+++ b/src/ppe/hwp/lib/p9_common_poweronoff.C
@@ -0,0 +1,71 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/lib/p9_common_poweronoff.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_common_poweronoff.C
+/// @brief common procedure for power on/off
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE:CME
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_common_poweronoff.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions:
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure:
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_common_poweronoff(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ|
+ fapi2::TARGET_TYPE_CORE>& i_target,
+ int i_operation)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/lib/p9_common_poweronoff.H b/src/ppe/hwp/lib/p9_common_poweronoff.H
new file mode 100644
index 0000000..a5bd036
--- /dev/null
+++ b/src/ppe/hwp/lib/p9_common_poweronoff.H
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/lib/p9_common_poweronoff.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_common_poweronoff.H
+/// @brief common procedure for power on/off
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE:CME
+/// *HWP Level : 1
+///
+
+#ifndef __P9_COMMON_POWERONOFF_H__
+#define __P9_COMMON_POWERONOFF_H__
+
+extern "C"
+{
+
+/// @typedef p9_common_proweronoff_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_common_proweronoff_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ|
+ fapi2::TARGET_TYPE_CORE>&,
+ int);
+
+
+/// @brief common procedure for power on/off
+///
+/// @param [in] i_target TARGET_TYPE_EQ|TARGET_TYPE_CORE target
+/// @param [in] i_operation ENUM(ON,OFF)
+///
+/// @attr
+/// @attritem ATTR_PFET_TIMING - EX target, uint32
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_common_proweronoff(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ|
+ fapi2::TARGET_TYPE_CORE>& i_target,
+ int i_operation);
+
+
+} // extern C
+
+#endif // __P9_COMMON_POWERONOFF_H__
diff --git a/src/ppe/hwp/lib/p9_common_pro_epi_log.C b/src/ppe/hwp/lib/p9_common_pro_epi_log.C
new file mode 100644
index 0000000..33237cd
--- /dev/null
+++ b/src/ppe/hwp/lib/p9_common_pro_epi_log.C
@@ -0,0 +1,70 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/lib/p9_common_pro_epi_log.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_common_pro_epi_log.C
+/// @brief common procedure prologue/epilogue routines
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+/// Procedure Summary:
+///
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+//#include <common_scom_addresses.H>
+//will be replaced with real scom address header file
+#include "p9_common_pro_epi_log.H"
+
+//------------------------------------------------------------------------------
+// Constant Definitions:
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Procedure:
+//------------------------------------------------------------------------------
+
+extern "C"
+{
+
+fapi2::ReturnCode
+p9_common_pro_epi_log(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ |
+ fapi2::TARGET_TYPE_CORE>& i_target,
+ int i_operation)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+
+} // Procedure
+
+
+} // extern C
+
+
diff --git a/src/ppe/hwp/lib/p9_common_pro_epi_log.H b/src/ppe/hwp/lib/p9_common_pro_epi_log.H
new file mode 100644
index 0000000..b119b37
--- /dev/null
+++ b/src/ppe/hwp/lib/p9_common_pro_epi_log.H
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/lib/p9_common_pro_epi_log.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9_common_pro_epi_log.H
+/// @brief common procedure prologue/epilogue routines
+///
+/// *HWP HWP Owner : David Du <daviddu@us.ibm.com>
+/// *HWP FW Owner : Reshmi Nair <resnair5@in.ibm.com>
+/// *HWP Team : PM
+/// *HWP Consumed by : SBE:SGPE
+/// *HWP Level : 1
+///
+
+#ifndef __P9_COMMON_PRO_EPI_LOG_H__
+#define __P9_COMMON_PRO_EPI_LOG_H__
+
+extern "C"
+{
+
+/// @typedef p9_common_pro_epi_log_FP_t
+/// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9_common_pro_epi_log_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ|
+ fapi2::TARGET_TYPE_CORE>&,
+ int);
+
+
+/// @brief common procedure prologue/epilogue routines
+///
+/// @param [in] i_target TARGET_TYPE_EQ|TARGET_TYPE_CORE target
+/// @param [in] i_operation ENUM(PROLOG, EPILOG)
+///
+/// @attr
+/// @attritem ATTR_EX_PARIAL_GOOD - EX target, uint32
+///
+/// @retval FAPI_RC_SUCCESS
+fapi2::ReturnCode
+p9_common_pro_epi_log(
+ const fapi2::Target<fapi2::TARGET_TYPE_EQ|
+ fapi2::TARGET_TYPE_CORE>& i_target,
+ int i_operation);
+
+
+} // extern C
+
+#endif // __P9_COMMON_PRO_EPI_LOG_H__
diff --git a/src/ppe/hwp/nest/.empty b/src/ppe/hwp/nest/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/hwp/nest/.empty
diff --git a/src/ppe/hwp/perv/.empty b/src/ppe/hwp/perv/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/hwp/perv/.empty
diff --git a/src/ppe/hwp/perv/Makefile b/src/ppe/hwp/perv/Makefile
new file mode 100644
index 0000000..68a803f
--- /dev/null
+++ b/src/ppe/hwp/perv/Makefile
@@ -0,0 +1,54 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/perv/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# This Makefile compiles all of the core hardware procedure code. See the
+# "pervfiles.mk" file in this directory.
+
+#all generated files from this makefile will end up in obj/perv
+export SUB_OBJDIR = /perv
+
+include img_defs.mk
+include pervfiles.mk
+
+
+OBJS := $(addprefix $(OBJDIR)/, $(PERV_OBJECTS))
+
+libperv.a: perv
+ $(AR) crs $(OBJDIR)/libperv.a $(OBJDIR)/*.o
+
+.PHONY: clean perv
+perv: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/hwp/perv/p9_sbe_attr_setup.C b/src/ppe/hwp/perv/p9_sbe_attr_setup.C
new file mode 100644
index 0000000..cc08372
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_attr_setup.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_attr_setup.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_attr_setup.C
+///
+/// @brief If and only if scratch registers are non-zero, HWP will read the contents of the scratch registers and call FAPI2 APIs to set the values into the corresponding platform ATTR
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_attr_setup.H"
+fapi2::ReturnCode p9_sbe_attr_setup(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_attr_setup: Entering ...");
+
+ FAPI_DBG("p9_sbe_attr_setup: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_attr_setup.H b/src/ppe/hwp/perv/p9_sbe_attr_setup.H
new file mode 100644
index 0000000..d392969
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_attr_setup.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_attr_setup.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_attr_setup.H
+///
+/// @brief If and only if scratch registers are non-zero, HWP will read the contents of the scratch registers and call FAPI2 APIs to set the values into the corresponding platform ATTR
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_ATTR_SETUP_H_
+#define _P9_SBE_ATTR_SETUP_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_attr_setup_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --Setting All Mailbox scratch register 1, 2, 3, 4, 5, 6, 7, 8
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_attr_setup(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_check_master.C b/src/ppe/hwp/perv/p9_sbe_check_master.C
new file mode 100644
index 0000000..b348bdf
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_check_master.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_check_master.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_check_master.C
+///
+/// @brief Deremine if this is master SBE -- External FSI/GP bitIf master continue, else enable runtime chipOps
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_check_master.H"
+fapi2::ReturnCode p9_sbe_check_master(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_check_master: Entering ...");
+
+ FAPI_DBG("p9_sbe_check_master: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_check_master.H b/src/ppe/hwp/perv/p9_sbe_check_master.H
new file mode 100644
index 0000000..04a1748
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_check_master.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_check_master.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_check_master.H
+///
+/// @brief Deremine if this is master SBE -- External FSI/GP bitIf master continue, else enable runtime chipOps
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_CHECK_MASTER_H_
+#define _P9_SBE_CHECK_MASTER_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_check_master_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief If master continue, else enable runtime chipOps
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_check_master(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_enable_seeprom.C b/src/ppe/hwp/perv/p9_sbe_enable_seeprom.C
new file mode 100644
index 0000000..eab78e2
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_enable_seeprom.C
@@ -0,0 +1,53 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_enable_seeprom.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_enable_seeprom.C
+///
+/// @brief SBE enable SEEPROM (runs from OTPROM)
+///
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_enable_seeprom.H"
+fapi2::ReturnCode p9_sbe_enable_seeprom(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_enable_seeprom: Entering ...");
+
+ FAPI_DBG("p9_sbe_enable_seeprom: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_enable_seeprom.H b/src/ppe/hwp/perv/p9_sbe_enable_seeprom.H
new file mode 100644
index 0000000..e74e114
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_enable_seeprom.H
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_enable_seeprom.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_enable_seeprom.H
+///
+/// @brief SBE enable SEEPROM (runs from OTPROM)
+///
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_ENABLE_SEEPROM_H_
+#define _P9_SBE_ENABLE_SEEPROM_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_enable_seeprom_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief -- Check SBE Vital Register for selected SEEPROM image
+/// -- Update SBE FI2C_E0_PARAM register
+/// -- Check for valid SEEPROM image
+/// -- Branch to SEEPROM
+///
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_enable_seeprom(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_lpc_init.C b/src/ppe/hwp/perv/p9_sbe_lpc_init.C
new file mode 100644
index 0000000..533bad3
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_lpc_init.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_lpc_init.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_lpc_init.C
+///
+/// @brief Requirement from the bootloader is that it only uses MMIOs to LPC master, not Xscom
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_lpc_init.H"
+fapi2::ReturnCode p9_sbe_lpc_init(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_lpc_init: Entering ...");
+
+ FAPI_DBG("p9_sbe_lpc_init: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_lpc_init.H b/src/ppe/hwp/perv/p9_sbe_lpc_init.H
new file mode 100644
index 0000000..859f7bf
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_lpc_init.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_lpc_init.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_lpc_init.H
+///
+/// @brief Requirement from the bootloader is that it only uses MMIOs to LPC master, not Xscom
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_LPC_INIT_H_
+#define _P9_SBE_LPC_INIT_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_lpc_init_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief PerfoPerform scoms to setup LPC bus
+/// -- Move the LPC clock to external input
+/// Pull the LPC unit out of reset
+/// Set LPC BAR -- hardcoded like Xscom BAR
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_lpc_init(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_arrayinit.C b/src/ppe/hwp/perv/p9_sbe_nest_arrayinit.C
new file mode 100644
index 0000000..141f29a
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_arrayinit.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_arrayinit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_arrayinit.C
+///
+/// @brief array init for nest chiplet arrays
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_nest_arrayinit.H"
+fapi2::ReturnCode p9_sbe_nest_arrayinit(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_nest_arrayinit: Entering ...");
+
+ FAPI_DBG("p9_sbe_nest_arrayinit: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_arrayinit.H b/src/ppe/hwp/perv/p9_sbe_nest_arrayinit.H
new file mode 100644
index 0000000..33deab2
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_arrayinit.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_arrayinit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_arrayinit.H
+///
+/// @brief array init for nest chiplet arrays
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NEST_ARRAYINIT_H_
+#define _P9_SBE_NEST_ARRAYINIT_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_nest_arrayinit_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --Run arrayinit on all enabled chiplets
+/// --Scan flush 0 to all rings except GPTR, Time, Repair on all enabled chiplets
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_nest_arrayinit(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.C b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.C
new file mode 100644
index 0000000..d60414b
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_chiplet_init.C
+///
+/// @brief proc sbe nest chiplet init
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_nest_chiplet_init.H"
+fapi2::ReturnCode p9_sbe_nest_chiplet_init(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_nest_chiplet_init: Entering ...");
+
+ FAPI_DBG("p9_sbe_nest_chiplet_init: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.H b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.H
new file mode 100644
index 0000000..795e3a6
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_chiplet_init.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_chiplet_init.H
+///
+/// @brief proc sbe nest chiplet init
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NEST_CHIPLET_INIT_H_
+#define _P9_SBE_NEST_CHIPLET_INIT_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_nest_chiplet_init_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --Scan 0 all rings (except time, repair, gptr) on all enabled chiplets
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_nest_chiplet_init(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.C b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.C
new file mode 100644
index 0000000..4a8626d
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_chiplet_reset.C
+///
+/// @brief proc nest chiplet reset
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_nest_chiplet_reset.H"
+fapi2::ReturnCode p9_sbe_nest_chiplet_reset(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_nest_chiplet_reset: Entering ...");
+
+ FAPI_DBG("p9_sbe_nest_chiplet_reset: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.H b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.H
new file mode 100644
index 0000000..e9922eb
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_chiplet_reset.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_chiplet_reset.H
+///
+/// @brief proc nest chiplet reset
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NEST_CHIPLET_RESET_H_
+#define _P9_SBE_NEST_CHIPLET_RESET_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_nest_chiplet_reset_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief Reset Nest chiplet
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_nest_chiplet_reset(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.C b/src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.C
new file mode 100644
index 0000000..c06d950
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_gptr_time_repr_initf.C
+///
+/// @brief proc sbe nest gptr time repr initf
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_nest_gptr_time_repr_initf.H"
+fapi2::ReturnCode p9_sbe_nest_gptr_time_repr_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_nest_gptr_time_repr_initf: Entering ...");
+
+ FAPI_DBG("p9_sbe_nest_gptr_time_repr_initf: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.H b/src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.H
new file mode 100644
index 0000000..b37145b
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_gptr_time_repr_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_gptr_time_repr_initf.H
+///
+/// @brief proc sbe nest gptr time repr initf
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NEST_GPTR_TIME_REPR_INITF_H_
+#define _P9_SBE_NEST_GPTR_TIME_REPR_INITF_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_nest_gptr_time_repr_initf_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief Scan 0 all rings on all enabled chiplets (except for TP)
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_nest_gptr_time_repr_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_initf.C b/src/ppe/hwp/perv/p9_sbe_nest_initf.C
new file mode 100644
index 0000000..c8bd4a7
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_initf.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_initf.C
+///
+/// @brief proc_sbe_nest_initf
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_nest_initf.H"
+fapi2::ReturnCode p9_sbe_nest_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_nest_initf: Entering ...");
+
+ FAPI_DBG("p9_sbe_nest_initf: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_initf.H b/src/ppe/hwp/perv/p9_sbe_nest_initf.H
new file mode 100644
index 0000000..2add6ac
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_initf.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_initf.H
+///
+/// @brief proc_sbe_nest_initf
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NEST_INITF_H_
+#define _P9_SBE_NEST_INITF_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_nest_initf_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief apply init file
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_nest_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_startclocks.C b/src/ppe/hwp/perv/p9_sbe_nest_startclocks.C
new file mode 100644
index 0000000..d44835d
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_startclocks.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_startclocks.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_startclocks.C
+///
+/// @brief start clocks for nest chiplets
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_nest_startclocks.H"
+fapi2::ReturnCode p9_sbe_nest_startclocks(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_nest_startclocks: Entering ...");
+
+ FAPI_DBG("p9_sbe_nest_startclocks: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_nest_startclocks.H b/src/ppe/hwp/perv/p9_sbe_nest_startclocks.H
new file mode 100644
index 0000000..e4644c9
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_nest_startclocks.H
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_nest_startclocks.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_nest_startclocks.H
+///
+/// @brief start clocks for nest chiplets
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NEST_STARTCLOCKS_H_
+#define _P9_SBE_NEST_STARTCLOCKS_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_nest_startclocks_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --drop vital fence
+/// --reset abstclk muxsel and syncclk muxsel
+/// --Module align chiplets
+/// --Module clock start stop
+/// --Check clock stat SL, NSL , ARY
+/// --drop chiplet fence
+/// --check checkstop register
+/// --clear flush inhibit to go into flush mode
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_nest_startclocks(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_npll_initf.C b/src/ppe/hwp/perv/p9_sbe_npll_initf.C
new file mode 100644
index 0000000..d40f141
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_npll_initf.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_npll_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_npll_initf.C
+///
+/// @brief apply initfile for level 0 & 1 PLLs
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_npll_initf.H"
+fapi2::ReturnCode p9_sbe_npll_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_npll_initf: Entering ...");
+
+ FAPI_DBG("p9_sbe_npll_initf: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_npll_initf.H b/src/ppe/hwp/perv/p9_sbe_npll_initf.H
new file mode 100644
index 0000000..8445de1
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_npll_initf.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_npll_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_npll_initf.H
+///
+/// @brief apply initfile for level 0 & 1 PLLs
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NPLL_INITF_H_
+#define _P9_SBE_NPLL_INITF_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_npll_initf_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --run scan0 module (scan region = PLL, scan_types = GPTR)
+/// --run scan0 module (scan region = PLL, scan_types = BNDY/FUNC)
+/// --Scan initialize PLL BNDY chain (chiplet = PERV, scan ring = PLL, scan type = BNDY)
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_npll_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_npll_setup.C b/src/ppe/hwp/perv/p9_sbe_npll_setup.C
new file mode 100644
index 0000000..1a66606
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_npll_setup.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_npll_setup.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_npll_setup.C
+///
+/// @brief scan initialize level 0 & 1 PLLs
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_npll_setup.H"
+fapi2::ReturnCode p9_sbe_npll_setup(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_npll_setup: Entering ...");
+
+ FAPI_DBG("p9_sbe_npll_setup: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_npll_setup.H b/src/ppe/hwp/perv/p9_sbe_npll_setup.H
new file mode 100644
index 0000000..bcc5f01
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_npll_setup.H
@@ -0,0 +1,73 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_npll_setup.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_npll_setup.H
+///
+/// @brief scan initialize level 0 & 1 PLLs
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_NPLL_SETUP_H_
+#define _P9_SBE_NPLL_SETUP_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_npll_setup_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --Release PLL test enable for SS, Filt & NEST PLLs
+/// --Release SS PLL reset0
+/// --check SS PLL lock
+/// --Release SS PLL bypass0
+/// --Release Filter PLL reset1
+/// --check PLL lock for Filter PLLs
+/// --Release Filter PLL bypass signals
+/// --Switch MC meshs to Nest mesh
+/// --Release test_pll_bypass2
+/// --Release Tank PLL reset2
+/// --check Nest PLL lock
+/// --Release Tank PLL bypass2
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_npll_setup(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_select_ex.C b/src/ppe/hwp/perv/p9_sbe_select_ex.C
new file mode 100644
index 0000000..1976840
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_select_ex.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_select_ex.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_select_ex.C
+///
+/// @brief proc sbe select ex
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_select_ex.H"
+fapi2::ReturnCode p9_sbe_select_ex(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_select_ex: Entering ...");
+
+ FAPI_DBG("p9_sbe_select_ex: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_select_ex.H b/src/ppe/hwp/perv/p9_sbe_select_ex.H
new file mode 100644
index 0000000..a62d1dd
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_select_ex.H
@@ -0,0 +1,66 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_select_ex.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_select_ex.H
+///
+/// @brief proc sbe select ex
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_SELECT_EX_H_
+#define _P9_SBE_SELECT_EX_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_select_ex_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief ATTR will indicate single core or all
+/// Use the partial good info and ATTR to find the first good core
+/// For selected master EQ and Core
+/// -- Turn on chiplet enable
+/// Write selected EQ/Core mask into OCC complex
+/// -- This is the "master record " of the enabled cores/quad in the system
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_select_ex(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_arrayinit.C b/src/ppe/hwp/perv/p9_sbe_tp_arrayinit.C
new file mode 100644
index 0000000..0371235
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_arrayinit.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_arrayinit.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_arrayinit.C
+///
+/// @brief SBE PRV Array Init Procedure
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_arrayinit.H"
+fapi2::ReturnCode p9_sbe_tp_arrayinit(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_arrayinit: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_arrayinit: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_arrayinit.H b/src/ppe/hwp/perv/p9_sbe_tp_arrayinit.H
new file mode 100644
index 0000000..5ece4e4
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_arrayinit.H
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_arrayinit.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_arrayinit.H
+///
+/// @brief SBE PRV Array Init Procedure
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_ARRAYINIT_H_
+#define _P9_SBE_TP_ARRAYINIT_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_arrayinit_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief -- Array Init for PRV Cplt
+/// -- Scan0 of PRV Chiplet (except PIB/PCB)
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_arrayinit(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.C b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.C
new file mode 100644
index 0000000..4756b0b
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_init1.C
+///
+/// @brief IPL STEP 2.3: SBE TP Chiplet Init 1 :: Releases PCB Reset, Sets TP chiplet enable, Drops Perv chiplet fence
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_chiplet_init1.H"
+fapi2::ReturnCode p9_sbe_tp_chiplet_init1(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_chiplet_init1: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_chiplet_init1: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.H b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.H
new file mode 100644
index 0000000..601c167
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_init1.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_init1.H
+///
+/// @brief IPL STEP 2.3: SBE TP Chiplet Init 1 :: Releases PCB Reset, Sets TP chiplet enable, Drops Perv chiplet fence
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_CHIPLET_INIT1_H_
+#define _P9_SBE_TP_CHIPLET_INIT1_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_chiplet_init1_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief DESCRIPTION -- Drop VSS2VIO fence
+/// -- Releases PCB reset
+/// -- Sets PRV Chiplet Enable
+/// -- Drops PRV Chiplet fence enable
+/// -- Drop Global Endpoint Reset
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_chiplet_init1(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.C b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.C
new file mode 100644
index 0000000..36ebf0f
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_init2.C
+///
+/// @brief IPL STEP 2.10 : SBE TP Chiplet Init2 :: Run scan 0 module for pervasive
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_chiplet_init2.H"
+fapi2::ReturnCode p9_sbe_tp_chiplet_init2(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_chiplet_init2: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_chiplet_init2: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.H b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.H
new file mode 100644
index 0000000..d37e8be
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_init2.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_init2.H
+///
+/// @brief IPL STEP 2.10 : SBE TP Chiplet Init2 :: Run scan 0 module for pervasive
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_CHIPLET_INIT2_H_
+#define _P9_SBE_TP_CHIPLET_INIT2_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_chiplet_init2_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief -- Initialize TP Hangcounter 6
+/// -- Scan Repair, Time and GPTR for PRV Chiplet
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_chiplet_init2(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.C b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.C
new file mode 100644
index 0000000..80cb27e
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_init3.C
+///
+/// @brief SBE Pervasive Init Procedure 3
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_chiplet_init3.H"
+fapi2::ReturnCode p9_sbe_tp_chiplet_init3(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_chiplet_init3: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_chiplet_init3: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.H b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.H
new file mode 100644
index 0000000..25c1c2e
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.H
@@ -0,0 +1,68 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_init3.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_init3.H
+///
+/// @brief SBE Pervasive Init Procedure 3
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_CHIPLET_INIT3_H_
+#define _P9_SBE_TP_CHIPLET_INIT3_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_chiplet_init3_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief -- Switches PRV Chiplet OOB mux
+/// -- Reset PCB Master Interrupt Register
+/// -- Drop Pervasive and OCC2PIB Fence in GP0 (bits 19 & 63)
+/// --"Clock Start" command (all other clk domains)
+/// -- Clear force_align in chiplet GP0
+/// -- Clear flushmode_inhibit in chiplet GP0
+/// -- Drop FSI fence 5 (checkstop, interrupt conditions)
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_chiplet_init3(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.C b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.C
new file mode 100644
index 0000000..bc90079
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_reset.C
+///
+/// @brief IPL STEP 2.8 : SBE TP Chiplet Reset :: setup hangcounter 6 for TP chiplet
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_chiplet_reset.H"
+fapi2::ReturnCode p9_sbe_tp_chiplet_reset(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_chiplet_reset: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_chiplet_reset: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.H b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.H
new file mode 100644
index 0000000..9f3c7ae
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_chiplet_reset.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_chiplet_reset.H
+///
+/// @brief IPL STEP 2.8 : SBE TP Chiplet Reset :: setup hangcounter 6 for TP chiplet
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_CHIPLET_RESET_H_
+#define _P9_SBE_TP_CHIPLET_RESET_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_chiplet_reset_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --Setup hang counter for PCB slaves/master
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_chiplet_reset(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.C b/src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.C
new file mode 100644
index 0000000..57ebc5f
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_gptr_time_repr_initf.C
+///
+/// @brief proc sbe tp gptr time repr initf
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_gptr_time_repr_initf.H"
+fapi2::ReturnCode p9_sbe_tp_gptr_time_repr_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_gptr_time_repr_initf: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_gptr_time_repr_initf: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.H b/src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.H
new file mode 100644
index 0000000..43e777a
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_gptr_time_repr_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_gptr_time_repr_initf.H
+///
+/// @brief proc sbe tp gptr time repr initf
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_GPTR_TIME_REPR_INITF_H_
+#define _P9_SBE_TP_GPTR_TIME_REPR_INITF_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_gptr_time_repr_initf_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --Load Scan Repair, Time and GPTR for TP Chiplet
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_gptr_time_repr_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_initf.C b/src/ppe/hwp/perv/p9_sbe_tp_initf.C
new file mode 100644
index 0000000..908cfad
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_initf.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_initf.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_initf.C
+///
+/// @brief TP chiplet scaninits for the TP rings
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_initf.H"
+fapi2::ReturnCode p9_sbe_tp_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_initf: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_initf: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_initf.H b/src/ppe/hwp/perv/p9_sbe_tp_initf.H
new file mode 100644
index 0000000..56c2cd1
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_initf.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_initf.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_initf.H
+///
+/// @brief TP chiplet scaninits for the TP rings
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_INITF_H_
+#define _P9_SBE_TP_INITF_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_initf_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief -- This doesn't include the gptr/time/repair rings,
+/// -- since they are scanned in tp_chiplet_init2.
+/// -- This doesn't include the net/pib/fuse rings,
+/// -- since they are used by the SBE hardware itself.
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_initf(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_ld_image.C b/src/ppe/hwp/perv/p9_sbe_tp_ld_image.C
new file mode 100644
index 0000000..2741796
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_ld_image.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_ld_image.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_ld_image.C
+///
+/// @brief Proc SBE load Image
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_ld_image.H"
+fapi2::ReturnCode p9_sbe_tp_ld_image(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_ld_image: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_ld_image: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_ld_image.H b/src/ppe/hwp/perv/p9_sbe_tp_ld_image.H
new file mode 100644
index 0000000..3e13af6
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_ld_image.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_ld_image.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_ld_image.H
+///
+/// @brief Proc SBE load Image
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_LD_IMAGE_H_
+#define _P9_SBE_TP_LD_IMAGE_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_ld_image_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief This procedure copies the .pibmem0 section of image from SEEPROM to the PIBMEM.
+/// The pibmem0 section contains the PORE branch table (error handlers) used for the majority of the SEEPROM IPL as well as
+/// performance sensitive routines such as the decompression-scan routine and the LCO loader.
+/// Once the image is loaded then the error handlers are switched to
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_ld_image(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_switch_gears.C b/src/ppe/hwp/perv/p9_sbe_tp_switch_gears.C
new file mode 100644
index 0000000..dc9cb47
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_switch_gears.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_switch_gears.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_switch_gears.C
+///
+/// @brief SBE switch gears Procedure
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_sbe_tp_switch_gears.H"
+fapi2::ReturnCode p9_sbe_tp_switch_gears(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_sbe_tp_switch_gears: Entering ...");
+
+ FAPI_DBG("p9_sbe_tp_switch_gears: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_sbe_tp_switch_gears.H b/src/ppe/hwp/perv/p9_sbe_tp_switch_gears.H
new file mode 100644
index 0000000..3a7e893
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_sbe_tp_switch_gears.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_sbe_tp_switch_gears.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_sbe_tp_switch_gears.H
+///
+/// @brief SBE switch gears Procedure
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SBE_TP_SWITCH_GEARS_H_
+#define _P9_SBE_TP_SWITCH_GEARS_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_sbe_tp_switch_gears_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief -- Calls the gear switcher procedure from PIBMEM
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_sbe_tp_switch_gears(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_select_boot_master.C b/src/ppe/hwp/perv/p9_select_boot_master.C
new file mode 100644
index 0000000..b849a4f
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_select_boot_master.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_select_boot_master.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_select_boot_master.C
+///
+/// @brief Select Boot Master
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_select_boot_master.H"
+fapi2::ReturnCode p9_select_boot_master(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_select_boot_master: Entering ...");
+
+ FAPI_DBG("p9_select_boot_master: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_select_boot_master.H b/src/ppe/hwp/perv/p9_select_boot_master.H
new file mode 100644
index 0000000..201fec0
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_select_boot_master.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_select_boot_master.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_select_boot_master.H
+///
+/// @brief Select Boot Master
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SELECT_BOOT_MASTER_H_
+#define _P9_SELECT_BOOT_MASTER_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_select_boot_master_FP_t)(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --Select Master Chip
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_select_boot_master(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_select_clock_mux.C b/src/ppe/hwp/perv/p9_select_clock_mux.C
new file mode 100644
index 0000000..c6482cf
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_select_clock_mux.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_select_clock_mux.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_select_clock_mux.C
+///
+/// @brief proc select clock mux
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_select_clock_mux.H"
+fapi2::ReturnCode p9_select_clock_mux(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_select_clock_mux: Entering ...");
+
+ FAPI_DBG("p9_select_clock_mux: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_select_clock_mux.H b/src/ppe/hwp/perv/p9_select_clock_mux.H
new file mode 100644
index 0000000..94fa7e1
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_select_clock_mux.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_select_clock_mux.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_select_clock_mux.H
+///
+/// @brief proc select clock mux
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SELECT_CLOCK_MUX_H_
+#define _P9_SELECT_CLOCK_MUX_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_select_clock_mux_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief Select internal clock mux to drive the memory clocks off of
+/// Flips all bits needed for clock routing (processor only), centaur is done later in p9_cen_ref_clk_enable
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_select_clock_mux(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_set_fsi_gp_shadow.C b/src/ppe/hwp/perv/p9_set_fsi_gp_shadow.C
new file mode 100644
index 0000000..ff32cc0
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_set_fsi_gp_shadow.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_set_fsi_gp_shadow.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_set_fsi_gp_shadow.C
+///
+/// @brief --IPL step 0.8 proc_prep_ipl
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_set_fsi_gp_shadow.H"
+fapi2::ReturnCode p9_set_fsi_gp_shadow(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_set_fsi_gp_shadow: Entering ...");
+
+ FAPI_DBG("p9_set_fsi_gp_shadow: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_set_fsi_gp_shadow.H b/src/ppe/hwp/perv/p9_set_fsi_gp_shadow.H
new file mode 100644
index 0000000..c08c3f3
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_set_fsi_gp_shadow.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_set_fsi_gp_shadow.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_set_fsi_gp_shadow.H
+///
+/// @brief --IPL step 0.8 proc_prep_ipl
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SET_FSI_GP_SHADOW_H_
+#define _P9_SET_FSI_GP_SHADOW_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_set_fsi_gp_shadow_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --update ROOT CTRL shadows if needed
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_set_fsi_gp_shadow(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_setup_clock_term.C b/src/ppe/hwp/perv/p9_setup_clock_term.C
new file mode 100644
index 0000000..0a62a24
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_setup_clock_term.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_setup_clock_term.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_setup_clock_term.C
+///
+/// @brief proc setup clock term
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_setup_clock_term.H"
+fapi2::ReturnCode p9_setup_clock_term(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_setup_clock_term: Entering ...");
+
+ FAPI_DBG("p9_setup_clock_term: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_setup_clock_term.H b/src/ppe/hwp/perv/p9_setup_clock_term.H
new file mode 100644
index 0000000..f49bb74
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_setup_clock_term.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_setup_clock_term.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_setup_clock_term.H
+///
+/// @brief proc setup clock term
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SETUP_CLOCK_TERM_H_
+#define _P9_SETUP_CLOCK_TERM_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_setup_clock_term_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief Setup the clock termination correctly for system/chip type
+/// Since this is the first procedure run against the chips it also clears the GP write protect
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_setup_clock_term(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_setup_sbe_config.C b/src/ppe/hwp/perv/p9_setup_sbe_config.C
new file mode 100644
index 0000000..68b0446
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_setup_sbe_config.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_setup_sbe_config.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_setup_sbe_config.C
+///
+/// @brief proc setup sbe config
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_setup_sbe_config.H"
+fapi2::ReturnCode p9_setup_sbe_config(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip)
+{
+ FAPI_DBG("p9_setup_sbe_config: Entering ...");
+
+ FAPI_DBG("p9_setup_sbe_config: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_setup_sbe_config.H b/src/ppe/hwp/perv/p9_setup_sbe_config.H
new file mode 100644
index 0000000..5c4521b
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_setup_sbe_config.H
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_setup_sbe_config.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_setup_sbe_config.H
+///
+/// @brief proc setup sbe config
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_SETUP_SBE_CONFIG_H_
+#define _P9_SETUP_SBE_CONFIG_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_setup_sbe_config_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief update mailbox with boot parameters
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_setup_sbe_config(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/p9_start_cbs.C b/src/ppe/hwp/perv/p9_start_cbs.C
new file mode 100644
index 0000000..fdec2cc
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_start_cbs.C
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_start_cbs.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_start_cbs.C
+///
+/// @brief Start CBS : Trigger CBS
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+//## auto_generated
+#include "p9_start_cbs.H"
+fapi2::ReturnCode p9_start_cbs(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ & i_target_chip)
+{
+ FAPI_DBG("p9_start_cbs: Entering ...");
+
+ FAPI_DBG("p9_start_cbs: Exiting ...");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+}
diff --git a/src/ppe/hwp/perv/p9_start_cbs.H b/src/ppe/hwp/perv/p9_start_cbs.H
new file mode 100644
index 0000000..7e89907
--- /dev/null
+++ b/src/ppe/hwp/perv/p9_start_cbs.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwp/perv/p9_start_cbs.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//------------------------------------------------------------------------------
+/// @file p9_start_cbs.H
+///
+/// @brief Start CBS : Trigger CBS
+// *!
+// *! OWNER NAME : Abhishek Agarwal Email: abagarw8@in.ibm.com
+// *! BACKUP NAME : Email:
+//------------------------------------------------------------------------------
+// *HWP HWP Owner : Abhishek Agarwal <abagarw8@in.ibm.com>
+// *HWP FW Owner : Brian Silver <bsilver@us.ibm.com>
+// *HWP Team : Perv
+// *HWP Level : 1
+// *HWP Consumed by : SBE
+//------------------------------------------------------------------------------
+
+
+#ifndef _P9_START_CBS_H_
+#define _P9_START_CBS_H_
+
+
+#include <fapi2.H>
+
+
+typedef fapi2::ReturnCode (*p9_start_cbs_FP_t)(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> &);
+
+/// @brief --check/wait for VDN_PGOOD = 1
+/// --check for OSC ok
+/// --check for VDD (VDD status check)
+/// --start CBS(CBS runs thru default path)
+///
+///
+/// @param[in] i_target_chip Reference to TARGET_TYPE_PROC_CHIP target
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+extern "C"
+{
+ fapi2::ReturnCode p9_start_cbs(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ & i_target_chip);
+}
+
+#endif
diff --git a/src/ppe/hwp/perv/pervasive_attributes.xml b/src/ppe/hwp/perv/pervasive_attributes.xml
new file mode 100644
index 0000000..f49ed7a
--- /dev/null
+++ b/src/ppe/hwp/perv/pervasive_attributes.xml
@@ -0,0 +1,149 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/ppe/hwp/perv/pervasive_attributes.xml $ -->
+<!-- -->
+<!-- OpenPOWER OnChipController Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2015 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- You may obtain a copy of the License at -->
+<!-- -->
+<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
+<!-- -->
+<!-- Unless required by applicable law or agreed to in writing, software -->
+<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
+<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -->
+<!-- implied. See the License for the specific language governing -->
+<!-- permissions and limitations under the License. -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
+<!-- This is an automatically generated file. -->
+<!-- File: pervasive_attributes.xml. -->
+<!-- XML file specifying attributes used by HW Procedures. Attributes are taken from model pervasive -->
+<!--pervasive_attributes.xml-->
+<attributes>
+<attribute>
+ <id>ATTR_BOOT_FREQ</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_CHIP_REGIONS_TO_ENABLE</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint32</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_CHIP_UNIT_POS</id>
+ <targetType>TARGET_TYPE_PERV,TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_ECID</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint64</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_EC_GARD</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_EQ_GARD</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_I2C_BUS_DIV_NEST</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_I2C_BUS_DIV_REF</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_MC_SYNC_MODE</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_NEST_PLL_BUCKET</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_PROC_PB_BNDY_DMIPLL_DATA</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_PROC_PB_BNDY_DMIPLL_FOR_DCCAL_DATA</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_PROC_PERV_BNDY_PLL_DATA</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_SBE_SEEPROM_I2C_DEVICE_ADDRESS</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint32</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_SBE_SEEPROM_I2C_PORT</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint32</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_VCS_BOOT_VOLTAGE</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+<attribute>
+ <id>ATTR_VDD_BOOT_VOLTAGE</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description></description>
+ <valueType>uint8</valueType>
+</attribute>
+
+</attributes>
diff --git a/src/ppe/hwp/perv/pervfiles.mk b/src/ppe/hwp/perv/pervfiles.mk
new file mode 100644
index 0000000..c99113c
--- /dev/null
+++ b/src/ppe/hwp/perv/pervfiles.mk
@@ -0,0 +1,74 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwp/perv/pervfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file pervfiles.mk
+#
+# @brief mk for including perv object files
+#
+# @page ChangeLogs Change Logs
+# @section pervfiles.mk
+# @verbatim
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+PERV-CPP-SOURCES = p9_sbe_setup_evid.C
+PERV-CPP-SOURCES +=p9_sbe_attr_setup.C
+PERV-CPP-SOURCES +=p9_sbe_tp_chiplet_init1.C
+PERV-CPP-SOURCES +=p9_sbe_check_master.C
+PERV-CPP-SOURCES +=p9_sbe_tp_chiplet_init2.C
+PERV-CPP-SOURCES +=p9_sbe_enable_seeprom.C
+PERV-CPP-SOURCES +=p9_sbe_tp_chiplet_init3.C
+PERV-CPP-SOURCES +=p9_sbe_lpc_init.C
+PERV-CPP-SOURCES +=p9_sbe_tp_chiplet_reset.C
+PERV-CPP-SOURCES +=p9_sbe_nest_arrayinit.C
+PERV-CPP-SOURCES +=p9_sbe_tp_gptr_time_repr_initf.C
+PERV-CPP-SOURCES +=p9_sbe_nest_chiplet_init.C
+PERV-CPP-SOURCES +=p9_sbe_tp_initf.C
+PERV-CPP-SOURCES +=p9_sbe_nest_chiplet_reset.C
+PERV-CPP-SOURCES +=p9_sbe_tp_ld_image.C
+PERV-CPP-SOURCES +=p9_sbe_nest_gptr_time_repr_initf.C
+PERV-CPP-SOURCES +=p9_sbe_tp_switch_gears.C
+PERV-CPP-SOURCES +=p9_sbe_nest_initf.C
+PERV-CPP-SOURCES +=p9_select_boot_master.C
+PERV-CPP-SOURCES +=p9_sbe_nest_startclocks.C
+PERV-CPP-SOURCES +=p9_select_clock_mux.C
+PERV-CPP-SOURCES +=p9_sbe_npll_initf.C
+PERV-CPP-SOURCES +=p9_set_fsi_gp_shadow.C
+PERV-CPP-SOURCES +=p9_sbe_npll_setup.C
+PERV-CPP-SOURCES +=p9_setup_clock_term.C
+PERV-CPP-SOURCES +=p9_sbe_select_ex.C
+PERV-CPP-SOURCES +=p9_setup_sbe_config.C
+PERV-CPP-SOURCES +=p9_sbe_tp_arrayinit.C
+PERV-CPP-SOURCES +=p9_start_cbs.C
+
+PERV-C-SOURCES =
+PERV-S-SOURCES =
+
+PERV_OBJECTS += $(PERV-CPP-SOURCES:.C=.o)
+PERV_OBJECTS += $(PERV-C-SOURCES:.c=.o)
+PERV_OBJECTS += $(PERV-S-SOURCES:.S=.o)
diff --git a/src/ppe/hwp/utils/.empty b/src/ppe/hwp/utils/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/hwp/utils/.empty
diff --git a/src/ppe/hwpf/fapi/.empty b/src/ppe/hwpf/fapi/.empty
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/hwpf/fapi/.empty
diff --git a/src/ppe/hwpf/fapi/docs/Doxyfile b/src/ppe/hwpf/fapi/docs/Doxyfile
new file mode 100755
index 0000000..9cb5dc4
--- /dev/null
+++ b/src/ppe/hwpf/fapi/docs/Doxyfile
@@ -0,0 +1,2355 @@
+# Doxyfile 1.8.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "FAPI 2"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = genfiles
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = NO
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = ../include ./topics
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.idl \
+ *.ddl \
+ *.odl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.cs \
+ *.d \
+ *.php \
+ *.php4 \
+ *.php5 \
+ *.phtml \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.for \
+ *.tcl \
+ *.vhd \
+ *.vhdl \
+ *.ucf \
+ *.qsf \
+ *.as \
+ *.js \
+ *.H
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = README.md
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 1
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = YES
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED = DOXYGEN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/src/ppe/hwpf/fapi/docs/README b/src/ppe/hwpf/fapi/docs/README
new file mode 100755
index 0000000..da66d67
--- /dev/null
+++ b/src/ppe/hwpf/fapi/docs/README
@@ -0,0 +1,6 @@
+
+To generate FAPI2 documentation, run
+
+$doxygen Doxyfile
+
+The documentation will be output into genfiles.
diff --git a/src/ppe/hwpf/fapi/docs/topics/DEPRECATED.md b/src/ppe/hwpf/fapi/docs/topics/DEPRECATED.md
new file mode 100755
index 0000000..39df626
--- /dev/null
+++ b/src/ppe/hwpf/fapi/docs/topics/DEPRECATED.md
@@ -0,0 +1,81 @@
+@deprecated Functions which were either not found used in the
+hostboot code or have other ways to perform the same operation
+with the new buffers are candidates for deprecation. They are listed
+here so if you're looking for something you might find that it's
+deprecated and not been implemented. If there's something in this
+list which should be implemented, let someone know and we can
+implement it.<br>
+- setDoubleWordLength(uint32_t i_newNumDoubleWords);<br>
+- setWordLength(uint32_t i_newNumWords);<br>
+- setHalfWordLength(uint32_t i_newNumHalfWords);<br>
+- setByteLength(uint32_t i_newNumBytes);<br>
+- setBitLength(uint32_t i_newNumBits);<br>
+- setCapacity (uint32_t i_newNumWords);<br>
+- shrinkBitLength(uint32_t i_newNumBits);<br>
+- growBitLength(uint32_t i_newNumBits);<br>
+Replaced with std::container operations
+- shiftRight(uint32_t i_shiftnum, uint32_t i_offset = 0);<br>
+Replaced with operator>> as offset appears unused<br>
+- shiftLeft(uint32_t i_shiftnum, uint32_t i_offset = 0xFFFFFFFF);<br>
+Replaced with operator<< as offset appears unused<br>
+- shiftRightAndResize(uint32_t i_shiftnum, uint32_t i_offset = 0);<br>
+- shiftLeftAndResize(uint32_t i_shiftnum);<br>
+- rotateRight(uint32_t i_rotatenum);<br>
+- rotateLeft(uint32_t i_rotatenum);<br>
+- flushTo0(); and flushTo1();<br>
+Replaced with flush<X>() where X can be {0,1}<br>
+- applyInversionMask(const uint32_t * i_invMask, uint32_t
+ i_invByteLen);<br>
+- applyInversionMask(const ecmdDataBufferBase & i_invMaskBuffer,
+ uint32_t i_invByteLen);<br>
+- insert(const ecmdDataBufferBase & i_bufferIn, uint32_t i_targetStart,
+ uint32_t i_len, uint32_t i_sourceStart = 0);<br>
+ insert(const uint32_t * i_data, uint32_t i_targetStart, uint32_t
+ i_len, uint32_t i_sourceStart = 0);<br>
+It appears from the usage that the insert functions were used like a
+initializer list - given a chunk of data, insert at bit 0.
+Other useages have been replaced with a templated version for
+variable_buffers and bit operations for integral buffers.<br>
+- insertFromRight<br>
+Replaced with a templated version for
+variable_buffers and bit operations for integral buffers.<br>
+- extract API<br>
+Replaced with a templated version for
+variable_buffers and bit operations for integral buffers.<br>
+- setOr API/merge API<br>
+- concat( ... );<br>
+Replaced with operator+() and operator+=()<br>
+- setOr(const uint32_t * i_data, uint32_t i_startbit,
+ uint32_t i_len);<br>
+ merge()
+Replaced with operator|=() as it looks like startbit is always 0
+and len is always the length of i_data. Merge is the same I think<br>
+- setXor(const ecmdDataBufferBase & i_bufferIn, uint32_t i_startbit,
+ uint32_t i_len);
+Replaced with operator|=() as it looks like startbit is always 0
+and len is always the length of i_data.<br>
+- setAnd(const ecmdDataBufferBase & i_bufferIn, uint32_t i_startbit,
+ uint32_t i_len);<br>
+Replaced with operator&=() as it looks like startbit is mostly 0
+and len is mostly the length of i_data. The few cases seen where
+this isn't the case, a uint64_t mask would work better.<br>
+- copy(ecmdDataBufferBase & o_copyBuffer) const
+Replaced with operator=()
+- memCopyIn, memCopyOut
+- flattenSize(void) const;
+- flatten(uint8_t * o_data, uint32_t i_len) const;
+- unflatten(const uint8_t * i_data, uint32_t i_len);
+- oddParity()
+- evenParity()
+- shareBuffer(ecmdDataBufferBase* i_sharingBuffer);
+- compressBuffer(ecmdCompressionMode_t i_mode = ECMD_COMP_PRD);
+- uncompressBuffer();
+- isBufferCompressed();
+- setWord(), setHalfWord(), etc.
+Replaced with a templated version, set<type>();
+- getDoubleWordLength(), getDoubleLength
+Replaced with a templated version taking the type as an argument
+- getCapacity()
+- writeBit(bits_type i_bit, uint32_t i_value);
+Replaced with set operations (this might be needed?)
+e \ No newline at end of file
diff --git a/src/ppe/hwpf/fapi/docs/topics/Examples.md b/src/ppe/hwpf/fapi/docs/topics/Examples.md
new file mode 100755
index 0000000..e7ccb02
--- /dev/null
+++ b/src/ppe/hwpf/fapi/docs/topics/Examples.md
@@ -0,0 +1,246 @@
+
+# Examples And Frequently Asked Questions
+
+## Buffers
+
+### Create a buffer of 32 bits and initialize it.
+
+ fapi2::buffer<uint32_t> data(0xAA55FFAA);
+
+### Flip bit 0
+
+ data.flipBit<0>();
+
+### Invert the buffer
+
+ data.invert();
+
+### Reset it's value
+
+ data = 0xFFFFFFFF;
+
+### Create a mask using an anonymous object
+
+ my_buffer &= buffer<T>().setBit<B>.invert();
+
+### Create an 8 bit buffer, initialize it, and flip some bits around
+
+ fapi2::buffer<uint8_t>(0xA5).flipBit<5>().flipBit<5>() == 0xA5;
+
+## Operations and Things
+### Is the FAPI_TRY / 'clean_up:' method, the recommended method for doing put/getscoms?
+
+Yes, FAPI_TRY is the preferred wrapper for put/get scom as well as other operations which used to do the do/while/break dance based on the fapi return code.
+A thread-local fapi return code, fapi2::current_err has been introduced to help with the housekeeping.
+
+Feel free to decompose the FAPI_TRY pattern if you have clean_up requirements which make FAPI_TRY too simplistic.
+
+
+## Targets
+
+### Create a processor target
+
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A);
+
+### Define a function which takes only a processor as an argument, enforced by the compiler
+
+ void takesProc( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& V );
+
+### How do I pass TARGET_TYPE_X into putScom?
+
+It should "just work." fapi2::putScom is defined as a template.
+Basically any TargetType will match. So,
+
+ Target<TARGET_TYPE_XBUS> foo;
+ Target<TARGET_TYPE_ABUS> bar;
+
+will both match fapi::putScom in it's more generic sense. However, platforms
+might specialize the hw_access templates. For example, if the operation to
+perform a putScom on an XBUS is different than accessing other targets, the
+platform needs to specialize for XBUS.
+
+ template<>
+ fapi2::ReturnCode fapi2::putScom (const fapi2::Target<TARGET_TYPE_XBUS> &i_target, const uint64_t i_address, buffer< uint64_t > &i_data)
+ {
+ // Do XBUS special code here.
+ }
+
+### How do I get <information> with the new targets when this used to be an attribute look up before?
+
+This question came up in the context of ATTR_CHIP_UNIT_POS, but really applies for any information
+previously tucked away in attributes.
+
+Do the attribute lookup, the platform can optimize the look up away. In any event the get_attr macro/call will always do the right thing.
+
+If the platform can resolve the lookup without looking anything up (all the information is encoded in the value of the target) the attribute
+mechanism can simply do that manipulation at compile time.
+
+For the smaller platforms, we discussed attribute look ups were templates which could be (would be?) specialized per attribute "key."
+In this way, the "look up" for the unit position could be coded to be nothing more than a static manipulation of the target value.
+A look up would, obviously, be needed if the unit position (or any other attribute value) couldn't be resolved from the target value alone.
+
+### Target Types
+
+#### How do I write a procedure which takes multiple target types?
+
+Depends on what you mean.
+
+##### If you mean "I have a procedure which is generic but only for a subset of types":
+
+ fapi2::ReturnCode newProcedure( const fapi2::Target<TARGET_TYPE_XBUS | TARGET_TYPE_ABUS> & i_target, ...);
+
+Note that newProcedure can not then say "if xbus, do this, if abus do the
+other." This is the static equivilent of grabbing a "base class" and the same
+rules apply - if the method is not generic for all the subclasses, you need to
+specialize for those subclasses.
+
+__Think twice about using this mechanism. It creates a new type (the or of the
+target types) and reduces the input to this type. There is no support for run
+time type conversion, and so the original type is not available in this scope.__
+
+##### If you mean "I have a procedure and I want it to do different things for different target types":
+
+You can create templates:
+
+ template<fapi2::TargetType T>
+ void newProcedure( const fapi2::Target<T>& i_target );
+
+ template<>
+ void newProcedure( const fapi2::Target<TARGET_TYPE_XBUS>& i_target )
+ {
+ // XBUS specific code here
+ }
+
+ template<>
+ void newProcedure( const fapi2::Target<TARGET_TYPE_ABUS>& i_target )
+ {
+ // ABUS specific code here
+ }
+
+Notice that because the generic case for newProcedure is declared but
+never defined you will get an error at compile time if newProcedure is
+called with a type other than XBUS or ABUS.
+
+Or overloaded functions:
+
+ void newProcedure( const fapi2::Target<TARGET_TYPE_XBUS>& i_target )
+ {
+ // XBUS specific code here
+ }
+
+ void newProcedure( const fapi2::Target<TARGET_TYPE_ABUS>& i_target )
+ {
+ // ABUS specific code here
+ }
+
+##### If you mean "I have a procedure which is mostly generic but I need special handling for some target types":
+
+More or less the same as above, but define the generic template. There is no equivilent for
+overloaded functions unless a composite target will suit your needs.
+
+ template<fapi2::TargetType T>
+ void newProcedure( const fapi2::Target<T>& i_target )
+ {
+ // Code for types other than ABUS or XBUS
+ }
+
+ template<>
+ void newProcedure( const fapi2::Target<TARGET_TYPE_XBUS>& i_target )
+ {
+ // XBUS specific code here
+ }
+
+ template<>
+ void newProcedure( const fapi2::Target<TARGET_TYPE_ABUS>& i_target )
+ {
+ // ABUS specific code here
+ }
+
+##### If you want to build a procedure which takes all target types:
+
+__It is recomended that you do not use TARGET_TYPE_ALL - that will reduce the
+type of the passed in target to the "top level base class" of targets and
+every procedure called will need to be completly generic. This is probably
+not what you inteded (but is sometimes useful.) Rather, it is recomended
+that you simply make a generic template.__
+
+ template<fapi2::TargetType T>
+ void newProcedure( const fapi2::Target<T>& i_target )
+ {
+ // Code for all types
+ fapi2::putScom(i_target, ... );
+ }
+
+Note that the putScom here will always be the correct putScom for the
+target type passed in. Assuming procedures called in this method have
+been specialized for specific target types, the compiler will find the
+best match and call it.
+
+#### Once I'm in newProcedure, what is the type of the target?
+
+If you used a generic or specialized template, the type will be the type
+of the target passed in. If you used a composite type (or'd together target
+types) then the type will be TYPE_A | TYPE_B.
+
+Notice there's no simple way to know the original type was TYPE_A in this
+case. If you think about this, it makes sense. Consider:
+
+ void f(double x);
+
+ int y = 3;
+ f(y);
+
+There's no way in f() to know that x started life as an int, which happened to
+be cast to a double.
+
+Targets are the same thing - they're just types we create on the fly. So all of
+the usual C++ tools to deal with this are available.
+
+#### So, wait - I can't write a procedure which handles multiple target types?
+
+You can. What you can't do is figure out the type of the object prior to
+the cast. So what you need to do is make sure the original type isn't lost,
+and that means you can't use TYPE_A | TYPE_B:
+
+##### Specialize. This is the prefered mechanism.
+The template and overload examples above show how to do this specialization.
+It will create very regular and easy to maintain code.
+
+##### Create a generic template and handle each type yourself.
+
+ template<fapi2::TargetType T>
+ void newProcedure( fapi2::Target<T> i_target )
+ {
+ // If this procedure isn't generic, check for allowed types here.
+ static_assert(fapi2::is_same<T, fapi2::TARGET_TYPE_ABUS>() || fapi2::is_same<T, fapi2::TARGET_TYPE_XBUS>(),
+ "newProcedure only takes X/A busses");
+
+ :
+ :
+
+ if (fapi2::is_same<T, fapi2::TARGET_TYPE_ABUS>())
+ {
+ // ABUS code
+ }
+
+ if (fapi2::is_same<T, fapi2::TARGET_TYPE_XBUS>())
+ {
+ // XBUS code
+ }
+
+ :
+ :
+ }
+
+newProcedure is a generic template, any target type will match. And, the type T of i_target is
+the original value of the target - the template matched without a cast because it's generic.
+However, with that generality we lost the compiler argument type checking so we replace it with
+the static_assert. This happens at compile time so the compiler will complain if a target other
+than an XBUS or ABUS is passed in to this procedure. To handle the special cases for the types,
+fapi2::is_same is used again - and is also a compile time operation. And so when this template
+matches an XBUS target, the code generated is specific to the XBUS target.
+
+#### Ok, so what is TARGET_TYPE_X | TARGET_TYPE_Y for then?
+
+Creating procedures which are generic to those types. Think of this as a base
+class method.
diff --git a/src/ppe/hwpf/fapi/docs/topics/Ffdc.md b/src/ppe/hwpf/fapi/docs/topics/Ffdc.md
new file mode 100755
index 0000000..85d696b
--- /dev/null
+++ b/src/ppe/hwpf/fapi/docs/topics/Ffdc.md
@@ -0,0 +1,149 @@
+
+# Using the FFDC/XML Error Parsing Tools
+
+For FAPI2, the parseErrorInfo PERL script has changed. The main goal was to
+enable FFDC generation classes/methods. This enables a named-parameter
+model as well as tucking the FFDC generation into a container which can
+easily be used by the FAPI_ASSERT macro.
+
+## Using the Tools
+
+parseErrorInfo.pl [--empty-ffdc-classes] [--use-variable-buffers] --output-dir=<output dir> <filename1> <filename2> ...
+- This perl script will parse HWP Error XML files and creates the following files:
+- hwp_return_codes.H. HwpReturnCode enumeration (HWP generated errors)
+- hwp_error_info.H. Error information (used by FAPI_SET_HWP_ERROR when a HWP generates an error)
+- collect_reg_ffdc.C. Function to collect register FFDC
+- set_sbe_error.H. Macro to create an SBE error
+
+The --empty-ffdc-classes option is for platforms which don't collect FFDC. It will generate stub classes which
+will allow the source to have the same code, but compile to no-ops on certain platforms.
+
+The --use-variable-bufers option is for platforms which support variable buffers.
+
+The XML input is the same format as for P8
+
+## Using the Generated Classes
+
+Each error found in the XML files generates a class in hwp_ffdc_classes.H.
+The name of the class is the same as the return code itself (lower case)
+and the set methods are the same as the elements the xml described as
+needing colletion.
+
+Take for example RC_MBVPD_INVALID_MT_DATA. Here is the XML:
+
+ <hwpError>
+ <rc>RC_MBVPD_INVALID_MT_DATA</rc>
+ <description>
+ To get the proper MT data, we need a valid
+ dimm rank combination.
+ </description>
+ <ffdc>RANK_NUM</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+It generates an FFDC class which looks like this (simplified):
+
+ class rc_mbvpd_invalid_mt_data
+ {
+ public:
+ rc_mbvpd_invalid_mt_data( ... )
+ { FAPI_ERR("To get the proper MT data, we need a valid dimm rank combination."); }
+
+ rc_mbvpd_invalid_mt_data& set_rank_num(const T& i_value)
+ { <setup ffdc> }
+
+ void execute(void)
+ {
+ FAPI_SET_HWP_ERROR(..., RC_MBVPD_INVALID_MT_DATA);
+ fapi2::logError( ... );
+ }
+ };
+
+To use this, for example, you may do:
+
+ FAPI_ASSERT( foo != bar,
+ rc_mbvpd_invalid_mt_data().set_rank_num(l_rank),
+ "foo didn't equal bar" );
+
+Notice the description of the error is automatically logged.
+
+## Buffer Support
+
+In FAPI, a ReturnCode had a mechanism for "containing" an error from an
+ecmdDataBuffer. The API, setEcmdError(), no longer exists. fapi2::buffers
+return ReturnCodes, and as such the FFDC information is added in a manner
+consistent with the rest of the FFDC gathering.
+
+There is a new error xml file specifically for buffers called
+buffer_error.xml. It will generate an FFDC class which will take a buffer
+as an argument and generate the correct FFDC.
+
+ <hwpError>
+ <rc>RC_FAPI2_BUFFER</rc>
+ <description>
+ fapi2 error from a buffer operation
+ </description>
+ <buffer>BUFFER</buffer>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+And its FFDC class:
+
+ class rc_fapi2_buffer
+ {
+ public:
+ rc_fapi2_buffer( ... )
+ { FAPI_ERR("fapi2 error from a buffer operation"); }
+
+ rc_fapi2_buffer& set_buffer(const fapi2::variable_buffer& i_value)
+ { ... }
+
+ template< typename T >
+ rc_fapi2_buffer& set_buffer(const fapi2::buffer<T>& i_value)
+ { ... }
+ };
+
+And it can be used:
+
+ fapi2::buffer<uint64_t> foo;
+ fapi2::variable_buffer bar;
+
+ FAPI_ASSERT( rc != FAPI2_RC_SUCCESS,
+ rc_fapi2_buffer().set_fapi2_buffer(foo),
+ "problem with buffer" );
+
+ FAPI_ASSERT( rc != FAPI2_RC_SUCCESS,
+ rc_fapi2_buffer().set_fapi2_buffer(bar),
+ "problem with buffer" );
+
+Note the indifference to integral or variable buffers.
+
+## Error Log Generation
+
+FAPI had a function called fapiLogError() which would generate platform
+errors. The pattern was to call fapiLogError() at the end of the block
+which generated the FFDC. With the addition of the FFDC classes, this
+is no longer needed - the class knows to create these logs for you.
+
+However, the severity information is needed by this logging mechanism.
+It was an argument to fapiLogError(), and so it's been added to the
+constructor of the FFDC class:
+
+rc_repair_ring_invalid_ringbuf_ptr(fapi2::errlSeverity_t i_sev, ...)
+
+It defaults to "unrecoverable" and so only need be set for errors
+which have a different severity. That is, doing nothing will get you
+and error log with unrecoverable severity - which was the default
+for FAPI.
+
+## Known Limitations
+
+- Collecting register FFDC is not presently implemented.
+- Calling out to hwp to collect FFDC is not presently implemented.
+- The FirstFailureData class does not have a platform pointer \ No newline at end of file
diff --git a/src/ppe/hwpf/fapi/docs/topics/README.md b/src/ppe/hwpf/fapi/docs/topics/README.md
new file mode 100755
index 0000000..ee7a9f0
--- /dev/null
+++ b/src/ppe/hwpf/fapi/docs/topics/README.md
@@ -0,0 +1,166 @@
+
+# FAPI 2 and FAPI Lite definitions for targets, buffers, error handling.
+
+## Were are some examples?
+
+Examples can be found in the "Related Pages" tab. These examples are constantly
+being expanded, please check back often.
+
+## How is the code structured?
+
+There is a new namespace; fapi2. This was created to prevent
+the FAPI 1 code, in the fapi namespace, from colliding with the new code.
+
+- Most documentation can be found under the class definition.
+- Documentation for FAPI_TRY/FAPI_ASSERT is in the file error_scope.H,
+ and doesn't have a "tab" in the HTML like the classes and the namespaces do.
+- The documentation for TargeType is in the fapi namespace section.
+
+## What do I need to implement for my platform?
+
+### fapi2::buffer and fapi2::variable_buffer
+There should be nothing for platforms to implement in the buffer code.
+Smaller platforms which use fapi2::variable_buffer will need to
+ensure they have an implementation of std::vector. Hostboot has one
+which I'm sure you can steal if needed.
+
+### fapi2::Target and fapi2::TargetType
+Target is defined as a template of <TargetType, Value> where
+Value is defined per platform. Smaller platforms will want an integer
+type here, say uint64_t. Larger platforms may want to change this to
+a pointer to an underlying platform specific targeting object.
+
+The target traversing functions will need to be implemented per-platform.
+
+### Hardware Access (fapi2::getScom() ...)
+
+All of the hardware access functions are assumed to need implementation
+per platform.
+
+Please use template specialization for target types which need special
+treatment. The API documented here are generic, but they can be made
+very specific for a target type or composite type.
+
+For example (perhaps a poor example ...)
+
+ template< TargetType K >
+ ReturnCode getScom(const Target<K>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& o_data)
+can become
+
+ template<>
+ ReturnCode getScom(const Target<TARGET_TYPE_DIMM>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& o_data)
+for DIMMs
+
+or
+
+ template<>
+ ReturnCode getScom(const Target<TARGET_TYPE_XBUS | TARGET_TYPE_ABUS>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& o_data)
+
+for XBUS and ABUS
+
+### fapi2::ReturnCode and error_scope.H
+
+For smaller platforms, a fapi::ReturnCode is nothing but a uint64_t. For
+larger platforms fapi2::ReturnCode inherits from a (TBD) FFDC object.
+
+There should be nothing to do for error_scope.H
+
+### fapi2::FirstFailureData (FFDC (work in progress))
+
+The platform specific FFDC object will need to be implemented, but the
+tooling to generate the FFDC functions used in FAPI_ASSERT will be provided.
+
+### Attributes
+
+As in FAPI 1, platforms will need to implement the mechanism behind the
+ATTR_GET/SET macros.
+
+## How to report an issue?
+
+Something in here is wrong - I'm sure of it. But you found it before someone
+else. Please don't fire off an email into the ether; it will get lost.
+Report an issue. Issues can be tracked and you can see what other issues are
+taking priority over yours, etc. It's just better for everyone.
+
+__To report an issue use Clear Quest__
+ - Tier: ip Firmware
+ - Reported Release: FW910
+ - Subsystem: Hostboot
+ - Component: FAPI
+
+## Not sure how to do something?
+
+So you've read the API documentation and it's horrible. You can't figure
+out how to get anything done. Could be an issue, could be you just need the
+crazy engineer who specified this horrible mess to see what struggles they
+created in their overzealous attempt to make things "simple."
+
+__Put it on the wiki__
+
+You could send someone an email, and that might work out great. But if you
+use the wiki you can be abrasive with your comments! Others might be able
+to help or offer an opinion or become a member of the virtual posse you're
+gathering to track down the crazy engineer. Good fun? You need a hobby.
+
+None the less, the crazy engineer should update the FAPI 2 documentation when
+the best practice is worked out, or create an issue to track the change
+(and add it to a test case.)
+
+Examples can be found in the "Related Pages" tab.
+
+Questions have been asked as topics on the PFD/HW for P9 community wiki.
+
+## Something missing? Before you report an issue ...
+
+Many of the API from FAPI 1 have been changed into templated functions. For
+example,
+
+ ecmdDataBuffer::getDoubleWordLength() -> fapi::buffer::getLength<uint64_t>()
+ ecmdDataBuffer::getWordLength() -> fapi::buffer::getLength<uint32_t>()
+ ecmdDataBuffer::getHalfWordLength() -> fapi::buffer::getLength<uint16_t>()
+
+Some API have been deprecated in favor of other API, some API have been
+deprecated and are waiting for a use-case, and they'll be implemented.
+A list of deprecated ecmdDataBuffer functions can be found in the
+fapi::buffer_base class documentation.
+
+Some API have been removed/deprecated and are expected to return in a different
+form once the requirements are understood. Examples of this are the compressed
+fapi::buffers. While platforms may need these functions, they have been removed
+from the class itself as they are not vital to the class operation. These
+functions, as needed, will be replaced with utility functions which perform the
+operations needed for the platform. An example is fapi::Target::toString.
+It has been replaced with fapi::toString(Target, ...) which can be overloaded
+to take any type, and makes a nice utility for the fapi namespace.
+
+Some API have plum been forgotten. You should open an issue so we can track
+the implementation.
+
+## Where's the documentation for Attributes?
+
+The attribute macros are not expected to change for FAPI 2:
+
+ l_rc = FAPI_ATTR_GET(<ID>, l_pTarget, l_val);
+ l_rc = FAPI_ATTR_SET(<ID>, l_pTarget, l_val);
+ l_rc = FAPI_ATTR_GET_PRIVILEGED(<ID>, l_pTarget, l_val);
+ l_rc = FAPI_ATTR_SET_PRIVILEGED(<ID>, l_pTarget, l_val);
+
+There is one outstanding question:
+ 1. whether we should/can change from a pointer to a target to a reference
+ to a target to save a dereference on the smaller platforms (maybe it gets
+ optimized out anyway?)
+
+ Seems like the answer will be "no," but this depends on the PPE attribute
+ look up scheme I think. Work in Progress.
+
+## Where's the FFDC documentation?
+
+Currently scheduled for End of February, 2015.
+
+## Other Known Issues
+
+- Thread local storage is broken on gcc 4.8, and the thread_local variables in
+error_scope.H will need to become pthread TLS for the time being.
diff --git a/src/ppe/hwpf/fapi/include/buffer.H b/src/ppe/hwpf/fapi/include/buffer.H
new file mode 100755
index 0000000..411ed53
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/buffer.H
@@ -0,0 +1,423 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/buffer.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 buffer.H
+ * @brief definitions for fapi2 variable integral buffers
+ */
+
+#ifndef __FAPI2_INTEGRAL_BUFFER__
+#define __FAPI2_INTEGRAL_BUFFER__
+
+#include <buffer_base.H>
+#include <return_code.H>
+
+namespace fapi2
+{
+ /// @brief Class representing a FAPI buffer<T>
+ /// @note Buffers support method chaining. So, rather than
+ /// this
+ /// @code
+ /// buffer<T> mask;
+ /// mask.setBit<B>();
+ /// mask.invert();
+ /// my_buffer &= mask;
+ /// @endcode
+ /// You can do
+ /// @code
+ /// my_buffer &= buffer<T>().setBit<B>.invert();
+ /// @endcode
+ template <typename T>
+ class buffer : public buffer_base<T>
+ {
+ public:
+ /// Shortcut typedef to map to our traits class
+ typedef typename buffer_base<T, buffer>::bits_type bits_type;
+
+ ///
+ /// @brief Integral buffer assignment constructor
+ /// @param[in] i_value initial value of the buffer
+ /// Meaningless for variable types and thus protected.
+ ///
+ inline buffer(T i_value = 0)
+ {
+ // Why not an initializer list? That would force buffer_base<T>
+ // to have a ctor which took a T, and I want to avoid that in
+ // the generic case: this makes it more clear that the two
+ // ctor's (integral and container) behave very differently.
+ // variable_buffers also have a ctor which takes a single
+ // numerical value, and that represents a bit count, not an
+ // initial value.
+ this->iv_data = i_value;
+ }
+
+
+ /// @name Bit/Word Manipulation Functions
+ ///@{
+
+ ///
+ /// @brief Return the length of the buffer in bits
+ /// @return Length in bits
+ ///
+ inline constexpr uint32_t getBitLength(void) const
+ { return bufferTraits<T>::bit_length(this->iv_data); }
+
+ ///
+ /// @brief Return the length of the buffer in OT units
+ /// @return Length in OT units rounded up
+ /// @tparam OT the type to get the length of. For example, if one
+ /// wanted the length in double words, OT would be uint64_t
+ /// (getLength<uint64_t>().) Similarly, to get the length in words,
+ /// getLength<uin32_t>().
+ ///
+ template< typename OT >
+ inline constexpr uint32_t getLength(void) const
+ {
+ return bufferTraits<T>::template size<OT>(this->iv_data);
+ }
+
+ ///
+ /// @brief Templated setBit for integral types
+ /// @tparam B the bit number to set.
+ /// @return buffer& Useful for method chaining
+ /// @note 0 is left-most
+ /// @note Example: fapi2::buffer<uint64_t>().setBit<3>();
+ ///
+ template <bits_type B>
+ inline buffer& setBit(void)
+ {
+ static_assert((B >= 0) &&
+ (B < bufferTraits<T>::bits_per_unit), "failed range check");
+
+ // Force iv_data to be dependent on the template type to force
+ // its look up in the second phase
+ this->iv_data |= (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit - B - 1);
+ return *this;
+ }
+
+ ///
+ /// @brief Clear a bit in buffer
+ /// @tparam B Bit in buffer to clear.
+ /// @return buffer& Useful for method chaining
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type B >
+ inline buffer& clearBit(void)
+ {
+ static_assert((B >= 0) &&
+ (B < bufferTraits<T>::bits_per_unit), "failed range check");
+
+ this->iv_data &= buffer<T>().setBit<B>().invert();
+ return *this;
+ }
+
+ ///
+ /// @brief Invert bit
+ /// @tparam B Bit in buffer to invert.
+ /// @return buffer& Useful for method chaining
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type B >
+ inline buffer& flipBit(void)
+ {
+ static_assert((B >= 0) &&
+ (B < bufferTraits<T>::bits_per_unit), "failed range check");
+
+ this->iv_data ^= buffer<T>().setBit<B>();
+ return *this;
+ }
+
+ ///
+ /// @brief Set a bit in the buffer
+ /// @param[in] i_bit the bit number to set.
+ /// @note 0 is left-most
+ /// @return FAPI2_RC_SUCCESS if OK
+ ///
+ inline fapi2::ReturnCode setBit(const bits_type& i_bit)
+ {
+ if (i_bit >= bufferTraits<T>::bits_per_unit)
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ // Force iv_data to be dependent on the template type to force
+ // its look up in the second phase
+ this->iv_data |=
+ (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit - i_bit - 1);
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Get the value of a bit in the buffer
+ /// @tparam B Bit in buffer to get.
+ /// @return true if bit is on, false if bit is off
+ ///
+ template< bits_type B >
+ inline bool getBit(void) const
+ {
+ return buffer<T>().setBit<B>() & this->iv_data;
+ }
+
+ ///@}
+
+ /// @name Buffer Manipulation Functions
+ ///@{
+
+ // Note: Many (all?) of these are not needed and the compiler complains
+ // as the cast to T yields a better operator. There are here mainly for
+ // documenation purposes.
+
+ ///
+ /// @brief operator>>()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator>>(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator<<()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator<<(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator+()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator+(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator+=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator+=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator|=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator&=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator|(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator&(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator^=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator^=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator~()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator~(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief operator==()
+ ///
+#ifdef DOXYGEN
+ bool operator==(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief operator!=()
+ ///
+#ifdef DOXYGEN
+ bool operator!=(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief Copy part of a OT into the DataBuffer
+ /// @tparam TS Start bit to insert into (target start)
+ /// @tparam L Length of bits to insert
+ /// @tparam SS Start bit in source
+ /// @tparam OT the type of the incoming (origin) data
+ /// @param[in] i_datain OT value to copy into DataBuffer
+ /// - data is taken left aligned
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template<bits_type TS, bits_type L, bits_type SS, typename OT>
+ inline void insert(const OT i_datain)
+ {
+ const bits_type target_length = parameterTraits<T>::bit_length;
+ const bits_type source_length = parameterTraits<OT>::bit_length;
+
+ // Error if input data don't make sense
+ static_assert((TS + L) <= target_length,
+ "insert(): (Target Start + Len) is out of bounds");
+ static_assert((SS + L) <= source_length,
+ "insert(): (Source Start + Len) is out of bounds");
+ static_assert(TS < target_length,
+ "insert(): Target Start is out of bounds");
+ static_assert(SS < source_length,
+ "insert(): Source Start is out of bounds");
+
+ // Get mask value for Target buffer
+ // Note: Need "& ((T)-1) because bit shift left for Target buffer doesn't roll off
+ T mask =((T(~0) << (target_length - L)) & T(~0)) >> TS;
+
+ // Calculate the equivalent position of the input Source start for the size of the Target buffer.
+
+ // Assume OT is smaller (sizeof(T) > sizeof(OT))
+ uint64_t sourceShift = abs(TS - ((target_length - source_length) + SS));
+ uint64_t sourceAlign = T(i_datain) << sourceShift;
+
+ if (sizeof(T) == sizeof(OT))
+ {
+ sourceShift = abs(SS - TS);
+ sourceAlign = (SS > TS) ? ((T)i_datain) << sourceShift : ((T)i_datain) >> sourceShift;
+ }
+
+ if (sizeof(T) < sizeof(OT))
+ {
+ sourceShift = source_length - target_length;
+ if (SS <= sourceShift)
+ {
+ sourceShift = sourceShift + TS - SS;
+ sourceAlign = ((OT)i_datain) >> sourceShift;
+ }
+
+ // (SS > sourceShift)
+ else
+ {
+ if (sourceShift > TS)
+ {
+ sourceShift = SS - sourceShift - TS;
+ sourceAlign = OT(i_datain) << sourceShift;
+ }
+ else
+ {
+ sourceShift = SS - sourceShift;
+ sourceAlign = (sourceShift < TS) ? OT(i_datain) >> sourceShift : OT(i_datain);
+ }
+ }
+ }
+
+ this->iv_data = (this->iv_data & ~mask) | (sourceAlign & mask);
+ return;
+ }
+
+ ///
+ /// @brief Copy in a right aligned value
+ /// @tparam SB Start bit to insert into
+ /// @tparam L Length of bits to insert
+ /// @tparam OT the type of the incoming (origin) data
+ /// @param[in] i_datain OT value to copy into DataBuffer
+ /// - data is taken right aligned
+ /// @note Data is assumed to be aligned on the word boundary of L
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template<bits_type TS, bits_type L, typename OT>
+ inline void insertFromRight(const OT i_datain)
+ {
+ // Error if input data don't make sense
+ static_assert(L < parameterTraits<OT>::bit_length,
+ "insertFromRight(): Len >= input buffer");
+ static_assert(TS < parameterTraits<T>::bit_length,
+ "insertFromRight(): Target Start is out of bounds");
+ static_assert((TS + L) <= parameterTraits<T>::bit_length,
+ "InsertFromRight(): (Target Start + Len) is out of bounds");
+
+ this->insert<TS, L, parameterTraits<OT>::bit_length - L>(i_datain);
+ return;
+ }
+
+ ///
+ /// @brief Copy data from this buffer into an OT
+ /// @tparam TS Start bit to insert into (target start)
+ /// @tparam L Length of bits to insert
+ /// @tparam SS Start bit in source
+ /// @tparam OT the type of the outgoing (target)
+ /// @param[out] o_out OT to copy into - data is placed left aligned
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template<bits_type TS, bits_type L, bits_type SS, typename OT>
+ inline void extract(OT& o_out)
+ {
+ // Extraction is just an insert into o_out
+
+ buffer<OT> out(o_out);
+ out.insert<TS, L, SS>(this->iv_data);
+ o_out = out;
+ return;
+ }
+
+#if 0
+ ///
+ /// @brief Copy data from this buffer into an OT and right justify
+ /// @tparam OT the type of the outgoing data - defaults to T
+ /// @tparam SB Start bit to insert into - defaults to 0
+ /// @tparam SS Start bit in o_out - default value is zero
+ /// @tparam L Length of bits to copy - defaults to sizeof(OT) * 8
+ /// @param[out] o_out OT to copy into - data is placed right aligned
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @post Data is copied from specified location to o_out, right
+ /// aligned. Data is only right aligned if L < sizeof(bits_type)
+ ///
+ template< typename OT = T, bits_type L = parameterTraits<OT>::bit_length,
+ bits_type SB = 0, bits_type SS = 0 >
+ void extractFromRight(OT& o_out);
+#endif
+ ///@}
+ };
+};
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/buffer_base.H b/src/ppe/hwpf/fapi/include/buffer_base.H
new file mode 100755
index 0000000..c93d770
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/buffer_base.H
@@ -0,0 +1,331 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/buffer_base.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 buffer_base.H
+ * @brief definitions for fapi2 buffer base class
+ */
+
+#ifndef __FAPI2_BUFFER_BASE__
+#define __FAPI2_BUFFER_BASE__
+
+#include <stdint.h>
+#include <initializer_list>
+#include <error_scope.H>
+#include <buffer_parameters.H>
+#include <buffer_traits.H>
+#include <return_code.H>
+
+namespace fapi2
+{
+ /// @brief Base class for buffers and variable buffers
+ /// @tparam T is the type of iv_data (std::vector, etc)
+ /// @tparam TT is the template trait, defaults to the trait for T
+ ///
+ /// Buffers can be of two styles; buffers made from an integral type and
+ /// buffers made from a container. Integral type buffers, while limited
+ /// in size, can be tightly controlled via the compiler by using c++
+ /// templates.
+ ///
+ /// C++ templates allow for very explicit control, but yield a
+ /// syntax different than the FAPI 1.x functional interface. For example,
+ /// a fapi2::buffer is defined as having a type:
+ /// @code
+ /// fapi2::buffer<uint64_t> new_buffer;
+ /// @endcode
+ /// defines a buffer with exactly 64 bits, and can be manipulated by the
+ /// compiler as a single intrgral value. These implementations result
+ /// in concise instruction streams, and a platform may choose to implement
+ /// all or some or none of the integral buffer types.
+ ///
+ /// Buffers which have containers as their underlying implementation
+ /// are found in the class fapi2::variable_buffer. variable_buffer is little
+ /// more than
+ /// @code
+ /// fapi2::buffer<fapi2::bits_container>
+ /// @endcode
+ /// where bits_container is the typedef of the underlying container (a
+ /// vector of uint32_t, for example)
+ ///
+ /// Examples:<br>
+ ///
+ /// * Simple uint64_t buffer
+ /// @code
+ /// const uint32_t x = 2;
+ ///
+ /// // this data buffer will contain data in a uint64_t type
+ /// fapi2::buffer<uint64_t> data;
+ ///
+ /// // Set using the template and a constant
+ /// data.setBit<x>();
+ ///
+ /// // Set using the template and a value
+ /// data.setBit<3>();
+ ///
+ /// // Set using the function interface, and a value
+ /// data.setBit(1);
+ ///
+ /// // compiler gets smart.
+ /// // movabs $0x7000000000000000,%rsi
+ /// @endcode
+ ///
+ /// * variable_buffer, same thing
+ /// @code
+ ///
+ /// const uint32_t x = 2;
+ ///
+ /// // Note: only 15 bits long
+ /// fapi2::variable_buffer data(15);
+ ///
+ ///
+ /// data.setBit(x);
+ /// data.setBit(3);
+ /// data.setBit(1);
+ /// @endcode
+ ///
+ /// * method chaining
+ /// Buffers support method chaining. So, rather than
+ /// this
+ /// @code
+ /// buffer<T> mask;
+ /// mask.setBit<B>();
+ /// mask.invert();
+ /// my_buffer &= mask;
+ /// @endcode
+ /// You can do
+ /// @code
+ /// my_buffer &= buffer<T>().setBit<B>.invert();
+ /// @endcode
+ ///
+ /// * buffer operations
+ /// @code
+ ///
+ /// // An 8 bit buffer, initialized with a value
+ /// fapi2::buffer<uint8_t> eight_bits = 0xAA;
+ /// fapi2::buffer<uint8_t> another_eight;
+ /// fapi2::buffer<uint16_t> sixteen_bits;
+ ///
+ /// // You can't assign an 8 bit buffer to a 16 bit buffer.
+ /// sixteen_bits = eight_bits; ERROR
+ ///
+ /// // But you can assign buffers of the same type
+ /// another_eight = eight_bits;
+ ///
+ /// // You can assign constants (or other known values) directly:
+ /// sixteen_bits = 0xAABB;
+ /// @endcode
+ ///
+ /// * Variable buffer operations
+ ///
+ /// @code
+ /// fapi2::variable_buffer data(16);
+ ///
+ /// // Very large buffers can be initialized rather than set bit by bit.
+ /// const fapi2::variable_buffer bit_settings_known(
+ /// {0xFFFF0000, 0xAABBF0F0,
+ /// 0xFFFF0000, 0xAABBF0F0,
+ /// 0xFFFF0000, 0xAABBF0F0,});
+ ///
+ /// // Assignment will expand or shrink the size automatically.
+ /// data = bit_settings_known;
+ ///
+ /// // You can assign directly to the buffer:
+ /// fapi2::variable_buffer other_bits;
+ /// const fapi2::container_unit x = 0xFF00AA55;
+ /// other_bits = {x, 0xDEADBEEF};
+ /// @endcode
+ ///
+ template <typename T, typename TT = bufferTraits<T> >
+ class buffer_base
+ {
+
+ public:
+
+ /// Shortcut typedef to get to our traits class
+ typedef typename TT::bits_type bits_type;
+ /// Shortcut typedef to get to our traits class
+ typedef typename TT::unit_type unit_type;
+
+ ///
+ /// @brief Default constructor
+ /// @note iv_data will get the "default" construction, which is
+ /// correct - 0 for integral types, an empty container for the others.
+ ///
+ buffer_base(void):
+ iv_data()
+ {}
+
+ virtual ~buffer_base(void)
+ {}
+
+#ifndef DOXYGEN
+ /// @brief Print the contents of the buffer to stdout
+ inline void print(void) const
+ { TT::print(iv_data); }
+#endif
+ ///
+ /// @brief Get the contents of the buffer
+ /// @return The contents of the buffer
+ ///
+ inline operator T() const { return iv_data; }
+
+ ///
+ /// @brief Get the contents of the buffer
+ /// @return The contents of the buffer
+ ///
+ inline operator T&() { return iv_data; }
+
+ ///
+ /// @brief Get the contents of the buffer
+ /// @return The contents of the buffer
+ ///
+ inline T& operator()(void) { return iv_data; }
+
+ ///
+ /// @brief Get the contents of the buffer
+ /// @return Reference to the contents of the buffer
+ ///
+ inline const T& operator()(void) const { return iv_data; }
+
+ ///
+ /// @brief Get a pointer to the buffer bits
+ /// @return Pointer to the buffer itself
+ ///
+ inline T* pointer(void) { return &iv_data; }
+
+ /// @name Buffer Manipulation Functions
+ ///@{
+
+ ///
+ /// @brief Set an OT of data in buffer
+ /// @param[in] i_value sizeof(OT) bits of data
+ /// @param[in] i_offset Start OT (start word, for example) in buffer
+ /// - defaults to 0 (will by default write the left most element)
+ /// @return FAPI2_RC_SUCCESS on success, FAPI2_RC_OVERFLOW otherwise
+ /// @note This is is only available for integral types. To set a
+ /// variable_buffer into a variable_buffer, use insert()
+ ///
+ template< typename OT>
+ inline fapi2::ReturnCode set(OT i_value, const bits_type i_offset = 0)
+ {
+ // Compile time check to make sure OT isn't a variable buffer
+ static_assert( !std::is_same<bits_container, OT>::value,
+ "Can't use a variable_buffer as input to set()" );
+
+ //
+ // There's a gotcha in here. size<OT>() returns the size in the buffer
+ // in OT units *rounded up*. This is the actual size of the buffer, not
+ // the perceived size of a variable_buffer. This should be OK however,
+ // as what we're trying to prevent is overflow, which this should do.
+ //
+ const uint32_t length = TT:: template size<OT>(iv_data);
+ static const bits_type bits_in_value = parameterTraits<OT>::bit_length;
+ const bits_type bit_length = TT::bit_length(iv_data);
+
+ if (i_offset >= length)
+ {
+ return FAPI2_RC_OVERFLOW;
+ }
+
+ // Create mask if part of this byte is not in the valid part of the buffer,
+ // Shift it left by the amount of unused bits,
+ // Clear the unused bits
+ if (((i_offset + 1) == length) && (bit_length % bits_in_value)) {
+ i_value &= parameterTraits<OT>::mask << ((bits_in_value * length) - bit_length);
+ }
+
+ parameterTraits<OT>::template write_element<unit_type>(TT::get_address(iv_data), i_value, i_offset);
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Set and entire buffer to X's
+ /// @tparam X {0,1} depending if you want to clear (0)
+ /// or fill (1) a buffer
+ ///
+ template< uint8_t X >
+ inline void flush(void)
+ {
+ static_assert( (X == 1) || (X == 0), "bad argument to flush" );
+ (0 == X) ? TT::clear(iv_data) : TT::set(iv_data);
+ }
+
+ ///
+ /// @brief Invert entire buffer
+ /// @return buffer_base&, Useful for method chaining
+ ///
+ inline buffer_base& invert(void)
+ { TT::invert(iv_data); return *this; }
+
+ ///
+ /// @brief Bit reverse entire buffer
+ /// @return buffer_base&, Useful for method chaining
+ ///
+ inline buffer_base& reverse(void)
+ { TT::reverse(iv_data); return *this; }
+
+ //@}
+ protected:
+
+ ///
+ /// @brief Variable buffer constructor
+ /// @param[in] i_value number of *bits* (sizeof(container_units) * 8)
+ /// needed. Meaningless for integral types and thus protected.
+ ///
+ buffer_base(bits_type i_value);
+
+ ///
+ /// @brief Variable buffer construct from a list
+ /// @param[in] i_value an initializer list to initialize the container.
+ /// Meaningless for integral types and thus protected
+ ///
+ buffer_base(std::initializer_list<unit_type> i_value);
+
+ ///
+ /// @brief Clear the buffer
+ ///
+ inline void clear(void)
+ { TT::clear(iv_data); }
+
+ /// The contents of the buffer
+ T iv_data;
+ };
+
+ template <typename T, typename TT>
+ inline buffer_base<T, TT>::buffer_base(bits_type i_value):
+ iv_data( std::max(bits_type(1),
+ bits_type(i_value / 8 / sizeof(bits_type))))
+ {
+ }
+
+ template <typename T, typename TT>
+ inline buffer_base<T, TT>::buffer_base(std::initializer_list<unit_type> i_value):
+ iv_data(i_value)
+ {
+ }
+};
+
+
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/buffer_parameters.H b/src/ppe/hwpf/fapi/include/buffer_parameters.H
new file mode 100755
index 0000000..cee4531
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/buffer_parameters.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/buffer_parameters.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 buffer_parameters.H
+ * @brief definitions for fapi2 buffer parameter types
+ */
+
+#ifndef __FAPI2_BUFFER_PARAM__
+#define __FAPI2_BUFFER_PARAM__
+
+#include <stdint.h>
+
+namespace fapi2
+{
+ /// @cond
+ /// @brief Traits of buffer parameters - things passed in
+ /// @tparam T is the type of i_value (typically an integral type)
+ template<typename T>
+ class parameterTraits
+ {
+ public:
+ enum
+ {
+ mask = T(~0),
+ bit_length = sizeof(T) * 8,
+ byte_length = sizeof(T),
+ };
+
+ template<typename U>
+ inline static void write_element(void* i_data, T i_value, uint32_t i_offset)
+ {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ T* ptr = (T*)i_data + (i_offset ^ ((sizeof(U) / sizeof(T)) - 1));
+#else
+ T* ptr = (T*)i_data + i_offset;
+#endif
+ *ptr = i_value;
+ }
+ };
+ /// @endcond
+};
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/buffer_traits.H b/src/ppe/hwpf/fapi/include/buffer_traits.H
new file mode 100755
index 0000000..3d5955e
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/buffer_traits.H
@@ -0,0 +1,232 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/buffer_traits.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 buffer_traits.H
+ * @brief trait definitions for fapi2 buffer base class
+ */
+
+#ifndef __FAPI2_BUFFER_TRAITS__
+#define __FAPI2_BUFFER_TRAITS__
+
+#include <stdint.h>
+#include <vector>
+#include <algorithm>
+#include <buffer_parameters.H>
+
+// for debug printing ... can be removed for flight
+#include <iostream>
+#include <iterator>
+
+namespace fapi2
+{
+ /// @cond
+ /// Types representing a container of bits. Used to create
+ /// variable_buffer.
+ typedef uint32_t container_unit;
+ typedef std::vector<container_unit> bits_container;
+
+ /// @brief Traits of buffers
+ // In general, we try to give buffers traits reflecting integral types. If
+ // this fails, the compiler will let someone know.
+ ///
+ /// @tparam T is the type of iv_data (std::vector, etc)
+ /// @tparam B is the type of the bit-specifier, typically uint32_t
+ template<typename T, typename B = uint32_t>
+ class bufferTraits
+ {
+ public:
+#ifndef DOXYGEN
+ ///
+ /// @brief Print a container of bits
+ /// @param[in] i_data the container of bits
+ ///
+ static inline void print(const T& i_data)
+ {
+ // convert to uint64_t to prevent uint8_t from being
+ // printed as a char.
+ std::cout << "\tdata is "
+ << std::hex
+ << static_cast<uint64_t>(i_data)
+ << std::dec << std::endl;
+ }
+#endif
+
+ ///
+ /// @brief Return the size of the buffer in E units
+ /// @tparam E, the element size.
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in E's rounded up
+ ///
+ template<typename E>
+ constexpr static B size(const T& i_buffer)
+ {
+ return (bit_length(i_buffer) +
+ (parameterTraits<E>::bit_length - 1)) /
+ parameterTraits<E>::bit_length;
+ }
+
+ ///
+ /// @brief Return the size of the buffer itself
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in bits (not units)
+ ///
+ constexpr static B bit_length(const T&)
+ { return sizeof(T) * 8; }
+
+ ///
+ /// @brief Clear the buffer
+ /// @param[in,out] io_buffer the buffer which to clear
+ ///
+ static inline void clear(T& io_buffer)
+ { io_buffer = static_cast<T>(0); }
+
+ ///
+ /// @brief Set the buffer
+ /// @param[in,out] io_buffer the buffer which to set
+ ///
+ static inline void set(T& io_buffer)
+ { io_buffer = static_cast<T>(~0); }
+
+ ///
+ /// @brief Invert the buffer
+ /// @param[in,out] io_buffer the buffer which to invert
+ ///
+ static inline void invert(T& io_buffer)
+ { io_buffer = ~io_buffer; }
+
+ ///
+ /// @brief Reverse the buffer
+ /// @param[in,out] io_buffer the buffer which to reverse
+ ///
+ static inline void reverse(T& io_buffer)
+ {
+ io_buffer =
+ ((io_buffer & 0xAAAAAAAAAAAAAAAA) >> 1) |
+ ((io_buffer & 0x5555555555555555) << 1);
+ }
+
+ ///
+ /// @brief Get the address of the buffer as an array
+ /// @param[in] i_buffer the buffer which to invert
+ /// @return The address of the first element of the buffer
+ ///
+ static inline void* get_address(T& i_buffer)
+ { return (void*)&i_buffer; }
+
+ typedef B bits_type;
+ typedef T unit_type;
+ enum { bits_per_unit = sizeof(unit_type) * 8 };
+ };
+
+ //
+ //
+ /// @brief Traits for buffers which are a container of bits
+ //
+ //
+ template<>
+ class bufferTraits<bits_container, uint32_t>
+ {
+ public:
+#ifndef DOXYGEN
+ ///
+ /// @brief Print a container of bits
+ /// @param[in] i_data the container of bits
+ ///
+ static inline void print(const bits_container& i_data)
+ {
+ std::cout << "\tdata is " << std::hex;
+ std::copy(i_data.begin(), i_data.end(),
+ std::ostream_iterator<container_unit>(std::cout, " "));
+ std::cout << std::dec << std::endl;
+ }
+#endif
+
+ ///
+ /// @brief Return the size of the buffer in E units
+ /// @tparam E, the element size.
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in E's rounded up
+ ///
+ template<typename E>
+ constexpr static uint32_t size(const bits_container& i_buffer)
+ {
+ return (bit_length(i_buffer) +
+ (parameterTraits<E>::bit_length - 1)) /
+ parameterTraits<E>::bit_length;
+ }
+
+ ///
+ /// @brief Return the size of the buffer itself
+ /// @param[in,out] io_buffer the buffer which to size
+ /// @return The size of the buffer in bits (not units)
+ ///
+ static inline uint32_t bit_length(const bits_container& i_buffer)
+ { return i_buffer.size() * sizeof(container_unit) * 8; }
+
+ ///
+ /// @brief Clear the buffer
+ /// @param[in,out] io_buffer the buffer which to clear
+ ///
+ static inline void clear(bits_container& io_buffer)
+ { io_buffer.assign(io_buffer.size(), 0); }
+
+ ///
+ /// @brief Set the buffer
+ /// @param[in,out] io_buffer the buffer which to set
+ ///
+ static inline void set(bits_container& io_buffer)
+ { io_buffer.assign(io_buffer.size(), ~0); }
+
+ ///
+ /// @brief Invert the buffer
+ /// @param[in,out] io_buffer the buffer which to invert
+ ///
+ static inline void invert(bits_container& io_buffer)
+ {
+ std::transform(io_buffer.begin(), io_buffer.end(),
+ io_buffer.begin(),
+ [](container_unit u) { return ~u; });
+ }
+
+ ///
+ /// @brief Get the address of the buffer as an array
+ /// @param[in] i_buffer the buffer which to invert
+ /// @return The address of the first element of the buffer
+ ///
+ static inline void* get_address(bits_container& i_buffer)
+ {
+ return (void*)&(i_buffer[0]);
+ }
+
+ typedef uint32_t bits_type;
+ typedef container_unit unit_type;
+ enum { bits_per_unit = sizeof(unit_type) * 8 };
+ };
+ /// @endcond
+};
+
+
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/collect_reg_ffdc.H b/src/ppe/hwpf/fapi/include/collect_reg_ffdc.H
new file mode 100755
index 0000000..661cdda
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/collect_reg_ffdc.H
@@ -0,0 +1,80 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/collect_reg_ffdc.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file collect_reg_ffdc.H
+ *
+ * @brief Defines the collectRegFfdc function that collects chip or
+ * chiplet register FFDC data. This is called automatically by
+ * FAPI_SET_HWP_ERROR (when a HWP creates an error) and
+ * FAPI_ADD_INFO_TO_HWP_ERROR (when an FFDC HWP adds error information
+ * to an existing error) if the error XML contains a
+ * <collectRegisterFfdc> element. This function should not be called
+ * directly by any user code. The function implementation is
+ * automatically generated from FAPI Error XML files.
+ */
+
+#ifndef FAPI2_COLLECT_REG_FFDC_H_
+#define FAPI2_COLLECT_REG_FFDC_H_
+
+#include <target.H>
+#include <return_code.H>
+#include <ffdc.H>
+#include <hwp_error_info.H>
+
+namespace fapi2
+{
+
+ ///
+ /// @brief Collects Register FFDC from a chip or chiplet
+ ///
+ /// @warning This should only be called by FAPI during FAPI_SET_HWP_ERROR or
+ /// FAPI_ADD_INFO_TO_HWP_ERROR
+ ///
+ /// @param[in] i_target Pointer to Target to collect FFDC from
+ /// @param[in] i_ffdcId FFDC Identifier
+ /// @param[out] o_rc Reference to ReturnCode that FFDC is added to
+ /// @param[in] i_child Specifies type of i_target's chiplet to collect
+ /// FFDC from. If this parameter is TARGET_TYPE_NONE
+ /// (default value), then register FFDC is collected
+ /// from i_target, else, register FFDC is collected
+ /// from all functional child chiplets i_target of
+ /// the specified type
+ /// @param[in] i_presChild When specified, register FFDC will be collected
+ /// from i_target's registers based on present chiplets
+ /// of this type.
+ /// @param[in] i_childOffsetMult Specifies the chiplet position offset multiplier.
+ /// This is used in calculating the scom register
+ /// addresses when collecting register FFDC based on
+ /// present child chiplets.
+ ///
+ void collectRegFfdc(const fapi2::Target<TARGET_TYPE_ALL>* i_target,
+ const fapi2::HwpFfdcId i_ffdcId,
+ fapi2::ReturnCode & o_rc,
+ const TargetType i_child = TARGET_TYPE_NONE,
+ const TargetType i_presChild = TARGET_TYPE_NONE,
+ uint32_t i_childOffsetMult = 0);
+}
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/error_info.H b/src/ppe/hwpf/fapi/include/error_info.H
new file mode 100755
index 0000000..d87aa8c
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/error_info.H
@@ -0,0 +1,854 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/error_info.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file error_info.H
+/// @brief Defines the Error Information structures and classes
+///
+
+#ifndef FAPI2_ERRORINFO_H_
+#define FAPI2_ERRORINFO_H_
+
+#include <stdint.h>
+#include <memory>
+#include <vector>
+#include <target.H>
+#include <assert.h>
+
+namespace fapi2
+{
+ class ReturnCode;
+
+ ///
+ /// @brief Type to hold the ffdc element in the ffdc class
+ /// Needed so that the size can be squirled away before the
+ /// macro is called.
+ ///
+ class ffdc_t
+ {
+ public:
+ ffdc_t(void)
+ {}
+
+ operator const void*() const { return iv_value.first; }
+ operator const uint8_t() const
+ { return *(reinterpret_cast<const uint8_t*>(iv_value.first)); }
+
+ int16_t size(void) const { return iv_value.second; }
+ int16_t& size(void) { return iv_value.second; }
+
+ const void* ptr(void) const { return iv_value.first; }
+ const void*& ptr(void) { return iv_value.first; }
+
+ private:
+ std::pair<const void*, int16_t> iv_value;
+ };
+
+ ///
+ /// @brief Enumeration of ErrorInfo FFDC sizes that are used to indicate a
+ /// special type that cannot simply be memcopied
+ enum ErrorInfoFfdcSize
+ {
+ EI_FFDC_SIZE_BUF = 0xffff, // fapi2::buffer<T>
+ EI_FFDC_SIZE_TARGET = 0xfffe, // fapi2::Target
+ EI_FFDC_SIZE_VBUF = 0xfffd, // fapi2::variable_buffer
+ EI_FFDC_MAX_SIZE = 0x1000, // Limit regular FFDC capture to 4kb
+ };
+
+ ///
+ /// @brief Enumeration of error log severity.
+ ///
+ enum errlSeverity_t
+ {
+ FAPI2_ERRL_SEV_RECOVERED = 0x10, /// Not seen by customer
+ FAPI2_ERRL_SEV_PREDICTIVE = 0x20, /// Error recovered but customer will see
+ FAPI2_ERRL_SEV_UNRECOVERABLE = 0x40 /// Unrecoverable, general
+ };
+
+ ///
+ /// @brief Enumeration of ErrorInfo types
+ ///
+ enum ErrorInfoType
+ {
+ EI_TYPE_FFDC = 0,
+ EI_TYPE_HW_CALLOUT = 1,
+ EI_TYPE_PROCEDURE_CALLOUT = 2,
+ EI_TYPE_BUS_CALLOUT = 3,
+ EI_TYPE_CDG = 4, // Target Callout/Deconfig/GARD
+ EI_TYPE_CHILDREN_CDG = 5, // Children Callout/Deconfig/GARD
+ EI_TYPE_COLLECT_TRACE = 6,
+ EI_LAST_TYPE = EI_TYPE_COLLECT_TRACE + 1,
+ };
+
+ ///
+ /// @enum HwCallout
+ ///
+ /// This enumeration defines the possible Hardware Callouts that are not
+ /// represented by fapi2::Targets
+ ///
+ /// Note that platform code may depend on the enum values starting at 0 and
+ /// incrementing in order to efficiently convert to a platform callout value
+ /// so do not reorder without consulting all platforms
+ ///
+ namespace HwCallouts
+ {
+ enum HwCallout
+ {
+ // Where indicated, a HW Callout in FAPI Error XML must include a
+ // reference target that is used to identify the HW. e.g. for
+ // TOD_CLOCK, the proc chip that the clock is attached to must be
+ // specified
+ TOD_CLOCK = 0, // Include proc-chip ref (or child chiplet)
+ MEM_REF_CLOCK = 1, // Include membuf-chip ref (or child chiplet)
+ PROC_REF_CLOCK = 2, // Include proc-chip ref (or child chiplet)
+ PCI_REF_CLOCK = 3, // Include proc-chip ref (or child chiplet)
+ FLASH_CONTROLLER_PART = 4,
+ PNOR_PART = 5,
+ SBE_SEEPROM_PART = 6,
+ VPD_PART = 7,
+ LPC_SLAVE_PART = 8,
+ GPIO_EXPANDER_PART = 9,
+ SPIVID_SLAVE_PART = 10,
+ };
+ }
+
+ ///
+ /// @enum ProcedureCallout
+ ///
+ /// This enumeration defines the possible Procedure Callouts
+ /// These instruct the customer/customer-engineer what to do
+ ///
+ /// Note that platform code may depend on the enum values starting at 0 and
+ /// incrementing in order to efficiently convert to a platform callout value
+ /// so do not reorder without consulting all platforms
+ ///
+ namespace ProcedureCallouts
+ {
+ enum ProcedureCallout
+ {
+ CODE = 0, // Code problem
+ LVL_SUPPORT = 1, // Call next level of support
+ MEMORY_PLUGGING_ERROR = 2, // DIMM Plugging error
+ BUS_CALLOUT = 3, // Bus Called Out
+ };
+ }
+
+ ///
+ /// @enum CalloutPriority
+ ///
+ /// This enumeration defines the possible Procedure and Target callout priorities
+ ///
+ /// Note that platform code may depend on the enum values starting at 0 and
+ /// incrementing in order to efficiently convert to a platform priority value
+ /// so do not reorder without consulting all platforms
+ ///
+ namespace CalloutPriorities
+ {
+ enum CalloutPriority
+ {
+ LOW = 0,
+ MEDIUM = 1,
+ HIGH = 2,
+ };
+ }
+
+ ///
+ /// @enum Collect Trace
+ ///
+ /// This enumeration defines the possible firmware traces to collect
+ ///
+ namespace CollectTraces
+ {
+ const uint32_t TRACE_SIZE = 256; // limit collected trace size
+ enum CollectTrace
+ {
+ FSI = 1,
+ SCOM = 2,
+ SCAN = 3,
+ MBOX = 4,
+ };
+ }
+
+ ///
+ /// @brief Get FFDC Size
+ ///
+ /// This is called by the FAPI_SET_HWP_ERROR macro to find out the size of
+ /// FFDC data. If the data is of a special type that is handled differently
+ /// than types that are simply memcopied then it is handled by a template
+ /// specialization.
+ /// If this function template is instantiated with a pointer, the compile
+ /// will fail.
+ ///
+ /// @return uint16_t. Size of the FFDC data
+ ///
+ template<typename T>
+ inline uint16_t getErrorInfoFfdcSize(const T &)
+ {
+ static_assert(sizeof(T) <= EI_FFDC_MAX_SIZE,
+ "FFDC too large to capture");
+ return sizeof(T);
+ }
+
+ ///
+ /// @brief Compile error if caller tries to get the FFDC size of a pointer
+ ///
+ template<typename T>
+ inline uint16_t getErrorInfoFfdcSize(const T*)
+ {
+ static_assert(std::is_pointer<T>::value,
+ "pointer passed to getErrorInfoFfdcSize");
+ }
+
+ ///
+ /// @brief Get FFDC Size specialization for fapi2::Target
+ ///
+ template<>
+ inline uint16_t getErrorInfoFfdcSize(const fapi2::Target<TARGET_TYPE_ALL>*)
+ {
+ return EI_FFDC_SIZE_TARGET;
+ }
+
+ ///
+ /// @brief Get FFDC Size specialization for ffdc method arguments
+ /// @note The ffdc class sets the std::pair when the method is
+ /// called so the size has been calculated. All that needs to be
+ /// done here is to grab it. We do it this way so the macro definitions
+ /// can be the same whether the ffdc class is used or the old-school
+ /// locals.
+ ///
+ template<>
+ inline uint16_t getErrorInfoFfdcSize(const fapi2::ffdc_t& i_thing)
+ {
+ return i_thing.size();
+ }
+
+ ///
+ /// @class ErrorInfoFfdc
+ ///
+ /// This class contains a copy of some FFDC data
+ ///
+ class ErrorInfoFfdc
+ {
+ public:
+ ///
+ /// @brief Constructor
+ ///
+ /// @param[in] i_ffdcId FFDC Identifier (used to decode FFDC)
+ /// @param[in] i_pFfdc Pointer to the FFDC to copy
+ /// @param[in] i_size Size of the FFDC to copy
+ ///
+ ErrorInfoFfdc(const uint32_t i_ffdcId,
+ const void* i_pFfdc,
+ const uint32_t i_size);
+
+ ///
+ /// @brief Get a pointer to the FfdcData
+ ///
+ /// @param[out] o_size Reference to uint32_t that is filled in with
+ /// the FFDC size
+ ///
+ /// @return void *. Pointer to the FFDC
+ ///
+ inline const void* getData(uint32_t & o_size) const
+ {
+ o_size = iv_size;
+ return iv_pFfdc.get();
+ }
+
+ ///
+ /// @brief Get a pointer to the FfdcData
+ /// @return void *. Pointer to the FFDC
+ ///
+ inline void* getData(void) const
+ { return iv_pFfdc.get(); }
+
+ ///
+ /// @brief Get the FFDC Identifier
+ ///
+ /// @return uint32_t The FFDC Identifier
+ ///
+ inline uint32_t getFfdcId(void)
+ { return iv_ffdcId; }
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ private:
+
+ // FFDC Identifier
+ uint32_t iv_ffdcId;
+
+ // Pointer to the FFDC
+ std::shared_ptr<uint8_t> iv_pFfdc;
+
+ // Size of the FFDC
+ uint32_t iv_size;
+
+ // Disabled
+ ErrorInfoFfdc(const ErrorInfoFfdc &) = delete;
+ ErrorInfoFfdc & operator=(const ErrorInfoFfdc &) = delete;
+ };
+
+ ///
+ /// @struct ErrorInfoHwCallout
+ ///
+ /// This struct contains hardware to callout
+ ///
+ struct ErrorInfoHwCallout
+ {
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_hw Hardware to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ /// @param[in] i_refTarget Reference to reference target
+ ///
+ ErrorInfoHwCallout(
+ const HwCallouts::HwCallout i_hw,
+ const CalloutPriorities::CalloutPriority i_calloutPriority,
+ const Target<TARGET_TYPE_ALL> & i_refTarget);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The hw to callout
+ HwCallouts::HwCallout iv_hw;
+
+ // The callout priority
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+
+ // The reference target (needed for some HW callouts to identify what to
+ // callout). The target handle is NULL if there is no reference target.
+ Target<TARGET_TYPE_ALL> iv_refTarget;
+ };
+
+ ///
+ /// @struct ErrorInfoProcedureCallout
+ ///
+ /// This struct contains a procedure to callout
+ ///
+ struct ErrorInfoProcedureCallout
+ {
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_procedure Procedure to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoProcedureCallout(
+ const ProcedureCallouts::ProcedureCallout i_procedure,
+ const CalloutPriorities::CalloutPriority i_calloutPriority);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The procedure to callout
+ ProcedureCallouts::ProcedureCallout iv_procedure;
+
+ // The callout priority
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+ };
+
+ ///
+ /// @struct ErrorInfoBusCallout
+ ///
+ /// This struct contains a bus to callout
+ ///
+ struct ErrorInfoBusCallout
+ {
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target1 Reference to target on one end of the bus
+ /// @param[in] i_target2 Reference to target on other end of the bus
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoBusCallout(
+ const Target<TARGET_TYPE_ALL> & i_target1,
+ const Target<TARGET_TYPE_ALL> & i_target2,
+ const CalloutPriorities::CalloutPriority i_calloutPriority);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The targets on each end of the bus to callout
+ Target<TARGET_TYPE_ALL> iv_target1;
+ Target<TARGET_TYPE_ALL> iv_target2;
+
+ // The callout priority
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+ };
+
+ ///
+ /// @struct ErrorInfoCDG
+ ///
+ /// This struct contains a target to callout/deconfigure/GARD
+ ///
+ struct ErrorInfoCDG
+ {
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target Reference to the target to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @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
+ ///
+ 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);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The target to callout/deconfigure/GARD
+ Target<TARGET_TYPE_ALL> iv_target;
+
+ // Callout Information
+ bool iv_callout;
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+
+ // Deconfigure Information
+ bool iv_deconfigure;
+
+ // GARD Information
+ bool iv_gard;
+ };
+
+ ///
+ /// @struct ErrorInfoChildrenCDG
+ ///
+ /// This struct contains children targets to callout/deconfigure/GARD
+ ///
+ /// Children by containment can be CDG (chiplets belonging to a parent chip)
+ /// e.g.
+ /// - PROC_CHIP -> EX_CHIPLET
+ /// - MEMBUF_CHIP -> MBA_CHIPLET
+ /// Children by affinity can be CDG.
+ /// Any from PROC_CHIP->MCS_CHIPLET->MEMBUF_CHIP->MBA_CHIPLET->DIMM e.g.
+ /// - PROC_CHIP->MEMBUF_CHIP
+ /// - MEMBUF_CHIP->DIMM
+ /// - MBA_CHIPLET->DIMM
+ /// Port and Number criteria can be applied to the child target as
+ /// detailed in the constructor
+ ///
+ struct ErrorInfoChildrenCDG
+ {
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_parent Reference to the parent target
+ /// @oaram[in] i_childType Child target type to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @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_childPort Child Port
+ /// For DIMM children, the MBA port number
+ /// @param[in] i_childNum Child Number
+ /// For DIMM children, the dimm socket number
+ /// For Chip children, the chip position
+ /// For Chiplet children, the chiplet unit pos
+ ///
+ ErrorInfoChildrenCDG(const Target<TARGET_TYPE_ALL> & i_parentChip,
+ const TargetType i_childType,
+ const bool i_callout,
+ const bool i_deconfigure,
+ const bool i_gard,
+ const CalloutPriorities::CalloutPriority i_priority,
+ const uint8_t i_childPort, const uint8_t i_childNum);
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // The parent chip
+ Target<TARGET_TYPE_ALL> iv_parent;
+
+ // The child target types to c/d/g
+ TargetType iv_childType;
+
+ // Callout Information
+ bool iv_callout;
+ CalloutPriorities::CalloutPriority iv_calloutPriority;
+
+ // Deconfigure Information
+ bool iv_deconfigure;
+
+ // GARD Information
+ bool iv_gard;
+
+ // Child Port
+ static const uint8_t ALL_CHILD_PORTS = 0xff;
+ uint8_t iv_childPort;
+
+ // Child Number
+ static const uint8_t ALL_CHILD_NUMBERS = 0xff;
+ uint8_t iv_childNumber;
+ };
+
+ ///
+ /// @struct ErrorInfoCollectTrace
+ ///
+ /// This struct contains trace ID to add to the error log
+ ///
+ struct ErrorInfoCollectTrace
+ {
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_trace
+ ///
+ ErrorInfoCollectTrace(CollectTraces::CollectTrace i_traceId);
+
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // trace
+ CollectTraces::CollectTrace iv_eiTraceId;
+ };
+
+ ///
+ /// @struct ErrorInfo
+ ///
+ /// This struct defines the error information associated with a fapi2::ffdc
+ /// Users are allowed to access the data directly
+ ///
+ struct ErrorInfo
+ {
+
+#ifdef FAPI_CUSTOM_MALLOC
+ ///
+ /// @brief Overload new operator to use platform-specific allocator
+ ///
+ /// @param[in] i_sz Size of memory to allocate in bytes
+ ///
+ /// @return Pointer to allocated memory
+ ///
+ static void* operator new(size_t i_sz);
+
+ ///
+ /// @brief Overload delete operator to use platform-specific deallocator
+ ///
+ /// @param[in] i_ptr Pointer to memory previously allocated with new
+ ///
+ static void operator delete(void* i_ptr);
+#endif
+
+ // Vector of FFDC Data
+ std::vector<std::shared_ptr<ErrorInfoFfdc> > iv_ffdcs;
+
+ // Vector of Hardware to callout
+ std::vector<std::shared_ptr<ErrorInfoHwCallout> > iv_hwCallouts;
+
+ // Vector of procedures to callout
+ std::vector<std::shared_ptr<ErrorInfoProcedureCallout> >
+ iv_procedureCallouts;
+
+ // Vector of buses to callout
+ std::vector<std::shared_ptr<ErrorInfoBusCallout> > iv_busCallouts;
+
+ // Vector of targets to callout/deconfigure/GARD
+ std::vector<std::shared_ptr<ErrorInfoCDG> > iv_CDGs;
+
+ // Vector of children targets to callout/deconfigure/GARD
+ std::vector<std::shared_ptr<ErrorInfoChildrenCDG> > iv_childrenCDGs;
+
+ // Vector of traces to collect
+ std::vector<std::shared_ptr<ErrorInfoCollectTrace> > iv_traces;
+ };
+
+ ///
+ /// @brief Structure representing a single ErrorInfo entry.
+ ///
+ /// An array of these is passed to the addErrorInfo function when a HWP
+ /// generates an error by calling the FAPI_SET_HWP_ERROR macro
+ // Why aren't these inherited classes? Saves on allocation overhead.
+ // We create an array of ErrorInfoEntries as automatics when we start
+ // FFDC collection. If we did this as inherited classes it would either
+ // be allocating and deallocating or we'd need to allocate an array of
+ // the largest and map each struct in to it. That's messy to do without
+ // unions (that's what they're for) so we do it like this. The inherited
+ // model would result in a jump table anyway, so we're basically doing
+ // all of that by hand to avoid the mess.
+ //
+ struct ErrorInfoEntryFfdc
+ {
+ uint8_t iv_ffdcObjIndex;
+ uint16_t iv_ffdcSize;
+ uint32_t iv_ffdcId;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+ };
+
+ ///
+ /// @brief Structure representing a hardware callout
+ ///
+ struct ErrorInfoEntryHwCallout
+ {
+ uint8_t iv_hw;
+ uint8_t iv_calloutPriority;
+ uint8_t iv_refObjIndex;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+ };
+
+ ///
+ /// @brief Structure representing a procedure callout
+ ///
+ struct ErrorInfoEntryProcCallout
+ {
+ uint8_t iv_procedure;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+
+ ErrorInfoEntryProcCallout(uint8_t i_procedure, uint8_t i_calloutPriority):
+ iv_procedure(i_procedure),
+ iv_calloutPriority(i_calloutPriority)
+ {}
+
+ ErrorInfoEntryProcCallout(void) = default;
+ };
+
+ ///
+ /// @brief Structure representing a bus callout
+ ///
+ struct ErrorInfoEntryBusCallout
+ {
+ uint8_t iv_endpoint1ObjIndex;
+ uint8_t iv_endpoint2ObjIndex;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+ };
+
+ ///
+ /// @brief Structure representing a target callout
+ ///
+ struct ErrorInfoEntryTargetCDG
+ {
+ uint8_t iv_targetObjIndex;
+ uint8_t iv_callout;
+ uint8_t iv_deconfigure;
+ uint8_t iv_gard;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+ };
+
+ ///
+ /// @brief Structure representing a child callout
+ ///
+ struct ErrorInfoEntryChildrenCDG
+ {
+ uint8_t iv_parentObjIndex;
+ uint8_t iv_callout;
+ uint8_t iv_deconfigure;
+ uint32_t iv_childType;
+ uint8_t iv_childPort;
+ uint8_t iv_childNumber;
+ uint8_t iv_gard;
+ uint8_t iv_calloutPriority;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+ };
+
+ ///
+ /// @brief Structure representing collected trace information
+ ///
+ struct ErrorInfoEntryCollectTrace
+ {
+ uint32_t iv_eieTraceId;
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const;
+ };
+
+ ///
+ /// @brief Union of all the error info types
+ ///
+ struct ErrorInfoEntry
+ {
+ uint8_t iv_type; // Value from ErrorInfoType
+ union
+ {
+ ErrorInfoEntryFfdc ffdc;
+ ErrorInfoEntryHwCallout hw_callout;
+ ErrorInfoEntryProcCallout proc_callout;
+ ErrorInfoEntryBusCallout bus_callout;
+ ErrorInfoEntryTargetCDG target_cdg;
+ ErrorInfoEntryChildrenCDG children_cdg;
+ ErrorInfoEntryCollectTrace collect_trace;
+ };
+
+ ///
+ /// @brief Add error information to the FFDC object
+ /// @param[in] i_info a shared pointer to the error info
+ /// @param[in] i_object the list of ffdc objects being collected
+ ///
+ void addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ // "unhandled error info type");
+ assert(iv_type < EI_LAST_TYPE);
+
+ switch(iv_type)
+ {
+ case EI_TYPE_FFDC:
+ ffdc.addErrorInfo(i_info, i_object);
+ break;
+ case EI_TYPE_HW_CALLOUT:
+ hw_callout.addErrorInfo(i_info, i_object);
+ break;
+ case EI_TYPE_PROCEDURE_CALLOUT:
+ proc_callout.addErrorInfo(i_info, i_object);
+ break;
+ case EI_TYPE_BUS_CALLOUT:
+ bus_callout.addErrorInfo(i_info, i_object);
+ break;
+ case EI_TYPE_CDG:
+ target_cdg.addErrorInfo(i_info, i_object);
+ break;
+ case EI_TYPE_CHILDREN_CDG:
+ children_cdg.addErrorInfo(i_info, i_object);
+ break;
+ case EI_TYPE_COLLECT_TRACE:
+ collect_trace.addErrorInfo(i_info, i_object);
+ break;
+ };
+ return;
+ }
+ };
+}
+
+#endif // FAPI2_ERRORINFO_H_
diff --git a/src/ppe/hwpf/fapi/include/error_scope.H b/src/ppe/hwpf/fapi/include/error_scope.H
new file mode 100755
index 0000000..1078235
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/error_scope.H
@@ -0,0 +1,104 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/error_scope.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 error_scope.H
+ * @brief definitions which create a scope for automatic error handling
+ */
+
+#ifndef __FAPI2_ERROR_SCOPE__
+#define __FAPI2_ERROR_SCOPE__
+
+#include <stdint.h>
+#include <thread>
+#include <stdio.h>
+#include <return_code.H>
+
+/// @cond
+#define FAPI_VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
+#define FAPI_VA_NARGS(...) FAPI_VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
+
+#define FAPI_TRY_IMPL2(count, ...) FAPI_TRY ## count (__VA_ARGS__)
+#define FAPI_TRY_IMPL(count, ...) FAPI_TRY_IMPL2(count, __VA_ARGS__)
+
+#define FAPI_TRY_NO_TRACE( __operation__ ) \
+ if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \
+ { \
+ goto clean_up; \
+ }
+
+// Why debug? Because this isn't a mechanism to gather FFDC
+// one should be using FAPI_ASSERT. However, it is nice to
+// have a conditional trace in the event of a failure in the
+// operation, so that's why this is here.
+#define FAPI_TRY_TRACE( __operation__, ... ) \
+ if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \
+ { \
+ FAPI_DBG(__VA_ARGS__); \
+ goto clean_up; \
+ }
+
+#define FAPI_TRY1 FAPI_TRY_NO_TRACE
+#define FAPI_TRY2 FAPI_TRY_TRACE
+#define FAPI_TRY3 FAPI_TRY_TRACE
+#define FAPI_TRY4 FAPI_TRY_TRACE
+#define FAPI_TRY5 FAPI_TRY_TRACE
+/// @endcond
+
+///
+/// @brief Wrapper to check an operation for an error state
+/// and jump to the label cleam_up if there is an error.
+/// @param[in] __operation__ an operation which returns a fapi::ReturnCode
+/// @param[in] ... vararg format/agruments for trace output (optional)
+/// @note This implementation does not support PIB error masks or
+/// FSP operational states.
+/// @warning The trace information is only going to be seen during
+/// debug, it's not an error or informational trace. This is because
+/// traces might not be seen in the field. If you want information
+/// you will see on a field error, use FAPI_ASSERT.
+///
+#ifdef DOXYGEN
+#define FAPI_TRY(__operation__, ...) FAPI_TRY_IMPL
+#else
+#define FAPI_TRY(...) FAPI_TRY_IMPL(FAPI_VA_NARGS(__VA_ARGS__), __VA_ARGS__)
+#endif
+
+///
+/// @brief Assert a conditional is true.
+/// If it is not, the FFDC gathering function is called and the
+/// trace is output as a FAPI error trace.
+/// @param[in] __conditional__ the condition to assert
+/// @param[in] __ffdc__ the FFDC gathering function
+/// @param[in] ... varargs, as input to FAPI_ERR
+///
+#define FAPI_ASSERT( __conditional__, __ffdc__, ... ) \
+ if (! (__conditional__)) \
+ { \
+ (__ffdc__).execute(); \
+ FAPI_ERR(__VA_ARGS__); \
+ goto clean_up; \
+ }
+
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/ffdc.H b/src/ppe/hwpf/fapi/include/ffdc.H
new file mode 100755
index 0000000..6a478e7
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/ffdc.H
@@ -0,0 +1,193 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/ffdc.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file ffdc.H
+ * @brief Defines the FirstFailureData class
+ */
+
+#ifndef FAPI2_FFDC_H_
+#define FAPI2_FFDC_H_
+
+#include <memory>
+#include <hwp_return_codes.H>
+#include <plat_trace.H>
+#include <error_info.H>
+#include <target.H>
+#include <assert.h>
+
+using fapi2::TARGET_TYPE_ALL;
+
+namespace fapi2
+{
+ ///
+ /// @brief Check the type of a variable
+ ///
+ /// This function can be called to check that a variable type is as expected
+ /// @note This mechanism will allow for cast ctor's which other static type
+ /// checking might not.
+ ///
+ template<typename T>
+ inline
+ void checkType(const T &) {}
+
+ class ReturnCode;
+
+ ///
+ /// @class FirstFailureData
+ ///
+ /// This class provides storage and methods for creating and manipulating
+ /// FFDC.
+ /// It is not needed on all platforms - platforms which need this class have
+ /// specified this by forcing their fapi2::ReturnCode to be a subclass of
+ /// this class.
+ ///
+ template< class R = fapi2::ReturnCode >
+ class FirstFailureData
+ {
+ public:
+
+ ///
+ /// @brief Default constructor.
+ /// @note We don't create our error info be default. It will be created
+ /// when its needed in the setHwpError() method. Note that dereferencing
+ /// the error info without will create a problem.
+ ///
+ FirstFailureData(void):
+ iv_info( nullptr )
+ {}
+
+ ///
+ /// @brief Copy Constructor
+ ///
+ /// @param[in] i_right Reference to FirstFailureData to copy
+ /// @note Generates default copy constructor - no deep pointer
+ /// copies necessary.
+ ///
+ FirstFailureData(const FirstFailureData & i_right) = default;
+
+ ///
+ /// @brief Destructor
+ ///
+ ~FirstFailureData(void) = default;
+
+ ///
+ /// @brief Assignment Operator.
+ ///
+ /// @param[in] i_right Reference to FirstFailureData to assign from.
+ /// @return Reference to 'this' FirstFailureData
+ ///
+ FirstFailureData & operator=(const FirstFailureData & i_right) = default;
+
+ ///
+ /// @brief Sets a HWP error. Sets the rcValue to the supplied value (from
+ /// the HwpFirstFailureData enumeration) and deletes any
+ /// associated data.
+ ///
+ /// HWP code must call the FAPI_SET_HWP_ERROR macro rather than this
+ /// function
+ /// directly to generate an error so that any error information is
+ /// automatically added to the FirstFailureData
+ ///
+ /// @param[in] i_rcValue Error value to set
+ ///
+ inline void _setHwpError(const fapi2::HwpReturnCode i_rcValue)
+ {
+ FAPI_ERR("_setHwpError: Creating HWP error 0x%x", i_rcValue);
+ static_cast<R*>(this)->operator=(i_rcValue);
+
+ // Forget about any associated data (this is a new error)
+ iv_info.reset(new ErrorInfo());
+ }
+
+ ///
+ /// @brief Get a pointer to any PlatData. FirstFailureData is still
+ /// responsible for deletion of the data. The caller must not
+ /// delete
+ ///
+ /// This is called by PLAT. The expected use-case is to get a pointer to
+ /// a platform error log. The data pointer should be used immediately in
+ /// the same thread.
+ ///
+ /// @return void *. Pointer to any PlatData. If NULL then no data
+ ///
+ void* getData(void) const;
+
+ ///
+ /// @brief Get a pointer to any PlatData and release ownership from
+ /// FirstFailureData. The caller is responsible for deletion.
+ ///
+ /// This is called by PLAT. The expected use-case is to retrieve a
+ /// platform error log.
+ ///
+ /// @return void*. Pointer to any PlatData. If NULL then no data
+ ///
+ void* releaseData(void);
+
+ ///
+ /// @brief Add ErrorInfo
+ ///
+ /// This is called by the FAPI_SET_HWP_ERROR and macro to add ErrorInfo
+ /// to the FirstFailureData when a HWP generates an error. The function
+ /// is designed to add all the ErrorInfo at once rather than the
+ /// FAPI_SET_HWP_ERROR macro making multiple function calls to add each
+ /// piece of ErrorInfo individually in order to minimize code size
+ ///
+ /// @param[in] i_pObjects Pointer to array of const pointers to const
+ /// objects that are referred to by ErrorInfoEntry objects
+ /// @param[in] i_pEntries Pointer to array of ErrorInfoEntry objects
+ /// defining the ErrorInfo that needs to be added
+ /// @param[in] i_count Number of ErrorInfoEntry entries
+ ///
+ void addErrorInfo(const void* const * i_pObjects,
+ const ErrorInfoEntry* i_pEntries,
+ const uint8_t i_count);
+
+ ///
+ /// @brief Get a pointer to any ErrorInfo
+ ///
+ /// This is called by PLAT to find information about an error
+ ///
+ /// @return ErrorInfo *. Pointer to any ErrorInfo. If NULL then no info
+ ///
+ inline const fapi2::ErrorInfo* getErrorInfo(void) const
+ { return iv_info.get(); }
+
+ ///
+ /// @brief Forgets about any associated data (PlatData and ErrorInfo)
+ ///
+ /// If this is the only FirstFailureData pointing to the data then the
+ /// data is deleted
+ ///
+ inline void forgetData(void)
+ { iv_info = nullptr; }
+
+ private:
+
+ // Pointer to the data
+ std::shared_ptr<ErrorInfo> iv_info;
+ };
+
+};
+#endif // FAPI2_FFDC_H_
diff --git a/src/ppe/hwpf/fapi/include/hw_access.H b/src/ppe/hwpf/fapi/include/hw_access.H
new file mode 100755
index 0000000..8b915c6
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/hw_access.H
@@ -0,0 +1,720 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/hw_access.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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_access.H
+ *
+ * @brief Defines the hardware access functions that platform code must
+ * implement.
+ */
+
+#ifndef FAPI2_HWACCESS_H_
+#define FAPI2_HWACCESS_H_
+
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+#include <fapiSpyIds.H>
+#endif
+
+#include <stdint.h>
+#include <thread>
+#include <buffer.H>
+#include <variable_buffer.H>
+#include <return_code.H>
+#include <target.H>
+
+#ifdef FAPI_SUPPORT_MULTI_SCOM
+#include <fapiMultiScom.H>
+#endif
+
+/// @cond
+typedef uint64_t spyId_t;
+typedef uint64_t scanRingId_t;
+/// @endcond
+
+namespace fapi2
+{
+
+ ///
+ /// @enum fapi2::ChipOpModifyMode
+ /// @brief Enumeration of modify modes used in HW access modify operations
+ ///
+ enum ChipOpModifyMode
+ {
+ CHIP_OP_MODIFY_MODE_OR = 1, ///< Modify or mode
+ CHIP_OP_MODIFY_MODE_AND = 2, ///< Modify and mode
+ CHIP_OP_MODIFY_MODE_XOR = 3, ///< Modify xor mode
+ };
+
+ ///
+ /// @enum fapi2::RingMode
+ /// @brief Enumeration of Ring access operation modes
+ /// This is a bitmap to allow the user to specify multiple modes.
+ ///
+ enum RingMode
+ {
+ RING_MODE_SET_PULSE = 0x00000001, ///< Set pulse
+ RING_MODE_NO_HEADER_CHECK = 0x00000002, ///< Dont' check header
+ // FUTURE_MODE = 0x00000004,
+ // FUTURE_MODE = 0x00000008,
+ };
+
+ //--------------------------------------------------------------------------
+ // PIB Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the PIB error mask - platform dependant
+ /// @param[in] i_mask The new error mask
+ inline void setPIBErrorMask(uint8_t i_mask)
+ {
+ // Platform specific funtion needs to be defined here.
+ // For Cronus/FSP/Hostboot, this is a no-op.
+ return;
+ }
+
+ /// @brief Gets the PIB error mask - platform dependant
+ /// @return uint8_t The current PIB error mask
+ inline uint8_t getPIBErrorMask(void)
+ {
+ // Platform specific funtion needs to be defined here.
+ // For Cronus/FSP/Hostboot, this always returns 0
+ return 0;
+ }
+
+ //--------------------------------------------------------------------------
+ // Operational Mode Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @enum OpModes operational Mode Error Functions
+ enum OpModes
+ {
+ // These are bit-masks in case they need to be or'd together
+ NORMAL = 0x00,
+ IGNORE_HW_ERROR = 0x01,
+ DO_NOT_DO_WAKEUP = 0x02,
+ };
+
+ /// @brief Sets the operational mode
+ /// @param[in] i_mode The new mode
+ inline void setOpMode(const OpModes i_mode)
+ {
+ // No-op for now. Should set thread-local operational mode
+ return;
+ }
+
+ /// @brief Gets the operational mode
+ /// @return the operational mode
+ inline OpModes getOpMode(void)
+ {
+ // No-op for now. Should read thread-local operational mode
+ return NORMAL;
+ }
+
+ //--------------------------------------------------------------------------
+ // HW Communication Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Reads a SCOM register from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode getScom(const Target<K>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& o_data)
+ {
+ o_data = 0x0000FEEDFACE0000;
+ std::cout << std::hex << " getScom "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "output data: " << uint64_t(o_data)
+ << std::dec << std::endl;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Writes a SCOM register on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putScom(const Target<K>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& i_data)
+ {
+ std::cout << std::hex << " putScom "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "input data: " << uint64_t(i_data)
+ << std::dec << std::endl;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Read-modify-write a SCOM register on a chip
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor).
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode modifyScom(const Target<K>& i_target,
+ const uint64_t i_address,
+ const buffer<uint64_t>& i_data,
+ const ChipOpModifyMode i_modifyMode)
+ {
+ fapi2::buffer<uint64_t> l_modifyDataBuffer = i_data;
+ std::cout << std::hex << " modifyScom "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "input modifying data: " << uint64_t(l_modifyDataBuffer) << "; "
+ << "input ChipOpModifyMode: " << i_modifyMode
+ << std::dec << std::endl;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Writes a SCOM register under mask on a chip
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @param[in] i_mask Buffer that holds the mask value.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putScomUnderMask(const Target<K>& i_target,
+ const uint64_t i_address,
+ buffer<uint64_t>& i_data,
+ buffer<uint64_t>& i_mask)
+ {
+ std::cout << std::hex << " putScomUnderMask "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "input data: " << uint64_t(i_data) << "; "
+ << "input mask: " << uint64_t(i_mask)
+ << std::dec << std::endl;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Reads a CFAM register from a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode getCfamRegister(const Target<K>& i_target,
+ const uint32_t i_address,
+ buffer<uint32_t>& o_data)
+ {
+ o_data = 0xFEED0CFA;
+ std::cout << std::hex << " getCfamRegister "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "output data: " << uint32_t(o_data)
+ << std::dec << std::endl;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Writes a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putCfamRegister(const Target<K>& i_target,
+ const uint32_t i_address,
+ buffer<uint32_t>& i_data)
+ {
+ std::cout << std::hex << " putCfamRegister "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "input data: " << uint32_t(i_data)
+ << std::dec << std::endl;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Read-modify-write a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to modify.
+ /// @param[in] i_data Buffer that holds data to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor).
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode modifyCfamRegister(const Target<K>& i_target,
+ const uint32_t i_address,
+ const buffer<uint32_t>& i_data,
+ const ChipOpModifyMode i_modifyMode)
+ {
+ fapi2::buffer<uint32_t> l_modifyDataBuffer = i_data;
+ std::cout << std::hex << " modifyCfamRegister "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "input modifying data: " << uint32_t(l_modifyDataBuffer) << "; "
+ << "input ChipOpModifyMode: " << i_modifyMode
+ << std::dec << std::endl;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Reads a ring from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode getRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& o_data,
+ const RingMode i_ringMode = 0)
+ {
+ o_data.setBit(0);
+ o_data.setBit(3);
+ std::cout << std::hex << " getRing "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "ring address: " << i_address << "; "
+ << "ring mode: " << i_ringMode << "; "
+ << "output data:";
+ o_data.print();
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Writes a ring to a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to write to.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to write into address
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& i_data,
+ const RingMode i_ringMode = 0)
+ {
+ std::cout << std::hex << " putRing "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "ring mode: " << i_ringMode << "; "
+ << "input data:";
+ i_data.print();
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+
+ /// @brief Writes a ring to a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to write to.
+ /// @param[in] i_data Pointer to location that contains RS4 compressed
+ // ring data to write into address
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ const void* i_data,
+ const RingMode i_ringMode = 0)
+ {
+ uint64_t* dataPtr = reinterpret_cast<uint64_t*>(const_cast<void*>(i_data));
+ std::cout << std::hex << " putRing (void*) "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "ring mode: " << i_ringMode << "; "
+ << "input data: " << (uint64_t)(*dataPtr)
+ << (uint64_t)*(dataPtr+1)
+ << (uint64_t)*(dataPtr+2)
+ << (uint64_t)*(dataPtr+3);
+ std::cout << std::dec << std::endl;
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Read-modify-write a ring on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to modify.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor)
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode modifyRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& i_data,
+ const ChipOpModifyMode i_modifyMode,
+ const RingMode i_ringMode = 0)
+ {
+ std::cout << std::hex << " modifyRing "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "address: " << i_address << "; "
+ << "input ChipOpModifyMode: " << i_modifyMode << "; "
+ << "ring mode: " << i_ringMode << "; "
+ << "input data: ";
+ i_data.print();
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @note
+ /// These spy access interfaces are only used in FSP and cronus
+ /// HB does not allow spy access
+
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+ /// @brief Reads a spy from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy whose data to be read.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependant on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// it with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi::ReturnCode rc = fapiGetSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#endif
+
+// Set to 1 for fapi2 API test
+#define FAPI_SUPPORT_SPY_AS_ENUM 1
+
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+
+#ifndef DOXYGEN
+#define fapiGetSpy(TARGET, ID, DATA) \
+ _fapiGetSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA )
+#endif
+ template< TargetType K >
+ inline ReturnCode _fapiGetSpy(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data)
+ {
+ o_data.setBit(1);
+ o_data.setBit(4);
+ std::cout << std::hex << " _fapiGetSpy "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "Spy ID: " << i_spyId << "; "
+ << "output data:";
+ o_data.print();
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+#endif
+
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+
+#ifndef DOXYGEN
+#define fapiGetSpy(TARGET, ID, DATA) _fapiGetSpy(TARGET, #ID, DATA)
+#endif
+ template< TargetType K >
+ inline ReturnCode _fapiGetSpy(const Target<K>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+ /// @brief Writes a spy on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy to write data to.
+ /// @param[out] i_data Buffer that holds data to write into spy.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// is with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi::ReturnCode rc = fapiPutSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#endif
+
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+#ifndef DOXYGEN
+#define fapiPutSpy(TARGET, ID, DATA) \
+ _fapiPutSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA)
+#endif
+ template< TargetType K >
+ inline ReturnCode _fapiPutSpy(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& i_data)
+ {
+ std::cout << std::hex << " _fapiPutSpy "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "Spy Id: " << i_spyId << "; "
+ << "input data:";
+ i_data.print();
+
+ return FAPI2_RC_SUCCESS;
+ }
+#endif
+
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+#ifndef DOXYGEN
+#define fapiPutSpy(TARGET, ID, DATA) _fapiPutSpy(TARGET, #ID, DATA)
+#endif
+ template< TargetType K >
+ inline ReturnCode _fapiPutSpy(const Target<K>& i_target,
+ const char* const i_spyId,
+ variable_buffer& i_data);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(FAPI_SUPPORT_SPY_AS_STRING)
+
+ /// @brief Writes spy data into a buffer holding ring data image
+ /// This API is used by L2/L3 repair to put column repair data
+ /// into a ring buffer image.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy.
+ /// @param[in] i_data Buffer that holds spy data to write into ring
+ /// image.
+ /// @param[out] o_data Buffer that holds updated ring image.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#endif
+
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+#ifndef DOCUMENTATION
+#define fapiPutSpyImage(TARGET, ID, DATA1, DATA2) \
+ _fapiPutSpyImage(TARGET, \
+ FAPI_SPY_NAMES::ID.value, \
+ DATA1, DATA2)
+#endif
+ template< TargetType K >
+ inline ReturnCode _fapiPutSpyImage(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& i_data,
+ variable_buffer& o_imageData)
+ {
+ std::cout << std::hex << " _fapiPutSpyImage "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "Spy Id: " << i_spyId << "; "
+ << "input data: ";
+ i_data.print();
+
+ // Set fake output data
+ o_imageData.invert();
+
+ return FAPI2_RC_SUCCESS;
+ }
+#endif
+
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+// fapiPutSpyImage function Cronus version
+#ifndef DOCUMENTATION
+#define fapiPutSpyImage(TARGET, ID, DATA1, DATA2) \
+ _fapiPutSpyImage(TARGET, #ID, \
+ DATA1,DATA2)
+#endif
+
+ template< TargetType K >
+ inline ReturnCode _fapiPutSpyImage(const Target<K>& i_target,
+ const char* const i_spyId,
+ variable_buffer& i_data,
+ variable_buffer& o_imageData);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+ /// @brief Reads spy data from a ring image buffer
+ /// @param[in] i_target Target to operate on
+ /// @param[in] i_spyId The spy's id
+ /// @param[out] o_data Buffer that holds data read from ring image.
+ /// @param[in] i_imageData Buffer that holds ring image to read data
+ /// from.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#endif
+
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+#ifndef DOXYGEN
+#define fapiGetSpyImage(TARGET, ID, DATA1, DATA2) \
+ _fapiGetSpyImage(TARGET, \
+ FAPI_SPY_NAMES::ID.value, \
+ DATA1, DATA2)
+#endif
+ template< TargetType K >
+ inline ReturnCode _fapiGetSpyImage(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData);
+#endif
+
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+// fapiGetSpyImage function Cronus version
+#ifndef DOXYGEN
+#define fapiGetSpyImage(TARGET, ID, DATA1, DATA2) \
+ _fapiGetSpyImage(TARGET, \
+ #ID, DATA1,DATA2)
+#endif
+
+ inline fapi::ReturnCode _fapiGetSpyImage(
+ const fapi::Target& i_target,
+ const char* const i_spyId,
+ fapi::buffer<fapi::bits_container> & o_data,
+ const fapi::buffer<fapi::bits_container> & i_imageData);
+#endif
+
+#if defined(FAPI_SUPPORT_MULTI_SCOM) || defined(DOXYGEN)
+
+ /// @brief Performs a multiple SCOM operation
+ /// This interface performs multiple SCOM operations on a chip in the
+ /// order specified by the input MultiScom object.
+ /// See fapiMultiScom.H for details of how to populate the MultiScom
+ /// object with SCOM operations.
+ ///
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in,out] io_multiScomObj Reference to a MultiScom object,
+ /// pre-populated with SingleScomInfo entries
+ /// to perform multiple SCOMs on input target
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note This is a synchronous interface and would return after all the
+ /// SCOM operations are completed or on the first failed operation
+ ///
+ /// @note SCOMs will be performed in the order they were added to the
+ /// input MultiScom object
+ ///
+ /// @note In case of errors, the platform code is responsible to collect
+ /// and add all the required error info and FFDC into the error data
+ /// for debugging
+ ///
+ /// @note If the SCOM operations added are specific to a processor chip,
+ /// then the FSI Shift Engine configured in scatter-gather DMA mode
+ /// extension would be used to execute the SCOM operations in a
+ /// performance optimize mode. In this mode, the special
+ /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are
+ /// supported that allow a large bulk of SCOM access (in multiple of
+ /// 64 bits) for targets that support auto-increment. The
+ /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode
+ ///
+ /// @note If the SCOM operations added are specific to a memory buffer
+ /// chip, then the regular SCOM engine is used to execute the SCOM
+ /// operations. SCOM_WRITE_UNDER_MASK operation is supported in
+ /// this mode, but the special SCOM_BULK_READ_MODE and
+ /// SCOM_BULK_WRITE_MODE operations are not supported due to
+ /// hardware limitations.
+ ///
+ fapi::ReturnCode fapiMultiScom (const Target<K>& i_target,
+ MultiScom& io_multiScomObj);
+#endif // FAPI_SUPPORT_MULTI_SCOM
+
+};
+
+#endif // FAPI2HWACCESS_H_
diff --git a/src/ppe/hwpf/fapi/include/plat_trace.H b/src/ppe/hwpf/fapi/include/plat_trace.H
new file mode 100755
index 0000000..38da71d
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/plat_trace.H
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/plat_trace.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_trace.H
+ * @brief Defines the FAPI2 trace macros.
+ *
+ * Note that platform code must provide the implementation.
+ *
+ * FAPI has provided a default implementation. Platform code must
+ * provide an alternate implementation if needed.
+ */
+
+#ifndef FAPI2_PLATTRACE_H_
+#define FAPI2_PLATTRACE_H_
+
+#include <stdio.h>
+
+#define MAX_ECMD_STRING_LEN 64
+
+// Information traces (go into fast trace buffer that can wrap often)
+#define FAPI_TRACE(_id_, _fmt_, _args_...) \
+ printf("%s: %s:%d ", _id_, __func__, __LINE__); \
+ printf(_fmt_, ##_args_); \
+ printf("\n")
+
+#define FAPI_INF(_fmt_, _args_...) FAPI_TRACE("inf", _fmt_, ##_args_)
+
+// Important traces (go into slow trace buffer that should not wrap often)
+#define FAPI_IMP(_fmt_, _args_...) FAPI_TRACE("imp", _fmt_, ##_args_)
+
+// Error traces (go into slow trace buffer that should not wrap often)
+#define FAPI_ERR(_fmt_, _args_...) FAPI_TRACE("err", _fmt_, ##_args_)
+
+// Debug traces (go into fast trace buffer that can wrap often)
+#define FAPI_DBG(_fmt_, _args_...) FAPI_TRACE("dbg", _fmt_, ##_args_)
+
+// Scan traces
+#define FAPI_SCAN(_fmt_, _args_...) FAPI_TRACE("scan", _fmt_, ##_args_)
+
+#define FAPI_MFG(_fmt_, _args_...) FAPI_TRACE("mfg", _fmt_, ##_args_)
+
+#endif // FAPI2_PLATTRACE_H_
diff --git a/src/ppe/hwpf/fapi/include/return_code.H b/src/ppe/hwpf/fapi/include/return_code.H
new file mode 100755
index 0000000..f1b4451
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/return_code.H
@@ -0,0 +1,180 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/return_code.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 return_code.H
+ * @brief definitions for fapi2 return codes
+ */
+
+#ifndef __FAPI2_RETURN_CODE__
+#define __FAPI2_RETURN_CODE__
+
+#include <stdint.h>
+
+// Remove this for platforms which don't support FFDC
+#include <ffdc.H>
+
+///
+/// @brief Set HWP Error macro
+///
+/// This macro should be used by a HWP to create an error. The ReturnCode's
+/// internal return code is set and any error information in the Error XML file
+/// is added to the ReturnCode
+///
+#define FAPI_SET_HWP_ERROR(RC, ERROR) \
+ RC._setHwpError(fapi2::ERROR); \
+ ERROR##_CALL_FUNCS_TO_COLLECT_FFDC(RC); \
+ ERROR##_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC); \
+ ERROR##_ADD_ERROR_INFO(RC)
+
+///
+/// @brief Add info to HWP Error macro
+///
+/// This macro should be used by an FFDC HWP to add error information from an
+/// Error XML file to an existing error.
+///
+#define FAPI_ADD_INFO_TO_HWP_ERROR(RC, ERROR) \
+ ERROR##_CALL_FUNCS_TO_COLLECT_FFDC(RC); \
+ ERROR##_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC); \
+ ERROR##_ADD_ERROR_INFO(RC)
+
+namespace fapi2
+{
+ ///
+ /// @brief Enumeration of return codes
+ ///
+ enum ReturnCodes
+ {
+ ///< Success
+ FAPI2_RC_SUCCESS = 0,
+
+ // Flag bits indicating which code generated the error.
+ FAPI2_RC_FAPI2_MASK = 0x04000000, ///< FAPI2 mask
+ FAPI2_RC_PLAT_MASK = 0x02000000, ///< Platform mask
+ FAPI2_RC_HWP_MASK = 0x00000000, ///< HWP mask
+
+ //
+ // FAPI generated return codes
+ //
+
+ FAPI2_RC_INVALID_ATTR_GET = FAPI2_RC_FAPI2_MASK | 0x01,
+ ///< Initfile requested an attribute with an invalid attribute ID
+
+ FAPI2_RC_INVALID_CHIP_EC_FEATURE_GET = FAPI2_RC_FAPI2_MASK | 0x02,
+ ///< HWP requested a chip EC feature with an invalid attribute ID
+
+ FAPI2_RC_INVALID_MULTISCOM_LENGTH = FAPI2_RC_FAPI2_MASK | 0x03,
+ ///< Invalid multiscom parameters
+
+ FAPI2_RC_INVALID_PARAMETER = FAPI2_RC_FAPI2_MASK | 0x04,
+ ///< Invalid parameters to a FAPI2 function
+
+ FAPI2_RC_OVERFLOW = FAPI2_RC_FAPI2_MASK | 0x05,
+ ///< Overflow condition, typically a buffer operation
+
+ //
+ // PLAT generated return codes. Additional details may be contained in
+ // ReturnCode platData (this can only be looked at by PLAT code)
+ //
+
+ FAPI2_RC_PLAT_ERR_SEE_DATA = FAPI2_RC_PLAT_MASK | 0x01,
+ ///< Generic platform error
+
+ FAPI2_RC_PLAT_ERR_ADU_LOCKED = FAPI2_RC_PLAT_MASK | 0x02,
+ ///< Operation to AlterDisplay unit failed because it is locked
+
+ FAPI2_RC_PLAT_NOT_SUPPORTED_AT_RUNTIME = FAPI2_RC_PLAT_MASK | 0x03,
+ ///< Operation not supported by HB runtime
+ };
+
+ ///
+ /// @brief Class representing a FAPI2 ReturnCode
+ ///
+ /// @note Remove the inheritance relationship with FirstFailureData if
+ /// the platform doesn't support FFDC.
+ class ReturnCode : public FirstFailureData<ReturnCode>
+ {
+ public:
+
+ ///
+ /// @brief Constructor.
+ /// @param[in] i_rc the rc to set
+ ///
+ ReturnCode(const uint64_t i_rc = FAPI2_RC_SUCCESS):
+ iv_rc(i_rc)
+ {};
+
+ ///
+ /// @brief integral type conversion function. Returns the error code
+ /// @return The error code
+ ///
+ inline operator uint64_t() const { return iv_rc; }
+
+ ///
+ /// @brief Returns true iff iv_rc == SUCCESS
+ /// @return true or false
+ ///
+ inline operator bool() const { return iv_rc == FAPI2_RC_SUCCESS; }
+
+ ///
+ /// @brief Assignement operator
+ ///
+ inline ReturnCode& operator=(const uint64_t& rhs)
+ {
+ iv_rc = rhs;
+ return *this;
+ }
+
+ inline ReturnCode& operator=(const ReturnCodes& rhs)
+ {
+ iv_rc = rhs;
+ return *this;
+ }
+
+ inline bool operator==(const uint64_t& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator==(const ReturnCodes& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator!=(const uint64_t& rhs) const
+ { return rhs != iv_rc; }
+
+ inline bool operator!=(const ReturnCodes& rhs) const
+ { return rhs != iv_rc; }
+
+ private:
+ uint64_t iv_rc;
+ };
+
+ /// This implementation assumes no exception handling and leverages thread-local
+ /// storage. For platforms without thread support, a global variable will
+ /// suffice for the error state.
+ extern thread_local ReturnCode current_err; /// the current error state
+ extern thread_local uint64_t pib_error_mask; /// the pib mask
+ extern thread_local uint64_t operational_state; /// the operational mode
+
+};
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/target.H b/src/ppe/hwpf/fapi/include/target.H
new file mode 100755
index 0000000..3eacb17
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/target.H
@@ -0,0 +1,337 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/target.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 target.H
+ * @brief definitions for fapi2 targets
+ */
+
+#ifndef __FAPI2_TARGET__
+#define __FAPI2_TARGET__
+
+#include <stdint.h>
+#include <vector>
+#include <target_types.H>
+#include <stdio.h>
+
+namespace fapi2
+{
+ ///
+ /// @brief Enumeration of target state values (bitmask values)
+ ///
+ enum TargetState
+ {
+ TARGET_STATE_PRESENT = 0x00000001,
+ TARGET_STATE_FUNCTIONAL = 0x00000002,
+ };
+
+ ///
+ /// @brief Class representing a FAPI2 Target
+ /// @tparam K the type (Kind) of target
+ /// @tparam V the type of the target's Value
+ /// @remark TargetLite targets are uint64_t, Targets
+ /// are uintptr_t (void*).
+ ///
+ /// Assuming there are representations of a processor,
+ /// a membuf and a system here are some examples:
+ /// @code
+ /// #define PROCESSOR_CHIP_A 0xFFFF0000
+ /// #define MEMBUF_CHIP_B 0x0000FFFF
+ /// #define SYSTEM_C 0x0000AAAA
+ /// @endcode
+ ///
+ /// * To define a target:
+ /// @code
+ /// fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A);
+ /// fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> C(SYSTEM_C);
+ /// fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> B(MEMBUF_CHIP_B);
+ /// @endcode
+ ///
+ /// * Functions which take composite target types
+ /// @code
+ /// void takesProcOrMembuf(
+ /// const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP |
+ /// fapi2::TARGET_TYPE_MEMBUF_CHIP>& V );
+ ///
+ /// void takesAny(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& V );
+ ///
+ /// @endcode
+ ///
+ /// * Traversing the target "tree"
+ /// @code
+ /// fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A);
+ ///
+ /// // Get A's parent
+ /// A.getParent<fapi2::TARGET_TYPE_SYSTEM>();
+ ///
+ /// // Get the 0x53'd core
+ /// fapi2::getTarget<fapi2::TARGET_TYPE_CORE>(0x53);
+ ///
+ /// // Get all *my* present/functional children which are cores
+ /// A.getChildren<fapi2::TARGET_TYPE_CORE>();
+ ///
+ /// // Get all of the the cores relative to my base target
+ /// fapi2::getChildren<fapi2::TARGET_TYPE_CORE>();
+ /// @endcode
+ ///
+ /// * Invalid casts
+ /// @code
+ /// // Can't cast to a specialized target
+ /// fapi2::Target<fapi2::TARGET_TYPE_NONE> D(MEMBUF_CHIP_B);
+ /// takesProcOrMembuf( D );
+ ///
+ /// // Not one of the shared types
+ /// fapi2::Target<fapi2::TARGET_TYPE_ABUS_ENDPOINT> E;
+ /// takesProcOrMembuf( E );
+ /// @endcode
+ template<TargetType K, typename V = uint64_t>
+ class Target
+ {
+ public:
+
+ ///
+ /// @brief Create a Target, with a value
+ /// @param[in] Value the value (i.e., specific element this
+ /// target represents, or pointer)
+ /// @note Platforms can mangle the value and K to get a
+ /// single uint64_t in value which represents all the information
+ /// they might need. value( K | V ), for example
+ ///
+ Target(V Value = 0):
+ iv_handle(Value)
+ {}
+
+ ///
+ /// @brief Assignment Operator.
+ /// @param[in] i_right Reference to Target to assign from.
+ /// @return Reference to 'this' Target
+ ///
+ Target& operator=(const Target& i_right)
+ { iv_handle = i_right.iv_handle; return *this; }
+
+ ///
+ /// @brief Equality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if equal.
+ /// @note Platforms need to define this so that the physical
+ /// targets are determined to be equivilent rather than just the handles
+ ///
+ bool operator==(const Target& i_right) const
+ { return i_right.iv_handle == iv_handle; }
+
+ ///
+ /// @brief Inquality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if not equal.
+ /// @note Platforms need to define this so that the physical
+ /// targets are determined to be equivilent rather than just the handles
+ ///
+ bool operator!=(const Target& i_right) const
+ { return i_right.iv_handle != iv_handle; }
+
+ ///
+ /// @brief Get the handle.
+ /// @return V The target's handle, or value
+ ///
+ V get(void) const
+ { return iv_handle; }
+
+ ///
+ /// @brief Get the handle as a V
+ /// @return V The target's handle, or value
+ ///
+ inline operator V() const { return iv_handle; }
+
+ ///
+ /// @brief Get a target's value
+ /// @return V The target's handle, or value
+ ///
+ inline V& operator()(void) { return iv_handle; }
+
+ ///
+ /// @brief Get the target type
+ /// @return The type of target represented by this target
+ ///
+ inline TargetType getType(void) const { return iv_type; }
+
+ ///
+ /// @brief Get this target's immediate parent
+ /// @tparam T The type of the parent
+ /// @return Target<T> a target representing the parent
+ ///
+ template< TargetType T >
+ inline Target<T> getParent(void) const
+ {
+ // For testing
+ return Target<T>(iv_handle);
+ }
+
+ ///
+ /// @brief Get this target's children
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return std::vector<Target<T> > a vector of present/functional
+ /// children
+ ///
+ template< TargetType T>
+ inline std::vector<Target<T> >
+ getChildren(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const
+ {
+ // For testing
+ return {Target<T>()};
+ }
+
+ ///
+ /// @brief Get the target at the other end of a bus - dimm included
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return Target<T> a target representing the thing on the other end
+ /// @note Can be easily changed to a vector if needed
+ ///
+ template<TargetType T>
+ inline Target<T>
+ getOtherEnd(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const
+ {
+ // Implementation note: cast to a composite of
+ // bus types and the compiler will check if this is
+ // a good function at compile time
+ return Target<T>();
+ }
+
+ ///
+ /// @brief Copy from a Target<O> to a Target<K>
+ /// @tparam O the target type of the other
+ ///
+ template<TargetType O>
+ inline Target( const Target<O>& Other ):
+ Target<K, V>(Other.get())
+ {
+ static_assert( (K & O) != 0,
+ "unable to cast Target, no shared types");
+
+ static_assert( bitCount<K>::count >= bitCount<O>::count,
+ "unable to cast to specialized Target");
+ }
+
+ private:
+ // Don't use enums here as it makes it hard to assign
+ // in the platform target cast constructor.
+ static const TargetType iv_type = K;
+ V iv_handle;
+
+ };
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] i_target Target<T>
+ /// @param[in] i_buffer buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template< TargetType T >
+ inline void toString(const Target<T>& i_target, char* i_buffer, size_t i_bsize)
+ {
+ snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target.get(), T);
+ }
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] A pointer to the Target<T>
+ /// @param[in] The buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template< TargetType T >
+ inline void toString(const Target<T>* i_target, char* i_buffer, size_t i_bsize)
+ {
+ snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target->get(), T);
+ }
+
+ ///
+ /// @brief Get an enumerated target of a specific type
+ /// @tparam T The type of the target
+ /// @param[in] Ordinal representing the ordinal number of
+ /// the desired target
+ /// @return Target<T> the target requested
+ ///
+ template<TargetType T>
+ inline Target<T> getTarget(uint64_t Ordinal)
+ {
+ // For testing
+ return Target<T>(Ordinal);
+ }
+
+ // Why has the been removed? For starters, the API name
+ // is probably wrong as it's already been confused with
+ // Target::getChildren(). And if I'm going to change it
+ // I really want to see if we need it. I'm still not
+ // clear on whether we're alloing this traversal or not.
+#if 0
+ ///
+ /// @brief Get the base target's children
+ /// @tparam T The type of the target
+ /// @return std::vector<Target<T> > a vector of present/functional
+ /// children
+ ///
+ template<TargetType T>
+ inline std::vector<Target<T> > getChildren()
+ {
+ // For testing
+ return {Target<T>(), Target<T>()};
+ }
+#endif
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] i_target Target<T>
+ /// @param[in] i_buffer buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template<TargetType T, typename B>
+ inline void toString(const Target<T>& i_target, B& i_buffer);
+
+ ///
+ /// @brief Check if the target is of a type, or in a type subset.
+ /// @tparam K the TargetType to check
+ /// @tparam T TargetType or TargetType composite to check against
+ /// @return True, iff K is a proper T
+ ///
+ template< TargetType K, TargetType T >
+ inline constexpr bool is_same(void)
+ { return (K & T) != 0; }
+
+
+};
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/target_types.H b/src/ppe/hwpf/fapi/include/target_types.H
new file mode 100755
index 0000000..926db45
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/target_types.H
@@ -0,0 +1,105 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/target_types.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 target_types.H
+ * @brief definitions for fapi2 target types
+ */
+
+#ifndef __FAPI2_TARGET_TYPES__
+#define __FAPI2_TARGET_TYPES__
+
+/// FAPI namespace
+namespace fapi2
+{
+ ///
+ /// @enum fapi::TargetType
+ /// @brief Types, kinds, of targets
+ /// @note TYPE_NONE is used to represent empty/NULL targets in lists
+ /// or tables. TYPE_ALL is used to pass targets to methods which
+ /// can act generally on any type of target
+ ///
+ /// Target Kind
+ enum TargetType
+ {
+ TARGET_TYPE_NONE = 0x00000000, ///< No type
+ TARGET_TYPE_SYSTEM = 0x00000001, ///< System type
+ TARGET_TYPE_DIMM = 0x00000002, ///< DIMM type
+ TARGET_TYPE_PROC_CHIP = 0x00000004, ///< Processor type
+ TARGET_TYPE_MEMBUF_CHIP = 0x00000008, ///< Membuf type
+ TARGET_TYPE_EX = 0x00000010, ///< Ex type
+ TARGET_TYPE_MBA = 0x00000020, ///< MBA type
+ TARGET_TYPE_MCS = 0x00000040, ///< MCS type
+ TARGET_TYPE_XBUS = 0x00000080, ///< XBUS type
+ TARGET_TYPE_ABUS = 0x00000100, ///< ABUS type
+ TARGET_TYPE_L4 = 0x00000200, ///< L4 type
+ TARGET_TYPE_CORE = 0x00000400, ///< Core type
+ TARGET_TYPE_EQ = 0x00000800, ///< EQ type
+ TARGET_TYPE_MCA = 0x00001000, ///< MCA type
+ TARGET_TYPE_MCBIST = 0x00002000, ///< MCBIST type
+ TARGET_TYPE_MIA = 0x00004000, ///< MIA type
+ TARGET_TYPE_MIS = 0x00008000, ///< MIS type
+ TARGET_TYPE_DMI = 0x00010000, ///< DMI type
+ TARGET_TYPE_OBUS = 0x00020000, ///< OBUS type
+ TARGET_TYPE_NV = 0x00040000, ///< NV bus type
+ TARGET_TYPE_SBE = 0x00080000, ///< SBE type
+ TARGET_TYPE_PPE = 0x00100000, ///< PPE type
+ TARGET_TYPE_PERV = 0x00200000, ///< Pervasive type
+ TARGET_TYPE_PEC = 0x00400000, ///< PEC type
+ TARGET_TYPE_PHB = 0x00800000, ///< PHB type
+ TARGET_TYPE_EL = 0x01000000, ///< L3/L2 Caches
+
+ TARGET_TYPE_ALL = 0xFFFFFFFF, ///< Any/All types
+
+ // Mappings to target types found in the error xml files
+ TARGET_TYPE_EX_CHIPLET = TARGET_TYPE_EX,
+ TARGET_TYPE_MBA_CHIPLET = TARGET_TYPE_MBA,
+ TARGET_TYPE_MCS_CHIPLET = TARGET_TYPE_MCS,
+ TARGET_TYPE_XBUS_ENDPOINT = TARGET_TYPE_XBUS,
+ TARGET_TYPE_ABUS_ENDPOINT = TARGET_TYPE_ABUS,
+ };
+
+ /// @cond
+ constexpr TargetType operator|(TargetType x, TargetType y)
+ {
+ return static_cast<TargetType>(static_cast<int>(x) |
+ static_cast<int>(y));
+ }
+
+ template<uint64_t V>
+ class bitCount {
+ public:
+ // Don't use enums, too hard to compare
+ static const uint8_t count = bitCount<(V >> 1)>::count + (V & 1);
+ };
+
+ template<>
+ class bitCount<0> {
+ public:
+ static const uint8_t count = 0;
+ };
+ /// @endcond
+};
+
+#endif
diff --git a/src/ppe/hwpf/fapi/include/utils.H b/src/ppe/hwpf/fapi/include/utils.H
new file mode 100755
index 0000000..490e0b2
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/utils.H
@@ -0,0 +1,59 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/utils.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file utils.H
+ * @brief Defines common fapi2 utilities
+ */
+
+#ifndef FAPI2_UTILS_H_
+#define FAPI2_UTILS_H_
+
+#include <stdint.h>
+#include <return_code.H>
+#include <error_info.H>
+
+namespace fapi2
+{
+ ///
+ /// @brief Log an error.
+ ///
+ /// @param[in,out] io_rc Reference to ReturnCode (Any references to data and error
+ /// target are removed and rc value is set to success after
+ /// function ends.)
+ /// @param[in] i_sev Fapi error log severity defaulted to unrecoverable
+ /// @param[in] i_unitTestError - flag to log error which does not cause a unit
+ /// test to fail.
+ ///
+ /// @note This function is called from the ffdc collection classes and no longer
+ /// needs to be called directly.
+ /// @note Implemented by platform code
+ ///
+ void logError(
+ fapi2::ReturnCode & io_rc,
+ fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE,
+ bool i_unitTestError = false );
+};
+
+#endif // FAPI2_UTILS_H_
diff --git a/src/ppe/hwpf/fapi/include/variable_buffer.H b/src/ppe/hwpf/fapi/include/variable_buffer.H
new file mode 100755
index 0000000..c0d637d
--- /dev/null
+++ b/src/ppe/hwpf/fapi/include/variable_buffer.H
@@ -0,0 +1,663 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/include/variable_buffer.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 variable_buffer.H
+ * @brief definitions for fapi2 variable length buffers
+ */
+
+#ifndef __FAPI2_VARIABLE_BUFFER__
+#define __FAPI2_VARIABLE_BUFFER__
+
+#include <buffer_base.H>
+
+namespace fapi2
+{
+ /// @brief Get a 32 bit mask quickly
+ // This is one of the main reasons we static_assert in the ctor's
+ // to ensure the unit_type is 32 bits.
+ inline uint32_t fast_mask32(int32_t i_pos, int32_t i_len)
+ {
+ // generates an arbitrary 32-bit mask using two operations, not too shabby
+
+ static const uint32_t l_mask32[] = {
+ 0x00000000,
+ 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,
+ 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,
+ 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000,
+ 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,
+ 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000,
+ 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00,
+ 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0,
+ 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF,
+ };
+ return l_mask32[i_len] >> i_pos;
+ }
+
+ //
+ // General set a series of bits in the buffer.
+ //
+
+ ///
+ /// @cond
+ /// @brief Internal bit inserting method.
+ /// @tparam unit_type The type of a unit of the arrays
+ /// @tparam bits_type The type of the bit counting values
+ /// @param[in] i_source The incoming data
+ /// @param[in] i_source_length The length in bits of the incoming data
+ /// @param[in] i_target The outgoing data
+ /// @param[in] i_target_length The length in bits of the outgoing data
+ /// @param[in] i_source_start_bit The starting bit location in the
+ /// incoming data
+ /// @param[in] i_target_start_bit The starting bit position in this
+ /// @param[in] i_length The length, in bits, the user wants copied.
+ ///
+ template<typename unit_type, typename bits_type>
+ inline fapi2::ReturnCode _insert(const unit_type* i_source,
+ bits_type i_source_length,
+ unit_type* i_target,
+ bits_type i_target_length,
+ bits_type i_source_start_bit,
+ bits_type i_target_start_bit,
+ bits_type i_length)
+ {
+ const bits_type bits_per_unit = fapi2::parameterTraits<unit_type>::bit_length;
+
+ // tartgetStart is defaulted to the sizeof(target) - (sizeof(source) - i_source_start_bit)
+ // which makes this act like insert from right
+ if (i_target_start_bit == ~0)
+ {
+ i_target_start_bit = (i_target_length - (i_source_length - i_source_start_bit));
+ }
+
+ // len defaults to (sizeof(OT) * 8) - i_source_start_bit
+ if (i_length == ~0)
+ {
+ i_length = i_source_length - i_source_start_bit;
+ }
+
+ // Check for overflow
+ if ((i_length + i_target_start_bit > i_target_length) ||
+ (i_length + i_source_start_bit > i_source_length))
+ {
+ return fapi2::FAPI2_RC_OVERFLOW;
+ }
+
+ do
+ {
+ const bits_type src_idx = i_source_start_bit / bits_per_unit;
+ const bits_type trg_idx = i_target_start_bit / bits_per_unit;
+
+ // "slop" = unaligned bits
+ const bits_type src_slop = i_source_start_bit % bits_per_unit;
+ const bits_type trg_slop = i_target_start_bit % bits_per_unit;
+
+ // "cnt" = largest number of bits to be moved each pass
+ bits_type cnt = std::min(i_length, bits_per_unit);
+ cnt = std::min(cnt, bits_per_unit - src_slop);
+ cnt = std::min(cnt, bits_per_unit - trg_slop);
+
+ // generate the source mask only once
+ bits_type mask = fast_mask32(src_slop, cnt);
+
+ // read the source bits only once
+ bits_type src_bits = i_source[src_idx] & mask;
+
+ // "shift" = amount of shifting needed for target alignment
+ int32_t shift = trg_slop - src_slop;
+
+ // ideally (i << -1) would yield (i >> 1), but it
+ // doesn't, so we need an extra branch here
+
+ if (shift < 0)
+ {
+ src_bits <<= -shift;
+ mask <<= -shift;
+ }
+ else
+ {
+ src_bits >>= shift;
+ mask >>= shift;
+ }
+
+ // clear source '0' bits in the target
+ i_target[trg_idx] &= ~mask;
+ // set source '1' bits in the target
+ i_target[trg_idx] |= src_bits;
+
+ i_source_start_bit += cnt;
+ i_target_start_bit += cnt;
+
+ i_length -= cnt;
+ } while (0 < i_length);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+ /// @endcond
+
+ /// @brief Class representing a FAPI variable_buffer.
+ /// @remark Variable buffers are buffers which can be variable in length
+ /// (and "odd sized.") These best represent the FAPI 1.X ecmdDataBuffer,
+ /// however they are implemented using the same template techniques
+ /// as the new fapi::buffer.
+ /// @note Variable buffers are not (presently) declared as std::bitset
+ /// as bitsets' size is fixed at runtime. It is not clear if this is
+ /// acceptable for variable_buffers at this time.
+ /// @note Variable buffers are not (presently) declared as std::vector<bool>
+ /// as it would need to be implemented separate from std::vector, and
+ /// it's not clear it would give us any real advantage. Howevever, its is
+ /// more likely this will become a std::vector<bool> than a std::bitset.
+ class variable_buffer : public buffer_base<bits_container>
+ {
+
+ public:
+
+ ///
+ /// @brief Variable buffer constructor
+ /// @param[in] i_value number of *bits* (sizeof(uint_type) * 8)
+ /// needed.
+ variable_buffer(bits_type i_value = 0);
+
+ ///
+ /// @brief Variable buffer list constructor
+ /// @param[in] i_value an initializer list to initialize the container.
+ ///
+ variable_buffer(const std::initializer_list<unit_type>& i_value);
+
+ /// @name Bit/Word Manipulation Functions
+ ///@{
+
+ ///
+ /// @brief Return the length of the buffer in bits
+ /// @return Length in bits
+ ///
+ inline uint32_t getBitLength(void) const
+ { return iv_perceived_bit_length; }
+
+ ///
+ /// @brief Return the length of the buffer in OT units
+ /// @return Length in OT units rounded up
+ /// @tparam OT the type to get the length of. For example, if one
+ /// wanted the length in double words, OT would be uint64_t
+ /// (getLength<uint64_t>().) Similarly, to get the length in words,
+ /// getLength<uin32_t>().
+ ///
+ template< typename OT >
+ inline uint32_t getLength(void) const
+ {
+ static const uint32_t bits_in_ot = sizeof(OT) * 8;
+ return (getBitLength() + (bits_in_ot - 1)) / bits_in_ot;
+ }
+
+ ///
+ /// @brief Set a bit in the buffer
+ /// @param[in] i_bit the bit number to set.
+ /// @note 0 is left-most
+ /// @return FAPI2_RC_SUCCESS if OK
+ ///
+ inline fapi2::ReturnCode setBit(const bits_type& i_bit)
+ {
+ const bits_type index = i_bit / bits_per_unit;
+
+ if (index > iv_data.size())
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ iv_data[index] |=
+ unit_type(1) << (bits_per_unit - 1) -
+ (i_bit - (index * bits_per_unit));
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Clear a bit in buffer
+ /// @tparam SB Start bit in buffer to clear.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// clear
+ /// @return FAPI2_RC_SUCCESS on success
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type SB, bits_type L >
+ fapi2::ReturnCode clearBit(void);
+
+ ///
+ /// @brief Invert bit
+ /// @tparam SB Start bit in buffer to invert.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// invert, defaults to 1
+ /// @return FAPI2_RC_SUCCESS on success
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ fapi2::ReturnCode flipBit(void);
+
+ ///
+ /// @brief Get the value of a bit in the buffer
+ /// @tparam B Bit in buffer to get.
+ /// @return true/1 if bit is on, false/0 if bit is off
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type B >
+ inline bool getBit(void) const
+ {
+ const bits_type index = B / bits_per_unit;
+ const unit_type mask = unit_type(1) << (bits_per_unit - 1) - (B - (index * bits_per_unit));
+ return iv_data[index] & mask;
+ }
+
+ ///
+ /// @brief Test if multiple bits are set
+ /// @tparam SB Start bit in buffer to test.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// test, defaults to 1
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @return true if all bits in range are set - false if any
+ /// bit is clear
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ bool isBitSet(void) const;
+
+ ///
+ /// @brief Test if multiple bits are clear
+ /// @tparam SB Start bit in buffer to test.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// test, defaults to 1
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @return true if bit is clear - false if bit is set
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ bool isBitClear(void) const;
+
+ ///
+ /// @brief Count number of bits set in a range
+ /// @tparam SB Start bit in buffer to test.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// test, defaults to 1
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @return Number of bits set in range
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ bits_type getNumBitsSet(void) const;
+
+ ///@}
+
+ /// @name Buffer Manipulation Functions
+ ///@{
+
+ // Note: Many (all?) of these are not needed and the compiler complains
+ // as the cast to T yields a better operator. There are here mainly for
+ // documenation purposes.
+
+ ///
+ /// @brief operator>>()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator>>(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator<<()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator<<(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator+()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator+(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator+=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator+=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator|=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator&=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator|(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator&(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator^=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator^=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator!=()
+ ///
+#ifdef DOXYGEN
+ bool operator!=(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief operator==()
+ /// @return true if and only if lhs == rhs
+ ///
+ inline bool operator==(const fapi2::bits_container& rhs) const
+ {
+ if (&iv_data == &rhs)
+ {
+ return true;
+ }
+
+ return iv_data == rhs;
+ }
+
+ ///
+ /// @brief Copy part of an element into the DataBuffer
+ /// @param[in] i_data OT value to copy into DataBuffer
+ /// @param[in] i_targetStart The position in this where the copy starts
+ /// @param[in] i_len How many bits to copy
+ /// @param[in] i_sourceStart The start positon in i_data, defaults to 0
+ /// @return FAPI2_RC_SUCCESS on success, FAPi2_RC_OVERFLOW otherwise
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insert(const OT& i_data,
+ bits_type i_targetStart = 0,
+ bits_type i_len = ~0,
+ bits_type i_sourceStart = 0);
+
+ ///
+ /// @brief Copy in a right aligned (decimal) element
+ /// @param[in] i_data the incoming data
+ /// - data is taken right aligned
+ /// @param[in] i_targetStart The starting bit position in this
+ /// - Defaultst to 0
+ /// @param[in] i_len The length, in bits, the user wants copied.
+ /// - Defaults to all of the bits in the source which fit
+ /// @return FAPI2_RC_SUCCESS on success, FAPI2_RC_OVERFLOW otherwise
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insertFromRight(const OT& i_data,
+ bits_type i_targetStart = 0,
+ bits_type i_len = ~0);
+
+ ///
+ /// @brief Copy data from this buffer into an OT
+ /// @tparam OT the type of the outgoing data
+ /// @param[out] o_out OT to copy into - data is placed left aligned
+ /// @param[in] i_start Start bit to copy from - defaults to 0
+ /// @param[in] i_len Length of bits to copy - defaults to filling o_out
+ /// @return FAPI2_RC_SUCCESS on success
+ ///
+ template< typename OT >
+ fapi2::ReturnCode extract(OT& o_out,
+ bits_type i_start = 0,
+ bits_type i_len = ~0) const;
+
+ ///
+ /// @brief Copy data from this buffer into an OT and right justify
+ /// @tparam OT the type of the outgoing data
+ /// @param[out] o_out OT to copy into - data is placed right aligned
+ /// @param[in] i_start Start bit to copy from - defaults to 0
+ /// @param[in] i_len Length of bits to copy - defaults to filling o_out
+ /// @return FAPI2_RC_SUCCESS on success
+ ///
+ template< typename OT >
+ fapi2::ReturnCode extractToRight(OT& o_out,
+ bits_type i_start = 0,
+ bits_type i_len = ~0) const;
+ ///@}
+
+ private:
+ // Just shorthand ...
+ static const bits_type bits_per_unit =
+ bufferTraits<bits_container>::bits_per_unit;
+
+ // The number of bits the user asked for. The actual size of the
+ // container might be larger.
+ bits_type iv_perceived_bit_length;
+
+ ///
+ /// @brief Internal bit extraction method.
+ /// @tparam OT The type of the destination
+ /// @param[in] i_start The starting bit position in this
+ /// @param[in] i_count The length, in bits, the user wants copied.
+ /// @param[out] o_dest Where to put the data
+ ///
+ template< typename OT >
+ fapi2::ReturnCode _extract(bits_type i_start,
+ bits_type i_count,
+ OT* o_dest) const;
+
+ ///
+ /// @brief Internal insertFromRight
+ /// @param[in] i_data, the incoming data
+ /// @param[in] i_data_length The length in bits of the incoming data
+ /// @param[in] i_target_start_bit The starting bit position in this
+ /// @param[in] i_length The length, in bits, the user wants copied.
+ ///
+ template<typename OT>
+ fapi2::ReturnCode _insertFromRight(const OT& i_data,
+ bits_type i_data_length,
+ bits_type i_targetStart,
+ bits_type i_len);
+
+ };
+
+ inline variable_buffer::
+ variable_buffer(bits_type i_value):
+ buffer_base(i_value),
+ iv_perceived_bit_length(i_value)
+ {
+ static_assert(std::is_same<unit_type, uint32_t>::value,
+ "code currently needs unit_type to be a unit32_t");
+ }
+
+ inline variable_buffer::
+ variable_buffer(const std::initializer_list<unit_type>& i_value):
+ buffer_base(i_value),
+ iv_perceived_bit_length(i_value.size() * sizeof(unit_type) * 8)
+ {
+ static_assert(std::is_same<unit_type, uint32_t>::value,
+ "code currently needs unit_type to be a unit32_t");
+ }
+
+
+
+ /// @cond
+ //
+ // Generic insert
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::insert(const OT& i_source,
+ bits_type i_targetStart,
+ bits_type i_len,
+ bits_type i_sourceStart)
+ {
+ return _insert((unit_type*)(&i_source), parameterTraits<OT>::bit_length,
+ &(iv_data[0]), getBitLength(),
+ i_sourceStart, i_targetStart, i_len);
+ }
+
+ //
+ // Insert another variable_bufer
+ //
+ template<>
+ inline fapi2::ReturnCode variable_buffer::insert(
+ const variable_buffer& i_data,
+ bits_type i_targetStart,
+ bits_type i_len,
+ bits_type i_sourceStart)
+ {
+ return _insert((unit_type*)&(i_data()[0]), i_data.getBitLength(),
+ &(iv_data[0]), getBitLength(),
+ i_sourceStart, i_targetStart, i_len);
+ }
+
+ //
+ // Generic insert from right
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::insertFromRight(
+ const OT& i_data,
+ bits_type i_targetStart,
+ bits_type i_len)
+ {
+ _insertFromRight(i_data, parameterTraits<OT>::bit_length, i_targetStart, i_len);
+ }
+
+ //
+ // variable_buffer insert from right
+ //
+ template<>
+ inline fapi2::ReturnCode variable_buffer::insertFromRight(
+ const variable_buffer& i_data,
+ bits_type i_targetStart,
+ bits_type i_len)
+ {
+ const bits_type bit_length_of_source = i_data.getBitLength();
+ _insertFromRight(i_data, bit_length_of_source, i_targetStart, i_len);
+ }
+
+
+
+
+ //
+ // Generic extract. Extract is an insert with the arguments reversed.
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::extract(
+ OT& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // Needed to trick the compiler into matching the template below
+ const bits_type max_length = parameterTraits<OT>::bit_length;
+
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if (i_len == ~0)
+ {
+ i_len = max_length;
+ }
+
+ return _insert((container_unit*)&iv_data[0], getBitLength(),
+ &i_data, max_length,
+ i_start, 0U, i_len);
+ }
+
+ //
+ // Extract in to another variable_bufer
+ //
+ template<>
+ inline fapi2::ReturnCode variable_buffer::extract(
+ variable_buffer& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if (i_len == ~0)
+ {
+ i_len = i_data.getBitLength();
+ }
+ return _insert((container_unit*)&iv_data[0], getBitLength(),
+ &(i_data()[0]), i_data.getBitLength(),
+ i_start, 0U, i_len);
+ }
+
+
+
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::_insertFromRight(
+ const OT& i_data,
+ bits_type i_data_length,
+ bits_type i_targetStart,
+ bits_type i_len)
+ {
+ // If they didn't pass in a length, assume they want all the i_data
+ // which will fit.
+ if( i_len == ~0 )
+ {
+ // The longest the length can be is the length of the data
+ // This is the miniumum of the length of the data or the
+ // number of available bits
+ i_len = std::min(i_data_length, getBitLength() - i_targetStart);
+ }
+
+ // Source start is the length, counted from the right
+ return insert(i_data, i_targetStart, i_len, i_data_length - i_len);
+ }
+
+ //
+ // Invalid specializations of set
+ //
+ /// @cond
+ // Sepcialize the variable_buffer version to to "undefined" so the
+ // linker complains loudly if anyone calls it.
+#if 0
+ template<>
+ inline fapi2::ReturnCode buffer_base::set(
+ const variable_buffer& i_value,
+ bits_type i_offset);
+#endif
+ /// @endcond
+};
+
+
+#endif
diff --git a/src/ppe/hwpf/fapi/src/error_info.C b/src/ppe/hwpf/fapi/src/error_info.C
new file mode 100755
index 0000000..df4888e
--- /dev/null
+++ b/src/ppe/hwpf/fapi/src/error_info.C
@@ -0,0 +1,412 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/src/error_info.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file error_info.C
+ * @brief Implements the error information classes
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <plat_trace.H>
+#include <error_info.H>
+#include <buffer.H>
+
+namespace fapi2
+{
+ ///
+ /// @brief Constructor
+ ///
+ /// @param[in] i_ffdcId FFDC Identifier (used to decode FFDC)
+ /// @param[in] i_pFfdc Pointer to the FFDC to copy
+ /// @param[in] i_size Size of the FFDC to copy
+ ///
+ ErrorInfoFfdc::ErrorInfoFfdc(const uint32_t i_ffdcId,
+ const void* i_pFfdc,
+ const uint32_t i_size):
+ iv_ffdcId(i_ffdcId),
+ iv_size(i_size)
+ {
+ iv_pFfdc = std::shared_ptr<uint8_t>(new uint8_t[i_size]());
+
+ // If they passed us a NULL pointer they want to fill
+ // in the data themselves later.
+ if (i_pFfdc != nullptr)
+ {
+ memcpy(iv_pFfdc.get(), i_pFfdc, i_size);
+ }
+ }
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_hw Hardware to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ /// @param[in] i_refTarget Reference to reference target
+ ///
+ ErrorInfoHwCallout::ErrorInfoHwCallout(
+ const HwCallouts::HwCallout i_hw,
+ const CalloutPriorities::CalloutPriority i_calloutPriority,
+ const Target<TARGET_TYPE_ALL> & i_refTarget):
+ iv_hw(i_hw),
+ iv_calloutPriority(i_calloutPriority),
+ iv_refTarget(i_refTarget)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_procedure Procedure to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoProcedureCallout::ErrorInfoProcedureCallout(
+ const ProcedureCallouts::ProcedureCallout i_procedure,
+ const CalloutPriorities::CalloutPriority i_calloutPriority):
+ iv_procedure(i_procedure),
+ iv_calloutPriority(i_calloutPriority)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target1 Reference to target on one end of the bus
+ /// @param[in] i_target2 Reference to target on other end of the bus
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoBusCallout::ErrorInfoBusCallout(
+ const Target<TARGET_TYPE_ALL> & i_target1,
+ const Target<TARGET_TYPE_ALL> & i_target2,
+ const CalloutPriorities::CalloutPriority i_calloutPriority):
+ iv_target1(i_target1),
+ iv_target2(i_target2),
+ iv_calloutPriority(i_calloutPriority)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target Reference to the target to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @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
+ ///
+ 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):
+ iv_target(i_target),
+ iv_callout(i_callout),
+ iv_deconfigure(i_deconfigure),
+ iv_gard(i_gard),
+ iv_calloutPriority(i_priority)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_parent Reference to the parent target
+ /// @oaram[in] i_childType Child target type to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @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_childPort Child Port
+ /// For DIMM children, the MBA port number
+ /// @param[in] i_childNum Child Number
+ /// For DIMM children, the dimm socket number
+ /// For Chip children, the chip position
+ /// For Chiplet children, the chiplet unit pos
+ ///
+ ErrorInfoChildrenCDG::ErrorInfoChildrenCDG(
+ const Target<TARGET_TYPE_ALL> & i_parentChip,
+ const TargetType i_childType,
+ const bool i_callout,
+ const bool i_deconfigure,
+ const bool i_gard,
+ const CalloutPriorities::CalloutPriority i_priority,
+ const uint8_t i_childPort, const uint8_t i_childNum):
+ iv_parent(i_parentChip),
+ iv_childType(i_childType),
+ iv_callout(i_callout),
+ iv_calloutPriority(i_priority),
+ iv_deconfigure(i_deconfigure),
+ iv_gard(i_gard),
+ iv_childPort(i_childPort),
+ iv_childNumber(i_childNum)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_trace
+ ///
+ ErrorInfoCollectTrace::ErrorInfoCollectTrace(
+ CollectTraces::CollectTrace i_traceId):
+ iv_eiTraceId(i_traceId)
+ {}
+
+
+ ///
+ /// @brief Collect target, buffer or generic FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryFfdc::addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_objects) const
+ {
+ // "variable buffer ffdc not yet implemented");
+ assert(iv_ffdcSize != EI_FFDC_SIZE_VBUF);
+
+ switch(iv_ffdcSize)
+ {
+ case EI_FFDC_SIZE_BUF:
+ {
+ const buffer<uint64_t>* object =
+ static_cast<const buffer<uint64_t>*>(i_objects[iv_ffdcObjIndex]);
+
+ i_info->iv_ffdcs.push_back(std::shared_ptr<ErrorInfoFfdc>(
+ new ErrorInfoFfdc(iv_ffdcId, object,
+ sizeof(object))));
+
+ FAPI_DBG("addErrorInfo: Adding buffer id: 0x%x size: %lu buf: 0x%lx",
+ iv_ffdcId, sizeof(object), uint64_t(*object));
+ }
+ break;
+
+ case EI_FFDC_SIZE_TARGET:
+ {
+ Target<TARGET_TYPE_ALL> object =
+ *(static_cast<const Target<TARGET_TYPE_ALL>*>
+ (i_objects[iv_ffdcObjIndex]));
+
+ // Allocate an ErrorInfoFfdc but don't copy anything in to it.
+ // We can copy the target string once if we copy directly into
+ // the error info
+ ErrorInfoFfdc* e =
+ new ErrorInfoFfdc(iv_ffdcId, nullptr, MAX_ECMD_STRING_LEN);
+
+ toString(object, static_cast<char*>(e->getData()),
+ MAX_ECMD_STRING_LEN);
+ i_info->iv_ffdcs.push_back(std::shared_ptr<ErrorInfoFfdc>(e));
+
+ FAPI_DBG("addErrorInfo: Adding target ffdc id: 0x%x %s",
+ iv_ffdcId, static_cast<char*>(e->getData()));
+ }
+ break;
+
+ default:
+ i_info->iv_ffdcs.push_back(std::shared_ptr<ErrorInfoFfdc>(
+ new ErrorInfoFfdc(
+ iv_ffdcId,
+ i_objects[iv_ffdcObjIndex],
+ iv_ffdcSize)));
+ FAPI_DBG("addErrorInfo: Adding ffdc id 0x%x size: %d",
+ iv_ffdcId, iv_ffdcSize);
+ break;
+
+ };
+
+ return;
+ }
+
+ ///
+ /// @brief Collect h/w callout FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryHwCallout::addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ // If the index is 0xFF, we use an empty target. Otherwise the
+ // target is taken from the object arrary with the given index.
+ const fapi2::Target<TARGET_TYPE_ALL> target =
+ iv_refObjIndex == 0xFF ?
+ fapi2::Target<TARGET_TYPE_ALL>() :
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_refObjIndex]));
+
+ ErrorInfoHwCallout* ei = new ErrorInfoHwCallout(
+ static_cast<HwCallouts::HwCallout>(iv_hw),
+ static_cast<CalloutPriorities::CalloutPriority>(iv_calloutPriority),
+ target);
+
+ FAPI_DBG("addErrorInfo: Adding hw callout target: 0x%lx hw: %d, pri: %d",
+ ei->iv_refTarget.get(), ei->iv_hw, ei->iv_calloutPriority);
+
+ i_info->iv_hwCallouts.push_back(std::shared_ptr<ErrorInfoHwCallout>(ei));
+ }
+
+ ///
+ /// @brief Collect proc callout FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryProcCallout::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ ErrorInfoProcedureCallout* ei = new ErrorInfoProcedureCallout(
+ static_cast<ProcedureCallouts::ProcedureCallout>(iv_procedure),
+ static_cast<CalloutPriorities::CalloutPriority>(iv_calloutPriority));
+
+ // Add the ErrorInfo
+ FAPI_DBG("addErrorInfo: Adding proc callout, proc: %d, pri: %d",
+ ei->iv_procedure, ei->iv_calloutPriority);
+
+ i_info->iv_procedureCallouts.push_back(
+ std::shared_ptr<ErrorInfoProcedureCallout>(ei));
+ }
+
+ ///
+ /// @brief Collect bus callout FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryBusCallout::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ // We need to add a procedure callout as well as a bus callout
+ ErrorInfoEntryProcCallout(ProcedureCallouts::BUS_CALLOUT,
+ iv_calloutPriority).addErrorInfo(i_info,
+ i_object);
+
+ // Now add our bus callout, but drop the priority by one.
+ ErrorInfoBusCallout* ei = new ErrorInfoBusCallout(
+ // First target
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_endpoint1ObjIndex])),
+
+ // Second target
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_endpoint2ObjIndex])),
+
+ // Priority, one lower.
+ (iv_calloutPriority == CalloutPriorities::HIGH) ?
+ CalloutPriorities::MEDIUM : CalloutPriorities::LOW);
+
+ FAPI_DBG("addErrorInfo: Adding bus callout t1: 0x%lx t2: 0x%lx, pri: %d",
+ ei->iv_target1.get(), ei->iv_target2.get(),
+ ei->iv_calloutPriority);
+
+ i_info->iv_busCallouts.push_back(
+ std::shared_ptr<ErrorInfoBusCallout>(ei));
+ }
+
+ ///
+ /// @brief Collect h/w target cdg FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryTargetCDG::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ ErrorInfoCDG* ei = new
+ ErrorInfoCDG(
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_targetObjIndex])),
+ iv_callout,
+ iv_deconfigure,
+ iv_gard,
+ static_cast<CalloutPriorities::CalloutPriority>
+ (iv_calloutPriority)
+ );
+
+ FAPI_DBG("addErrorInfo: Adding target 0x%lx cdg (%d:%d:%d), pri: %d",
+ ei->iv_target.get(),
+ ei->iv_callout, ei->iv_deconfigure,
+ ei->iv_gard, ei->iv_calloutPriority);
+
+ // Add the ErrorInfo
+ i_info->iv_CDGs.push_back(std::shared_ptr<ErrorInfoCDG>(ei));
+ }
+
+ ///
+ /// @brief Collect h/w children cdg FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryChildrenCDG::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ ErrorInfoChildrenCDG* ei = new ErrorInfoChildrenCDG(
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_parentObjIndex])),
+ static_cast<fapi2::TargetType>(iv_childType),
+ iv_callout,
+ iv_deconfigure,
+ iv_gard,
+ static_cast<CalloutPriorities::CalloutPriority>
+ (iv_calloutPriority),
+ iv_childPort,
+ iv_childNumber);
+
+ FAPI_DBG("addErrorInfo: Adding children cdg (%d:%d:%d), type:"
+ " 0x%08x, pri: %d",
+ ei->iv_callout, ei->iv_deconfigure, ei->iv_gard,
+ ei->iv_childType, ei->iv_calloutPriority);
+
+ // Add the ErrorInfo
+ i_info->iv_childrenCDGs.push_back(
+ std::shared_ptr<ErrorInfoChildrenCDG>(ei));
+ }
+
+ ///
+ /// @brief Collect trace information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryCollectTrace::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ ErrorInfoCollectTrace* ei = new ErrorInfoCollectTrace(
+ static_cast<CollectTraces::CollectTrace>(iv_eieTraceId));
+
+ FAPI_DBG("addErrorInfo: Adding trace: 0x%x", ei->iv_eiTraceId);
+
+ // Add the ErrorInfo
+ i_info->iv_traces.push_back(std::shared_ptr<ErrorInfoCollectTrace>(ei));
+ }
+
+};
diff --git a/src/ppe/hwpf/fapi/src/ffdc.C b/src/ppe/hwpf/fapi/src/ffdc.C
new file mode 100755
index 0000000..9b7504d
--- /dev/null
+++ b/src/ppe/hwpf/fapi/src/ffdc.C
@@ -0,0 +1,59 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/src/ffdc.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file ffdc.C
+ * @brief Implements the FirstFailureData class
+ */
+
+#include <plat_trace.H>
+#include <ffdc.H>
+#include <error_info.H>
+
+namespace fapi2
+{
+
+ ///
+ /// @brief Add error information to this ffdc object
+ /// @param[in] A pointer to a list of objects
+ /// @param[in] A pointer to the list of entries
+ /// @param[in] The count of how many entries there are
+ /// @return void
+ ///
+ template<>
+ void FirstFailureData<ReturnCode>::addErrorInfo(
+ const void* const* i_pObjects,
+ const ErrorInfoEntry* i_pEntries,
+ const uint8_t i_count)
+ {
+ FAPI_DBG("%d entries", i_count);
+ for (uint32_t i = 0; i < i_count; i++)
+ {
+ i_pEntries[i].addErrorInfo(iv_info, i_pObjects);
+ }
+ }
+
+
+
+};
diff --git a/src/ppe/hwpf/fapi/src/plat_utils.C b/src/ppe/hwpf/fapi/src/plat_utils.C
new file mode 100755
index 0000000..aafc35f
--- /dev/null
+++ b/src/ppe/hwpf/fapi/src/plat_utils.C
@@ -0,0 +1,119 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/fapi/src/plat_utils.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_utils.C
+ * @brief Implements fapi2 common utilities
+ */
+
+#include <stdint.h>
+#include <plat_trace.H>
+#include <return_code.H>
+#include <error_info.H>
+
+namespace fapi2
+{
+ ///
+ /// @brief Log an error.
+ ///
+ void logError(
+ fapi2::ReturnCode & io_rc,
+ fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE,
+ bool i_unitTestError = false )
+ {
+ FAPI_DBG("logging 0x%lx.", uint64_t(io_rc));
+
+ // Iterate over the vectors and output what is in them.
+ const ErrorInfo* ei = io_rc.getErrorInfo();
+
+ FAPI_DBG("ffdcs: %lu", ei->iv_ffdcs.size());
+ for( auto i = ei->iv_ffdcs.begin(); i != ei->iv_ffdcs.end(); ++i )
+ {
+ uint32_t sz;
+ (*i)->getData(sz);
+ FAPI_DBG("\tid: 0x%x size %d", (*i)->getFfdcId(), sz);
+ }
+
+ FAPI_DBG("hwCallouts: %lu", ei->iv_hwCallouts.size());
+ for( auto i = ei->iv_hwCallouts.begin(); i != ei->iv_hwCallouts.end();
+ ++i )
+ {
+ FAPI_DBG("\thw: %d pri %d target: 0x%lx",
+ (*i)->iv_hw, (*i)->iv_calloutPriority,
+ (*i)->iv_refTarget.get());
+ }
+
+ FAPI_DBG("procedureCallouts: %lu", ei->iv_procedureCallouts.size());
+ for( auto i = ei->iv_procedureCallouts.begin();
+ i != ei->iv_procedureCallouts.end(); ++i )
+ {
+ FAPI_DBG("\tprocedure: %d pri %d",
+ (*i)->iv_procedure, (*i)->iv_calloutPriority);
+ }
+
+ FAPI_DBG("busCallouts: %lu", ei->iv_busCallouts.size());
+ for( auto i = ei->iv_busCallouts.begin(); i != ei->iv_busCallouts.end();
+ ++i )
+ {
+ FAPI_DBG("\tbus: t1: 0x%lx t2: 0x%lx pri: %d",
+ (*i)->iv_target1.get(), (*i)->iv_target2.get(),
+ (*i)->iv_calloutPriority);
+ }
+
+
+ FAPI_DBG("cdgs: %lu", ei->iv_CDGs.size());
+ for( auto i = ei->iv_CDGs.begin(); i != ei->iv_CDGs.end(); ++i )
+ {
+ FAPI_DBG("\ttarget: 0x%lx co: %d dc: %d gard: %d pri: %d",
+ (*i)->iv_target.get(),
+ (*i)->iv_callout,
+ (*i)->iv_deconfigure,
+ (*i)->iv_gard,
+ (*i)->iv_calloutPriority);
+
+ }
+
+ FAPI_DBG("childrenCDGs: %lu", ei->iv_childrenCDGs.size());
+ for( auto i = ei->iv_childrenCDGs.begin();
+ i != ei->iv_childrenCDGs.end(); ++i )
+ {
+ FAPI_DBG("\tchildren: parent 0x%lx co: %d dc: %d gard: %d pri: %d",
+ (*i)->iv_parent.get(),
+ (*i)->iv_callout,
+ (*i)->iv_deconfigure,
+ (*i)->iv_gard,
+ (*i)->iv_calloutPriority);
+ }
+
+ FAPI_DBG("traces: %lu", ei->iv_traces.size());
+ for( auto i = ei->iv_traces.begin(); i != ei->iv_traces.end(); ++i )
+ {
+ FAPI_DBG("\ttraces: 0x%x", (*i)->iv_eiTraceId);
+ }
+
+ // Release the ffdc information now that we're done with it.
+ io_rc.forgetData();
+
+ }
+};
diff --git a/src/ppe/hwpf/fapi/tools/parseErrorInfo.pl b/src/ppe/hwpf/fapi/tools/parseErrorInfo.pl
new file mode 100755
index 0000000..ba2fefb
--- /dev/null
+++ b/src/ppe/hwpf/fapi/tools/parseErrorInfo.pl
@@ -0,0 +1,1479 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwpf/fapi/tools/parseErrorInfo.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2011,2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# $Id: fapiParseErrorInfo.pl,v 1.30 2014/07/25 00:36:41 jmcgill Exp $
+# Purpose: This perl script will parse HWP Error XML files and create required
+# FAPI code.
+#
+# Author: CamVan Nguyen and Mike Jones
+# Reworked for fapi2/P9
+#
+# Usage:
+# fapiParseErrorInfo.pl <output dir> <filename1> <filename2> ...
+
+use strict;
+
+#------------------------------------------------------------------------------
+# 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-
+# space (i.e. parse errors that do not make sense).
+#------------------------------------------------------------------------------
+$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use Digest::MD5 qw(md5_hex);
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+use Data::Dumper;
+use Getopt::Long;
+
+my $target_ffdc_type = "fapi2::Target<fapi2::TARGET_TYPE_ALL>";
+my $buffer_ffdc_type = "fapi2::buffer";
+my $variable_buffer_ffdc_type = "fapi2::variable_buffer";
+my $ffdc_type = "fapi2::ffdc_t";
+
+# We want to keep the signatures for the ffdc gathering hwp so that
+# we can create members of the proper types for the ffdc classes.
+my %signatures = ("proc_extract_pore_halt_ffdc" => ["por_base_state",
+ "por_halt_type_t",
+ "por_ffdc_offset_t"],
+ "hwpTestFfdc1" => [$target_ffdc_type],
+ "proc_extract_pore_base_ffdc" => ["por_base_state", "por_sbe_base_state"],
+ "proc_tp_collect_dbg_data" => [$target_ffdc_type],
+ );
+
+# There are some names used in the XML files which exist in either
+# c++ keywords (case, for example) or macros (DOMAIN). The one's which
+# cause problems and need to be changed are here.
+#
+# DOMAIN is defined to 1 in math.h
+my %mangle_names = ("DOMAIN" => "FAPI2_DOMAIN");
+
+# A list of deprecated elements. These will report messages to the
+# user, and not define anything. They have not been found to be used,
+# but that doesn't mean they're not ...
+my %deprecated = ("RC_PROCPM_PMCINIT_TIMEOUT" => "CHIP_IN_ERROR is defined as a callout procedure");
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $arg_empty_ffdc = undef;
+my $arg_output_dir = undef;
+my $arg_use_variable_buffers = undef;
+
+# Get the options from the command line - the rest of @ARGV will
+# be filenames
+GetOptions("empty-ffdc-classes" => \$arg_empty_ffdc,
+ "output-dir=s" => \$arg_output_dir,
+ "use-variable-buffers" => \$arg_use_variable_buffers);
+
+my $numArgs = $#ARGV + 1;
+if (($numArgs < 1) || ($arg_output_dir eq undef))
+{
+ print ("Usage: parseErrorInfo.pl [--empty-ffdc-classes] [--use-variable-buffers] --output-dir=<output dir> <filename1> <filename2> ...\n");
+ print (" This perl script will parse HWP Error XML files and creates\n");
+ print (" the following files:\n");
+ print (" - hwp_return_codes.H. HwpReturnCode enumeration (HWP generated errors)\n");
+ print (" - hwp_error_info.H. Error information (used by FAPI_SET_HWP_ERROR\n");
+ print (" when a HWP generates an error)\n");
+ print (" - collect_reg_ffdc.C. Function to collect register FFDC\n");
+ print (" - set_sbe_error.H. Macro to create an SBE error\n");
+ print (" The --empty-ffdc-classes option is for platforms which don't collect ffdc.\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Hashes containing error names/enum-values
+#------------------------------------------------------------------------------
+my %errNameToValueHash;
+my %errValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Hashes containing ffdc names/enum-values
+#------------------------------------------------------------------------------
+my %ffdcNameToValueHash;
+my %ffdcValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Subroutine that checks if an entry exists in an array. If it doesn't exist
+# then it is added. The index of the entry within the array is returned
+#------------------------------------------------------------------------------
+sub addEntryToArray
+{
+ my ($arrayref, $entry ) = @_;
+
+ my $match = 0;
+ my $index = 0;
+
+ foreach my $element (@$arrayref)
+ {
+ if ($element eq $entry)
+ {
+ $match = 1;
+ last;
+ }
+ else
+ {
+ $index++;
+ }
+ }
+
+ if (!($match))
+ {
+ push(@$arrayref, $entry);
+ }
+
+ return $index;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an error enum value from an error name and stores
+# it in global hashes
+#------------------------------------------------------------------------------
+sub setErrorEnumValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the error name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errNameToValueHash{$name}))
+ {
+ # Two different errors with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate error name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the error enum-value. This is a hash value generated from
+ # the error name. A hash is used for Cronus so that if a HWP is not
+ # recompiled against a new eCMD/Cronus version where the errors have
+ # changed then there will not be a mismatch in error values.
+ # This is a 24bit hash value because FAPI has a requirement that the
+ # top byte of the 32 bit error value be zero to store flags indicating
+ # the creator of the error
+ #--------------------------------------------------------------------------
+ my $errHash128Bit = md5_hex($name);
+ my $errHash24Bit = substr($errHash128Bit, 0, 6);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errValuePresentHash{$errHash24Bit}))
+ {
+ # Two different errors generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate error hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $errValuePresentHash{$errHash24Bit} = 1;
+ $errNameToValueHash{$name} = $errHash24Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an FFDC ID value from an FFDC name and stores it
+# in global hashes for use when creating the enumeration of FFDC IDs
+#------------------------------------------------------------------------------
+sub setFfdcIdValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the FFDC name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcNameToValueHash{$name}))
+ {
+ # Two different FFDCs with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate FFDC name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the FFDC enum-value. This is a hash value generated from
+ # the FFDC name.
+ #--------------------------------------------------------------------------
+ my $ffdcHash128Bit = md5_hex($name);
+ my $ffdcHash32Bit = substr($ffdcHash128Bit, 0, 8);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcValuePresentHash{$ffdcHash32Bit}))
+ {
+ # Two different FFDCs generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate FFDC hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $ffdcValuePresentHash{$ffdcHash32Bit} = 1;
+ $ffdcNameToValueHash{$name} = $ffdcHash32Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine to create ffdc methods
+#------------------------------------------------------------------------------
+sub addFfdcMethod
+{
+ my $methods = shift;
+ my $ffdc_uc = shift;
+ my $class_name = shift;
+ my $type = shift;
+ my $ffdc_lc = lc($ffdc_uc);
+
+ # If we didn't get a type passed in, this element will get an ffdc_t pair.
+ $type = $ffdc_type if ($type eq undef);
+
+ # Mangle the uppercase name if needed
+ $ffdc_uc = $mangle_names{$ffdc_uc} if ($mangle_names{$ffdc_uc} ne undef);
+
+ my $key = $ffdc_lc.$type;
+ my $key_target = $ffdc_lc.$target_ffdc_type;
+ my $key_ffdc = $ffdc_lc.$ffdc_type;
+
+ # Check to see if this element already has been recorded with this
+ # type or a target type. Note the effect we're shooting for here is
+ # to define the member if it's not been defined before *or* it's
+ # changing from an ffdc_t to a target due to other information in the xml
+ return if ($methods->{$key}{type} eq $type);
+ return if ($methods->{$key_target}{type} eq $target_ffdc_type);
+
+ # Just leave if this is a variable_buffer ans we're not supporting that.
+ return if (($type eq $variable_buffer_ffdc_type) && ($arg_use_variable_buffers eq undef));
+
+ # Set the proper type, and clear out any previous members/methods if
+ # we're going from an ffdc_t to a target.
+ $methods->{$key}{type} = $type;
+ delete $methods->{$key_ffdc} if ($type eq $target_ffdc_type);
+
+ my $method = "";
+ my $method_body = "";
+
+ if ($type eq $ffdc_type)
+ {
+ $method = "\n template< typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr >\n";
+ $method .= " $class_name& set_$ffdc_lc(const T& i_value)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ elsif ($type eq $buffer_ffdc_type)
+ {
+ # Two methods - one for integral buffers and one for variable_buffers
+ $method = "\n template< typename T >\n";
+ $method .= " $class_name& set_$ffdc_lc(const fapi2::buffer<T>& i_value)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ elsif ($type eq $variable_buffer_ffdc_type)
+ {
+ $method = "\n $class_name& set_$ffdc_lc(const fapi2::variable_buffer& i_value)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ # No need to add the member here, it was added with fapi2::buffer. And we can't have variable
+ # buffer support with out integral buffer support (can we?)
+ }
+
+ else
+ {
+ $method = "\n $class_name& set_$ffdc_lc(const $type& i_value)\n";
+ $method_body .= " {$ffdc_uc = &i_value; return *this;}\n\n";
+
+ $methods->{$key}{member} = "const $type* $ffdc_uc;\n ";
+ }
+
+ $method .= ($arg_empty_ffdc eq undef) ? $method_body : " {}\n\n";
+ $methods->{$key}{method} = $method;
+}
+
+#------------------------------------------------------------------------------
+# Open output files for writing
+#------------------------------------------------------------------------------
+my $rcFile = $arg_output_dir;
+$rcFile .= "/";
+$rcFile .= "hwp_return_codes.H";
+open(RCFILE, ">", $rcFile);
+
+my $eiFile = $arg_output_dir;
+$eiFile .= "/";
+$eiFile .= "hwp_error_info.H";
+open(EIFILE, ">", $eiFile);
+
+my $ecFile = $arg_output_dir;
+$ecFile .= "/";
+$ecFile .= "hwp_ffdc_classes.H";
+open(ECFILE, ">", $ecFile);
+
+my $crFile = $arg_output_dir;
+$crFile .= "/";
+$crFile .= "collect_reg_ffdc.C";
+open(CRFILE, ">", $crFile);
+
+my $sbFile = $arg_output_dir;
+$sbFile .= "/";
+$sbFile .= "set_sbe_error.H";
+open(SBFILE, ">", $sbFile);
+
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "// hwp_error_info.H\n";
+print EIFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print EIFILE "#ifndef FAPI2_HWPERRORINFO_H_\n";
+print EIFILE "#define FAPI2_HWPERRORINFO_H_\n\n";
+print EIFILE "#include <target.H>\n";
+print EIFILE "#include <return_code.H>\n";
+print EIFILE "#include <plat_trace.H>\n";
+print EIFILE "/**\n";
+print EIFILE " * \@brief Error Information macros and HwpFfdcId enumeration\n";
+print EIFILE " *\/\n";
+
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "// hwp_ffdc_classes.H\n";
+print ECFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print ECFILE "#ifndef FAPI2_HWP_FFDC_CLASSES_H_\n";
+print ECFILE "#define FAPI2_HWP_FFDC_CLASSES_H_\n\n";
+print ECFILE "#include <ffdc.H>\n";
+print ECFILE "#include <buffer.H>\n";
+print ECFILE "#include <variable_buffer.H>\n" if ($arg_use_variable_buffers ne undef);
+print ECFILE "#include <error_info.H>\n";
+print ECFILE "#include <utils.H>\n";
+print ECFILE "#include <hwp_error_info.H>\n";
+print ECFILE "#include <collect_reg_ffdc.H>\n";
+#print ECFILE "#include <proc_extract_sbe_rc.H>\n\n";
+print ECFILE "/**\n";
+print ECFILE " * \@brief FFDC gathering classes\n";
+print ECFILE " *\/\n";
+print ECFILE "namespace fapi2\n{\n";
+
+#------------------------------------------------------------------------------
+# Print start of file information to collectRegFfdc.C
+#------------------------------------------------------------------------------
+print CRFILE "// collect_reg_ffdc.C\n";
+print CRFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print CRFILE "#include <stdint.h>\n";
+print CRFILE "#include <vector>\n";
+
+print CRFILE "#include <buffer.H>\n";
+print CRFILE "#include <collect_reg_ffdc.H>\n";
+print CRFILE "#include <target.H>\n";
+print CRFILE "#include <return_code.H>\n";
+print CRFILE "#include <hw_access.H>\n";
+print CRFILE "#include <plat_trace.H>\n\n";
+
+print CRFILE "namespace fapi2\n";
+print CRFILE "{\n";
+print CRFILE "void collectRegFfdc(const fapi2::Target<TARGET_TYPE_ALL>* i_target,\n";
+print CRFILE " const fapi2::HwpFfdcId i_ffdcId,\n";
+print CRFILE " fapi2::ReturnCode & o_rc,\n";
+print CRFILE " const TargetType i_child,\n";
+print CRFILE " const TargetType i_presChild,\n";
+print CRFILE " uint32_t i_childOffsetMult)\n";
+print CRFILE "{\n";
+print CRFILE " FAPI_INF(\"collectRegFfdc. FFDC ID: 0x%x\", i_ffdcId);\n";
+print CRFILE " fapi2::ReturnCode l_rc;\n";
+print CRFILE " fapi2::buffer<uint64_t> l_buf;\n";
+print CRFILE " uint32_t l_cfamData = 0;\n";
+print CRFILE " uint64_t l_scomData = 0;\n";
+print CRFILE " std::vector<uint32_t> l_cfamAddresses;\n";
+print CRFILE " std::vector<uint64_t> l_scomAddresses;\n";
+print CRFILE " uint32_t l_ffdcSize = 0;\n\n";
+print CRFILE " switch (i_ffdcId)\n";
+print CRFILE " {\n";
+
+#------------------------------------------------------------------------------
+# Print start of file information to setSbeError.H
+#------------------------------------------------------------------------------
+print SBFILE "// setSbeError.H\n";
+print SBFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print SBFILE "// When SBE code creates an error, it produces an error value\n";
+print SBFILE "// that matches a value in the HwpReturnCode enum in\n";
+print SBFILE "// fapiHwpReturnCodes.H. The SBE uses the __ASSEMBLER__\n";
+print SBFILE "// primitives in hwpReturnCodes.H to do this. The function\n";
+print SBFILE "// that extracts the error value from the SBE needs to call\n";
+print SBFILE "// FAPI_SET_HWP_ERROR to create the error and get all the\n";
+print SBFILE "// actions in the error XML file performed, but that macro can\n";
+print SBFILE "// only be called with the enumerator, not the value. This\n";
+print SBFILE "// FAPI_SET_SBE_ERROR macro can be called instead, it calls\n";
+print SBFILE "// FAPI_SET_HWP_ERROR with the correct error enumerator.\n";
+print SBFILE "// Errors containing <sbeError/> in their XML are supported\n";
+print SBFILE "// in this macro.\n\n";
+print SBFILE "// Note that it is expected that this macro will be called\n";
+print SBFILE "// in one place (the function that extracts the error from\n";
+print SBFILE "// the SBE), if this changes and it is called in multiple\n";
+print SBFILE "// places then the macro could be turned into a function to\n";
+print SBFILE "// avoid the code size increase of expanding the macro in\n";
+print SBFILE "// multiple places. The function approach is slightly more\n";
+print SBFILE "// complicated, there is an extra C file and the function\n";
+print SBFILE "// must take a parameter for the generic chip ID in the error\n";
+print SBFILE "// XML.\n\n";
+print SBFILE "#ifndef FAPI2_SETSBEERROR_H_\n";
+print SBFILE "#define FAPI2_SETSBEERROR_H_\n\n";
+print SBFILE "#define FAPI_SET_SBE_ERROR(RC, ERRVAL)\\\n";
+print SBFILE "{\\\n";
+print SBFILE "switch (ERRVAL)\\\n";
+print SBFILE "{\\\n";
+
+#------------------------------------------------------------------------------
+# For each XML file
+#------------------------------------------------------------------------------
+foreach my $argnum (0 .. $#ARGV)
+{
+ my $infile = $ARGV[$argnum];
+ my $count = 0;
+
+ #--------------------------------------------------------------------------
+ # Read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one element
+ #--------------------------------------------------------------------------
+ my $errors = $xml->XMLin($infile, ForceArray =>
+ ['hwpError', 'collectFfdc', 'ffdc', 'callout', 'deconfigure', 'gard',
+ 'registerFfdc', 'collectRegisterFfdc', 'cfamRegister', 'scomRegister',
+ 'id','collectTrace', 'buffer']);
+
+ # Uncomment to get debug output of all errors
+ #print "\nFile: ", $infile, "\n", Dumper($errors), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Error
+ #--------------------------------------------------------------------------
+ foreach my $err (@{$errors->{hwpError}})
+ {
+ # Hash of methods for the ffdc-gathering class
+ my %methods;
+
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $err->{rc})
+ {
+ print ("parseErrorInfo.pl ERROR. rc missing\n");
+ exit(1);
+ }
+
+ if (! exists $err->{description})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. description missing\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Check that this rc hasn't been deprecated
+ #----------------------------------------------------------------------
+ if ($deprecated{$err->{rc}} ne undef)
+ {
+ print "WARNING: $err->{rc} has been deprecated because $deprecated{$err->{rc}}\n";
+ next;
+ }
+
+ #----------------------------------------------------------------------
+ # Set the error enum value in a global hash
+ #---------------------------------------------------------------------
+ setErrorEnumValue($err->{rc});
+
+ #----------------------------------------------------------------------
+ # If this is an SBE error, add it to set_sbe_error.H
+ #----------------------------------------------------------------------
+ if (exists $err->{sbeError})
+ {
+ print SBFILE " case fapi2::$err->{rc}:\\\n";
+ print SBFILE " FAPI_SET_HWP_ERROR(RC, $err->{rc});\\\n";
+ print SBFILE " break;\\\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_FFDC(RC) ";
+
+ # For now, this code is removed. It appears to work just fine but
+ # will require more of the fapi2 infrastructure to be in place.
+ # Because the ffdc collection classes create members with real types,
+ # the declarations of the types need to be visible - and they're not
+ # right now. When we get further along, we can enable this code.
+=begin NO_FFDC_COLLECT_HWP
+ $count = 0;
+
+ foreach my $collectFfdc (@{$err->{collectFfdc}})
+ {
+ if ($count == 0)
+ {
+ print EIFILE "{ fapi2::ReturnCode l_tempRc; ";
+ }
+ $count++;
+
+ print EIFILE "FAPI_EXEC_HWP(l_tempRc, $collectFfdc, RC); ";
+
+ # collectFfdc is a string we're going to stuff into FAPI_EXEC_HWP
+ # but we need to create the arguments in the ffdc class. The first
+ # element inthe collectFfdc string is the function to call.
+ my @elements = split /,/, $collectFfdc;
+ my @signature = @{$signatures{@elements[0]}};
+ for (my $i = 1; $i <= $#elements; $i++)
+ {
+ @elements[$i] =~ s/^\s+|\s+$//g;
+ addFfdcMethod(\%methods, @elements[$i], lc($err->{rc}), @signature[$i-1]);
+ }
+ }
+
+ if ($count > 0)
+ {
+ print EIFILE "}";
+ }
+=cut NO_FFDC_COLLECT_HWP
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_REG_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC) ";
+
+ foreach my $collectRegisterFfdc (@{$err->{collectRegisterFfdc}})
+ {
+ #------------------------------------------------------------------
+ # Check that expected fields are present
+ #------------------------------------------------------------------
+ if (! exists $collectRegisterFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. id(s) missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ foreach my $id (@{$collectRegisterFfdc->{id}})
+ {
+ #---------------------------------------------------------------------------------
+ # Check FFDC register collection type: target, child, or based on present children
+ #---------------------------------------------------------------------------------
+ if (exists $collectRegisterFfdc->{target})
+ {
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{target}, ";
+ print EIFILE "fapi2::$id, RC, fapi2::TARGET_TYPE_NONE, fapi2::TARGET_TYPE_NONE); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{target},
+ lc($err->{rc}), $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{childTargets})
+ {
+ if (! exists $collectRegisterFfdc->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR: parent missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{childTargets}->{parent}, fapi2::$id, ";
+ print EIFILE "RC, fapi2::$collectRegisterFfdc->{childTargets}->{childType}, fapi2::TARGET_TYPE_NONE); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{childTargets}->{parent},
+ lc($err->{rc}), $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{basedOnPresentChildren})
+ {
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{target})
+ {
+ print ("parseErrorInfo.pl ERROR: target missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier})
+ {
+ print ("parseErrorInfo.pl ERROR: childPosOffsetMultiplier missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{basedOnPresentChildren}->{target}, fapi2::$id, RC, ";
+ print EIFILE "fapi2::TARGET_TYPE_NONE, fapi2::$collectRegisterFfdc->{basedOnPresentChildren}->{childType}, ";
+ print EIFILE "$collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier}); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{basedOnPresentChildren}->{target},
+ lc($err->{rc}), $target_ffdc_type);
+ }
+ else
+ {
+ print ("parseErrorInfo.pl ERROR: Invalid collectRegisterFfdc configuration\n");
+ exit(1);
+ }
+ }
+ }
+
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the ADD_ERROR_INFO macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_ADD_ERROR_INFO(RC) ";
+
+ # Array of EI Objects
+ my @eiObjects;
+
+ my $eiObjectStr = "const void * l_objects[] = {";
+ my $eiEntryStr = "";
+ my $eiEntryCount = 0;
+ my %cdgTargetHash; # Records the callout/deconfigure/gards for Targets
+ my %cdgChildHash; # Records the callout/deconfigure/gards for Children
+
+ # collect firmware trace
+ foreach my $collectTrace (@{$err->{collectTrace}})
+ {
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_COLLECT_TRACE; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].collect_trace.iv_eieTraceId = fapi2::CollectTraces::$collectTrace; \\\n";
+ $eiEntryCount++;
+ }
+
+ # Local FFDC
+ foreach my $ffdc (@{$err->{ffdc}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $ffdcName = $err->{rc} . "_";
+ $ffdcName = $ffdcName . $ffdc;
+ setFfdcIdValue($ffdcName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $ffdc);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $ffdc, lc($err->{rc}));
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$ffdcName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = fapi2::getErrorInfoFfdcSize($ffdc); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Buffers, looks a lot like local ffdc
+ foreach my $buffer (@{$err->{buffer}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $bufferName = $err->{rc} . "_";
+ $bufferName = $bufferName . $buffer;
+ setFfdcIdValue($bufferName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $buffer);
+
+ # Add a method to the ffdc-gathering class - one for each buffer type
+ addFfdcMethod(\%methods, $buffer, lc($err->{rc}), $buffer_ffdc_type);
+ addFfdcMethod(\%methods, $buffer, lc($err->{rc}), $variable_buffer_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$bufferName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = fapi2::getErrorInfoFfdcSize($buffer); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Procedure/Target/Bus/Child callouts
+ foreach my $callout (@{$err->{callout}})
+ {
+ if (! exists $callout->{priority})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout priority missing\n");
+ exit(1);
+ }
+
+ my $elementsFound = 0;
+ if (exists $callout->{hw})
+ {
+ # HW Callout
+ if (! exists $callout->{hw}->{hwid})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. HW Callout hwid missing\n");
+ exit(1);
+ }
+
+ # Check that those HW callouts that need reference targets have them
+ if (($callout->{hw}->{hwid} eq "TOD_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "MEM_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PROC_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PCI_REF_CLOCK"))
+ {
+ if (! exists $callout->{hw}->{refTarget})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout missing refTarget\n");
+ exit(1);
+ }
+ }
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_HW_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_hw = fapi2::HwCallouts::$callout->{hw}->{hwid}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ if (exists $callout->{hw}->{refTarget})
+ {
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $callout->{hw}->{refTarget});
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = $objNum; \\\n";
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $callout->{hw}->{refTarget}, lc($err->{rc}));
+ }
+ else
+ {
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = 0xff; \\\n";
+ }
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{procedure})
+ {
+ # Procedure Callout
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_PROCEDURE_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_procedure = fapi2::ProcedureCallouts::$callout->{procedure}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{bus})
+ {
+ # A Bus Callout consists of two targets separated by
+ # commas/spaces
+ my @targets = split(/\s*,\s*|\s+/, $callout->{bus});
+
+ if (scalar @targets != 2)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. did not find two targets in bus callout\n");
+ exit(1);
+ }
+
+ # Check the type of the Targets
+ print EIFILE "fapi2::checkType<const $target_ffdc_type *>($targets[0]); \\\n";
+ print EIFILE "fapi2::checkType<const $target_ffdc_type *>($targets[1]); \\\n";
+
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum1 = addEntryToArray(\@eiObjects, $targets[0]);
+
+ my $objNum2 = addEntryToArray(\@eiObjects, $targets[1]);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $targets[0], lc($err->{rc}), $target_ffdc_type);
+ addFfdcMethod(\%methods, $targets[1], lc($err->{rc}), $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_BUS_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint1ObjIndex = $objNum1; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint2ObjIndex = $objNum2; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # deconfigure and GARD requests
+ $cdgTargetHash{$callout->{target}}{callout} = 1;
+ $cdgTargetHash{$callout->{target}}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+ }
+ if (exists $callout->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $callout->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout parent missing\n");
+ exit(1);
+ }
+
+ if (! exists $callout->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any deconfigure and GARD requests
+ my $parent = $callout->{childTargets}->{parent};
+ my $childType = $callout->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{callout} = 1;
+ $cdgChildHash{$parent}{$childType}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+
+ if (exists $callout->{childTargets}->{childPort})
+ {
+ my $childPort = $callout->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if (exists $callout->{childTargets}->{childNumber})
+ {
+ my $childNum = $callout->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout has multiple elements\n");
+ exit(1);
+ }
+ } # callout
+
+ # Target/Child deconfigures
+ foreach my $deconfigure (@{$err->{deconfigure}})
+ {
+ my $elementsFound = 0;
+ if (exists $deconfigure->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and GARD requests
+ $cdgTargetHash{$deconfigure->{target}}{deconf} = 1;
+ $elementsFound++;
+ }
+ if (exists $deconfigure->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $deconfigure->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure parent missing\n");
+ exit(1);
+ }
+ if (! exists $deconfigure->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and GARD requests
+ my $parent = $deconfigure->{childTargets}->{parent};
+ my $childType = $deconfigure->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{deconf} = 1;
+
+ $elementsFound++;
+
+ if ( exists $deconfigure->{childTargets}->{childPort})
+ {
+ my $childPort = $deconfigure->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if ( exists $deconfigure->{childTargets}->{childNumber})
+ {
+ my $childNum = $deconfigure->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure has multiple elements\n");
+ exit(1);
+ }
+ } # deconfigure
+
+ # Target/Child Gards
+ foreach my $gard (@{$err->{gard}})
+ {
+ my $elementsFound = 0;
+ if (exists $gard->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and deconfigure requests
+ $cdgTargetHash{$gard->{target}}{gard} = 1;
+ $elementsFound++;
+ }
+ if (exists $gard->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $gard->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD parent missing\n");
+ exit(1);
+ }
+ if (! exists $gard->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and deconfigure requests
+ my $parent = $gard->{childTargets}->{parent};
+ my $childType = $gard->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{gard} = 1;
+
+ $elementsFound++;
+
+ if ( exists $gard->{childTargets}->{childPort})
+ {
+ my $childPort = $gard->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+
+ }
+
+ if ( exists $gard->{childTargets}->{childNumber})
+ {
+ my $childNum = $gard->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD has multiple elements\n");
+ exit(1);
+ }
+ } # gard
+
+ # Process the callout, deconfigures and GARDs for each Target
+ foreach my $cdg (keys %cdgTargetHash)
+ {
+ # Check the type
+ print EIFILE "fapi2::checkType<const $target_ffdc_type *>($cdg); \\\n";
+
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+
+ if (exists $cdgTargetHash{$cdg}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{priority})
+ {
+ $priority = $cdgTargetHash{$cdg}->{priority};
+ }
+ if (exists $cdgTargetHash{$cdg}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{gard})
+ {
+ $gard = 1;
+ }
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $cdg);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $cdg, lc($err->{rc}), $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CDG; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_targetObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+
+ # Process the callout, deconfigures and GARDs for Child Targets
+ foreach my $parent (keys %cdgChildHash)
+ {
+ # Check the type
+ print EIFILE "fapi2::checkType<const $target_ffdc_type *>($parent); \\\n";
+
+ foreach my $childType (keys %{$cdgChildHash{$parent}})
+ {
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+ my $childPort = 0xFF;
+ my $childNumber = 0xFF;
+
+ if (exists $cdgChildHash{$parent}{$childType}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{priority})
+ {
+ $priority =
+ $cdgChildHash{$parent}->{$childType}->{priority};
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childPort})
+ {
+ $childPort =
+ $cdgChildHash{$parent}->{$childType}->{childPort} ;
+ addFfdcMethod(\%methods, $childPort, lc($err->{rc}));
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childNumber})
+ {
+ $childNumber =
+ $cdgChildHash{$parent}->{$childType}->{childNumber} ;
+ addFfdcMethod(\%methods, $childNumber, lc($err->{rc}));
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{gard})
+ {
+ $gard = 1;
+ }
+
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $parent);
+ addFfdcMethod(\%methods, $parent, lc($err->{rc}), $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CHILDREN_CDG; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_parentObjIndex = $objNum; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childType = fapi2::$childType; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childPort = $childPort; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childNumber = $childNumber; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+ }
+
+ # Add all objects to $eiObjectStr
+ my $objCount = 0;
+
+ foreach my $eiObject (@eiObjects)
+ {
+ if ($objCount > 0)
+ {
+ $eiObjectStr .= ", ";
+ }
+
+ if ($mangle_names{$eiObject} eq undef)
+ {
+ $eiObjectStr .= "$eiObject"
+ }
+ else
+ {
+ $eiObjectStr .= $mangle_names{$eiObject};
+ }
+
+ $objCount++;
+ }
+ $eiObjectStr .= "};";
+
+ # Print info to file
+ if ($eiEntryCount > 0)
+ {
+ print EIFILE "\\\n{ \\\n $eiObjectStr \\\n";
+ print EIFILE " fapi2::ErrorInfoEntry l_entries[$eiEntryCount]; \\\n";
+ print EIFILE "$eiEntryStr";
+ print EIFILE " RC.addErrorInfo(l_objects, l_entries, $eiEntryCount); \\\n}";
+ }
+
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ # Remove the repeated whitespace and newlines other characters from the description
+ $err->{description} =~ s/^\s+|\s+$|"//g;
+ $err->{description} =~ tr{\n}{ };
+ $err->{description} =~ s/\h+/ /g;
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ my $class_name = lc($err->{rc});
+
+ # Class declaration
+ print ECFILE "\nclass $class_name\n{\n public:\n";
+
+ # Constructor. This traces the description. If this is too much, we can
+ # remove it.
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err):\n";
+ print ECFILE " iv_rc(i_rc),\n";
+ print ECFILE " iv_sev(i_sev)\n";
+ print ECFILE " { FAPI_ERR(\"$err->{description}\"); }\n";
+ }
+ else
+ {
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err)\n";
+ print ECFILE " {}\n";
+ }
+
+ # Methods
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{method};
+ }
+
+ # Stick the execute method at the end of the other methods.
+ print ECFILE " void execute(void)\n";
+ print ECFILE " {\n";
+ print ECFILE " FAPI_SET_HWP_ERROR(iv_rc, $err->{rc});\n" if ($arg_empty_ffdc eq undef);
+ print ECFILE " fapi2::logError(iv_rc, iv_sev);\n" if ($arg_empty_ffdc eq undef);
+ print ECFILE " }\n\n";
+
+ # Instance variables
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " private:\n ";
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{member};
+ }
+
+ print ECFILE "fapi2::ReturnCode& iv_rc;\n";
+ print ECFILE " fapi2::errlSeverity_t iv_sev;\n";
+ }
+
+ print ECFILE "};\n\n\n\n";
+ }
+
+ #--------------------------------------------------------------------------
+ # For each registerFfdc.
+ #--------------------------------------------------------------------------
+ foreach my $registerFfdc (@{$errors->{registerFfdc}})
+ {
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $registerFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR. id missing from registerFfdc\n");
+ exit(1);
+ }
+
+ if (scalar @{$registerFfdc->{id}} > 1)
+ {
+ print ("parseErrorInfo.pl ERROR. multiple ids in registerFfdc\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Set the FFDC ID value in a global hash
+ #----------------------------------------------------------------------
+ setFfdcIdValue($registerFfdc->{id}[0]);
+
+ #----------------------------------------------------------------------
+ # Generate code to capture the registers in collect_reg_ffdc.C
+ #----------------------------------------------------------------------
+ print CRFILE " case $registerFfdc->{id}[0]:\n";
+
+=begin NEED_P9_REGISTERS
+ # Look for CFAM Register addresses
+ foreach my $cfamRegister (@{$registerFfdc->{cfamRegister}})
+ {
+ print CRFILE " l_cfamAddresses.push_back($cfamRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_cfamData);\n";
+ }
+
+ # Look for SCOM Register addresses
+ foreach my $scomRegister (@{$registerFfdc->{scomRegister}})
+ {
+ print CRFILE " l_scomAddresses.push_back($scomRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_scomData);\n";
+ }
+=cut NEED_P9_REGISTERS
+
+ print CRFILE " break;\n";
+ }
+
+}
+
+#------------------------------------------------------------------------------
+# Print end of file information to collect_reg_ffdc.C
+#------------------------------------------------------------------------------
+print CRFILE " default:\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Invalid FFDC ID 0x%x\", ";
+print CRFILE "i_ffdcId);\n";
+print CRFILE " return;\n";
+print CRFILE " }\n\n";
+
+=begin NEED_P9_REGISTERS
+
+print CRFILE " uint8_t * l_pBuf = NULL;\n";
+print CRFILE " uint8_t * l_pData = NULL;\n";
+print CRFILE " std::vector<fapi::Target> l_targets;\n";
+print CRFILE " uint32_t l_chipletPos32 = 0;\n";
+#---------------------------------------------------------------------------------------------------------
+# Populate chiplet vectors (if required by register collection method) and adjust buffer sizes accordingly
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_child)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_child, l_targets, TARGET_STATE_FUNCTIONAL);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_presChild, l_targets, TARGET_STATE_PRESENT);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " l_targets.push_back(i_target);\n";
+print CRFILE " }\n\n";
+#---------------------------------------------------------------------------------------------------------
+# Obtain target position and insert as the first word in the buffer
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " bool l_targIsChiplet = i_target.isChiplet();\n\n";
+print CRFILE " for (std::vector<fapi::Target>::const_iterator targetIter = l_targets.begin();\n";
+print CRFILE " targetIter != l_targets.end(); ++targetIter)\n";
+print CRFILE " {\n";
+print CRFILE " if ((fapi2::TARGET_TYPE_NONE != i_child) ||\n";
+print CRFILE " (fapi2::TARGET_TYPE_NONE != i_presChild) ||\n";
+print CRFILE " (true == l_targIsChiplet))\n";
+print CRFILE " {\n";
+print CRFILE " uint8_t l_chipletPos = 0;\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*targetIter), l_chipletPos);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chiplet position\");\n";
+print CRFILE " l_chipletPos = 0xFF;\n";
+print CRFILE " }\n";
+ #-------------------------------------------------------------------------
+ # We print the target's position in the error log whether the target is a
+ # chip or chiplet, so we need to store the chiplet position in a uint32_t
+ # to have consitency in the buffer as ATTR_POS below returns a uint32_t
+ #-------------------------------------------------------------------------
+print CRFILE " l_chipletPos32 = l_chipletPos;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_POS, &(*targetIter), l_chipletPos32);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chip position\");\n";
+print CRFILE " l_chipletPos32 = 0xFFFFFFFF;\n";
+print CRFILE " }\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_chipletPos32;\n";
+print CRFILE " l_pData += sizeof(l_chipletPos32);\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert cfam data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint32_t>::const_iterator cfamIter = l_cfamAddresses.begin();\n";
+print CRFILE " cfamIter != l_cfamAddresses.end(); ++cfamIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(i_target, (*cfamIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(*targetIter, *cfamIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: CFAM error for 0x%x\",";
+print CRFILE "*cfamIter);\n";
+print CRFILE " l_cfamData = 0xbaddbadd;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_cfamData = l_buf.getWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_cfamData;\n";
+print CRFILE " l_pData += sizeof(l_cfamData);\n";
+print CRFILE " }\n\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert any scom data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint64_t>::const_iterator scomIter = l_scomAddresses.begin();\n";
+print CRFILE " scomIter != l_scomAddresses.end(); ++scomIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(i_target, (*scomIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(*targetIter, *scomIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: SCOM error for 0x%llx\",";
+print CRFILE "*scomIter);\n";
+print CRFILE " l_scomData = 0xbaddbaddbaddbaddULL;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_scomData = l_buf.getDoubleWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint64_t *>(l_pData)) = l_scomData;\n";
+print CRFILE " l_pData += sizeof(l_scomData);\n";
+print CRFILE " }\n";
+print CRFILE " }\n\n";
+print CRFILE " o_rc.addEIFfdc(i_ffdcId, l_pBuf, l_ffdcSize);\n";
+print CRFILE " delete [] l_pBuf;\n";
+=cut NEED_P9_REGISTERS
+
+print CRFILE "}\n";
+print CRFILE "}\n";
+
+
+#------------------------------------------------------------------------------
+# Print the fapiHwpReturnCodes.H file
+#------------------------------------------------------------------------------
+print RCFILE "// fapiHwpReturnCodes.H\n";
+print RCFILE "// This file is generated by perl script parseErrorInfo.pl\n\n";
+print RCFILE "#ifndef FAPI2_HWPRETURNCODES_H_\n";
+print RCFILE "#define FAPI2_HWPRETURNCODES_H_\n\n";
+print RCFILE "#ifndef __ASSEMBLER__\n";
+print RCFILE "namespace fapi2\n";
+print RCFILE "{\n\n";
+print RCFILE "/**\n";
+print RCFILE " * \@brief Enumeration of HWP return codes\n";
+print RCFILE " *\/\n";
+print RCFILE "enum HwpReturnCode\n";
+print RCFILE "{\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " $key = 0x$errNameToValueHash{$key},\n";
+}
+print RCFILE "};\n\n";
+print RCFILE "}\n\n";
+print RCFILE "#else\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " .set $key, 0x$errNameToValueHash{$key}\n";
+}
+print RCFILE "#endif\n";
+print RCFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print the HwpFfdcId enumeration to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "namespace fapi2\n";
+print EIFILE "{\n\n";
+print EIFILE "/**\n";
+print EIFILE " * \@brief Enumeration of FFDC identifiers\n";
+print EIFILE " *\/\n";
+print EIFILE "enum HwpFfdcId\n";
+print EIFILE "{\n";
+foreach my $key (keys %ffdcNameToValueHash)
+{
+ print EIFILE " $key = 0x$ffdcNameToValueHash{$key},\n";
+}
+print EIFILE "};\n\n";
+print EIFILE "}\n\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "\n};\n"; # close the namespace
+print ECFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to set_sbe_error.H
+#------------------------------------------------------------------------------
+print SBFILE " default:\\\n";
+print SBFILE " FAPI_SET_HWP_ERROR(RC, RC_SBE_UNKNOWN_ERROR);\\\n";
+print SBFILE " break;\\\n";
+print SBFILE "}\\\n";
+print SBFILE "}\n\n";
+print SBFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Close output files
+#------------------------------------------------------------------------------
+close(RCFILE);
+close(EIFILE);
+close(ECFILE);
+close(CRFILE);
+close(SBFILE);
diff --git a/src/ppe/hwpf/fapi/xml/buffer_errors.xml b/src/ppe/hwpf/fapi/xml/buffer_errors.xml
new file mode 100755
index 0000000..4cf6718
--- /dev/null
+++ b/src/ppe/hwpf/fapi/xml/buffer_errors.xml
@@ -0,0 +1,40 @@
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/ppe/hwpf/fapi/xml/buffer_errors.xml $ -->
+<!-- -->
+<!-- OpenPOWER OnChipController Project -->
+<!-- -->
+<!-- Contributors Listed Below - COPYRIGHT 2012,2015 -->
+<!-- [+] International Business Machines Corp. -->
+<!-- -->
+<!-- -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
+<!-- you may not use this file except in compliance with the License. -->
+<!-- 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_FAPI2_BUFFER</rc>
+ <description>
+ fapi2 error from a buffer operation
+ </description>
+ <buffer>BUFFER</buffer>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+</hwpErrors>
diff --git a/src/ppe/hwpf/plat/.empty b/src/ppe/hwpf/plat/.empty
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/hwpf/plat/.empty
diff --git a/src/ppe/hwpf/plat/include/array.H b/src/ppe/hwpf/plat/include/array.H
new file mode 100644
index 0000000..ca83088
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/array.H
@@ -0,0 +1,174 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/array.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 array.H
+ * @brief definitions for fapi2 arrays
+ */
+
+#ifndef __FAPI2_ARRAY__
+#define __FAPI2_ARRAY__
+
+#include <stdint.h>
+#include <utility>
+#include <assert.h>
+#include <string.h>
+
+namespace fapi2
+{
+ ///
+ /// @brief Class representing a FAPI2 array
+ /// FAPI2 arrays are defined to be very lightweight but support
+ /// c++ container operations (iterators, bounds checking, assignment, etc.)
+ /// To avoid the code-bloat associated with std::vector templates,
+ /// fapi2::array is presently limited to 64-bit elements.
+ ///
+ /// To construct an array, you can either pass in an existing chunk
+ /// of memory, or let the container allocate memory for you:
+ /// fapi2::array foo(3, &PIB_MEM_BLOCK);
+ /// creates an array 3 x uit64_t in size, located at &PIB_MEM_BLOCK.
+ /// The memory pointed to by the address passed in is untouched
+ /// during creation. This allows for a light-weight overlay on top
+ /// of existing memory. It also means you need to initialize the space
+ /// yourself.
+ /// fapi2_array foo(3);
+ /// creates an array 3 x uint64_t in size, and that memory will be
+ /// allocated by the constructor and initiaized to 0's.
+ ///
+ ///
+ class array
+ {
+ public:
+
+ typedef uint64_t element_type;
+ typedef element_type* iterator;
+ typedef const element_type* const_iterator;
+
+ ///
+ /// @brief Create an array
+ /// @param[in] the size of the array
+ /// @param[in] a pointer to memory of appropriate size
+ /// defaults to nullptr which causes the platform to
+ /// allocate memory of size * element_type
+ /// @warning fapi2::arrays, like arrays, can not be re-sized after
+ /// creation.
+ ///
+ array(const uint32_t i_size, element_type* i_data = nullptr);
+
+ ///
+ /// @brief Destroy an array
+ ///
+ ~array(void);
+
+ ///
+ /// @brief operator[]
+ /// @param[in] the index of the element
+ /// @return a reference to the element in question.
+ /// @note array[0] = 0 works as well as foo = array[0]
+ ///
+ element_type& operator[](const uint32_t i_index);
+
+ ///
+ /// @brief operator=()
+ /// @param[in] the other array
+ /// @return a reference to this, after the assignement
+ ///
+ array& operator=(const array& i_other);
+
+ ///
+ /// @brief move operator=()
+ /// @note To use: new_array = std::move(old_array). old_array will be
+ /// destroyed and no copy will be made (moved)
+ ///
+ array& operator=(array&& i_other);
+
+ ///
+ /// @brief operator==()
+ ///
+ bool operator==(const array& i_other);
+
+ ///
+ /// @brief operator!=()
+ ///
+ __attribute__ ((always_inline))
+ bool operator!=(const array& i_other)
+ { return ! operator==(i_other); }
+
+ ///
+ /// @brief Return an iterator the to beginning of the array
+ /// @return An iterator to the beginning of the array
+ ///
+ __attribute__ ((always_inline))
+ iterator begin(void)
+ { return iv_data; }
+
+ ///
+ /// @brief Return an iterator the to end of the array
+ /// @return An iterator to the end of the array
+ ///
+ __attribute__ ((always_inline))
+ iterator end(void)
+ { return iv_data + size(); }
+
+ ///
+ /// @brief Return a const_iterator the to beginning of the array
+ /// @return A const_iterator to the beginning of the array
+ ///
+ __attribute__ ((always_inline))
+ const_iterator begin(void) const
+ { return iv_data; }
+
+ ///
+ /// @brief Return a const_iterator the to end of the array
+ /// @return A const_iterator to the end the array
+ ///
+ __attribute__ ((always_inline))
+ const_iterator end(void) const
+ { return iv_data + size(); }
+
+ private:
+
+ enum
+ {
+ // Bit in iv_size representing whether we delete in the dtor
+ delete_bit = 0x80000000,
+
+ // The resulting size limit
+ size_limit = 0x7FFFFFFF,
+ };
+
+ __attribute__ ((always_inline))
+ uint32_t size(void)
+ { return (iv_size & ~delete_bit); }
+
+ __attribute__ ((always_inline))
+ uint32_t size(void) const
+ { return (iv_size & ~delete_bit); }
+
+ uint32_t iv_size;
+ element_type* iv_data;
+ };
+}
+
+#endif
diff --git a/src/ppe/hwpf/plat/include/buffer.H b/src/ppe/hwpf/plat/include/buffer.H
new file mode 100644
index 0000000..607107d
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/buffer.H
@@ -0,0 +1,423 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/buffer.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 buffer.H
+ * @brief definitions for fapi2 variable integral buffers
+ */
+
+#ifndef __FAPI2_INTEGRAL_BUFFER__
+#define __FAPI2_INTEGRAL_BUFFER__
+
+#include <buffer_base.H>
+#include <return_code.H>
+
+namespace fapi2
+{
+ /// @brief Class representing a FAPI buffer<T>
+ /// @note Buffers support method chaining. So, rather than
+ /// this
+ /// @code
+ /// buffer<T> mask;
+ /// mask.setBit<B>();
+ /// mask.invert();
+ /// my_buffer &= mask;
+ /// @endcode
+ /// You can do
+ /// @code
+ /// my_buffer &= buffer<T>().setBit<B>.invert();
+ /// @endcode
+ template <typename T>
+ class buffer : public buffer_base<T>
+ {
+ public:
+ /// Shortcut typedef to map to our traits class
+ typedef typename buffer_base<T, buffer>::bits_type bits_type;
+
+ ///
+ /// @brief Integral buffer assignment constructor
+ /// @param[in] i_value initial value of the buffer
+ /// Meaningless for variable types and thus protected.
+ ///
+ inline buffer(T i_value = 0)
+ {
+ // Why not an initializer list? That would force buffer_base<T>
+ // to have a ctor which took a T, and I want to avoid that in
+ // the generic case: this makes it more clear that the two
+ // ctor's (integral and container) behave very differently.
+ // variable_buffers also have a ctor which takes a single
+ // numerical value, and that represents a bit count, not an
+ // initial value.
+ this->iv_data = i_value;
+ }
+
+
+ /// @name Bit/Word Manipulation Functions
+ ///@{
+
+ ///
+ /// @brief Return the length of the buffer in bits
+ /// @return Length in bits
+ ///
+ inline constexpr uint32_t getBitLength(void) const
+ { return bufferTraits<T>::bit_length(this->iv_data); }
+
+ ///
+ /// @brief Return the length of the buffer in OT units
+ /// @return Length in OT units rounded up
+ /// @tparam OT the type to get the length of. For example, if one
+ /// wanted the length in double words, OT would be uint64_t
+ /// (getLength<uint64_t>().) Similarly, to get the length in words,
+ /// getLength<uin32_t>().
+ ///
+ template< typename OT >
+ inline constexpr uint32_t getLength(void) const
+ {
+ return bufferTraits<T>::template size<OT>(this->iv_data);
+ }
+
+ ///
+ /// @brief Templated setBit for integral types
+ /// @tparam B the bit number to set.
+ /// @return buffer& Useful for method chaining
+ /// @note 0 is left-most
+ /// @note Example: fapi2::buffer<uint64_t>().setBit<3>();
+ ///
+ template <bits_type B>
+ inline buffer& setBit(void)
+ {
+ static_assert((B >= 0) &&
+ (B < bufferTraits<T>::bits_per_unit), "failed range check");
+
+ // Force iv_data to be dependent on the template type to force
+ // its look up in the second phase
+ this->iv_data |= (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit - B - 1);
+ return *this;
+ }
+
+ ///
+ /// @brief Clear a bit in buffer
+ /// @tparam B Bit in buffer to clear.
+ /// @return buffer& Useful for method chaining
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type B >
+ inline buffer& clearBit(void)
+ {
+ static_assert((B >= 0) &&
+ (B < bufferTraits<T>::bits_per_unit), "failed range check");
+
+ this->iv_data &= buffer<T>().setBit<B>().invert();
+ return *this;
+ }
+
+ ///
+ /// @brief Invert bit
+ /// @tparam B Bit in buffer to invert.
+ /// @return buffer& Useful for method chaining
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type B >
+ inline buffer& flipBit(void)
+ {
+ static_assert((B >= 0) &&
+ (B < bufferTraits<T>::bits_per_unit), "failed range check");
+
+ this->iv_data ^= buffer<T>().setBit<B>();
+ return *this;
+ }
+
+ ///
+ /// @brief Set a bit in the buffer
+ /// @param[in] i_bit the bit number to set.
+ /// @note 0 is left-most
+ /// @return FAPI2_RC_SUCCESS if OK
+ ///
+ inline fapi2::ReturnCode setBit(const bits_type& i_bit)
+ {
+ if (i_bit >= bufferTraits<T>::bits_per_unit)
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ // Force iv_data to be dependent on the template type to force
+ // its look up in the second phase
+ this->iv_data |=
+ (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit - i_bit - 1);
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Get the value of a bit in the buffer
+ /// @tparam B Bit in buffer to get.
+ /// @return true if bit is on, false if bit is off
+ ///
+ template< bits_type B >
+ inline bool getBit(void) const
+ {
+ return buffer<T>().setBit<B>() & this->iv_data;
+ }
+
+ ///@}
+
+ /// @name Buffer Manipulation Functions
+ ///@{
+
+ // Note: Many (all?) of these are not needed and the compiler complains
+ // as the cast to T yields a better operator. There are here mainly for
+ // documenation purposes.
+
+ ///
+ /// @brief operator>>()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator>>(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator<<()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator<<(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator+()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator+(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator+=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator+=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator|=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator&=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator|(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator&(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator^=()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator^=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator~()
+ ///
+#ifdef DOXYGEN
+ buffer<T>& operator~(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief operator==()
+ ///
+#ifdef DOXYGEN
+ bool operator==(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief operator!=()
+ ///
+#ifdef DOXYGEN
+ bool operator!=(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief Copy part of a OT into the DataBuffer
+ /// @tparam TS Start bit to insert into (target start)
+ /// @tparam L Length of bits to insert
+ /// @tparam SS Start bit in source
+ /// @tparam OT the type of the incoming (origin) data
+ /// @param[in] i_datain OT value to copy into DataBuffer
+ /// - data is taken left aligned
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template<bits_type TS, bits_type L, bits_type SS, typename OT>
+ inline void insert(const OT i_datain)
+ {
+ const bits_type target_length = parameterTraits<T>::bit_length;
+ const bits_type source_length = parameterTraits<OT>::bit_length;
+
+ // Error if input data don't make sense
+ static_assert((TS + L) <= target_length,
+ "insert(): (Target Start + Len) is out of bounds");
+ static_assert((SS + L) <= source_length,
+ "insert(): (Source Start + Len) is out of bounds");
+ static_assert(TS < target_length,
+ "insert(): Target Start is out of bounds");
+ static_assert(SS < source_length,
+ "insert(): Source Start is out of bounds");
+
+ // Get mask value for Target buffer
+ // Note: Need "& ((T)-1) because bit shift left for Target buffer doesn't roll off
+ T mask =((T(~0) << (target_length - L)) & T(~0)) >> TS;
+
+ // Calculate the equivalent position of the input Source start for the size of the Target buffer.
+
+ // Assume OT is smaller (sizeof(T) > sizeof(OT))
+ uint64_t sourceShift = abs(TS - ((target_length - source_length) + SS));
+ uint64_t sourceAlign = T(i_datain) << sourceShift;
+
+ if (sizeof(T) == sizeof(OT))
+ {
+ sourceShift = abs(SS - TS);
+ sourceAlign = (SS > TS) ? ((T)i_datain) << sourceShift : ((T)i_datain) >> sourceShift;
+ }
+
+ if (sizeof(T) < sizeof(OT))
+ {
+ sourceShift = source_length - target_length;
+ if (SS <= sourceShift)
+ {
+ sourceShift = sourceShift + TS - SS;
+ sourceAlign = ((OT)i_datain) >> sourceShift;
+ }
+
+ // (SS > sourceShift)
+ else
+ {
+ if (sourceShift > TS)
+ {
+ sourceShift = SS - sourceShift - TS;
+ sourceAlign = OT(i_datain) << sourceShift;
+ }
+ else
+ {
+ sourceShift = SS - sourceShift;
+ sourceAlign = (sourceShift < TS) ? OT(i_datain) >> sourceShift : OT(i_datain);
+ }
+ }
+ }
+
+ this->iv_data = (this->iv_data & ~mask) | (sourceAlign & mask);
+ return;
+ }
+
+ ///
+ /// @brief Copy in a right aligned value
+ /// @tparam SB Start bit to insert into
+ /// @tparam L Length of bits to insert
+ /// @tparam OT the type of the incoming (origin) data
+ /// @param[in] i_datain OT value to copy into DataBuffer
+ /// - data is taken right aligned
+ /// @note Data is assumed to be aligned on the word boundary of L
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template<bits_type TS, bits_type L, typename OT>
+ inline void insertFromRight(const OT i_datain)
+ {
+ // Error if input data don't make sense
+ static_assert(L <= parameterTraits<OT>::bit_length,
+ "insertFromRight(): Len >= input buffer");
+ static_assert(TS < parameterTraits<T>::bit_length,
+ "insertFromRight(): Target Start is out of bounds");
+ static_assert((TS + L) <= parameterTraits<T>::bit_length,
+ "InsertFromRight(): (Target Start + Len) is out of bounds");
+
+ this->insert<TS, L, parameterTraits<OT>::bit_length - L>(i_datain);
+ return;
+ }
+
+ ///
+ /// @brief Copy data from this buffer into an OT
+ /// @tparam TS Start bit to insert into (target start)
+ /// @tparam L Length of bits to insert
+ /// @tparam SS Start bit in source
+ /// @tparam OT the type of the outgoing (target)
+ /// @param[out] o_out OT to copy into - data is placed left aligned
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template<bits_type TS, bits_type L, bits_type SS, typename OT>
+ inline void extract(OT& o_out)
+ {
+ // Extraction is just an insert into o_out
+
+ buffer<OT> out(o_out);
+ out.insert<TS, L, SS>(this->iv_data);
+ o_out = out;
+ return;
+ }
+
+#if 0
+ ///
+ /// @brief Copy data from this buffer into an OT and right justify
+ /// @tparam OT the type of the outgoing data - defaults to T
+ /// @tparam SB Start bit to insert into - defaults to 0
+ /// @tparam SS Start bit in o_out - default value is zero
+ /// @tparam L Length of bits to copy - defaults to sizeof(OT) * 8
+ /// @param[out] o_out OT to copy into - data is placed right aligned
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @post Data is copied from specified location to o_out, right
+ /// aligned. Data is only right aligned if L < sizeof(bits_type)
+ ///
+ template< typename OT = T, bits_type L = parameterTraits<OT>::bit_length,
+ bits_type SB = 0, bits_type SS = 0 >
+ void extractFromRight(OT& o_out);
+#endif
+ ///@}
+ };
+};
+
+#endif
diff --git a/src/ppe/hwpf/plat/include/buffer_parameters.H b/src/ppe/hwpf/plat/include/buffer_parameters.H
new file mode 100644
index 0000000..c34686e
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/buffer_parameters.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/buffer_parameters.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 buffer_parameters.H
+ * @brief definitions for fapi2 buffer parameter types
+ */
+
+#ifndef __FAPI2_BUFFER_PARAM__
+#define __FAPI2_BUFFER_PARAM__
+
+#include <stdint.h>
+
+namespace fapi2
+{
+ /// @cond
+ /// @brief Traits of buffer parameters - things passed in
+ /// @tparam T is the type of i_value (typically an integral type)
+ template<typename T>
+ class parameterTraits
+ {
+ public:
+ enum
+ {
+ mask = T(~0),
+ bit_length = sizeof(T) * 8,
+ byte_length = sizeof(T),
+ };
+
+ template<typename U>
+ inline static void write_element(void* i_data, T i_value, uint32_t i_offset)
+ {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ T* ptr = (T*)i_data + (i_offset ^ ((sizeof(U) / sizeof(T)) - 1));
+#else
+ T* ptr = (T*)i_data + i_offset;
+#endif
+ *ptr = i_value;
+ }
+ };
+ /// @endcond
+};
+
+#endif
diff --git a/src/ppe/hwpf/plat/include/buffer_traits.H b/src/ppe/hwpf/plat/include/buffer_traits.H
new file mode 100644
index 0000000..cfc699b
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/buffer_traits.H
@@ -0,0 +1,238 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/buffer_traits.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 buffer_traits.H
+ * @brief trait definitions for fapi2 buffer base class
+ */
+
+#ifndef __FAPI2_BUFFER_TRAITS__
+#define __FAPI2_BUFFER_TRAITS__
+
+#include <stdint.h>
+#include <vector>
+#include <algorithm>
+#include <buffer_parameters.H>
+
+#ifdef __FAPI2_DEBUG__
+// for debug printing ... can be removed for flight
+#include <iostream>
+#endif
+#include <iterator>
+
+namespace fapi2
+{
+ /// @cond
+ /// Types representing a container of bits. Used to create
+ /// variable_buffer.
+ typedef uint32_t container_unit;
+ typedef std::vector<container_unit> bits_container;
+
+ /// @brief Traits of buffers
+ // In general, we try to give buffers traits reflecting integral types. If
+ // this fails, the compiler will let someone know.
+ ///
+ /// @tparam T is the type of iv_data (std::vector, etc)
+ /// @tparam B is the type of the bit-specifier, typically uint32_t
+ template<typename T, typename B = uint32_t>
+ class bufferTraits
+ {
+ public:
+#ifndef DOXYGEN
+#ifdef __FAPI2_DEBUG__
+ ///
+ /// @brief Print a container of bits
+ /// @param[in] i_data the container of bits
+ ///
+ static inline void print(const T& i_data)
+ {
+ // convert to uint64_t to prevent uint8_t from being
+ // printed as a char.
+ std::cout << "\tdata is "
+ << std::hex
+ << static_cast<uint64_t>(i_data)
+ << std::dec << std::endl;
+ }
+#endif
+#endif
+
+ ///
+ /// @brief Return the size of the buffer in E units
+ /// @tparam E, the element size.
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in E's rounded up
+ ///
+ template<typename E>
+ constexpr static B size(const T& i_buffer)
+ {
+ return (bit_length(i_buffer) +
+ (parameterTraits<E>::bit_length - 1)) /
+ parameterTraits<E>::bit_length;
+ }
+
+ ///
+ /// @brief Return the size of the buffer itself
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in bits (not units)
+ ///
+ constexpr static B bit_length(const T&)
+ { return sizeof(T) * 8; }
+
+ ///
+ /// @brief Clear the buffer
+ /// @param[in,out] io_buffer the buffer which to clear
+ ///
+ static inline void clear(T& io_buffer)
+ { io_buffer = static_cast<T>(0); }
+
+ ///
+ /// @brief Set the buffer
+ /// @param[in,out] io_buffer the buffer which to set
+ ///
+ static inline void set(T& io_buffer)
+ { io_buffer = static_cast<T>(~0); }
+
+ ///
+ /// @brief Invert the buffer
+ /// @param[in,out] io_buffer the buffer which to invert
+ ///
+ static inline void invert(T& io_buffer)
+ { io_buffer = ~io_buffer; }
+
+ ///
+ /// @brief Reverse the buffer
+ /// @param[in,out] io_buffer the buffer which to reverse
+ ///
+ static inline void reverse(T& io_buffer)
+ {
+ io_buffer =
+ ((io_buffer & 0xAAAAAAAAAAAAAAAA) >> 1) |
+ ((io_buffer & 0x5555555555555555) << 1);
+ }
+
+ ///
+ /// @brief Get the address of the buffer as an array
+ /// @param[in] i_buffer the buffer which to invert
+ /// @return The address of the first element of the buffer
+ ///
+ static inline void* get_address(T& i_buffer)
+ { return (void*)&i_buffer; }
+
+ typedef B bits_type;
+ typedef T unit_type;
+ enum { bits_per_unit = sizeof(unit_type) * 8 };
+ };
+
+ //
+ //
+ /// @brief Traits for buffers which are a container of bits
+ //
+ //
+ template<>
+ class bufferTraits<bits_container, uint32_t>
+ {
+ public:
+#ifndef DOXYGEN
+#ifdef __FAPI2_DEBUG__
+ ///
+ /// @brief Print a container of bits
+ /// @param[in] i_data the container of bits
+ ///
+ static inline void print(const bits_container& i_data)
+ {
+ std::cout << "\tdata is " << std::hex;
+ std::copy(i_data.begin(), i_data.end(),
+ std::ostream_iterator<container_unit>(std::cout, " "));
+ std::cout << std::dec << std::endl;
+ }
+#endif
+#endif
+
+ ///
+ /// @brief Return the size of the buffer in E units
+ /// @tparam E, the element size.
+ /// @param[in] io_buffer the buffer which to size
+ /// @return The size of the buffer in E's rounded up
+ ///
+ template<typename E>
+ constexpr static uint32_t size(const bits_container& i_buffer)
+ {
+ return (bit_length(i_buffer) +
+ (parameterTraits<E>::bit_length - 1)) /
+ parameterTraits<E>::bit_length;
+ }
+
+ ///
+ /// @brief Return the size of the buffer itself
+ /// @param[in,out] io_buffer the buffer which to size
+ /// @return The size of the buffer in bits (not units)
+ ///
+ static inline uint32_t bit_length(const bits_container& i_buffer)
+ { return i_buffer.size() * sizeof(container_unit) * 8; }
+
+ ///
+ /// @brief Clear the buffer
+ /// @param[in,out] io_buffer the buffer which to clear
+ ///
+ static inline void clear(bits_container& io_buffer)
+ { io_buffer.assign(io_buffer.size(), 0); }
+
+ ///
+ /// @brief Set the buffer
+ /// @param[in,out] io_buffer the buffer which to set
+ ///
+ static inline void set(bits_container& io_buffer)
+ { io_buffer.assign(io_buffer.size(), ~0); }
+
+ ///
+ /// @brief Invert the buffer
+ /// @param[in,out] io_buffer the buffer which to invert
+ ///
+ static inline void invert(bits_container& io_buffer)
+ {
+ std::transform(io_buffer.begin(), io_buffer.end(),
+ io_buffer.begin(),
+ [](container_unit u) { return ~u; });
+ }
+
+ ///
+ /// @brief Get the address of the buffer as an array
+ /// @param[in] i_buffer the buffer which to invert
+ /// @return The address of the first element of the buffer
+ ///
+ static inline void* get_address(bits_container& i_buffer)
+ {
+ return (void*)&(i_buffer[0]);
+ }
+
+ typedef uint32_t bits_type;
+ typedef container_unit unit_type;
+ enum { bits_per_unit = sizeof(unit_type) * 8 };
+ };
+ /// @endcond
+};
+
+
+
+#endif
diff --git a/src/ppe/hwpf/plat/include/error_scope.H b/src/ppe/hwpf/plat/include/error_scope.H
new file mode 100644
index 0000000..173b6d1
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/error_scope.H
@@ -0,0 +1,147 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/error_scope.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 error_scope.H
+ * @brief definitions which create a scope for automatic error handling
+ */
+
+#ifndef __FAPI2_ERROR_SCOPE__
+#define __FAPI2_ERROR_SCOPE__
+
+#include <stdint.h>
+#include <thread>
+#include <stdio.h>
+#include <return_code.H>
+#include <plat_includes.H>
+
+
+extern "C"
+{
+#ifndef __noRC__
+ extern fapi2::ReturnCode G_current_err;
+#endif
+ extern uint64_t G_pib_error_mask;
+ extern uint64_t G_operational_state;
+}
+
+
+///
+/// @brief Place holder until more of the FAPI infrastructure
+/// can be compiled with this file
+/// @param[in] ... varargs, passed to a platform specific output function
+/// @note This is skeleton implementation for prototype purposes. This
+/// does not imply "printf" is used on any or all platforms.
+///
+#define FAPI_INF( ... )
+#define FAPI_ERR( ... ) PK_TRACE( __VA_ARGS__ )
+//#define FAPI_DBG( ... ) PK_TRACE( __VA_ARGS__ )
+#define FAPI_DBG( ... )
+
+/// @cond
+#define FAPI_VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
+#define FAPI_VA_NARGS(...) FAPI_VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
+
+//#define FAPI_TRY_IMPL2(...) FAPI_TRY_TRACE (__VA_ARGS__)
+#define FAPI_TRY_IMPL2(count, ...) FAPI_TRY ## count (__VA_ARGS__)
+#define FAPI_TRY_IMPL(count, ...) FAPI_TRY_IMPL2(count, __VA_ARGS__)
+
+#ifndef __noRC__
+#define FAPI_TRY_NO_TRACE( __operation__ ) \
+ if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \
+ { \
+ goto clean_up; \
+ }
+#else
+#define FAPI_TRY_NO_TRACE( __operation__ ) \
+ (__operation__);
+#endif
+
+// Why debug? Because this isn't a mechanism to gather FFDC
+// one should be using FAPI_ASSERT. However, it is nice to
+// have a conditional trace in the event of a failure in the
+// operation, so that's why this is here.
+// if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS)
+#ifndef __noRC__
+#define FAPI_TRY_TRACE( __operation__, ... ) \
+ if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \
+ { \
+ FAPI_DBG(__VA_ARGS__); \
+ goto clean_up; \
+ }
+#define FAPI_CLEANUP() \
+clean_up:
+#else
+/// @todo: something is wrong needed the goto_cleanup
+#define FAPI_TRY_TRACE( __operation__, ... ) \
+ FAPI_DBG(__VA_ARGS__); \
+ (__operation__)
+
+#define FAPI_CLEANUP()
+
+#endif
+
+#define FAPI_TRY0 FAPI_TRY_NO_TRACE
+#define FAPI_TRY1 FAPI_TRY_TRACE
+#define FAPI_TRY2 FAPI_TRY_TRACE
+#define FAPI_TRY3 FAPI_TRY_TRACE
+#define FAPI_TRY4 FAPI_TRY_TRACE
+#define FAPI_TRY5 FAPI_TRY_TRACE
+/// @endcond
+
+///
+/// @brief Wrapper to check an operation for an error state
+/// and jump to the label cleam_up if there is an error.
+/// @param[in] __operation__ an operation which returns a fapi::ReturnCode
+/// @param[in] Optional vararg format/agruments for trace output.
+/// @note This implementation does not support PIB error masks or
+/// FSP operational states.
+/// @warning The trace information is only going to be seen during
+/// debug, it's not an error or informational trace. This is because
+/// traces might not be seen in the field. If you want information
+/// you will see on a field error, use FAPI_ASSERT.
+///
+#ifdef DOXYGEN
+#define FAPI_TRY(__operation__, ...) FAPI_TRY_IMPL
+#else
+#define FAPI_TRY(...) FAPI_TRY_IMPL(FAPI_VA_NARGS(__VA_ARGS__), __VA_ARGS__)
+#endif
+
+///
+/// @brief Assert a conditional is true.
+/// If it is not, the FFDC gathering function is called and the
+/// trace is output as a FAPI error trace.
+/// @param[in] __conditional__ the condition to assert
+/// @param[in] __ffdc__ the FFDC gathering function
+/// @param[in] ... varargs, as input to FAPI_ERR
+///
+#define FAPI_ASSERT( __conditional__, __ffdc__, ... ) \
+ if (! (__conditional__)) \
+ { \
+ /* __ffdc__; */ \
+ FAPI_ERR(__VA_ARGS__); \
+ goto clean_up; \
+ }
+
+#endif // __FAPI2_ERROR_SCOPE__
diff --git a/src/ppe/hwpf/plat/include/fapi2.H b/src/ppe/hwpf/plat/include/fapi2.H
new file mode 100644
index 0000000..17d3d59
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/fapi2.H
@@ -0,0 +1,76 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/fapi2.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file fapi2.H
+/// @brief top level header for fapi2
+///
+
+#ifndef __FAPI2_TOP_LEVEL__
+#define __FAPI2_TOP_LEVEL__
+
+// Define which platforms will not have FAPI Return Codes
+#undef __noRC__
+#if defined (__CME__) || defined (__SGPE__) || defined (__PGPE__)
+#define __noRC__
+#endif
+
+// Determine if running on a PPE platform
+#ifndef __PPE__
+#if defined (__SBE__) || defined (__CME__) || defined (__SGPE__) || defined (__PGPE__)
+#define __PPE__
+#endif
+#endif
+
+#include <plat_trace.H>
+#include <target.H>
+#include <return_code.H>
+#include <buffer.H>
+#include <hw_access.H>
+#include <utils.H>
+
+
+// In turn includes the needed generated headers (hwp_ffd_classes, etc.)
+#include <error_scope.H>
+//#include <set_sbe_error.H> // Generated file mb empty file addCopyright.pl does not like empty files
+#include <fapi2AttributeService.H>
+#include <fapi2AttributeIds.H> // Generated file
+
+
+// #include <hwp_executor.H> // mb empty file addCopyright.pl does not like empty files
+
+// Block of headers not currently in fapi2
+#ifdef FAPI2_MISSING_HEADERS
+ #include <mvpdAccess.H>
+ #include <mbvpdAccess.H>
+#endif
+
+
+#endif // __FAPI2_TOP_LEVEL__
+
+
+
+
+
+
diff --git a/src/ppe/hwpf/plat/include/fapi2Structs.H b/src/ppe/hwpf/plat/include/fapi2Structs.H
new file mode 100644
index 0000000..c13b428
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/fapi2Structs.H
@@ -0,0 +1,133 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/fapi2Structs.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef fapiStructs_h
+#define fapiStructs_h
+// Copyright **********************************************************
+//
+// File fapiStructs.H
+//
+// IBM Confidential
+// OCO Source Materials
+// 9400 Licensed Internal Code
+// (C) COPYRIGHT IBM CORP. 1996
+//
+// The source code for this program is not published or otherwise
+// divested of its trade secrets, irrespective of what has been
+// deposited with the U.S. Copyright Office.
+//
+// End Copyright ******************************************************
+
+/**
+ * @file fapiStructs.H
+ * @brief fapi eCMD Extension Structures
+
+ * Extension Owner : John Farrugia
+*/
+
+//--------------------------------------------------------------------
+// Includes
+//--------------------------------------------------------------------
+#include <string>
+
+
+//--------------------------------------------------------------------
+// Forward References
+//--------------------------------------------------------------------
+
+#define ECMD_FAPI_CAPI_VERSION "1.0" ///< eCMD FAPI Extension version
+
+
+
+#ifndef ECMD_PERLAPI
+
+namespace fapi
+{
+
+/**
+ * @brief Enumeration of fapi file types
+ */
+typedef enum {
+ FAPI_FILE_UNKNOWN, ///< Default for not initialized
+ FAPI_FILE_HWP
+} FileType_t;
+
+
+enum AttributeSource
+{
+ FAPI_ATTRIBUTE_SOURCE_UNKNOWN = 0x00000000,
+ FAPI_ATTRIBUTE_SOURCE_PLAT = 0x00000001,
+ FAPI_ATTRIBUTE_SOURCE_HWP = 0x00000002,
+};
+
+
+#define FAPI_ATTRIBUTE_TYPE_STRING 0x80000000
+#define FAPI_ATTRIBUTE_TYPE_UINT8 0x40000000
+#define FAPI_ATTRIBUTE_TYPE_UINT32 0x20000000
+#define FAPI_ATTRIBUTE_TYPE_UINT64 0x10000000
+#define FAPI_ATTRIBUTE_TYPE_UINT8ARY 0x04000000
+#define FAPI_ATTRIBUTE_TYPE_UINT32ARY 0x02000000
+#define FAPI_ATTRIBUTE_TYPE_UINT64ARY 0x01000000
+
+#define FAPI_ATTRIBUTE_MODE_CONST 0x80000000
+/**
+ @brief Used by the get/set configuration functions to return the data
+*/
+template<typename T>
+class Attribute
+{
+public:
+ // Constructor
+ Attribute();
+
+ // Destructor
+ ~Attribute();
+
+ //
+ /// @brief Assignment Operator.
+ /// @param[in] i_right Reference to Value to assign from.
+ /// @return Reference to 'this' Target
+ ///
+ Attribute<T>& operator=(const T& i_right)
+ {
+ this->value = i_right->value;
+ }
+
+private:
+ T value;
+
+};
+
+inline AttributeData::AttributeData() {}
+
+inline AttributeData::~AttributeData() {}
+
+} //namespace
+#endif // #ifndef ECMD_PERLAPI
+#endif
+
+
+
+
+
diff --git a/src/ppe/hwpf/plat/include/hw_access.H b/src/ppe/hwpf/plat/include/hw_access.H
new file mode 100644
index 0000000..758f035
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/hw_access.H
@@ -0,0 +1,606 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/hw_access.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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_access.H
+ *
+ * @brief Defines the hardware access functions for PPE platforms that
+ * don't leverage FAPI2 return codes.
+ */
+
+#ifndef FAPI2_HWACCESS_H_
+#define FAPI2_HWACCESS_H_
+
+
+// variable_buffer isn't supported on PPE
+#ifndef __PPE__
+#include <variable_buffer.H>
+#endif
+
+#include <plat_hw_access.H>
+#include <fapi2_hw_access.H>
+
+namespace fapi2
+{
+
+ //--------------------------------------------------------------------------
+ // PIB Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the PIB error mask - platform dependant
+ /// @param[in] i_mask The new error mask
+ void setPIBErrorMask(uint8_t i_mask)
+ {
+ PLAT_SET_PIB_ERROR_MASK(i_mask);
+ }
+
+ /// @brief Gets the PIB error mask - platform dependant
+ /// @return uint8_t The current PIB error mask
+ uint8_t getPIBErrorMask(void)
+ {
+ uint8_t o_pib_mask;
+ PLAT_GET_PIB_ERROR_MASK(o_pib_mask);
+ return o_pib_mask;
+ }
+
+ //--------------------------------------------------------------------------
+ // Operational Mode Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the operational mode
+ /// @param[in] i_mode The new mode
+ // note: this can be moved to a C file if desired
+ inline void setOpMode(const OpModes i_mode)
+ {
+ // Keeps the compiler from complaining about the unused i_mode
+ static_cast<void>(i_mode);
+
+ // No-op for now. Should set thread-local operational mode
+ return;
+ }
+
+ /// @brief Gets the operational mode
+ /// @return the operational mode
+ // note: this can be moved to a C file if desired
+ inline OpModes getOpMode(void)
+ {
+ // No-op for now. Should read thread-local operational mode
+ return NORMAL;
+ }
+
+ //--------------------------------------------------------------------------
+ // HW Communication Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Reads a SCOM register from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline void getScom(const Target<K>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& o_data)
+ {
+ // PLAT_GETSCOM(i_target,
+// (uint32_t)(i_address & BITS(40,24)),
+// &(o_data()));
+
+// fapi2::ReturnCode l_rc;
+ PLAT_GETSCOM(current_err,
+ i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ &(o_data()));
+ }
+
+
+ /// @brief Writes a SCOM register on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline void putScom(const Target<K>& i_target, const uint64_t i_address,
+ buffer<uint64_t>& i_data)
+ {
+
+ PLAT_PUTSCOM(i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ &(i_data()));
+ }
+
+ /// @brief Read-modify-write a SCOM register on a chip
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor).
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline void modifyScom( const Target<K>& i_target,
+ const uint64_t i_address,
+ const buffer<uint64_t>& i_data,
+ const ChipOpModifyMode i_modifyMode)
+ {
+ fapi2::buffer<uint64_t> l_modifyDataBuffer;
+
+ PLAT_GETSCOM(i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ &(l_modifyDataBuffer()));
+
+ if ( i_modifyMode == CHIP_OP_MODIFY_MODE_OR)
+ {
+ l_modifyDataBuffer |= i_data;
+ }
+
+ if ( i_modifyMode == CHIP_OP_MODIFY_MODE_AND)
+ {
+ l_modifyDataBuffer &= i_data;
+ }
+
+ if ( i_modifyMode == CHIP_OP_MODIFY_MODE_XOR)
+ {
+ l_modifyDataBuffer ^= i_data;
+ }
+
+ PLAT_PUTSCOM(i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ &(l_modifyDataBuffer()));
+ return;
+ }
+
+ /// @brief Writes a SCOM register under mask on a chip
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @param[in] i_mask Buffer that holds the mask value.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline void putScomUnderMask(const Target<K>& i_target,
+ const uint64_t i_address,
+ buffer<uint64_t>& i_data,
+ buffer<uint64_t>& i_mask)
+ {
+ fapi2::buffer<uint64_t> l_modifyDataBuffer = i_data;
+
+ l_modifyDataBuffer &= i_mask;
+
+ PLAT_PUTSCOM(i_target,
+ (uint32_t)(i_address & BITS(40,24)),
+ &(l_modifyDataBuffer()));
+ return;
+ }
+
+
+ /// @brief Reads a CFAM register from a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode getCfamRegister(const Target<K>& i_target,
+ const uint32_t i_address,
+ buffer<uint32_t>& o_data)
+ {
+ PLAT_GETCFAM(i_target.get(),
+ (uint32_t)(i_address & BITS(40,24)),
+ &(o_data()));
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Writes a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to write to.
+ /// @param[in] i_data Buffer that holds data to write into address.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putCfamRegister(const Target<K>& i_target,
+ const uint32_t i_address,
+ buffer<uint32_t>& i_data)
+ {
+ PLAT_PUTCFAM(i_target.get(),
+ (uint32_t)(i_address & BITS(40,24)),
+ &(i_data()));
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Read-modify-write a CFAM register on a chip.
+ /// CFAM register is 32-bit wide.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address CFAM register address to modify.
+ /// @param[in] i_data Buffer that holds data to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor).
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode modifyCfamRegister(const Target<K>& i_target,
+ const uint32_t i_address,
+ const buffer<uint32_t>& i_data,
+ const ChipOpModifyMode i_modifyMode)
+ {
+ PLAT_MODCFAM(i_target.get(),
+ (uint32_t)(i_address & BITS(40,24)),
+ &(i_data()),
+ i_modifyMode);
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a ring from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode getRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& o_data,
+ const RingMode i_ringMode = 0)
+ {
+ o_data.setBit(0);
+ o_data.setBit(3);
+#ifndef __PPE__
+ std::cout << std::hex << " getRing "
+ << "target: {" << i_target.getType() << ","
+ << uint64_t(i_target) << "}; "
+ << "ring address: " << i_address << "; "
+ << "ring mode: " << i_ringMode << "; "
+ << "output data:";
+ o_data.print();
+#endif
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Writes a ring to a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to write to.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to write into address
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& i_data,
+ const RingMode i_ringMode = 0)
+ {
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+
+ /// @brief Writes a ring to a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to write to.
+ /// @param[in] i_data Pointer to location that contains RS4 compressed
+ // ring data to write into address
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ const void* i_data,
+ const RingMode i_ringMode = 0)
+ {
+ uint64_t* dataPtr = reinterpret_cast<uint64_t*>(const_cast<void*>(i_data));
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ /// @brief Read-modify-write a ring on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to modify.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor)
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode modifyRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& i_data,
+ const ChipOpModifyMode i_modifyMode,
+ const RingMode i_ringMode = 0)
+ {
+
+ return FAPI2_RC_SUCCESS;
+ }
+#endif
+
+
+#ifdef FAPI_SUPPORT_MULTI_SCOM
+ /// @brief Performs a multiple SCOM operation
+ /// This interface performs multiple SCOM operations on a chip in the
+ /// order specified by the input MultiScom object.
+ /// See fapiMultiScom.H for details of how to populate the MultiScom
+ /// object with SCOM operations.
+ ///
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in,out] io_multiScomObj Reference to a MultiScom object,
+ /// pre-populated with SingleScomInfo entries
+ /// to perform multiple SCOMs on input target
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note This is a synchronous interface and would return after all the
+ /// SCOM operations are completed or on the first failed operation
+ ///
+ /// @note SCOMs will be performed in the order they were added to the
+ /// input MultiScom object
+ ///
+ /// @note In case of errors, the platform code is responsible to collect
+ /// and add all the required error info and FFDC into the error data
+ /// for debugging
+ ///
+ /// @note If the SCOM operations added are specific to a processor chip,
+ /// then the FSI Shift Engine configured in scatter-gather DMA mode
+ /// extension would be used to execute the SCOM operations in a
+ /// performance optimize mode. In this mode, the special
+ /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are
+ /// supported that allow a large bulk of SCOM access (in multiple of
+ /// 64 bits) for targets that support auto-increment. The
+ /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode
+ ///
+ /// @note If the SCOM operations added are specific to a memory buffer
+ /// chip, then the regular SCOM engine is used to execute the SCOM
+ /// operations. SCOM_WRITE_UNDER_MASK operation is supported in
+ /// this mode, but the special SCOM_BULK_READ_MODE and
+ /// SCOM_BULK_WRITE_MODE operations are not supported due to
+ /// hardware limitations.
+ ///
+ template< TargetType K >
+ fapi2::ReturnCode multiScom (const Target<K>& i_target,
+ MultiScom& io_multiScomObj)
+ {
+ }
+#endif
+
+ // --------------------------------------------------------------------------
+ // NOTE:
+ // Implement platform Spy access functions if platform supports them.
+ // --------------------------------------------------------------------------
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a spy from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy whose data to be read.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependant on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// it with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiGetSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K >
+ inline ReturnCode getSpy(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data)
+ {
+ static_assert(K == 0, "implement getSpy (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K >
+ inline ReturnCode getSpy(const Target<K>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data)
+ {
+ static_assert(K == 0, "implement getSpy (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+ /// @brief Writes a spy on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy to write data to.
+ /// @param[out] i_data Buffer that holds data to write into spy.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// is with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiPutSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K >
+ inline ReturnCode putSpy(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& i_data)
+ {
+ static_assert(K == 0, "implement putSpy (enum)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K >
+ inline ReturnCode putSpy(const Target<K>& i_target,
+ const char* const i_spyId,
+ variable_buffer& i_data)
+ {
+ static_assert(K == 0, "implement putSpy (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+ /// @brief Writes spy data into a buffer holding ring data image
+ /// This API is used by L2/L3 repair to put column repair data
+ /// into a ring buffer image.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy.
+ /// @param[in] i_data Buffer that holds spy data to write into ring
+ /// image.
+ /// @param[out] o_data Buffer that holds updated ring image.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K >
+ inline ReturnCode putSpyImage(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData)
+ {
+ static_assert(K == 0, "implement putSpyImage (enum)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K >
+ inline ReturnCode putSpyImage(const Target<K>& i_target,
+ const char* const i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData)
+ {
+ static_assert(K == 0, "implement putSpyImage (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+ /// @brief Reads spy data from a ring image buffer
+ /// @param[in] i_target Target to operate on
+ /// @param[in] i_spyId The spy's id
+ /// @param[out] o_data Buffer that holds data read from ring image.
+ /// @param[in] i_imageData Buffer that holds ring image to read data
+ /// from.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+ template< TargetType K >
+ inline ReturnCode getSpyImage(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData)
+ {
+ static_assert(K == 0, "implement getSpyImage (enum)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+#ifdef FAPI_SUPPORT_SPY_AS_STRING
+ template< TargetType K >
+ inline ReturnCode getSpyImage(const Target<K>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData)
+ {
+ static_assert(K == 0, "implement getSpyImage (string)");
+ return ~FAPI2_RC_SUCCESS;
+ }
+#endif
+
+#endif // PPE
+
+};
+
+#endif // _FAPI2_HWACCESS_H_
diff --git a/src/ppe/hwpf/plat/include/plat_hw_access.H b/src/ppe/hwpf/plat/include/plat_hw_access.H
new file mode 100644
index 0000000..429ceff
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/plat_hw_access.H
@@ -0,0 +1,102 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/plat_hw_access.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_hw_access.H
+ *
+ * @brief Define platform specific calls for PPE Platforms that use the machine
+ * check function of the PPE to deal with errors (eg no explicit return codes
+ * returned)
+ */
+
+#ifndef PLATHWACCESS_H_
+#define PLATHWACCESS_H_
+
+#include <plat_includes.H>
+
+/// PIB Error Mask
+
+#define PLAT_SET_PIB_ERROR_MASK(_m_mask) \
+ { /* Read MSR */ \
+ uint32_t msr_data = mfmsr(); \
+ /* Set SEM field */ \
+ msr_data &= ~(BITS(0,8)); \
+ msr_data |= (uint32_t)(i_mask << 24); \
+ /* Write MSR */ \
+ mtmsr(msr_data); \
+ };
+
+#define PLAT_GET_PIB_ERROR_MASK(_m_mask) \
+ uint8_t _m_mask; \
+ uint32_t _sem = mfmsr(); \
+ _m_mask = (uint8_t)((_sem & MSR_SEM) >> (32-(MSR_SEM_START_BIT + MSR_SEM_LEN)));
+
+// Building block PPE instructions
+#define PPE_MFMSR(_m_data) \
+asm volatile \
+ ( \
+ "mfmsr %[data] \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data) \
+ );
+
+#define PPE_MTMSR(_m_data) \
+asm volatile \
+ ( \
+ "mtmsr %[data] \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data) \
+ );
+
+
+/// GetScom
+#define PLAT_GETSCOM(_m_rc, _m_base, _m_offset, _m_data) \
+ PPE_LVDX(_m_base.getAddressOverlay(), (uint32_t)(_m_offset & BITS(40,24)), _m_data)
+
+/// PutScom
+#define PLAT_PUTSCOM(_m_base, _m_offset, _m_data) \
+ PPE_STVDX(_m_rc, _m_base.getAddressOverlay(), (uint32_t)(_m_offset & BITS(40,24)), _m_data)
+
+/// ModifyScom
+#define PLAT_MODSCOM(_m_base, _m_offset, _m_data, _m_mode) \
+ PPE_STVDX(_m_base.getAddressOverlay(), _m_offset, _m_data)
+
+
+/// GetCFAM
+#define PLAT_GETCFAM(_m_base, _m_offset, _m_data) \
+ static_assert( K == TARGET_TYPE_NONE, \
+ "getCfamRegister is not supported by PPE platforms")
+
+/// PutCFAM
+#define PLAT_PUTCFAM(_m_base, _m_offset, _m_data) \
+ static_assert( K == TARGET_TYPE_NONE, \
+ "putCfamRegister is not supported by PPE platforms")
+
+/// ModifyCFAM
+#define PLAT_MODCFAM(_m_base, _m_offset, _m_data, _m_mode) \
+ static_assert( K == TARGET_TYPE_NONE, \
+ "modifyCfamRegister is not supported by PPE platforms")
+
+#endif // PLATHWACCESS_H_
+
diff --git a/src/ppe/hwpf/plat/include/plat_includes.H b/src/ppe/hwpf/plat/include/plat_includes.H
new file mode 100644
index 0000000..b549ca0
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/plat_includes.H
@@ -0,0 +1,40 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/plat_includes.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 plat_includes.H
+ * @brief Platform specific include to implement FAPI2 APIs
+ */
+
+#ifndef __PLAT_INCLUDES_H__
+#define __PLAT_INCLUDES_H__
+
+#include <plat_hw_access.H>
+
+#include <ppe42_scom.h>
+#include <ppe42_msr.h>
+//#include <pk.h>
+
+
+#endif // __PLAT_INCLUDES_H__
diff --git a/src/ppe/hwpf/plat/include/plat_target.H b/src/ppe/hwpf/plat/include/plat_target.H
new file mode 100644
index 0000000..a9c1866
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/plat_target.H
@@ -0,0 +1,43 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/plat_target.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 plat_target.H
+ * @brief platform definitions for fapi2 targets
+ */
+
+#ifndef __FAPI2_PLAT_TARGET__
+#define __FAPI2_PLAT_TARGET__
+
+//
+// Define what a platform handle looks like. For Hostboot,
+// for example, this might be a void*. For the SBE, this
+// will be a uint64_t ...
+//
+namespace fapi2
+{
+ typedef uint64_t plat_target_handle_t;
+}
+
+#endif
diff --git a/src/ppe/hwpf/plat/include/plat_target_definitions.H b/src/ppe/hwpf/plat/include/plat_target_definitions.H
new file mode 100644
index 0000000..4056f92
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/plat_target_definitions.H
@@ -0,0 +1,112 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/plat_target_definitions.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 plat_ppe_target.H
+ * @brief Definitions for fapi2 PPE targets
+ */
+
+#ifndef __FAPI2_PPE_TARGET__
+#define __FAPI2_PPE_TARGET__
+
+#define TARGET_CHIP(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP > _name((uint64_t)_index);
+
+#define TARGET_CHIP_PERV(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_PERV> _name((uint64_t)_index);
+
+#define TARGET_EQ(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_EQ> _name((uint64_t)_index);
+
+#define TARGET_CORE(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_CORE> _name((uint64_t)_index);
+
+#define TARGET_EX(_name, _index) \
+ fapi2::Target<fapi2::TARGET_TYPE_EX> _name((uint64_t)_index);
+
+namespace fapi2
+{
+
+ TARGET_CHIP (chip_target, 0);
+ TARGET_CHIP_PERV (perv_target, 1);
+ TARGET_CHIP_PERV (n0_target, 2);
+ TARGET_CHIP_PERV (n1_target, 3);
+ TARGET_CHIP_PERV (n2_target, 4);
+ TARGET_CHIP_PERV (n3_target, 5);
+ TARGET_CHIP_PERV (xb_target, 6);
+ TARGET_CHIP_PERV (mc0_target, 7);
+ TARGET_CHIP_PERV (mc1_target, 8);
+ TARGET_CHIP_PERV (ob0_target, 9);
+ TARGET_CHIP_PERV (ob1_target, 10);
+ TARGET_CHIP_PERV (ob2_target, 11);
+ TARGET_CHIP_PERV (ob3_target, 12);
+ TARGET_CHIP_PERV (pci0_target, 13);
+ TARGET_CHIP_PERV (pci1_target, 14);
+ TARGET_CHIP_PERV (pci2_target, 15);
+ TARGET_EQ (eq0_target, 0);
+ TARGET_EQ (eq1_target, 1);
+ TARGET_EQ (eq2_target, 2);
+ TARGET_EQ (eq3_target, 3);
+ TARGET_EQ (eq4_target, 4);
+ TARGET_EQ (eq5_target, 5);
+ TARGET_EX (ex0_target, 0);
+ TARGET_EX (ex1_target, 1);
+ TARGET_EX (ex2_target, 2);
+ TARGET_EX (ex3_target, 3);
+ TARGET_EX (ex4_target, 4);
+ TARGET_EX (ex5_target, 5);
+ TARGET_EX (ex6_target, 6);
+ TARGET_EX (ex7_target, 7);
+ TARGET_EX (ex8_target, 8);
+ TARGET_EX (ex9_target, 9);
+ TARGET_EX (ex10_target, 10);
+ TARGET_EX (ex11_target, 11);
+ TARGET_CORE (core0_target, 0);
+ TARGET_CORE (core1_target, 1);
+ TARGET_CORE (core2_target, 2);
+ TARGET_CORE (core3_target, 3);
+ TARGET_CORE (core4_target, 4);
+ TARGET_CORE (core5_target, 5);
+ TARGET_CORE (core6_target, 6);
+ TARGET_CORE (core7_target, 7);
+ TARGET_CORE (core8_target, 8);
+ TARGET_CORE (core9_target, 9);
+ TARGET_CORE (core10_target,10);
+ TARGET_CORE (core11_target,11);
+ TARGET_CORE (core12_target,12);
+ TARGET_CORE (core13_target,13);
+ TARGET_CORE (core14_target,14);
+ TARGET_CORE (core15_target,15);
+ TARGET_CORE (core16_target,16);
+ TARGET_CORE (core17_target,17);
+ TARGET_CORE (core18_target,18);
+ TARGET_CORE (core19_target,19);
+ TARGET_CORE (core20_target,20);
+ TARGET_CORE (core21_target,21);
+ TARGET_CORE (core22_target,22);
+ TARGET_CORE (core23_target,23);
+
+}; // fapi2 namespace
+
+#endif // __FAPI2_PPE_TARGET__
diff --git a/src/ppe/hwpf/plat/include/plat_target_parms.H b/src/ppe/hwpf/plat/include/plat_target_parms.H
new file mode 100644
index 0000000..2c724a3
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/plat_target_parms.H
@@ -0,0 +1,62 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/plat_target_parms.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 plat_ppe_target.H
+ * @brief Definitions for fapi2 PPE targets
+ */
+
+#ifndef __FAPI2_PPE_TARGET_PARMS__
+#define __FAPI2_PPE_TARGET_PARMS__
+
+
+#ifndef __ASSEMBLER__
+
+const uint64_t CHIPLET_COUNT = 0x38;
+
+const uint64_t CHIP_TARGET_COUNT = 1;
+const uint64_t CHIP_TARGET_OFFSET = 0;
+
+const uint64_t PERV_TARGET_OFFSET = CHIP_TARGET_OFFSET + CHIP_TARGET_COUNT;
+const uint64_t PERV_CHIPLET_OFFSET = 0x1;
+const uint64_t PERV_TARGET_COUNT = 15;
+
+const uint64_t EQ_TARGET_OFFSET = PERV_TARGET_OFFSET + PERV_TARGET_COUNT;
+const uint64_t EQ_CHIPLET_OFFSET = 0x10;
+const uint64_t EQ_TARGET_COUNT = 6;
+
+const uint64_t CORE_TARGET_OFFSET = EQ_TARGET_OFFSET + EQ_TARGET_COUNT;
+const uint64_t CORE_CHIPLET_OFFSET = 0x20;
+const uint64_t CORE_TARGET_COUNT = 24;
+
+const uint64_t EX_TARGET_OFFSET = CORE_TARGET_OFFSET + CORE_TARGET_COUNT;
+const uint64_t EX_CHIPLET_OFFSET = 0x10;
+const uint64_t EX_TARGET_COUNT = 12;
+
+
+const uint64_t TARGET_COUNT = EX_TARGET_OFFSET + EX_TARGET_COUNT;
+
+#endif
+
+#endif // __FAPI2_PPE_TARGET_PARMS__
diff --git a/src/ppe/hwpf/plat/include/plat_trace.H b/src/ppe/hwpf/plat/include/plat_trace.H
new file mode 100644
index 0000000..d656d60
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/plat_trace.H
@@ -0,0 +1,70 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/plat_trace.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_trace.H
+ * @brief Defines the FAPI2 trace macros.
+ *
+ * Note that platform code must provide the implementation.
+ *
+ * FAPI has provided a default implementation. Platform code must
+ * provide an alternate implementation if needed.
+ */
+
+#ifndef FAPI2_PLATTRACE_H_
+#define FAPI2_PLATTRACE_H_
+
+#include <stdio.h>
+#include <stdint.h>
+
+// Why not a #define, why is this in the fapi2 namespace?
+// To prevent problems with Cronus and the fapi1 definitions.
+namespace fapi2
+{
+ static const uint32_t MAX_ECMD_STRING_LEN = 64;
+};
+
+// Information traces (go into fast trace buffer that can wrap often)
+#define FAPI_TRACE(_id_, _fmt_, _args_...) \
+ printf("%s: %s:%d ", _id_, __func__, __LINE__); \
+ printf(_fmt_, ##_args_); \
+ printf("\n")
+
+#define FAPI_INF(_fmt_, _args_...) FAPI_TRACE("inf", _fmt_, ##_args_)
+
+// Important traces (go into slow trace buffer that should not wrap often)
+#define FAPI_IMP(_fmt_, _args_...) FAPI_TRACE("imp", _fmt_, ##_args_)
+
+// Error traces (go into slow trace buffer that should not wrap often)
+#define FAPI_ERR(_fmt_, _args_...) FAPI_TRACE("err", _fmt_, ##_args_)
+
+// Debug traces (go into fast trace buffer that can wrap often)
+#define FAPI_DBG(_fmt_, _args_...) FAPI_TRACE("dbg", _fmt_, ##_args_)
+
+// Scan traces
+#define FAPI_SCAN(_fmt_, _args_...) FAPI_TRACE("scan", _fmt_, ##_args_)
+
+#define FAPI_MFG(_fmt_, _args_...) FAPI_TRACE("mfg", _fmt_, ##_args_)
+
+#endif // FAPI2_PLATTRACE_H_
diff --git a/src/ppe/hwpf/plat/include/return_code.H b/src/ppe/hwpf/plat/include/return_code.H
new file mode 100644
index 0000000..67aa0ab
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/return_code.H
@@ -0,0 +1,187 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/return_code.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 return_code.H
+ * @brief definitions for fapi2 return codes
+ */
+
+#ifndef __FAPI2_RETURN_CODE__
+#define __FAPI2_RETURN_CODE__
+
+#include <stdint.h>
+
+// Remove this for platforms which don't support FFDC
+//#include <ffdc.H>
+
+///
+/// @brief Set HWP Error macro
+///
+/// This macro should be used by a HWP to create an error. The ReturnCode's
+/// internal return code is set and any error information in the Error XML file
+/// is added to the ReturnCode
+///
+#define FAPI_SET_HWP_ERROR(RC, ERROR) \
+ RC._setHwpError(fapi2::ERROR); \
+ ERROR##_CALL_FUNCS_TO_COLLECT_FFDC(RC); \
+ ERROR##_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC); \
+ ERROR##_ADD_ERROR_INFO(RC)
+
+///
+/// @brief Add info to HWP Error macro
+///
+/// This macro should be used by an FFDC HWP to add error information from an
+/// Error XML file to an existing error.
+///
+#define FAPI_ADD_INFO_TO_HWP_ERROR(RC, ERROR) \
+ ERROR##_CALL_FUNCS_TO_COLLECT_FFDC(RC); \
+ ERROR##_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC); \
+ ERROR##_ADD_ERROR_INFO(RC)
+
+namespace fapi2
+{
+ ///
+ /// @brief Enumeration of return codes
+ ///
+ enum ReturnCodes
+ {
+ ///< Success
+ FAPI2_RC_SUCCESS = 0,
+
+ // Flag bits indicating which code generated the error.
+ FAPI2_RC_FAPI2_MASK = 0x04000000, ///< FAPI2 mask
+ FAPI2_RC_PLAT_MASK = 0x02000000, ///< Platform mask
+ FAPI2_RC_HWP_MASK = 0x00000000, ///< HWP mask
+
+ //
+ // FAPI generated return codes
+ //
+
+ FAPI2_RC_INVALID_ATTR_GET = FAPI2_RC_FAPI2_MASK | 0x01,
+ ///< Initfile requested an attribute with an invalid attribute ID
+
+ FAPI2_RC_INVALID_CHIP_EC_FEATURE_GET = FAPI2_RC_FAPI2_MASK | 0x02,
+ ///< HWP requested a chip EC feature with an invalid attribute ID
+
+ FAPI2_RC_INVALID_MULTISCOM_LENGTH = FAPI2_RC_FAPI2_MASK | 0x03,
+ ///< Invalid multiscom parameters
+
+ FAPI2_RC_INVALID_PARAMETER = FAPI2_RC_FAPI2_MASK | 0x04,
+ ///< Invalid parameters to a FAPI2 function
+
+ FAPI2_RC_OVERFLOW = FAPI2_RC_FAPI2_MASK | 0x05,
+ ///< Overflow condition, typically a buffer operation
+
+ //
+ // PLAT generated return codes. Additional details may be contained in
+ // ReturnCode platData (this can only be looked at by PLAT code)
+ //
+
+ FAPI2_RC_PLAT_ERR_SEE_DATA = FAPI2_RC_PLAT_MASK | 0x01,
+ ///< Generic platform error
+
+ FAPI2_RC_PLAT_ERR_ADU_LOCKED = FAPI2_RC_PLAT_MASK | 0x02,
+ ///< Operation to AlterDisplay unit failed because it is locked
+
+ FAPI2_RC_PLAT_NOT_SUPPORTED_AT_RUNTIME = FAPI2_RC_PLAT_MASK | 0x03,
+ ///< Operation not supported by HB runtime
+ };
+
+
+ ///
+ /// @brief Class representing a FAPI2 ReturnCode
+ ///
+ /// @note Remove the inheritance relationship with FirstFailureData if
+ /// the platform doesn't support FFDC.
+ class ReturnCode
+ {
+ public:
+
+ ///
+ /// @brief Constructor.
+ /// @param[in] i_rc the rc to set
+ ///
+ ReturnCode(const uint32_t i_rc = FAPI2_RC_SUCCESS):
+ iv_rc(i_rc)
+ {};
+
+ ///
+ /// @brief integral type conversion function. Returns the error code
+ /// @return The error code
+ ///
+ inline operator uint32_t() const { return iv_rc; }
+
+ ///
+ /// @brief Returns true iff iv_rc == SUCCESS
+ /// @return true or false
+ ///
+ inline operator bool() const { return iv_rc == FAPI2_RC_SUCCESS; }
+
+ ///
+ /// @brief Assignement operator
+ ///
+ inline ReturnCode& operator=(const uint32_t& rhs)
+ {
+ iv_rc = rhs;
+ return *this;
+ }
+
+ inline ReturnCode& operator=(const ReturnCodes& rhs)
+ {
+ iv_rc = rhs;
+ return *this;
+ }
+
+ inline bool operator==(const uint32_t& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator==(const ReturnCodes& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator!=(const uint32_t& rhs) const
+ { return rhs != iv_rc; }
+
+ inline bool operator!=(const ReturnCodes& rhs) const
+ { return rhs != iv_rc; }
+
+ ReturnCode& insertPIBcode(const uint32_t& pibrc)
+ {
+ iv_rc = FAPI2_RC_PLAT_MASK | pibrc;
+ return *this;
+ }
+
+ private:
+ uint32_t iv_rc;
+ };
+
+ /// This implementation assumes no exception handling and leverages thread-local
+ /// storage. For platforms without thread support, a global variable will
+ /// suffice for the error state.
+ extern thread_local ReturnCode current_err; /// the current error state
+ extern thread_local uint32_t pib_error_mask; /// the pib mask
+ extern thread_local uint32_t operational_state; /// the operational mode
+
+};
+
+#endif
diff --git a/src/ppe/hwpf/plat/include/target.H b/src/ppe/hwpf/plat/include/target.H
new file mode 100644
index 0000000..c23b43e
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/target.H
@@ -0,0 +1,553 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/target.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 target.H
+ * @brief definitions for fapi2 targets
+ */
+
+#ifndef __FAPI2_TARGET__
+#define __FAPI2_TARGET__
+
+#include <stdint.h>
+//#include <vector>
+#include <target_types.H>
+#include <utils.H>
+#include "plat_target_parms.H"
+
+#define MC_ENABLE 0x1 << 6
+#define MC_WRITE 5
+#define MC_READ_OR 0
+#define MC_READ_AND 1
+
+#define EX_ADDRESS_MASK 0x0000FF00
+
+#ifdef __ASSEMBLER__
+
+#ifndef ULL
+#define ULL(x) x
+#endif
+
+#else
+
+#ifndef ULL
+#define ULL(x) x##ull
+
+#endif
+
+#endif // __ASSEMBLER
+
+/// Create a multi-bit mask of \a n bits starting at bit \a b
+#define BITS(b, n) ((ULL(0xffffffffffffffff) << (64 - (n))) >> (b))
+
+/// Create a single bit mask at bit \a b
+#define BIT(b) BITS((b), 1)
+
+
+namespace fapi2
+{
+ ///
+ /// @brief Class representing a FAPI2 Target
+ /// @tparam K the type (Kind) of target
+ /// @tparam V the type of the target's Value
+ /// @remark TargetLite targets are uint64_t, Targets
+ /// are uintptr_t (void*).
+ ///
+ /// Assuming there are representations of a processor,
+ /// a membuf and a system here are some examples:
+ /// @code
+ /// #define PROCESSOR_CHIP_A 0xFFFF0000
+ /// #define MEMBUF_CHIP_B 0x0000FFFF
+ /// #define SYSTEM_C 0x0000AAAA
+ /// @endcode
+ ///
+ /// * To define a target:
+ /// @code
+ /// fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A);
+ /// fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> C(SYSTEM_C);
+ /// fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> B(MEMBUF_CHIP_B);
+ /// @endcode
+ ///
+ /// * Functions which take composite target types
+ /// @code
+ /// void takesProcOrMembuf(
+ /// const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP |
+ /// fapi2::TARGET_TYPE_MEMBUF_CHIP>& V );
+ ///
+ /// void takesAny(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& V );
+ ///
+ /// @endcode
+ ///
+ /// * Traversing the target "tree"
+ /// @code
+ /// fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A);
+ ///
+ /// // Get A's parent
+ /// A.getParent<fapi2::TARGET_TYPE_SYSTEM>();
+ ///
+ /// // Get the 0x53'd core
+ /// fapi2::getTarget<fapi2::TARGET_TYPE_CORE>(0x53);
+ ///
+ /// // Get all *my* present/functional children which are cores
+ /// A.getChildren<fapi2::TARGET_TYPE_CORE>();
+ ///
+ /// // Get all of the the cores relative to my base target
+ /// fapi2::getChildren<fapi2::TARGET_TYPE_CORE>();
+ /// @endcode
+ ///
+ /// * Invalid casts
+ /// @code
+ /// // Can't cast to a specialized target
+ /// fapi2::Target<fapi2::TARGET_TYPE_NONE> D(MEMBUF_CHIP_B);
+ /// takesProcOrMembuf( D );
+ ///
+ /// // Not one of the shared types
+ /// fapi2::Target<fapi2::TARGET_TYPE_ABUS_ENDPOINT> E;
+ /// takesProcOrMembuf( E );
+ /// @endcode
+ template<TargetType K, typename V = uint64_t>
+ class Target
+ {
+ public:
+
+ ///
+ /// @brief Create a Target, with a value
+ /// @param[in] V the value (i.e., specific element this
+ /// target represents, or pointer)
+ /// @note Platforms can mangle the value and K to get a
+ /// single uint64_t in value which represents all the information
+ /// they might need. value( K | V ), for example
+ ///
+
+ /// Default constructor is basically a TARGET_TYPE_ALL
+ Target()
+ {
+ this->iv_handle.fields.chiplet_num = 0;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ Target( V Value )
+ {
+ static_assert( ((K == TARGET_TYPE_CORE) &
+ (K == TARGET_TYPE_EQ) ) != true,
+ "TARGET_TYPE_CORE and TARGET_TYPE_EQ cannot be specified at the same time");
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ this->iv_handle.fields.chiplet_num = Value;
+ this->iv_handle.fields.type = TARGET_TYPE_PROC_CHIP;
+ this->iv_handle.fields.type_target_num = Value; // TODO: check this
+// this->iv_address.fields.chiplet_num = Value;
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ this->iv_handle.fields.chiplet_num = Value;
+ this->iv_handle.fields.type = TARGET_TYPE_PERV | TARGET_TYPE_PROC_CHIP;
+ this->iv_handle.fields.type_target_num = Value; // TODO: check this
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ /*
+ if (Value > CORE_CHIPLET_COUNT)
+ {
+ PK_TRACE("Chiplet number is greater than CORE_CHIPLET_COUNT");
+ return -1;
+ }
+ */
+ this->iv_handle.fields.chiplet_num = Value + CORE_CHIPLET_OFFSET;
+ this->iv_handle.fields.type = TARGET_TYPE_CORE;
+ this->iv_handle.fields.type_target_num = Value;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ this->iv_handle.fields.chiplet_num = Value + EQ_CHIPLET_OFFSET;
+ this->iv_handle.fields.type = TARGET_TYPE_EQ;
+ this->iv_handle.fields.type_target_num = Value;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+
+ this->iv_handle.fields.chiplet_num = (Value / 2) + EX_CHIPLET_OFFSET;
+ this->iv_handle.fields.type = TARGET_TYPE_EX;
+ this->iv_handle.fields.type_target_num = Value;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_EQ_MC_WRITE)
+ {
+ this->iv_handle.fields.chiplet_num =
+ (((MC_ENABLE) |
+ ((MC_WRITE << 3) | (Value & 0x07))) &
+ BITS(57,7));
+ this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_WRITE;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_EQ_MC_READOR)
+ {
+ this->iv_handle.fields.chiplet_num =
+ (((MC_ENABLE) |
+ ((MC_READ_OR << 3) | (Value & 0x07))) &
+ BITS(57,7));
+ this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_READOR;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_EQ_MC_READAND)
+ {
+ this->iv_handle.fields.chiplet_num =
+ (((MC_ENABLE) |
+ ((MC_READ_AND << 3) | (Value & 0x07))) &
+ BITS(57,7));
+ this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_READAND;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_CORE_MC_WRITE)
+ {
+ this->iv_handle.fields.chiplet_num =
+ (((MC_ENABLE) |
+ ((MC_WRITE << 3) | (Value & 0x07))) &
+ BITS(57,7));
+ this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_WRITE;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_CORE_MC_READOR)
+ {
+ this->iv_handle.fields.chiplet_num =
+ (((MC_ENABLE) |
+ ((MC_READ_OR << 3) | (Value & 0x07))) &
+ BITS(57,7));
+ this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_READOR;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K & TARGET_TYPE_CORE_MC_READAND)
+ {
+ this->iv_handle.fields.chiplet_num =
+ (((MC_ENABLE) |
+ ((MC_READ_AND << 3) | (Value & 0x07))) &
+ BITS(57,7));
+ this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_READAND;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+ if(K == TARGET_TYPE_ALL)
+ {
+ this->iv_handle.fields.chiplet_num = Value;
+ this->iv_handle.fields.type = TARGET_TYPE_ALL;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ }
+
+// if(K == TARGET_TYPE_ADDRESS)
+// {
+// this->iv_handle.fields.chiplet_num = Value;
+// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+// }
+ }
+
+ ///
+ /// @brief Assignment Operator.
+ /// @param[in] i_right Reference to Target to assign from.
+ /// @return Reference to 'this' Target
+ ///
+ Target<K,V>& operator=(const Target<K,V>& i_right)
+ {
+ this->iv_handle.value = i_right->iv_handle.value;
+ this->iv_addresss.value = i_right->iv_address.value;
+ return *this;
+ }
+
+ ///
+ /// @brief Equality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if equal.
+ ///
+ bool operator==(const Target<K,V>& i_right) const
+ {
+ if (this->iv_handle.value == i_right->iv_handle.value)
+ return true;
+ else
+ return false;
+ }
+ ///
+ /// @brief Inquality Comparison Operator
+ /// @param[in] i_right Reference to Target to compare.
+ /// @return bool. True if equal.
+ ///
+ bool operator!=(const Target<K,V>& i_right) const
+ {
+ if (this->iv_handle.value != i_right->iv_handle.value)
+ return true;
+ else
+ return false;
+ }
+
+ ///
+ /// @brief Get the handle.
+ /// @return V The target's handle, or value
+ ///
+ V get(void) const
+ {
+ return this->iv_handle.value;
+ }
+
+ ///
+ /// @brief Get the handle as a V
+ /// @return V The target's handle, or value
+ ///
+ operator V() const
+ {
+ return this->iv_handle.value;
+ }
+
+ ///
+ /// @brief Get a target's value
+ /// @return V The target's handle, or value
+ ///
+ V& operator()(void)
+ {
+ return *this->iv_handle;
+ }
+
+ ///
+ /// @brief Get the target type
+ /// @return The type of target represented by this target
+ ///
+ TargetType getType(void) const
+ {
+ return (TargetType)this->iv_handle.fields.type;
+ }
+
+ ///
+ /// @brief Get address overlay to reduce runtime processing
+ /// @return Overlay as a type V
+ ///
+ V getAddressOverlay(void) const
+ {
+ return this->iv_handle.fields.address_overlay;
+ }
+
+
+#if 0
+ ///
+ /// @brief Get this target's immediate parent
+ /// @tparam T The type of the parent
+ /// @return Target<T> a target representing the parent
+ ///
+ template<TargetType T>
+ Target<T,V> getParent(void) const
+ {
+ static_assert((T & ~(TARGET_TYPE_PROC_CHIP | TARGET_TYPE_PERV) != 0),
+ "Only TARGET_TYPE_PROC_CHIP and TARGET_TYPE_PERV parent types supported");
+
+ static_assert( ((((T & TARGET_TYPE_PROC_CHIP) == 0) &
+ (T & TARGET_TYPE_PERV ) == 0) ),
+ "Either TARGET_TYPE_PROC_CHIP or TARGET_TYPE_PERV parent type must be specified");
+ }
+
+ ///
+ /// @brief Get this target's children
+ /// @tparam T The type of the parent
+ /// @return std::vector<Target<T> > a vector of present/functional
+ /// children
+ ///
+ template< TargetType T>
+ std::vector<Target<T,V> > getChildren(void) const
+ {
+ static_assert( ((T & ~TARGET_TYPE_PROC_CHIP) != 0 ) != true,
+ "Only TARGET_TYPE_CHIP and TARGET_TYPE_EQ child types supported");
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ std::vector<Target<T,V> chip_children(CHIPLET_COUNT);
+ for (int i = 0; i < CHIPLET_COUNT; i++)
+ {
+ if (this->iv_handle.fields.type == TARGET_TYPE_PROC_CHIP &
+ this->iv_handle.fields.present = 1 &
+ this->iv_handle.fields.functional = 1 )
+ {
+ chip_children.push_back(this->iv_handle)
+ }
+ }
+ return chip_children;
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ this->iv_handle.fields.chiplet_num = Value;
+ // this->iv_handle.fields.type_perv = 1;
+ this->iv_handle.fields.type_target_num = 0;
+ }
+
+ }
+
+ ///
+ /// @brief Get the target at the other end of a bus - dimm included
+ /// @tparam T The type of the parent
+ /// @return Target<T> a target representing the thing on the other end
+ /// @note Can be easily changed to a vector if needed
+ ///
+ template<TargetType T>
+ Target<T,K> getOtherEnd(void) const
+ {
+ static_assert( false, "getOtherEnd() is not supported on PPE platforms");
+ }
+#endif
+
+ ///
+ /// @brief Copy from a Target<O> to a Target<K>
+ /// @tparam O the target type of the other
+ ///
+ template<TargetType O>
+ Target<K,V>( const Target<O>& Other ):
+ Target<K,V>(Other.get())
+ {
+ static_assert( (K & O) != 0,
+ "unable to cast Target, no shared types");
+
+ static_assert( bitCount<K>::count >= bitCount<O>::count,
+ "unable to cast to specialized Target");
+ }
+
+ private:
+
+// union {
+// V value;
+// struct {
+// #ifdef _BIG_ENDIAN
+// V chiplet_num : 8;
+// V _reserved_b24 : 24;
+// #else
+// V _reserved_b24 : 24;
+// V chiplet_num : 8;
+// #endif
+// } fields;
+//
+// } iv_address;
+//
+ union {
+ V value;
+ struct {
+#ifdef _BIG_ENDIAN
+ V chiplet_num : 8;
+ V type_target_num : 8;
+ V type : 8;
+ V _reserved_b6 : 6;
+ V present : 1;
+ V functional : 1;
+ V address_overlay : 32;
+#else
+ V address_overlay : 32;
+ V functional : 1;
+ V present : 1;
+ V _reserved_b6 : 6;
+ V type : 8;
+ V type_target_num : 8;
+ V chiplet_num : 8;
+#endif
+ } fields;
+ } iv_handle ;
+
+// uint64_t iv_present_children;
+// uint64_t iv_functional_children;
+
+ };
+
+
+#if 0
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] The Target<T>
+ /// @param[in] The buffer
+ /// @return void
+ /// @post The contents of the buffer is replaced with the string
+ /// representation of the target
+ ///
+ template<TargetType T, typename B>
+ void toString(const Target<T>& i_target, B& i_buffer)
+ {
+ static_assert( false, "toString is not supported on PPE platforms");
+ }
+
+ ///
+ /// @brief Get an enumerated target of a specific type
+ /// @tparam T The type of the target
+ /// @param[in] uint64_t representing the ordinal number of
+ /// the desired target
+ /// @return Target<T> the target requested
+ ///
+ template<TargetType T>
+ Target<T> getTarget(uint64_t Ordinal)
+ {
+ // For testing
+ return Target<T>(Ordinal);
+ }
+#endif
+ // Why has the been removed? For starters, the API name
+ // is probably wrong as it's already been confused with
+ // Target::getChildren(). And if I'm going to change it
+ // I really want to see if we need it. I'm still not
+ // clear on whether we're alloing this traversal or not.
+#if 0
+ ///
+ /// @brief Get the base target's children
+ /// @tparam T The type of the target
+ /// @return std::vector<Target<T> > a vector of present/functional
+ /// children
+ ///
+ template<TargetType T>
+ std::vector<Target<T> > getChildren()
+ {
+ // For testing
+ return {Target<T>(), Target<T>()};
+ }
+#endif
+
+ ///
+ /// @brief Check if the target is of a type, or in a type subset.
+ /// @tparam K the TargetType to check
+ /// @tparam T TargetType or TargetType composite to check against
+ /// @return True, iff K is a proper T
+ ///
+ template< TargetType K, TargetType T >
+ constexpr bool is_same(void)
+ { return (K & T) != 0; }
+
+
+
+
+};
+//#include "plat_ppe_targets_hold.H"
+#endif
diff --git a/src/ppe/hwpf/plat/include/target_types.H b/src/ppe/hwpf/plat/include/target_types.H
new file mode 100644
index 0000000..11c48ed
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/target_types.H
@@ -0,0 +1,132 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/target_types.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 target_types.H
+ * @brief definitions for fapi2 target types
+ */
+
+#ifndef __FAPI2_TARGET_TYPES__
+#define __FAPI2_TARGET_TYPES__
+
+#ifndef __ASSEMBLER__
+
+
+/// FAPI namespace
+namespace fapi2
+{
+ ///
+ /// @enum fapi::TargetType
+ /// @brief Types, kinds, of targets
+ /// @note TYPE_NONE is used to represent empty/NULL targets in lists
+ /// or tables. TYPE_ALL is used to pass targets to methods which
+ /// can act generally on any type of target
+ ///
+ /// Target Kind
+ enum TargetType
+ {
+ TARGET_TYPE_NONE = 0x00, ///< No type
+ TARGET_TYPE_PROC_CHIP = 0x01, ///< Processor type
+ TARGET_TYPE_EX = 0x02, ///< Ex type
+ TARGET_TYPE_CORE = 0x04, ///< Core type
+ TARGET_TYPE_EQ = 0x08, ///< EQ type
+ TARGET_TYPE_PERV = 0x10, ///< Pervasive type
+ TARGET_TYPE_EQ_MC_WRITE = 0x20, ///< EQ Multicast Type
+ TARGET_TYPE_EQ_MC_READAND = 0x21, ///< EQ Multicast Read AND Type
+ TARGET_TYPE_EQ_MC_READOR = 0x22, ///< EQ Multicast Read OR Type
+ TARGET_TYPE_CORE_MC_WRITE = 0x23, ///< Core Multicast Type
+ TARGET_TYPE_CORE_MC_READAND = 0x24, ///< Core Multicast Read AND Type
+ TARGET_TYPE_CORE_MC_READOR = 0x25, ///< Core Multicast Read OR Type
+ TARGET_TYPE_CME_CORE0 = 0x40, ///< CME Core0 (CME only)
+ TARGET_TYPE_CME_CORE1 = 0x41, ///< CME Core1 (CME only)
+ TARGET_TYPE_ALL = 0xFF, ///< Any/All types
+
+
+// TARGET_TYPE_NONE = 0x00000000, ///< No type
+// TARGET_TYPE_SYSTEM = 0x00000001, ///< System type
+// TARGET_TYPE_DIMM = 0x00000002, ///< DIMM type
+// TARGET_TYPE_PROC_CHIP = 0x00000004, ///< Processor type
+// TARGET_TYPE_MEMBUF_CHIP = 0x00000008, ///< Membuf type
+// TARGET_TYPE_EX = 0x00000010, ///< Ex type
+// TARGET_TYPE_MBA = 0x00000020, ///< MBA type
+// TARGET_TYPE_MCS = 0x00000040, ///< MCS type
+// TARGET_TYPE_XBUS = 0x00000080, ///< XBUS type
+// TARGET_TYPE_ABUS = 0x00000100, ///< ABUS type
+// TARGET_TYPE_L4 = 0x00000200, ///< L4 type
+// TARGET_TYPE_CORE = 0x00000400, ///< Core type
+// TARGET_TYPE_EQ = 0x00000800, ///< EQ type
+// TARGET_TYPE_MCA = 0x00001000, ///< MCA type
+// TARGET_TYPE_MCBIST = 0x00002000, ///< MCBIST type
+// TARGET_TYPE_MIA = 0x00004000, ///< MIA type
+// TARGET_TYPE_MIS = 0x00008000, ///< MIS type
+// TARGET_TYPE_DMI = 0x00010000, ///< DMI type
+// TARGET_TYPE_OBUS = 0x00020000, ///< OBUS type
+// TARGET_TYPE_NV = 0x00040000, ///< NV bus type
+// TARGET_TYPE_SBE = 0x00080000, ///< SBE type
+// TARGET_TYPE_PPE = 0x00100000, ///< PPE type
+// TARGET_TYPE_PERV = 0x00200000, ///< Pervasive type
+// TARGET_TYPE_PEC = 0x00400000, ///< PEC type
+// TARGET_TYPE_PHB = 0x00800000, ///< PHB type
+// TARGET_TYPE_EQ_MC_WRITE = 0x01000000, ///< EQ Multicast Type
+// TARGET_TYPE_EQ_MC_READAND = 0x02000000, ///< EQ Multicast Read AND Type
+// TARGET_TYPE_EQ_MC_READOR = 0x04000000, ///< EQ Multicast Read OR Type
+// TARGET_TYPE_CORE_MC_WRITE = 0x08000000, ///< Core Multicast Type
+// TARGET_TYPE_CORE_MC_READAND = 0x10000000, ///< Core Multicast Read AND Type
+// TARGET_TYPE_CORE_MC_READOR = 0x20000000, ///< Core Multicast Read OR Type
+// TARGET_TYPE_CME_CORE0 = 0x40000000, ///< CME Core0 (CME only)
+// TARGET_TYPE_CME_CORE1 = 0x80000000, ///< CME Core1 (CME only)
+// TARGET_TYPE_ADDRESS = 0xAAAAAAAA, ///< Address Overlay Type
+// TARGET_TYPE_ALL = 0xFFFFFFFF, ///< Any/All types
+ };
+
+
+ /**
+ * @brief Typedef used when passing multiple TargetType values
+ */
+ typedef uint8_t TargetTypes_t;
+
+ /// @cond
+ constexpr TargetType operator|(TargetType x, TargetType y)
+ {
+ return static_cast<TargetType>(static_cast<int>(x) |
+ static_cast<int>(y));
+ }
+
+ template<uint64_t V>
+ class bitCount {
+ public:
+ // Don't use enums, too hard to compare
+ static const uint8_t count = bitCount<(V >> 1)>::count + (V & 1);
+ };
+
+ template<>
+ class bitCount<0> {
+ public:
+ static const uint8_t count = 0;
+ };
+ /// @endcond
+};
+
+#endif // __ASSEMBLER__
+#endif // __FAPI2_TARGET_TYPES__
diff --git a/src/ppe/hwpf/plat/include/utils.H b/src/ppe/hwpf/plat/include/utils.H
new file mode 100644
index 0000000..8fb74cb
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/utils.H
@@ -0,0 +1,56 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/utils.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 utils.H
+ *
+ * @brief Defines common utility elements for FAPI2 use.
+ */
+
+#ifndef FAPI2_UTILS_H_
+#define FAPI2_UTILS_H_
+
+#ifdef __ASSEMBLER__
+
+#ifndef ULL
+#define ULL(x) x
+#endif
+
+#else
+
+#ifndef ULL
+#define ULL(x) x##ull
+
+#endif
+
+#endif // __ASSEMBLER
+
+/// Create a multi-bit mask of \a n bits starting at bit \a b
+#define BITS(b, n) ((ULL(0xffffffffffffffff) << (64 - (n))) >> (b))
+
+/// Create a single bit mask at bit \a b
+#define BIT(b) BITS((b), 1)
+
+
+#endif // FAPI2_UTILS_H_
diff --git a/src/ppe/hwpf/plat/include/variable_buffer.H b/src/ppe/hwpf/plat/include/variable_buffer.H
new file mode 100644
index 0000000..55f0577
--- /dev/null
+++ b/src/ppe/hwpf/plat/include/variable_buffer.H
@@ -0,0 +1,670 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/include/variable_buffer.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 variable_buffer.H
+ * @brief definitions for fapi2 variable length buffers
+ */
+
+#ifndef __FAPI2_VARIABLE_BUFFER__
+#define __FAPI2_VARIABLE_BUFFER__
+
+#include <buffer_base.H>
+
+namespace fapi2
+{
+ /// @brief Get a 32 bit mask quickly
+ // This is one of the main reasons we static_assert in the ctor's
+ // to ensure the unit_type is 32 bits.
+ inline uint32_t fast_mask32(int32_t i_pos, int32_t i_len)
+ {
+ // generates an arbitrary 32-bit mask using two operations, not too shabby
+
+ static const uint32_t l_mask32[] = {
+ 0x00000000,
+ 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,
+ 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,
+ 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000,
+ 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,
+ 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000,
+ 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00,
+ 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0,
+ 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF,
+ };
+ return l_mask32[i_len] >> i_pos;
+ }
+
+ //
+ // General set a series of bits in the buffer.
+ //
+
+ ///
+ /// @cond
+ /// @brief Internal bit inserting method.
+ /// @tparam unit_type The type of a unit of the arrays
+ /// @tparam bits_type The type of the bit counting values
+ /// @param[in] i_source The incoming data
+ /// @param[in] i_source_length The length in bits of the incoming data
+ /// @param[in] i_target The outgoing data
+ /// @param[in] i_target_length The length in bits of the outgoing data
+ /// @param[in] i_source_start_bit The starting bit location in the
+ /// incoming data
+ /// @param[in] i_target_start_bit The starting bit position in this
+ /// @param[in] i_length The length, in bits, the user wants copied.
+ ///
+ template<typename unit_type, typename bits_type>
+ inline fapi2::ReturnCode _insert(const unit_type* i_source,
+ bits_type i_source_length,
+ unit_type* i_target,
+ bits_type i_target_length,
+ bits_type i_source_start_bit,
+ bits_type i_target_start_bit,
+ bits_type i_length)
+ {
+ const bits_type bits_per_unit = fapi2::parameterTraits<unit_type>::bit_length;
+
+ // tartgetStart is defaulted to the sizeof(target) - (sizeof(source) - i_source_start_bit)
+ // which makes this act like insert from right
+ if (i_target_start_bit == ~0)
+ {
+ i_target_start_bit = (i_target_length - (i_source_length - i_source_start_bit));
+ }
+
+ // len defaults to (sizeof(OT) * 8) - i_source_start_bit
+ if (i_length == ~0)
+ {
+ i_length = i_source_length - i_source_start_bit;
+ }
+
+ // Check for overflow
+ if ((i_length + i_target_start_bit > i_target_length) ||
+ (i_length + i_source_start_bit > i_source_length))
+ {
+ return fapi2::FAPI2_RC_OVERFLOW;
+ }
+
+ do
+ {
+ const bits_type src_idx = i_source_start_bit / bits_per_unit;
+ const bits_type trg_idx = i_target_start_bit / bits_per_unit;
+
+ // "slop" = unaligned bits
+ const bits_type src_slop = i_source_start_bit % bits_per_unit;
+ const bits_type trg_slop = i_target_start_bit % bits_per_unit;
+
+ // "cnt" = largest number of bits to be moved each pass
+ bits_type cnt = std::min(i_length, bits_per_unit);
+ cnt = std::min(cnt, bits_per_unit - src_slop);
+ cnt = std::min(cnt, bits_per_unit - trg_slop);
+
+ // generate the source mask only once
+ bits_type mask = fast_mask32(src_slop, cnt);
+
+ // read the source bits only once
+ bits_type src_bits = i_source[src_idx] & mask;
+
+ // "shift" = amount of shifting needed for target alignment
+ int32_t shift = trg_slop - src_slop;
+
+ // ideally (i << -1) would yield (i >> 1), but it
+ // doesn't, so we need an extra branch here
+
+ if (shift < 0)
+ {
+ src_bits <<= -shift;
+ mask <<= -shift;
+ }
+ else
+ {
+ src_bits >>= shift;
+ mask >>= shift;
+ }
+
+ // clear source '0' bits in the target
+ i_target[trg_idx] &= ~mask;
+ // set source '1' bits in the target
+ i_target[trg_idx] |= src_bits;
+
+ i_source_start_bit += cnt;
+ i_target_start_bit += cnt;
+
+ i_length -= cnt;
+ } while (0 < i_length);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+ /// @endcond
+
+ /// @brief Class representing a FAPI variable_buffer.
+ /// @remark Variable buffers are buffers which can be variable in length
+ /// (and "odd sized.") These best represent the FAPI 1.X ecmdDataBuffer,
+ /// however they are implemented using the same template techniques
+ /// as the new fapi::buffer.
+ /// @note Variable buffers are not (presently) declared as std::bitset
+ /// as bitsets' size is fixed at runtime. It is not clear if this is
+ /// acceptable for variable_buffers at this time.
+ /// @note Variable buffers are not (presently) declared as std::vector<bool>
+ /// as it would need to be implemented separate from std::vector, and
+ /// it's not clear it would give us any real advantage. Howevever, its is
+ /// more likely this will become a std::vector<bool> than a std::bitset.
+ class variable_buffer : public buffer_base<bits_container>
+ {
+
+ public:
+
+ ///
+ /// @brief Variable buffer constructor
+ /// @param[in] i_value number of *bits* (sizeof(uint_type) * 8)
+ /// needed.
+ variable_buffer(bits_type i_value = 0);
+
+ ///
+ /// @brief Variable buffer list constructor
+ /// @param[in] i_value an initializer list to initialize the container.
+ ///
+ variable_buffer(const std::initializer_list<unit_type>& i_value);
+
+ /// @name Bit/Word Manipulation Functions
+ ///@{
+
+ ///
+ /// @brief Return the length of the buffer in bits
+ /// @return Length in bits
+ ///
+ inline uint32_t getBitLength(void) const
+ { return iv_perceived_bit_length; }
+
+ ///
+ /// @brief Return the length of the buffer in OT units
+ /// @return Length in OT units rounded up
+ /// @tparam OT the type to get the length of. For example, if one
+ /// wanted the length in double words, OT would be uint64_t
+ /// (getLength<uint64_t>().) Similarly, to get the length in words,
+ /// getLength<uin32_t>().
+ ///
+ template< typename OT >
+ inline uint32_t getLength(void) const
+ {
+ static const uint32_t bits_in_ot = sizeof(OT) * 8;
+ return (getBitLength() + (bits_in_ot - 1)) / bits_in_ot;
+ }
+
+ ///
+ /// @brief Set a bit in the buffer
+ /// @param[in] i_bit the bit number to set.
+ /// @note 0 is left-most
+ /// @return FAPI2_RC_SUCCESS if OK
+ ///
+ inline fapi2::ReturnCode setBit(const bits_type& i_bit)
+ {
+ const bits_type index = i_bit / bits_per_unit;
+
+ if (index > iv_data.size())
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+
+/// @todo: check with Brian no the correct parens
+ iv_data[index] |=
+ unit_type(1) << ((bits_per_unit - 1) -
+ (i_bit - (index * bits_per_unit)));
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Clear a bit in buffer
+ /// @tparam SB Start bit in buffer to clear.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// clear
+ /// @return FAPI2_RC_SUCCESS on success
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type SB, bits_type L >
+ fapi2::ReturnCode clearBit(void);
+
+ ///
+ /// @brief Invert bit
+ /// @tparam SB Start bit in buffer to invert.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// invert, defaults to 1
+ /// @return FAPI2_RC_SUCCESS on success
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ fapi2::ReturnCode flipBit(void);
+
+ ///
+ /// @brief Get the value of a bit in the buffer
+ /// @tparam B Bit in buffer to get.
+ /// @return true/1 if bit is on, false/0 if bit is off
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type B >
+ inline bool getBit(void) const
+ {
+ const bits_type index = B / bits_per_unit;
+ const unit_type mask = unit_type(1) << (bits_per_unit - 1) - (B - (index * bits_per_unit));
+ return iv_data[index] & mask;
+ }
+
+ ///
+ /// @brief Test if multiple bits are set
+ /// @tparam SB Start bit in buffer to test.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// test, defaults to 1
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @return true if all bits in range are set - false if any
+ /// bit is clear
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ bool isBitSet(void) const;
+
+ ///
+ /// @brief Test if multiple bits are clear
+ /// @tparam SB Start bit in buffer to test.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// test, defaults to 1
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @return true if bit is clear - false if bit is set
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ bool isBitClear(void) const;
+
+ ///
+ /// @brief Count number of bits set in a range
+ /// @tparam SB Start bit in buffer to test.
+ /// @tparam L Number of consecutive bits from start bit to
+ /// test, defaults to 1
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ /// @return Number of bits set in range
+ ///
+ template< bits_type SB, bits_type L = 1 >
+ bits_type getNumBitsSet(void) const;
+
+ ///@}
+
+ /// @name Buffer Manipulation Functions
+ ///@{
+
+ // Note: Many (all?) of these are not needed and the compiler complains
+ // as the cast to T yields a better operator. There are here mainly for
+ // documenation purposes.
+
+ ///
+ /// @brief operator>>()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator>>(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator<<()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator<<(bits_type i_shiftnum);
+#endif
+
+ ///
+ /// @brief operator+()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator+(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator+=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator+=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator|=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator&=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator|()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator|(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator&()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator&(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator^=()
+ ///
+#ifdef DOXYGEN
+ variable_buffer<T>& operator^=(const T& rhs);
+#endif
+
+ ///
+ /// @brief operator!=()
+ ///
+#ifdef DOXYGEN
+ bool operator!=(const T& rhs) const;
+#endif
+
+ ///
+ /// @brief operator==()
+ /// @return true if and only if lhs == rhs
+ ///
+ inline bool operator==(const fapi2::bits_container& rhs) const
+ {
+ if (&iv_data == &rhs)
+ {
+ return true;
+ }
+
+ return iv_data == rhs;
+ }
+
+ ///
+ /// @brief Copy part of an element into the DataBuffer
+ /// @param[in] i_data OT value to copy into DataBuffer
+ /// @param[in] i_targetStart The position in this where the copy starts
+ /// @param[in] i_len How many bits to copy
+ /// @param[in] i_sourceStart The start positon in i_data, defaults to 0
+ /// @return FAPI2_RC_SUCCESS on success, FAPi2_RC_OVERFLOW otherwise
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insert(const OT& i_data,
+ bits_type i_targetStart = 0,
+ bits_type i_len = ~0,
+ bits_type i_sourceStart = 0);
+
+ ///
+ /// @brief Copy in a right aligned (decimal) element
+ /// @param[in] i_data the incoming data
+ /// - data is taken right aligned
+ /// @param[in] i_targetStart The starting bit position in this
+ /// - Defaultst to 0
+ /// @param[in] i_len The length, in bits, the user wants copied.
+ /// - Defaults to all of the bits in the source which fit
+ /// @return FAPI2_RC_SUCCESS on success, FAPI2_RC_OVERFLOW otherwise
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insertFromRight(const OT& i_data,
+ bits_type i_targetStart = 0,
+ bits_type i_len = ~0);
+
+ ///
+ /// @brief Copy data from this buffer into an OT
+ /// @tparam OT the type of the outgoing data
+ /// @param[out] o_out OT to copy into - data is placed left aligned
+ /// @param[in] i_start Start bit to copy from - defaults to 0
+ /// @param[in] i_len Length of bits to copy - defaults to filling o_out
+ /// @return FAPI2_RC_SUCCESS on success
+ ///
+ template< typename OT >
+ fapi2::ReturnCode extract(OT& o_out,
+ bits_type i_start = 0,
+ bits_type i_len = ~0) const;
+
+ ///
+ /// @brief Copy data from this buffer into an OT and right justify
+ /// @tparam OT the type of the outgoing data
+ /// @param[out] o_out OT to copy into - data is placed right aligned
+ /// @param[in] i_start Start bit to copy from - defaults to 0
+ /// @param[in] i_len Length of bits to copy - defaults to filling o_out
+ /// @return FAPI2_RC_SUCCESS on success
+ ///
+ template< typename OT >
+ fapi2::ReturnCode extractToRight(OT& o_out,
+ bits_type i_start = 0,
+ bits_type i_len = ~0) const;
+ ///@}
+
+ private:
+ // Just shorthand ...
+ static const bits_type bits_per_unit =
+ bufferTraits<bits_container>::bits_per_unit;
+
+ // The number of bits the user asked for. The actual size of the
+ // container might be larger.
+ bits_type iv_perceived_bit_length;
+
+ ///
+ /// @brief Internal bit extraction method.
+ /// @tparam OT The type of the destination
+ /// @param[in] i_start The starting bit position in this
+ /// @param[in] i_count The length, in bits, the user wants copied.
+ /// @param[out] o_dest Where to put the data
+ ///
+ template< typename OT >
+ fapi2::ReturnCode _extract(bits_type i_start,
+ bits_type i_count,
+ OT* o_dest) const;
+
+ ///
+ /// @brief Internal insertFromRight
+ /// @param[in] i_data, the incoming data
+ /// @param[in] i_data_length The length in bits of the incoming data
+ /// @param[in] i_target_start_bit The starting bit position in this
+ /// @param[in] i_length The length, in bits, the user wants copied.
+ ///
+ template<typename OT>
+ fapi2::ReturnCode _insertFromRight(const OT& i_data,
+ bits_type i_data_length,
+ bits_type i_targetStart,
+ bits_type i_len);
+
+ };
+
+ inline variable_buffer::
+ variable_buffer(bits_type i_value):
+ buffer_base(i_value),
+ iv_perceived_bit_length(i_value)
+ {
+ static_assert(std::is_same<unit_type, uint32_t>::value,
+ "code currently needs unit_type to be a unit32_t");
+ }
+
+ inline variable_buffer::
+ variable_buffer(const std::initializer_list<unit_type>& i_value):
+ buffer_base(i_value),
+ iv_perceived_bit_length(i_value.size() * sizeof(unit_type) * 8)
+ {
+ static_assert(std::is_same<unit_type, uint32_t>::value,
+ "code currently needs unit_type to be a unit32_t");
+ }
+
+
+
+ /// @cond
+ //
+ // Generic insert
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::insert(const OT& i_source,
+ bits_type i_targetStart,
+ bits_type i_len,
+ bits_type i_sourceStart)
+ {
+ return _insert((unit_type*)(&i_source), parameterTraits<OT>::bit_length,
+ &(iv_data[0]), getBitLength(),
+ i_sourceStart, i_targetStart, i_len);
+ }
+
+ //
+ // Insert another variable_bufer
+ //
+ template<>
+ inline fapi2::ReturnCode variable_buffer::insert(
+ const variable_buffer& i_data,
+ bits_type i_targetStart,
+ bits_type i_len,
+ bits_type i_sourceStart)
+ {
+ return _insert((unit_type*)&(i_data()[0]), i_data.getBitLength(),
+ &(iv_data[0]), getBitLength(),
+ i_sourceStart, i_targetStart, i_len);
+ }
+
+ //
+ // Generic insert from right
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::insertFromRight(
+ const OT& i_data,
+ bits_type i_targetStart,
+ bits_type i_len)
+ {
+ /// @todo check with Brian on additional return
+ return _insertFromRight(i_data, parameterTraits<OT>::bit_length, i_targetStart, i_len);
+ }
+
+ //
+ // variable_buffer insert from right
+ //
+ template<>
+ inline fapi2::ReturnCode variable_buffer::insertFromRight(
+ const variable_buffer& i_data,
+ bits_type i_targetStart,
+ bits_type i_len)
+ {
+ const bits_type bit_length_of_source = i_data.getBitLength();
+ /// @todo check with Brian on additional return
+ return _insertFromRight(i_data, bit_length_of_source, i_targetStart, i_len);
+ }
+
+
+
+
+ //
+ // Generic extract. Extract is an insert with the arguments reversed.
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::extract(
+ OT& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // Needed to trick the compiler into matching the template below
+ const bits_type max_length = parameterTraits<OT>::bit_length;
+
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if (i_len == ~0)
+ {
+ i_len = max_length;
+ }
+
+ return _insert((container_unit*)&iv_data[0], getBitLength(),
+ &i_data, max_length,
+ i_start, 0U, i_len);
+ }
+
+ //
+ // Extract in to another variable_bufer
+ //
+ template<>
+ inline fapi2::ReturnCode variable_buffer::extract(
+ variable_buffer& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ // @todo Needed to add (bits_type) to compile. Not clear why this is
+ // different than other similar comparisons
+ // error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
+ if ( i_len == ~(bits_type)0 )
+ {
+ i_len = i_data.getBitLength();
+ }
+ return _insert((container_unit*)&iv_data[0], getBitLength(),
+ &(i_data()[0]), i_data.getBitLength(),
+ i_start, 0U, i_len);
+ }
+
+
+
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::_insertFromRight(
+ const OT& i_data,
+ bits_type i_data_length,
+ bits_type i_targetStart,
+ bits_type i_len)
+ {
+ // If they didn't pass in a length, assume they want all the i_data
+ // which will fit.
+ if( i_len == ~0 )
+ {
+ // The longest the length can be is the length of the data
+ // This is the miniumum of the length of the data or the
+ // number of available bits
+ i_len = std::min(i_data_length, getBitLength() - i_targetStart);
+ }
+
+ // Source start is the length, counted from the right
+ return insert(i_data, i_targetStart, i_len, i_data_length - i_len);
+ }
+
+ //
+ // Invalid specializations of set
+ //
+ /// @cond
+ // Sepcialize the variable_buffer version to to "undefined" so the
+ // linker complains loudly if anyone calls it.
+#if 0
+ template<>
+ inline fapi2::ReturnCode buffer_base::set(
+ const variable_buffer& i_value,
+ bits_type i_offset);
+#endif
+ /// @endcond
+};
+
+
+#endif
diff --git a/src/ppe/hwpf/plat/src/Makefile b/src/ppe/hwpf/plat/src/Makefile
new file mode 100644
index 0000000..926aabc
--- /dev/null
+++ b/src/ppe/hwpf/plat/src/Makefile
@@ -0,0 +1,45 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwpf/plat/src/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile is designed to be invoked with the -I argument set to
+# the location of the "pk.mk" for the build
+
+include img_defs.mk
+include fapi2ppefiles.mk
+
+
+OBJS := $(addprefix $(OBJDIR)/, $(FAPI2LIB_OBJECTS))
+
+all: $(OBJS)
+
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
+
diff --git a/src/ppe/hwpf/plat/src/array.C b/src/ppe/hwpf/plat/src/array.C
new file mode 100644
index 0000000..7bb142b
--- /dev/null
+++ b/src/ppe/hwpf/plat/src/array.C
@@ -0,0 +1,145 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/src/array.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 array.C
+ * @brief fapi2 arrays
+ */
+
+#include <stdint.h>
+#include <array.H>
+
+namespace fapi2
+{
+ /// @brief Create an array
+ array::array(const uint32_t i_size, element_type* i_data):
+ iv_size(i_size),
+ iv_data(i_data)
+ {
+#ifdef GREG
+ assert(iv_size <= size_limit);
+ if (iv_data == nullptr)
+ {
+ iv_data = new element_type[iv_size]();
+ iv_size |= delete_bit;
+ }
+#endif
+ // If the caller passed in a pointer, leave it be. Don't
+ // initialize it or anything. That will allow a placement
+ // operation where generic memory can use fapi2::array
+ // methods without much overhead.
+ }
+
+ /// @brief Destroy an array
+ array::~array(void)
+ {
+ if ((iv_size & delete_bit) != 0)
+ {
+#ifdef GREG
+ delete[] iv_data;
+#endif
+ }
+ }
+
+ /// @brief operator[]
+ array::element_type& array::operator[](const uint32_t i_index)
+ {
+#ifdef GREG
+ assert(i_index < size());
+#endif
+ return iv_data[i_index];
+ }
+
+ /// @brief operator=()
+ array& array::operator=(const array& i_other)
+ {
+#ifdef GREG
+ // Check to make sure it'll fit.
+ assert(i_other.size() <= size());
+#endif
+ // Our new size will be the other's size.
+ // Save of whether we should delete our iv_data ...
+ uint64_t l_our_delete_state = iv_size | delete_bit;
+
+ // ... our new size is the size (minus the delete state) of i_other
+ iv_size = i_other.size();
+
+ // ... do the copy ...
+#ifdef GREG
+ memcpy(iv_data, i_other.iv_data, iv_size * sizeof(element_type));
+#else
+ for(size_t i = 0; i < iv_size * sizeof(element_type); ++i)
+ {
+ iv_data[i] = i_other.iv_data[i];
+ }
+#endif
+
+ // ... and record our old delete state.
+ iv_size |= l_our_delete_state;
+
+ return *this;
+ }
+
+ /// @brief move operator=()
+ array& array::operator=(array&& i_other)
+ {
+ iv_size = i_other.iv_size;
+
+ // Make sure to clear the delete bit in the other. We
+ // don't want our memory to be deleted.
+ i_other.iv_size = i_other.size();
+
+ iv_data = std::move(i_other.iv_data);
+ return *this;
+ }
+
+ /// @brief operator==()
+ bool array::operator==(const array& i_other)
+ {
+ // If they're not the same size, they're not the same
+ if (size() != i_other.size())
+ {
+ return false;
+ }
+
+ // If they're the same size and point to the same memory, they're the same.
+ if (iv_data == i_other.iv_data)
+ {
+ return true;
+ }
+
+ auto oitr = i_other.begin();
+ auto iter = begin();
+
+ for(; iter != end(); ++iter, ++oitr)
+ {
+ if (*iter != *oitr)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/src/ppe/hwpf/plat/src/error_info.C b/src/ppe/hwpf/plat/src/error_info.C
new file mode 100644
index 0000000..08cfcb3
--- /dev/null
+++ b/src/ppe/hwpf/plat/src/error_info.C
@@ -0,0 +1,412 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/src/error_info.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file error_info.C
+ * @brief Implements the error information classes
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <plat_trace.H>
+#include <error_info.H>
+#include <buffer.H>
+
+namespace fapi2
+{
+ ///
+ /// @brief Constructor
+ ///
+ /// @param[in] i_ffdcId FFDC Identifier (used to decode FFDC)
+ /// @param[in] i_pFfdc Pointer to the FFDC to copy
+ /// @param[in] i_size Size of the FFDC to copy
+ ///
+ ErrorInfoFfdc::ErrorInfoFfdc(const uint32_t i_ffdcId,
+ const void* i_pFfdc,
+ const uint32_t i_size):
+ iv_ffdcId(i_ffdcId),
+ iv_size(i_size)
+ {
+ iv_pFfdc = std::shared_ptr<uint8_t>(new uint8_t[i_size]());
+
+ // If they passed us a NULL pointer they want to fill
+ // in the data themselves later.
+ if (i_pFfdc != nullptr)
+ {
+ memcpy(iv_pFfdc.get(), i_pFfdc, i_size);
+ }
+ }
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_hw Hardware to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ /// @param[in] i_refTarget Reference to reference target
+ ///
+ ErrorInfoHwCallout::ErrorInfoHwCallout(
+ const HwCallouts::HwCallout i_hw,
+ const CalloutPriorities::CalloutPriority i_calloutPriority,
+ const Target<TARGET_TYPE_ALL> & i_refTarget):
+ iv_hw(i_hw),
+ iv_calloutPriority(i_calloutPriority),
+ iv_refTarget(i_refTarget)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_procedure Procedure to callout
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoProcedureCallout::ErrorInfoProcedureCallout(
+ const ProcedureCallouts::ProcedureCallout i_procedure,
+ const CalloutPriorities::CalloutPriority i_calloutPriority):
+ iv_procedure(i_procedure),
+ iv_calloutPriority(i_calloutPriority)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target1 Reference to target on one end of the bus
+ /// @param[in] i_target2 Reference to target on other end of the bus
+ /// @param[in] i_calloutPriority Priority of callout
+ ///
+ ErrorInfoBusCallout::ErrorInfoBusCallout(
+ const Target<TARGET_TYPE_ALL> & i_target1,
+ const Target<TARGET_TYPE_ALL> & i_target2,
+ const CalloutPriorities::CalloutPriority i_calloutPriority):
+ iv_target1(i_target1),
+ iv_target2(i_target2),
+ iv_calloutPriority(i_calloutPriority)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_target Reference to the target to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @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
+ ///
+ 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):
+ iv_target(i_target),
+ iv_callout(i_callout),
+ iv_calloutPriority(i_priority),
+ iv_deconfigure(i_deconfigure),
+ iv_gard(i_gard)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_parent Reference to the parent target
+ /// @oaram[in] i_childType Child target type to c/d/g
+ /// @param[in] i_callout True if Target should be called out
+ /// @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_childPort Child Port
+ /// For DIMM children, the MBA port number
+ /// @param[in] i_childNum Child Number
+ /// For DIMM children, the dimm socket number
+ /// For Chip children, the chip position
+ /// For Chiplet children, the chiplet unit pos
+ ///
+ ErrorInfoChildrenCDG::ErrorInfoChildrenCDG(
+ const Target<TARGET_TYPE_ALL> & i_parentChip,
+ const TargetType i_childType,
+ const bool i_callout,
+ const bool i_deconfigure,
+ const bool i_gard,
+ const CalloutPriorities::CalloutPriority i_priority,
+ const uint8_t i_childPort, const uint8_t i_childNum):
+ iv_parent(i_parentChip),
+ iv_childType(i_childType),
+ iv_callout(i_callout),
+ iv_calloutPriority(i_priority),
+ iv_deconfigure(i_deconfigure),
+ iv_gard(i_gard),
+ iv_childPort(i_childPort),
+ iv_childNumber(i_childNum)
+ {}
+
+ ///
+ /// @brief Constructor.
+ ///
+ /// @param[in] i_trace
+ ///
+ ErrorInfoCollectTrace::ErrorInfoCollectTrace(
+ CollectTraces::CollectTrace i_traceId):
+ iv_eiTraceId(i_traceId)
+ {}
+
+
+ ///
+ /// @brief Collect target, buffer or generic FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryFfdc::addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_objects) const
+ {
+ // "variable buffer ffdc not yet implemented");
+ assert(iv_ffdcSize != EI_FFDC_SIZE_VBUF);
+
+ switch(iv_ffdcSize)
+ {
+ case EI_FFDC_SIZE_BUF:
+ {
+ const buffer<uint64_t>* object =
+ static_cast<const buffer<uint64_t>*>(i_objects[iv_ffdcObjIndex]);
+
+ i_info->iv_ffdcs.push_back(std::shared_ptr<ErrorInfoFfdc>(
+ new ErrorInfoFfdc(iv_ffdcId, object,
+ sizeof(object))));
+
+ FAPI_DBG("addErrorInfo: Adding buffer id: 0x%x size: %lu buf: 0x%lx",
+ iv_ffdcId, sizeof(object), uint64_t(*object));
+ }
+ break;
+
+ case EI_FFDC_SIZE_TARGET:
+ {
+ Target<TARGET_TYPE_ALL> object =
+ *(static_cast<const Target<TARGET_TYPE_ALL>*>
+ (i_objects[iv_ffdcObjIndex]));
+
+ // Allocate an ErrorInfoFfdc but don't copy anything in to it.
+ // We can copy the target string once if we copy directly into
+ // the error info
+ ErrorInfoFfdc* e =
+ new ErrorInfoFfdc(iv_ffdcId, nullptr, MAX_ECMD_STRING_LEN);
+
+ toString(object, static_cast<char*>(e->getData()),
+ MAX_ECMD_STRING_LEN);
+ i_info->iv_ffdcs.push_back(std::shared_ptr<ErrorInfoFfdc>(e));
+
+ FAPI_DBG("addErrorInfo: Adding target ffdc id: 0x%x %s",
+ iv_ffdcId, static_cast<char*>(e->getData()));
+ }
+ break;
+
+ default:
+ i_info->iv_ffdcs.push_back(std::shared_ptr<ErrorInfoFfdc>(
+ new ErrorInfoFfdc(
+ iv_ffdcId,
+ i_objects[iv_ffdcObjIndex],
+ iv_ffdcSize)));
+ FAPI_DBG("addErrorInfo: Adding ffdc id 0x%x size: %d",
+ iv_ffdcId, iv_ffdcSize);
+ break;
+
+ };
+
+ return;
+ }
+
+ ///
+ /// @brief Collect h/w callout FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryHwCallout::addErrorInfo(std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ // If the index is 0xFF, we use an empty target. Otherwise the
+ // target is taken from the object arrary with the given index.
+ const fapi2::Target<TARGET_TYPE_ALL> target =
+ iv_refObjIndex == 0xFF ?
+ fapi2::Target<TARGET_TYPE_ALL>() :
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_refObjIndex]));
+
+ ErrorInfoHwCallout* ei = new ErrorInfoHwCallout(
+ static_cast<HwCallouts::HwCallout>(iv_hw),
+ static_cast<CalloutPriorities::CalloutPriority>(iv_calloutPriority),
+ target);
+
+ FAPI_DBG("addErrorInfo: Adding hw callout target: 0x%lx hw: %d, pri: %d",
+ ei->iv_refTarget.get(), ei->iv_hw, ei->iv_calloutPriority);
+
+ i_info->iv_hwCallouts.push_back(std::shared_ptr<ErrorInfoHwCallout>(ei));
+ }
+
+ ///
+ /// @brief Collect proc callout FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryProcCallout::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* ) const
+ {
+ ErrorInfoProcedureCallout* ei = new ErrorInfoProcedureCallout(
+ static_cast<ProcedureCallouts::ProcedureCallout>(iv_procedure),
+ static_cast<CalloutPriorities::CalloutPriority>(iv_calloutPriority));
+
+ // Add the ErrorInfo
+ FAPI_DBG("addErrorInfo: Adding proc callout, proc: %d, pri: %d",
+ ei->iv_procedure, ei->iv_calloutPriority);
+
+ i_info->iv_procedureCallouts.push_back(
+ std::shared_ptr<ErrorInfoProcedureCallout>(ei));
+ }
+
+ ///
+ /// @brief Collect bus callout FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryBusCallout::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ // We need to add a procedure callout as well as a bus callout
+ ErrorInfoEntryProcCallout(ProcedureCallouts::BUS_CALLOUT,
+ iv_calloutPriority).addErrorInfo(i_info,
+ i_object);
+
+ // Now add our bus callout, but drop the priority by one.
+ ErrorInfoBusCallout* ei = new ErrorInfoBusCallout(
+ // First target
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_endpoint1ObjIndex])),
+
+ // Second target
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_endpoint2ObjIndex])),
+
+ // Priority, one lower.
+ (iv_calloutPriority == CalloutPriorities::HIGH) ?
+ CalloutPriorities::MEDIUM : CalloutPriorities::LOW);
+
+ FAPI_DBG("addErrorInfo: Adding bus callout t1: 0x%lx t2: 0x%lx, pri: %d",
+ ei->iv_target1.get(), ei->iv_target2.get(),
+ ei->iv_calloutPriority);
+
+ i_info->iv_busCallouts.push_back(
+ std::shared_ptr<ErrorInfoBusCallout>(ei));
+ }
+
+ ///
+ /// @brief Collect h/w target cdg FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryTargetCDG::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ ErrorInfoCDG* ei = new
+ ErrorInfoCDG(
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_targetObjIndex])),
+ iv_callout,
+ iv_deconfigure,
+ iv_gard,
+ static_cast<CalloutPriorities::CalloutPriority>
+ (iv_calloutPriority)
+ );
+
+ FAPI_DBG("addErrorInfo: Adding target 0x%lx cdg (%d:%d:%d), pri: %d",
+ ei->iv_target.get(),
+ ei->iv_callout, ei->iv_deconfigure,
+ ei->iv_gard, ei->iv_calloutPriority);
+
+ // Add the ErrorInfo
+ i_info->iv_CDGs.push_back(std::shared_ptr<ErrorInfoCDG>(ei));
+ }
+
+ ///
+ /// @brief Collect h/w children cdg FFDC information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryChildrenCDG::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* i_object) const
+ {
+ ErrorInfoChildrenCDG* ei = new ErrorInfoChildrenCDG(
+ *(static_cast<const fapi2::Target<TARGET_TYPE_ALL>*>
+ (i_object[iv_parentObjIndex])),
+ static_cast<fapi2::TargetType>(iv_childType),
+ iv_callout,
+ iv_deconfigure,
+ iv_gard,
+ static_cast<CalloutPriorities::CalloutPriority>
+ (iv_calloutPriority),
+ iv_childPort,
+ iv_childNumber);
+
+ FAPI_DBG("addErrorInfo: Adding children cdg (%d:%d:%d), type:"
+ " 0x%08x, pri: %d",
+ ei->iv_callout, ei->iv_deconfigure, ei->iv_gard,
+ ei->iv_childType, ei->iv_calloutPriority);
+
+ // Add the ErrorInfo
+ i_info->iv_childrenCDGs.push_back(
+ std::shared_ptr<ErrorInfoChildrenCDG>(ei));
+ }
+
+ ///
+ /// @brief Collect trace information to this ffdc
+ /// object
+ /// @param[in] A pointer to the error info we're collecting
+ /// @param[in] A pointer to the objects
+ /// @return void
+ ///
+ void ErrorInfoEntryCollectTrace::addErrorInfo(
+ std::shared_ptr<ErrorInfo> i_info,
+ const void* const* ) const
+ {
+ ErrorInfoCollectTrace* ei = new ErrorInfoCollectTrace(
+ static_cast<CollectTraces::CollectTrace>(iv_eieTraceId));
+
+ FAPI_DBG("addErrorInfo: Adding trace: 0x%x", ei->iv_eiTraceId);
+
+ // Add the ErrorInfo
+ i_info->iv_traces.push_back(std::shared_ptr<ErrorInfoCollectTrace>(ei));
+ }
+
+};
diff --git a/src/ppe/hwpf/plat/src/fapi2ppefiles.mk b/src/ppe/hwpf/plat/src/fapi2ppefiles.mk
new file mode 100644
index 0000000..3adeec6
--- /dev/null
+++ b/src/ppe/hwpf/plat/src/fapi2ppefiles.mk
@@ -0,0 +1,51 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/hwpf/plat/src/fapi2ppefiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file fapi2ppefiles.mk
+#
+# @brief mk for including fapi2 object files
+#
+# @page ChangeLogs Change Logs
+# @section fapi2ppefiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+
+FAPI2-C-SOURCES += fapi2PlatAttributeService.C \
+ plat_utils.C
+
+FAPI2-S-SOURCES =
+
+FAPI2LIB_OBJECTS += $(FAPI2-C-SOURCES:.C=.o) $(FAPI2-S-SOURCES:.S=.o)
+
diff --git a/src/ppe/hwpf/plat/src/ffdc.C b/src/ppe/hwpf/plat/src/ffdc.C
new file mode 100644
index 0000000..d200e4f
--- /dev/null
+++ b/src/ppe/hwpf/plat/src/ffdc.C
@@ -0,0 +1,59 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/src/ffdc.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file ffdc.C
+ * @brief Implements the FirstFailureData class
+ */
+
+#include <plat_trace.H>
+#include <ffdc.H>
+#include <error_info.H>
+
+namespace fapi2
+{
+
+ ///
+ /// @brief Add error information to this ffdc object
+ /// @param[in] A pointer to a list of objects
+ /// @param[in] A pointer to the list of entries
+ /// @param[in] The count of how many entries there are
+ /// @return void
+ ///
+ template<>
+ void FirstFailureData<ReturnCode>::addErrorInfo(
+ const void* const* i_pObjects,
+ const ErrorInfoEntry* i_pEntries,
+ const uint8_t i_count)
+ {
+ FAPI_DBG("%d entries", i_count);
+ for (uint32_t i = 0; i < i_count; i++)
+ {
+ i_pEntries[i].addErrorInfo(iv_info, i_pObjects);
+ }
+ }
+
+
+
+};
diff --git a/src/ppe/hwpf/plat/src/plat_utils.C b/src/ppe/hwpf/plat/src/plat_utils.C
new file mode 100644
index 0000000..2b6773a
--- /dev/null
+++ b/src/ppe/hwpf/plat/src/plat_utils.C
@@ -0,0 +1,137 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/src/plat_utils.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_utils.C
+ * @brief Implements fapi2 common utilities
+ */
+
+#include <stdint.h>
+#include <plat_trace.H>
+#include <return_code.H>
+#include <error_info.H>
+
+namespace fapi2
+{
+ ///
+ /// @brief Log an error.
+ ///
+ void logError(
+ fapi2::ReturnCode & io_rc,
+ fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE,
+ bool i_unitTestError = false )
+ {
+ // To keep the compiler from complaing about i_sevbeing unused.
+ static_cast<void>(i_sev);
+ static_cast<void>(i_unitTestError);
+
+ FAPI_DBG("logging 0x%lx.", uint64_t(io_rc));
+
+ // Iterate over the vectors and output what is in them.
+ const ErrorInfo* ei = io_rc.getErrorInfo();
+
+ FAPI_DBG("ffdcs: %lu", ei->iv_ffdcs.size());
+ for( auto i = ei->iv_ffdcs.begin(); i != ei->iv_ffdcs.end(); ++i )
+ {
+ uint32_t sz;
+ (*i)->getData(sz);
+ FAPI_DBG("\tid: 0x%x size %d", (*i)->getFfdcId(), sz);
+ }
+
+ FAPI_DBG("hwCallouts: %lu", ei->iv_hwCallouts.size());
+ for( auto i = ei->iv_hwCallouts.begin(); i != ei->iv_hwCallouts.end();
+ ++i )
+ {
+ FAPI_DBG("\thw: %d pri %d target: 0x%lx",
+ (*i)->iv_hw, (*i)->iv_calloutPriority,
+ (*i)->iv_refTarget.get());
+ }
+
+ FAPI_DBG("procedureCallouts: %lu", ei->iv_procedureCallouts.size());
+ for( auto i = ei->iv_procedureCallouts.begin();
+ i != ei->iv_procedureCallouts.end(); ++i )
+ {
+ FAPI_DBG("\tprocedure: %d pri %d",
+ (*i)->iv_procedure, (*i)->iv_calloutPriority);
+ }
+
+ FAPI_DBG("busCallouts: %lu", ei->iv_busCallouts.size());
+ for( auto i = ei->iv_busCallouts.begin(); i != ei->iv_busCallouts.end();
+ ++i )
+ {
+ FAPI_DBG("\tbus: t1: 0x%lx t2: 0x%lx pri: %d",
+ (*i)->iv_target1.get(), (*i)->iv_target2.get(),
+ (*i)->iv_calloutPriority);
+ }
+
+
+ FAPI_DBG("cdgs: %lu", ei->iv_CDGs.size());
+ for( auto i = ei->iv_CDGs.begin(); i != ei->iv_CDGs.end(); ++i )
+ {
+ FAPI_DBG("\ttarget: 0x%lx co: %d dc: %d gard: %d pri: %d",
+ (*i)->iv_target.get(),
+ (*i)->iv_callout,
+ (*i)->iv_deconfigure,
+ (*i)->iv_gard,
+ (*i)->iv_calloutPriority);
+
+ }
+
+ FAPI_DBG("childrenCDGs: %lu", ei->iv_childrenCDGs.size());
+ for( auto i = ei->iv_childrenCDGs.begin();
+ i != ei->iv_childrenCDGs.end(); ++i )
+ {
+ FAPI_DBG("\tchildren: parent 0x%lx co: %d dc: %d gard: %d pri: %d",
+ (*i)->iv_parent.get(),
+ (*i)->iv_callout,
+ (*i)->iv_deconfigure,
+ (*i)->iv_gard,
+ (*i)->iv_calloutPriority);
+ }
+
+ FAPI_DBG("traces: %lu", ei->iv_traces.size());
+ for( auto i = ei->iv_traces.begin(); i != ei->iv_traces.end(); ++i )
+ {
+ FAPI_DBG("\ttraces: 0x%x", (*i)->iv_eiTraceId);
+ }
+
+ // Release the ffdc information now that we're done with it.
+ io_rc.forgetData();
+
+ }
+
+ ///
+ /// @brief Delay this thread.
+ ///
+ ReturnCode delay(uint64_t i_nanoSeconds, uint64_t i_simCycles)
+ {
+ // void statements to keep the compiler from complaining
+ // about unused variables.
+ static_cast<void>(i_nanoSeconds);
+ static_cast<void>(i_simCycles);
+
+ // replace with platform specific implementation
+ return FAPI2_RC_SUCCESS;
+ }
+};
diff --git a/src/ppe/hwpf/plat/src/target.C b/src/ppe/hwpf/plat/src/target.C
new file mode 100644
index 0000000..2439a3f
--- /dev/null
+++ b/src/ppe/hwpf/plat/src/target.C
@@ -0,0 +1,35 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/hwpf/plat/src/target.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* 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 <target.H>
+
+namespace fapi2
+{
+ std::vector Target::getChildren(void) const
+
+};
+
+
+
diff --git a/src/ppe/hwpf/plat/target_map b/src/ppe/hwpf/plat/target_map
new file mode 100755
index 0000000..4ea3c0d
--- /dev/null
+++ b/src/ppe/hwpf/plat/target_map
@@ -0,0 +1,49 @@
+ TARGET_TYPE_NONE = 0x00000000,
+ TARGET_TYPE_SYSTEM = 0x00000001,
+ TARGET_TYPE_DIMM = 0x00000002,
+ TARGET_TYPE_PROC_CHIP = 0x00000004,
+ TARGET_TYPE_MEMBUF_CHIP = 0x00000008,
+ TARGET_TYPE_EX = 0x00000010,
+ TARGET_TYPE_MBA = 0x00000020,
+ TARGET_TYPE_MCS = 0x00000040,
+ TARGET_TYPE_XBUS = 0x00000080,
+ TARGET_TYPE_ABUS = 0x00000100,
+ TARGET_TYPE_L4 = 0x00000200,
+ TARGET_TYPE_CORE = 0x00000400,
+ TARGET_TYPE_EQ = 0x00000800,
+ TARGET_TYPE_MCA = 0x00001000,
+ TARGET_TYPE_MCBIST = 0x00002000,
+ TARGET_TYPE_MIA = 0x00004000,
+ TARGET_TYPE_MIS = 0x00008000,
+ TARGET_TYPE_DMI = 0x00010000,
+ TARGET_TYPE_OBUS = 0x00020000,
+ TARGET_TYPE_NV = 0x00040000,
+ TARGET_TYPE_SBE = 0x00080000,
+ TARGET_TYPE_PPE = 0x00100000,
+ TARGET_TYPE_PERV = 0x00200000,
+ TARGET_TYPE_PEC = 0x00400000,
+ TARGET_TYPE_PHB = 0x00800000,
+ TARGET_TYPE_ALL = 0xFFFFFFFF
+
+
+ Perv 0x01
+N0 0x02
+N1 0x03
+N2 0x04
+N3 0x05
+XB 0x06
+MC0 0x07
+MC1 0x08
+OB0 0x09
+OB1 0x0A
+OB2 0x0B
+OB3 0x0C
+PCI0 0x0D
+PCI1 0x0E
+PCI2 0x0F
+
+
+
+
+
+
diff --git a/src/ppe/import/.empty b/src/ppe/import/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/import/.empty
diff --git a/src/ppe/include/ppe_compiler.mk b/src/ppe/include/ppe_compiler.mk
new file mode 100755
index 0000000..2595787
--- /dev/null
+++ b/src/ppe/include/ppe_compiler.mk
@@ -0,0 +1,83 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/include/ppe_compiler.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Make header to set up PPE Compiler
+#
+ifndef CC_VERSION
+export CC_VERSION = 4.8.3
+endif
+
+ifndef CC_TARGET
+export CC_TARGET = powerpc-buildroot-linux-gnu
+endif
+
+# GCC libraries
+ifndef LIB_GCC_DIR
+export LIB_GCC_DIR = $(CC_ROOT)/usr/lib/gcc/$(CC_TARGET)/$(CC_VERSION)
+endif
+LIB_DIRS += -L$(LIB_GCC_DIR)
+
+# GCC libraries
+ifndef LIB_GCC_BASE
+export LIB_GCC_BASE = $(CC_ROOT)/usr/lib/gcc/$(CC_TARGET)
+endif
+LIB_DIRS += -L$(LIB_GCC_BASE)
+
+# GCC libraries
+ifndef LIB_BASE
+export LIB_BASE = $(CC_ROOT)/usr/lib
+endif
+LIB_DIRS += -L$(LIB_BASE)
+
+# Shared Object C and C++ libraries
+ifndef LIB_TARGET
+export LIB_TARGET = $(CC_ROOT)/usr/$(CC_TARGET)/lib
+endif
+#CLIBS += $(LIB_TARGET)/libstdc++.a
+#LIB_DIRS += -L$(LIB_TARGET)
+
+# Static C and C++ libraries
+ifndef LIB_CLIB_DIR
+export LIB_CLIB_DIR = $(CC_ROOT)/usr/$(CC_TARGET)/sysroot/lib
+endif
+LIB_DIRS += -L$(LIB_CLIB_DIR)
+
+# Runtime Static C and C++ libraries
+ifndef LIB_CULIB_DIR
+export LIB_CULIB_DIR = $(CC_ROOT)/usr/$(CC_TARGET)/sysroot/usr/lib
+endif
+LIB_DIRS += -L$(LIB_CULIB_DIR)
+
+GCCLIBS += $(LIB_CULIB_DIR)/libstdc++.a
+GCCLIBS += $(LIB_CULIB_DIR)/libm.a
+GCCLIBS += $(LIB_CULIB_DIR)/libc.a
+
+ifdef ENABLE_UCLIB
+GCCLIBS += $(LIB_CULIB_DIR)/uclibc_nonshared.a
+GCCLIBS += $(LIB_CULIB_DIR)/crt1.o
+GCCLIBS += $(LIB_CULIB_DIR)/crti.o
+endif
+
+GCCLIBS += $(LIB_GCC_DIR)/libgcc.a
+GCCLIBS += $(LIB_GCC_DIR)/libgcc_eh.a
diff --git a/src/ppe/include/proc_hcd_common.H b/src/ppe/include/proc_hcd_common.H
new file mode 100644
index 0000000..7fe5042
--- /dev/null
+++ b/src/ppe/include/proc_hcd_common.H
@@ -0,0 +1,44 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/include/proc_hcd_common.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PROC_HCD_COMMON_H
+#define __PROC_HCD_COMMON_H
+
+/// \file proc_hcd_common.H
+/// \brief Standard bit-manipulation macros (C and Assembler) for PORE code
+
+/// \defgroup be64_bits Bit manipulation for 64-bit Big-Endian values
+///
+/// \note These macros only work in the assembler context because we build our
+/// assemblers to do 64-bit arithmetic, which is required for PORE assembly.
+///
+/// @{
+
+/// Create a multi-bit mask of \a n bits starting at bit \a b
+#define BITS(b, n) ((ULL(0xffffffffffffffff) << (64 - (n))) >> (b))
+
+/// Create a single bit mask at bit \a b
+#define BIT(b) BITS((b), 1)
+
+#endif // __PROC_HCD_COMMON_H
diff --git a/src/ppe/lib/.empty b/src/ppe/lib/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/lib/.empty
diff --git a/src/ppe/ops/.empty b/src/ppe/ops/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/ops/.empty
diff --git a/src/ppe/pk/.empty b/src/ppe/pk/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/pk/.empty
diff --git a/src/ppe/pk/README b/src/ppe/pk/README
new file mode 100644
index 0000000..2227ec3
--- /dev/null
+++ b/src/ppe/pk/README
@@ -0,0 +1,8 @@
+Subdirectories are organized as follows:
+
+kernel: Architecture-independent kernel code
+ppe42: Kernel code that is common for all ppe42 instances
+std: External interrupt support for standard ppe42 instances (SBE, CME, etc.)
+gpe: External interrupt support for ppe42 instances residing in the OCC complex
+ppe: Support for ppe42 instances that do not require or have external interrupts
+trace: Kernel trace support
diff --git a/src/ppe/pk/gpe/Makefile b/src/ppe/pk/gpe/Makefile
new file mode 100644
index 0000000..bee7ad8
--- /dev/null
+++ b/src/ppe/pk/gpe/Makefile
@@ -0,0 +1,74 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/gpe/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile compiles all of the PK code required for the GPE port
+# of PK. See the "pk.mk" file in this directory.
+
+#all generated files from this makefile will end up in obj/$(IMAGE_NAME)/pk
+export SUB_OBJDIR = /pk
+
+include img_defs.mk
+include pkgpefiles.mk
+
+ifeq "$(PK_TIMER_SUPPORT)" "1"
+GPE_OBJECTS += ${GPE-TIMER-C-SOURCES:.c=.o} ${GPE-TIMER-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" "1"
+GPE_OBJECTS += ${GPE-THREAD-C-SOURCES:.c=.o} ${GPE-THREAD-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(GPE_ASYNC_SUPPORT)" "1"
+GPE_OBJECTS += ${GPE-ASYNC-C-SOURCES:.c=.o} ${GPE-ASYNC-S-SOURCES:.S=.o}
+endif
+
+OBJS := $(addprefix $(OBJDIR)/, $(GPE_OBJECTS))
+
+libpk.a: kernel ppe42 trace gpe
+ $(AR) crs $(OBJDIR)/libpk.a $(OBJDIR)/*.o
+
+.PHONY: clean gpe kernel ppe42 trace
+gpe: $(OBJS)
+
+trace:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../trace
+
+kernel:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../kernel
+
+ppe42:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../ppe42
+
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/pk/gpe/gpe.h b/src/ppe/pk/gpe/gpe.h
new file mode 100644
index 0000000..ef5ad01
--- /dev/null
+++ b/src/ppe/pk/gpe/gpe.h
@@ -0,0 +1,59 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/gpe.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __GPE_H__
+#define __GPE_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp.h
+/// \brief The GPE environment for PK.
+
+// This is a 'circular' reference in PK, but included here to simplify PGAS
+// programming.
+
+#ifndef HWMACRO_GPE
+#define HWMACRO_GPE
+#include "ppe42.h"
+#endif
+
+#include "ocb_register_addresses.h"
+#include "gpe_common.h"
+
+/*
+#include "pcbs_register_addresses.h"
+#include "pcbs_firmware_registers.h"
+
+#include "tod_register_addresses.h"
+#include "tod_firmware_registers.h"
+
+#include "plb_arbiter_register_addresses.h"
+#include "plb_arbiter_firmware_registers.h"
+
+*/
+
+#endif /* __GPE_H__ */
diff --git a/src/ppe/pk/gpe/gpe_common.h b/src/ppe/pk/gpe/gpe_common.h
new file mode 100644
index 0000000..debae8e
--- /dev/null
+++ b/src/ppe/pk/gpe/gpe_common.h
@@ -0,0 +1,89 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/gpe_common.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __GPE_COMMON_H__
+#define __GPE_COMMON_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file gpe_common.h
+/// \brief Common header for GPE
+///
+/// This header is maintained as part of the PK port for GPE, but needs to be
+/// physically present in the PMX area to allow dropping PMX code as a whole
+/// to other teams.
+
+// -*- WARNING: This file is maintained as part of PK. Do not edit in -*-
+// -*- the PMX area as your edits will be lost. -*-
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif
+
+#include "occhw_common.h"
+
+/// Each GPE instance has it's own interrupt status register these macros
+/// are added for convenience in accessing the correct register
+#define GPE_GISR0(instance_id) (OCB_G0ISR0 + (instance_id * 8))
+#define GPE_GISR1(instance_id) (OCB_G0ISR1 + (instance_id * 8))
+
+#ifdef __ASSEMBLER__
+/// This macro contains GPE specific code for determining what IRQ caused the
+/// external exception handler to be invoked by the PPE
+
+/// Check for interrupts pending in status register 0 while the IRQ is
+/// computed. The IRQ is expected to be stored in r4. If no IRQ is
+/// pending then load the phantom irq # (EXTERNAL_IRQS).
+///
+/// r1, r2, r3, and r13 must not be modified. All other registers may be used.
+///
+ .macro hwmacro_get_ext_irq
+
+ _lwzi %r5, %r5, GPE_GISR0(APPCFG_OCC_INSTANCE_ID)
+ cntlzw %r4, %r5
+ cmpwible %r4, 31, call_external_irq_handler #branch if irq is lt or eq to 31
+
+ ## No IRQ pending in interrupt set 0. Try set 1.
+ ## Note: irq # will be 64 (EXTERNAL_IRQS) if no bits were set in either register
+
+ _lwzi %r6, %r6, GPE_GISR1(APPCFG_OCC_INSTANCE_ID)
+ cntlzw %r4, %r6
+ addi %r4, %r4, 32
+
+ .endm
+
+
+/// Redirect the .hwmacro_irq_cfg_bitmaps macro to call our macro that is common for both
+/// GPE's and the 405 inside the OCC complex. This is called from the ppe42_exceptions.S
+/// file.
+ .macro .hwmacro_irq_cfg_bitmaps
+ .occhw_irq_cfg_bitmaps
+ .endm
+#endif /* __ASSEMBLER__ */
+
+#endif /* __GPE_COMMON_H__ */
diff --git a/src/ppe/pk/gpe/gpe_init.c b/src/ppe/pk/gpe/gpe_init.c
new file mode 100644
index 0000000..9692aad
--- /dev/null
+++ b/src/ppe/pk/gpe/gpe_init.c
@@ -0,0 +1,146 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/gpe_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file gpe_init.c
+/// \brief PK initialization for GPE
+///
+/// The entry points in this routine are used during initialization. This
+/// code space can be deallocated and reassigned after application
+/// initialization if required.
+
+#include "pk.h"
+#include "ocb_register_addresses.h"
+
+/// GPE environment initial setup.
+///
+/// This is setup common to all GPE HW Macro applications. This setup takes place
+/// during boot, before main() is called.
+
+void
+__hwmacro_setup(void)
+{
+ uint64_t oirrA;
+ uint64_t oirrB;
+ uint64_t oirrC;
+ uint64_t owned_actual;
+ uint64_t reverse_polarity;
+
+ //verify that this code is running on the correct GPE instance (one time check)
+ if((mfspr(SPRN_PIR) & PIR_PPE_INSTANCE_MASK) != APPCFG_OCC_INSTANCE_ID)
+ {
+ //APPCFG_OCC_INSTANCE_ID does not match actual instance ID!
+ PK_PANIC(OCCHW_INSTANCE_MISMATCH);
+ }
+
+#if (APPCFG_OCC_INSTANCE_ID == OCCHW_IRQ_ROUTE_OWNER)
+ //If this instance is the owner of the interrupt routting registers
+ //then write the routing registers for all OCC interrupts.
+ //This instance must be the first instance to run within the OCC
+ //This will be done while all external interrupts are masked.
+ PKTRACE("Initializing External Interrupt Routing Registers");
+ out32(OCB_OIMR0_OR, 0xffffffff);
+ out32(OCB_OIMR1_OR, 0xffffffff);
+ out32(OCB_OIRR0A, (uint32_t)(g_ext_irqs_routeA >> 32));
+ out32(OCB_OIRR1A, (uint32_t)g_ext_irqs_routeA);
+ out32(OCB_OIRR0B, (uint32_t)(g_ext_irqs_routeB >> 32));
+ out32(OCB_OIRR1B, (uint32_t)g_ext_irqs_routeB);
+ out32(OCB_OIRR0C, (uint32_t)(g_ext_irqs_routeC >> 32));
+ out32(OCB_OIRR1C, (uint32_t)g_ext_irqs_routeC);
+#endif
+
+ //Determine from the routing registers which irqs are owned by this instance
+ //NOTE: If a bit is not set in the routeA register, it is not owned by a GPE
+
+ oirrA = ((uint64_t)in32(OCB_OIRR0A)) << 32;
+ oirrA |= in32(OCB_OIRR1A);
+ oirrB = ((uint64_t)in32(OCB_OIRR0B)) << 32;
+ oirrB |= in32(OCB_OIRR1B);
+ oirrC = ((uint64_t)in32(OCB_OIRR0C)) << 32;
+ oirrC |= in32(OCB_OIRR1C);
+
+ //All interrupts routed to a GPE will have a bit set in routeA
+ owned_actual = oirrA;
+
+ //wittle it down by bits in the routeB register
+#if APPCFG_OCC_INSTANCE_ID & 0x2
+ owned_actual &= oirrB;
+#else
+ owned_actual &= ~oirrB;
+#endif
+
+ //wittle it down further by bits in the routeC register
+#if APPCFG_OCC_INSTANCE_ID & 0x1
+ owned_actual &= oirrC;
+#else
+ owned_actual &= ~oirrC;
+#endif
+
+ //Panic if we don't own the irqs we were expecting
+ //NOTE: we don't panic if we are given more IRQ's than expected
+ if((owned_actual & g_ext_irqs_owned) != g_ext_irqs_owned)
+ {
+ //IRQ's were not routed to us correctly.
+ PK_PANIC(OCC_IRQ_ROUTING_ERROR);
+ }
+
+ //Mask all external interrupts owned by this instance
+ //(even the ones given to us that we weren't expecting)
+ out32(OCB_OIMR0_OR, (uint32_t)(owned_actual >> 32));
+ out32(OCB_OIMR1_OR, (uint32_t)owned_actual);
+
+ //Set the interrupt type for all interrupts owned by this instance
+ out32(OCB_OITR0_CLR, (uint32_t)(g_ext_irqs_owned >> 32));
+ out32(OCB_OITR1_CLR, (uint32_t)g_ext_irqs_owned);
+ out32(OCB_OITR0_OR, (uint32_t)(g_ext_irqs_type >> 32));
+ out32(OCB_OITR1_OR, (uint32_t)g_ext_irqs_type);
+
+ //Set the interrupt polarity for all interrupts owned by this instance
+ out32(OCB_OIEPR0_CLR, (uint32_t)(g_ext_irqs_owned >> 32));
+ out32(OCB_OIEPR1_CLR, (uint32_t)g_ext_irqs_owned);
+ out32(OCB_OIEPR0_OR, (uint32_t)(g_ext_irqs_polarity >> 32));
+ out32(OCB_OIEPR1_OR, (uint32_t)g_ext_irqs_polarity);
+
+ //clear the status of all external interrupts owned by this instance
+ out32(OCB_OISR0_CLR, ((uint32_t)(g_ext_irqs_owned >> 32)));
+ out32(OCB_OISR1_CLR, ((uint32_t)g_ext_irqs_owned));
+
+ //set the status for interrupts that have reverse polarity
+ reverse_polarity = ~g_ext_irqs_polarity & g_ext_irqs_owned;
+ out32(OCB_OISR0_OR, ((uint32_t)(reverse_polarity >> 32)));
+ out32(OCB_OISR1_OR, ((uint32_t)reverse_polarity));
+
+ //Unmask the interrupts owned by this instance that are to be enabled by default
+ out32(OCB_OIMR0_CLR, (uint32_t)(g_ext_irqs_enable >> 32));
+ out32(OCB_OIMR1_CLR, (uint32_t)g_ext_irqs_enable);
+
+ //Wait for the last out32 operation to complete
+ sync();
+
+}
diff --git a/src/ppe/pk/gpe/gpe_irq.h b/src/ppe/pk/gpe/gpe_irq.h
new file mode 100644
index 0000000..6a71765
--- /dev/null
+++ b/src/ppe/pk/gpe/gpe_irq.h
@@ -0,0 +1,271 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/gpe_irq.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __GPE_IRQ_H__
+#define __GPE_IRQ_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file occhw_irq.h
+/// \brief GPE-OCCHW Interrupt handling for PK
+///
+/// The OCCHW interrupt controller supports a maximum of 64 interrupts, split
+/// into 2 x 32-bit non-cascaded interrupt controllers with simple OR
+/// combining of the interrupt signals.
+///
+/// The OCB interrupt controller allows interrupt status to be set directly by
+/// software, as well as providing a mode that causes an enabled pending
+/// interrupt to trigger an Unconditional Debug Event. The OCB interrupt
+/// controller contains a 'mask' register, unlike other 405 interrupt
+/// controllers that have an 'enable' register. The OCCHW mask and status
+/// registers also have atomic CLR/OR function so that it is never necessary
+/// to enter a critical section to enable/disable/clear interrupts and
+/// interrupt status.
+
+#include "occhw_common.h"
+#include "ocb_register_addresses.h"
+#include "ppe42.h"
+
+#ifndef __ASSEMBLER__
+
+/// Enable an interrupt by clearing the mask bit.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_enable(PkIrqId irq)
+{
+ out32(OCCHW_OIMR_CLR(irq), OCCHW_IRQ_MASK32(irq));
+}
+
+
+/// Disable an interrupt by setting the mask bit.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_disable(PkIrqId irq)
+{
+ out32(OCCHW_OIMR_OR(irq), OCCHW_IRQ_MASK32(irq));
+}
+
+
+/// Clear interrupt status with an CLR mask. Only meaningful for
+/// edge-triggered interrupts.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_status_clear(PkIrqId irq)
+{
+ out32(OCCHW_OISR_CLR(irq), OCCHW_IRQ_MASK32(irq));
+}
+
+
+/// Get IRQ status as a 0 or non-0 integer
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline int
+pk_irq_status_get(PkIrqId irq)
+{
+ return (in32(OCCHW_OISR(irq)) & OCCHW_IRQ_MASK32(irq)) != 0;
+}
+
+
+/// Set or clear interrupt status explicitly.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_status_set(PkIrqId irq, int value)
+{
+ if (value) {
+ out32(OCCHW_OISR_OR(irq), OCCHW_IRQ_MASK32(irq));
+ } else {
+ out32(OCCHW_OISR_CLR(irq), OCCHW_IRQ_MASK32(irq));
+ }
+}
+
+
+#endif /* __ASSEMBLER__ */
+
+/// \page occhw_irq_macros OCCHW IRQ API Assembler Macros
+///
+/// These macros encapsulate the PK API for the OCCHW interrupt
+/// controller. These macros require 2 scratch registers in addition to the \c
+/// irq parameter register passed into the handler from PK interrupt
+/// dispatch. These macros also modify CR0.
+///
+/// \arg \c rirq A register that holds the \c irq parameter passed to
+/// the handler from PK interrupt dispatch. This register is not
+/// modified.
+/// \arg \c rmask A scratch register - At the end of macro execution this
+/// register contains the 32-bit mask form of the irq.
+///
+/// \arg \c raddr A scratch register - At the end of macro execution this
+/// register holds the address of the interrupt
+/// controller facility that implements the action.
+///
+/// \arg \c imm An immediate (0/non-0) value for certain macros.
+///
+/// Forms:
+///
+/// \b _pk_irq_enable \a rirq, \a rmask, \a raddr - Enable an \c irq. \n
+/// \b _pk_irq_disable \a rirq, \a rmask, \a raddr - Disable an \c irq. \n
+/// \b _pk_irq_status_clear \a rirq, \a rmask, \a raddr - Clear \c irq
+/// interrupt status. \n
+/// \b _pk_irq_status_set \a rirq, \a rmask, \a raddr, \a imm - Set \c irq status
+/// with an immediate (0/non-0) value. \n
+///
+/// \todo Once the logic design is locked down, revisit whether these macros
+/// (and C-code versions) can be implemented without branching. This could be
+/// done in theory by converting bit 26 into the byte offset between addresses
+/// in interupt controller 0 and interrupt controller 1 - assuming the
+/// distances are all the same power-of-two.
+///
+/// \cond
+
+// IRQ numbers are in the range 0..63. IRQs are converted to the 32-bit
+// residue used to compute the mask. CR0 is set as a test of IRQ > 32 - the
+// register \c raddr is used as scratch for these computations. Hopefully the
+// local labels 888 and 999 are unique enough.
+
+// Register names must be compared as strings - e.g., %r0 is not
+// a symbol, it is converted to "0" by the assembler.
+
+#ifdef __ASSEMBLER__
+
+ .macro .two_unique, ra, rb
+ .ifnc \ra, \rb
+ .exitm
+ .endif
+ .error "Both register arguments must be unique"
+ .endm
+
+
+ .macro .three_unique, ra, rb, rc
+ .ifnc \ra, \rb
+ .ifnc \rb, \rc
+ .ifnc \ra, \rc
+ .exitm
+ .endif
+ .endif
+ .endif
+ .error "All three register arguments must be unique"
+ .endm
+
+
+ .macro _occhw_irq_or_mask, rirq:req, rmask:req
+ .two_unique \rirq, \rmask
+ lis \rmask, 0x8000
+ srw \rmask, \rmask, \rirq
+ .endm
+
+ .macro _occhw_irq_clr_mask, rirq:req, rmask:req
+ .two_unique \rirq, \rmask
+ _occhw_irq_or_mask \rirq, \rmask
+ .endm
+
+
+ .macro _pk_irq_enable, rirq:req, rmask:req, raddr:req
+ .three_unique \rirq, \rmask, \raddr
+
+ andi. \raddr, \rirq, 0x20
+ clrlwi \raddr, \rirq, 27
+ _occhw_irq_clr_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OIMR0_CLR
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OIMR1_CLR
+999:
+ eieio
+ .endm
+
+
+ .macro _pk_irq_disable, rirq:req, rmask:req, raddr:req
+ .three_unique \rirq, \rmask, \raddr
+
+ andi. \raddr, \rirq, 0x20
+ clrlwi \raddr, \rirq, 27
+ _occhw_irq_or_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OIMR0_OR
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OIMR1_OR
+999:
+ eieio
+ .endm
+
+
+ .macro _pk_irq_status_clear, rirq:req, rmask:req, raddr:req
+ .three_unique \rirq, \rmask, \raddr
+
+ andi. \raddr, \rirq, 0x20
+ clrlwi \raddr, \rirq, 27
+ _occhw_irq_clr_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OISR0_CLR
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OISR1_CLR
+999:
+ eieio
+ .endm
+
+
+ .macro _pk_irq_status_set, rirq:req, rmask:req, raddr:req, imm:req
+ .three_unique \rirq, \rmask, \raddr
+
+ andi. \raddr, \rirq, 0x20
+ clrlwi \raddr, \rirq, 27
+
+ .if \imm
+ _occhw_irq_or_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OISR0_OR
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OISR1_OR
+
+ .else
+
+ _occhw_irq_clr_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OISR0_CLR
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OISR1_CLR
+ .endif
+
+999:
+ eieio
+ .endm
+
+#endif /* __ASSEMBLER__ */
+
+/// \endcond
+
+#endif /* __GPE_IRQ_H__ */
diff --git a/src/ppe/pk/gpe/gpe_irq_init.c b/src/ppe/pk/gpe/gpe_irq_init.c
new file mode 100644
index 0000000..995ebac
--- /dev/null
+++ b/src/ppe/pk/gpe/gpe_irq_init.c
@@ -0,0 +1,130 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/gpe_irq_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file gpe_irq_init.c
+/// \brief OCCHW IRQ initialization code for PK
+///
+/// The entry points in this file are initialization rotines that could be
+/// eliminated/deallocated by the application to free up storage if they are
+/// no longer needed after initialization.
+
+#include "pk.h"
+
+/// Define the polarity and trigger condition for an interrupt.
+///
+/// It is up to the application to take care of any side effects that may
+/// occur from programming or reprogramming the interrupt controller. For
+/// example, changing edge/level sensitivity or active level may set or clear
+/// interrupt status in the controller.
+///
+/// Note that PK allows this API to be called from any context, and changes
+/// to the interrupt controller are made from a critical section.
+///
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_IRQ_SETUP One or more arguments are invalid,
+/// including an invalid \a irq, or invalid \a polarity or \a trigger parameters.
+
+int
+pk_irq_setup(PkIrqId irq,
+ int polarity,
+ int trigger)
+{
+ PkMachineContext ctx;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(!OCCHW_IRQ_VALID(irq) ||
+ !OCCHW_IRQ_OWNED(irq) ||
+ !((polarity == PK_IRQ_POLARITY_ACTIVE_HIGH) ||
+ (polarity == PK_IRQ_POLARITY_ACTIVE_LOW)) ||
+ !((trigger == PK_IRQ_TRIGGER_LEVEL_SENSITIVE) ||
+ (trigger == PK_IRQ_TRIGGER_EDGE_SENSITIVE)),
+ PK_INVALID_ARGUMENT_IRQ_SETUP);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ if (polarity == PK_IRQ_POLARITY_ACTIVE_HIGH) {
+ out32(OCCHW_OIEPR_OR(irq), OCCHW_IRQ_MASK32(irq));
+ } else {
+ out32(OCCHW_OIEPR_CLR(irq), OCCHW_IRQ_MASK32(irq));
+ }
+
+ if (trigger == PK_IRQ_TRIGGER_EDGE_SENSITIVE) {
+ out32(OCCHW_OITR_OR(irq), OCCHW_IRQ_MASK32(irq));
+ } else {
+ out32(OCCHW_OITR_CLR(irq), OCCHW_IRQ_MASK32(irq));
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// (Re)define the IRQ handler and priority for an interrupt.
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// Note that PK allows this API to be called from any context, and changes
+/// to the interrupt controller are made from a critical section.
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_IRQ_HANDLER One or more arguments are
+/// invalid, including an invalid \a irq, a null (0) \a handler,
+/// or invalid \a priority.
+
+int
+pk_irq_handler_set(PkIrqId irq,
+ PkIrqHandler handler,
+ void *arg)
+{
+ PkMachineContext ctx;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(!OCCHW_IRQ_VALID(irq) ||
+ (handler == 0),
+ PK_INVALID_ARGUMENT_IRQ_HANDLER);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ __ppe42_irq_handlers[irq].handler = handler;
+ __ppe42_irq_handlers[irq].arg = arg;
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+
diff --git a/src/ppe/pk/gpe/gpe_scom_handler.S b/src/ppe/pk/gpe/gpe_scom_handler.S
new file mode 100644
index 0000000..7edc17e
--- /dev/null
+++ b/src/ppe/pk/gpe/gpe_scom_handler.S
@@ -0,0 +1,122 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/gpe_scom_handler.S $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file gpe_scom_handler.S
+/// \brief Interrupt handler code for SCOM requests from the ppc405
+///
+
+ .nolist
+#include "pk.h"
+#include "occhw_shared_data.h"
+ .list
+
+ ## This function handles requests from the ppc405 to perform a getscom
+ ## or putscom operation.
+ ##
+ ## The ppc405 must supply a request in the following format:
+ ##
+ ## bytes : Content
+ ## -------------------
+ ## 0-3 : Status
+ ## 4-7 : cmd/address (bit 0 is r/!w bit)
+ ## 8-15 : data (supplied by ppc405 on writes)
+ ##
+ ## Register Usage:
+ ##
+ ## r3: SRAM base address
+ ## r4: SCOM address
+ ## r5: MSR manipulation
+ ## d5: SCOM data
+ ##
+ ## NOTE: getscom requires 2 IC lines and 1 DC line
+ ## putscom requires 3 IC lines and 1 DC line
+ ## Both require the same number of instructions (16)
+ .align 5
+ .global gpe_scom_handler
+gpe_scom_handler:
+
+ ## Load the hardcoded base address of the scom request
+ _liwa %r3, OSD_GPE_SCOM_ADDR
+
+ ## Load the scom address from SRAM
+ lwz %r4, OCCHW_SCOM_ADDR_OFFSET(%r3)
+
+ ## Mask all SIB errors
+ mfmsr %r7
+ _oriwa %r5, %r7, MSR_SEM
+ mtmsr %r5
+
+ ## Check bit 0 of the scom address to determine if this
+ ## is a getscom or a putscom request
+ bb0wi %r4, 0, _do_putscom #branch if bit 0 is 0
+
+_do_getscom:
+ ## the cmd bit was set, which means we're doing a getscom.
+ ## need to clear the bit first.
+ clrbwi %r4, %r4, 0
+
+ ## do the getscom
+ lvd %d5, 0(%r4)
+
+ ## store the data into the request in SRAM
+ stvd %d5, OCCHW_SCOM_DATA_OFFSET(%r3)
+
+_get_scom_status:
+
+ ## status is in the MSR, copy it to the scom request in SRAM
+ mfmsr %r5
+ stw %r5, OCCHW_SCOM_STATUS_OFFSET(%r3)
+
+ ## clear the IPI_SCOM interrupt:
+ ## first, load the bit we want to clear into a register
+ _liwa %r3, OCCHW_IRQ_MASK32(OCCHW_IRQ_IPI_SCOM)
+
+ ## then, store it to the OISR0_CLR address
+ _stwi %r3, %r4, OCB_OISR0_CLR
+
+ ## restore the MSR as it was before we changed it
+ mtmsr %r7
+
+ ## return
+ blr
+
+_do_putscom:
+
+ ## load data from the request
+ lvd %d5, OCCHW_SCOM_DATA_OFFSET(%r3)
+
+ ## do the putscom
+ stvd %d5, 0(%r4)
+
+ b _get_scom_status
+
+
+
+
diff --git a/src/ppe/pk/gpe/gpe_timebase.h b/src/ppe/pk/gpe/gpe_timebase.h
new file mode 100644
index 0000000..57c96ce
--- /dev/null
+++ b/src/ppe/pk/gpe/gpe_timebase.h
@@ -0,0 +1,64 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/gpe_timebase.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __GPE_TIMEBASE_H__
+#define __GPE_TIMEBASE_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file gpe_timebase.h
+/// \brief support for using the OCB 32 bit timebase register
+///
+/// The OCB timebase register is a 32 bit count-up register that is shared
+/// by all GPE's in the OCC complex.
+
+#include "pk.h"
+
+#ifndef __ASSEMBLER__
+
+#ifdef APPCFG_USE_EXT_TIMEBASE
+static inline
+uint32_t pk_timebase32_get(void)
+{
+ return in32(OCB_OTBR);
+}
+
+#else
+//assembly function is defined in ppe42_timebase.S
+uint32_t pk_timebase32_get(void);
+
+#endif /* APPCFG_USE_EXT_TIMEBASE */
+
+#else
+
+ .macro _pk_timebase32_get rT, rA
+ _lwzi \rT, \rA, OCB_OTBR
+ .endm
+#endif /* __ASSEMBLER__ */
+
+#endif /* __GPE_TIMEBASE_H__ */
diff --git a/src/ppe/pk/gpe/pk_port.h b/src/ppe/pk/gpe/pk_port.h
new file mode 100644
index 0000000..89751d7
--- /dev/null
+++ b/src/ppe/pk/gpe/pk_port.h
@@ -0,0 +1,40 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/gpe/pk_port.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_PORT_H__
+#define __PK_PORT_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_port.h
+/// \brief The top-level GPE environment header for PK.
+
+#define HWMACRO_GPE
+
+#include "ppe42.h"
+#include "gpe_timebase.h"
+#endif /* __PK_PORT_H__ */
diff --git a/src/ppe/pk/gpe/pkgpefiles.mk b/src/ppe/pk/gpe/pkgpefiles.mk
new file mode 100644
index 0000000..34f0f1a
--- /dev/null
+++ b/src/ppe/pk/gpe/pkgpefiles.mk
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/gpe/pkgpefiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file pkgpefiles.mk
+#
+# @brief mk for including gpe object files
+#
+# @page ChangeLogs Change Logs
+# @section pkgpefiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+GPE-C-SOURCES = gpe_init.c gpe_irq_init.c
+GPE-S-SOURCES = gpe_scom_handler.S
+
+GPE-TIMER-C-SOURCES =
+GPE-TIMER-S-SOURCES =
+
+GPE-THREAD-C-SOURCES =
+GPE-THREAD-S-SOURCES =
+
+GPE-ASYNC-C-SOURCES =
+GPE-ASYNC-S-SOURCES =
+
+GPE_OBJECTS += $(GPE-C-SOURCES:.c=.o) $(GPE-S-SOURCES:.S=.o)
+
diff --git a/src/ppe/pk/kernel/.empty b/src/ppe/pk/kernel/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/pk/kernel/.empty
diff --git a/src/ppe/pk/kernel/Makefile b/src/ppe/pk/kernel/Makefile
new file mode 100644
index 0000000..d08930a
--- /dev/null
+++ b/src/ppe/pk/kernel/Makefile
@@ -0,0 +1,50 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/kernel/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile is designed to be invoked with the -I argument set to
+# the location of the "pk.mk" for the build
+
+include img_defs.mk
+include pkkernelfiles.mk
+
+ifeq "$(PK_TIMER_SUPPORT)" "1"
+PK_OBJECTS += ${PK-TIMER-C-SOURCES:.c=.o}
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" "1"
+PK_OBJECTS += ${PK-THREAD-C-SOURCES:.c=.o}
+endif
+
+OBJS := $(addprefix $(OBJDIR)/, $(PK_OBJECTS))
+
+all: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/pk/kernel/pk.h b/src/ppe/pk/kernel/pk.h
new file mode 100644
index 0000000..055d579
--- /dev/null
+++ b/src/ppe/pk/kernel/pk.h
@@ -0,0 +1,149 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_H__
+#define __PK_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk.h
+/// \brief The combined header of the PK kernel.
+///
+/// This header will be included in any C or assembler source file that
+/// requires any of the PK API. All headers defined by PK and co-compiled
+/// code should be protected such that they can be included without error into
+/// assembly.
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#include <stddef.h>
+#endif /* __ASSEMBLER__ */
+
+#ifndef __PK__
+#define __PK__ 1
+#endif
+
+/// The application environment specifies whether or not it will provide an
+/// application configuration file, which must be named "pk_app_cfg.h".
+
+#ifndef USE_PK_APP_CFG_H
+#define USE_PK_APP_CFG_H 0
+#endif
+
+#if USE_PK_APP_CFG_H
+#include "pk_app_cfg.h"
+#endif
+
+#include "pk_macros.h"
+#include "pk_api.h"
+#include "pk_port.h"
+#include "pk_kernel.h"
+//#include "pk_io.h"
+
+#ifndef __ASSEMBLER__
+
+#define MIN(X, Y) \
+ ({ \
+ typeof (X) __x = (X); \
+ typeof (Y) __y = (Y); \
+ (__x < __y) ? __x : __y; })
+
+#define MAX(X, Y) \
+ ({ \
+ typeof (X) __x = (X); \
+ typeof (Y) __y = (Y); \
+ (__x > __y) ? __x : __y; \
+ })
+
+/// \todo These don't require 32/64 bit versions, can always promote 32->64.
+
+#define FLOOR_LOG2_32(x) (32 - 1 - cntlz32(x))
+#define FLOOR_LOG2_64(x) (64 - 1 - cntlz64(x))
+
+#define CEILING_LOG2(x) \
+ ({ \
+ uint64_t __x = (uint64_t)(x); \
+ int __y; \
+ __y = FLOOR_LOG2_64(__x); \
+ if ((__x & (__x - 1)) != 0) { \
+ __y++; \
+ } \
+ __y;})
+
+
+#define POW2_32(x) ((uint32_t)1 << (x))
+#define POW2_64(x) ((uint64_t)1 << (x))
+
+/// Cast a pointer to another type
+///
+/// This macro is necessary when casting a pointer to a longer integer type.
+/// The pointer is first cast to the equivalent integer type 'unsigned long',
+/// then cast to the final type. You can also use this to cast integers longer
+/// than pointers back to pointers.
+
+#define CAST_POINTER(t, p) ((t)((unsigned long)(p)))
+
+
+/// Create an alignment attribute.
+#define ALIGNED_ATTRIBUTE(alignment) __attribute__ ((aligned (alignment)))
+
+/// Create a specific-section attribute
+///
+/// Note that the section \a s here must be a string. Also note that data
+/// specified to reside in specific sections must always be
+/// initialized. Otherwise it confuses the linker which wants to put
+/// uninitialized data into .bss sections.
+///
+/// \code
+///
+/// int foo SECTION_ATTRIBUTE(".noncacheable") = 0;
+/// int bar[10] SECTION_ATTRIBUTE(".noncacheable") = {0};
+///
+/// \endcode
+#define SECTION_ATTRIBUTE(s) __attribute__ ((section (s)))
+
+/// Create a 'used' attribute
+///
+/// This is required for example to avoid "function unused" warnings when a
+/// function is declared static but only referenced by inline assembler:
+///
+/// \code
+///
+/// static USED_ATTRIBUTE void
+/// _checkstop(void* arg, PkIrqId irq, int priority)
+/// {
+/// PK_PANIC(VALIDATION_CHECKSTOP);
+/// }
+///
+/// PK_IRQ_FAST2FULL(_validationCheckstopHandler, _checkstop);
+///
+/// \endcode
+#define USED_ATTRIBUTE __attribute__ ((used))
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PK_H__ */
diff --git a/src/ppe/pk/kernel/pk_api.h b/src/ppe/pk/kernel/pk_api.h
new file mode 100644
index 0000000..add02ba
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_api.h
@@ -0,0 +1,1026 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_api.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_API_H__
+#define __PK_API_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_api.h
+/// \brief Macros and declarations for the PK API.
+
+// Basic constants
+
+/// Although the number of threads is defined as a manifest constant,
+/// numerous parts of the PK code assume this definition. The number of
+/// supported threads _can not_ be changed simply by changing this constant.
+
+#define PK_THREADS 32
+
+#define PK_IDLE_THREAD_PRIORITY PK_THREADS
+
+// Interrupt API
+
+#define PK_IRQ_POLARITY_ACTIVE_LOW 0
+#define PK_IRQ_POLARITY_ACTIVE_HIGH 1
+
+#define PK_IRQ_TRIGGER_LEVEL_SENSITIVE 0
+#define PK_IRQ_TRIGGER_EDGE_SENSITIVE 1
+
+// API return codes
+
+#define PK_OK 0
+#define PK_ILLEGAL_CONTEXT_THREAD_CONTEXT 0x00779002
+#define PK_ILLEGAL_CONTEXT_INTERRUPT_CONTEXT 0x00779003
+#define PK_ILLEGAL_CONTEXT_THREAD 0x00779004
+#define PK_ILLEGAL_CONTEXT_TIMER 0x00779005
+#define PK_INVALID_THREAD_AT_RESUME1 0x00779007
+#define PK_INVALID_THREAD_AT_RESUME2 0x00779008
+#define PK_INVALID_THREAD_AT_SUSPEND1 0x00779009
+#define PK_INVALID_THREAD_AT_SUSPEND2 0x0077900a
+#define PK_INVALID_THREAD_AT_DELETE 0x0077900b
+#define PK_INVALID_THREAD_AT_INFO 0x0077900c
+#define PK_INVALID_THREAD_AT_CHANGE 0x0077900d
+#define PK_INVALID_THREAD_AT_SWAP1 0x0077900e
+#define PK_INVALID_THREAD_AT_SWAP2 0x0077900f
+#define PK_INVALID_THREAD_AT_CREATE 0x00779010
+#define PK_INVALID_SEMAPHORE_AT_POST 0x00779011
+#define PK_INVALID_SEMAPHORE_AT_PEND 0x00779012
+#define PK_INVALID_SEMAPHORE_AT_RELEASE 0x00779013
+#define PK_INVALID_SEMAPHORE_AT_INFO 0x00779014
+#define PK_INVALID_SEMAPHORE_AT_CREATE 0x00779015
+#define PK_INVALID_TIMER_AT_SCHEDULE 0x00779016
+#define PK_INVALID_TIMER_AT_CANCEL 0x00779017
+#define PK_INVALID_TIMER_AT_INFO 0x00779018
+#define PK_INVALID_TIMER_AT_CREATE 0x00779019
+#define PK_INVALID_ARGUMENT_IRQ_SETUP 0x0077901a
+#define PK_INVALID_ARGUMENT_IRQ_HANDLER 0x0077901b
+#define PK_INVALID_ARGUMENT_INTERRUPT 0x00779024
+#define PK_INVALID_ARGUMENT_CONTEXT_SET 0x00779025
+#define PK_INVALID_ARGUMENT_CONTEXT_GET 0x00779026
+#define PK_INVALID_ARGUMENT_FIT 0x00779027
+#define PK_INVALID_ARGUMENT_WATCHDOG 0x00779028
+#define PK_INVALID_ARGUMENT_INIT 0x00779029
+#define PK_INVALID_ARGUMENT_SEMAPHORE 0x0077902a
+#define PK_INVALID_ARGUMENT_THREAD_CHANGE 0x0077902b
+#define PK_INVALID_ARGUMENT_THREAD_PRIORITY 0x0077902c
+#define PK_INVALID_ARGUMENT_THREAD1 0x0077902d
+#define PK_INVALID_ARGUMENT_THREAD2 0x0077902e
+#define PK_INVALID_ARGUMENT_THREAD3 0x0077902f
+#define PK_STACK_OVERFLOW 0x00779030
+#define PK_TIMER_ACTIVE 0x00779031
+#define PK_TIMER_NOT_ACTIVE 0x00779032
+#define PK_PRIORITY_IN_USE_AT_RESUME 0x00779033
+#define PK_PRIORITY_IN_USE_AT_CHANGE 0x00779034
+#define PK_PRIORITY_IN_USE_AT_SWAP 0x00779035
+#define PK_SEMAPHORE_OVERFLOW 0x00779036
+#define PK_SEMAPHORE_PEND_NO_WAIT 0x00779037
+#define PK_SEMAPHORE_PEND_TIMED_OUT 0x00779038
+#define PK_SEMAPHORE_PEND_WOULD_BLOCK 0x00779039
+#define PK_INVALID_DEQUE_SENTINEL 0x0077903a
+#define PK_INVALID_DEQUE_ELEMENT 0x0077903b
+#define PK_INVALID_OBJECT 0x0077903c
+
+// Kernel panics
+
+#define PK_NO_TIMER_SUPPORT 0x0077903d
+#define PK_START_THREADS_RETURNED 0x0077903e
+#define PK_UNIMPLEMENTED 0x0077903f
+#define PK_SCHEDULING_INVARIANT 0x00779040
+#define PK_TIMER_HANDLER_INVARIANT 0x00779041
+#define PK_THREAD_TIMEOUT_STATE 0x00779045
+
+
+/// \defgroup pk_thread_states PK Thread States
+///
+/// Threads are created in the state PK_THREAD_STATE_SUSPENDED_RUNNABLE.
+/// When the thread is mapped it transitions to state PK_THREAD_STATE_MAPPED.
+/// A mapped thread is runnable if it appears in the run queue; there is no
+/// other flag or status to indicate a runnable thread. If a blocked thread
+/// is suspended it goes into state PK_THREAD_STATE_SUSPENDED_BLOCKED. For
+/// all threads the reason for blockage is detailed in the \a flags field of
+/// the thread; See \ref pk_thread_flags. PK_THREAD_STATE_DELETED and
+/// PK_THREAD_STATE_COMPLETED are effectively equivalent but named
+/// individually for reporting purposes.
+///
+/// \note This separation of the thread \a state and \a flags allows the use
+/// of an PK semaphore as a thread barrier, as it supports a non-iterative
+/// implementation of pk_semaphore_release_all() in which all threads blocked
+/// on the semaphore are simultaneously inserted into the run queue with an
+/// atomic operation, followed by each individual thread readjusting its flags
+/// appropriately once the thread runs again.
+///
+/// @{
+
+#define PK_THREAD_STATE_SUSPENDED_RUNNABLE 1
+#define PK_THREAD_STATE_MAPPED 2
+#define PK_THREAD_STATE_SUSPENDED_BLOCKED 3
+#define PK_THREAD_STATE_COMPLETED 4
+#define PK_THREAD_STATE_DELETED 5
+
+/// @}
+
+
+/// \defgroup pk_thread_flags PK Thread Flags
+///
+/// The \a flag field of the thread extends the information contained in the
+/// \a state field; See \ref pk_thread_states. Blocked threads will show
+/// PK_THREAD_FLAG_SEMAPHORE_PEND, PK_THREAD_FLAG_TIMER_PEND or both (if
+/// blocked on a semaphore with timeout). The flag PK_THREAD_FLAG_TIMED_OUT
+/// indicates that a thread timer timed out before the thread became
+/// runnable. Currently only the semaphore-pend-with-timeout code uses this
+/// flag.
+///
+/// Note that a thread can be mapped and runnable (in the run queue) even
+/// though PK_THREAD_FLAG_SEMAPHORE_PEND and/or PK_THREAD_FLAG_TIMER_PEND
+/// are set. These flags are always cleared by the thread itself, not the code
+/// that unblocks the thread. This allows the implementation of the
+/// pk_semaphore_release_all() as explained in \ref pk_thread_states.
+///
+/// @{
+
+#define PK_THREAD_FLAG_SEMAPHORE_PEND 0x1
+#define PK_THREAD_FLAG_TIMER_PEND 0x2
+#define PK_THREAD_FLAG_TIMED_OUT 0x4
+
+/// @}
+
+
+// Critical Sections
+
+/// Enter a critical section, saving the current machine
+/// context.
+
+#define pk_critical_section_enter(pctx) \
+ pk_interrupt_disable(pctx)
+
+/// Exit a critical section by restoring the previous machine context.
+
+#define pk_critical_section_exit(pctx) \
+ pk_machine_context_set(pctx)
+
+
+/// Execute a statement atomically
+
+#define PK_ATOMIC(stmt) \
+ do { \
+ PkMachineContext __ctx; \
+ pk_critical_section_enter(&__ctx); \
+ stmt; \
+ pk_critical_section_exit(&__ctx); \
+ } while (0)
+
+
+// Application-overrideable definitions
+
+/// Control whether or not the API functions check for errors.
+///
+/// This definition can be overriden by the application.
+
+#ifndef PK_ERROR_CHECK_API
+#define PK_ERROR_CHECK_API 1
+#endif
+
+/// Control whether API errors cause kernel panics or return negative error
+/// codes.
+///
+/// This selection is only valid if \c PK_ERROR_CHECK_API is defined
+/// non-0. This definition can be overriden by the application.
+
+#ifndef PK_ERROR_PANIC
+#define PK_ERROR_PANIC 1
+#endif
+
+/// Control whether or not the PK kernel checks key invariants.
+///
+/// Violations of kernel invariants always cause kernel panics. This
+/// definition can be overriden by the application.
+
+#ifndef PK_ERROR_CHECK_KERNEL
+#define PK_ERROR_CHECK_KERNEL 1
+#endif
+
+/// Define the time interval type, which must be an unsigned type of a size
+/// less then or equal to the size of \c PkTimebase. This definition can be
+/// overridden by the application.
+
+#ifndef PK_TIME_INTERVAL_TYPE
+#define PK_TIME_INTERVAL_TYPE uint32_t
+#endif
+
+/// Provide support for the PkTimer APIs in addition to the default
+/// initerrupt APIs. This definition can be overridden by the application.
+
+#ifndef PK_TIMER_SUPPORT
+#define PK_TIMER_SUPPORT 1
+#endif
+
+/// Provide support for the all PK APIs. Thread support requires/implies
+/// support for time services and semaphores. This definition can be
+/// overridden by the application.
+
+#ifndef PK_THREAD_SUPPORT
+#define PK_THREAD_SUPPORT 1
+#endif
+
+/// Control the level of stack checking.
+///
+/// This definition can be overriden by the application.
+///
+/// 0 : No stack prepatterning or checking is made for thread and kernel
+/// stacks.
+///
+/// 1 : Kernel interrupt stacks are prepatterned during
+/// \c pk_initialize(). Thread stacks are prepatterned during
+/// \c pk_thread_create().
+///
+/// 2 : (\b Default - Currently Unimplemented) In addition to prepatterning,
+/// stack utilization is computed at the exit of context switches and
+/// interrupt processing. The maximum utilization is stored in
+/// the thread data structure. The kernel will panic if stack overflow is
+/// detected. Stack utilization is not computed for the idle thread.
+
+#ifndef PK_STACK_CHECK
+#define PK_STACK_CHECK 1
+#endif
+
+/// A hook for main()
+///
+/// This hook macro is expanded in the body of __pk_main() prior to the call
+/// of the application main(). The application can redefine this hook macro
+/// in (or in headers referred to in) the application header
+/// pk_app_cfg.h. The PK_MAIN_HOOK will run on the stack of main().
+
+#ifndef PK_MAIN_HOOK
+#define PK_MAIN_HOOK do {} while (0)
+#endif
+
+/// A hook for pk_start_threads()
+///
+/// This hook macro is expanded in the call-tree of pk_start_threads() before
+/// threads are actually started. The application can redefine this hook
+/// macro in (or in headers referred to in) the application header
+/// pk_app_cfg.h.
+///
+/// The PK_START_THREADS_HOOK runs as a pseudo-interrupt handler on the
+/// kernel stack, with external interrupts disabled.
+
+#ifndef PK_START_THREADS_HOOK
+#define PK_START_THREADS_HOOK do {} while (0)
+#endif
+
+/// The maximum value of the \c PkTimebase type.
+
+#define PK_TIMEBASE_MAX ((PkTimebase)-1)
+
+/// A special value that specifies that the timebase will not be reset during
+/// pk_init().
+
+#define PK_TIMEBASE_CONTINUES PK_TIMEBASE_MAX
+
+/// By convention, a timeout value indicating 'no waiting' in a call of \c
+/// pk_semaphore_pend().
+
+#define PK_NO_WAIT 0
+
+/// By convention, a timeout value indicating 'wait forever' in a call of \c
+/// pk_semaphore_pend().
+
+#define PK_WAIT_FOREVER ((PkInterval)-1)
+
+/// The PK timebase frequency in Hz
+///
+/// Earlier version of PK defined the timbase frequency as a preprocessor
+/// macro. Now, the timebase frequency is specified as a parameter of the
+/// pk_initialize() API. The macro remains defined for backwards
+/// compatibility, however all kernel uses of the timebase frequency are now
+/// optimized around the timebase parameter.
+
+#define PK_TIMEBASE_FREQUENCY_HZ __pk_timebase_frequency_hz
+
+/// This is the unscaled timebase frequency in Hz.
+#ifdef APPCFG_USE_EXT_TIMEBASE
+#define PK_BASE_FREQ_HZ 25000000
+#else
+#define PK_BASE_FREQ_HZ 400000000
+#endif /* APPCFG_USE_EXT_TIMEBASE */
+
+/// Scale a time interval to be _closer_ to what was actually requested
+/// base on the actual timebase frequency.
+#define PK_INTERVAL_SCALE(interval) ((interval) + ((interval) >> __pk_timebase_rshift))
+
+/// Convert a time in integral seconds to a time interval - overflows are
+/// ignored. The application can redefine this macro.
+
+#ifndef PK_SECONDS
+#define PK_SECONDS(s) ((PkInterval)(PK_BASE_FREQ_HZ * (PkInterval)(s)))
+#endif
+
+/// Convert a time in integral milliseconds to a time interval - overflows are
+/// ignored, and a frequency evenly (or closely) divisible by 1000 is
+/// assumed. The application can redefine this macro.
+
+#ifndef PK_MILLISECONDS
+#define PK_MILLISECONDS(m) ((PkInterval)((PK_BASE_FREQ_HZ * (PkInterval)(m)) / 1000))
+#endif
+
+/// Convert a time in integral microseconds to a time interval - overflows are
+/// ignored, and a frequncy evenly (or closely) divisible by 1,000,000 is
+/// assumed. The application can redefine this macro.
+
+#ifndef PK_MICROSECONDS
+#define PK_MICROSECONDS(u) ((PkInterval)((PK_BASE_FREQ_HZ * (PkInterval)(u)) / 1000000))
+#endif
+
+/// Convert a time in integral nanoseconds to a time interval - overflows are
+/// ignored, and a frequeyncy evenly (or closely) divisible by 1,000,000 is
+/// assumed. The application can redefine this macro.
+
+#ifndef PK_NANOSECONDS
+#define PK_NANOSECONDS(n) ((PkInterval)((PK_BASE_FREQ_HZ * (PkInterval)(n)) / 1000000000))
+#endif
+
+
+/// Enable PK application tracing (enabled by default)
+#ifndef PK_TRACE_ENABLE
+#define PK_TRACE_ENABLE 1
+#endif
+
+/// Enable PK kernel tracing (disabled by default)
+#ifndef PK_KERNEL_TRACE_ENABLE
+#define PK_KERNEL_TRACE_ENABLE 0
+#endif
+
+//Application trace macros
+#if !PK_TRACE_ENABLE
+#define PK_TRACE(...)
+#define PK_TRACE_BIN(str, bufp, buf_size)
+#else
+#define PK_TRACE(...) PKTRACE(__VA_ARGS__)
+#define PK_TRACE_BIN(str, bufp, buf_size) PKTRACE_BIN(str, bufp, buf_size)
+#endif
+
+
+//Kernel trace macros
+#if !PK_KERNEL_TRACE_ENABLE
+#define PK_KERN_TRACE(...)
+#define PK_KERN_TRACE_ASM16(...)
+#else
+#define PK_KERN_TRACE(...) PK_TRACE(__VA_ARGS__)
+#define PK_KERN_TRACE_ASM16(...) PK_TRACE_ASM16(__VA_ARGS__)
+#endif /* PK_KERNEL_TRACE_ENABLE */
+
+
+/// Add a string to the trace buffer with an optional register holding a 16bit value
+/// WARNING: This calls a c function which may clobber any of the volatile registers
+#if (PK_TRACE_SUPPORT && PK_TIMER_SUPPORT)
+#define PK_TRACE_ASM16(...) TRACE_ASM_HELPER16(VARG_COUNT(__VA_ARGS__), __VA_ARGS__)
+#else
+#define PK_TRACE_ASM16(...)
+#endif /* PK_TRACE_SUPPORT */
+
+/// The following macros are helper macros for tracing. They should not be called
+/// directly.
+#define VARG_COUNT_HELPER(_0, _1, _2, _3, _4, _5, _6, _7, N, ...) N
+#define VARG_COUNT(...) VARG_COUNT_HELPER(, ##__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
+
+#ifdef __ASSEMBLER__
+#define TRACE_ASM_HELPER16_CALL(count, ...) TINY_TRACE_ASM ## count (__VA_ARGS__)
+#define TRACE_ASM_HELPER16(count, ...) TRACE_ASM_HELPER16_CALL(count, __VA_ARGS__)
+
+#define TINY_TRACE_ASM0() .error "format string required"
+#define TINY_TRACE_ASM1(str) \
+ .tiny_trace_asm1 trace_ppe_hash(str, PK_TRACE_HASH_PREFIX)
+#define TINY_TRACE_ASM2(str, reg) \
+ .tiny_trace_asm2 trace_ppe_hash(str, PK_TRACE_HASH_PREFIX), reg
+#define TINY_TRACE_ASM3() .error "too many parameters"
+#define TINY_TRACE_ASM4() .error "too many parameters"
+#define TINY_TRACE_ASM5() .error "too many parameters"
+#define TINY_TRACE_ASM6() .error "too many parameters"
+#define TINY_TRACE_ASM7() .error "too many parameters"
+
+//TODO: add support for tracing more than 1 parameter and binary data in assembly
+
+ .global pk_trace_tiny
+
+ .macro .tiny_trace_asm1 hash16
+ lis %r3, \hash16
+ bl pk_trace_tiny
+ .endm
+
+ .macro .tiny_trace_asm2 hash16, parm16
+ clrlwi %r3, \parm16, 16
+ oris %r3, %r3, \hash16
+ bl pk_trace_tiny
+ .endm
+
+#endif /*__ASSEMBLER__*/
+
+
+
+#ifndef __ASSEMBLER__
+
+#include <stddef.h>
+#include <stdint.h>
+
+/// The timebase frequency in Hz; A parameter to pk_initialize()
+extern uint32_t __pk_timebase_frequency_hz;
+
+extern uint8_t __pk_timebase_rshift;
+
+/// The timebase frequency in KHz
+extern uint32_t __pk_timebase_frequency_khz;
+
+/// The timebase frequency in Mhz
+extern uint32_t __pk_timebase_frequency_mhz;
+
+
+typedef unsigned long int PkAddress;
+
+typedef uint8_t PkThreadState;
+
+typedef uint8_t PkThreadPriority;
+
+typedef uint8_t PkThreadFlags;
+
+typedef uint32_t PkSemaphoreCount;
+
+typedef uint64_t PkTimebase;
+
+typedef PK_TIME_INTERVAL_TYPE PkInterval;
+
+#include "pk_port_types.h"
+
+typedef struct {
+
+ /// A priority queue of threads pending on the semaphore.
+ PkThreadQueue pending_threads;
+
+ /// The current semaphore count.
+ PkSemaphoreCount count;
+
+ /// The maximum allowable count - for error checking.
+ PkSemaphoreCount max_count;
+
+} PkSemaphore;
+
+
+/// Compile-time initialize a PkSemaphore structure
+///
+/// This low-level macro creates a structure initializatin of an PkSemaphore
+/// structure. This can be used for example to create compile-time initialized
+/// arrays of semaphores.
+#define PK_SEMAPHORE_INITIALIZATION(_initial_count, _max_count) \
+ {.pending_threads = 0, \
+ .count = (_initial_count), \
+ .max_count = (_max_count)}
+
+
+/// Declare and initialize a semaphore
+#define PK_SEMAPHORE(sem, initial_count, max_count) \
+ PkSemaphore sem = PK_SEMAPHORE_INITIALIZATION(initial_count, max_count)
+
+
+/// Trace macros for C functions
+#define HASH_ARG_COMBO(str, arg) \
+ ((((uint32_t)trace_ppe_hash(str, PK_TRACE_HASH_PREFIX)) << 16) | ((uint32_t)(arg) & 0x0000ffff))
+
+#define PKTRACE0(...) pk_trace_tiny() //will fail at compile time
+
+#define PKTRACE1(str) \
+ pk_trace_tiny((trace_ppe_hash(str, PK_TRACE_HASH_PREFIX) << 16))
+
+#define PKTRACE2(str, parm0) \
+ ((sizeof(parm0) <= 2)? \
+ pk_trace_tiny(HASH_ARG_COMBO(str, parm0)): \
+ pk_trace_big(HASH_ARG_COMBO(str, 1), ((uint64_t)parm0) << 32, 0))
+
+#define PKTRACE3(str, parm0, parm1) \
+ pk_trace_big(HASH_ARG_COMBO(str, 2), ((((uint64_t)parm0) << 32) | parm1), 0)
+
+#define PKTRACE4(str, parm0, parm1, parm2) \
+ pk_trace_big(HASH_ARG_COMBO(str, 3), ((((uint64_t)parm0) << 32) | parm1),\
+ ((uint64_t)parm2) << 32 )
+
+#define PKTRACE5(str, parm0, parm1, parm2, parm3) \
+ pk_trace_big(HASH_ARG_COMBO(str, 4), ((((uint64_t)parm0) << 32) | parm1),\
+ ((((uint64_t)parm2) << 32) | parm3) )
+
+#define PKTRACE6(...) pk_trace_tiny() //will fail at compile time
+#define PKTRACE7(...) pk_trace_tiny() //will fail at compile time
+
+#define PKTRACE_HELPER2(count, ...) PKTRACE ## count (__VA_ARGS__)
+#define PKTRACE_HELPER(count, ...) PKTRACE_HELPER2(count, __VA_ARGS__)
+
+#if (PK_TRACE_SUPPORT && PK_TIMER_SUPPORT)
+#define PKTRACE(...) PKTRACE_HELPER(VARG_COUNT(__VA_ARGS__), __VA_ARGS__)
+#define PKTRACE_BIN(str, bufp, buf_size) \
+ pk_trace_binary(((buf_size < 255)? HASH_ARG_COMBO(str, buf_size): HASH_ARG_COMBO(str, 255)), bufp)
+#else
+#define PKTRACE(...)
+#define PKTRACE_BIN(str, bufp, buf_size)
+#endif //PK_TRACE_SUPPORT
+
+
+
+/// A generic doubly-linked list object
+///
+/// This object functions both as a sentinel mode for a deque as well as a
+/// pointer container for elements in deques. The PK API assumes that
+/// queueable structures will be defined with an PkDeque structure as the
+/// initial 'data member' of the structure. This allows a pointer to a queue
+/// element to be cast to a pointer to an PkDeque and vice-versa.
+
+typedef struct PkDeque {
+
+ /// Pointer to the head or the next element in a deque.
+ ///
+ /// When an PkDeque is used as the sentinel node for a queue, \a next
+ /// points to the head of the queue, and the condition (next == \<self\>)
+ /// indicates an empty PkDeque. By convention the condition (\a next ==
+ /// 0) is used to indicate that a queue element is not enqueued.
+ struct PkDeque* next;
+
+ /// Pointer to the tail or previous element in a deque.
+ ///
+ /// When a DQueue is used as the sentinel node for a queue, \a previous
+ /// points to the tail of the queue.
+ struct PkDeque* previous;
+
+} PkDeque;
+
+
+typedef void (*PkTimerCallback)(void *);
+
+#define PK_TIMER_CALLBACK(callback) void callback(void *)
+
+struct PkTimer;
+
+/// The PK timer object
+
+typedef struct PkTimer {
+
+ /// The time queue management pointers
+ ///
+ /// This pointer container is defined as the first element of the
+ /// structure to allow the PkTimer to be cast to an PkDeque and
+ /// vice-versa.
+ PkDeque deque;
+
+ /// The absolute timeout of the timer.
+ PkTimebase timeout;
+
+ /// The timer callback
+ ///
+ /// For PK thread timers used to implement Sleep and semaphore pend
+ /// timeouts this field is initialized to __pk_thread_timeout().
+ PkTimerCallback callback;
+
+ /// Private data passed to the callback.
+ ///
+ /// For PK thread timers used to implement Sleep and semaphore pend this
+ /// field is initialized to a pointer to the thread.
+ void *arg;
+
+} PkTimer;
+
+
+// Threads
+
+typedef void (*PkThreadRoutine)(void *arg);
+
+#define PK_THREAD_ROUTINE(f) void f(void *arg);
+
+typedef struct {
+
+ /// Stack pointer saved during context switches. Assembler code expects
+ /// this to always be at address offset 0 from the thread pointer.
+ PkAddress saved_stack_pointer;
+
+ /// This is 1 past the last valid byte address of the thread stack.
+ /// Assembler code expects this to always be at address offset (sizeof
+ /// PkAddress) from the thread pointer.
+ PkAddress stack_limit;
+
+ /// This is the original base of the stack.
+ /// Assembler code expects this to always be at address offset 2 * (sizeof
+ /// PkAddress) from the thread pointer.
+ PkAddress stack_base;
+
+ /// If the thread is blocked on a semaphore, then this is the semaphore the
+ /// thread is blocked on.
+ PkSemaphore *semaphore;
+
+ /// The thread priority.
+ PkThreadPriority priority;
+
+ /// The thread state; See \ref pk_thread_states
+ PkThreadState state;
+
+ /// Thread flags; See \ref pk_thread_flags
+ PkThreadFlags flags;
+
+ /// The timer structure handles Sleep and blocking on a semaphore with
+ /// timeout.
+ PkTimer timer;
+
+} PkThread;
+
+
+typedef void (*PkBhHandler)(void *);
+
+#define PK_BH_HANDLER(handler) void handler(void *)
+
+typedef struct {
+
+ /// The bottom half queue management pointers
+ ///
+ /// This pointer container is defined as the first element of the
+ /// structure to allow the PkBottomHalf to be cast to a PkDeque and
+ /// vice-versa.
+ PkDeque deque;
+
+ /// The bottom half handler
+ PkBhHandler bh_handler;
+
+ /// Private data passed to the handler.
+ void *arg;
+
+} PkBottomHalf;
+
+
+// Initialization APIs
+
+int
+pk_initialize(PkAddress kernel_stack,
+ size_t kernel_stack_size,
+ PkTimebase initial_timebase,
+ uint32_t timebase_frequency_hz);
+
+
+// Timebase APIs
+
+PkTimebase
+pk_timebase_get(void);
+
+
+// Timer APIs
+
+int
+pk_timer_create(PkTimer *timer,
+ PkTimerCallback callback,
+ void *arg);
+
+
+int
+pk_timer_schedule(PkTimer *timer,
+ PkInterval interval);
+
+int
+pk_timer_cancel(PkTimer *timer);
+
+int
+pk_timer_info_get(PkTimer *timer,
+ PkTimebase *timeout,
+ int *active);
+
+// Thread APIs
+
+int
+pk_thread_create(PkThread *thread,
+ PkThreadRoutine thread_routine,
+ void *arg,
+ PkAddress stack,
+ size_t stack_size,
+ PkThreadPriority priority);
+
+int
+pk_start_threads(void);
+
+int
+pk_thread_resume(PkThread *thread);
+
+int
+pk_thread_suspend(PkThread *thread);
+
+int
+pk_thread_delete(PkThread *thread);
+
+int
+pk_complete(void);
+
+int
+pk_sleep(PkInterval interval);
+
+int
+pk_thread_info_get(PkThread *thread,
+ PkThreadState *state,
+ PkThreadPriority *priority,
+ int *runnable);
+
+int
+pk_thread_priority_change(PkThread *thread,
+ PkThreadPriority new_priority,
+ PkThreadPriority *old_priority);
+
+int
+pk_thread_at_priority(PkThreadPriority priority,
+ PkThread **thread);
+
+int
+pk_thread_priority_swap(PkThread* thread_a, PkThread* thread_b);
+
+
+// Semaphore APIs
+
+int
+pk_semaphore_create(PkSemaphore *semaphore,
+ PkSemaphoreCount initial_count,
+ PkSemaphoreCount max_count);
+
+int
+pk_semaphore_post(PkSemaphore *semaphore);
+
+int
+pk_semaphore_pend(PkSemaphore *semaphore,
+ PkInterval timeout);
+
+int
+pk_semaphore_release_all(PkSemaphore *semaphore);
+
+
+int
+pk_semaphore_info_get(PkSemaphore *semaphore,
+ PkSemaphoreCount *count,
+ int *pending);
+
+void
+pk_semaphore_post_handler(void *arg,
+ PkIrqId irq);
+
+// Misc. APIs
+
+void
+pk_halt() __attribute__ ((noreturn));
+
+// Deque APIs
+
+int
+pk_deque_sentinel_create(PkDeque *deque);
+
+#define PK_DEQUE_SENTINEL_INIT(dq_addr) \
+{\
+ .next = dq_addr, \
+ .previous = dq_addr \
+}
+
+#define PK_DEQUE_SENTINEL_STATIC_CREATE(deque) \
+ PkDeque deque = PK_DEQUE_SENTINEL_INIT(&deque)
+
+int
+pk_deque_element_create(PkDeque *element);
+
+#define PK_DEQUE_ELEMENT_INIT() \
+{\
+ .next = 0, \
+ .previous = 0 \
+}
+
+#define PK_DEQUE_ELEMENT_STATIC_CREATE(deque) \
+ PkDeque deque = PK_DEQUE_ELEMENT_INIT()
+
+/// Check for an empty PkDeque
+///
+/// \param deque The sentinel node of a deque
+///
+/// \retval 0 The PkDeque is not empty
+///
+/// \retval 1 The PkDeque is empty
+
+static inline int
+pk_deque_is_empty(PkDeque *deque)
+{
+ return (deque == deque->next);
+}
+
+
+/// Check if an PkDeque element is currently enqueued
+///
+/// \param element Typically the PkDeque object of a queable structure
+///
+/// \retval 0 The element is not currently enqueued
+///
+/// \retval 1 The element is currently enqueued
+
+static inline int
+pk_deque_is_queued(PkDeque *element)
+{
+ return (element->next != 0);
+}
+
+
+/// Append an element to the tail of a deque (FIFO order)
+///
+/// \param deque The sentinel node of a deque
+///
+/// \param element Typically the PkDeque object of a queable structure
+///
+/// It is an error to call this API on an element that is already enqueued,
+/// but the API does not check for this error.
+
+static inline void
+pk_deque_push_back(PkDeque *deque, PkDeque *element)
+{
+ deque->previous->next = element;
+ element->previous = deque->previous;
+ element->next = deque;
+ deque->previous = element;
+}
+
+
+/// Push an element at the head of a deque (LIFO order)
+///
+/// \param deque The sentinel node of a deque
+///
+/// \param element Typically the PkDeque object of a queable structure
+///
+/// It is an error to call this API on an element that is already enqueued,
+/// but the API does not check for this error.
+
+static inline void
+pk_deque_push_front(PkDeque *deque, PkDeque *element)
+{
+ deque->next->previous = element;
+ element->next = deque->next;
+ element->previous = deque;
+ deque->next = element;
+}
+
+/// Pop an element from the head of a deque
+///
+/// \param deque The sentinel node of a deque
+///
+/// \retval 0 The PkDeque was empty prior to the call
+///
+/// \retval non-0 A pointer to the previous head of the deque, which has been
+/// removed from the deque and marked as no longer queued.
+
+// The cast of 'head' is used to remove the 'volatile' attribute.
+
+static inline PkDeque *
+pk_deque_pop_front(PkDeque *deque)
+{
+ PkDeque *head;
+
+ if (pk_deque_is_empty(deque)) {
+ return 0;
+ } else {
+ head = (PkDeque *)(deque->next);
+ deque->next = head->next;
+ deque->next->previous = deque;
+ head->next = 0;
+ return head;
+ }
+}
+
+
+/// Remove a deque element from any position in the deque
+///
+/// \param element Typically the PkDeque object of a queable structure
+///
+/// It is an error to call this API on an element that is not currently
+/// enqueued, but the API does not check for this error.
+
+static inline void
+pk_deque_delete(PkDeque *element)
+{
+ element->previous->next = element->next;
+ element->next->previous = element->previous;
+ element->next = 0;
+}
+
+// Bottom Half APIs
+
+extern PkDeque _pk_bh_queue;
+
+static inline void
+pk_bh_schedule(PkBottomHalf *bottom_half)
+{
+ pk_deque_push_back(&_pk_bh_queue, (PkDeque *)bottom_half);
+}
+
+#define PK_BH_INIT(_handler, _arg) \
+{\
+ .deque = PK_DEQUE_ELEMENT_INIT(), \
+ .bh_handler = _handler, \
+ .arg = _arg \
+}
+
+#define PK_BH_STATIC_CREATE(bh_name, handler, arg) \
+PkBottomHalf bh_name = PK_BH_INIT(handler, arg)
+
+
+//Trace function prototypes
+void pk_trace_tiny(uint32_t i_parm);
+void pk_trace_big(uint32_t i_hash_and_count,
+ uint64_t i_parm1, uint64_t i_parm2);
+void pk_trace_binary(uint32_t i_hash_and_size, void* bufp);
+void pk_trace_set_timebase(PkTimebase timebase);
+
+
+/// Cast a pointer to another type, in a way that won't cause warnings
+
+#define PK_CAST_POINTER(t, p) ((t)((PkAddress)(p)))
+
+// Static Assert Macro for Compile time assertions.
+// - This macro can be used both inside and outside of a function.
+// - A value of false will cause the ASSERT to produce this error
+// - This will show up on a compile fail as:
+// <file>:<line> error: size of array '_static_assert' is negative
+// - It would be trivial to use the macro to paste a more descriptive
+// array name for each assert, but we will leave it like this for now.
+#define PK_STATIC_ASSERT(cond) extern uint8_t _static_assert[(cond) ? 1 : -1] __attribute__ ((unused))
+
+/// \page pk_errors PK API and Kernel Error Handling
+///
+/// Error checking in the PK API consumes a significant amount of code space.
+/// Approximately 20% of the object code in the PPC405 port is devoted to
+/// error checking. Presumably a like amount of time overhead is also added to
+/// PK API calls by this checking.
+///
+/// API error checking can be disabled to save space and time in the kernel.
+/// API errors can also be configured to cause kernel panics, allowing
+/// applications to be coded without the overhead of error checking but still
+/// providing an escape in the event of application errors or (unlikely)
+/// hardware failures. The PK default is to check for API errors and kernel
+/// invariants, and panic should errors occur.
+///
+/// PK follows the Unix convention that a successful call of an API returns 0
+/// (PK_OK), but returns a negative code in the event of failure, or to
+/// provide further information. The error codes are all defined as manifest
+/// constants.
+///
+/// Some negative codes returned by PK APIs are not considered errors. These
+/// conditions are always checked, never cause a panic if they occur, and
+/// their interpretation is always left to the application. See the detailed
+/// documentation for each API for lists of error and non-error codes returned
+/// by the API.
+///
+/// There are three configuration options that control error handling in the
+/// PK API and kernel:
+///
+/// \c PK_ERROR_CHECK_API
+///
+/// \arg \b 0 - No PK API error checking. APIs that potentially return error
+/// codes will always return 0 (PK_OK) instead of an error code. Those
+/// APIs that return negative codes that are not errors (see Table 1.5)
+/// always return the negative non-error codes when appropriate.
+///
+/// \arg \b 1 - (Default) All PK API errors are checked. The behavior in
+/// the event of an error is defined by the configuration option
+/// PK_ERROR_PANIC.
+///
+/// \c PK_ERROR_CHECK_KERNEL
+///
+/// \arg \b 0 - No kernel invariant error checking is done.
+///
+/// \arg \b 1 - (Default) Selected kernel invariants are checked. The overhead
+/// for these checks should be minimal.
+///
+/// \c PK_ERROR_PANIC
+///
+/// \arg \b 0 - PK API calls return negative error codes in the event of
+/// errors. Note that PK kernel invariants always cause a panic if
+/// violations occur.
+///
+/// \arg \b 1 - (Default) In the event of errors PK APIs invoke PK_PANIC(code),
+/// where code is a positive error code. Kernel invariant checks always
+/// cause a panic if violations are detected.
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PK_API_H__ */
diff --git a/src/ppe/pk/kernel/pk_bh_core.c b/src/ppe/pk/kernel/pk_bh_core.c
new file mode 100644
index 0000000..5db40af
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_bh_core.c
@@ -0,0 +1,53 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_bh_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_bh_core.c
+/// \brief PK bottom half APIs
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present at runtime in any PK application.
+
+#include "pk.h"
+
+/// Statically initialize the bottom half queue
+PK_DEQUE_SENTINEL_STATIC_CREATE(_pk_bh_queue);
+
+void _pk_process_bh(void)
+{
+ PkBottomHalf *bh;
+ while((bh = (PkBottomHalf*)pk_deque_pop_front(&_pk_bh_queue)) != 0)
+ {
+ bh->bh_handler(bh->arg);
+ }
+ return;
+}
+
+
+#undef __PK_THREAD_CORE_C__
diff --git a/src/ppe/pk/kernel/pk_core.c b/src/ppe/pk/kernel/pk_core.c
new file mode 100644
index 0000000..d22e3bd
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_core.c
@@ -0,0 +1,103 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_core.c
+/// \brief Core routines for the PK kernel.
+///
+/// The entry points in this file are routines that are expected to be needed
+/// at runtime by all PK applications. This file also serves as a place for
+/// kernel global variables to be realized.
+
+#define __PK_CORE_C__
+
+#include "pk.h"
+
+#if !PK_TIMER_SUPPORT
+
+/// If there is no timer support, then any call of the timer interrupt handler
+/// is considered a fatal error.
+
+void
+__pk_timer_handler()
+{
+ PK_PANIC(PK_NO_TIMER_SUPPORT);
+}
+
+#endif /* PK_TIMER_SUPPORT */
+
+
+/// Initialize an PkDeque sentinel node
+///
+/// \param deque The sentinel node of the deque
+///
+/// PK has no way of knowing whether the \a deque is currently in use, so
+/// this API must only be called on unitialized or otherwise unused sentinel
+/// nodes.
+///
+/// \retval 0 success
+///
+/// \retval -PK_INVALID_DEQUE_SENTINEL The \a deque pointer was null
+
+int
+pk_deque_sentinel_create(PkDeque *deque)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(deque == 0, PK_INVALID_DEQUE_SENTINEL);
+ }
+
+ deque->next = deque->previous = deque;
+ return 0;
+}
+
+
+/// Initialize an PkDeque element
+///
+/// \param element Typically the PkDeque object of a queable structure
+///
+/// PK has no way of knowing whether the \a element is currently in use, so
+/// this API must only be called on unitialized or otherwise unused deque
+/// elements.
+///
+/// \retval 0 success
+///
+/// \retval -PK_INVALID_DEQUE_ELEMENT The \a element pointer was null
+
+int
+pk_deque_element_create(PkDeque *element)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(element == 0, PK_INVALID_DEQUE_ELEMENT);
+ }
+
+ element->next = 0;
+ return 0;
+}
+
+#undef __PK_CORE_C__
diff --git a/src/ppe/pk/kernel/pk_debug_ptrs.c b/src/ppe/pk/kernel/pk_debug_ptrs.c
new file mode 100644
index 0000000..df2288b
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_debug_ptrs.c
@@ -0,0 +1,77 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_debug_ptrs.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_debug_ptrs.c
+/// \brief Defines a table of pointers to important kernel debug data.
+///
+/// This table is placed in a special section named .debug_ptrs which can be
+/// placed at a well-known memory location for tools to find.
+///
+
+#include "pk.h"
+#include "pk_trace.h"
+#include "pk_debug_ptrs.h"
+
+extern PkTimebase ppe42_64bit_timebase;
+
+#if PK_TRACE_SUPPORT
+extern PkTraceBuffer g_pk_trace_buf;
+#endif
+
+pk_debug_ptrs_t pk_debug_ptrs SECTION_ATTRIBUTE(".debug_ptrs") =
+{
+ .debug_ptrs_size = sizeof(pk_debug_ptrs),
+ .debug_ptrs_version = PK_DEBUG_PTRS_VERSION,
+
+#if PK_TRACE_SUPPORT
+ .debug_trace_ptr = &g_pk_trace_buf,
+ .debug_trace_size = sizeof(g_pk_trace_buf),
+#else
+ .debug_trace_ptr = 0,
+ .debug_trace_size = 0,
+#endif /* PK_TRACE_SUPPORT */
+
+#if PK_THREAD_SUPPORT
+ .debug_thread_table_ptr = &__pk_priority_map,
+ .debug_thread_table_size = sizeof(__pk_priority_map),
+ .debug_thread_runq_ptr = (void*)&__pk_run_queue,
+ .debug_thread_runq_size = sizeof(__pk_run_queue),
+#else
+ .debug_thread_table_ptr = 0,
+ .debug_thread_table_size = 0,
+ .debug_thread_runq_ptr = 0,
+ .debug_thread_runq_size = 0,
+#endif /* PK_THREAD_SUPPORT */
+
+ .debug_timebase_ptr = &ppe42_64bit_timebase,
+ .debug_timebase_size = sizeof(ppe42_64bit_timebase),
+
+};
+
diff --git a/src/ppe/pk/kernel/pk_debug_ptrs.h b/src/ppe/pk/kernel/pk_debug_ptrs.h
new file mode 100644
index 0000000..92a01c5
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_debug_ptrs.h
@@ -0,0 +1,63 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_debug_ptrs.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_DEBUG_PTRS_H__
+#define __PK_DEBUG_PTRS_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_debug_ptrs.h
+/// \brief Structure for a table of pointers to kernel debug data
+///
+
+#define PK_DEBUG_PTRS_VERSION 1
+
+typedef struct
+{
+ // The size and version of this structure
+ unsigned short debug_ptrs_size;
+ unsigned short debug_ptrs_version;
+
+ // Trace buffer location and size
+ void* debug_trace_ptr;
+ unsigned long debug_trace_size;
+
+ // Thread table location and size
+ void* debug_thread_table_ptr;
+ unsigned long debug_thread_table_size;
+
+ // Thread run queue location and size
+ void* debug_thread_runq_ptr;
+ unsigned long debug_thread_runq_size;
+
+ // Emulated timebase location and size
+ void* debug_timebase_ptr;
+ unsigned long debug_timebase_size;
+
+} pk_debug_ptrs_t;
+
+#endif /*__PK_DEBUG_PTRS_H__*/
diff --git a/src/ppe/pk/kernel/pk_init.c b/src/ppe/pk/kernel/pk_init.c
new file mode 100644
index 0000000..4886c53
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_init.c
@@ -0,0 +1,220 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_init.c
+/// \brief PK initialization
+///
+/// The entry points in this file are initialization routines - they are never
+/// needed after PK initialization and their code space could be reclaimed by
+/// the application after initialization if required.
+
+#include "pk.h"
+#include "pk_trace.h"
+
+uint32_t __pk_timebase_frequency_hz;
+
+/// The timebase frequency is passed into PK during initialization. It cannot
+/// be set statically because there is a requirement to support a frequency
+/// that can change from one IPL to the next. On the 405, scaling of time
+/// intervals is accomplished by doing a 32x32 bit multiplication which is
+/// supported by the ppc405 instruction set. PPE42 does not support 32x32 bit
+/// multiplication directly and some applications can not afford to use a
+/// function call to emulate the operation. Instead we scale the time
+/// interval by shifting the value X bits to the right and adding it to itself.
+/// This can scale the value by 2, 1.5, 1.25, 1.125, etc.
+///
+/// This is the right shift value.
+/// NOTE: shifting by 0 gives a 2x scale factor, shifting by 32 gives a 1x
+/// scale factor.
+uint8_t __pk_timebase_rshift = 32;
+
+void pk_set_timebase_rshift(uint32_t timebase_freq_hz)
+{
+ //Use 1.0 scale if less than halfway between 1.0 and 1.25
+ if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 3)))
+ {
+ __pk_timebase_rshift = 32;
+ }
+
+ //use 1.25 scale if less than halfway between 1.25 and 1.5
+ else if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 3) + (PK_BASE_FREQ_HZ >> 2)))
+ {
+ __pk_timebase_rshift = 2;
+ }
+ //use 1.5 scale if less than halfway between 1.5 and 2.0
+ else if(timebase_freq_hz <= (PK_BASE_FREQ_HZ + (PK_BASE_FREQ_HZ >> 2) + (PK_BASE_FREQ_HZ >> 1)))
+ {
+ __pk_timebase_rshift = 1;
+ }
+ //use 2.0 scale if greater than 1.5
+ else
+ {
+ __pk_timebase_rshift = 0;
+ }
+}
+
+/// Initialize PK.
+///
+/// \param kernel_stack A stack area for interrupt and bottom-half handlers.
+///
+/// \param kernel_stack_size The size (in bytes) of the stack area for
+/// interrupt and bottom-half handlers.
+///
+/// \param initial_timebase The initial value of the PK timebase.
+/// If the argument is given as the special value \c PK_TIMEBASE_CONTINUES, then the
+/// timebase is not reset.
+///
+/// \param timebase_frequency_hz The frequency of the PK timebase in Hz.
+///
+/// This routine \e must be called before any other PK / routines, and \e
+/// should be called before any interrupts are enabled.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_INIT A stack pointer is 0 or is given
+/// a 0 size.
+///
+/// \retval -PK_STACK_OVERFLOW One or both stacks are not large enough to
+/// support a minimum context save in the event of an interrupt.
+
+// Note that PK does not rely on any static initialization of dynamic
+// variables. In debugging sessions using RAM-resident PK images it is
+// assumed that the processor may be reset at any time, so we always need to
+// reset everything at initialization.
+
+int
+pk_initialize(PkAddress kernel_stack,
+ size_t kernel_stack_size,
+ PkTimebase initial_timebase,
+ uint32_t timebase_frequency_hz)
+{
+ int rc;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF((kernel_stack == 0) ||
+ (kernel_stack_size == 0),
+ PK_INVALID_ARGUMENT_INIT);
+ }
+
+ __pk_timebase_frequency_hz = timebase_frequency_hz;
+
+ __pk_thread_machine_context_default = PK_THREAD_MACHINE_CONTEXT_DEFAULT;
+
+ rc = __pk_stack_init(&kernel_stack, &kernel_stack_size);
+ if (rc) {
+ return rc;
+ }
+
+ __pk_kernel_stack = kernel_stack;
+ __pk_kernel_stack_size = kernel_stack_size;
+
+#if PK_TIMER_SUPPORT
+
+ // Initialize the time queue sentinel as a circular queue, set the next
+ // timeout and clear the cursor.
+
+ pk_deque_sentinel_create((PkDeque*)&__pk_time_queue);
+ __pk_time_queue.cursor = 0;
+ __pk_time_queue.next_timeout = PK_TIMEBASE_MAX;
+
+#if PK_TRACE_SUPPORT
+extern PkTimer g_pk_trace_timer;
+extern PkTraceBuffer g_pk_trace_buf;
+
+ //set the trace timebase HZ
+ g_pk_trace_buf.hz = timebase_frequency_hz;
+
+ //set the shift adjustment to get us closer to the true
+ //timebase frequency (versus what was hardcoded)
+ pk_set_timebase_rshift(timebase_frequency_hz);
+
+ if(initial_timebase != PK_TIMEBASE_CONTINUES)
+ {
+ //set the timebase ajdustment for trace synchronization
+ pk_trace_set_timebase(initial_timebase);
+ }
+
+ // Schedule the timer that puts a 64bit timestamp in the trace buffer
+ // periodically. This allows us to use 32bit timestamps.
+ pk_timer_schedule(&g_pk_trace_timer,
+ PK_TRACE_TIMER_PERIOD);
+
+#endif /* PK_TRACE_SUPPORT */
+
+#endif /* PK_TIMER_SUPPORT */
+
+#if PK_THREAD_SUPPORT
+
+ // Clear the priority map. The final entry [PK_THREADS] is for the idle
+ // thread.
+
+ int i;
+ for (i = 0; i <= PK_THREADS; i++) {
+ __pk_priority_map[i] = 0;
+ }
+
+ // Initialize the thread scheduler
+
+ __pk_thread_queue_clear(&__pk_run_queue);
+ __pk_current_thread = 0;
+ __pk_next_thread = 0;
+ __pk_delayed_switch = 0;
+
+#endif /* PK_THREAD_SUPPORT */
+
+ return PK_OK;
+}
+
+
+/// Call the application main()
+///
+/// __pk_main() is called from the bootloader. It's only purpose is to
+/// provide a place for the PK_MAIN_HOOK to be called before main() is
+/// called.
+
+void
+__pk_main(int argc, char **argv)
+{
+ PK_MAIN_HOOK;
+
+ int main(int argc, char **argv);
+ main(argc, argv);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/ppe/pk/kernel/pk_kernel.h b/src/ppe/pk/kernel/pk_kernel.h
new file mode 100644
index 0000000..82ffd29
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_kernel.h
@@ -0,0 +1,270 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_kernel.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_KERNEL_H__
+#define __PK_KERNEL_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_kernel.h
+/// \brief PK portable kernel (non-API) data and data structures
+///
+/// \todo In theory, as long as the critical section entry/exit macros use GCC
+/// memory barriers, we should be able to eliminate all of the 'volatile'
+/// declarations in PK code. These have been added to the port, so
+/// we should try it.
+
+#ifdef __PK_CORE_C__
+#define IF__PK_CORE_C__(x) x
+#define UNLESS__PK_CORE_C__(x)
+#else
+#define IF__PK_CORE_C__(x)
+#define UNLESS__PK_CORE_C__(x) x
+#endif
+
+#if PK_MINIMIZE_KERNEL_CODE_SPACE
+#define IF_PK_MINIMIZE_KERNEL_CODE_SPACE(x) x
+#define UNLESS_PK_MINIMIZE_KERNEL_CODE_SPACE(x)
+#else
+#define IF_PK_MINIMIZE_KERNEL_CODE_SPACE(x)
+#define UNLESS_PK_MINIMIZE_KERNEL_CODE_SPACE(x) x
+#endif
+
+
+#ifndef __ASSEMBLER__
+
+/// This is the stack pointer saved when switching from a thread context to an
+/// interrupt context.
+
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkAddress __pk_saved_sp;
+
+/// The kernel stack; constant once defined by the call of
+/// pk_initialize().
+
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkAddress __pk_kernel_stack;
+
+/// This is the run queue - the queue of mapped runnable tasks.
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkThreadQueue __pk_run_queue;
+
+/// This flag is set by \c __pk_schedule() if a new highest-priority thread
+/// becomes runnable during an interrupt handler. The context switch will
+/// take place at the end of interrupt processing, and the
+/// interrupt handling code will clear the flag.
+
+UNLESS__PK_CORE_C__(extern)
+volatile
+int __pk_delayed_switch;
+
+/// The currently running thread, or NULL (0) to indicate the idle thread
+///
+/// \a __pk_current_thread holds a pointer to the currently executing
+/// thread. This pointer will be NULL (0) under the following conditions:
+///
+/// - After pk_initialize() but prior to pk_start_threads()
+///
+/// - After pk_start_threads(), when no threads are runnable. In this case
+/// the NULL (0) value indicates that the PK idle thread is 'running'.
+///
+/// - After pk_start_threads(), when the current (non-idle) thread has
+/// completed or been deleted.
+///
+/// If \a __pk_current_thread == 0 then there is no requirement to save any
+/// register state on a context switch, either because the PK idle thread has
+/// no permanent context, or because any thread context on the kernel stack is
+/// associated with a deleted thread.
+///
+/// If \a __pk_current_thread != 0 then \a __pk_current_thread is a pointer
+/// to the currently executing thread. In an interrupt handler \a
+/// pk_current_thread is a pointer to the thread whose context is saved on
+/// the kernel stack.
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkThread* __pk_current_thread;
+
+/// The thread to switch to during the next context switch, or NULL (0).
+///
+/// \a __pk_next_thread is computed by __pk_schedule(). \a
+/// __pk_next_thread holds a pointer to the thread to switch to at the next
+/// context switch. In a thread context the switch happens immediately if \a
+/// __pk_next_thread == 0 or \a __pk_next_thread != \a __pk_current_thread.
+/// In an interrupt context the check happens at the end of processing all
+/// interrupts.
+///
+/// \a __pk_next_thread may be NULL (0) under the following
+/// conditions:
+///
+/// - After pk_initialize() but prior to pk_start_threads(), assuming no
+/// threads have been made runnable.
+///
+/// - After pk_start_threads(), when no threads are runnable. In this case
+/// the NULL (0) value indicates that the PK idle thread is the next thread
+/// to 'run'.
+///
+/// If \a __pk_next_thread == 0 then there is no requirement to restore
+/// any register state on a context switch, because the PK idle thread has
+/// no permanent context.
+///
+/// If \a __pk_next_thread != 0 then \a __pk_next_thread is a pointer
+/// to the thread whose context will be restored at the next context switch.
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkThread* __pk_next_thread;
+
+/// The priority of \a __pk_next_thread
+///
+/// If \a __pk_next_thread == 0, the \a __pk_next_priority == PK_THREADS.
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkThreadPriority __pk_next_priority;
+
+/// This variable holds the default thread machine context for newly created
+/// threads. The idle thread also uses this context. This variable is normally
+/// constant after the call of \c pk_initialize().
+
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkMachineContext __pk_thread_machine_context_default;
+
+
+/// The size of the kernel stack (bytes).
+
+UNLESS__PK_CORE_C__(extern)
+volatile
+size_t __pk_kernel_stack_size;
+
+/// This table maps priorities to threads, and contains PK_THREADS + 1
+/// entries. The final entry is for the idle thread and will always be null
+/// after initizlization.
+
+UNLESS__PK_CORE_C__(extern)
+volatile
+PkThread* __pk_priority_map[PK_THREADS + 1];
+
+/// The PK time queue structure
+///
+/// This structure is defined for use by the kernel, however applications
+/// could also use this structure to define their own time queues.
+
+typedef struct {
+
+ /// A sentinel node for the time queue.
+ ///
+ /// The time queue is an PkDeque managed as a FIFO queue for queue
+ /// management purpose, although events time out in time order.
+ ///
+ /// This pointer container is defined as the first element of the
+ /// structure to allow the PkTimeQueue to be cast to an PkDeque.
+ PkDeque queue;
+
+ /// The next timeout in absolute time.
+ PkTimebase next_timeout;
+
+ /// A pointer to allow preemption of time queue processing
+ ///
+ /// If non-0, then this is the next timer in the time queue to handle, or
+ /// a pointer to the \a queue object indicating no more timers to handle.
+ ///
+ /// \a cursor != 0 implies that time queue handler is in the midst of
+ /// processing the time queue, but has enabled interrupt preemption for
+ /// processing a timer handler. This means that 1) if the timer pointed to
+ /// by \a cursor is deleted then the cursor must be assigned to the
+ /// next timer in the queue; and 2) if a new timer is scheduled then
+ /// activating the next timeout will be handled by the timer handler.
+ PkDeque* cursor;
+
+} PkTimeQueue;
+
+UNLESS__PK_CORE_C__(extern)
+PkTimeQueue __pk_time_queue;
+
+/// Return a pointer to the PkThread object of the currently running thread,
+/// or NULL (0) if PK is idle or has not been started.
+///
+/// In this API the current thread is not volatile - it will never change
+/// inside application code - thus the 'volatile' is cast away. The PK kernel
+/// does not (must not) use this API.
+
+UNLESS__PK_CORE_C__(extern)
+inline PkThread *
+pk_current(void)
+{
+ return (PkThread *)__pk_current_thread;
+}
+
+/// Schedule the next timeout in a machine-specific way.
+
+void
+__pk_schedule_hardware_timeout(PkTimebase timeout);
+
+/// The thread timeout handler. Portable.
+
+PK_TIMER_CALLBACK(__pk_thread_timeout);
+
+/// Generic stack initialization. Portable.
+
+int
+__pk_stack_init(PkAddress *stack,
+ size_t *size);
+
+/// Machine-specific thread context initialization.
+
+void
+__pk_thread_context_initialize(PkThread *thread,
+ PkThreadRoutine thread_routine,
+ void *arg);
+
+/// Machine specific resumption of __pk_next_thread at __pk_next_priority
+/// without saving the current context.
+void
+__pk_next_thread_resume(void);
+
+/// Schedule a timer in the time queue. Portable.
+void
+__pk_timer_schedule(PkTimer *timer);
+
+/// Remove a timer from the time queue. Portable.
+int
+__pk_timer_cancel(PkTimer *timer);
+
+void
+__pk_schedule(void);
+
+
+// Call the application main(). Portable.
+
+void
+__pk_main(int argc, char **argv);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PK_KERNEL_H__ */
diff --git a/src/ppe/pk/kernel/pk_macros.h b/src/ppe/pk/kernel/pk_macros.h
new file mode 100644
index 0000000..0bff22b
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_macros.h
@@ -0,0 +1,134 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_macros.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_MACROS_H__
+#define __PK_MACROS_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_macros.h
+/// \brief Boilerplate macros for PK
+
+/// This macro encapsulates error handling boilerplate for code that uses the
+/// PK API-type error handling, for errors that do not occur in critical
+/// sections.
+
+#define PK_ERROR(code) \
+ do { \
+ if (PK_ERROR_PANIC) { \
+ PK_PANIC(code); \
+ } else { \
+ return -(code); \
+ } \
+ } while (0)
+
+
+/// This macro encapsulates error handling boilerplate in the PK API
+/// functions, for errors that do not occur in critical sections.
+
+#define PK_ERROR_IF(condition, code) \
+ do { \
+ if (condition) { \
+ PK_ERROR(code); \
+ } \
+ } while (0)
+
+
+/// This macro encapsulates error handling boilerplate in the PK API
+/// functions, for errors that do not occur in critical sections and always
+/// force a kernel panic, indicating a kernel or API bug.
+
+#define PK_PANIC_IF(condition, code) \
+ do { \
+ if (condition) { \
+ PK_PANIC(code); \
+ } \
+ } while (0)
+
+
+/// This macro encapsulates error handling boilerplate in the PK API
+/// functions, for errors that do not occur in critical sections.
+/// The error handling will only be enabled when PK_ERROR_CHECK_API
+/// is enabled.
+
+#define PK_ERROR_IF_CHECK_API(condition, code) \
+ do { \
+ if (PK_ERROR_CHECK_API) { \
+ PK_ERROR_IF(condition, code); \
+ } \
+ } while (0)
+
+/// This macro encapsulates error handling boilerplate in the PK API
+/// functions, for errors that occur in critical sections.
+
+#define PK_ERROR_IF_CRITICAL(condition, code, context) \
+ do { \
+ if (condition) { \
+ if (PK_ERROR_PANIC) { \
+ PK_PANIC(code); \
+ pk_critical_section_exit(context); \
+ } else { \
+ pk_critical_section_exit(context); \
+ return -(code); \
+ } \
+ } \
+ } while (0)
+
+
+/// This is a general macro for errors that require cleanup before returning
+/// the error code.
+
+#define PK_ERROR_IF_CLEANUP(condition, code, cleanup) \
+ do { \
+ if (condition) { \
+ if (PK_ERROR_PANIC) { \
+ PK_PANIC(code); \
+ cleanup; \
+ } else { \
+ cleanup; \
+ return -(code); \
+ } \
+ } \
+ } while (0)
+
+
+
+/// Some PK APIs can only be called from thread contexts - these are APIs
+/// that threads call on 'themselves'.
+
+#define PK_ERROR_UNLESS_THREAD_CONTEXT() \
+ PK_ERROR_IF(!__pk_kernel_context_thread(), \
+ PK_ILLEGAL_CONTEXT_THREAD_CONTEXT)
+
+
+/// Some PK APIs must be called from an interrupt context only.
+
+#define PK_ERROR_UNLESS_ANY_INTERRUPT_CONTEXT() \
+ PK_ERROR_IF(!__pk_kernel_context_any_interrupt(), \
+ PK_ILLEGAL_CONTEXT_INTERRUPT_CONTEXT)
+
+#endif /* __PK_MACROS_H__ */
diff --git a/src/ppe/pk/kernel/pk_semaphore_core.c b/src/ppe/pk/kernel/pk_semaphore_core.c
new file mode 100644
index 0000000..fd47106
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_semaphore_core.c
@@ -0,0 +1,342 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_semaphore_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_semaphore_core.c
+/// \brief PK semaphore APIs
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present at runtime in any PK application that enables
+/// semaphores.
+
+#include "pk.h"
+
+/// Post a count to a semaphore
+///
+/// \param semaphore A pointer to the semaphore
+///
+/// If any thread is pending on the semaphore, the highest priority thread
+/// will be made runnable and the internal count will remain 0.
+///
+/// If no thread is pending on the semaphore then the internal count will be
+/// incremented by 1, with overflow wrapping the internal count through 0. If
+/// the \a max_count argument supplied when the semaphore was created is
+/// non-zero and the new internal count is greater than the \a max_count, an
+/// overflow error will be signalled.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_SEMAPHORE_AT_POST The \a semaphore is a null (0) pointer.
+///
+/// \retval -PK_SEMAPHORE_OVERFLOW The \a max_count argument supplied when
+/// the semaphore was created is non-zero and the new internal count is
+/// greater than the \a max_count.
+
+int
+pk_semaphore_post(PkSemaphore *semaphore)
+{
+ PkMachineContext ctx;
+ PkThreadPriority priority;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_POST);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ priority = __pk_thread_queue_min(&(semaphore->pending_threads));
+
+ if (priority != PK_IDLE_THREAD_PRIORITY) {
+
+ __pk_thread_queue_delete(&(semaphore->pending_threads), priority);
+ __pk_thread_queue_insert(&__pk_run_queue, priority);
+
+ PK_KERN_TRACE("THREAD_SEMAPHORE_POST(%d)", priority);
+
+ __pk_schedule();
+
+ } else {
+
+ semaphore->count++;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF((semaphore->max_count > 0) &&
+ (semaphore->count > semaphore->max_count),
+ PK_SEMAPHORE_OVERFLOW);
+ }
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// Pend on a semaphore with timeout
+///
+/// \param semaphore A pointer to the semaphore
+///
+/// \param timeout A relative timeout in PK timebase ticks, including the
+/// special values PK_NO_WAIT and PK_WAIT_FOREVER
+///
+/// This API is normally called from threads, and can only be successfully
+/// called from interupt handlers under special conditions.
+///
+/// If the internal count of the \a semaphore is non-zero, the internal count
+/// is decremented by one and execution of the caller continues.
+///
+/// If the internal count of the \a semaphore is zero and the \a timeout is
+/// PK_NO_WAIT (0) then the call returns immediately with the informational
+/// code -PK_SEMAPHORE_PEND_NO_WAIT.
+///
+/// If the internal count of the \a semaphore is zero and the \a timeout is
+/// non-zero then a thread will block until either a semaphore count is
+/// acquired or the relative timeout expires. If this condition occurs in a
+/// call from an interrupt context or before threads have been started then
+/// the call will fail with the error \c -PK_SEMAPHORE_PEND_WOULD_BLOCK.
+///
+/// Once timed out the thread is removed from the semaphore pending queue and
+/// made runnable, and the pk_semaphore_pend() operation will fail, even if
+/// the semaphore count becomes available before the thread runs again. The
+/// pk_semaphore_pend() API returns the informational code
+/// -PK_SEMAPHORE_PEND_TIMED_OUT in this case.
+///
+/// By convention, a timeout interval equal to the maximum possible value of
+/// the \c PkInterval type is taken to mean "wait forever". A thread blocked
+/// on a semaphore in this mode will never time out. PK provides this
+/// constant as \c PK_WAIT_FOREVER.
+///
+/// Return values other than PK_OK (0) are not necessarily errors; see \ref
+/// pk_errors
+///
+/// The following return codes are non-error codes:
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_SEMAPHORE_PEND_NO_WAIT timeout is set to PK_NO_WAIT
+///
+/// \retval -PK_SEMAPHORE_PEND_TIMED_OUT The semaphore was not acquired
+/// before the timeout expired.
+///
+/// The following return codes are error codes:
+///
+/// \retval -PK_INVALID_SEMAPHORE_AT_PEND The \a semaphore is a null (0)
+/// pointer.
+///
+/// \retval -PK_SEMAPHORE_PEND_WOULD_BLOCK The call was made from an
+/// interrupt context (or before threads have been started), the semaphore
+/// internal count was 0 and a non-zero timeout was specified.
+
+// Note: Casting __pk_current_thread removes the 'volatile' attribute.
+
+int
+pk_semaphore_pend(PkSemaphore *semaphore,
+ PkInterval timeout)
+{
+ PkMachineContext ctx;
+ PkThreadPriority priority;
+ PkThread *thread;
+ PkTimer *timer = 0;
+ PkInterval scaled_timeout = PK_INTERVAL_SCALE(timeout);
+
+ int rc = PK_OK;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_PEND);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ if (semaphore->count != 0) {
+
+ semaphore->count--;
+
+ } else if (timeout == PK_NO_WAIT) {
+
+ rc = -PK_SEMAPHORE_PEND_NO_WAIT;
+
+ } else {
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF_CRITICAL(!__pk_kernel_context_thread(),
+ PK_SEMAPHORE_PEND_WOULD_BLOCK,
+ &ctx);
+ }
+
+ thread = (PkThread *)__pk_current_thread;
+ priority = thread->priority;
+
+ __pk_thread_queue_insert(&(semaphore->pending_threads), priority);
+
+ thread->semaphore = semaphore;
+ thread->flags |= PK_THREAD_FLAG_SEMAPHORE_PEND;
+
+ PK_KERN_TRACE("THREAD_SEMAPHORE_PEND(%d)", priority);
+
+ if (timeout != PK_WAIT_FOREVER) {
+ timer = &(thread->timer);
+ timer->timeout = pk_timebase_get() + scaled_timeout;
+ __pk_timer_schedule(timer);
+ thread->flags |= PK_THREAD_FLAG_TIMER_PEND;
+ }
+
+ __pk_thread_queue_delete(&__pk_run_queue, priority);
+ __pk_schedule();
+
+ thread->flags &= ~PK_THREAD_FLAG_SEMAPHORE_PEND;
+
+ if (thread->flags & PK_THREAD_FLAG_TIMER_PEND) {
+ if (thread->flags & PK_THREAD_FLAG_TIMED_OUT) {
+ rc = -PK_SEMAPHORE_PEND_TIMED_OUT;
+ __pk_thread_queue_delete(&(semaphore->pending_threads), thread->priority);
+ } else {
+ __pk_timer_cancel(timer);
+ }
+ thread->flags &=
+ ~(PK_THREAD_FLAG_TIMER_PEND | PK_THREAD_FLAG_TIMED_OUT);
+ }
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return rc;
+}
+
+
+/// Release all threads blocked on a semaphore
+///
+/// \param semaphore A pointer to a semaphore
+///
+/// This API is provided to allow an PK semaphore to be used as a thread
+/// barrier. pk_semaphore_release_all() simultaneously unblocks all threads
+/// (if any) currently pending on a semaphore. A semaphore to be used as a
+/// thread barrier will typically be initialized with
+/// pk_semaphore_create(\a sem, 0, 0), and sxx_semaphore_post() would never be
+/// called on the \a sem.
+///
+/// This API never modifies the \a count field of the semaphore; If any
+/// threads are blocked on a semaphore the semaphore count is 0 by definition.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_SEMAPHORE_AT_RELEASE The \a semaphore is a null (0)
+/// pointer.
+
+int
+pk_semaphore_release_all(PkSemaphore* semaphore)
+{
+ PkMachineContext ctx;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_RELEASE);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ __pk_thread_queue_union(&__pk_run_queue, &(semaphore->pending_threads));
+ __pk_thread_queue_clear(&(semaphore->pending_threads));
+ __pk_schedule();
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// Get information about a semaphore.
+///
+/// \param semaphore A pointer to the PkSemaphore to query
+///
+/// \param count The value returned through this pointer is the current count
+/// of the semaphore. The caller can set this parameter to the null pointer
+/// (0) if this information is not required.
+///
+/// \param pending The value returned through this pointer is the current
+/// number of threads pending on the semaphore. The caller can set this
+/// parameter to the null pointer (0) if this information is not required.
+///
+/// The information returned by this API can only be guaranteed consistent if
+/// the API is called from a critical section.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_SEMAPHORE_AT_INFO The \a semaphore is a null (0)
+/// pointer.
+
+int
+pk_semaphore_info_get(PkSemaphore* semaphore,
+ PkSemaphoreCount* count,
+ int* pending)
+
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_INFO);
+ }
+
+ if (count) {
+ *count = semaphore->count;
+ }
+ if (pending) {
+ *pending = __pk_thread_queue_count(&(semaphore->pending_threads));
+ }
+
+ return PK_OK;
+}
+
+
+/// An simple interrupt handler that posts to a semaphore.
+///
+/// To implement basic event-driven blocking of a thread, install
+/// pk_semaphore_post_handler() as the handler for an interrupt
+/// and provide a pointer to the semaphore as the \a arg argument in
+/// pk_irq_handler_set(). The semaphore should be initialized with
+/// pk_semaphore_create(&sem, 0, 1). This handler simply disables (masks)
+/// the interrupt, clears the status and calls pk_semaphore_post() on the
+/// semaphore.
+///
+/// Note that clearing the status in the interrupt controller as done here is
+/// effectively a no-op for level-sensitive interrupts. In the level-sensitive
+/// case any thread pending on the semaphore must reset the interrupt
+/// condition in the device before re-enabling the interrupt.
+#if 0
+void
+pk_semaphore_post_handler(void *arg, PkIrqId irq, int priority)
+{
+ pk_irq_disable(irq);
+ pk_irq_status_clear(irq);
+ pk_semaphore_post((PkSemaphore *)arg);
+}
+
+#endif
diff --git a/src/ppe/pk/kernel/pk_semaphore_init.c b/src/ppe/pk/kernel/pk_semaphore_init.c
new file mode 100644
index 0000000..aea00f6
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_semaphore_init.c
@@ -0,0 +1,106 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_semaphore_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_semaphore_init.c
+/// \brief PK semaphore API initialization routines
+///
+/// The entry points in this file are routines that are typically used during
+/// initialization, and their code space could be deallocated and recovered if
+/// no longer needed by the application after initialization.
+
+#include "pk.h"
+
+/// Create (initialize) a semaphore
+///
+/// \param semaphore A pointer to an PkSemaphore structure to initialize
+///
+/// \param initial_count The initial count of the semaphore
+///
+/// \param max_count The maximum count allowed in the semaphore, for error
+/// checking
+///
+/// Semaphores are created (initialized) by a call of \c
+/// pk_semaphore_create(), using an application-provided instance of an \c
+/// PkSemaphore structure. This structure \e is the semaphore, so the
+/// application must never modify the structure if the semaphore is in use.
+/// PK has no way to know if an \c PkSemaphore structure provided to
+/// \c pk_semaphore_create() is safe to use as a semaphore, and will silently
+/// modify whatever memory is provided.
+///
+/// PK provides two simple overflow semantics based on the value of max_count
+/// in the call of \c pk_semaphore_create().
+///
+/// If \a max_count = 0, then posting to the semaphore first increments the
+/// internal count by 1. Overflows are ignored and will wrap the internal
+/// count through 0.
+///
+/// If \a max_count != 0, then posting to the semaphore first increments the
+/// internal count by 1, wrapping through 0 in the event of overflow. If the
+/// resulting count is greater than max_count, \c pk_semaphore_post() will
+/// return the error \c -PK_SEMAPHORE_POST_OVERFLOW to the caller.
+///
+/// In most applications it is probably best to use the \a max_count != 0
+/// semantics to trap programming errors, unless there is a specific
+/// application where overflow is expected and ignorable. As a fine point of
+/// the specification, a \a max_count of 0 is equivalent to a max_count of
+/// 0xFFFFFFFF.
+///
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_SEMAPHORE_AT_CREATE The \a semaphore is a null (0)
+/// pointer.
+///
+/// \retval -PK_INVALID_ARGUMENT_SEMAPHORE The \a max_count is non-zero
+/// and less than the \a initial_count.
+
+int
+pk_semaphore_create(PkSemaphore *semaphore,
+ PkSemaphoreCount initial_count,
+ PkSemaphoreCount max_count)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_CREATE);
+ PK_ERROR_IF((max_count != 0) && (initial_count > max_count),
+ PK_INVALID_ARGUMENT_SEMAPHORE);
+ }
+
+ __pk_thread_queue_clear(&(semaphore->pending_threads));
+ semaphore->count = initial_count;
+ semaphore->max_count = max_count;
+
+ return PK_OK;
+}
+
+
+
+
+
diff --git a/src/ppe/pk/kernel/pk_stack_init.c b/src/ppe/pk/kernel/pk_stack_init.c
new file mode 100644
index 0000000..4cfc260
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_stack_init.c
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_stack_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_stack_init.c
+/// \brief PK stack initialization
+///
+/// The entry points in this file are initialization routines - they are never
+/// needed after PK initialization and their code space could be reclaimed by
+/// the application after initialization if required.
+///
+/// This code was split out from "pk_init.c" because it may be needed in a
+/// thread configuration if threads are being created dynamically. in an
+/// interrupt-only configuration it is not needed after \c pk_initialize().
+
+#include "pk.h"
+
+/// Initialize a stack area.
+///
+/// \param stack A pointer to the smallest legal address of the stack. The
+/// stack address is modified as the stack is aligned and initialized.
+///
+/// \param size A pointer to the size of the stack (in bytes). The size is
+/// modified as the stack is aligned and initialized. At exit this is the
+/// final usable stack area size aligned to the size of the PK_STACK_TYPE.
+///
+/// PK makes no assumptions about size or alignment of the area provided as a
+/// stack, and carefully aligns and initializes the stack. Regardless of how
+/// the stack grows, the \a stack parameter is considered to be the lowest
+/// legal address of the stack.
+
+int
+__pk_stack_init(PkAddress *stack,
+ size_t *size)
+{
+ PkAddress mask;
+ size_t excess, i, count;
+ PK_STACK_TYPE *p;
+
+ if (PK_STACK_DIRECTION < 0) {
+
+ // Stacks grow down. The initial stack pointer is set to just above
+ // the last allocated stack address. This is legal for pre-decrement
+ // stacks, otherwise the initial address is first brought into range
+ // before alignment. The stack is aligned downward, then the size is
+ // adjusted to a multiple of the stack type. Stacks are optionally
+ // prepatterned. Alignment is assumed to be a power of 2.
+
+ *stack += *size;
+
+ if (!PK_STACK_PRE_DECREMENT) {
+ *stack -= sizeof(PK_STACK_TYPE);
+ *size -= sizeof(PK_STACK_TYPE);
+ }
+
+ mask = PK_STACK_ALIGNMENT - 1;
+ excess = *stack & mask;
+ *stack -= excess;
+ *size -= excess;
+ *size = (*size / sizeof(PK_STACK_TYPE)) * sizeof(PK_STACK_TYPE);
+
+ if (PK_STACK_CHECK) {
+ p = (PK_STACK_TYPE *)(*stack);
+ count = *size / sizeof(PK_STACK_TYPE);
+ for (i = 0; i < count; i++) {
+ if (PK_STACK_PRE_DECREMENT) {
+ *(--p) = PK_STACK_PATTERN;
+ } else {
+ *(p--) = PK_STACK_PATTERN;
+ }
+ }
+ }
+
+ __pk_stack_create_initial_frame(stack, size);
+
+ } else {
+
+ PK_PANIC(PK_UNIMPLEMENTED);
+ }
+
+ return PK_OK;
+}
+
diff --git a/src/ppe/pk/kernel/pk_thread.h b/src/ppe/pk/kernel/pk_thread.h
new file mode 100644
index 0000000..4848650
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_thread.h
@@ -0,0 +1,80 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_thread.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_THREAD_H__
+#define __PK_THREAD_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_thread.h
+/// \brief Contains private declarations and definitions needed for threads
+///
+
+void
+__pk_thread_map(PkThread* thread);
+
+void
+__pk_thread_unmap(PkThread *thread);
+
+
+// Interrupts must be disabled at entry.
+
+static inline int
+__pk_thread_is_active(PkThread *thread)
+{
+ return ((thread->state != PK_THREAD_STATE_COMPLETED) &&
+ (thread->state != PK_THREAD_STATE_DELETED));
+}
+
+
+// Interrupts must be disabled at entry.
+
+static inline int
+__pk_thread_is_mapped(PkThread *thread)
+{
+ return (thread->state == PK_THREAD_STATE_MAPPED);
+}
+
+
+// Interrupts must be disabled at entry. This is only called on mapped threads.
+
+static inline int
+__pk_thread_is_runnable(PkThread *thread)
+{
+ return __pk_thread_queue_member(&__pk_run_queue, thread->priority);
+}
+
+
+// Interrupts must be disabled at entry.
+
+static inline PkThread*
+__pk_thread_at_priority(PkThreadPriority priority)
+{
+ return (PkThread*)__pk_priority_map[priority];
+}
+
+#endif /* __PK_THREAD_H__ */
diff --git a/src/ppe/pk/kernel/pk_thread_core.c b/src/ppe/pk/kernel/pk_thread_core.c
new file mode 100644
index 0000000..06a2e1b
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_thread_core.c
@@ -0,0 +1,597 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_thread_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_thread_core.c
+/// \brief PK thread APIs
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present at runtime in any PK application that enables threads.
+
+#include "pk.h"
+#include "pk_thread.h"
+
+#define __PK_THREAD_CORE_C__
+
+
+// This routine is only used locally. Interrupts must be disabled
+// at entry. The caller must also have checked that the priority is free.
+// This routine is only called on threads known to be in a suspended state,
+// either PK_THREAD_STATE_SUSPENDED_RUNNABLE or
+// PK_THREAD_STATE_SUSPENDED_BLOCKED. Mapping a runnable thread adds it to
+// the run queue. Mapping a thread pending on a semaphore either takes the
+// count and becomes runnable or adds the thread to the pending queue for the
+// semaphore. Mapping a sleeping thread requires no further action
+// here. Scheduling after the map must be handled by the caller.
+
+void
+__pk_thread_map(PkThread* thread)
+{
+ PkThreadPriority priority;
+
+ priority = thread->priority;
+ __pk_priority_map[priority] = thread;
+
+ if (thread->state == PK_THREAD_STATE_SUSPENDED_RUNNABLE) {
+
+ __pk_thread_queue_insert(&__pk_run_queue, priority);
+
+ } else if (thread->flags & PK_THREAD_FLAG_SEMAPHORE_PEND) {
+
+ if (thread->semaphore->count) {
+
+ thread->semaphore->count--;
+ __pk_thread_queue_insert(&__pk_run_queue, priority);
+
+ } else {
+
+ __pk_thread_queue_insert(&(thread->semaphore->pending_threads),
+ priority);
+ }
+ }
+
+ thread->state = PK_THREAD_STATE_MAPPED;
+
+ if (PK_KERNEL_TRACE_ENABLE) {
+ if (__pk_thread_is_runnable(thread)) {
+ PK_KERN_TRACE("THREAD_MAPPED_RUNNABLE(%d)", priority);
+ } else if (thread->flags & PK_THREAD_FLAG_SEMAPHORE_PEND) {
+ PK_KERN_TRACE("THREAD_MAPPED_SEMAPHORE_PEND(%d)", priority);
+ } else {
+ PK_KERN_TRACE("THREAD_MAPPED_SLEEPING(%d)", priority);
+ }
+ }
+}
+
+
+// This routine is only used locally. Interrupts must be disabled
+// at entry. This routine is only ever called on threads in the
+// PK_THREAD_STATE_MAPPED. Unmapping a thread removes it from the priority
+// map, the run queue and any semaphore pend, but does not cancel any
+// timers. Scheduling must be handled by the code calling
+// __pk_thread_unmap().
+
+void
+__pk_thread_unmap(PkThread *thread)
+{
+ PkThreadPriority priority;
+
+ priority = thread->priority;
+ __pk_priority_map[priority] = 0;
+
+ if (__pk_thread_is_runnable(thread)) {
+
+ thread->state = PK_THREAD_STATE_SUSPENDED_RUNNABLE;
+ __pk_thread_queue_delete(&__pk_run_queue, priority);
+
+ } else {
+
+ thread->state = PK_THREAD_STATE_SUSPENDED_BLOCKED;
+ if (thread->flags & PK_THREAD_FLAG_SEMAPHORE_PEND) {
+ __pk_thread_queue_delete(&(thread->semaphore->pending_threads),
+ priority);
+ }
+ }
+}
+
+
+// Schedule and run the highest-priority mapped runnable thread.
+//
+// The priority of the next thread to run is first computed. This may be
+// PK_THREADS, indicating that the only thread to run is the idle thread.
+// This will always cause (or defer) a 'context switch' to the idle thread.
+// Otherwise, if the new thread is not equal to the current thread this will
+// also cause (or defer) a context switch. Note that scheduling is defined in
+// terms of priorities but actually implemented in terms of PkThread pointers.
+//
+// If we are not yet in thread mode we're done - threads will be started by
+// pk_start_threads() later. If we're in thread context a context switch
+// happens immediately. In an interrupt context the switch is deferred to the
+// end of interrupt processing.
+
+void
+__pk_schedule(void)
+{
+ __pk_next_priority = __pk_thread_queue_min(&__pk_run_queue);
+ __pk_next_thread = __pk_priority_map[__pk_next_priority];
+
+ if ((__pk_next_thread == 0) ||
+ (__pk_next_thread != __pk_current_thread)) {
+
+ if (__pk_kernel_mode_thread()) {
+ if (__pk_kernel_context_thread()) {
+ if (__pk_current_thread != 0) {
+ __pk_switch();
+ } else {
+ __pk_next_thread_resume();
+ }
+ } else {
+ __pk_delayed_switch = 1;
+ }
+ }
+ }
+}
+
+
+// This routine is only used locally.
+//
+// Completion and deletion are pretty much the same thing. Completion is
+// simply self-deletion of the current thread (which is mapped by
+// definition.) The complete/delete APIs have slightly different error
+// conditions but are otherwise the same.
+//
+// Deleting a mapped thread first unmaps (suspends) the thread, which takes
+// care of removing the thread from any semaphores it may be pending on. Then
+// any outstanding timer is also cancelled.
+//
+// If the current thread is being deleted we install the idle thread as
+// __pk_current_thread, so scheduling is forced and no context is saved on
+// the context switch.
+//
+// Note that we do not create trace events for unmapped threads since the trace
+// tag only encodes the priority, which may be in use by a mapped thread.
+
+void
+__pk_thread_delete(PkThread *thread, PkThreadState final_state)
+{
+ PkMachineContext ctx;
+ int mapped;
+
+ pk_critical_section_enter(&ctx);
+
+ mapped = __pk_thread_is_mapped(thread);
+
+ if (mapped) {
+ __pk_thread_unmap(thread);
+ }
+
+ __pk_timer_cancel(&(thread->timer));
+ thread->state = final_state;
+
+ if (mapped) {
+
+ if (PK_KERNEL_TRACE_ENABLE) {
+ if (final_state == PK_THREAD_STATE_DELETED) {
+ PK_KERN_TRACE("THREAD_DELETED(%d)", thread->priority);
+ } else {
+ PK_KERN_TRACE("THREAD_COMPLETED(%d)", thread->priority);
+ }
+ }
+
+ if (thread == __pk_current_thread) {
+ __pk_current_thread = 0;
+ }
+ __pk_schedule();
+ }
+
+ pk_critical_section_exit(&ctx);
+}
+
+
+// Generic thread timeout
+//
+// This routine is called as a timer callback either because a sleeping thread
+// has timed out or a thread pending on a semaphore has timed out. If the
+// thread is not already runnable then the the timeout flag is set, and if the
+// thread is mapped it is scheduled.
+//
+// This implementation allows that a thread blocked on a timer may have been
+// made runnable by some other mechanism, such as acquiring a semaphore. In
+// order to provide an iteration-free implementation of
+// pk_semaphore_release_all(), cancelling any semaphore timeouts is deferred
+// until the thread runs again.
+//
+// Note that we do not create trace events for unmapped threads since the trace
+// tag only encodes the priority, which may be in use by a mapped thread.
+
+void
+__pk_thread_timeout(void *arg)
+{
+ PkMachineContext ctx;
+ PkThread *thread = (PkThread *)arg;
+
+ pk_critical_section_enter(&ctx);
+
+ switch (thread->state) {
+
+ case PK_THREAD_STATE_MAPPED:
+ if (!__pk_thread_is_runnable(thread)) {
+ thread->flags |= PK_THREAD_FLAG_TIMED_OUT;
+ __pk_thread_queue_insert(&__pk_run_queue, thread->priority);
+ __pk_schedule();
+ }
+ break;
+
+ case PK_THREAD_STATE_SUSPENDED_RUNNABLE:
+ break;
+
+ case PK_THREAD_STATE_SUSPENDED_BLOCKED:
+ thread->flags |= PK_THREAD_FLAG_TIMED_OUT;
+ thread->state = PK_THREAD_STATE_SUSPENDED_RUNNABLE;
+ break;
+
+ default:
+ PK_PANIC(PK_THREAD_TIMEOUT_STATE);
+ }
+
+ pk_critical_section_exit(&ctx);
+}
+
+
+// This routine serves as a container for the PK_START_THREADS_HOOK and
+// actually starts threads. The helper routine __pk_call_pk_start_threads()
+// arranges this routine to be called with interrupts disabled while running
+// on the kernel stack.
+//
+// The reason for this roundabout is that we want to be able to run a hook
+// routine (transparent to the application) that can hand over every last byte
+// of free memory to "malloc()" - including the stack of main(). Since we
+// always need to run on some stack, we chose to run the hook on the kernel
+// stack. However to do this safely we need to make sure
+// that no interrupts will happen during this time. When __pk_thread_resume()
+// is finally called all stack-based context is lost but it doesn't matter at
+// that point - it's a one-way street into thread execution.
+//
+// This is considered part of pk_start_threads() and so is also considered a
+// 'core' routine.
+
+void
+__pk_start_threads(void)
+{
+ PK_START_THREADS_HOOK;
+
+ __pk_next_thread_resume();
+
+ PK_PANIC(PK_START_THREADS_RETURNED);
+}
+
+
+/// Start PK threads
+///
+/// This routine starts the PK thread scheduler infrastructure. This routine
+/// must be called after a call of \c pk_initialize(). This routine never
+/// returns. Interrupt (+ timer) only configurations of PK need not call this
+/// routine.
+///
+/// Note: This tiny routine is considered a 'core' routine so that the
+/// initialziation code can safely recover all 'init' code space before
+/// starting threads.
+///
+/// This routine typically does not return - any return value indicates an
+/// error; see \ref pk_errors
+///
+/// \retval -PK_ILLEGAL_CONTEXT_THREAD The API was called twice.
+
+int
+pk_start_threads(void)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(__pk_kernel_mode_thread(), PK_ILLEGAL_CONTEXT_THREAD);
+ }
+
+ __pk_call_pk_start_threads();
+
+ return 0;
+}
+
+
+/// Resume a suspended thread
+///
+/// \param thread The thread to resume
+///
+/// PK only allows one thread at a time to run at a given priority, and
+/// implements the notion of a thread \e claiming a priority. A suspended
+/// thread claims a priority when it is mapped by a call of
+/// pk_thread_resume(). This API will succeed only if no other active thread
+/// is currently mapped at the priority assigned to the thread. PK provides
+/// the pk_thread_at_priority() API which allows an application-level
+/// scheduler to correctly manage multiple threads running at the same
+/// priority.
+///
+/// If the thread was sleeping while suspended it remains asleep. However if
+/// the sleep timer timed out while the thread was suspended it will be
+/// resumed runnable.
+///
+/// If the thread was blocked on a semaphore when it was suspended, then when
+/// the thread is resumed it will attempt to reacquire the semaphore.
+/// However, if the thread was blocked on a semaphore with timeout while
+/// suspended and the timeout interval has passed, the thread will be resumed
+/// runnable and see that the semaphore pend timed out.
+///
+/// It is not an error to call pk_thread_resume() on a mapped
+/// thread. However it is an error to call pk_thread_resume() on a completed
+/// or deleted thread.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion, including calls on a \a thread that is
+/// already mapped.
+///
+/// \retval -PK_INVALID_THREAD_AT_RESUME1 The \a thread is a null (0) pointer.
+///
+/// \retval -PK_INVALID_THREAD_AT_RESUME2 The \a thread is not active,
+/// i.e. has completed or been deleted.
+///
+/// \retval -PK_PRIORITY_IN_USE_AT_RESUME Another thread is already mapped at
+/// the priority of the \a thread.
+
+int
+pk_thread_resume(PkThread *thread)
+{
+ PkMachineContext ctx;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_RESUME1);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF_CRITICAL(!__pk_thread_is_active(thread),
+ PK_INVALID_THREAD_AT_RESUME2,
+ &ctx);
+ }
+
+ if (!__pk_thread_is_mapped(thread)) {
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF_CRITICAL(__pk_priority_map[thread->priority] != 0,
+ PK_PRIORITY_IN_USE_AT_RESUME,
+ &ctx);
+ }
+ __pk_thread_map(thread);
+ __pk_schedule();
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// Suspend a thread
+///
+/// Any active thread can be suspended. A suspended thread 1) remains active
+/// but will not be scheduled; 2) relinquishes its priority assignment,
+/// allowing another thread to be resumed at the suspended thread's priority;
+/// and 3) disassociates from any semaphore mutual exclusion it may have been
+/// participating in.
+///
+/// If a sleeping thread is suspended, the sleep timer remains active but a
+/// timeout of the timer simply marks the thread as runnable, but does not
+/// resume the thread.
+///
+/// If a thread blocked on a semaphore is suspended, the thread no longer
+/// participates in the semaphore mutual exclusion. If the thread is later
+/// resumed it will attempt to acquire the semaphore again the next time it
+/// runs (unless it was blocked with a timeout and the timeout has expired).
+///
+/// If a thread blocked on a semaphore with timeout is suspended, the
+/// semaphore timeout timer continues to run. If the timer times out while the
+/// thread is suspended the thread is simply marked runnable. If the thread is
+/// later resumed, the suspended call of \c pk_semaphore_pend() will return the
+/// timeout code -PK_SEMAPHORE_PEND_TIMED_OUT.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion, including calls on a \a thread that is
+/// already suspended.
+///
+/// \retval -PK_INVALID_THREAD_AT_SUSPEND1 The \a thread is a null (0) pointer
+///
+/// \retval -PK_INVALID_THREAD_AT_SUSPEND2 The \a thread is not active,
+/// i.e. has completed or been deleted.
+
+int
+pk_thread_suspend(PkThread *thread)
+{
+ PkMachineContext ctx;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF((thread == 0), PK_INVALID_THREAD_AT_SUSPEND1);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF_CRITICAL(!__pk_thread_is_active(thread),
+ PK_INVALID_THREAD_AT_SUSPEND2,
+ &ctx);
+ }
+
+ if (__pk_thread_is_mapped(thread)) {
+
+ PK_KERN_TRACE("THREAD_SUSPENDED(%d)", thread->priority);
+ __pk_thread_unmap(thread);
+ __pk_schedule();
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// Delete a thread
+///
+/// Any active thread can be deleted. If a thread is deleted it is removed
+/// from the run queue, deleted from the timer queue (if sleeping or blocked
+/// on a semaphore with timeout), and deleted from the semaphore mutual
+/// exclusion if blocked on a semaphore. The thread control block is then
+/// marked as deleted.
+///
+/// Once a thread has completed or been deleted the thread structure and
+/// thread stack areas can be used for other purposes.
+///
+/// \param thread The thread to delete
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors. If a
+/// thread deletes itself this API does not return at all.
+///
+/// \retval 0 Successful completion, including calls on a \a thread that has
+/// completed or had already been deleted.
+///
+///
+/// \retval -PK_INVALID_THREAD_AT_DELETE The \a thread is a null (0) pointer.
+
+int
+pk_thread_delete(PkThread *thread)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_DELETE);
+ }
+
+ __pk_thread_delete(thread, PK_THREAD_STATE_DELETED);
+
+ return PK_OK;
+}
+
+
+/// Complete a thread
+///
+/// If a thread ever returns from the subroutine defining the thread entry
+/// point, the thread is removed from all PK kernel data structures and
+/// marked completed. The thread routine can also use the API pk_complete()
+/// to make this more explicit if desired. PK makes no distinction between
+/// completed and deleted threads, but provides these indications for
+/// the benefit of the application.
+///
+/// Note that this API is only available from the current thread to mark its
+/// own completion.
+///
+/// Once a thread has completed or been deleted the thread structure and
+/// thread stack areas can be used for other purposes.
+///
+/// Any return value indicates an error; see \ref pk_errors. In the event of
+/// a successful completion this API does not return to the caller, which is
+/// always the thread context being completed.
+///
+/// \retval -PK_ILLEGAL_CONTEXT_THREAD The API was not called from a thread
+/// context.
+
+// Note: Casting __pk_current_thread removes the 'volatile' attribute.
+
+int
+pk_complete(void)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_UNLESS_THREAD_CONTEXT();
+ }
+
+ __pk_thread_delete((PkThread *)__pk_current_thread,
+ PK_THREAD_STATE_COMPLETED);
+
+ return PK_OK;
+}
+
+/// Sleep a thread for an interval relative to the current time.
+///
+/// \param interval A time interval relative to the current timebase.
+///
+/// Threads can use this API to sleep for a time relative to the current
+/// timebase. The absolute timeout is \c pk_timebase_get() + \a interval.
+///
+/// Sleeping threads are not scheduled, although they maintain their
+/// priorities. This differs from thread suspension, where the suspended
+/// thread relinquishes its priority. When the sleep timer times out the
+/// thread becomes runnable again, and will run as soon as it becomes the
+/// highest-priority mapped runnable thread.
+///
+/// Sleeping threads may also be later suspended. In this case the Sleep timer
+/// continues to run, and if it times out before the thread is resumed the
+/// thread will be immediately runnable when it is resumed.
+///
+/// See the PK specification for a full discussion of how PK handles
+/// scheduling events at absolute times "in the past". Briefly stated, if the
+/// \a interval is 0 or is so small that the absolute time becomes a "past"
+/// time before the Sleep is actually scheduled, the thread will Sleep for the
+/// briefest possible period supported by the hardware.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion.
+///
+/// \retval -PK_ILLEGAL_CONTEXT_THREAD The API was not called from a thread
+/// context.
+
+int
+pk_sleep(PkInterval interval)
+{
+ PkTimebase time;
+ PkMachineContext ctx;
+ PkThread *current;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_UNLESS_THREAD_CONTEXT();
+ }
+
+ time = pk_timebase_get() + PK_INTERVAL_SCALE(interval);
+
+ pk_critical_section_enter(&ctx);
+
+ current = (PkThread *)__pk_current_thread;
+
+ current->timer.timeout = time;
+ __pk_timer_schedule(&(current->timer));
+
+ current->flags |= PK_THREAD_FLAG_TIMER_PEND;
+
+ PK_KERN_TRACE("THREAD_SLEEP(%d)", current->priority);
+
+ __pk_thread_queue_delete(&__pk_run_queue, current->priority);
+ __pk_schedule();
+
+ current->flags &= ~(PK_THREAD_FLAG_TIMER_PEND | PK_THREAD_FLAG_TIMED_OUT);
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+#undef __PK_THREAD_CORE_C__
diff --git a/src/ppe/pk/kernel/pk_thread_init.c b/src/ppe/pk/kernel/pk_thread_init.c
new file mode 100644
index 0000000..b2c7735
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_thread_init.c
@@ -0,0 +1,158 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_thread_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_thread_init.c
+/// \brief PK thread API initialization routines
+///
+/// The entry points in this file are routines that are typically used during
+/// initialization, and their code space could be deallocated and recovered if
+/// no longer needed by the application after initialization.
+
+#include "pk.h"
+
+/// Create (initialize) a thread
+///
+/// \param thread A pointer to an PkThread structure to initialize
+///
+/// \param thread_routine The subroutine that implements the thread
+///
+/// \param arg Private data to be passed as the argument to the thread
+/// routine when it begins execution
+///
+/// \param stack The stack space of the thread
+///
+/// \param stack_size The size of the stack in bytes
+///
+/// \param priority The initial priority of the thread
+///
+/// The \a thread argument must be a pointer to an uninitialized or completed
+/// or deleted thread. This \c PkThread structure \em is the thread, so this
+/// memory area must not be modified by the application until the thread
+/// completes or is deleted. PK can not tell if an PkThread structure is
+/// currently in use as a thread control block.pk_thread_create() will
+/// silently overwrite an PkThread structure that is currently in use.
+///
+/// The stack area must be large enough to hold the dynamic stack requirements
+/// of the entry point routine, and all subroutines and functions that might
+/// be invoked on any path from the entry point. The stack must also always
+/// be able to hold the thread context in the event the thread is preempted,
+/// plus other critical context. PK aligns stack areas in machine-specific
+/// ways, so that the actual stack area may reduced in size slightly if it is
+/// not already aligned.
+///
+/// Threads are created runnable but unmapped. A newly created thread will
+/// not be eligible to run until a call of pk_thread_resume() targets the
+/// thread.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_THREAD_AT_CREATE The \a thread is a null (0) pointer.
+///
+/// \retval -PK_INVALID_ARGUMENT_THREAD1 the \a thread_routine is null (0)
+///
+/// \retval -PK_INVALID_ARGUMENT_THREAD2 the \a priority is invalid,
+///
+/// \retval -PK_INVALID_ARGUMENT_THREAD3 the stack area wraps around
+/// the end of memory.
+///
+/// \retval -PK_STACK_OVERFLOW The stack area at thread creation is smaller
+/// than the minimum safe size.
+
+int
+pk_thread_create(PkThread *thread,
+ PkThreadRoutine thread_routine,
+ void *arg,
+ PkAddress stack,
+ size_t stack_size,
+ PkThreadPriority priority)
+{
+ int rc;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_CREATE);
+ PK_ERROR_IF((thread_routine == 0) ||
+ (priority >= PK_THREADS),
+ PK_INVALID_ARGUMENT_THREAD1);
+ }
+
+ rc = __pk_stack_init(&stack, &stack_size);
+ if (rc) {
+ return rc;
+ }
+
+ thread->saved_stack_pointer = stack;
+ thread->stack_base = stack;
+
+ if (PK_STACK_DIRECTION < 0) {
+
+ thread->stack_limit = stack - stack_size;
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(thread->stack_limit > thread->stack_base,
+ PK_INVALID_ARGUMENT_THREAD2);
+ }
+
+ } else {
+
+ thread->stack_limit = stack + stack_size;
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(thread->stack_limit < thread->stack_base,
+ PK_INVALID_ARGUMENT_THREAD3);
+ }
+ }
+
+ thread->semaphore = 0;
+ thread->priority = priority;
+ thread->state = PK_THREAD_STATE_SUSPENDED_RUNNABLE;
+ thread->flags = 0;
+
+ pk_timer_create(&(thread->timer),
+ __pk_thread_timeout,
+ (void *)thread);
+
+ __pk_thread_context_initialize(thread, thread_routine, arg);
+
+ return rc;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ppe/pk/kernel/pk_thread_util.c b/src/ppe/pk/kernel/pk_thread_util.c
new file mode 100644
index 0000000..e69d250
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_thread_util.c
@@ -0,0 +1,315 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_thread_util.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_thread_util.c
+/// \brief PK thread utility APIs
+///
+/// The entry points in this file are considered extra routines that will
+/// only be included in a PK application that enables threads and uses at
+/// least one of these interfaces.
+
+#include "pk.h"
+#include "pk_thread.h"
+
+/// Get information about a thread.
+///
+/// \param thread A pointer to the PkThread to query
+///
+/// \param state The value returned through this pointer is the current state
+/// of the thread; See \ref pk_thread_states. The caller can set this
+/// parameter to the null pointer (0) if this information is not required.
+///
+/// \param priority The value returned through this pointer is the current
+/// priority of the thread. The caller can set this parameter to the null
+/// pointer (0) if this information is not required.
+///
+/// \param runnable The value returned through this pointer is 1 if the thread
+/// is in state PK_THREAD_STATE_MAPPED and is currently in the run queue
+/// (i.e., neither blocked on a semaphore nor sleeping), otherwise 0. The
+/// caller can set this parameter to the null pointer (0) if this information
+/// is not required.
+///
+/// The information returned by this API can only be guaranteed consistent if
+/// the API is called from a critical section.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_THREAD_AT_INFO The \a thread is a null (0) pointer.
+
+int
+pk_thread_info_get(PkThread *thread,
+ PkThreadState *state,
+ PkThreadPriority *priority,
+ int *runnable)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_INFO);
+ }
+
+ if (state) {
+ *state = thread->state;
+ }
+ if (priority) {
+ *priority = thread->priority;
+ }
+ if (runnable) {
+ *runnable = ((thread->state == PK_THREAD_STATE_MAPPED) &&
+ __pk_thread_queue_member(&__pk_run_queue,
+ thread->priority));
+ }
+ return PK_OK;
+}
+
+
+/// Change the priority of a thread.
+///
+/// \param thread The thread whose priority will be changed
+///
+/// \param new_priority The new priority of the thread
+///
+/// \param old_priority The value returned through this pointer is the
+/// old priority of the thread prior to the change. The caller can set
+/// this parameter to the null pointer (0) if this information is not
+/// required.
+///
+/// Thread priorities can be changed by the \c pk_thread_priority_change()
+/// API. This call will fail if the thread pointer is invalid or if the thread
+/// is mapped and the new priority is currently in use. The call will succeed
+/// even if the \a thread is suspended, completed or deleted. The
+/// application-level scheduling algorithm is completely responsible for the
+/// correctness of the application in the event of suspended, completed or
+/// deleted threads.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion, including the redundant case of
+/// attempting to change the priority of the thread to its current priority.
+///
+/// \retval -PK_INVALID_THREAD_AT_CHANGE The \a thread is null (0) or
+/// otherwise invalid.
+///
+/// \retval -PK_INVALID_ARGUMENT_THREAD_CHANGE The \a new_priority is invalid.
+///
+/// \retval -PK_PRIORITY_IN_USE_AT_CHANGE The \a thread is mapped and the \a
+/// new_priority is currently in use by another thread.
+
+int
+pk_thread_priority_change(PkThread *thread,
+ PkThreadPriority new_priority,
+ PkThreadPriority *old_priority)
+{
+ PkMachineContext ctx;
+ PkThreadPriority priority;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(thread == 0, PK_INVALID_THREAD_AT_CHANGE);
+ PK_ERROR_IF(new_priority > PK_THREADS,
+ PK_INVALID_ARGUMENT_THREAD_CHANGE);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ priority = thread->priority;
+
+ if (priority != new_priority) {
+
+ if (!__pk_thread_is_mapped(thread)) {
+
+ thread->priority = new_priority;
+
+ } else {
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF_CRITICAL(__pk_priority_map[new_priority] != 0,
+ PK_PRIORITY_IN_USE_AT_CHANGE,
+ &ctx);
+ }
+
+ __pk_thread_unmap(thread);
+ thread->priority = new_priority;
+ __pk_thread_map(thread);
+ __pk_schedule();
+ }
+ }
+
+ if (old_priority) {
+ *old_priority = priority;
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// Return a pointer to the thread (if any) mapped at a given priority.
+///
+/// \param priority The thread priority of interest
+///
+/// \param thread The value returned through this pointer is a pointer to the
+/// thread currently mapped at the given priority level. If no thread is
+/// mapped, or if the \a priority is the priority of the idle thread, the
+/// pointer returned will be null (0).
+///
+/// The information returned by this API can only be guaranteed consistent if
+/// the API is called from a critical section.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion.
+///
+/// \retval -PK_INVALID_ARGUMENT_THREAD_PRIORITY The \a priority is invalid
+/// or the \a thread parameter is null (0).
+
+int
+pk_thread_at_priority(PkThreadPriority priority,
+ PkThread **thread)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF((priority > PK_THREADS) || (thread == 0),
+ PK_INVALID_ARGUMENT_THREAD_PRIORITY);
+ }
+
+ *thread = __pk_thread_at_priority(priority);
+
+ return PK_OK;
+}
+
+
+/// Swap thread priorities
+///
+/// \param thread_a A pointer to an initialized PkThread
+///
+/// \param thread_b A pointer to an initialized PkThread
+///
+/// This API swaps the priorities of \a thread_a and \a thread_b. The API is
+/// provided to support general and efficient application-directed scheduling
+/// algorithms. The requirements on the \a thread_a and \a thread_b arguments
+/// are that they are valid pointers to initialized PkThread structures, that
+/// the current thread priorities of both threads are legal, and that if a
+/// thread is currently mapped, that the new thread priority is not otherwise
+/// in use.
+///
+/// The API does not require either thread to be mapped, or even to be active.
+/// It is legal for one or both of the swap partners to be suspended, deleted
+/// or completed threads. The application is completely responsible for the
+/// correctness of scheduling algorithms that might operate on inactive or
+/// suspended threads.
+///
+/// The API does not change the mapped status of a thread. A thread will be
+/// mapped after the call of pk_thread_priority_swap() if and only if it was
+/// mapped prior to the call. If the new priority of a mapped thread is
+/// currently in use (by a thread other than the swap partner), then the
+/// PK_PRIORITY_IN_USE_AT_SWAP error is signalled and the swap does not take
+/// place. This could only happen if the swap partner is not currently mapped.
+///
+/// It is legal for a thread to swap its own priority with another thread. The
+/// degenerate case that \a thread_a and \a thread_b are equal is also legal -
+/// but has no effect.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion, including the redundant cases that do not
+/// actually change priorities, or the cases that assign new priorities to
+/// suspended, completed or deleted threads.
+///
+/// \retval -PK_INVALID_THREAD_AT_SWAP1 One or both of \a thread_a and
+/// \a thread_b is null (0) or otherwise invalid,
+///
+/// \retval -PK_INVALID_THREAD_AT_SWAP2 the priorities of One or both of
+/// \a thread_a and \a thread_b are invalid.
+///
+/// \retval -PK_INVALID_ARGUMENT One or both of the priorities
+/// of \a thread_a and \a thread_b is invalid.
+///
+/// \retval -PK_PRIORITY_IN_USE_AT_SWAP Returned if a thread is mapped and the
+/// new thread priority is currently in use by another thread (other than the
+/// swap partner).
+
+int
+pk_thread_priority_swap(PkThread* thread_a, PkThread* thread_b)
+{
+ PkMachineContext ctx;
+ PkThreadPriority priority_a, priority_b;
+ int mapped_a, mapped_b;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF((thread_a == 0) || (thread_b == 0),
+ PK_INVALID_THREAD_AT_SWAP1);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ if (thread_a != thread_b) {
+
+ mapped_a = __pk_thread_is_mapped(thread_a);
+ mapped_b = __pk_thread_is_mapped(thread_b);
+ priority_a = thread_a->priority;
+ priority_b = thread_b->priority;
+
+ if (PK_ERROR_CHECK_API) {
+ int priority_in_use;
+ PK_ERROR_IF_CRITICAL((priority_a > PK_THREADS) ||
+ (priority_b > PK_THREADS),
+ PK_INVALID_THREAD_AT_SWAP2,
+ &ctx);
+ priority_in_use =
+ (mapped_a && !mapped_b &&
+ (__pk_thread_at_priority(priority_b) != 0)) ||
+ (!mapped_a && mapped_b &&
+ (__pk_thread_at_priority(priority_a) != 0));
+ PK_ERROR_IF_CRITICAL(priority_in_use,
+ PK_PRIORITY_IN_USE_AT_SWAP, &ctx);
+ }
+
+ if (mapped_a) {
+ __pk_thread_unmap(thread_a);
+ }
+ if (mapped_b) {
+ __pk_thread_unmap(thread_b);
+ }
+ thread_a->priority = priority_b;
+ thread_b->priority = priority_a;
+ if (mapped_a) {
+ __pk_thread_map(thread_a);
+ }
+ if (mapped_b) {
+ __pk_thread_map(thread_b);
+ }
+ __pk_schedule();
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
diff --git a/src/ppe/pk/kernel/pk_timer_core.c b/src/ppe/pk/kernel/pk_timer_core.c
new file mode 100644
index 0000000..334c6e5
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_timer_core.c
@@ -0,0 +1,425 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_timer_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_timer_core.c
+/// \brief PK portable kernel timer handler
+///
+/// This file contains core routines that would be needed by any application
+/// that requires PK timer support at runtime.
+///
+/// PK implements a 'tickless' kernel - all events are scheduled at absolute
+/// times of the PK timebase. This approach gives the application full
+/// control over granularity of event scheduling. Scheduling in absolute time
+/// opens up the possibility of scheduling events "in the past". PK
+/// uniformly handles this case by scheduling "past" events to occur 1
+/// timebase tick in the future, so that timer callbacks are always run in the
+/// expected interrupt context.
+///
+/// PK implements the time queue as a simple unordered list of events, plus a
+/// dedicated variable that holds the earliest timeout of any event in the
+/// list. This is thought to be an appropriate data structure for the
+/// following reasons:
+///
+/// - PK applications will be small and will not schedule a large number of
+/// events. Therefore the cost of scanning the list each time an event times
+/// out is balanced against the cost of maintaining the list as a sorted data
+/// structure each time an event is added or removed from the event queue.
+///
+/// - PK applications may schedule and cancel many, many more events (safety
+/// timeouts) than are ever allowed to expire. Events can be added and deleted
+/// from the simple DEQUE very quickly since there is no sorting
+/// overhead.
+///
+/// Events are added to the queue simply by placing them at the end of the
+/// queue. If the new event times out earlier than the previous earliest
+/// event, the hardware timeout is rescheduled for the new event time. Events
+/// are deleted from the queue (cancelled) simply by deleting them. Deletion
+/// does not affect the hardware timeout, even if the deleted event would have
+/// been the next to time out. It is not an error for the timer handler to
+/// take a timer interrupt and find no events pending. Pending events can
+/// also be rescheduled in place.
+///
+/// When a timeout occurs the event list is scanned from the beginning, and
+/// any event that has timed out has its callback processed.
+/// Since event and callback processing take
+/// time, the list is potentially scanned multiple times until there are no
+/// more timed-out events in the list.
+///
+/// Note that callbacks are not necessarily processed in time-order. In this
+/// sense the PK time queue is like a traditional tick-based time queue in
+/// that events are effectively lumped into groups of events that time out
+/// together. In a tick-based kernel the 'lump' is the tick interval; here
+/// the 'lump' is a variable interval that corresponds to the time it takes to
+/// process the entire event list.
+///
+/// Timer callbacks are typically run with interrupt preemption enabled.
+/// Special callbacks may run without preemption. This is the only part of
+/// the PK kernel where data structures of indeterminate size are processed.
+/// During processing of the event list by the timer interrupt handler, the
+/// consideration of each event always includes a window of preemptability.
+
+#define __PK_TIMER_CORE_C__
+
+#include "pk.h"
+
+// Declare the timer bottom half handler
+static PK_BH_HANDLER(__pk_timer_bh_handler);
+
+// Define the timer bottom half handler that the interrupt handler will
+// schedule
+PK_BH_STATIC_CREATE(pk_timer_bh, __pk_timer_bh_handler, 0);
+
+
+// This routine is only used in this file, and will always be called in a
+// critical section.
+
+static inline int
+timer_active(PkTimer* timer)
+{
+ return pk_deque_is_queued((PkDeque*)timer);
+}
+
+
+// This is the kernel version of pk_timer_cancel().
+//
+// This routine is used here and by thread and semaphore routines.
+// External interrupts must be disabled at entry.
+//
+// If the timer is active, then there is a special case if we are going to
+// delete the 'cursor' - that is the timer that __pk_timer_handler() is going
+// to handle next. In this case we need to move the cursor to the next timer
+// in the queue.
+//
+// Note that cancelling a timer does not cause a re-evaluation of the next
+// timeout. This will happen naturally when the current timeout expires.
+
+int
+__pk_timer_cancel(PkTimer *timer)
+{
+ int rc;
+ PkDeque* timer_deque = (PkDeque*)timer;
+ PkTimeQueue* tq = &__pk_time_queue;
+
+ if (!timer_active(timer)) {
+
+ rc = -PK_TIMER_NOT_ACTIVE;
+
+ } else {
+
+ if (timer_deque == tq->cursor) {
+ tq->cursor = tq->cursor->next;
+ }
+ pk_deque_delete(timer_deque);
+ rc = 0;
+ }
+ return rc;
+}
+
+
+// This is the kernel version of pk_timer_schedule().
+//
+// This routine is used here and by thread and semaphore routines.
+// interrupts must be disabled at entry.
+//
+// Unless the timer is already active it is enqueued in the doubly-linked
+// timer list by inserting the timer at the end of the queue. Then the
+// hardware timeout is scheduled if necessary. If the time queue 'cursor' != 0
+// we are in the midst of processing the time queue, and the end of time queue
+// processing will schedule the next hardware timemout.
+
+void
+__pk_timer_schedule(PkTimer* timer)
+{
+ PkTimeQueue* tq = &__pk_time_queue;
+
+ if (!timer_active(timer)) {
+ pk_deque_push_back((PkDeque*)tq, (PkDeque*)timer);
+ }
+
+ if (timer->timeout < tq->next_timeout) {
+ tq->next_timeout = timer->timeout;
+ if (tq->cursor == 0) {
+ __pk_schedule_hardware_timeout(tq->next_timeout);
+ }
+ }
+}
+
+
+// The tickless timer mechanism has timed out. Note that due to timer
+// deletions and other factors, there may not actually be a timer in the queue
+// that has timed out - but it doesn't matter (other than for efficiency).
+//
+// This routine must not be entered reentrantly.
+//
+// First, time out any timers that have expired. Timers in the queue are
+// unordered, so we have to check every one. Since passing through the
+// loop takes time, we may have to make multiple passes until we know
+// that there are no timers in the queue that have already timed
+// out. Note that it would also work to only go through the loop once and
+// let the hardware scheduler take care of looping, but that would imply
+// more overhead than the current implementation.
+//
+// On each pass through the loop tq->next_timeout computes the minimum timeout
+// of events remaining in the queue. This is the only part of the kernel that
+// searches a list of indefinite length. Kernel interrupt latency is mitigated
+// by running this function as a bottom half. As such, interrupts are only
+// disabled when explicitly requested.
+//
+// Because interrupt preemption is enabled during processing, and preempting
+// handlers may invoke time queue operations, we need to establish a pointer
+// to the next entry to be examined (tq->cursor) before enabling interupts.
+// It's possible that this pointer will be changed by other interrupt handlers
+// that cancel the timer pointed to by tq->cursor.
+//
+// The main loop iterates on the PkDeque form of the time queue, casting each
+// element back up to the PkTimer as it is processed.
+
+static void
+__pk_timer_bh_handler(void* arg)
+{
+ PkMachineContext ctx;
+ PkTimeQueue* tq;
+ PkTimebase now;
+ PkTimer* timer;
+ PkDeque* timer_deque;
+ PkTimerCallback callback;
+
+ tq = &__pk_time_queue;
+
+ // Check if we entered the function while it was running in another context.
+ if (PK_ERROR_CHECK_KERNEL) {
+ if (tq->cursor != 0) {
+ PK_PANIC(PK_TIMER_HANDLER_INVARIANT);
+ }
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ while ((now = pk_timebase_get()) >= tq->next_timeout) {
+ tq->next_timeout = PK_TIMEBASE_MAX;
+ timer_deque = ((PkDeque*)tq)->next;
+
+ // Iterate through the entire timer list, calling the callback of
+ // timed-out elements and finding the timer that will timeout next,
+ // which is stored in tq->next_timeout.
+ while (timer_deque != (PkDeque*)tq) {
+
+ timer = (PkTimer*)timer_deque;
+
+ // Setting this to a non-zero value indicates we are in the middle
+ // of processing the time queue.
+ tq->cursor = timer_deque->next;
+
+ if (timer->timeout <= now) {
+
+ // The timer timed out. It is removed from the queue.
+ //
+ // The callback may be made with interrupt preemption enabled
+ // or disabled. However to mitigate kernel interrupt latency
+ // we go ahead and open up to interrupts after the callback if
+ // the callback itself was not preemptible.
+
+ pk_deque_delete(timer_deque);
+
+ pk_critical_section_exit(&ctx);
+
+ callback = timer->callback;
+ if (callback) {
+ callback(timer->arg);
+ }
+
+ } else {
+
+ // This timer has not timed out. Its timeout will simply
+ // participate in the computation of the next timeout.
+ tq->next_timeout = MIN(timer->timeout, tq->next_timeout);
+ pk_critical_section_exit(&ctx);
+ }
+
+ timer_deque = tq->cursor;
+ pk_critical_section_enter(&ctx);
+ }
+
+ // Time has passed since we checked the time. Loop back
+ // to check the time again and see if enough time has passed
+ // that the next timer has timed out too.
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ // This marks that we are no longer processing the time queue
+ tq->cursor = 0;
+
+ // Finally, reschedule the next timeout
+ __pk_schedule_hardware_timeout(tq->next_timeout);
+}
+
+
+void
+__pk_timer_handler(void)
+{
+ //schedule the timer bottom half handler which
+ //is preemptible.
+ pk_bh_schedule(&pk_timer_bh);
+}
+
+
+/// Schedule a timer for an interval relative to the current time.
+///
+/// \param timer The PkTimer to schedule.
+///
+/// \param interval The timer will be scheduled to time out at the current
+/// time (pk_timebase_get()) plus this \a interval.
+///
+/// Once created with pk_timer_create() a timer can be \e scheduled, which
+/// queues the timer in the kernel time queue. It is not an error to call \c
+/// pk_timer_schedule() on a timer that is already scheduled in the time
+/// queue - the timer is simply rescheduled with the new characteristics.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_TIMER_AT_SCHEDULE A a null (0) pointer was provided as
+/// the \a timer argument.
+///
+
+int
+pk_timer_schedule(PkTimer *timer,
+ PkInterval interval)
+{
+ PkMachineContext ctx;
+ PkTimebase timeout = pk_timebase_get() + PK_INTERVAL_SCALE(interval);
+
+ pk_critical_section_enter(&ctx);
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(timer == 0, PK_INVALID_TIMER_AT_SCHEDULE);
+ }
+
+ timer->timeout = timeout;
+ __pk_timer_schedule(timer);
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// Cancel (dequeue) a timer.
+///
+/// \param timer The PkTimer to cancel.
+///
+/// Timers can be canceled at any time. It is never an error to call
+/// pk_timer_cancel() on an PkTimer object after it is created. Memory used
+/// by an PkTimer can be safely reused for another purpose after a successful
+/// call ofpk_timer_cancel().
+///
+/// Return values other than PK_OK (0) are not necessarily errors; see \ref
+/// pk_errors
+///
+/// The following return codes are non-error codes:
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_TIMER_NOT_ACTIVE The \a timer is not currently scheduled,
+/// i.e. it was never scheduled or has timed out. This code is returned for
+/// information only and is not considered an error.
+///
+/// The following return codes are error codes:
+///
+/// \retval -PK_INVALID_TIMER_AT_CANCEL The \a timer is a null (0) pointer.
+///
+
+int
+pk_timer_cancel(PkTimer *timer)
+{
+ PkMachineContext ctx;
+ int rc = PK_OK;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(timer == 0, PK_INVALID_TIMER_AT_CANCEL);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ rc = __pk_timer_cancel(timer);
+
+ pk_critical_section_exit(&ctx);
+
+ return rc;
+}
+
+
+/// Get information about a timer.
+///
+/// \param timer The PkTimer to query
+///
+/// \param timeout The API returns the absolute timeout of the timer through
+/// this pointer. If the timer is active, this is the current timeout. If
+/// the timer has timed out then this is the previous absolute timeout. If
+/// the timer was never scheduled this will be 0. The caller can set this
+/// parameter to the null pointer (0) if this information is not required.
+///
+/// \param active If the value returned through this pointer is 1 then the
+/// timer is active (currently scheduled), otherwise the value will be 0
+/// indicating an inactive timer. The caller can set this parameter to the
+/// null pointer (0) if this information is not required.
+///
+/// The information returned by this API can only be guaranteed consistent if
+/// the API is called from a critical section.
+///
+/// Return values other than PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_TIMER_AT_INFO The \a timer is a null (0) pointer.
+
+int
+pk_timer_info_get(PkTimer *timer,
+ PkTimebase *timeout,
+ int *active)
+
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(timer == 0, PK_INVALID_TIMER_AT_INFO);
+ }
+
+ if (timeout) {
+ *timeout = timer->timeout;
+ }
+ if (active) {
+ *active = timer_active(timer);
+ }
+
+ return PK_OK;
+}
+
+#undef __PK_TIMER_CORE_C__
diff --git a/src/ppe/pk/kernel/pk_timer_init.c b/src/ppe/pk/kernel/pk_timer_init.c
new file mode 100644
index 0000000..3ec636d
--- /dev/null
+++ b/src/ppe/pk/kernel/pk_timer_init.c
@@ -0,0 +1,86 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/kernel/pk_timer_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_timer_init.c
+/// \brief PK timer initialization
+///
+/// The entry points in this file might only be used during initialization of
+/// the application. In this case the code space for these routines could be
+/// recovered and reused after initialization.
+
+#include "pk.h"
+
+
+/// Create (initialize) a timer.
+///
+/// \param timer The PkTimer to initialize.
+///
+/// \param callback The timer callback
+///
+/// \param arg Private data provided to the callback.
+///
+/// Once created with pk_timer_create() a timer can be scheduled with
+/// pk_timer_schedule() or pk_timer_schedule_absolute(), which queues the
+/// timer in the kernel time queue. Timers can be cancelled by a call of
+/// pk_timer_cancel().
+///
+/// Timers created with pk_timer_create() are always run as
+/// bottom-half handlers with interrupt preemption enabled. Timer callbacks are
+/// free to enter critical sections if required, but must
+/// always exit with interrupts enabled.
+///
+/// Caution: PK has no way to know if an PkTimer structure provided to
+/// pk_timer_create() is safe to use as a timer, and will silently modify
+/// whatever memory is provided.
+///
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_TIMER_AT_CREATE The \a timer is a null (0) pointer.
+
+int
+pk_timer_create(PkTimer *timer,
+ PkTimerCallback callback,
+ void *arg)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF((timer == 0), PK_INVALID_TIMER_AT_CREATE);
+ }
+
+ pk_deque_element_create((PkDeque*)timer);
+ timer->timeout = 0;
+ timer->callback = callback;
+ timer->arg = arg;
+
+ return PK_OK;
+}
+
+
diff --git a/src/ppe/pk/kernel/pkkernelfiles.mk b/src/ppe/pk/kernel/pkkernelfiles.mk
new file mode 100644
index 0000000..599d73b
--- /dev/null
+++ b/src/ppe/pk/kernel/pkkernelfiles.mk
@@ -0,0 +1,56 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/kernel/pkkernelfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file pkkernelfiles.mk
+#
+# @brief mk for including architecture independent pk object files
+#
+# @page ChangeLogs Change Logs
+# @section pkkernelfiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Include
+##########################################################################
+
+
+##########################################################################
+# Object Files
+##########################################################################
+PK-C-SOURCES = pk_core.c pk_init.c pk_stack_init.c pk_bh_core.c pk_debug_ptrs.c
+
+PK-TIMER-C-SOURCES += pk_timer_core.c pk_timer_init.c
+
+PK-THREAD-C-SOURCES += pk_thread_init.c pk_thread_core.c pk_thread_util.c \
+ pk_semaphore_init.c pk_semaphore_core.c
+
+PK_OBJECTS += $(PK-C-SOURCES:.c=.o)
+
diff --git a/src/ppe/pk/ppe/Makefile b/src/ppe/pk/ppe/Makefile
new file mode 100644
index 0000000..51afc5c
--- /dev/null
+++ b/src/ppe/pk/ppe/Makefile
@@ -0,0 +1,74 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/ppe/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile compiles all of the PK code required for the PPE port
+# of PK. See the "pk.mk" file in this directory.
+
+#all generated files from this makefile will end up in obj/$(IMAGE_NAME)/pk
+export SUB_OBJDIR = /pk
+
+include img_defs.mk
+include pkppefiles.mk
+
+ifeq "$(PK_TIMER_SUPPORT)" "1"
+PPE_OBJECTS += ${PPE-TIMER-C-SOURCES:.c=.o} ${PPE-TIMER-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" "1"
+PPE_OBJECTS += ${PPE-THREAD-C-SOURCES:.c=.o} ${PPE-THREAD-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PPE_ASYNC_SUPPORT)" "1"
+PPE_OBJECTS += ${PPE-ASYNC-C-SOURCES:.c=.o} ${PPE-ASYNC-S-SOURCES:.S=.o}
+endif
+
+OBJS := $(addprefix $(OBJDIR)/, $(PPE_OBJECTS))
+
+libpk.a: kernel ppe42 trace ppe
+ $(AR) crs $(OBJDIR)/libpk.a $(OBJDIR)/*.o
+
+.PHONY: clean ppe kernel ppe42 trace
+ppe: $(OBJS)
+
+trace:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../trace
+
+kernel:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../kernel
+
+ppe42:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../ppe42
+
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/pk/ppe/pk_port.h b/src/ppe/pk/ppe/pk_port.h
new file mode 100644
index 0000000..e185170
--- /dev/null
+++ b/src/ppe/pk/ppe/pk_port.h
@@ -0,0 +1,41 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe/pk_port.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_PORT_H__
+#define __PK_PORT_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_port.h
+/// \brief The top-level CME environment header for PK.
+
+#define HWMACRO_PPE
+
+#include "ppe42.h"
+#include "ppe_timebase.h"
+
+#endif /* __PK_PORT_H__ */
diff --git a/src/ppe/pk/ppe/pkppefiles.mk b/src/ppe/pk/ppe/pkppefiles.mk
new file mode 100644
index 0000000..83b63f7
--- /dev/null
+++ b/src/ppe/pk/ppe/pkppefiles.mk
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/ppe/pkppefiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file pkppefiles.mk
+#
+# @brief mk for including ppe object files
+#
+# @page ChangeLogs Change Logs
+# @section pkppefiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+PPE-C-SOURCES = ppe_init.c
+PPE-S-SOURCES =
+
+PPE-TIMER-C-SOURCES =
+PPE-TIMER-S-SOURCES =
+
+PPE-THREAD-C-SOURCES =
+PPE-THREAD-S-SOURCES =
+
+PPE-ASYNC-C-SOURCES =
+PPE-ASYNC-S-SOURCES =
+
+PPE_OBJECTS += $(PPE-C-SOURCES:.c=.o) $(PPE-S-SOURCES:.S=.o)
+
diff --git a/src/ppe/pk/ppe/ppe.h b/src/ppe/pk/ppe/ppe.h
new file mode 100644
index 0000000..94669d5
--- /dev/null
+++ b/src/ppe/pk/ppe/ppe.h
@@ -0,0 +1,46 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe/ppe.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE_H__
+#define __PPE_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp.h
+/// \brief The PPE environment for PK.
+
+// This is a 'circular' reference in PK, but included here to simplify PGAS
+// programming.
+
+#ifndef HWMACRO_PPE
+#define HWMACRO_PPE
+#include "ppe42.h"
+#endif
+
+#include "ppe_common.h"
+
+#endif /* __PPE_H__ */
diff --git a/src/ppe/pk/ppe/ppe_common.h b/src/ppe/pk/ppe/ppe_common.h
new file mode 100644
index 0000000..a462e1f
--- /dev/null
+++ b/src/ppe/pk/ppe/ppe_common.h
@@ -0,0 +1,73 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe/ppe_common.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE_COMMON_H__
+#define __PPE_COMMON_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe_common.h
+/// \brief Common header for PPE
+///
+/// This header is maintained as part of the PK port for PPE, but needs to be
+/// physically present in the PMX area to allow dropping PMX code as a whole
+/// to other teams.
+
+// -*- WARNING: This file is maintained as part of PK. Do not edit in -*-
+// -*- the PMX area as your edits will be lost. -*-
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif
+
+/// This constant is used to define the size of the table of interrupt handler
+/// structures as well as a limit for error checking.
+/// NOTE: This can be specific to each PPE type (SBE, PPE, GPE)
+#define EXTERNAL_IRQS 64
+
+#ifdef __ASSEMBLER__
+/// This macro contains PPE specific code.
+/// Since standalone models of the PPE do not support external interrupts
+/// we just set the code to 64 (phantom interrupt)
+ .macro hwmacro_get_ext_irq
+
+ li %r4, 64
+
+ .endm
+
+/// Redirect the .hwmacro_irq_cfg_bitmaps macro to call our ppe specific implementation
+/// This is called from the ppe42_exceptions.S file.
+/// NOTE: The standalone version of PPE doesn't support external interrupts so this
+/// does nothing.
+ .macro .hwmacro_irq_cfg_bitmaps
+ .endm
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE_COMMON_H__ */
diff --git a/src/ppe/pk/ppe/ppe_init.c b/src/ppe/pk/ppe/ppe_init.c
new file mode 100644
index 0000000..7bbcf6c
--- /dev/null
+++ b/src/ppe/pk/ppe/ppe_init.c
@@ -0,0 +1,49 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe/ppe_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe_init.c
+/// \brief PK initialization for PPE
+///
+/// The entry points in this routine are used during initialization. This
+/// code space can be deallocated and reassigned after application
+/// initialization if required.
+
+#include "pk.h"
+
+/// PPE environment initial setup.
+///
+/// This is setup common to all PPE HW Macro applications. This setup takes place
+/// during boot, before main() is called.
+
+void
+__hwmacro_setup(void)
+{
+ //async_initialize();
+}
diff --git a/src/ppe/pk/ppe/ppe_timebase.h b/src/ppe/pk/ppe/ppe_timebase.h
new file mode 100644
index 0000000..935f4f1
--- /dev/null
+++ b/src/ppe/pk/ppe/ppe_timebase.h
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe/ppe_timebase.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE_TIMEBASE_H__
+#define __PPE_TIMEBASE_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe_timebase.h
+/// \brief support for using the OCB 32 bit timebase register
+///
+
+#include "pk.h"
+
+//The timebase register will never be supported in the base ppe model
+#ifdef APPCFG_USE_EXT_TIMEBASE
+#error "External timebase is not supported on the PPE standalone model"
+#endif /* APPCFG_USE_EXT_TIMEBASE */
+
+#ifndef __ASSEMBLER__
+
+//assembly function is defined in ppe42_timebase.S
+uint32_t pk_timebase32_get(void);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE_TIMEBASE_H__ */
diff --git a/src/ppe/pk/ppe42/.empty b/src/ppe/pk/ppe42/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/pk/ppe42/.empty
diff --git a/src/ppe/pk/ppe42/Makefile b/src/ppe/pk/ppe42/Makefile
new file mode 100644
index 0000000..8d7ce82
--- /dev/null
+++ b/src/ppe/pk/ppe42/Makefile
@@ -0,0 +1,50 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/ppe42/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile is designed to be invoked with the -I argument set to
+# the location of the "pk.mk" for the build
+
+include img_defs.mk
+include pkppe42files.mk
+
+ifeq "$(PK_TIMER_SUPPORT)" "1"
+PPE42_OBJECTS += ${PPE42-TIMER-C-SOURCES:.c=.o} ${PPE42-TIMER-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" "1"
+PPE42_OBJECTS += ${PPE42-THREAD-C-SOURCES:.c=.o} ${PPE42-THREAD-S-SOURCES:.S=.o}
+endif
+
+OBJS := $(addprefix $(OBJDIR)/, $(PPE42_OBJECTS))
+
+all: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/pk/ppe42/div64.S b/src/ppe/pk/ppe42/div64.S
new file mode 100644
index 0000000..ec93250
--- /dev/null
+++ b/src/ppe/pk/ppe42/div64.S
@@ -0,0 +1,272 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/div64.S $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file div64.S
+/// \brief Unsigned 64/64 bit division
+///
+/// This is IBM code, originally part of OS Open. The code has been slightly
+/// modified from its original form, both to be compatible with PK and to
+/// change the function prototype slightly.
+///
+/// The code was provided by Matt Tyrlik in Raleigh.
+
+/* @#START#@
+**
+** PSCN (Power Service and Control Network)
+** Cage Controller OS Open Code
+**
+** (C) Copyright International Business Machines Corporation 2002
+** All Rights Reserved
+** Licensed Material - Program Property of I B M
+** Refer to copyright instructions: Form G120-2083
+**
+** Module:
+** div64.s
+**
+** Description:
+** Divide 64 bit unsigned values on 32 bit CPU
+** div64(uint64_t dividen, uint64_t divisor,
+** uint64_t *quotient, uint64_t *remainder)
+**
+** Original source from:
+** "The PowerPC Compiler Writer's Guide", pp62-65 by
+** Steve Hoxey, Faraydon Karim, Bill Hay, Hank Warray,
+** published by Warthman Associates, 240 Hamilton Avenue,
+** Palo Alto, CA 94301, USA, 1996 for IBM.
+** ISBN 0-9649654-0-2.
+**
+** This version checks for divisor equal to zero.
+**
+** Environment:
+** OS Open (XCOFF)
+**
+** Linkage:
+** AIX 4.3.3
+**
+** @author
+** Thomas Richter
+**
+** History:
+** Date Author Description
+** -----------------------------------------------------------------------------
+** 23-Sep-02 Richter Created
+**
+** @#END#@*/
+
+ .nolist
+#include "pk.h"
+ .list
+
+ .global_function __ppe42_udiv64
+
+ /*
+ ** Code comment notation:
+ ** msw = most-significant (high-order) word, i.e. bits 0..31
+ ** lsw = least-significant (low-order) word, i.e. bits 32..63
+ ** LZ = Leading Zeroes
+ ** SD = Significant Digits
+ **
+ ** R3:R4 = Input parameter, dividend.
+ ** R5:R6 = Input parameter, divisor.
+ ** R7 = Output parameter, pointer to quotient.
+ ** R8 = Output parameter, pointer to remainder.
+ **
+ ** Pointer arguments point to a uint64_t.
+ **
+ ** Division is achieved using a shift/rotate/substract algorithsm
+ ** described above.
+ ** The registers are used as follows:
+ ** R3:R4 = dividend (upper 32bits:lower 32bits)
+ ** R5:R6 = divisor (upper 32bits:lower 32bits)
+ **
+ ** R7:R8 = temporary 64 bit register (upper 32bits:lower 32bits)
+ ** count the number of leading 0s in the dividend
+ **
+ ** Here is the description from the book. The dividend is placed
+ ** in the low order part of a 4 (32bit) register sequence named
+ ** tmp-high:tmp-low:dividend-high:dividend:low or tmp:dvd for short.
+ **
+ ** Each iteration includes the following steps:
+ ** 1. Shift tmp:dvd by one bit to the left.
+ ** 2. Subtract the divisor from tmp. This is a 64 bit operation.
+ ** 3. If result is greater than or equal, place result in tmp and
+ ** set the low order bit of dividend
+ ** 4. If result is negative, do not modify tmp and
+ ** clear the low order bit of dividend
+ ** 5. If the number of iterations is less than the width of the
+ ** dividend, goto step 1.
+ **
+ ** Now the algorithm can be improved by reducing the number of
+ ** iterations to be executed.
+ ** 1. Calculate the leading zeroes of the dividend.
+ ** 2. Calculate the leading zeroes of the divisor.
+ ** 3. Calculate the significant ones of the dividend.
+ ** 4. Calculate the significant ones of the divisor.
+ **
+ ** Initial tmp := dvd >> (dvd.SD - dvs.SD)
+ ** Initial dvd := dvd << (dvd.LZ + dvs.SD)
+ ** Loops: dvd.SD - dvs.SD.
+ **
+ ** Warning: Special care must be taken if dvd.LZ == dvs.LZ. The code
+ ** below does so by reducing the number of dvs.SD by one. This leads
+ ** to the loop being executed 1 more time than really necessary,
+ ** but avoids to check for the case when dvd.LZ == dvs.LZ.
+ ** This case (dvd.LZ == dvs.LZ) only checks for the number of leading
+ ** zeroes, but does not check if dividend is really greater than the
+ ** divisor.
+ ** Consider 16/17, both have an LZ value of 59. The code sets dvs.LZ
+ ** 60. This resutls in dvs.SD to 4, thus one iteration after which
+ ** tmp is the remainder 16.
+ */
+
+__ppe42_udiv64: // PK
+
+ /* push R30 & R31 onto the stack */
+ stwu r1, -16(r1)
+ stvd r30, 8(r1)
+
+ /* Save result pointers on volatile spare registers */
+ ori r31, r8, 0 /* Save remainder address */
+ ori r30, r7, 0 /* Save quotient address */
+
+ /* count the number of leading 0s in the dividend */
+ cmpwi cr0, r3, 0 /* dvd.msw == 0? */
+ cntlzw r0, r3 /* R0 = dvd.msw.LZ */
+ cntlzw r9, r4 /* R9 = dvd.lsw.LZ */
+ bne cr0, lab1 /* if(dvd.msw == 0) dvd.LZ = dvd.msw.LZ */
+ addi r0, r9, 32 /* dvd.LZ = dvd.lsw.LZ + 32 */
+lab1:
+ /* count the number of leading 0s in the divisor */
+ cmpwi cr0, r5, 0 /* dvd.msw == 0? */
+ cntlzw r9, r5 /* R9 = dvs.msw.LZ */
+ cntlzw r10, r6 /* R10 = dvs.lsw.LZ */
+ bne cr0, lab2 /* if(dvs.msw == 0) dvs.LZ = dvs.msw.LZ */
+ cmpwi cr0, r6, 0 /* dvd.lsw == 0? */
+ beq cr0, lab10 /* dvs.msw == 0 */
+ addi r9, r10, 32 /* dvs.LZ = dvs.lsw.LZ + 32 */
+
+lab2:
+ /* Determine shift amounts to minimize the number of iterations */
+ cmpw cr0, r0, r9 /* Compare dvd.LZ to dvs.LZ */
+ subfic r10, r0, 64 /* R10 = dvd.SD */
+ bgt cr0, lab9 /* if(dvs > dvd) quotient = 0 */
+ addi r9, r9, 1 /* See comment above. ++dvs.LZ (or --dvs.SD) */
+ subfic r9, r9, 64 /* R9 = dvs.SD */
+ add r0, r0, r9 /* (dvd.LZ + dvs.SD) = left shift of dvd for */
+ /* initial dvd */
+ subf r9, r9, r10 /* (dvd.SD - dvs.SD) = right shift of dvd for */
+ /* initial tmp */
+ mtctr r9 /* Number of iterations = dvd.SD - dvs.SD */
+
+ /* R7:R8 = R3:R4 >> R9 */
+ cmpwi cr0, r9, 32 /* compare R9 to 32 */
+ addi r7, r9, -32
+ blt cr0, lab3 /* if(R9 < 32) jump to lab3 */
+ srw r8, r3, r7 /* tmp.lsw = dvd.msw >> (R9 - 32) */
+ addi r7, r0, 0 /* tmp.msw = 0 */
+ b lab4
+
+lab3:
+ srw r8, r4, r9 /* R8 = dvd.lsw >> R9 */
+ subfic r7, r9, 32
+ slw r7,r3,r7 /* R7 = dvd.msw << 32 - R9 */
+ or r8, r8,r7 /* tmp.lsw = R8 | R7 */
+ srw r7,r3,r9 /* tmp.msw = dvd.msw >> R9 */
+lab4:
+ /* R3:R4 = R3:R4 << R0 */
+ cmpwi cr0, r0, 32 /* Compare R0 to 32 */
+ addic r9, r0, -32
+ blt cr0, lab5 /* if(R0 < 32) jump to lab5 */
+ slw r3, r4, r9 /* dvd.msw = dvd.lsw << R9 */
+ addi r4, r0, 0 /* dvd.lsw = 0 */
+ b lab6
+
+lab5:
+ slw r3, r3, r0 /* r3 = dvd.msw << r0 */
+ subfic r9, r0, 32
+ srw r9, r4, r9 /* r9 = dvd.lsw >> 32 - r0 */
+ or r3, r3, r9 /* dvd.msw = r3 | r9 */
+ slw r4, r4, r0 /* dvd.lsw = dvd.lsw << r0 */
+lab6:
+ /* Restoring division shift and subtract loop */
+ addi r10, r0, -1 /* r10 = -1 */
+ addic r7, r7, 0 /* Clear carry bit before loop starts */
+lab7:
+ /*
+ ** tmp:dvd is considered one large register
+ ** each portion is shifted left 1 bit by adding it to itself
+ ** adde sums the carry from the previous and creates a new carry
+ */
+ adde r4, r4, r4 /* Shift dvd.lsw left 1 bit */
+ adde r3, r3, r3 /* Shift dvd.msw to left 1 bit */
+ adde r8, r8, r8 /* Shift tmp.lsw to left 1 bit */
+ adde r7, r7, r7 /* Shift tmp.msw to left 1 bit */
+ subfc r0, r6, r8 /* tmp.lsw - dvs.lsw */
+ subfe. r9, r5, r7 /* tmp.msw - dvs.msw */
+ blt cr0, lab8 /* if(result < 0) clear carry bit */
+ or r8, r0, r0 /* Move lsw */
+ or r7, r9, r9 /* Move msw */
+ addic r0, r10, 1 /* Set carry bit */
+
+lab8:
+ bdnz lab7
+
+ /* Write quotient and remainder */
+ adde r4, r4, r4 /* quo.lsw (lsb = CA) */
+ adde r3, r3, r3 /* quo.msw (lsb from lsw) */
+ stw r4, 4(r30)
+ stw r3, 0(r30)
+ stw r8, 4(r31) /* rem.lsw */
+ stw r7, 0(r31) /* rem.msw */
+ b lab11
+
+lab9:
+ /* Qoutient is 0, divisor > dividend */
+ addi r0, r0, 0
+ stw r3, 0(r31) /* Store remainder */
+ stw r4, 4(r31)
+ stw r0, 0(r30) /* Set quotient to zero */
+ stw r0, 4(r30)
+ b lab11
+
+lab10:
+ /* Divisor is 0 */
+ addi r0, r0, -1
+ stw r0, 0(r31) /* Set remainder to zero */
+ stw r0, 4(r31)
+ stw r0, 0(r30) /* Set quotient to zero */
+ stw r0, 4(r30)
+
+lab11:
+ //pop r30 & r31 from stack
+ lvd r30, 8(r1)
+ lwz r1, 0(r1)
+ blr
+ .epilogue __ppe42_udiv64
diff --git a/src/ppe/pk/ppe42/pk_port_types.h b/src/ppe/pk/ppe42/pk_port_types.h
new file mode 100644
index 0000000..2c80389
--- /dev/null
+++ b/src/ppe/pk/ppe42/pk_port_types.h
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/pk_port_types.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_PORT_TYPES_H__
+#define __PK_PORT_TYPES_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_port_types.h
+/// \brief Type definitions required by the PK port.
+///
+/// \todo GCC provides a portable version of cntlzw called __builtin_clz().
+/// We should make the PK priority queues portable by using this facility.
+///
+/// \todo I think that if more of the port-dependent types were moved here, we
+/// could break the circular dependencies in some of the header inclusion and
+/// simplify the way the PK/port/chip headers are included.
+
+/// An PkIrqId is an integer in the range of valid interrupts defined by the
+/// interrupt controller.
+
+typedef uint8_t PkIrqId;
+
+/// PK requires the port to define the type PkThreadQueue, which is a
+/// priority queue (where 0 is the highest priority). This queue must be able
+/// to handle PK_THREADS + 1 priorities (the last for the idle thread). The
+/// port must also define methods for clearing, insertion, deletion and min
+/// (with assumed legal priorities). The min operation returns PK_THREADS if
+/// the queue is empty. (Or a queue could be initialized with the PK_THREADS
+/// entry always present - PK code never tries to delete the idle thread from
+/// a thread queue).
+///
+/// These queues are used both for the run queue and the pending queue
+/// associated with every semaphore.
+///
+/// On PPE42 with 32 threads (implied), this is a job for a uint32_t and
+/// cntlzw().
+
+typedef uint32_t PkThreadQueue;
+
+#endif /* __PK_PORT_TYPES_H__ */
diff --git a/src/ppe/pk/ppe42/pkppe42files.mk b/src/ppe/pk/ppe42/pkppe42files.mk
new file mode 100644
index 0000000..30e19b5
--- /dev/null
+++ b/src/ppe/pk/ppe42/pkppe42files.mk
@@ -0,0 +1,70 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/ppe42/pkppe42files.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file pkppe42files.mk
+#
+# @brief mk for including ppe42 object files
+#
+# @page ChangeLogs Change Logs
+# @section pkppe42files.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Include Files
+##########################################################################
+
+
+
+##########################################################################
+# Object Files
+##########################################################################
+PPE42-C-SOURCES = ppe42_core.c \
+ ppe42_init.c \
+ ppe42_irq_core.c\
+ ppe42_gcc.c\
+ ppe42_scom.c
+
+PPE42-S-SOURCES = ppe42_boot.S \
+ ppe42_exceptions.S\
+ div64.S\
+ ppe42_timebase.S
+
+PPE42-TIMER-C-SOURCES =
+PPE42-TIMER-S-SOURCES =
+
+PPE42-THREAD-C-SOURCES +=
+PPE42-THREAD-S-SOURCES += ppe42_thread_init.S
+
+
+PPE42_OBJECTS += $(PPE42-C-SOURCES:.c=.o) $(PPE42-S-SOURCES:.S=.o)
+
+
+
diff --git a/src/ppe/pk/ppe42/ppe42.h b/src/ppe/pk/ppe42/ppe42.h
new file mode 100644
index 0000000..0321c49
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42.h
@@ -0,0 +1,853 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_H__
+#define __PPE42_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42.h
+/// \brief PPE42 port header for PK
+
+// Macros to define where declared code is actually compiled
+
+#ifdef __PPE42_C__
+#define IF__PPE42_CORE_C__(x) x
+#define UNLESS__PPE42_CORE_C__(x)
+#else
+#define IF__PPE42_CORE_C__(x)
+#define UNLESS__PPE42_CORE_C__(x) x
+#endif
+
+#ifdef __PPE42_IRQ_CORE_C__
+#define IF__PPE42_IRQ_CORE_C__(x) x
+#define UNLESS__PPE42_IRQ_CORE_C__(x)
+#else
+#define IF__PPE42_IRQ_CORE_C__(x)
+#define UNLESS__PPE42_IRQ_CORE_C__(x) x
+#endif
+
+#ifdef HWMACRO_GPE
+#include "gpe.h"
+#elif defined(HWMACRO_STD)
+#include "std.h"
+#elif defined(HWMACRO_PPE)
+#include "ppe.h"
+#else
+#error "Macro Type not specified. Are you building from the correct directory?"
+#endif
+
+
+#include "ppe42_asm.h"
+#include "ppe42_gcc.h"
+#include "ppe42_spr.h"
+#include "ppe42_msr.h"
+
+
+///start
+
+/// The synchronization macros defined here all create a compiler
+/// memory barrier that will cause GCC to flush/invalidate all memory data
+/// held in registers before the macro. This is consistent with other systems,
+/// e.g., the PowerPC Linux kernel, and is the safest way to define these
+/// macros.
+
+
+// Condition register fields
+
+#define CR_LT(n) (0x80000000u >> (4 * (n)))
+#define CR_GT(n) (0x40000000u >> (4 * (n)))
+#define CR_EQ(n) (0x20000000u >> (4 * (n)))
+#define CR_SO(n) (0x10000000u >> (4 * (n)))
+
+
+#ifndef __ASSEMBLER__
+
+#include "stdint.h"
+
+/// ssize_t is defined explictly rather than bringing in all of <unistd.h>
+#ifndef __ssize_t_defined
+#define __ssize_t_defined
+typedef int ssize_t;
+#endif
+
+/// A memory barrier
+#define barrier() asm volatile ("" : : : "memory")
+
+/// Ensure In-order Execution of Input/Output
+#define eieio() asm volatile ("sync" : : : "memory")
+
+/// Memory barrier
+#define sync() asm volatile ("sync" : : : "memory")
+
+/// Instruction barrier
+#define isync() asm volatile ("sync" : : : "memory")
+
+/// CouNT Leading Zeros Word
+#define cntlzw(x) \
+({uint32_t __x = (x); \
+ uint32_t __lzw; \
+ asm volatile ("cntlzw %0, %1" : "=r" (__lzw) : "r" (__x)); \
+ __lzw;})
+
+/// CouNT Leading Zeros : uint32_t
+static inline int
+cntlz32(uint32_t x) {
+ return cntlzw(x);
+}
+
+/// CouNT Leading Zeros : uint64_t
+static inline int
+cntlz64(uint64_t x) {
+ if (x > 0xffffffff) {
+ return cntlz32(x >> 32);
+ } else {
+ return 32 + cntlz32(x);
+ }
+}
+
+
+/// 32-bit population count
+static inline int
+popcount32(uint32_t x)
+{
+ return __builtin_popcount(x);
+}
+
+
+/// 64-bit population count
+static inline int
+popcount64(uint64_t x)
+{
+ return __builtin_popcountll(x);
+}
+
+
+// NB: Normally we wouldn't like to force coercion inside a macro because it
+// can mask programming errors, but for the MMIO macros the addresses are
+// typically manifest constants or 32-bit unsigned integer expressions so we
+// embed the coercion to avoid warnings.
+
+/// 8-bit MMIO Write
+#define out8(addr, data) \
+do {*(volatile uint8_t *)(addr) = (data);} while(0)
+
+/// 8-bit MMIO Read
+#define in8(addr) \
+({uint8_t __data = *(volatile uint8_t *)(addr); __data;})
+
+/// 16-bit MMIO Write
+#define out16(addr, data) \
+do {*(volatile uint16_t *)(addr) = (data);} while(0)
+
+/// 16-bit MMIO Read
+#define in16(addr) \
+({uint16_t __data = *(volatile uint16_t *)(addr); __data;})
+
+/// 32-bit MMIO Write
+#define out32(addr, data) \
+do {*(volatile uint32_t *)(addr) = (data);} while(0)
+
+/// 32-bit MMIO Read
+#define in32(addr) \
+({uint32_t __data = *(volatile uint32_t *)(addr); __data;})
+
+#ifdef HWMACRO_GPE
+
+/// 64-bit MMIO Write
+#define out64(addr, data) \
+ do { \
+ uint64_t __data = (data); \
+ volatile uint32_t *__addr_hi = (uint32_t *)(addr); \
+ volatile uint32_t *__addr_lo = __addr_hi + 1; \
+ *__addr_hi = (__data >> 32); \
+ *__addr_lo = (__data & 0xffffffff); \
+ } while(0)
+
+#else /* standard PPE's require a 64 bit write */
+
+/// 64-bit MMIO Write
+#define out64(addr, data) \
+{\
+ uint64_t __d = (data); \
+ uint32_t* __a = (uint32_t*)(addr); \
+ asm volatile \
+ (\
+ "stvd %1, %0 \n" \
+ : "=o"(*__a) \
+ : "r"(__d) \
+ ); \
+}
+
+#endif /* HWMACRO_GPE */
+
+#ifdef HWMACRO_GPE
+/// 64-bit MMIO Read
+#define in64(addr) \
+ ({ \
+ uint64_t __data; \
+ volatile uint32_t *__addr_hi = (uint32_t *)(addr); \
+ volatile uint32_t *__addr_lo = __addr_hi + 1; \
+ __data = *__addr_hi; \
+ __data = (__data << 32) | *__addr_lo; \
+ __data;})
+
+#else /* Standard PPE's require a 64 bit read */
+
+#define in64(addr) \
+({\
+ uint64_t __d; \
+ uint32_t* __a = (uint32_t*)(addr); \
+ asm volatile \
+ (\
+ "lvd %0, %1 \n" \
+ :"=r"(__d) \
+ :"o"(*__a) \
+ ); \
+ __d; \
+})
+
+#endif /* HWMACRO_GPE */
+
+#endif /* __ASSEMBLER__ */
+
+#include "ppe42_irq.h"
+
+#ifndef __ASSEMBLER__
+
+/// Store revision information as a (global) string constant
+#define REVISION_STRING(symbol, rev) const char* symbol = rev;
+
+#else // __ASSEMBLER__
+
+/// Store revision information as a global string constant
+ .macro .revision_string, symbol:req, rev:req
+ .pushsection .rodata
+ .balign 4
+ .global \symbol
+\symbol\():
+ .asciz "\rev"
+ .balign 4
+ .popsection
+ .endm
+
+#endif // __ASSEMBLER__
+
+
+
+#include "ppe42_context.h"
+
+// PPE42 stack characteristics for PK. The pre-pattern pattern is selected
+// to be easily recognizable yet be an illegal instruction.
+
+#define PK_STACK_DIRECTION -1
+#define PK_STACK_PRE_DECREMENT 1
+#define PK_STACK_ALIGNMENT 8
+#define PK_STACK_TYPE unsigned int
+#define PK_STACK_PATTERN 0x03abcdef
+
+// Kernel data structure offsets for assembler code
+
+#define PK_THREAD_OFFSET_SAVED_STACK_POINTER 0
+#define PK_THREAD_OFFSET_STACK_LIMIT 4
+#define PK_THREAD_OFFSET_STACK_BASE 8
+
+// PK boot loader panic codes
+
+#define PPE42_BOOT_VECTORS_NOT_ALIGNED 0x00405001
+
+// Interrupt handler panic codes
+
+#define PPE42_DEFAULT_IRQ_HANDLER 0x00405010
+#define PPE42_DEFAULT_SPECIAL_HANDLER 0x00405011
+#define PPE42_PHANTOM_INTERRUPT 0x00405012
+#define PPE42_PROGRAM_HALT 0x00405013
+
+
+// Exception handling invariant panic codes
+
+#define PPE42_IRQ_FULL_EXIT_INVARIANT 0x00405020
+#define PPE42_IRQ_FAST2FULL_INVARIANT 0x00405021
+
+
+// API error panic codes
+
+
+// Application-overrideable definitions
+
+/// The default thread machine context has MSR[CE], MSR[EE] and MSR[ME] set,
+/// and all other MSR bits cleared.
+///
+/// The default definition allows external and machine check exceptions. This
+/// definition can be overriden by the application.
+
+#ifndef PK_THREAD_MACHINE_CONTEXT_DEFAULT
+#define PK_THREAD_MACHINE_CONTEXT_DEFAULT \
+ (MSR_UIE | MSR_EE | MSR_ME)
+
+#endif
+
+
+#ifndef __ASSEMBLER__
+
+/// The PK kernel default panic sequence for C code
+///
+/// By default a kernel panic from C code forces external debug mode then
+/// generates a \c trap instruction followed by the error code. The \a code
+/// argument must be a compile-time integer immediate. This definition can be
+/// overriden by the application.
+///
+/// The OCC may be running in internal debug mode for various reasons, and
+/// TRAP-ing in internal debug mode would lead to an infinite loop in the
+/// default Program Interrupt handler - which itself would be a TRAP (since
+/// that's the default implementation of PK_PANIC(). Therefore by default
+/// the panic is implemented as a special code sequence that forces the core
+/// into external debug mode before issuing a TRAP which will halt the core.
+/// To preserve the state we use the special global variables
+/// __pk_panic_save_dbcr0 and __pk_panic_save_r3 defined in ppe42_core.c.
+/// The original value of DBCR0 is destroyed, but can be recovered from the
+/// global. In the end %r3 is reloaded from temporary storage and will be
+/// unchanged at the halt.
+///
+/// Note that there is a small chance that an interrupt will fire and
+/// interrupt this code before the halt - in general there is no way around
+/// this.
+///
+/// The Simics environment does not model Debug events correctly. It executes
+/// the TRAP as an illegal instruction and branches to the Program Interrupt
+/// handler, destroying the contents of SRR0 and SRR1. Therefore we always
+/// insert a special Simics magic breakpoint (which is an effective NOP)
+/// before the hardware trap. The special-form magic instruction is
+/// recognized by our Simics support scripts which decode the kernel state and
+/// try to help the user interpret what happened based on the TRAP code.
+
+#ifndef PK_PANIC
+
+/*#define PK_PANIC(code) \
+ do { \
+ barrier(); \
+ asm volatile ("stw %r3, __pk_panic_save_r3@sda21(0)"); \
+ asm volatile ("mfdbcr0 %r3"); \
+ asm volatile ("stw %r3, __pk_panic_save_dbcr0@sda21(0)"); \
+ asm volatile ("lwz %r3, __pk_panic_dbcr0@sda21(0)"); \
+ asm volatile ("mtdbcr0 %r3"); \
+ asm volatile ("isync"); \
+ asm volatile ("lwz %r3, __pk_panic_save_r3@sda21(0)"); \
+ asm volatile ("rlwimi 1,1,0,0,0"); \
+ asm volatile ("trap"); \
+ asm volatile (".long %0" : : "i" (code)); \
+ } while (0)
+*/
+#define PK_PANIC(code) \
+ do { \
+ barrier(); \
+ asm volatile ("b ."); \
+ } while (0)
+
+// These variables are used by the PK_PANIC() definition above to save and
+// restore state. __pk_panic_dbcr0 is the value loaded into DBCR0 to force
+// traps to halt the OCC and freeze the timers.
+
+//#ifdef __PPE42_CORE_C__
+//uint32_t __pk_panic_save_r3;
+//uint32_t __pk_panic_save_dbcr0;
+//uint32_t __pk_panic_dbcr0 = DBCR0_EDM | DBCR0_TDE | DBCR0_FT;
+//#endif
+
+#endif // PK_PANIC
+
+/// This is the Simics 'magic breakpoint' instruction.
+///
+/// Note that this form does not include a memory barrier, as doing so might
+/// change the semantics of the program. There is an alternative form
+/// SIMICS_MAGIC_BREAKPOINT_BARRIER that does include a barrier.
+
+//#define SIMICS_MAGIC_BREAKPOINT asm volatile ("rlwimi 0,0,0,0,0")
+
+/// This is the Simics 'magic breakpoint' instruction including a memory
+/// barrier.
+///
+/// Note that the memory barrier guarantees that all variables held in
+/// registers are flushed to memory before the breakpoint, however this might
+/// change the semantics of the program. There is an alternative form of
+/// SIMICS_MAGIC_BREAKPOINT that does not include a barrier. If the idea is
+/// to use the breakpoint for tracing code execution in Simics, the barrier
+/// form may be preferred so that variable values will be visible in memory.
+
+/*#define SIMICS_MAGIC_BREAKPOINT_BARRIER \
+ asm volatile ("rlwimi 0,0,0,0,0" : : : "memory")
+*/
+
+#else // __ASSEMBLER__
+
+/// This is the Simics 'magic breakpoint' instruction. An assembler macro
+/// form is also provided for use within macros.
+
+//#define SIMICS_MAGIC_BREAKPOINT rlwimi 0,0,0,0,0
+
+// .macro _simics_magic_breakpoint
+// rlwimi 0,0,0,0,0
+// .endm
+
+/// The PK kernel panic default panic sequence for assembler code
+///
+/// By default a kernel panic from assembler forces external debug mode then
+/// generates a \c trap instruction followed by the error code. The \a code
+/// argument must be a compile-time integer immediate. This definition can be
+/// overriden by the application.
+///
+/// See the comments for the non-ASSEMBLER version for further details. Note
+/// that the code space reserved for exception handlers is only 8
+/// instructions, so in the assembler context we don't save DBCR0 as doing so
+/// would require 10.
+
+#ifndef PK_PANIC
+
+#define PK_PANIC(code) _pk_panic code
+
+ .macro _pk_panic, code
+ b .
+ .endm
+
+#endif // PK_PANIC
+
+#endif // __ASSEMBLER__
+
+
+// Application-overridible definitions for the PK boot loader
+
+/// In order to enable the default kernel panic (a trap) to halt the machine,
+/// the Debug Control Register 0 (DBCR0) is initialized in externel debug
+/// mode, with the Trap Debug Event enabled so that the trap will not cause a
+/// program exception, and the FT bit set so that the timers will freeze.
+/// This definition can be overridden by the application.
+///
+/// NB: It is expected that a reliable production system will redefine all of
+/// the 'panic' macros and the default DBCR0 setup.
+
+#ifndef PPE42_DBCR_INITIAL
+#define PPE42_DBCR_INITIAL DBCR_TRAP
+#endif
+
+/// This is the value of the MSR used during initialization. Once PK threads
+/// are started (with \c pk_start_threads()), all machine contexts derive
+/// from the default thread context \c
+/// PK_THREAD_MACHINE_CONTEXT_DEFAULT. This definition can be overriden by
+/// the application.
+///
+/// The default is to enable machine checks only.
+
+#ifndef PPE42_MSR_INITIAL
+#define PPE42_MSR_INITIAL MSR_ME
+#endif
+
+/// The \a argc argument passed to \c main(). This definition can be overriden
+/// by the application.
+
+#ifndef PPE42_ARGC_INITIAL
+#define PPE42_ARGC_INITIAL 0
+#endif
+
+/// The \a argv argument passed to \c main(). This definition can be overriden
+/// by the application.
+
+#ifndef PPE42_ARGV_INITIAL
+#define PPE42_ARGV_INITIAL 0
+#endif
+
+/// Optionally trap the reset for the debugger, which means that the PPE42
+/// will simply spin at the symbol \c __reset_trap after a chip reset. Set R0
+/// to a non-zero value in the debugger to continue execution. This definition
+/// can be overriden by the application.
+
+#ifndef PPE42_RESET_TRAP
+#define PPE42_RESET_TRAP 0
+#endif
+
+// PPE42 doesn't support the system call instruction so we use this illegal
+// instruction to force a program exception which then emulates the system call
+// instruction.
+#define PPE42_SC_INST 0x44000002
+
+#ifndef __ASSEMBLER__
+
+/// The PPE42 PK machine context is simply the MSR, a 32-bit integer.
+
+typedef uint32_t PkMachineContext;
+
+/// Disable interrupts and return the current
+/// context.
+///
+/// \param context A pointer to an PkMachineContext, this is the context that
+/// existed before interrupts were disabled. Typically this
+/// context is restored at the end of a critical section.
+///
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_INTERRUPT An illegal priority was specified.
+
+UNLESS__PPE42_CORE_C__(extern)
+inline int
+pk_interrupt_disable(PkMachineContext *context)
+{
+ *context = mfmsr();
+
+ wrteei(0);
+
+ return PK_OK;
+}
+
+/// Set the machine context.
+///
+/// \param context A pointer to an PkMachineContext
+///
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_CONTEXT_SET A null pointer was provided as
+/// the \a context argument or an illegal machine context was specified.
+
+UNLESS__PPE42_CORE_C__(extern)
+inline int
+pk_machine_context_set(PkMachineContext *context)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(context == 0, PK_INVALID_ARGUMENT_CONTEXT_SET);
+ }
+
+ mtmsr(*context);
+
+ return PK_OK;
+}
+
+/// Get the machine context.
+///
+/// \param context A pointer to an PkMachineContext.
+///
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_CONTEXT_GET A null pointer was provided as
+/// the \a context argument.
+
+UNLESS__PPE42_CORE_C__(extern)
+inline int
+pk_machine_context_get(PkMachineContext *context)
+{
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(context == 0, PK_INVALID_ARGUMENT_CONTEXT_GET);
+ }
+
+ *context = mfmsr();
+
+ return PK_OK;
+}
+
+/// The PK kernel thread context switch - PPE42 uses the 'sc' illegal instruction
+/// to force a program exception to occur.
+#define __pk_switch() asm volatile (".long 0x44000002")
+
+
+/// In the PowerPC EABI all initial stack frames require 8 bytes - the 4 bytes
+/// at the SP are zeroed to indicate the end of the stack, and the 4 bytes
+/// behind the SP are for the initial subroutine's LR.
+
+static inline void
+__pk_stack_create_initial_frame(PkAddress *stack, size_t *size) \
+{
+ *stack -= 8;
+ *size -= 8;
+ *((PK_STACK_TYPE *)(*stack)) = 0;
+}
+
+/// The PK Kernel Context for PPE42
+///
+/// The PK portable kernel does not define how the kernel keeps track of
+/// whether PK is running, interrupt levels, and other debug
+/// information. Instead it defines an API that the port must provide to the
+/// portable kernel.
+///
+/// In the PPE42 port, the kernel context is maintained in SPRG0. This
+/// 32-bit value is treated as 6 distinct fields as indicated in the structure
+/// definition.
+typedef union {
+
+ uint32_t value;
+
+ struct {
+
+ /// A flag indicating that PK is in thread mode after a call of
+ /// pk_start_threads().
+ unsigned thread_mode : 1;
+
+ /// If this field is non-zero then PK is processing an interrupt
+ /// and the \c irq field will contain the PkIrqId of the interrupt
+ /// that kicked off interrupt processing.
+ unsigned processing_interrupt : 1;
+
+ /// The priority of the currently running thread. In an interrupt
+ /// context, this is the priority of the thread that was interrupted.
+ unsigned thread_priority : 6;
+
+ /// This bit tracks whether the current context can be discarded or
+ /// if the context must be saved. If the processor takes an interrupt
+ /// and this bit is set, then the current context will be discarded.
+ /// This bit is set at the end of handling an interrupt and prior
+ /// to entering the wait enabled state.
+ unsigned discard_ctx : 1;
+
+ /// The PkIrqId of the currently running (or last run) handler. If
+ /// \c processing_interrupt is set, then this is the
+ /// PkIrqId of the IRQ that is currently executing.
+ unsigned irq : 7;
+
+ /// Each PPE application will define (or not) the interpretation of
+ /// this field. Since SPRG0 is saved and restored during during thread
+ /// context switches, this field can be used to record the progress of
+ /// individual threads. The kernel and/or application will provide
+ /// APIs or macros to read and write this field.
+ unsigned app_specific : 16;
+
+ } fields;
+
+} __PkKernelContext;
+
+// These APIs are provided for applications to get and set the app_specific
+// field of the kernel context which is held in sprg0.
+
+static inline uint16_t ppe42_app_ctx_get(void)
+{
+ __PkKernelContext __ctx;
+ __ctx.value = mfspr(SPRN_SPRG0);
+ return __ctx.fields.app_specific;
+}
+
+static inline void ppe42_app_ctx_set(uint16_t app_ctx)
+{
+ PkMachineContext mctx;
+ __PkKernelContext __ctx;
+ mctx = mfmsr();
+ wrteei(0);
+ __ctx.value = mfspr(SPRN_SPRG0);
+ __ctx.fields.app_specific = app_ctx;
+ mtspr(SPRN_SPRG0, __ctx.value);
+ mtmsr(mctx);
+}
+
+// These APIs are provided to the PK portable kernel by the port.
+
+/// PK threads have been started by a call of pk_start_threads().
+
+#define __pk_kernel_mode_thread() \
+ ({ \
+ __PkKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_SPRG0); \
+ __ctx.fields.thread_mode;})
+
+
+/// PK is executing in a thread context (not an interrupt handler).
+
+#define __pk_kernel_context_thread() \
+ ({ \
+ __PkKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_SPRG0); \
+ __ctx.fields.thread_mode && !__ctx.fields.processing_interrupt;})
+
+
+/// PK is executing an interrupt handler of any priority.
+
+#define __pk_kernel_context_any_interrupt() \
+ ({ \
+ __PkKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_SPRG0); \
+ __ctx.fields.processing_interrupt;})
+
+
+// PK requires the port to define the type PkThreadQueue, which is a
+// priority queue (where 0 is the highest priority). This queue must be able
+// to handle PK_THREADS + 1 priorities (the last for the idle thread) The
+// port must also define methods for clearing, insertion, deletion and min
+// (with assumed legal priorities). The min operation returns PK_THREADS if
+// the queue is empty (or a queue could be initialized with that entry always
+// present - PK code never tries to delete the idle thread from a thread
+// queue).
+//
+// These queues are used both for the run queue and the pending queue
+// associated with every semaphore.
+//
+// On PPE42 with 32 threads (implied), this is a job for a uint32_t and
+// cntlzw().
+
+static inline void
+__pk_thread_queue_clear(volatile PkThreadQueue *queue)
+{
+ *queue = 0;
+}
+
+static inline void
+__pk_thread_queue_insert(volatile PkThreadQueue *queue, PkThreadPriority priority)
+{
+ *queue |= (0x80000000u >> priority);
+}
+
+static inline void
+__pk_thread_queue_delete(volatile PkThreadQueue *queue, PkThreadPriority priority)
+{
+ *queue &= ~(0x80000000u >> priority);
+}
+
+static inline PkThreadPriority
+__pk_thread_queue_min(volatile PkThreadQueue *queue)
+{
+ return cntlzw(*queue);
+}
+
+static inline int
+__pk_thread_queue_member(volatile PkThreadQueue *queue, PkThreadPriority priority)
+{
+ return ((*queue >> (31 - priority)) & 1);
+}
+
+static inline void
+__pk_thread_queue_union(volatile PkThreadQueue *queue0,
+ volatile PkThreadQueue *queue1)
+{
+ *queue0 |= *queue1;
+}
+
+static inline int
+__pk_thread_queue_count(volatile PkThreadQueue* queue)
+{
+ return __builtin_popcount(*queue);
+}
+
+
+/// This macro is used to call __pk_start_threads() using the kernel stack,
+/// in a critical section.
+
+#define __pk_call_pk_start_threads() \
+ do { \
+ PkMachineContext ctx; \
+ pk_critical_section_enter(&ctx); \
+ asm volatile ("mr 1, %0; mtlr %1; blrl" : : \
+ "r" (__pk_kernel_stack), \
+ "r" (__pk_start_threads)); \
+ PK_PANIC(PK_START_THREADS_RETURNED); \
+ } while (0)
+
+
+#endif /* __ASSEMBLER__ */
+
+/// The __PkKernelContext 'thread_mode' bit as a flag
+
+#define PPE42_THREAD_MODE 0x8000
+#define PPE42_PROC_IRQ 0x4000
+#define PPE42_DISCARD_CTX 0x0080
+
+#define PPE42_THREAD_MODE_BIT 0
+#define PPE42_PROC_IRQ_BIT 1
+#define PPE42_DISCARD_CTX_BIT 8
+
+#ifndef __ASSEMBLER__
+
+/// Code breakpoints for PPE42
+///
+/// This macro inserts a special PPE42-only breakpoint into the object code
+/// at the place the macro invocation appears. This facility is designed for
+/// VBU/VPO procedure debugging. This type of breakpoint may not be required
+/// on real hardware as we will then have the full power of RISCWatch, gdb,
+/// etc. Once inserted into the code, code breakpoints can be enabled or
+/// disabled by manipulating the global variable _code_breakpoint_enable,
+/// which defaults to 1.
+///
+/// The code breakpoint is implemented as a setup routine and a teardown
+/// routine, executed in an critical section. The actual break
+/// will occur at the address of the call of the teardown routine, in the
+/// context of the calling code. The setup routine saves the state of DBCR0/1
+/// and IAC4, then programs the DBCR for an external debug mode, IAC4
+/// breakpoint. The IAC4 breakpoint is set for the address of the call of the
+/// teardown routine. The teardown routine simply restores the state of the
+/// debug registers that existed before the code breakpoint.
+///
+/// Once hit, restarting from the break requires clearing IAC4 and restarting
+/// instructions:
+///
+/// \code
+///
+/// putspr pu.occ iac4 0
+/// cipinstruct pu.occ start
+///
+/// \endcode
+///
+/// The above restart processes is also encapsulated as the p8_tclEcmd
+/// procedure 'unbreakOcc'.
+///
+/// In code built for the Simics environment (i.e., with the preprocessor
+/// macro SIMICS_ENVIRONMENT=1) this macro simply expands into
+/// SIMICS_MAGIC_BREAKPOINT, and simulation can be continued from the break as
+/// normal. This Simics magic breakpoint is also under the control of
+/// _code_breakpoint_enable. In code not built with SIMICS_ENVIROMENT=1, note
+/// that the CODE_BREAKPOINT is ignored by the Simics PPE42 model as it does
+/// not model debug events.
+
+//#if defined(SIMICS_ENVIRONMENT) && (SIMICS_ENVIRONMENT != 0)
+/*#define CODE_BREAKPOINT \
+ do { \
+ if (_code_breakpoint_enable) { \
+ SIMICS_MAGIC_BREAKPOINT; \
+ } \
+ } while (0)
+#else
+#define CODE_BREAKPOINT \
+ do { \
+ if (_code_breakpoint_enable) { \
+ PkMachineContext __ctx; \
+ pk_critical_section_enter(&__ctx); \
+ _code_breakpoint_prologue(); \
+ _code_breakpoint_epilogue(); \
+ pk_critical_section_exit(&__ctx); \
+ } \
+ } while (0)
+#endif
+*/
+
+//void
+//_code_breakpoint_prologue(void);
+
+//void
+//_code_breakpoint_epilogue(void);
+
+//extern uint32_t _code_breakpoint_enable;
+
+#endif // __ASSEMBLER__
+
+
+#endif /* __PPE42_H__ */
diff --git a/src/ppe/pk/ppe42/ppe42_asm.h b/src/ppe/pk/ppe42/ppe42_asm.h
new file mode 100644
index 0000000..16b2714
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_asm.h
@@ -0,0 +1,632 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_asm.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_ASM_H__
+#define __PPE42_ASM_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_asm.h
+/// \brief Generic assembler macros for 32-bit PPE42
+
+// Doxygen is confused by assembler; the best I know how to make it
+// work is to put all of the documentation at the beginning like below
+// and effectively comment out the code using Doxygen cond/endcond.
+
+/// \page ppe42_asm Generic assembler macros for 32-bit PPE42
+///
+///
+/// \section _lxzi _l<w,h,b>zi - Load register and Zero from Immediate address
+///
+/// These macros encapsulate the 2-instruction sequence required to
+/// load from a 32-bit immediate address.
+///
+/// \arg \c dreg A register to receive the load data.
+/// \arg \c areg A register to hold the immediate address. This can \e
+/// not be register 0. Note that if \a areg != \a dreg
+/// then \a areg will contain the address at the end of
+/// the macro sequence.
+/// \arg \c addr A 32-bit immediate address, which may be either an
+/// absolute or relocatable expression.
+///
+/// Forms:
+///
+/// \b _lbzi \a dreg, \a areg, \a addr - Load Byte and Zero from Immediate address \n
+/// \b _lhzi \a dreg, \a areg, \a addr - Load Halfword and Zero from Immediate address \n
+/// \b _lwzi \a dreg, \a areg, \a addr - Load Word and Zero from Immediate address \n
+///
+///
+/// \section _stxi _st<w,h,b>i - STore register to Immediate address
+///
+/// These macros encapsulate the 2-instruction sequence required to
+/// store to a 32-bit immediate address.
+///
+/// \arg \c dreg The register to store.
+/// \arg \c areg A register to hold the immediate address. This can \e
+/// not be register 0, and can not be the same as \a dreg.
+/// Note that \a areg will contain the address at the end of
+/// the macro sequence.
+/// \arg \c addr A 32-bit immediate address, which may be either an
+/// absolute or relocatable expression.
+///
+/// Forms:
+///
+/// \b _stbi \a dreg, \a areg, \a addr - STore Byte to Immediate address \n
+/// \b _sthi \a dreg, \a areg, \a addr - STore Halfword to Immediate address \n
+/// \b _stwi \a dreg, \a areg, \a addr - STore Word to Immediate address \n
+///
+///
+/// \section _lstzsd _<l,st><w,h,b><z>sd - Load/STore register from/to Small Data area
+///
+/// These macros encapulate the small data area relocations for access
+/// to storage in the small data sections .sbss, .sdata, .sbss2 and
+/// .sdata2. Use of these macros implies small data area support in
+/// the compile environment (for variables shared between compiled and
+/// assembled code) and initialization code that sets up the small data
+/// area registers R13 (and optionally R2).
+///
+/// The relocations generated by this macro will work for both SVR4 ABI
+/// and EABI environments. In particular, for EABI environments
+/// the link editor will insert offsets to either R13 or R2 depending
+/// on the section of the symbol.
+///
+/// \arg \c dreg The register to load or store.
+/// \arg \c addr A 32-bit immediate address, assumed to be a
+/// relocatable address in one of the small data sections.
+///
+/// Forms:
+///
+/// \b _lbzsd \a dreg, \a addr - Load Byte and Zero from Small Data area \n
+/// \b _lhzsd \a dreg, \a addr - Load Halfword and Zero from Small Data area \n
+/// \b _lwzsd \a dreg, \a addr - Load Word and Zero from Small Data area \n
+/// \b _stbsd \a dreg, \a addr - STore Byte to Small Data area \n
+/// \b _sthsd \a dreg, \a addr - STore Halfword to Small Data area \n
+/// \b _stwsd \a dreg, \a addr - STore Word to Small Data area \n
+///
+///
+/// \section _liw _liw<a> - Load Immediate Word (Absolute)
+///
+/// These macros encapsulate the two instructions required to load a
+/// 32-bit immediate value into a register. If the immediate is an
+/// absolute expression, then the \c 'a' form may be able to optimize
+/// to a single instruction depending on whether only the high- or
+/// low-order bits of the immediate are non-zero.
+///
+/// Forms:
+///
+/// \b _liw \a rd, \a imm - Load register \a rd with the 32-bit immediate \a imm \n
+/// \b _liwa \a rd, \a imm - Load register \a rd with the 32-bit absolute immediate \a imm \n
+///
+///
+/// \section _oriwa _oriwa - OR Immediate Word Absolute
+///
+/// This macro encapsulates the logical OR of a 32-bit immediate with a
+/// register. The immediate value must be an absolute expression.
+///
+/// The PowerPC has instructions for OR-ing 16-bit immediates into the
+/// upper (\c oris) and lower (\c ori) portions of a register. This
+/// macro optimizes the generated code based on which bits (if any) of
+/// the absolte immediate are non-zero.
+///
+/// This special macro is only provided for the OR function. For other
+/// logical operations and recording forms it is necessary in general
+/// to first load the 32-bit immediate into a register (e.g., with \c
+/// _liwa) then perform the logical operation.
+///
+/// \arg \c rd The destination register; at the end will contain \c rs
+/// OR \a imm
+/// \arg \c rs The source register.
+/// \arg \c imm 32-bit absolute expression.
+///
+/// Forms:
+///
+/// \b _oriwa \a rd, \a rs, \a imm - \a rd gets \a rs OR \a imm \n
+///
+///
+/// \section _incr64_fast - 64-bit increment for fast interrupt handlers
+///
+/// This macros implements 64-bit counter update in fast interrupt handlers
+/// which are forbidden from using the carry-bit in the XER (without
+/// saving/restoring it.)
+///
+/// \arg \c rs Scratch register
+/// \arg \c ra Register containing the counter address at entry
+///
+/// \a rs and \a ra must be unique. At the end of the macro the count
+/// is updated to memory and \a ra is unmodified.
+///
+///
+/// \section _setclear_bits Set/Clear/Copy Bits from Immediate Positions
+///
+/// There are situations where it is easier/faster to clear individual bits
+/// and bit fields, set bits or copy fields, based on immediate bit numbers
+/// and locations, rather than loading masks, since setting up a mask
+/// requires 2 instruction in general, whereas these macros generate a single
+/// instruction.
+///
+/// \arg \c rd - The destination register
+/// \arg \c rs - The source register
+/// \arg \c n - An immediate size of a bit field, in the range 0 to 32
+/// \arg \c b - An immediate big-endian bit number in the range 0 to 31
+///
+/// Forms:
+///
+/// \b _clrfield \a rd, \a rs, \a n, \a b - Clear an \a n bit field from \a rs
+/// to \a rd starting from bit \a b \n
+/// \b _clrbit \a rd, \a rs, \a b - Clear bit \a b \n
+/// \b _setbit \a rd, \a rs, \a b - Set bit \a b \n
+/// \b _copyfield \a rd, \a rs, \a n, \a b - Copy an n-bit field from \a rs to
+/// \a rd starting from bit \a b \n
+///
+///
+/// \section pseudo_ops Assembler Pseudo-Ops Macros
+///
+/// Several macros define new 'pseudo-ops'.
+///
+/// \subsection cache_align .cache_align
+///
+/// The \c .cache_align pseudo-op is used to force alignment on a
+/// cache-line boundary. It requires a preprocessor symbol definition for
+/// \c LOG_CACHE_LINE_SIZE
+///
+/// Forms:
+///
+/// \b .cache_align \n
+///
+///
+/// \subsection global_function Local and Global Functions
+///
+/// The \c .function and \c .global_function pseudo-ops define function
+/// symbols in the \c .text section.
+///
+/// Forms:
+///
+/// \b .function \a symbol - Define a local function \a symbol \n
+/// \b .global_function \a symbol - Define a global function \a symbol \n
+///
+///
+/// \subsection epilogue .epilogue
+///
+/// The \c .epilogue pseudo-op adds size and type information for
+/// functions defined in assembler.
+///
+/// \arg \c symbol - Assembler epilogue for the function \a symbol.
+///
+/// Forms:
+///
+/// \b .epilogue \a symbol \n
+///
+///
+/// \cond
+
+#ifdef __ASSEMBLER__
+
+
+### ****************************************************************************
+### _l<b,h,w>zi
+### _st<b,h,w>i
+### ****************************************************************************
+
+ .macro _lbzi dreg, areg, addr
+ lis \areg, \addr@ha
+ .ifc \areg, \dreg
+ lbz \dreg, \addr@l(\areg)
+ .else
+ lbzu \dreg, \addr@l(\areg)
+ .endif
+ .endm
+
+ .macro _lhzi dreg, areg, addr
+ lis \areg, \addr@ha
+ .ifc \areg, \dreg
+ lhz \dreg, \addr@l(\areg)
+ .else
+ lhzu \dreg, \addr@l(\areg)
+ .endif
+ .endm
+
+ .macro _lwzi dreg, areg, addr
+ lis \areg, \addr@ha
+ .ifc \areg, \dreg
+ lwz \dreg, \addr@l(\areg)
+ .else
+ lwzu \dreg, \addr@l(\areg)
+ .endif
+ .endm
+
+ .macro _stbi dreg, areg, addr
+ .ifc \areg, \dreg
+ .err
+ .endif
+ lis \areg, \addr@ha
+ stbu \dreg, \addr@l(\areg)
+ .endm
+
+ .macro _sthi dreg, areg, addr
+ .ifc \areg, \dreg
+ .err
+ .endif
+ lis \areg, \addr@ha
+ sthu \dreg, \addr@l(\areg)
+ .endm
+
+ .macro _stwi dreg, areg, addr
+ .ifc \areg, \dreg
+ .err
+ .endif
+ lis \areg, \addr@ha
+ stwu \dreg, \addr@l(\areg)
+ .endm
+
+
+### ****************************************************************************
+### _l<b,h,w>zsd
+### _st<b,h,w>sd
+### ****************************************************************************
+
+ .macro _lbzsd dreg, addr
+ lbz \dreg, \addr@sda21(0)
+ .endm
+
+ .macro _lhzsd dreg, addr
+ lhz \dreg, \addr@sda21(0)
+ .endm
+
+ .macro _lwzsd dreg, addr
+ lwz \dreg, \addr@sda21(0)
+ .endm
+
+ .macro _stbsd dreg, addr
+ stb \dreg, \addr@sda21(0)
+ .endm
+
+ .macro _sthsd dreg, addr
+ sth \dreg, \addr@sda21(0)
+ .endm
+
+ .macro _stwsd dreg, addr
+ stw \dreg, \addr@sda21(0)
+ .endm
+
+
+### ****************************************************************************
+### _liw<a>
+### _oriwa
+### ****************************************************************************
+
+ .macro _liw rd, imm
+ lis \rd, \imm@h
+ ori \rd, \rd, \imm@l
+ .endm
+
+ .macro _liwa rd, imm
+ .if (\imm & 0xffff0000)
+ lis \rd, \imm@h
+ .if (\imm & 0xffff)
+ ori \rd, \rd, \imm@l
+ .endif
+ .else
+ li \rd, \imm@l
+ .endif
+ .endm
+
+ .macro _oriwa rd, rs, imm
+ .if (\imm & 0xffff0000)
+ oris \rd, \rs, \imm@h
+ .if (\imm & 0xffff)
+ ori \rd, \rd, \imm@l
+ .endif
+ .else
+ ori \rd, \rs, \imm@l
+ .endif
+ .endm
+
+### ****************************************************************************
+### _incr64_fast
+### ****************************************************************************
+
+ .macro _incr64_fast, rs:req, ra:req
+
+ lwz \rs, 4(\ra)
+ addi \rs, \rs, 1
+ cmpwi \rs, 0
+ stw \rs, 4(\ra)
+ bne 233643278f
+
+ lwz \rs, 0(\ra)
+ addi \rs, \rs, 1
+ stw \rs, 0(\ra)
+233643278:
+
+ .endm
+
+### ****************************************************************************
+### _clrfield
+### _clrbit
+### _setbit
+### _copyfield
+### ****************************************************************************
+
+ .macro _clrfield, rd, rs, n, b
+ rlwinm \rd, \rs, 0, (\b + \n) & 0x1f, (\b - 1) & 0x1f
+ .endm
+
+ .macro _clrbit, rd, rs, b
+ _clrfield \rd, \rs, 1, \b
+ .endm
+
+ .macro _setbit, rd, rs, b
+ .ifle \b - 15
+ oris \rd, \rs, 1 << (15 - \b)
+ .else
+ ori \rd, \rs, 1 << (31 - \b)
+ .endif
+ .endm
+
+ .macro _copyfield, rd, rs, n, b
+ rlwimi \rd, \rs, 0, \b , (\b + \n - 1)
+ .endm
+
+### ****************************************************************************
+### .cache_align
+### .<global_>function
+### .epilogue
+### ****************************************************************************
+
+ .set _log_cache_line_size, LOG_CACHE_LINE_SIZE
+
+ .macro .cache_align
+ .align _log_cache_line_size
+ .endm
+
+ .macro .function symbol
+ .text
+ .align 2
+ .endm
+
+ .macro .global_function symbol
+ .text
+ .align 2
+ .global \symbol
+ .endm
+
+ .macro .epilogue symbol
+ .type \symbol, @function
+ .size \symbol, . - \symbol
+ .endm
+
+### ***************************************************************************
+### 64-bit macros
+### ***************************************************************************
+
+### ***************************************************************************
+### Using symbols for register names makes the code more readable and allows
+### us to do register arithmetic within macros.
+### ***************************************************************************
+
+.equiv r0, 0
+.equiv r1, 1
+.equiv sp, 1
+.equiv r3, 3
+.equiv r4, 4
+.equiv r5, 5
+.equiv r6, 6
+.equiv r7, 7
+.equiv r8, 8
+.equiv r9, 9
+.equiv r10, 10
+
+.equiv r28, 28
+.equiv r29, 29
+.equiv r30, 30
+.equiv r31, 31
+
+.equiv d3, 3
+.equiv d4, 4
+.equiv d5, 5
+.equiv d6, 6
+.equiv d7, 7
+.equiv d8, 8
+.equiv d9, 9
+.equiv d10, 10
+.equiv d28, 28
+.equiv d29, 29
+.equiv d30, 30
+.equiv d31, 31
+
+### ***************************************************************************
+### Load virtual doubleword generic. Load a virtual doubleword from a relocatable
+### address expression. If the optional RA is specified, the address remains in
+### RA.
+### ***************************************************************************
+.macro _lvdg DT:req addr:req RA=-1
+ .if \RA == -1
+ lis \DT, (\addr)@ha
+ lvd \DT, (\addr)@l(\DT)
+ .else
+ lis \RA, (\addr)@ha
+ lvdu \DT, (\addr)@l(\RA)
+ .endif
+.endm
+
+### ***************************************************************************
+### Load virtual doubleword from a relocatable small data area address
+### ***************************************************************************
+.macro _lvdsd DT:req addr:req
+ lvd \DT, (\addr)@sda21(0)
+.endm
+
+### ***************************************************************************
+### Store virtual doubleword generic. Store a virtual doubleword based on a
+### relocatable address expression. The address remains in RA.
+### ***************************************************************************
+.macro _stvdg DS:req addr:req RA:req
+ lis \RA, (\addr)@ha
+ stvdu \DS, (\addr)@l(\RA)
+.endm
+
+### ***************************************************************************
+### Store virtual doubleword to a relocatable small data address expression
+### ***************************************************************************
+.macro _stvdsd DS:req addr:req
+ stvd \DS, (\addr)@sda21(0)
+.endm
+
+### ***************************************************************************
+### Load virtual doubleword absolute. Set DT to an absolute 64-bit constant
+### ***************************************************************************
+.macro _lvda DT, cvalue
+ lwa (\DT + 1)%32, (\cvalue) & 0x00000000ffffffff
+ lwa \DT, (\cvalue) >> 32
+.endm
+
+### ***************************************************************************
+###
+### 64-bit arithmetic macros
+###
+### ***************************************************************************
+
+.macro check_overlap2 DA, DB
+ .if ((\DA - \DB) % 32) == 1 || ((\DA - \DB) % 32) == -1
+ .error "virtual doubleword registers must be identical or non-overlapping"
+ .endif
+.endm
+
+.macro check_overlap3 DA, DB, DC
+ check_overlap2 \DA, \DB
+ check_overlap2 \DA, \DC
+ check_overlap2 \DB, \DC
+.endm
+
+### ***************************************************************************
+### Add virtual doubleword carrying
+### ***************************************************************************
+.macro _addvdc DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ addc (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ adde \DT, \DA, \DB
+.endm
+
+### ***************************************************************************
+### Add virtual doubleword to signed 16-bit immediate carrying
+### ***************************************************************************
+.macro _addvdic DT, DA, SI
+ .if \DA == 31
+ .error "d31 for addend register is not supported"
+ .endif
+ check_overlap2 \DT, \DA
+ addi (\DT+1)%32, \DA+1, SI
+ addze \DT, \DA
+.endm
+
+### ***************************************************************************
+### Add virtual doubleword to unsigned word carrying
+### ***************************************************************************
+.macro _addvdwuc DT, DA, RB
+ check_overlap2 \DT, \DA
+ addc (\DT+1)%32, (\DA+1)%32, \RB
+ addze \DT, \DA
+.endm
+
+### ***************************************************************************
+### Subtract virtual doubleword carrying
+### ***************************************************************************
+.macro _subvdc DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ subfc (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ subfe \DT, \DA, \DB
+.endm
+
+### ***************************************************************************
+###
+### 64-bit logic macros
+###
+### ***************************************************************************
+
+### ***************************************************************************
+### AND virtual doubleword
+### ***************************************************************************
+.macro _andvd DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ and (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ and \DT, \DA, \DB
+.endm
+
+### ***************************************************************************
+### ANDC virtual doubleword
+### ***************************************************************************
+.macro _andcvd DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ andc (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ andc \DT, \DA, \DB
+.endm
+
+### ***************************************************************************
+### EQV virtual doubleword
+### ***************************************************************************
+.macro _eqvvd DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ eqv (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ eqv \DT, \DA, \DB
+.endm
+
+### ***************************************************************************
+### OR virtual doubleword
+### ***************************************************************************
+.macro _orvd DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ or (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ or \DT, \DA, \DB
+.endm
+
+### ***************************************************************************
+### ORC virtual doubleword
+### ***************************************************************************
+.macro _orcvd DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ orc (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ orc \DT, \DA, \DB
+.endm
+
+### ***************************************************************************
+### XOR virtual doubleword
+### ***************************************************************************
+.macro _xorvd DT, DA, DB
+ check_overlap3 \DT, \DA, \DB
+ xor (\DT+1)%32, (\DA+1)%32, (\DB+1)%32
+ xor \DT, \DA, \DB
+.endm
+
+#endif /* __ASSEMBLER__ */
+
+/// \endcond
+
+// Local Variables:
+// mode:asm
+// End:
+
+#endif /* __PPE42_ASM_H__ */
diff --git a/src/ppe/pk/ppe42/ppe42_boot.S b/src/ppe/pk/ppe42/ppe42_boot.S
new file mode 100644
index 0000000..f237690
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_boot.S
@@ -0,0 +1,193 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_boot.S $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_boot.S
+/// \brief PK bootloader for PPE42
+
+ .nolist
+#include "pk.h"
+ .list
+
+### PK Bootloader for PPE42
+###
+### This is the basic restart initialization of the processor.
+### Parts of this code were derived from examples in the IBM OSopen
+### OpenBIOS for the 405GP written by James Burke.
+###
+### This code does not really do very much, just makes sure that there will
+### be a reasonable state in the machine when control is turned over to
+### the PK application. Any core setup that requires SPR access will be done
+### here. All other setup is expected to take place in system-specific
+### routines.
+###
+### From the PowerPC 405-S Embedded Core User's manual:
+###
+### "In general, the contents of SPRs are undefined after a core, chip or
+### system reset. Some SPRs retain the content they had before the reset
+### occurred."
+###
+### Registers fully reset:
+### DBCR1 - Data compares disabled
+### DCWR - Data cache write-through disabled
+### ESR - No exception syndromes
+### MSR - No exceptions/interrupts are allowed
+###
+### Registers partially reset:
+### CCR0 = 0x00700000 - Sets ICU and DCU PLB Priority
+### DBCR0 [EDM] = 0 - External debug mode disabled
+### [RST] = 0 - No reset action
+### DBSR [MRR] = x - x indicates most recent reset action
+### SGR = 0xffffffff - Storage is guarded
+### TCR [WRC] = 0 - Watchdog timer reset disabled
+### TSR [WRS] = x - x is a copy of TCR[WRC] Watchdog reset status
+### [PIS] = x - undefined
+
+ .global_function __pk_boot
+ .global __reset_trap
+
+__pk_boot:
+
+ ## Trap the reset for the debugger. Set R0 to a non-zero value in the
+ ## debugger to continue.
+
+ .if PPE42_RESET_TRAP
+ li %r0, 0
+__reset_trap:
+ cmpwi %r0, 0
+ beq __reset_trap
+ .endif
+
+ ## Set up PowerPC EABI constant registers. These registers are never
+ ## again touched by the PK kernel or the application (if they are
+ ## behaving).
+
+ _liw %r2, _SDA2_BASE_
+ _liw %r13, _SDA_BASE_
+
+ ## Clear the timer control register. This masks all timer interrupts.
+
+ li %r3, 0
+ mttcr %r3
+
+ ## The stack pointer is initialized for use by the remainder of the
+ ## initialization, including the application main(). The linker script
+ ## defines the initial stack area.
+ ##
+ ## Stacks are always 8-byte aligned. A '0' is stored at the
+ ## stack pointer to indicate the end of the stack chain. Stack frames
+ ## always consist of at least 8 bytes - the backchain pointer and the
+ ## slot above the backchain pointer for the callee's LR.
+
+ _liw %r1, _PK_INITIAL_STACK
+ _clrfield %r1, %r1, 3, 29 # 8-byte align
+ li %r3, 0
+ stwu %r3, -8(%r1)
+
+ ## SPRG0 (__PkKernelContext) is initialized to 0
+ ## indicating that the PK kernel is not in thread mode, and no
+ ## interrupts are active.
+
+ li %r3, 0
+ mtsprg0 %r3
+
+ ## Set up the initial value of Debug Control Register 0. Note that
+ ## DBCR1 is specified to be cleared at reset. VBU simulation requested
+ ## an option that this register not be modified so that they could
+ ## completely control debug behavior from reset of the PPE42.
+
+#ifndef NO_INIT_DBCR0
+ _liwa %r3, PPE42_DBCR_INITIAL
+ mtdbcr %r3
+#endif
+
+ ## The exception vector prefix is set - it must be 512 byte aligned.
+ ## NOTE: for PPE42, the IVPR is read only, but can be changed through scoms
+
+ #_liw %r3, __vectors
+ #andi. %r4, %r3, 0x01ff
+ #beq 1f
+ #_pk_panic PPE42_BOOT_VECTORS_NOT_ALIGNED
+#1:
+ #mtivpr %r3
+ #sync
+
+ ## The MSR to be used during the rest of intialization is
+ ## established. This MSR should NOT enable
+ ## interrupts, but could enable machine check exceptions.
+
+ _liwa %r3, PPE42_MSR_INITIAL
+ mtmsr %r3
+ sync
+
+#ifdef PK_BOOT_FROM_ROM
+
+ ## NB: I don't think the old linker scripts were necessarily the most
+ ## optimal. We need to revisit this if we actually do ROM boots in PK
+ ## Version 2. Not sure the comments are correct.
+
+ ## Data is copied from the initial ROM image to the RAM. The
+ ## address symbols are defined in the linker command file. The linker
+ ## will have zeroed this area in the ROM image.
+
+ liw %r3, __pk_ram_lma - 4 # src
+ liw %r4, __pk_ram_vma - 4 # dest
+ liw %r5, __pk_ram_size
+ liw %r6, 2
+ srw %r5, %r5, %r6 # Number of word transfers
+ mtctr %r5
+
+copy_loop:
+ lwzu %r5, 4(%r3)
+ stwu %r5, 4(%r4)
+ bdnz copy_loop
+
+#endif /* PK_BOOT_FROM_ROM */
+
+
+ ## Call the system setup code.
+
+ bl __ppe42_system_setup
+
+ ## Call the application. If for some reason we return from
+ ## the call of the application we call an alternate entry point of the
+ ## idle thread.
+ ##
+ ## An initial argc/argv can be passed into main(). argc is expected to
+ ## be a 32-bit immediate integer, and argv is expected to be a 32-bit
+ ## absolute or relocatable expression.
+
+ _liwa %r3, PPE42_ARGC_INITIAL
+ _liw %r4, PPE42_ARGV_INITIAL
+ bl __pk_main
+
+ b __pk_idle_thread_from_bootloader
+
+ .epilogue __pk_boot
+
diff --git a/src/ppe/pk/ppe42/ppe42_cache.h b/src/ppe/pk/ppe42/ppe42_cache.h
new file mode 100644
index 0000000..16340f0
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_cache.h
@@ -0,0 +1,126 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_cache.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_CACHE_H__
+#define __PPE42_CACHE_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_cache.h
+/// \brief PowerPC-lite (PPE) cache management header for PK
+///
+/// The data cache flush/invalidate macros defined here create a compiler
+/// memory barrier that will cause GCC to flush/invalidate all memory data
+/// held in registers before the macro.
+
+#ifndef __ASSEMBLER__
+
+/// Determine cache-alignment of a pointer or byte-count
+#define cache_aligned(x) \
+ ((((unsigned long)(x)) & (POW2_32(LOG_CACHE_LINE_SIZE) - 1)) == 0)
+
+/// Cache-align a pointer or byte count. If the 'direction' is <= 0 then we
+/// round down, else round up.
+#define cache_align(x, direction) \
+ ({ \
+ unsigned long __x = (unsigned long)(x); \
+ unsigned long __r; \
+ if ((direction) <= 0) { \
+ __r = __x & ~(((unsigned long)CACHE_LINE_SIZE) - 1); \
+ } else { \
+ if (__x % CACHE_LINE_SIZE) { \
+ __r = __x + (CACHE_LINE_SIZE - (__x % CACHE_LINE_SIZE)); \
+ } \
+ } \
+ (void *)__r; \
+ })
+
+/// Data Cache Block Flush
+#define dcbf(p) asm volatile ("dcbf 0, %0" : : "r" (p) : "memory")
+
+/// Data Cache Block Touch
+#define dcbt(p) asm volatile ("dcbt 0, %0" : : "r" (p) : "memory")
+
+/// Data Cache Block Invalidate (Privileged)
+#define dcbi(p) asm volatile ("dcbi 0, %0" : : "r" (p) : "memory")
+
+void
+dcache_invalidate_all(void);
+
+void
+dcache_flush_all(void);
+
+void
+dcache_invalidate(void *p, size_t bytes);
+
+void
+dcache_flush(void *p, size_t bytes);
+
+/// Invalidate a line in the D-cache
+///
+/// \param p An address withing the cache line to be invalidated.
+///
+/// The dcache_invalidate_line() API is used to invalidate a single cache line
+/// containing the address \a p. Note that invalidation is a destructive
+/// operation that may cause the loss of information. It is the caller's
+/// responsibility to insure that no useful data is inadverdently invalidated.
+/// D-cache invalidation is more-or-less a no-op for data either not in the
+/// cache or marked as non-cacheable.
+///
+/// This API always issues a sync() after the invalidation.
+
+static inline void
+dcache_invalidate_line(void *p)
+{
+ dcbi(p);
+ sync();
+}
+
+/// Flush and invalidate a line from the D-cache
+///
+/// \param p An address within the cache line to be flushed.
+///
+/// The dcache_flush_line() API can be used as a shortcut to flush and
+/// invalidate a single cache line. Note that flushing is not a destructive
+/// operation in the sense that no information is lost, however the caller
+/// must make sure that the entirity of the data to be flushed is contained in
+/// the line that includes the address \a p. D-cache flush is more-or-less a
+/// no-op for data either not in the cache or marked as non-cacheable.
+///
+/// This API always issues a sync() after the flush.
+
+static inline void
+dcache_flush_line(void *p)
+{
+ dcbf(p);
+ sync();
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE42_CAHE_H__ */
diff --git a/src/ppe/pk/ppe42/ppe42_context.h b/src/ppe/pk/ppe42/ppe42_context.h
new file mode 100644
index 0000000..68d29e3
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_context.h
@@ -0,0 +1,225 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_context.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_CONTEXT_H__
+#define __PPE42_CONTEXT_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_context.h
+/// \brief PPE42 Machine and Thread context for PK
+
+/// \page ppe42_machine_context PPE42 Assembler Macros for PK Machine
+/// Context (Critical Sections)
+///
+/// \section _pk_enter_critical \b _pk_critical_section_enter/exit
+///
+/// These macro encapsulates the instruction sequences required to enter and
+/// exit critical sections, along with the machine context save for later
+/// exiting the critical section.
+///
+/// \arg \c ctxreg A register that will hold (holds) the machine context (MSR)
+/// prior to entering the critical section (to be restored) for \c
+/// _pk_critical_section_enter (\c _pk_critical_section_exit).
+///
+/// \arg \c scrreg A scratch register required for the computation of
+/// \c _pk_critical_section_enter.
+///
+/// Forms:
+///
+/// \b _pk_critical_section_enter \a priority, \a ctxreg, \a scrreg - Enter a
+/// critical section \n
+/// \b _pk_critical_section_exit \a ctxreg - Exit a critical section
+
+#ifdef __ASSEMBLER__
+
+ .set _msr_ee_bit, MSR_EE_BIT
+
+ .macro _pk_critical_section_enter ctxreg, scrreg
+ mfmsr \ctxreg
+ wrteei 0
+ .endm
+
+ .macro _pk_critical_section_exit ctxreg
+ mtmsr \ctxreg
+ .endm
+
+// ****************************************************************************
+// PK context save/restore macros for 32-bit Embedded PowerPC
+// ****************************************************************************
+
+// All stack frames are 8-byte aligned in conformance with the EABI. PK
+// never saves or restores GPR2 or GPR13. GPR13 is constant in (E)ABI
+// applications - the base of the read-write small data area. GPR2 is
+// system-reserved in ABI applications, and is the base for read-only small data
+// in EABI applications.
+
+// USPRG0 holds the __PkKernelContext structure (defined in ppe42.h) that
+// represents the current kernel context. The layout is as follows:
+//
+// Bits Meaning
+// ==============
+// 0 The 'thread_mode' flag
+// 1 The 'processing_interrupt" flag
+// 2:7 The thread priority of the running thread
+// 8 The 'discard_ctx' flag
+// 9:15 The IRQ currently being processed
+// 16:31 The application specific data
+//
+// When PK is initialized USPRG0 is initialized to 0. When thread-mode is
+// entered (by pk_start_threads()) bit 0 is set to 1. If desired,
+// once initialized (with pk_initialize()) PK can simply
+// handle interrupts, reverting back to the non-thread-mode idle loop when
+// there's nothing to do.
+//
+
+ ## ------------------------------------------------------------
+ ## Unused registers for embedded PPE42`
+ ## ------------------------------------------------------------
+
+ ## Registers GPR2 and GPR13 are never saved or restored. In ABI and
+ ## EABI applications these registers are constant.
+
+ .set UNUSED_GPR2, 0x2 # Dedicated; EABI read-only small data area
+ .set UNUSED_GPR13, 0xd # Dedicated; (E)ABI read-write small data area
+
+ ## ------------------------------------------------------------
+ ## The PK context layout for Embedded PPE42
+ ## ------------------------------------------------------------
+
+ .set PK_CTX_GPR1, 0x00 # Dedicated; Stack pointer
+ .set PK_CTX_LINKAGE, 0x04 # Slot for handler to store LR
+ .set PK_CTX_GPR3, 0x08 # Volatile; Parameter; Return Value
+ .set PK_CTX_GPR4, 0x0c # Volatile; Parameter
+ .set PK_CTX_GPR5, 0x10 # Volatile; Parameter
+ .set PK_CTX_GPR6, 0x14 # Volatile; Parameter
+ .set PK_CTX_CR, 0x18 # Condition register
+ .set PK_CTX_LR, 0x1c # Link register
+
+ .set PK_CTX_GPR7, 0x20 # Volatile; Parameter
+ .set PK_CTX_GPR8, 0x24 # Volatile; Parameter
+ .set PK_CTX_GPR9, 0x28 # Volatile; Parameter
+ .set PK_CTX_GPR10, 0x2c # Volatile; Parameter
+ .set PK_CTX_GPR28, 0x30 # Non-volatile
+ .set PK_CTX_GPR29, 0x34 # Non-volatile
+ .set PK_CTX_GPR30, 0x38 # Non-volatile
+ .set PK_CTX_GPR31, 0x3c # Non-volatile
+
+ .set PK_CTX_XER, 0x40 # Fixed-point exception register
+ .set PK_CTX_CTR, 0x44 # Count register
+ .set PK_CTX_SRR0, 0x48 # Save/restore register 0
+ .set PK_CTX_SRR1, 0x4c # Save/restore register 1
+ .set PK_CTX_GPR0, 0x50 # Volatile; Language specific
+ .set PK_CTX_KERNEL_CTX, 0x54 # Saved __PkKernelContext for IRQ
+
+ .set PK_CTX_SIZE, 0x58 # Must be 8-byte aligned
+
+ ## ------------------------------------------------------------
+ ## Push the interrupted context if necessary
+ ##
+ ## This macro saves off some context in preparation for calling
+ ## the pk_ctx_check_discard routine. This is an attempt to use
+ ## the 32 byte cache more efficiently.
+ ##
+ ## 8 Instructions
+ ## ------------------------------------------------------------
+ ##
+
+ .macro _pk_ctx_push_as_needed branch_addr:req
+
+ stwu %r1, -PK_CTX_SIZE(%r1)
+ stvd %d3, PK_CTX_GPR3(%r1)
+ mfcr %r3
+ mflr %r4
+ stvd %d3, PK_CTX_CR(%r1)
+ _liw %r3, \branch_addr
+ b ctx_check_discard
+ .endm
+
+
+ ## ------------------------------------------------------------
+ ## update the kernel context in response to an interrupt.
+ ## ------------------------------------------------------------
+
+ ## The kernel context is updated with the currently active
+ ## IRQ in bits 9:15.
+
+ .macro _update_kernel_context irqreg, ctxreg
+ rlwimi \ctxreg, \irqreg, 16, 9, 15 //set the irq #
+ oris \ctxreg, \ctxreg, 0x4000 //set the 'processing_interrupt' flag
+ mtsprg0 \ctxreg
+
+#if PK_KERNEL_TRACE_ENABLE
+ mr %r31, \irqreg
+ srwi \ctxreg, \ctxreg, 16
+ PK_KERN_TRACE_ASM16("INTERRUPT_CONTEXT(0x%04x)", \ctxreg)
+ mr \irqreg, %r31
+#endif
+
+ .endm
+
+#else /* __ASSEMBLER__ */
+
+/// PK thread context layout as a C structure.
+///
+/// This is the structure of the stack area pointed to by
+/// thread->saved_stack_pointer when a thread is fully context-switched out.
+
+typedef struct {
+ uint32_t r1;
+ uint32_t linkage;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t cr;
+ uint32_t lr;
+
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r28;
+ uint32_t r29;
+ uint32_t r30;
+ uint32_t r31;
+
+ uint32_t xer;
+ uint32_t ctr;
+ uint32_t srr0;
+ uint32_t srr1;
+ uint32_t r0;
+ uint32_t sprg0;
+
+} PkThreadContext;
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE42_CONTEXT_H__ */
+
+
diff --git a/src/ppe/pk/ppe42/ppe42_core.c b/src/ppe/pk/ppe42/ppe42_core.c
new file mode 100644
index 0000000..ad4b2c3
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_core.c
@@ -0,0 +1,150 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_core.c
+/// \brief The final bits of PK runtime code required to complete the PPE42
+/// port.
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present during runtime in any PK application.
+
+#define __PPE42_CORE_C__
+
+#include "pk.h"
+
+typedef union
+{
+ uint64_t value;
+ struct
+ {
+ uint32_t dec_start;
+ uint32_t dec_change_tag;
+ };
+}ppe42_timebase_data_t;
+
+ppe42_timebase_data_t ppe42_tb_data = {0};
+PkTimebase ppe42_64bit_timebase = 0;
+
+
+#if PK_TIMER_SUPPORT
+
+// The tickless kernel timer mechanism for PPE42
+//
+// This routine must be called from a critical section.
+//
+// Tickless timeouts are provided by programming the PIT timer based on when
+// the next timeout will occur. If the timeout is for the end of time there's
+// nothing to do - PK does not use auto-reload mode so no more PIT interrupts
+// will be arriving. Otherwise, if the timeout is longer than the 32-bit PIT
+// timer can handle, we simply schedule the timeout for 2**32 - 1 and
+// __pk_timer_handler() will keep rescheduling it until it finally occurs.
+// If the \a timeout is in the past, we schedule the PIT interrupt for 1 tick
+// in the future in accordance with the PK specification.
+
+#ifndef APPCFG_USE_EXT_TIMEBASE
+void
+__pk_schedule_hardware_timeout(PkTimebase timeout)
+{
+ PkTimebase now;
+ uint32_t new_dec;
+ uint32_t dec;
+
+ if (timeout != PK_TIMEBASE_MAX) {
+
+ now = pk_timebase_get();
+
+ if (timeout <= now) {
+ new_dec = 1;
+ } else if ((timeout - now) > 0xffff0000) {
+ new_dec = 0xffff0000;
+ } else {
+ new_dec = timeout - now;
+ }
+
+ //read and write the DEC back-to-back so that we lose as little time
+ //as possible
+ dec = mfspr(SPRN_DEC);
+ mtspr(SPRN_DEC, new_dec);
+
+ //update our 64bit accumulator with how much time has advanced since
+ //we last changed it.
+ ppe42_64bit_timebase += ppe42_tb_data.dec_start - dec;
+
+ //update our start time so we know how much time has advanced since
+ //this update of the accumulator
+ ppe42_tb_data.dec_start = new_dec;
+ ppe42_tb_data.dec_change_tag++;
+ }
+}
+
+#else
+
+void
+__pk_schedule_hardware_timeout(PkTimebase timeout)
+{
+ PkTimebase now;
+ PkTimebase diff;
+ uint32_t new_dec;
+
+ if (timeout != PK_TIMEBASE_MAX) {
+
+ now = pk_timebase_get();
+
+ //update our 64bit accumulator with the current snapshot
+ ppe42_64bit_timebase = now;
+
+ if (timeout <= now)
+ {
+ new_dec = 1;
+ }
+ else
+ {
+ diff = (timeout - now);
+
+ if (diff > 0xfffffffful)
+ {
+ new_dec = 0xffffffff;
+ }
+ else
+ {
+ new_dec = diff;
+ }
+ }
+
+ mtspr(SPRN_DEC, new_dec);
+
+ }
+}
+
+#endif /* APPCFG_USE_EXT_TIMEBASE */
+
+#endif /* PK_TIMER_SUPPORT */
+
+#undef __PPE42_CORE_C__
diff --git a/src/ppe/pk/ppe42/ppe42_exceptions.S b/src/ppe/pk/ppe42/ppe42_exceptions.S
new file mode 100644
index 0000000..9d79429
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_exceptions.S
@@ -0,0 +1,521 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_exceptions.S $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_exceptions.S
+/// \brief PPE42 exception vector area.
+///
+/// \cond
+
+ .nolist
+#include "pk.h"
+ .list
+
+## declare and initializes global variables that hold external irq config data
+## Each PPE macro type (GPE, CME, and SBE) will have it's own implementation of this macro
+## defined in (gpe, cme, sbe)_common.h
+ .hwmacro_irq_cfg_bitmaps
+
+### ****************************************************************************
+### .vectors - This section contains all ppe42 exception vectors
+###
+### ****************************************************************************
+
+ .section .vectors, "ax", @progbits
+
+ .global __vectors
+
+__vectors:
+
+ ############################################################
+ # 0x0000 : Machine Check
+ ############################################################
+
+ ### Unmaskable interrupts (including program interrupts) are promoted
+ ### to machine check interrupts if MSR[UIE] = 0 and MSR[ME] = 1.
+ ### If the machine check was caused by a program interrupt it
+ ### will be forwarded to the program exception handler.
+__machine_check:
+
+ PPE42_MACHINE_CHECK_HANDLER
+
+ ############################################################
+ # 0x0040 : System Reset
+ ############################################################
+ .global __system_reset
+ .org __vectors + 0x0040
+__system_reset:
+ b __pk_boot
+
+ ############################################################
+ # 0x0060 : Data Storage Interrupt
+ ############################################################
+
+ .org __vectors + 0x0060
+__data_storage:
+
+ PPE42_DATA_STORAGE_HANDLER
+
+ ############################################################
+ # 0x0080 : Instruction Storage Interrupt
+ ############################################################
+
+ .org __vectors + 0x0080
+__instruction_storage:
+
+ PPE42_INSTRUCTION_STORAGE_HANDLER
+
+
+ ############################################################
+ # 0x00A0 : External Interrupt
+ ############################################################
+
+ .org __vectors + 0x00A0
+__external_interrupt_vector:
+ _pk_ctx_push_as_needed __get_ext_irq
+
+ ############################################################
+ # 0x00C0 : Alignment Exception
+ ############################################################
+
+ .org __vectors + 0x00C0
+__alignment_exception:
+
+ PPE42_ALIGNMENT_HANDLER
+
+
+ ############################################################
+ # 0x00E0 : Program Interrupt
+ ############################################################
+
+ .org __vectors + 0x00E0
+
+ ### Program exceptions are utilized for emulating the system call
+ ### instruction (0x44000002) which is used for doing context
+ ### switches between threads. They can also be used by the code
+ ### to signal an exception in an error scenario.
+__program_exception:
+ _pk_ctx_push_as_needed program_exception_handler
+
+
+ ############################################################
+ # 0x0100 : DEC Interrupts
+ ############################################################
+
+ .org __vectors + 0x0100
+__dec_interrupt:
+ _pk_ctx_push_as_needed dec_handler
+
+ ############################################################
+ # 0x0120 : FIT Interrupts
+ ############################################################
+ .org __vectors + 0x0120
+__fit_interrupt:
+
+ _pk_ctx_push_as_needed fit_handler
+
+ ############################################################
+ # 0x0140 : Watchdog Interrupts
+ ############################################################
+ .org __vectors + 0x0140
+__watchdog_interrupt:
+
+ _pk_ctx_push_as_needed watchdog_handler
+
+
+### ****************************************************************************
+### The rest of the code in this file doesn't have to be placed anywhere
+### special, so just place it in the .text section.
+### ****************************************************************************
+
+ .section .text, "ax", @progbits
+
+
+ ## The idle thread has no permanent register context. The idle thread
+ ## entry point is re-entered whenever the idle thread is scheduled.
+
+ .global __pk_idle_thread
+ .global __pk_idle_thread_from_bootloader
+
+__pk_idle_thread:
+
+ ## The idle thread 'uses' the kernel stack. Any register context
+ ## pushed here is redundant and is wiped out/ignored every time the
+ ## idle thread is re-scheduled.
+
+ ## The idle thread simply establishes a default machine context and
+ ## enters the wait-enable state. The idle thread is always entered
+ ## with interrupts disabled.
+ ##
+ ## The kernel context is initialized to indicate that the idle thread
+ ## is running - the idle thread priority is PK_THREADS, the
+ ## 'thread-mode' bit is asserted and so is the 'discard-ctx" bit.
+ ## In addition, the previous kernel context is stored in the lower
+ ## 16 bits.
+ ##
+ ## This loop can also be called from the PK bootloader if main()
+ ## returns - in which case we don't muck with the SPRG0 or the stack
+ ## pointer.
+ mfsprg0 %r3
+ srwi %r3, %r3, 16
+ oris %r3, %r3, (PK_THREADS << 8) | PPE42_THREAD_MODE | PPE42_DISCARD_CTX
+ mtsprg0 %r3
+ _lwzsd %r1, __pk_kernel_stack
+
+__pk_idle_thread_from_bootloader:
+
+ PK_KERN_TRACE_ASM16("ENTER_IDLE_STATE")
+
+ _lwzsd %r3, __pk_thread_machine_context_default
+ _oriwa %r3, %r3, MSR_WE
+ mtmsr %r3
+ b .
+
+ ## pk_halt() is implemented on the ppe42 by writing a value of 0x3 to
+ ## the RST field of the DBCR.
+ .global pk_halt
+pk_halt:
+ lis %r31, 0x3000
+ mtdbcr %r31
+ .long 0
+
+
+dec_handler:
+
+ ## The portable timer handler of PK is a full-mode handler with the prototype:
+ ## void (*pk_timer_handler)(void).
+ ##
+ ## To support the portable specification, the kernel clears the
+ ## interrupt by writing the DIS back into the TSR before calling the
+ ## handler. The timer handler does not take any arguments.
+
+ li %r4, PPE42_IRQ_DEC
+ _update_kernel_context %r4, %r3
+
+ _liwa %r3, TSR_DIS
+ mttsr %r3
+
+ bl __pk_timer_handler
+ b check_for_ext_interrupt
+
+program_exception_handler:
+ ## first check if exception was caused by an illegal 'sc' instruction
+ mfspr %r3, SPRN_EDR
+ _liw %r4, PPE42_SC_INST
+ cmpwbeq %r3, %r4, __sc_helper
+ _pk_panic PPE42_ILLEGAL_INSTRUCTION
+
+ ## Saved SRR0 is currently pointing to the 'sc' instruction. We need to advance it
+ ## to the next instruction so that we don't end up in an endless loop (something
+ ## that the ppc sc instruction does automatically).
+__sc_helper:
+ mfsrr0 %r4
+ _lwzsd %r3, __pk_saved_sp
+ addi %r4, %r4, 4
+ stw %r4, PK_CTX_SRR0(%r3)
+
+ .global __pk_next_thread_resume
+__pk_next_thread_resume:
+
+ _lwzsd %r3, __pk_next_thread
+ _stwsd %r3, __pk_current_thread
+
+ ## Enter the wait enabled state if the thread pointer is null
+ bwz %r3, __pk_idle_thread
+
+ ## switch to the new thread stack
+ lwz %r1, PK_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
+
+ ## load sprg0 from the stack and update the thread priority
+ ## in case it changed.
+restore_and_update_sprg0:
+ _lbzsd %r31, __pk_next_priority
+
+ PK_KERN_TRACE_ASM16("RESUME_THREAD(%d)", %r31)
+
+ lwz %r3, PK_CTX_KERNEL_CTX(%r1)
+ rlwimi %r3, %r31, 24, 2, 7
+ mtsprg0 %r3
+
+ b ctx_pop
+
+fit_handler:
+
+ ## The FIT handler is user defined. By
+ ## convention the kernel clears the interrupt by writing the FIS back
+ ## into the TSR.
+
+ li %r4, PPE42_IRQ_FIT
+
+ _update_kernel_context %r4, %r3
+
+ _lwzsd %r3, __ppe42_fit_arg
+
+ _liwa %r6, TSR_FIS
+ mttsr %r6
+
+ _lwzsd %r6, __ppe42_fit_routine
+ mtlr %r6
+ blrl
+
+ b check_for_ext_interrupt
+
+watchdog_handler:
+ ## Watchdog setup is described in the PK Specification.
+ ## The kernel clears TSR[WIS] prior to calling the handler.
+
+ li %r4, PPE42_IRQ_WATCHDOG
+
+ _update_kernel_context %r4, %r3
+
+ _liwa %r6, TSR_WIS
+ mttsr %r6
+
+ _lwzsd %r6, __ppe42_watchdog_routine
+ mtlr %r6
+ blrl
+
+ b check_for_ext_interrupt
+
+
+ ## Check if we can disard the interrupted context.
+ ## This routine expects r3, r4, lr, and cr to already be pushed.
+ ## It also expects r3 to hold the address of the function to jump
+ ## to after the interrupted context has been pushed (if necessary).
+
+ .align 5
+ctx_check_discard:
+
+ ## Prepare to jump to the branch function that was passed in
+ mtlr %r3
+
+ ## Check if the DISCARD_CTX bit is set in the kernel context
+ mfsprg0 %r3
+ bb0wi %r3, PPE42_DISCARD_CTX_BIT, ctx_continue_push
+
+ctx_discard:
+ ## DISCARD_CTX bit was set. Discard stack and branch to interrupt
+ ## handler code
+ addi %r1, %r1, PK_CTX_SIZE
+ blr
+
+ ## DISCARD_CTX bit was not set. Continue saving full context.
+ ## (r3, r4, lr, and cr have already been saved for us) and
+ ## r3 contains the interrupted kernel context
+
+ctx_continue_push:
+
+ stvd %d5, PK_CTX_GPR5(%r1)
+ stvd %d7, PK_CTX_GPR7(%r1)
+ stvd %d9, PK_CTX_GPR9(%r1)
+ stvd %d28, PK_CTX_GPR28(%r1)
+ stvd %d30, PK_CTX_GPR30(%r1)
+ mfxer %r5
+ mfctr %r6
+ stvd %d5, PK_CTX_XER(%r1)
+ mfsrr0 %r7
+ mfsrr1 %r8
+ stvd %d7, PK_CTX_SRR0(%r1)
+ stw %r0, PK_CTX_GPR0(%r1)
+ stw %r3, PK_CTX_KERNEL_CTX(%r1)
+
+ ## If the 'processing interrupt' bit is set then we were already
+ ## using the kernel stack and don't need to modify or save the current
+ ## stack pointer.
+ bb1wi %r3, PPE42_PROC_IRQ_BIT, ctx_push_completed
+
+ ## load the pointer to the current thread control block
+ _lwzsd %r4, __pk_current_thread
+
+ ## don't save the stack pointer in the thread control block
+ ## if the current thread was the idle thread (null pointer)
+ bwz %r4, switch_to_kernel_stack
+
+ ## we interrupted a bonafide thread, so save off the stack
+ ## pointer
+ stw %r1, PK_THREAD_OFFSET_SAVED_STACK_POINTER(%r4)
+
+switch_to_kernel_stack:
+ _stwsd %r1, __pk_saved_sp
+ _lwzsd %r1, __pk_kernel_stack
+
+ctx_push_completed:
+ blr
+
+__get_ext_irq:
+
+ ## Entry invariants:
+ ## 1. external interupts are disabled;
+ ## 2. previous context has ben saved off
+ ## 3. r3 contains the kernel context
+ ## 4. r1 points to the kernel stack
+
+ ## This is HW Macro specific code that is responsible for finding the
+ ## IRQ # and storing it in r4 (phantom IRQ's are assigned a value of EXTERNAL_IRQS).
+
+ hwmacro_get_ext_irq
+
+ ## An active or phantom IRQ was found.
+ ## R3 has the context of the interrupted thread or bottom half
+ ## R4 has the IRQ number.
+ ## The IRQ is converted into a pointer to an 8-byte handler
+ ## structure, and the handler is dispatched. The call is made with the
+ ## parameters:
+
+ ## R3 = private data ptr
+ ## R4 = irq
+
+call_external_irq_handler:
+
+ _update_kernel_context %r4, %r3
+ slwi %r3, %r4, 3 //multiply the irq# by 8
+ _liw %r6, __ppe42_irq_handlers
+ lwzx %r5, %r6, %r3
+ addi %r3, %r3, 4
+ lwzx %r3, %r6, %r3
+ mtlr %r5
+ blrl
+
+ ## Once the interrupt handler returns, check if any interrupts are
+ ## waiting and handle them now.
+
+check_for_ext_interrupt:
+
+ ## Set the CTX_DISCARD bit in the kernel context so that if there is
+ ## an interrupt it will not bother saving the full context.
+ mfsprg0 %r31
+ oris %r31, %r31, PPE42_DISCARD_CTX
+ mtsprg0 %r31
+
+ ###### Enable/Disable External Interrupts #####
+ wrteei 1
+ wrteei 0
+
+ ## If we made it this far, there must not be any interrupts pending.
+ ## If bottom half processing was interrupted we need to restore it
+check_interrupted_bh:
+
+ ## If the thread ID is 33 then the bottom half handler was interrupted
+ ## and needs to be restored.
+ extrwi %r4, %r31, 6, 2
+ cmpwi %r4, 33
+ beq ctx_pop_with_sprg0
+
+check_for_bh:
+ ## if the bottom half queue is pointing to itself then the queue is
+ ## empty and there are no bottom halves that need processing.
+ _lwzsd %r4, _pk_bh_queue
+ lwz %r5, 0(%r4)
+ cmplwbeq %r4, %r5, restore_interrupted_sp
+
+process_bottom_halves:
+ ## Clear the CTX_DISCARD bit so that interrupted bottom half context
+ ## will be saved in case an interrupt occurs after this point. Also
+ ## set the thread ID to 33 so that we know to restore the bottom half
+ ## context that was interrupted.
+ rlwinm %r3, %r31, 0, 9, 1 //clear thread id + discard bit
+ oris %r3, %r3, 0x2100 //set thread id to 33
+ mtsprg0 %r3 //set bottom half context
+
+ ## branch to a C function that processes bottom halves
+ wrteei 1
+ bl _pk_process_bh
+ wrteei 0
+
+ ## restore the previous kernel context (with discard bit set)
+ mtsprg0 %r31
+
+restore_interrupted_sp:
+ ## restore the interrupted thread stack pointer
+ _lwzsd %r1, __pk_saved_sp
+
+ ## If we are not in thread mode (i.e., we took an interrupt in an
+ ## interupt-only configuration of PK or after pk_initialize() but
+ ## before pk_start_threads) simply pop the context and RFI - in this
+ ## case we'll most likely be returning to main() or the non-thread-mode
+ ## idle thread.
+
+check_thread_mode:
+ bb0wi %r31, PPE42_THREAD_MODE_BIT, ctx_pop_with_sprg0
+
+ ## Check if external interrupt activated a delayed context switch. The
+ ## C-level code has taken care of the scheduling decisions - we simply
+ ## need to implement them here.
+check_for_ctx_switch:
+
+ _lwzsd %r3, __pk_delayed_switch
+ bwz %r3, check_for_idle_thread
+
+ ## Clear the delayed switch flag and go to the context switch code to
+ ## finish the switch.
+
+ li %r3, 0
+ _stwsd %r3, __pk_delayed_switch
+
+ b __pk_next_thread_resume
+
+ ## check if we should switch to the wait enabled state (idle)
+check_for_idle_thread:
+ _lwzsd %r3, __pk_current_thread
+ bwz %r3, __pk_idle_thread
+
+ctx_pop_with_sprg0:
+ ## we must ensure that interrupts are disabled while restoring context
+ ##
+ ## restore sprg0 from the saved context
+ lwz %r0, PK_CTX_KERNEL_CTX(%r1)
+ mtsprg0 %r0
+
+#if PK_KERNEL_TRACE_ENABLE
+ srwi %r0, %r0, 16
+ PK_KERN_TRACE_ASM16("RESUME_CONTEXT(0x%04x)", %r0)
+#endif
+
+ctx_pop:
+ lwz %r0, PK_CTX_GPR0(%r1)
+ lvd %d7, PK_CTX_SRR0(%r1)
+ mtsrr1 %r8
+ mtsrr0 %r7
+ lvd %d5, PK_CTX_XER(%r1)
+ mtctr %r6
+ mtxer %r5
+ lvd %d30, PK_CTX_GPR30(%r1)
+ lvd %d28, PK_CTX_GPR28(%r1)
+ lvd %d9, PK_CTX_GPR9(%r1)
+ lvd %d7, PK_CTX_GPR7(%r1)
+ lvd %d5, PK_CTX_GPR5(%r1)
+ lvd %d3, PK_CTX_CR(%r1)
+ mtlr %r4
+ mtcr %r3
+ lvd %d3, PK_CTX_GPR3(%r1)
+ addi %r1, %r1, PK_CTX_SIZE
+
+ rfi
+
+/// \endcond
diff --git a/src/ppe/pk/ppe42/ppe42_gcc.c b/src/ppe/pk/ppe42/ppe42_gcc.c
new file mode 100644
index 0000000..37674dc
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_gcc.c
@@ -0,0 +1,329 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_gcc.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_gcc.h
+/// \brief 32-bit PowerPC functions expected by GCC
+///
+/// GCC expects certain built-in functions to be defined in the environment.
+/// Since PK applications are statically linked, we must define these
+/// functions ourselves to avoid a static link with the GCC libraries, which
+/// would legaly require us to distribute (at least) the binary forms of PK
+/// applications.
+///
+/// We obviously had to look at some GCC library code to understand the
+/// specifications of these routines. However, all of the code here is new -
+/// no structure definitions or lines of executable code were copied from the
+/// GCC sources.
+
+#include "pk.h"
+#include "ppe42_gcc.h"
+
+/// A 64-bit logical right shift.
+///
+/// Note that shifts with negative shift counts or shifts with shift counts
+/// longer than 63 bits are undefined.
+
+uint64_t
+__lshrdi3(uint64_t x, int i)
+{
+ Uint64 input, result;
+
+ if (i == 0) {
+ return x;
+ }
+
+ input.value = x;
+
+ if (i >= 32) {
+ result.word[0] = 0;
+ result.word[1] = input.word[0] >> (i - 32);
+ } else {
+ result.word[0] = input.word[0] >> i;
+ result.word[1] = (input.word[1] >> i) | (input.word[0] << (32 - i));
+ }
+
+ return result.value;
+}
+
+
+/// A 64 bit arithmetic left shift.
+///
+/// Note that shifts with negative shift counts or shifts with shift counts
+/// longer than 63 bits are undefined.
+
+uint64_t
+__ashldi3(uint64_t x, int i)
+{
+ Uint64 input, result;
+
+ if (i == 0) {
+ return x;
+ }
+
+ input.value = x;
+
+ if (i >= 32) {
+ result.word[1] = 0;
+ result.word[0] = input.word[1] << (i - 32);
+ } else {
+ result.word[1] = input.word[1] << i;
+ result.word[0] = (input.word[0] << i) | (input.word[1] >> (32 - i));
+ }
+
+ return result.value ;
+
+}
+
+
+/// A 64 bit arithmetic right shift.
+///
+/// Note that shifts with negative shift counts or shifts with shift counts
+/// longer than 63 bits are undefined.
+
+uint64_t
+__ashrdi3(uint64_t x, int i)
+{
+ Int64 input, result;
+
+ if (i == 0) {
+ return x;
+ }
+
+ input.value = x;
+
+ if (i >= 32) {
+ result.word[0] = input.word[0] >> 31;
+ result.word[1] = input.word[0] >> (i - 32);
+ } else {
+ result.word[0] = input.word[0] >> i;
+ result.word[1] =
+ (((uint32_t)input.word[1]) >> i) |
+ (input.word[0] << (32 - i));
+ }
+
+ return result.value ;
+
+}
+
+
+/// 32-bit Population count
+
+// This is a well-known divide-and-conquer algorithm, e.g. look on Wikipedia
+// under "Hamming Weight". The idea is to compute sums of adjacent bit
+// segments in parallel, in place.
+
+int
+__popcountsi2(uint32_t x)
+{
+ uint32_t m1 = 0x55555555;
+ uint32_t m2 = 0x33333333;
+ uint32_t m4 = 0x0f0f0f0f;
+ x -= (x >> 1) & m1; /* Sum pairs of bits */
+ x = (x & m2) + ((x >> 2) & m2);/* Sum 4-bit segments */
+ x = (x + (x >> 4)) & m4; /* Sum 8-bit segments */
+ x += x >> 8; /* Sum 16-bit segments */
+ return (x + (x >> 16)) & 0x3f; /* Final sum */
+}
+
+
+/// 64-bit Population count
+
+int
+__popcountdi2(uint64_t x)
+{
+ return __popcountsi2(x >> 32) + __popcountsi2(x & 0xffffffff);
+}
+
+
+// 64-bit divides
+//
+// For the unsigned case, note that divide by 0 returns quotient = remainder =
+// 0.
+//
+// For the signed case, in general we perform the division on the absolute
+// values and fix the signs of the quotient and remainder at the end.
+//
+// For the signed case, the convention in other libraries seems to be to
+// ignore the case of the most-negative integer. Although it seems "wrong" to
+// return the wrong answer when the right answer can be easily computed, in
+// the interest of code size we follow the convention here and ignore the most
+// negative integer.
+//
+// The assembler routine __ppe42_udiv64() assembles to ??? bytes. The full C
+// routine __ppc_sdiv64 compiles to ??? bytes with the most-negative checks,
+// but only ??? bytes as configured here.
+
+// For the signed cases, we need to handle the special case that the dividend
+// or divisor is the most negative integer.
+//
+// If the dividend is the most negative integer, then dividing this integer by
+// -1 would overflow as a positive quotient, so we set quotient and remainder
+// to 0 in this case. For divide by 1, the quotient is the most negative
+// integer. Otherwise we adjust the dividend by the absolute value of the
+// divisor, then fix up the quotient later by adding or subtracting 1.
+//
+// If the divisor is the most negative integer, then the quotient is always 0
+// unless the dividend is also the most negative integer, in which case the
+// quotient is 1 and the remainder is 0.
+//
+
+uint64_t
+__udivdi3(uint64_t u, uint64_t v)
+{
+ uint64_t quotient, remainder;
+
+ __ppe42_udiv64(u, v, &quotient, &remainder);
+ return quotient;
+}
+
+
+uint64_t
+__umoddi3(uint64_t u, uint64_t v)
+{
+ uint64_t quotient, remainder;
+
+ __ppe42_udiv64(u, v, &quotient, &remainder);
+ return remainder;
+}
+
+
+#if 0
+#define INT64_T_MIN ((int64_t)(0x8000000000000000ull))
+#endif
+
+void
+__ppe42_sdiv64(int64_t u, int64_t v,
+ int64_t *quotient, int64_t *remainder)
+{
+ int q_negate, r_negate;
+ uint64_t uu, uv;
+#if 0
+ int fixup = 0;
+#endif
+
+ q_negate = (u < 0) ^ (v < 0);
+ r_negate = (u < 0);
+ uu = (u < 0 ? -u : u);
+ uv = (v < 0 ? -v : v);
+
+#if 0
+ if (u == INT64_T_MIN) {
+ if (v == -1) {
+ *quotient = 0;
+ *remainder = 0;
+ return;
+ } else if (v == 1) {
+ *quotient = INT64_T_MIN;
+ *remainder = 0;
+ return;
+ } else if (v == INT64_T_MIN) {
+ *quotient = 1;
+ *remainder = 0;
+ return;
+ } else {
+ fixup = 1;
+ u += (v < 0 ? -v : v);
+ }
+ } else if (v == INT64_T_MIN) {
+ *quotient = 0;
+ *remainder = u;
+ return;
+ }
+#endif
+
+ __ppe42_udiv64(uu, uv, (uint64_t *)quotient, (uint64_t *)remainder);
+
+#if 0
+ if (fixup) {
+ *quotient += 1;
+ }
+#endif
+ if (q_negate) {
+ *quotient = -(*quotient);
+ }
+ if (r_negate) {
+ *remainder = -(*remainder);
+ }
+}
+
+
+int64_t
+__divdi3(int64_t u, int64_t v)
+{
+ int64_t quotient, remainder;
+
+ __ppe42_sdiv64(u, v, &quotient, &remainder);
+ return quotient;
+}
+
+
+int64_t
+__moddi3(int64_t u, int64_t v)
+{
+ int64_t quotient, remainder;
+
+ __ppe42_sdiv64(u, v, &quotient, &remainder);
+ return remainder;
+}
+
+
+/// 64-bit unsigned compare as a function, returning 0 (<), 1 (==) or 2 (>).
+
+int
+__ucmpdi2(uint64_t i_a, uint64_t i_b)
+{
+ Uint64 a, b;
+ int rv;
+
+ a.value = i_a;
+ b.value = i_b;
+
+ if (a.word[0] < b.word[0]) {
+ rv = 0;
+ } else if (a.word[0] > b.word[0]) {
+ rv = 2;
+ } else if (a.word[1] < b.word[1]) {
+ rv = 0;
+ } else if (a.word[1] > b.word[1]) {
+ rv = 2;
+ } else {
+ rv = 1;
+ }
+
+ return rv;
+}
+
+
+
+
+
+
+
+
diff --git a/src/ppe/pk/ppe42/ppe42_gcc.h b/src/ppe/pk/ppe42/ppe42_gcc.h
new file mode 100644
index 0000000..c5c16e8
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_gcc.h
@@ -0,0 +1,96 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_gcc.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_GCC_H__
+#define __PPE42_GCC_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_gcc.h
+/// \brief 32-bit functions expected by GCC
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/// A 64-bit unsigned integer type
+
+typedef union {
+ uint64_t value;
+ uint32_t word[2];
+} Uint64;
+
+/// A 64-bit signed integer type
+
+typedef union {
+ int64_t value;
+ int32_t word[2];
+} Int64;
+
+uint64_t
+__lshrdi3(uint64_t x, int i);
+
+uint64_t
+__ashldi3(uint64_t x, int i);
+
+uint64_t
+__ashrdi3(uint64_t x, int i);
+
+int
+__popcountsi2(uint32_t x);
+
+int
+__popcountdi2(uint64_t x);
+
+/// Unsigned 64/64 bit divide, returning quotient and remainder via pointers.
+
+void
+__ppe42_udiv64(uint64_t u, uint64_t v, uint64_t *q, uint64_t *r);
+
+/// Signed 64/64 bit divide, returning quotient and remainder via pointers.
+
+void
+__ppe42_sdiv64(int64_t u, int64_t v, int64_t *q, int64_t *r);
+
+uint64_t
+__udivdi3(uint64_t u, uint64_t v);
+
+int64_t
+__divdi3(int64_t u, int64_t v);
+
+int64_t
+__moddi3(int64_t u, int64_t v);
+
+uint64_t
+__umoddi3(uint64_t u, uint64_t v);
+
+int
+__ucmpdi2(uint64_t a, uint64_t b);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE42_GCC_H__ */
diff --git a/src/ppe/pk/ppe42/ppe42_init.c b/src/ppe/pk/ppe42/ppe42_init.c
new file mode 100644
index 0000000..dcc660a
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_init.c
@@ -0,0 +1,101 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_init.c
+/// \brief PPE42 initialization routines
+///
+/// The entry points in this file are routines that are typically used during
+/// initialization, and their code space could be deallocated and recovered if
+/// no longer needed by the application after initialization.
+
+#include "pk.h"
+#include "pk_trace.h"
+
+// Note that __ppe42_system_setup() is called from the PK bootloader early
+// in the initialization, at a point before the aplication has enabled
+// interrupts.
+
+// This function is expected to be defined by the macro specific code (GPE, CME, SBE)
+void __hwmacro_setup(void);
+
+
+void
+__ppe42_system_setup()
+{
+ //Only do this if the application hasn't provided a static table definition
+#ifndef STATIC_IRQ_TABLE
+ PkIrqId irq;
+
+ // Initialize the interrupt vectors.
+ for (irq = 0; irq < EXTERNAL_IRQS; irq++) {
+ __ppe42_irq_handlers[irq].handler = __ppe42_default_irq_handler;
+ }
+
+ //NOTE: EXTERNAL_IRQS is the phantom interrupt assigned irq
+ __ppe42_irq_handlers[irq].handler = __ppe42_phantom_irq_handler;
+
+ // Initialize special interrupt handlers
+
+ __ppe42_fit_routine = __ppe42_default_irq_handler;
+ __ppe42_fit_arg = 0;
+
+ __ppe42_watchdog_routine = __ppe42_default_irq_handler;
+ __ppe42_watchdog_arg = 0;
+
+/*
+ __ppe42_debug_routine = __ppe42_default_irq_handler;
+ __ppe42_debug_arg = 0;
+*/
+#endif /*STATIC_IRQ_TABLE*/
+
+ //Clear all status bits in the TSR
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+#ifdef APPCFG_USE_EXT_TIMEBASE
+ //Enable the DEC interrupt and configure it to use the external dec_timer signal
+ mtspr(SPRN_TCR, TCR_DIE | TCR_DS);
+#else
+ //Enable the DEC interrupt and configure it to use the internal clock signal
+ mtspr(SPRN_TCR, TCR_DIE);
+#endif /* APPCFG_USE_EXT_TIMEBASE */
+
+#if PK_TIMER_SUPPORT
+#if PK_TRACE_SUPPORT
+extern PkTraceBuffer g_pk_trace_buf;
+ //set the ppe instance id
+ g_pk_trace_buf.instance_id = (uint16_t)(mfspr(SPRN_PIR) & PIR_PPE_INSTANCE_MASK);
+#endif /* PK_TRACE_SUPPORT */
+#endif /* PK_TIMER_SUPPORT */
+
+ //call macro-specific setup
+ __hwmacro_setup();
+}
+
+
diff --git a/src/ppe/pk/ppe42/ppe42_irq.h b/src/ppe/pk/ppe42/ppe42_irq.h
new file mode 100644
index 0000000..b86a030
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_irq.h
@@ -0,0 +1,242 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_irq.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_IRQ_H__
+#define __PPE42_IRQ_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_irq.h
+/// \brief PPE42 interrupt handling for PK
+///
+/// Interrupt handling protocols and interrupt controller programming are
+/// inherently non-portable, however PK defines APIs that may be useful among
+/// different machines.
+///
+
+
+// Define pseudo-IRQ numbers for PPE42 built-in interrupts. These numbers
+// will appear in bits 16:23 of SPRG0 (__PkKernelContext) when the handlers
+// are active
+
+#define PPE42_EXC_MACHINE_CHECK 0x50
+#define PPE42_EXC_DATA_STORAGE 0x53
+#define PPE42_EXC_INSTRUCTION_STORAGE 0x54
+#define PPE42_EXC_ALIGNMENT 0x56
+#define PPE42_EXC_PROGRAM 0x57
+#define PPE42_IRQ_DEC 0x58
+#define PPE42_IRQ_FIT 0x59
+#define PPE42_IRQ_WATCHDOG 0x5A
+
+
+// Unhandled exceptions default to a kernel panic, but the application can
+// override these definition. Note that the exception area only allocates 32
+// bytes (8 instructions) to an unhandled exception, so any redefinition
+// would most likely be a branch to an application-defined handler.
+
+#ifndef PPE42_MACHINE_CHECK_HANDLER
+#define PPE42_MACHINE_CHECK_HANDLER PK_PANIC(0x0200)
+#endif
+
+#ifndef PPE42_DATA_STORAGE_HANDLER
+#define PPE42_DATA_STORAGE_HANDLER PK_PANIC(0x0300)
+#endif
+
+#ifndef PPE42_INSTRUCTION_STORAGE_HANDLER
+#define PPE42_INSTRUCTION_STORAGE_HANDLER PK_PANIC(0x0400)
+#endif
+
+#ifndef PPE42_ALIGNMENT_HANDLER
+#define PPE42_ALIGNMENT_HANDLER PK_PANIC(0x0600)
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////
+// PK API
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+/// An IRQ handler takes 2 arguments:
+/// \arg \c arg - Private handler data installed by \c ssx_irq_setup() or
+/// \c ssx_irq_handler_set().
+/// \arg \c irq - The IRQ id; to enable a generic handler to manipulate
+/// its own interrupt status .
+
+typedef void (*PkIrqHandler)(void* arg, PkIrqId irq);
+
+/// Declare a subroutine as an IRQ handler
+
+#define PK_IRQ_HANDLER(f) void f(void* arg, PkIrqId irq)
+
+int pk_irq_setup(PkIrqId irq,
+ int polarity,
+ int trigger);
+
+int pk_irq_handler_set(PkIrqId irq,
+ PkIrqHandler handler,
+ void* arg);
+
+void pk_irq_enable(PkIrqId irq);
+void pk_irq_disable(PkIrqId irq);
+void pk_irq_statusclear(PkIrqId irq);
+
+PK_IRQ_HANDLER(__ppe42_default_irq_handler);
+PK_IRQ_HANDLER(__ppe42_phantom_irq_handler);
+
+
+int
+ppe42_fit_setup(int tcr_fp, PkIrqHandler handler, void* arg);
+
+
+/// The address of the optional FIT interrupt handler
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+volatile
+PkIrqHandler __ppe42_fit_routine;
+
+
+/// The private data of the optional FIT interrupt handler
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+volatile
+void* __ppe42_fit_arg;
+
+
+int
+ppe42_watchdog_setup(int tcr_wp, int tcr_wrc,
+ PkIrqHandler handler, void* arg);
+
+
+/// The address of the optional Watchdog interrupt handler
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+volatile
+PkIrqHandler __ppe42_watchdog_routine;
+
+
+/// The private data of the optional Watchdog interrupt handler
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+volatile
+void* __ppe42_watchdog_arg;
+
+
+int
+ppe42_debug_setup(PkIrqHandler handler, void* arg);
+
+
+/// The address of the optional Debug interrupt handler
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+volatile
+PkIrqHandler __ppe42_debug_routine;
+
+
+/// The private data of the optional Watchdog interrupt handler
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+volatile
+void* __ppe42_debug_arg;
+
+#endif /* __ASSEMBLER__ */
+
+// It's hard to be portable and get all of the definitions and headers in the
+// correct order. We need to bring in the system IRQ header here.
+
+#ifdef HWMACRO_GPE
+#include "gpe_irq.h"
+#else
+#ifdef HWMACRO_STD
+#include "std_irq.h"
+#endif
+#endif
+
+/// \page ppe42_irq_macros_page PPE42 PK IRQ Assembler Macros
+///
+///
+
+#ifndef __ASSEMBLER__
+
+
+/// This structure holds the interrupt handler routine addresses and private
+/// data. Assembler code assumes the given structure layout, so any changes
+/// to this structure will need to be reflected down into the interrupt
+/// dispatch assembler code.
+
+typedef struct {
+ PkIrqHandler handler;
+ void *arg;
+} Ppe42IrqHandler;
+
+
+#ifdef STATIC_IRQ_TABLE
+
+#define IRQ_HANDLER(func, arg) \
+ {func, arg},
+
+#define IRQ_HANDLER_DEFAULT \
+ {__ppe42_default_irq_handler, 0},
+
+#define EXTERNAL_IRQ_TABLE_END \
+ {__ppe42_phantom_irq_handler, 0}\
+};
+
+#define EXTERNAL_IRQ_TABLE_START \
+ Ppe42IrqHandler __ppe42_irq_handlers[EXTERNAL_IRQS + 1] = \
+{
+
+#else
+
+#define EXTERNAL_IRQ_TABLE_START
+
+#define IRQ_HANDLER(func, arg)
+
+#define IRQ_HANDLER_DEFAULT
+
+#define EXTERNAL_IRQ_TABLE_END
+
+#endif /*STATIC_IRQ_TABLE*/
+
+/// Interrupt handlers for real (implemented interrupts) plus one for the phantom interrupt handler
+extern Ppe42IrqHandler __ppe42_irq_handlers[EXTERNAL_IRQS + 1];
+
+
+/// The 'phantom interrupt' handler
+///
+/// A 'phantom' interrupt occurs when the interrupt handling code in the
+/// kernel is entered, but no interrupt is found pending in the controller.
+/// This is considered a serious bug, as it indictates a short window
+/// condition where a level-sensitive interrupt has been asserted and then
+/// quickly deasserted before it can be handled.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+Ppe42IrqHandler __ppe42_phantom_irq;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE42_IRQ_H__ */
diff --git a/src/ppe/pk/ppe42/ppe42_irq_core.c b/src/ppe/pk/ppe42/ppe42_irq_core.c
new file mode 100644
index 0000000..40460b5
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_irq_core.c
@@ -0,0 +1,71 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_irq_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_irq_core.c
+/// \brief Core IRQ routines required of any PPE42 configuration of PK
+///
+/// This file is mostly only a placeholder - where 'extern inline' API
+/// functions and 'extern' variables are realized. A couple of default
+/// handlers are also installed here. The entry points in this file are
+/// considered 'core' routines that will always be present at runtime in any
+/// PK application.
+
+#define __PPE42_IRQ_CORE_C__
+
+#include "pk.h"
+
+#ifndef STATIC_IRQ_TABLE
+Ppe42IrqHandler __ppe42_irq_handlers[EXTERNAL_IRQS + 1];
+#endif
+
+/// This function is installed by default for interrupts not explicitly set up
+/// by the application. These interrupts should never fire.
+
+void
+__ppe42_default_irq_handler(void* arg, PkIrqId irq)
+{
+ PK_PANIC(PPE42_DEFAULT_IRQ_HANDLER);
+}
+
+
+/// This function is installed by default to handle the case that the
+/// interrupt dispatch code is entered in response to an external
+/// interrupt, but no interrupt is found pending in the interrupt
+/// controller. This should never happen, as it would indicate that a
+/// 'glitch' occurred on the external interrupt input
+/// to the PPE42 core.
+
+void __ppe42_phantom_irq_handler(void* arg, PkIrqId irq)
+{
+ PK_PANIC(PPE42_PHANTOM_INTERRUPT);
+}
+
+
+#undef __PPE42_IRQ_CORE_C__
diff --git a/src/ppe/pk/ppe42/ppe42_msr.h b/src/ppe/pk/ppe42/ppe42_msr.h
new file mode 100644
index 0000000..783285b
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_msr.h
@@ -0,0 +1,112 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_msr.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_MSR_H__
+#define __PPE42_MSR_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_msr.h
+/// \brief Everything related to the PPE42 Machine State Register
+///
+/// All of the macros defined here that \e modify the MSR create a compiler
+/// memory barrier that will cause GCC to flush/invalidate all memory data
+/// held in registers before the macro. This is consistent with other systems,
+/// e.g., the PowerPC Linux kernel, and is the safest way to define these
+/// macros as it guarantess for example that kernel data structure updates
+/// have completed before exiting a critical section.
+
+#define MSR_SEM 0x7f000000 /* SIB Error Mask */
+#define MSR_IS0 0x00800000 /* Instance-Specific Field 0 */
+#define MSR_SIBRC 0x00700000 /* Last SIB return code */
+#define MSR_LP 0x00080000 /* Low Priority */
+#define MSR_WE 0x00040000 /* Wait State Enable */
+#define MSR_IS1 0x00020000 /* Instance-Specific Field 1 */
+#define MSR_UIE 0x00010000 /* Unmaskable Interrupt Enable */
+#define MSR_EE 0x00008000 /* External Interrupt Enable */
+#define MSR_ME 0x00001000 /* Machine Check Exception Enable */
+#define MSR_IPE 0x00000100 /* Imprecise Mode Enable */
+#define MSR_SIBRCA 0x000000ff /* SIB Return Code Accumulator */
+
+//#define MSR_CE_BIT 14
+#define MSR_EE_BIT 16
+//#define MSR_IR_BIT 26
+//#define MSR_DR_BIT 27
+
+
+#define MSR_SEM_START_BIT 1
+#define MSR_SEM_LEN 7
+#define MSR_SIBRC_START_BIT 9
+#define MSR_SIBRC_LEN 3
+
+
+#ifndef __ASSEMBLER__
+
+/// Move From MSR
+
+#define mfmsr() \
+ ({uint32_t __msr; \
+ asm volatile ("mfmsr %0" : "=r" (__msr)); \
+ __msr;})
+
+
+/// Move to MSR
+
+#define mtmsr(value) \
+ asm volatile ("mtmsr %0" : : "r" (value) : "memory")
+
+
+/// Read-Modify-Write the MSR with OR (Set MSR bits). This operation is only
+/// guaranteed atomic in a critical section.
+
+#define or_msr(x) \
+ mtmsr(mfmsr() | (x))
+
+
+/// Read-Modify-Write the MSR with AND complement (Clear MSR bits). This
+/// operation is only guaranteed atomic in a critical section.
+
+#define andc_msr(x) \
+ mtmsr(mfmsr() & ~(x))
+
+
+/// Write MSR[EE] with an immediate value (0/1)
+///
+/// Note that the immediate value \a i must be a compile-time constant.
+
+#define wrteei(i) \
+ asm volatile ("wrteei %0" : : "i" (i) : "memory")
+
+
+/// Write MSR[EE] from the EE bit of another MSR
+
+#define wrtee(other_msr) \
+ asm volatile ("wrtee %0" : : "r" (other_msr) : "memory")
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE42_MSR_H__ */
diff --git a/src/ppe/pk/ppe42/ppe42_scom.c b/src/ppe/pk/ppe42/ppe42_scom.c
new file mode 100755
index 0000000..20da4df
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_scom.c
@@ -0,0 +1,101 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_scom.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_scom.c
+/// \brief Lowest level PK SCOM definitions.
+///
+/// Currently these SCOM functions are only optimized for functionality, not
+/// speed. Speed optimization will be done when we have full compiler support
+/// for the low-level stvd and lvd SCOM OPs.
+///
+/// A FAPI-lite SCOM can call these PK SCOM functions.
+///
+/// Comment:
+/// - No need to poll for SCOM completion, nor return error code of SCOM fails.
+/// A SCOM fail will cause the GPE to hang if configured to do so. But do we
+/// necessarily have to do this? Wouldn't a gentle recovery from a SCOM fail
+/// be preferred?
+
+#include "pk.h"
+#include "ppe42_scom.h"
+#include "ppe42_msr.h"
+
+
+uint32_t putscom_abs(const uint32_t i_address, uint64_t *i_data)
+{
+
+ // Perform the Store Virtual Double instruction
+ PPE_STVD(i_address, &i_data);
+
+ // Get the MSR[SIBRC] as the return code
+ uint32_t rc = mfmsr();
+ rc = ((rc & MSR_SIBRC) >> (32-(MSR_SIBRC_START_BIT + MSR_SIBRC_LEN)));
+ return (rc);
+
+}
+
+uint32_t _putscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t *i_data)
+{
+
+ // Perform the Store Virtual Double Index instruction
+ PPE_STVDX(i_chiplet_id, i_address, &i_data);
+
+ // Get the MSR[SIBRC] as the return code
+ uint32_t rc = mfmsr();
+ rc = ((rc & MSR_SIBRC) >> (32-(MSR_SIBRC_START_BIT + MSR_SIBRC_LEN)));
+ return (rc);
+
+}
+
+uint32_t getscom_abs( const uint32_t i_address, uint64_t *o_data)
+{
+
+ // Perform the Load Virtual Double instruction
+ PPE_LVD(i_address, &o_data);
+
+ // Get the MSR[SIBRC] as the return code
+ uint32_t rc = mfmsr();
+ rc = ((rc & MSR_SIBRC) >> (32-(MSR_SIBRC_START_BIT + MSR_SIBRC_LEN)));
+ return (rc);
+}
+
+
+uint32_t _getscom( const uint32_t i_chiplet_id, const uint32_t i_address, uint64_t *o_data)
+{
+
+ // Perform the Load Virtual Double Index instruction
+ PPE_LVDX(i_chiplet_id, i_address, &o_data);
+
+ // Get the MSR[SIBRC] as the return code
+ uint32_t rc = mfmsr();
+ rc = ((rc & MSR_SIBRC) >> (32-(MSR_SIBRC_START_BIT + MSR_SIBRC_LEN)));
+ return (rc);
+
+}
diff --git a/src/ppe/pk/ppe42/ppe42_scom.h b/src/ppe/pk/ppe42/ppe42_scom.h
new file mode 100755
index 0000000..42bc87a
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_scom.h
@@ -0,0 +1,160 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_scom.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_scom.h
+/// \brief Include file for PK SCOMs
+///
+
+#ifndef __PK_SCOM_H__
+#define __PK_SCOM_H__
+
+/// SCOM operations return non-zero error codes that may or may not indicate
+/// an actual error, depending on which SCOM is begin accessed. This error
+/// code will appear in the MSR[SIBRC] field, bits[9:11] right after the
+/// SCOM OP returns. The error code value increases with the severity of the
+/// error.
+#define PCB_ERROR_NONE 0
+#define PCB_ERROR_RESOURCE_OCCUPIED 1
+#define PCB_ERROR_CHIPLET_OFFLINE 2
+#define PCB_ERROR_PARTIAL_GOOD 3
+#define PCB_ERROR_ADDRESS_ERROR 4
+#define PCB_ERROR_CLOCK_ERROR 5
+#define PCB_ERROR_PACKET_ERROR 6
+#define PCB_ERROR_TIMEOUT 7
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/// PPE Load Virtual Double operation
+#define PPE_LVD(_m_address, _m_data) \
+asm volatile \
+ ( \
+ "lvd %[data], 0(%[address]) \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data), \
+ [address]"r"(_m_address) \
+ );
+
+
+// PPE Store Virtual Double operation
+#define PPE_STVD(_m_address, _m_data) \
+asm volatile \
+ ( \
+ "stvd %[data], 0(%[address]) \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data), \
+ [address]"r"(_m_address) \
+ : "memory" \
+ );
+
+/// PPE Load Virtual Double Indexed operation
+#define PPE_LVDX(_m_base, _m_offset, _m_data) \
+asm volatile \
+ ( \
+ "lvdx %[data], %[base], %[offset] \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data), \
+ [base]"r"(_m_base), \
+ [offset]"r"(_m_offset) \
+ );
+
+
+// PPE Store Virtual Double Indexed operation
+#define PPE_STVDX(_m_base, _m_offset, _m_data) \
+asm volatile \
+ ( \
+ "stvdx %[data], %[base], %[offset] \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data), \
+ [base]"r"(_m_base), \
+ [offset]"r"(_m_offset) \
+ : "memory" \
+ );
+
+#define PPE_MFMSR(_m_data) \
+asm volatile \
+ ( \
+ "mfmsr %[data] \n" \
+ : [data]"=&r"(*_m_data) \
+ : "[data]"(*_m_data) \
+ );
+
+/// @brief putscom with absolute address
+/// @param [in] i_address Fully formed SCOM address
+/// @param [in] i_data Pointer to uint64_t data to be written. A pointer is used
+/// to optimize the underlying hardware execution
+///
+/// @retval On PPE42 platform, unmasked errors will take machine check interrupts
+uint32_t putscom_abs(const uint32_t i_address, uint64_t *i_data);
+
+/// @brief getscom with absolute address
+/// @param [in] i_address Fully formed SCOM address
+/// @param [in] *o_data Pointer to uint64_t data read
+///
+/// @retval On PPE42 platform, unmasked errors will take machine check interrupts
+
+uint32_t getscom_abs( const uint32_t i_address, uint64_t *o_data);
+
+/// @brief Implementation of PPE putscom functionality
+/// @param [in] i_chiplet Chiplet ID (@todo Should only be right justified)
+/// @param [in] i_address Base SCOM address
+/// @param [in] i_data Pointer to uint64_t data to be written. A pointer is used
+/// to optimize the underlying hardware execution
+///
+/// @retval On PPE42 platform, unmasked errors will take machine check interrupts
+uint32_t _putscom( const uint32_t i_chiplet, const uint32_t i_address, uint64_t *i_data);
+
+
+/// @brief Implementation of PPE getscom functionality
+/// @param [in] i_chiplet Chiplet ID (@todo Should only be right justified)
+/// @param [in] i_address Base SCOM address
+/// @param [in] i_data Pointer to uint64_t data read
+///
+/// @retval On PPE42 platform, unmasked errors will take machine check interrupts
+uint32_t _getscom( uint32_t i_chiplet, uint32_t i_address, uint64_t *o_data);
+
+extern inline uint32_t putscom(const uint32_t i_chiplet, const uint32_t i_address, uint64_t *i_data)
+{
+ return _putscom(i_chiplet, i_address, i_data);
+}
+
+
+extern inline uint32_t getscom(const uint32_t i_chiplet, const uint32_t i_address, uint64_t *o_data)
+{
+ return _getscom(i_chiplet, i_address, o_data);
+}
+
+#ifdef __cplusplus
+} // extern C
+#endif
+
+#endif // __PK_SCOM_H__
diff --git a/src/ppe/pk/ppe42/ppe42_spr.h b/src/ppe/pk/ppe42/ppe42_spr.h
new file mode 100644
index 0000000..e53a5d5
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_spr.h
@@ -0,0 +1,197 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_spr.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PPE42_SPR_H__
+#define __PPE42_SPR_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppe42_spr.h
+/// \brief Everything related to PPE42-specific SPRs
+
+/// \defgroup ppe42_sprs PPE42 SPRs
+///
+/// These are the documented SPRs of the PPE42. Most of these SPRs are
+/// available in RISCWatch and eCmd using the defined names (minus SPRN_). In
+/// some cases RISCWatch/eCMD use different names, which appear in square
+/// brackets in the brief comments for each register. RISCWatch/eCMD also
+/// allow CR, MSR and IAR (Instruction Address Register) to be accessed as
+/// SPRs.
+///
+/// @{
+
+ #define SPRN_XER 0x001 /// Fixed-point exception register
+ #define SPRN_LR 0x008 /// Link register
+ #define SPRN_CTR 0x009 /// Count register
+ #define SPRN_DEC 0x016 /// Decrementer
+ #define SPRN_SRR0 0x01a /// Save/restore register 0
+ #define SPRN_SRR1 0x01b /// Save/restore register 1
+ #define SPRN_EDR 0x03d /// Error Data Register
+ #define SPRN_ISR 0x03e /// Interrupt Status Register
+ #define SPRN_IVPR 0x03f /// Interrupt Vector Prefix Register
+ #define SPRN_SPRG0 0x110 /// SPR general register 0
+ #define SPRN_PIR 0x11e /// Processor Identification Register
+ #define SPRN_PVR 0x11f /// Processor version register
+ #define SPRN_DBCR 0x134 /// Debug Control Register
+ #define SPRN_DACR 0x13c /// Debug Address Compare Register
+ #define SPRN_TSR 0x150 /// Timer Status Register
+ #define SPRN_TCR 0x154 /// Timer Control Register
+
+/* DBCR - Debug Control Register */
+
+#define DBCR_RST 0x30000000 /* Reset: 01=Soft Reset, 10=Hard Reset, 11=Halt */
+#define DBCR_TRAP 0x01000000 /* Trap Instruction Enable */
+#define DBCR_IACE 0x00800000 /* Instruction Address Compare Enable */
+#define DBCR_DACE 0x000c0000 /* Data Address Compare Enable: 01=store, 10=load, 11=both */
+
+/* TCR - Timer Control Register */
+
+#define TCR_WP_MASK 0xc0000000 /* Watchdog timer select bits */
+#define TCR_WP_0 0x00000000 /* WDT uses timer 0 */
+#define TCR_WP_1 0x40000000 /* WDT uses timer 1 */
+#define TCR_WP_2 0x80000000 /* WDT uses timer 2 */
+#define TCR_WP_3 0xc0000000 /* WDT uses timer 3 */
+#define TCR_WRC_MASK 0x30000000 /* Watchdog Reset Control mask */
+#define TCR_WRC_NONE 0x00000000 /* WDT results in no action */
+#define TCR_WRC_SOFT 0x10000000 /* WDT results in Soft reset */
+#define TCR_WRC_HARD 0x20000000 /* WDT results in Hard reset */
+#define TCR_WRC_HALT 0x30000000 /* WDT results in Halt */
+#define TCR_WIE 0x08000000 /* Watchdog Interrupt Enable */
+#define TCR_DIE 0x04000000 /* Decrementer Interrupt Enable */
+#define TCR_FP_MASK 0x03000000 /* FIT Timer Select bits*/
+#define TCR_FP_0 0x00000000 /* FIT uses timer 0 */
+#define TCR_FP_1 0x01000000 /* FIT uses timer 1 */
+#define TCR_FP_2 0x02000000 /* FIT uses timer 2 */
+#define TCR_FP_3 0x03000000 /* FIT uses timer 3 */
+#define TCR_FIE 0x00800000 /* FIT Interrupt Enable */
+#define TCR_DS 0x00400000 /* Decrementer timer select: 0=every cycle, 1=use dec_timer input signal */
+
+#ifndef __ASSEMBLER__
+
+typedef union {
+ uint32_t value;
+ struct {
+ unsigned int wp : 2;
+ unsigned int wrc : 2;
+ unsigned int wie : 1;
+ unsigned int die : 1;
+ unsigned int fp : 2;
+ unsigned int fie : 1;
+ unsigned int ds : 1;
+ unsigned int reserved : 22;
+ } fields;
+} Ppe42TCR;
+
+#endif /* __ASSEMBLER__ */
+
+/* TSR - Timer Status Register */
+
+#define TSR_ENW 0x80000000 /* Enable Next Watchdog */
+#define TSR_WIS 0x40000000 /* Watchdog Interrupt Status */
+#define TSR_WRS_MASK 0x30000000 /* Watchdog Reset Status */
+#define TSR_WRS_NONE 0x00000000 /* No watchdog reset has occurred */
+#define TSR_WRS_SOFT 0x10000000 /* Soft reset was forced by the watchdog */
+#define TSR_WRS_HARD 0x20000000 /* Hard reset was forced by the watchdog */
+#define TSR_WRS_HALT 0x30000000 /* Halt was forced by the watchdog */
+#define TSR_DIS 0x08000000 /* Decrementer Interrupt Status */
+#define TSR_FIS 0x04000000 /* FIT Interrupt Status */
+
+/* PIR - Processor Identification Register */
+#define PIR_PPE_TYPE_MASK 0x000000E0
+#define PIR_PPE_TYPE_GPE 0x00000020
+#define PIR_PPE_TYPE_CME 0x00000040
+#define PIR_PPE_INSTANCE_MASK 0x0000001F
+
+#ifndef __ASSEMBLER__
+
+/// Move From SPR
+///
+/// Note that \a sprn must be a compile-time constant.
+
+#define mfspr(sprn) \
+ ({uint32_t __value; \
+ asm volatile ("mfspr %0, %1" : "=r" (__value) : "i" (sprn)); \
+ __value;})
+
+
+/// Move to SPR
+///
+/// Note that \a sprn must be a compile-time constant.
+
+#define mtspr(sprn, value) \
+ ({uint32_t __value = (value); \
+ asm volatile ("mtspr %0, %1" : : "i" (sprn), "r" (__value)); \
+ })
+
+
+/// Read-Modify-Write an SPR with OR (Set SPR bits)
+///
+/// Note that \a sprn must be a compile-time constant. This operation is only
+/// guaranteed atomic in a critical section.
+
+#define or_spr(sprn, x) \
+ mtspr(sprn, mfspr(sprn) | (x))
+
+
+/// Read-Modify-Write an SPR with AND complement (Clear SPR bits)
+///
+/// Note that \a sprn must be a compile-time constant. This operation is only
+/// guaranteed atomic in a critical section.
+
+#define andc_spr(sprn, x) \
+ mtspr(sprn, mfspr(sprn) & ~(x))
+
+#endif /* __ASSEMBLER__ */
+
+#ifdef __ASSEMBLER__
+
+ /// \cond
+
+ // Use this macro to define new mt<spr> and mf<spr> instructions that
+ // may not exist in the assembler.
+
+ .macro _sprinstrs, name, num
+ .macro mt\name, reg
+ mtspr \num, \reg
+ .endm
+ .macro mf\name, reg
+ mfspr \reg, \num
+ .endm
+ .endm
+
+ _sprinstrs dbcr, SPRN_DBCR
+ _sprinstrs tcr, SPRN_TCR
+ _sprinstrs tsr, SPRN_TSR
+ _sprinstrs sprg0, SPRN_SPRG0
+ _sprinstrs ivpr, SPRN_IVPR
+ _sprinstrs dec, SPRN_DEC
+
+ /// \endcond
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPE42_SPR_H__ */
diff --git a/src/ppe/pk/ppe42/ppe42_thread_init.S b/src/ppe/pk/ppe42/ppe42_thread_init.S
new file mode 100644
index 0000000..14fb3d0
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_thread_init.S
@@ -0,0 +1,134 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/ppe42/ppe42_thread_init.S $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+/// \file ppe42_thread_init.S
+/// \brief PPE42-specific thread initialization
+///
+/// The entry points in this file are routines that are typically used during
+/// initialization, and their code space could be deallocated and recovered if
+/// no longer needed by the application after initialization.
+
+ .nolist
+#include "pk.h"
+ .list
+
+/// \fn void __pk_thread_context_initialize(PkThread *thread, PkThreadRoutine thread_routine, void *private)
+/// \brief Create the initial thread context on the stack
+///
+/// The non-reserved GPRs are prepatterned with 0x0000\<rn\>\<rn\> where \<rn\> is
+/// the register number (as decimal). The initial context is set up with the
+/// thread running in the default machine context, and when the thread is
+/// switched in it will begin executing at the entry point of the thread
+/// routine with the \c private parameter in R3. The LR is initialized such
+/// that when the thread returns, it will return to the entry point of \c
+/// pk_complete().
+#ifdef DOXYGEN_ONLY
+void
+__pk_thread_context_initialize(PkThread *thread,
+ PkThreadRoutine thread_routine,
+ void *private);
+#endif
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \cond
+
+ .global_function __pk_thread_context_initialize
+
+__pk_thread_context_initialize:
+
+ ## R3 = thread (param)
+ ## R4 = thread_routine (param)
+ ## R5 = private (param)
+ ## R6 = thread stack pointer (computed)
+ ## R7 = scratch
+
+ .macro _gpr_init, prefix, reg, val
+ li %r7, \val
+ stw %r7, \prefix\reg(%r6)
+ .endm
+
+ ## Initialize volatile context on the thread stack. The CR is cleared,
+ ## the LR = pk_complete(), R3 has the private parameter.
+
+ lwz %r6, PK_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
+
+ stwu %r6, -PK_CTX_SIZE(%r6)
+
+ li %r7, 0
+ stw %r7, PK_CTX_CR(%r6)
+
+ _liw %r7, pk_complete
+ stw %r7, PK_CTX_LR(%r6)
+
+ stw %r5, PK_CTX_GPR3(%r6)
+
+ _gpr_init PK_CTX_GPR, 4, 0x0404
+ _gpr_init PK_CTX_GPR, 5, 0x0505
+ _gpr_init PK_CTX_GPR, 6, 0x0606
+
+ ## XER and CTR are clear, SRR0 = thread_routine, SRR1 = default machine
+ ## context.
+
+ li %r7, 0
+ stw %r7, PK_CTX_XER(%r6)
+ stw %r7, PK_CTX_CTR(%r6)
+
+ stw %r4, PK_CTX_SRR0(%r6)
+
+ _lwzsd %r7, __pk_thread_machine_context_default
+ stw %r7, PK_CTX_SRR1(%r6)
+
+ _gpr_init PK_CTX_GPR, 0, 0x0000
+ _gpr_init PK_CTX_GPR, 7, 0x0707
+ _gpr_init PK_CTX_GPR, 8, 0x0808
+ _gpr_init PK_CTX_GPR, 9, 0x0909
+ _gpr_init PK_CTX_GPR, 10, 0x1010
+
+ ## Initialize the non-volatile context on the thread stack.
+
+ _gpr_init PK_CTX_GPR, 28, 0x2828
+ _gpr_init PK_CTX_GPR, 29, 0x2929
+ _gpr_init PK_CTX_GPR, 30, 0x3030
+ _gpr_init PK_CTX_GPR, 31, 0x3131
+
+ ## Initialize the kernel context on the thread stack.
+ ## Note: Thread priority is set later each time the thread is
+ ## resumed.
+
+ lis %r7, PPE42_THREAD_MODE
+ stw %r7, PK_CTX_KERNEL_CTX(%r6)
+
+ ## Initialization is done - the stack pointer is stored back in the
+ ## thread.
+
+ stw %r6, PK_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
+ blr
+
+ .epilogue __pk_thread_context_initialize
+
+/// \endcond
diff --git a/src/ppe/pk/ppe42/ppe42_timebase.S b/src/ppe/pk/ppe42/ppe42_timebase.S
new file mode 100644
index 0000000..a0884e6
--- /dev/null
+++ b/src/ppe/pk/ppe42/ppe42_timebase.S
@@ -0,0 +1,140 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/ppe42/ppe42_timebase.S $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// \file ppe42_timebase.S
+/// \brief PPE42-specific 64 bit timebase emulation
+///
+ .nolist
+#include "pk.h"
+ .list
+
+/// \fn PkTimebase pk_timebase_get(void)
+/// \brief Returns a 64 bit timebase
+///
+#ifdef DOXYGEN_ONLY
+PkTimebase
+pk_timebase_get(void);
+#endif
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \cond
+ .global ppe42_64bit_timebase
+ .global ppe42_tb_data
+ .global_function pk_timebase_get
+
+#ifndef APPCFG_USE_EXT_TIMEBASE
+
+ /// Note that it is ok to use this function in a fast interrupt
+ /// context
+ .align 5
+ .global_function pk_timebase32_get
+pk_timebase32_get:
+
+ //load the decrementer start time and change tag
+ lvd %r4, ppe42_tb_data@sda21(0)
+
+ //load the lower 32 bits of the 64bit timebase accumulator
+ lwz %r3, ppe42_64bit_timebase+4@sda21(0)
+
+ //load the current decrementer value
+ mfdec %r0
+
+ //load the change tag again (should already be in the cache)
+ lwz %r6, ppe42_tb_data+4@sda21(0)
+
+ //loop until the change tag is the same (typically should be same)
+ cmplwbne %r5, %r6, pk_timebase32_get
+
+ //calculate how much time has passed since the decrementer was started and store in r6
+ subf %r5, %r0, %r4
+
+ //add the 32bit difference to our 32bit timebase accumulator
+ add %r3, %r5, %r3
+
+ blr
+
+
+/// Use the DEC for our timebase until we have a real timebase register (uses
+/// 9 instructions).
+/// Note: It is not ok to use this function in a fast interrupt context due to
+/// its use of r7
+ .align 5
+pk_timebase_get:
+
+ //load the decrementer start time and change tag
+ lvd %r5, ppe42_tb_data@sda21(0)
+
+ //load 64bit timebase accumulator
+ lvd %r3, ppe42_64bit_timebase@sda21(0)
+
+
+ //load the current decrementer value
+ mfdec %r0
+
+ //load the change tag again (should already be in the cache)
+ lwz %r7, ppe42_tb_data+4@sda21(0)
+
+ //loop until the change tag is the same
+ cmplwbne %r6, %r7, pk_timebase_get
+
+ //calculate how much time has passed since the decrementer was started and store in r6
+ subf %r6, %r0, %r5
+
+ //add the 32bit difference to the 64bit timebase accumulator
+ addc %r4, %r6, %r4
+ addze %r3, %r3
+
+ blr
+
+//enable this once we have a local timebase register in the model
+#else
+
+// use the local timebase register to keep more accurate time with just 6 instructions
+// in the common case and 7 otherwise.
+ .align 5
+pk_timebase_get:
+
+ //load the 64bit timebase accumulator
+ lvd r3, ppe42_64bit_timebase@sda21(0)
+
+ //read the local timebase register (2 instructions)
+ _pk_timebase32_get r5, r5
+
+ //increment the upper 32 bits if the lower 32 bits have flipped
+ cmplwbge r5, r4, update_lower_32
+
+ //increment the upper 32 bits
+ addi r3, r3, 1
+
+update_lower_32:
+ //replace the lower 32bits with what we read from the local timebase register
+ mr r4, r5
+
+ blr
+#endif /* APPCFG_USE_EXT_TIMEBASE */
+/// \endcond
diff --git a/src/ppe/pk/std/Makefile b/src/ppe/pk/std/Makefile
new file mode 100644
index 0000000..443430f
--- /dev/null
+++ b/src/ppe/pk/std/Makefile
@@ -0,0 +1,74 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/std/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile compiles all of the PK code required for the STD (standard PPE) port
+# of PK. See the "pk.mk" file in this directory.
+
+#all generated files from this makefile will end up in obj/$(IMAGE_NAME)/pk
+export SUB_OBJDIR = /pk
+
+include img_defs.mk
+include pkstdfiles.mk
+
+ifeq "$(PK_TIMER_SUPPORT)" "1"
+STD_OBJECTS += ${STD-TIMER-C-SOURCES:.c=.o} ${STD-TIMER-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" "1"
+STD_OBJECTS += ${STD-THREAD-C-SOURCES:.c=.o} ${STD-THREAD-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(STD_ASYNC_SUPPORT)" "1"
+STD_OBJECTS += ${STD-ASYNC-C-SOURCES:.c=.o} ${STD-ASYNC-S-SOURCES:.S=.o}
+endif
+
+OBJS := $(addprefix $(OBJDIR)/, $(STD_OBJECTS))
+
+libpk.a: kernel ppe42 trace std
+ $(AR) crs $(OBJDIR)/libpk.a $(OBJDIR)/*.o
+
+.PHONY: clean std kernel ppe42 trace
+std: $(OBJS)
+
+trace:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../trace
+
+kernel:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../kernel
+
+ppe42:
+ $(MAKE) -I $(IMAGE_SRCDIR) -C ../ppe42
+
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/pk/std/pk_port.h b/src/ppe/pk/std/pk_port.h
new file mode 100644
index 0000000..2ed0d3d
--- /dev/null
+++ b/src/ppe/pk/std/pk_port.h
@@ -0,0 +1,41 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/pk_port.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_PORT_H__
+#define __PK_PORT_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_port.h
+/// \brief The top-level standard PPE environment header for PK.
+
+#define HWMACRO_STD
+
+#include "ppe42.h"
+#include "std_timebase.h"
+
+#endif /* __PK_PORT_H__ */
diff --git a/src/ppe/pk/std/pkstdfiles.mk b/src/ppe/pk/std/pkstdfiles.mk
new file mode 100644
index 0000000..3f9a731
--- /dev/null
+++ b/src/ppe/pk/std/pkstdfiles.mk
@@ -0,0 +1,57 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/std/pkstdfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file pkstdfiles.mk
+#
+# @brief mk for including std object files
+#
+# @page ChangeLogs Change Logs
+# @section pkstdfiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+STD-C-SOURCES = std_init.c std_irq_init.c
+STD-S-SOURCES =
+
+STD-TIMER-C-SOURCES =
+STD-TIMER-S-SOURCES =
+
+STD-THREAD-C-SOURCES =
+STD-THREAD-S-SOURCES =
+
+STD-ASYNC-C-SOURCES =
+STD-ASYNC-S-SOURCES =
+
+STD_OBJECTS += $(STD-C-SOURCES:.c=.o) $(STD-S-SOURCES:.S=.o)
+
diff --git a/src/ppe/pk/std/std.h b/src/ppe/pk/std/std.h
new file mode 100644
index 0000000..b20f6ae
--- /dev/null
+++ b/src/ppe/pk/std/std.h
@@ -0,0 +1,44 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STD_H__
+#define __STD_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp.h
+/// \brief The STD environment for PK.
+
+#ifndef HWMACRO_STD
+#define HWMACRO_STD
+#include "ppe42.h"
+#endif
+
+#include "std_register_addresses.h"
+#include "std_common.h"
+
+#endif /* __STD_H__ */
diff --git a/src/ppe/pk/std/std_common.h b/src/ppe/pk/std/std_common.h
new file mode 100644
index 0000000..e709f67
--- /dev/null
+++ b/src/ppe/pk/std/std_common.h
@@ -0,0 +1,78 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std_common.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STD_COMMON_H__
+#define __STD_COMMON_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file cme_common.h
+/// \brief Common header for standard PPE's
+///
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif
+
+//#include "cmehw_interrupts.h"
+#include "pk.h"
+#include "std_irq_config.h"
+
+#ifdef __ASSEMBLER__
+/// This macro contains standard PPE code for determining what IRQ caused the
+/// external exception handler to be invoked by the PPE
+
+/// Check for interrupts pending in the interrupt status register while the IRQ
+/// is computed. The IRQ is expected to be stored in r4. If no IRQ is
+/// pending then load the phantom irq # (EXTERNAL_IRQS).
+///
+/// r1, r2, r3, and r13 must not be modified. All other registers may be used.
+///
+ .macro hwmacro_get_ext_irq
+
+ _lvdg d5, STD_LCL_EISTR #load the 64bit interrupt status into d5
+ cntlzw r4, r5
+ cmpwible r4, 31, call_external_irq_handler #branch if irq is lt or eq to 31
+
+ ## No IRQ pending in r5. Try r6.
+ ## Note: irq # will be 64 (phantom irq) if no bits were set in either register
+
+ cntlzw r4, r6
+ addi r4, r4, 32
+
+ .endm
+
+/// Redirect the .hwmacro_irq_cfg_bitmaps macro to call our standard PPE implementation
+/// This is called from the ppe42_exceptions.S file.
+ .macro .hwmacro_irq_cfg_bitmaps
+ .std_irq_cfg_bitmaps
+ .endm
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __STD_COMMON_H__ */
diff --git a/src/ppe/pk/std/std_init.c b/src/ppe/pk/std/std_init.c
new file mode 100644
index 0000000..8d9bb12
--- /dev/null
+++ b/src/ppe/pk/std/std_init.c
@@ -0,0 +1,74 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file std_init.c
+/// \brief PK initialization for a standard PPE.
+///
+/// The entry points in this routine are used during initialization. This
+/// code space can be deallocated and reassigned after application
+/// initialization if required.
+
+#include "pk.h"
+
+/// Standard PPE environment initial setup.
+///
+/// This is setup common to all standard PPE Macro applications. This setup takes place
+/// during boot, before main() is called.
+
+void
+__hwmacro_setup(void)
+{
+ //mask all interrupts
+ out64(STD_LCL_EIMR_OR, 0xffffffffffffffffull);
+
+ //Set all interrupts to active low, level sensitive by default
+ out64(STD_LCL_EIPR_CLR, 0xffffffffffffffffull);
+ out64(STD_LCL_EITR_CLR, 0xffffffffffffffffull);
+
+ //set up the configured type
+ out64(STD_LCL_EITR_OR, g_ext_irqs_type);
+
+ //set up the configured polarity
+ out64(STD_LCL_EIPR_OR, g_ext_irqs_polarity);
+
+ //clear the status of all active-high interrupts (has no affect on
+ //level sensitive interrupts)
+ out64(STD_LCL_EISR_CLR, g_ext_irqs_polarity);
+
+ //clear the status of all active-low interrupts (has no affect on
+ //level sensitive interrupts)
+ out64(STD_LCL_EISR_OR, ~g_ext_irqs_polarity);
+
+ //unmask the interrupts that are to be enabled by default
+ out64(STD_LCL_EIMR_CLR, g_ext_irqs_enable);
+
+ //wait for the last operation to complete
+ sync();
+}
diff --git a/src/ppe/pk/std/std_irq.h b/src/ppe/pk/std/std_irq.h
new file mode 100644
index 0000000..e30a219
--- /dev/null
+++ b/src/ppe/pk/std/std_irq.h
@@ -0,0 +1,110 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std_irq.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STD_IRQ_H__
+#define __STD_IRQ_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file occhw_irq.h
+/// \brief Standard PPE Externnal Interrupt handling for PK
+///
+/// The standard PPE interrupt controller supports a maximum of 64 interrupts with
+/// simple OR combining of the interrupt signals.
+///
+/// The standard PPE interrupt controller allows interrupt status to be set directly by
+/// software. It contains a 'mask' register, unlike most 405 interrupt
+/// controllers that have an 'enable' register. The standard PPE mask and status
+/// registers also have atomic CLR/OR function so that it is never necessary
+/// to enter a critical section to enable/disable/clear interrupts and
+/// interrupt status.
+
+#include "std_common.h"
+#include "std_register_addresses.h"
+#include "ppe42.h"
+
+#ifndef __ASSEMBLER__
+
+/// Enable an interrupt by clearing the mask bit.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_enable(PkIrqId irq)
+{
+ out64(STD_LCL_EIMR_CLR, STD_IRQ_MASK64(irq));
+}
+
+
+/// Disable an interrupt by setting the mask bit.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_disable(PkIrqId irq)
+{
+ out64(STD_LCL_EIMR_OR, STD_IRQ_MASK64(irq));
+}
+
+
+/// Clear interrupt status with an CLR mask. Only meaningful for
+/// edge-triggered interrupts.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_status_clear(PkIrqId irq)
+{
+ out64(STD_LCL_EISR_CLR, STD_IRQ_MASK64(irq));
+}
+
+
+/// Get IRQ status as a 0 or non-0 integer
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline int
+pk_irq_status_get(PkIrqId irq)
+{
+ return (in64(STD_LCL_EISR) & STD_IRQ_MASK64(irq)) != 0;
+}
+
+
+/// Set or clear interrupt status explicitly.
+
+UNLESS__PPE42_IRQ_CORE_C__(extern)
+inline void
+pk_irq_status_set(PkIrqId irq, int value)
+{
+ if (value) {
+ out64(STD_LCL_EISR_OR, STD_IRQ_MASK64(irq));
+ } else {
+ out64(STD_LCL_EISR_CLR, STD_IRQ_MASK64(irq));
+ }
+}
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __STD_IRQ_H__ */
diff --git a/src/ppe/pk/std/std_irq_config.h b/src/ppe/pk/std/std_irq_config.h
new file mode 100644
index 0000000..5044b42
--- /dev/null
+++ b/src/ppe/pk/std/std_irq_config.h
@@ -0,0 +1,165 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std_irq_config.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STD_IRQ_CONFIG_H__
+#define __STD_IRQ_CONFIG_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file std_irq_config.h
+/// \brief Contains data and macros pertaining to external interrupt
+/// configuration for a standard PPE.
+///
+
+/// This constant is used to define the size of the table of interrupt handler
+/// structures as well as a limit for error checking.
+#define EXTERNAL_IRQS 64
+
+// Standard interrupt type values (level or edge)
+#define STD_IRQ_TYPE_LEVEL 0
+#define STD_IRQ_TYPE_EDGE 1
+
+// Standard interrupt polarity values (high or low, rising falling)
+#define STD_IRQ_POLARITY_LO 0
+#define STD_IRQ_POLARITY_FALLING 0
+#define STD_IRQ_POLARITY_HI 1
+#define STD_IRQ_POLARITY_RISING 1
+
+// Standard interrupt mask values (masked or enabled)
+#define STD_IRQ_MASKED 0
+#define STD_IRQ_ENABLED 1
+
+// Fail to compile if the application does not define this
+#ifndef APPCFG_EXT_IRQS_CONFIG
+#error "APPCFG_EXT_IRQS_CONFIG must be defined in pk_app_cfg.h"
+#endif
+
+// Fail to compile if the application does not define this
+#ifndef APPCFG_IRQ_INVALID_MASK
+#error "APPCFG_IRQ_INVALID_MASK must be defined in pk_app_cfg.h"
+#endif
+
+#ifndef __ASSEMBLER__
+
+/// This expression recognizes only those IRQ numbers that have named
+/// (non-reserved) interrupts in the standard PPE interrupt controller.
+#define STD_IRQ_VALID(irq) \
+ ({unsigned __irq = (unsigned)(irq); \
+ ((__irq < EXTERNAL_IRQS) && \
+ ((STD_IRQ_MASK64(__irq) & \
+ APPCFG_IRQ_INVALID_MASK) == 0));})
+
+/// This is a 64-bit mask, with big-endian bit 'irq' set.
+#define STD_IRQ_MASK64(irq) (0x8000000000000000ull >> (irq))
+
+#else
+
+//Untyped assembler version of STD_IRQ_MASK64
+#define STD_IRQ_MASK64(irq) (0x8000000000000000 >> (irq))
+
+#endif /* __ASSEMBLER__ */
+
+#ifndef __ASSEMBLER__
+/// These globals are statically initialized elsewhere
+extern uint64_t g_ext_irqs_type;
+extern uint64_t g_ext_irqs_valid;
+extern uint64_t g_ext_irqs_polarity;
+extern uint64_t g_ext_irqs_enable;
+#endif
+
+#ifdef __ASSEMBLER__
+/// These macros aid in the initialization of the external interrupt globals. I would
+/// prefer to use CPP macros, but they don't support recursive macros which I use to
+/// convert the variable number of interrupts that a processor can control into static
+/// bitmaps used by __hwmacro_setup() at runtime.
+
+
+ //helper macro for setting up the irq configuration bitmaps for a standard PPE
+ .macro .std_irq_config irq_num=-1 irq_type=-1 irq_polarity=-1 irq_mask=-1 parms:vararg
+ .if (( \irq_num == -1 ) && ( \irq_type == -1 ) && ( \irq_polarity == -1 ) && ( \irq_mask == -1 ))
+#.if ( .ext_irqs_defd != .ext_irqs_valid )
+#.error "###### .std_irq_config: Missing configuration for one or more interrupts ######"
+#.endif
+
+ .section .sdata
+ .align 3
+ .global g_ext_irqs_type
+ .global g_ext_irqs_polarity
+ .global g_ext_irqs_enable
+ g_ext_irqs_polarity:
+ .quad .ext_irqs_polarity
+ g_ext_irqs_type:
+ .quad .ext_irqs_type
+ g_ext_irqs_enable:
+ .quad .ext_irqs_enable
+ .else
+ .if (( \irq_num < 0 ) || ( \irq_num > (EXTERNAL_IRQS - 1)))
+ .error "###### .std_irq_config: invalid irq number \irq_num ######"
+ .elseif ((.ext_irqs_valid & (1 << ( EXTERNAL_IRQS - 1 - \irq_num ))) == 0 )
+ .error "###### .std_irq_config: Attempt to configure invalid irq number \irq_num ######"
+ .elseif (.ext_irqs_defd & (1 << ( EXTERNAL_IRQS - 1 - \irq_num )))
+ .error "###### .std_irq_config: duplicate definition for irq \irq_num ######"
+ .else
+ .ext_irqs_defd = .ext_irqs_defd | (1 << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .if (( \irq_type < 0 ) || ( \irq_type > 1 ))
+ .error "###### .std_irq_config: invalid/unspecified irq type \irq_type for irq \irq_num ######"
+ .else
+ .ext_irqs_type = .ext_irqs_type | ( \irq_type << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .if (( \irq_polarity < 0 ) || ( \irq_polarity > 1 ))
+ .error "###### .std_irq_config: invalid/unspecified irq polarity ( \irq_polarity ) for irq \irq_num ######"
+ .else
+ .ext_irqs_polarity = .ext_irqs_polarity | ( \irq_polarity << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .if (( \irq_mask < 0 ) || ( \irq_mask > 1 ))
+ .error "###### .std_irq_config: invalid/unspecified irq mask ( \irq_mask ) for irq \irq_num ######"
+ .else
+ .ext_irqs_enable = .ext_irqs_enable | ( \irq_mask << ( EXTERNAL_IRQS - 1 - \irq_num ))
+ .endif
+
+ .std_irq_config \parms
+ .endif
+ .endm
+
+ //Top level macro for generating interrupt configuration globals for a standard PPE
+ .macro .std_irq_cfg_bitmaps
+ .ext_irqs_valid = ~(APPCFG_IRQ_INVALID_MASK)
+ .ext_irqs_type = 0
+ .ext_irqs_polarity = 0
+ .ext_irqs_enable = 0
+ .irq_mask = 0
+ .ext_irqs_defd = 0
+ .std_irq_config APPCFG_EXT_IRQS_CONFIG
+ .endm
+
+#endif /*__ASSEMBLER__*/
+
+#endif /*__STD_IRQ_CONFIG_H__*/
diff --git a/src/ppe/pk/std/std_irq_init.c b/src/ppe/pk/std/std_irq_init.c
new file mode 100644
index 0000000..c7a0771
--- /dev/null
+++ b/src/ppe/pk/std/std_irq_init.c
@@ -0,0 +1,129 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std_irq_init.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file std_irq_init.c
+/// \brief Standard PPE IRQ initialization code for PK
+///
+/// The entry points in this file are initialization routines that could be
+/// eliminated/deallocated by the application to free up storage if they are
+/// no longer needed after initialization.
+
+#include "pk.h"
+
+/// Define the polarity and trigger condition for an interrupt.
+///
+/// It is up to the application to take care of any side effects that may
+/// occur from programming or reprogramming the interrupt controller. For
+/// example, changing edge/level sensitivity or active level may set or clear
+/// interrupt status in the controller.
+///
+/// Note that PK allows this API to be called from any context, and changes
+/// to the interrupt controller are made from a critical section.
+///
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_IRQ_SETUP One or more arguments are invalid,
+/// including an invalid \a irq, or invalid \a polarity or \a trigger parameters.
+
+int
+pk_irq_setup(PkIrqId irq,
+ int polarity,
+ int trigger)
+{
+ PkMachineContext ctx;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(!STD_IRQ_VALID(irq) ||
+ !((polarity == PK_IRQ_POLARITY_ACTIVE_HIGH) ||
+ (polarity == PK_IRQ_POLARITY_ACTIVE_LOW)) ||
+ !((trigger == PK_IRQ_TRIGGER_LEVEL_SENSITIVE) ||
+ (trigger == PK_IRQ_TRIGGER_EDGE_SENSITIVE)),
+ PK_INVALID_ARGUMENT_IRQ_SETUP);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ if (polarity == PK_IRQ_POLARITY_ACTIVE_HIGH) {
+ out64(STD_LCL_EIPR_OR, STD_IRQ_MASK64(irq));
+ } else {
+ out64(STD_LCL_EIPR_CLR, STD_IRQ_MASK64(irq));
+ }
+
+ if (trigger == PK_IRQ_TRIGGER_EDGE_SENSITIVE) {
+ out64(STD_LCL_EITR_OR, STD_IRQ_MASK64(irq));
+ } else {
+ out64(STD_LCL_EITR_CLR, STD_IRQ_MASK64(irq));
+ }
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+/// (Re)define the IRQ handler and priority for an interrupt.
+/// Return values other then PK_OK (0) are errors; see \ref pk_errors
+///
+/// Note that PK allows this API to be called from any context, and changes
+/// to the interrupt controller are made from a critical section.
+///
+/// \retval 0 Successful completion
+///
+/// \retval -PK_INVALID_ARGUMENT_IRQ_HANDLER One or more arguments are
+/// invalid, including an invalid \a irq, a null (0) \a handler,
+/// or invalid \a priority.
+
+int
+pk_irq_handler_set(PkIrqId irq,
+ PkIrqHandler handler,
+ void *arg)
+{
+ PkMachineContext ctx;
+
+ if (PK_ERROR_CHECK_API) {
+ PK_ERROR_IF(!STD_IRQ_VALID(irq) ||
+ (handler == 0),
+ PK_INVALID_ARGUMENT_IRQ_HANDLER);
+ }
+
+ pk_critical_section_enter(&ctx);
+
+ __ppe42_irq_handlers[irq].handler = handler;
+ __ppe42_irq_handlers[irq].arg = arg;
+
+ pk_critical_section_exit(&ctx);
+
+ return PK_OK;
+}
+
+
+
diff --git a/src/ppe/pk/std/std_register_addresses.h b/src/ppe/pk/std/std_register_addresses.h
new file mode 100644
index 0000000..8cf671a
--- /dev/null
+++ b/src/ppe/pk/std/std_register_addresses.h
@@ -0,0 +1,73 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std_register_addresses.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STD_REGISTER_ADDRESSES_H__
+#define __STD_REGISTER_ADDRESSES_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file std_register_addresses.h
+/// \brief Symbolic addresses for a standard PPE
+
+#include "pk.h"
+
+// Define the base address for the external interrupt controller registers
+// This can be overridden in the pk_app_cfg.h file
+#ifndef STD_EIC_BASE
+#define STD_EIC_BASE 0xC0000000
+#endif
+
+// Define the base address for the PPE mode registers
+// This can be overridden in the pk_app_cfg.h file
+#ifndef STD_PMR_BASE
+#define STD_PMR_BASE 0xC0000100
+#endif
+
+// Note: This list only contains registers that are needed by PK. If
+// an application requires other registers, it should define them
+// elsewhere (i.e., cme_register_addresses.h)
+#define STD_LCL_EISR (STD_EIC_BASE + 0x0000)
+#define STD_LCL_EISR_OR (STD_EIC_BASE + 0x0010)
+#define STD_LCL_EISR_CLR (STD_EIC_BASE + 0x0018)
+#define STD_LCL_EIMR (STD_EIC_BASE + 0x0020)
+#define STD_LCL_EIMR_OR (STD_EIC_BASE + 0x0030)
+#define STD_LCL_EIMR_CLR (STD_EIC_BASE + 0x0038)
+#define STD_LCL_EIPR (STD_EIC_BASE + 0x0040)
+#define STD_LCL_EIPR_OR (STD_EIC_BASE + 0x0050)
+#define STD_LCL_EIPR_CLR (STD_EIC_BASE + 0x0058)
+#define STD_LCL_EITR (STD_EIC_BASE + 0x0060)
+#define STD_LCL_EITR_OR (STD_EIC_BASE + 0x0070)
+#define STD_LCL_EITR_CLR (STD_EIC_BASE + 0x0078)
+#define STD_LCL_EISTR (STD_EIC_BASE + 0x0080)
+#define STD_LCL_EINR (STD_EIC_BASE + 0x00a0)
+
+#define STD_LCL_TSEL (STD_PMR_BASE + 0x0000)
+#define STD_LCL_TBR (STD_PMR_BASE + 0x0040)
+
+#endif // __STD_REGISTER_ADDRESSES_H__
+
diff --git a/src/ppe/pk/std/std_timebase.h b/src/ppe/pk/std/std_timebase.h
new file mode 100644
index 0000000..10cacf9
--- /dev/null
+++ b/src/ppe/pk/std/std_timebase.h
@@ -0,0 +1,66 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/std/std_timebase.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __STD_TIMEBASE_H__
+#define __STD_TIMEBASE_H__
+
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2015
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file std_timebase.h
+/// \brief support for using the standard PPE 32 bit timebase register
+///
+/// Each standard PPE has it's own timebase register that runs at a constant
+/// frequency.
+
+#include "pk.h"
+
+#ifndef __ASSEMBLER__
+
+#ifndef APPCFG_USE_EXT_TIMEBASE
+static inline
+uint32_t pk_timebase32_get(void)
+{
+ return (uint32_t)((in64(STD_LCL_TBR)) >> 32);
+}
+
+#else
+//assembly function is defined in ppe42_timebase.S
+uint32_t pk_timebase32_get(void);
+
+#endif /* APPCFG_USE_EXT_TIMEBASE */
+
+#else
+
+ .macro _pk_timebase32_get rT, rA
+ lis \rA, STD_LCL_TBR@ha
+ lvd \rT, STD_LCL_TBR@l(\rA)
+ .endm
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __STD_TIMEBASE_H__ */
diff --git a/src/ppe/pk/trace/Makefile b/src/ppe/pk/trace/Makefile
new file mode 100644
index 0000000..45f5a44
--- /dev/null
+++ b/src/ppe/pk/trace/Makefile
@@ -0,0 +1,50 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/trace/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# This Makefile is designed to be invoked with the -I argument set to
+# the location of the "pk.mk" for the build
+
+include img_defs.mk
+include pktracefiles.mk
+
+ifeq "$(PK_TIMER_SUPPORT)" "1"
+PKTRACE_OBJECTS += ${PKTRACE-TIMER-C-SOURCES:.c=.o} ${PKTRACE-TIMER-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" "1"
+PKTRACE_OBJECTS += ${PKTRACE-THREAD-C-SOURCES:.c=.o} ${PKTRACE-THREAD-S-SOURCES:.S=.o}
+endif
+
+OBJS := $(addprefix $(OBJDIR)/, $(PKTRACE_OBJECTS))
+
+all: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/pk/trace/pk_trace.h b/src/ppe/pk/trace/pk_trace.h
new file mode 100644
index 0000000..81d8eaf
--- /dev/null
+++ b/src/ppe/pk/trace/pk_trace.h
@@ -0,0 +1,303 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/trace/pk_trace.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_TRACE_H__
+#define __PK_TRACE_H__
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_trace.h
+/// \brief Macros and declarations for the PK Firmware Tracing Facility.
+///
+
+#include <stdint.h>
+
+#define PK_TRACE_VERSION 2
+
+#ifndef PK_TRACE_SZ
+#define PK_TRACE_SZ 256
+#endif
+
+//Fail compilation if size is not a power of 2
+#if ((PK_TRACE_SZ - 1) & PK_TRACE_SZ)
+#error "PK_TRACE_SZ is not a power of two!!!"
+#endif
+
+//Fail compilation if size is smaller than 64 bytes
+#if (PK_TRACE_SZ < 64)
+#error "PK_TRACE_SZ must be at least 64 bytes!!!"
+#endif
+
+//Mask for calculating offsets into the trace circular buffer
+#define PK_TRACE_CB_MASK (PK_TRACE_SZ - 1)
+
+#define STRINGIFY_HELPER(x) #x
+#define STRINGIFY(x) STRINGIFY_HELPER(x)
+
+#define PPE_IMG_STRING STRINGIFY(IMAGE_NAME)
+
+#ifdef PK_TRACE_HASH_PREFIX
+#if (PK_TRACE_HASH_PREFIX > 0xffff)
+#error PK_TRACE_HASH_PREFIX must be defined as a 16 bit constant value
+#endif
+#endif //PK_TRACE_HASH_PREFIX
+
+//This provides a 128ns tick (assuming a 32ns clock period)
+//and 4 different format values
+#define PK_TRACE_TS_BITS 30
+
+#define PK_TRACE_FORMAT_BITS (32 - PK_TRACE_TS_BITS)
+
+#define PK_TRACE_TS_MASK (0xfffffffful << PK_TRACE_FORMAT_BITS)
+#define PK_TRACE_FORMAT_MASK (~PK_TRACE_TS_MASK)
+
+#define PK_GET_TRACE_FORMAT(w32) (PK_TRACE_FORMAT_MASK & w32)
+#define PK_GET_TRACE_TIME(w32) (PK_TRACE_TS_MASK & w32)
+
+//Set the trace timer period to be the maximum
+//32 bit time minus 2 seconds (assuming a 32ns tick)
+//This allows for up to 1 second of interrupt latency +
+//1 second for PK_TRACE_MTBT while only requiring a trace
+//every 135 seconds in order to maintain the 64bit timebase.
+#define PK_TRACE_TIMER_PERIOD (0xfffffffful - 62500000)
+
+//The Maximum Time Between Traces. In order to reduce the time that interrupts
+//are disabled for tracing, reading of the time stamp is not done atomically
+//with alocating an entry in the circular buffer. This means that the
+//timestamps might not appear in order in the trace buffer. This is a
+//problem because our calculation of the 64 bit timebase uses the unsigned
+//difference of the current 32bit timestamp and the previous one and if they
+//are out of order it will result in a very large difference. To solve this
+//problem, any time that the parser code sees a very large difference (larger
+//than PK_TRACE_MTBT) it will treat it as a negative number.
+#define PK_TRACE_MTBT (0xfffffffful - 31250000)
+
+#define PK_TRACE_MAX_PARMS 4
+
+//This is the maximum number of bytes allowed to be traced in a binary trace
+//entry.
+//The trace version needs to change if this changes.
+#define PK_TRACE_MAX_BINARY 256
+
+//clip the largest binary trace according to the trace buffer size.
+//(The trace version does not need to change if this changes as long
+// as it remains less than PK_TRACE_MAX_BINARY)
+#if (PK_TRACE_SZ <= 256)
+#define PK_TRACE_CLIPPED_BINARY_SZ PK_TRACE_SZ / 2
+#else
+#define PK_TRACE_CLIPPED_BINARY_SZ PK_TRACE_MAX_BINARY
+#endif
+
+//Trace formats that are supported
+typedef enum
+{
+ PK_TRACE_FORMAT_EMPTY,
+ PK_TRACE_FORMAT_TINY,
+ PK_TRACE_FORMAT_BIG,
+ PK_TRACE_FORMAT_BINARY,
+}PkTraceFormat; //pk_trace_format_t;
+
+//This combines the timestamp and the format bits into a
+//single 32 bit word.
+typedef union
+{
+ struct
+ {
+ uint32_t timestamp : PK_TRACE_TS_BITS;
+ uint32_t format : PK_TRACE_FORMAT_BITS;
+ };
+ uint32_t word32;
+}PkTraceTime; //pk_trace_time_t;
+
+//PK trace uses a 16 bit string format hash value
+typedef uint16_t PkTraceHash; //pk_trace_hash_t;
+
+//The constant 16 bit hash value is combined with a
+//16 bit parameter value when doing a tiny trace
+typedef union
+{
+ struct
+ {
+ PkTraceHash string_id;
+ uint16_t parm;
+ };
+ uint32_t word32;
+}PkTraceTinyParms; //pk_trace_tiny_parms_t;
+
+//A tiny trace fits within a single 8 byte word. This includes
+//the timestamp, format bits, hash id, and a 16 bit parameter.
+typedef union
+{
+ struct
+ {
+ PkTraceTinyParms parms;
+ PkTraceTime time_format;
+ };
+ uint64_t word64;
+}PkTraceTiny; //pk_trace_tiny_t;
+
+//Larger traces that require a 32 bit parameter or more than one
+//parameter use the big trace format. The number of parms and
+//the 'complete' flag are combined with the hash id. 'complete'
+//is set to 0 initially and set to one only after all of the trace
+//data has been written.
+typedef union
+{
+ struct
+ {
+ PkTraceHash string_id;
+ uint8_t complete;
+ uint8_t num_parms;
+ };
+ uint32_t word32;
+}PkTraceBigParms; //pk_trace_big_parms_t;
+
+typedef union
+{
+ struct
+ {
+ PkTraceBigParms parms;
+ PkTraceTime time_format;
+ };
+ uint64_t word64;
+}PkTraceBig; //pk_trace_big_t;
+
+//Binary traces are handled in a similar fashion to big traces, except
+//that instead of having a number of parameters, we have number of bytes.
+typedef union
+{
+ struct
+ {
+ PkTraceHash string_id;
+ uint8_t complete;
+ uint8_t num_bytes;
+ };
+ uint32_t word32;
+}PkTraceBinaryParms; //pk_trace_binary_parms_t;
+
+typedef union
+{
+ struct
+ {
+ PkTraceBinaryParms parms;
+ PkTraceTime time_format;
+ };
+ uint64_t word64;
+}PkTraceBinary; //pk_trace_binary_t;
+
+//This is a generic structure that can be used to retrieve data
+//for tiny, big, and binary formatted entries.
+typedef union
+{
+ struct
+ {
+ PkTraceHash string_id;
+ union
+ {
+ uint16_t parm16;
+ struct
+ {
+ uint8_t complete;
+ uint8_t bytes_or_parms_count;
+ };
+ };
+ PkTraceTime time_format;
+ };
+ uint64_t word64;
+}PkTraceGeneric; //pk_trace_generic_t;
+
+//This is a format that might be used in the future for tracing
+//a 64 bit timestamp so that we don't fill up the buffer with periodic
+//timer traces. It is not currently used.
+#if 0
+typedef union
+{
+ struct
+ {
+ uint32_t upper32;
+ PkTraceTime time_format;
+ };
+ uint64_t word64;
+}PkTraceTime64; //pk_trace_time64_t;
+#endif
+
+//It would probably be more accurate to call this a footer since it
+//actually resides at the highest address of each trace entry. These eight
+//bytes contain information that allow us to walk the trace buffer from the
+//most recent entry to the oldest entry.
+typedef union
+{
+ PkTraceGeneric generic;
+ PkTraceBinary binary;
+ PkTraceBig big;
+ PkTraceTiny small;
+}PkTraceEntryFooter; //pk_trace_entry_header_t;
+
+
+//This is the data that is updated (in the buffer header) every time we add
+//a new entry to the buffer.
+typedef union
+{
+ struct
+ {
+ uint32_t tbu32;
+ uint32_t offset;
+ };
+ uint64_t word64;
+}PkTraceState; //pk_trace_state_t;
+
+#define PK_TRACE_IMG_STR_SZ 16
+
+//Header data for the trace buffer that is used for parsing the data.
+//Note: pk_trace_state_t contains a uint64_t which is required to be
+//placed on an 8-byte boundary according to the EABI Spec. This also
+//causes cb to start on an 8-byte boundary.
+typedef struct
+{
+ //these values are needed by the parser
+ uint16_t version;
+ uint16_t rsvd;
+ char image_str[PK_TRACE_IMG_STR_SZ];
+ uint16_t instance_id;
+ uint16_t partial_trace_hash;
+ uint16_t hash_prefix;
+ uint16_t size;
+ uint32_t max_time_change;
+ uint32_t hz;
+ uint32_t pad;
+ uint64_t time_adj64;
+
+ //updated with each new trace entry
+ PkTraceState state;
+
+ //circular trace buffer
+ uint8_t cb[PK_TRACE_SZ];
+}PkTraceBuffer; //pk_trace_buffer_t;
+
+extern PkTraceBuffer g_pk_trace_buf;
+
+#endif /* __PK_TRACE_H__ */
diff --git a/src/ppe/pk/trace/pk_trace_big.c b/src/ppe/pk/trace/pk_trace_big.c
new file mode 100644
index 0000000..46c0eed
--- /dev/null
+++ b/src/ppe/pk/trace/pk_trace_big.c
@@ -0,0 +1,116 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/trace/pk_trace_big.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_trace_big.c
+/// \brief PK Trace function that supports up to four 32-bit parameters
+///
+/// The pk_trace_big function is only called (via some macro magic) if the
+/// caller passes in a single parameter (not including the format string)
+/// that is larger than 16 bits to the PK_TRACE(...) macro.
+///
+
+#include "pk.h"
+#include "pk_trace.h"
+
+#if (PK_TRACE_SUPPORT && PK_TIMER_SUPPORT)
+void pk_trace_big(uint32_t i_hash_and_count,
+ uint64_t i_parm1, uint64_t i_parm2)
+{
+ PkTraceBig footer;
+ PkTraceBig* footer_ptr;
+ PkTraceState state;
+ uint64_t* ptr64;
+ uint64_t tb64;
+ PkMachineContext ctx;
+ uint32_t parm_size;
+ uint32_t cur_offset;
+ uint32_t footer_offset;
+
+ //fill in the footer data
+ tb64 = pk_timebase_get();
+ footer.parms.word32 = i_hash_and_count; //this has the parm count and hash
+ state.tbu32 = tb64 >> 32;
+ footer.time_format.word32 = tb64 & 0x00000000ffffffffull;
+ footer.time_format.format = PK_TRACE_FORMAT_BIG;
+
+ //round up to 8 byte boundary
+ if(footer.parms.num_parms <= 2)
+ {
+ parm_size = 8;
+ }
+ else
+ {
+ parm_size = 16;
+ }
+
+ //*****The following operations must be done atomically*****
+ pk_critical_section_enter(&ctx);
+
+ //load in the offset in the cb for the entry we are adding
+ cur_offset = g_pk_trace_buf.state.offset;
+
+ //Find the offset for the footer (at the end of the entry)
+ footer_offset = cur_offset + parm_size;
+
+ //calculate the address of the footer
+ ptr64 = (uint64_t*)&g_pk_trace_buf.cb[footer_offset & PK_TRACE_CB_MASK];
+
+ //calculate the offset for the next entry in the cb
+ state.offset = footer_offset + sizeof(PkTraceBig);
+
+ //update the cb state (tbu and offset)
+ g_pk_trace_buf.state.word64 = state.word64;
+
+ //write the data to the circular buffer including the
+ //timesamp, string hash, and 16bit parameter
+ *ptr64 = footer.word64;
+
+ //*******************exit the critical section***************
+ pk_critical_section_exit(&ctx);
+
+
+ //write parm values to the circular buffer
+ footer_ptr = (PkTraceBig*)ptr64;
+ ptr64 = (uint64_t*)&g_pk_trace_buf.cb[cur_offset & PK_TRACE_CB_MASK];
+ *ptr64 = i_parm1;
+ if(parm_size > 8)
+ {
+ ptr64 = (uint64_t*)&g_pk_trace_buf.cb[(cur_offset + 8) & PK_TRACE_CB_MASK];
+ *ptr64 = i_parm2;
+ }
+
+ //Mark the trace entry update as being completed
+ footer_ptr->parms.complete = 1;
+
+}
+
+#endif
+
+
diff --git a/src/ppe/pk/trace/pk_trace_binary.c b/src/ppe/pk/trace/pk_trace_binary.c
new file mode 100644
index 0000000..a510d9d
--- /dev/null
+++ b/src/ppe/pk/trace/pk_trace_binary.c
@@ -0,0 +1,115 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/trace/pk_trace_binary.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_trace_binary.c
+/// \brief PK Trace function for dumping memory contents
+///
+/// The pk_trace_binary function is called by the PK_TRACE_BINARY() macro.
+///
+
+
+#include "pk.h"
+#include "pk_trace.h"
+
+#if (PK_TRACE_SUPPORT && PK_TIMER_SUPPORT)
+void pk_trace_binary(uint32_t i_hash_and_size, void* bufp)
+{
+ PkTraceBinary footer;
+ PkTraceBinary* footer_ptr;
+ PkTraceState state;
+ uint64_t* ptr64;
+ uint64_t tb64;
+ PkMachineContext ctx;
+ uint32_t data_size;
+ uint32_t cb_offset;
+ uint32_t footer_offset;
+ uint8_t* dest;
+ uint8_t* src;
+ uint32_t index;
+
+ //fill in the footer data
+ tb64 = pk_timebase_get();
+ footer.parms.word32 = i_hash_and_size; //this has the size and hash
+ state.tbu32 = tb64 >> 32;
+ footer.time_format.word32 = tb64 & 0x00000000ffffffffull;
+ footer.time_format.format = PK_TRACE_FORMAT_BINARY;
+
+ //round up to 8 byte boundary
+ data_size = (footer.parms.num_bytes + 7) & ~0x00000007ul;
+
+ //limit data size
+ if(data_size > PK_TRACE_CLIPPED_BINARY_SZ)
+ {
+ data_size = PK_TRACE_CLIPPED_BINARY_SZ;
+ }
+
+ //*****The following operations must be done atomically*****
+ pk_critical_section_enter(&ctx);
+
+ //load in the offset in the cb for the entry we are adding
+ cb_offset = g_pk_trace_buf.state.offset;
+
+ //Find the offset for the footer (at the end of the entry)
+ footer_offset = cb_offset + data_size;
+
+ //calculate the address of the footer
+ ptr64 = (uint64_t*)&g_pk_trace_buf.cb[footer_offset & PK_TRACE_CB_MASK];
+
+ //calculate the offset for the next entry in the cb
+ state.offset = footer_offset + sizeof(PkTraceBinary);
+
+ //update the cb state (tbu and offset)
+ g_pk_trace_buf.state.word64 = state.word64;
+
+ //write the footer data to the circular buffer including the
+ //timesamp, string hash and data size
+ *ptr64 = footer.word64;
+
+ //*******************exit the critical section***************
+ pk_critical_section_exit(&ctx);
+
+ //write data to the circular buffer
+ for(src = bufp, index = 0;
+ index < data_size;
+ index++)
+ {
+ dest = &g_pk_trace_buf.cb[(cb_offset + index) & PK_TRACE_CB_MASK];
+ *dest = *(src++);
+ }
+
+ //Mark the trace entry update as being completed
+ footer_ptr = (PkTraceBinary*)ptr64;
+ footer_ptr->parms.complete = 1;
+
+}
+
+#endif
+
+
diff --git a/src/ppe/pk/trace/pk_trace_core.c b/src/ppe/pk/trace/pk_trace_core.c
new file mode 100644
index 0000000..17aaca1
--- /dev/null
+++ b/src/ppe/pk/trace/pk_trace_core.c
@@ -0,0 +1,140 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/pk/trace/pk_trace_core.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_trace_core.c
+/// \brief PK Trace core data and code.
+///
+/// This file includes the minimal code/data required to do minimal tracing.
+/// This includes the periodic timer initialization and the pk_trace_tiny
+/// function. The pk_trace_tiny function is called by the PK_TRACE() macro
+/// when there is one or less parameters (not including the format string)
+/// and the parameter size is 16 bits or smaller.
+///
+
+#include "pk.h"
+#include "pk_trace.h"
+
+void pk_trace_timer_callback(void* arg);
+
+#if (PK_TRACE_SUPPORT && PK_TIMER_SUPPORT)
+
+//Static initialization of the trace timer
+PkTimer g_pk_trace_timer = {
+ .deque = PK_DEQUE_ELEMENT_INIT(),
+ .timeout = 0,
+ .callback = pk_trace_timer_callback,
+ .arg = 0,
+};
+
+//Static initialization of the pk trace buffer
+PkTraceBuffer g_pk_trace_buf =
+{
+ .version = PK_TRACE_VERSION,
+ .image_str = PPE_IMG_STRING,
+ .hash_prefix = PK_TRACE_HASH_PREFIX,
+ .partial_trace_hash = trace_ppe_hash("PARTIAL TRACE ENTRY. HASH_ID = %d", PK_TRACE_HASH_PREFIX),
+ .size = PK_TRACE_SZ,
+ .max_time_change = PK_TRACE_MTBT,
+ .hz = 500000000, //default value. Actual value is set in pk_init.c
+ .time_adj64 = 0,
+ .state.word64 = 0,
+ .cb = {0}
+};
+
+//Needed for buffer extraction in simics for now
+PkTraceBuffer* g_pk_trace_buf_ptr = &g_pk_trace_buf;
+
+// Creates an 8 byte entry in the trace buffer that includes a timestamp,
+// a format string hash value and a 16 bit parameter.
+//
+// i_parm has the hash value combined with the 16 bit parameter
+void pk_trace_tiny(uint32_t i_parm)
+{
+ PkTraceTiny footer;
+ PkTraceState state;
+ uint64_t* ptr64;
+ uint64_t tb64;
+ PkMachineContext ctx;
+
+ //fill in the footer data
+ footer.parms.word32 = i_parm;
+ tb64 = pk_timebase_get();
+ state.tbu32 = tb64 >> 32;
+ footer.time_format.word32 = tb64 & 0x00000000ffffffffull;
+
+ footer.time_format.format = PK_TRACE_FORMAT_TINY;
+
+ //The following operations must be done atomically
+ pk_critical_section_enter(&ctx);
+
+ //load the current byte count and calculate the address for this
+ //entry in the cb
+ ptr64 = (uint64_t*)&g_pk_trace_buf.cb[g_pk_trace_buf.state.offset & PK_TRACE_CB_MASK];
+
+ //calculate the offset for the next entry in the cb
+ state.offset = g_pk_trace_buf.state.offset + sizeof(PkTraceTiny);
+
+ //update the cb state (tbu and offset)
+ g_pk_trace_buf.state.word64 = state.word64;
+
+ //write the data to the circular buffer including the
+ //timesamp, string hash, and 16bit parameter
+ *ptr64 = footer.word64;
+
+ //exit the critical section
+ pk_critical_section_exit(&ctx);
+}
+
+
+// This function is called periodically in order to ensure that the max ticks
+// between trace entries is no more than what will fit inside a 32bit value.
+void pk_trace_timer_callback(void* arg)
+{
+
+ // guarantee at least one trace before the lower 32bit timebase flips
+ PK_TRACE("PERIODIC TIMESTAMPING TRACE");
+
+ // restart the timer
+ pk_timer_schedule(&g_pk_trace_timer,
+ PK_TRACE_TIMER_PERIOD);
+}
+
+// Use this function to synchronize the timebase between multiple PPEs.
+// PPE A can send PPE B it's current timebase and then PPE B can set that
+// as the current timebase for tracing purposes. It can also be used
+// to set the current time to 0. This function changes the timebase for
+// all entries that are currently in the trace buffer. Setting the current
+// timebase to 0 will cause previous traces to have very large timestamps.
+void pk_trace_set_timebase(PkTimebase timebase)
+{
+ g_pk_trace_buf.time_adj64 = timebase - pk_timebase_get();
+}
+
+#endif
diff --git a/src/ppe/pk/trace/pktracefiles.mk b/src/ppe/pk/trace/pktracefiles.mk
new file mode 100644
index 0000000..5ef8823
--- /dev/null
+++ b/src/ppe/pk/trace/pktracefiles.mk
@@ -0,0 +1,63 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/pk/trace/pktracefiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file pkppe42files.mk
+#
+# @brief mk for including ppe42 object files
+#
+# @page ChangeLogs Change Logs
+# @section pkppe42files.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+##########################################################################
+# Include Files
+##########################################################################
+
+
+
+##########################################################################
+# Object Files
+##########################################################################
+PKTRACE-C-SOURCES = pk_trace_core.c pk_trace_big.c pk_trace_binary.c
+
+PKTRACE-S-SOURCES =
+
+PKTRACE-TIMER-C-SOURCES =
+PKTRACE-TIMER-S-SOURCES =
+
+PKTRACE-THREAD-C-SOURCES +=
+PKTRACE-THREAD-S-SOURCES +=
+
+
+PKTRACE_OBJECTS += $(PKTRACE-C-SOURCES:.c=.o) $(PKTRACE-S-SOURCES:.S=.o)
+
+
+
diff --git a/src/ppe/sbe/.empty b/src/ppe/sbe/.empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/ppe/sbe/.empty
diff --git a/src/ppe/sbe/image/Makefile b/src/ppe/sbe/image/Makefile
new file mode 100644
index 0000000..a784342
--- /dev/null
+++ b/src/ppe/sbe/image/Makefile
@@ -0,0 +1,222 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/sbe/image/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+#remove this once we have a real compiler
+export P2P_ENABLE = 1
+
+#remove this once we have a real compiler
+export SBEFW_ENABLE = 1
+
+#Pull in the definitions that affect all makefiles for this image
+include img_defs.mk
+
+#Pull in object file names for the top directory
+include topfiles.mk
+
+ifdef P2P_ENABLE
+include $(P2P_SRCDIR)/p2pfiles.mk
+endif
+
+#Pull in PPE complier libraries .
+# Sets up the following variables:
+# $(GCCLIBS) -> Libary objects to be linked
+# $(LIB_DIRS) -> Include directories
+include ../../include/ppe_compiler.mk
+
+
+PK_MAKE_DIR := $(PK_SRCDIR)/$(PPE_TYPE)
+LIB_DIRS += -L$(OBJDIR)/pk
+PKLIB := $(OBJDIR)/pk/libpk.a
+LLIBS += -lpk
+
+SBEFW_MAKE_DIR := ../sbefw
+LIB_DIRS += -L$(OBJDIR)/sbefw
+SBEFWLIB := $(OBJDIR)/sbefw/libsbefw.a
+LLIBS += -lsbefw
+
+SAMPLE_MAKE_DIR := ../sample
+LIB_DIRS += -L$(OBJDIR)/sample
+SAMPLELIB := $(OBJDIR)/sample/libsample.a
+#LLIBS += -lsample
+
+# FAPI2 library
+FAPI2_MAKE_DIR := $(PLAT_FAPI2_DIR)
+LIB_DIRS += -L$(OBJDIR)/fapi2
+FAPI2LIB := $(OBJDIR)/fapi2/libfapi2.a
+LLIBS += -lfapi2
+
+ifdef P2P_ENABLE
+LIB_DIRS += -L$(OBJDIR)/p2p
+P2PLIB := $(OBJDIR)/p2p/libp2p.a
+LINK_OBJS += $(P2PLIB)
+LLIBS += -lp2p
+endif
+
+# HWP LIB library
+HWPLIB_MAKE_DIR := $(HWPLIB_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/lib
+HWPLIB := $(OBJDIR)/libcommon.a
+LLIBS += -lcommon
+
+# Common Cache HWP Exit library
+CACHE_MAKE_DIR := $(CACHE_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/cache
+CACHELIB := $(OBJDIR)/cache/libcache.a
+LLIBS += -lcache
+
+
+# Common Core libraries
+CORE_MAKE_DIR := $(CORE_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/core
+CORELIB := $(OBJDIR)/core/libcore.a
+LLIBS += -lcore
+
+# Common Perv libraries
+PERV_MAKE_DIR := $(PERV_SRCDIR)
+LIB_DIRS += -L$(OBJDIR)/perv
+PERVLIB := $(OBJDIR)/perv/libperv.a
+LLIBS += -lperv
+
+LINK_OBJS = $(OBJS) $(PKLIB) $(SBEFWLIB) $(FAPI2LIB) $(CACHELIB) $(CORELIB) $(HWPLIB) $(P2PLIB) $(PERVLIB)
+
+# Define the objects
+OBJS := $(addprefix $(OBJDIR)/, $(TOP_OBJECTS))
+LINK_OBJS += $(OBJS) $(GCCLIBS)
+#LINK_OBJS += $(OBJS) $(PKLIB) $(CPPLIB) $(PPELIB)
+LINK_SCRIPT = $(addprefix $(OBJDIR)/, linkscript)
+
+
+
+#default target is to make a binary application image
+#This removes all unecessary headers from the ELF executable
+$(OBJDIR)/$(IMAGE_NAME).bin $(OBJDIR)/$(IMAGE_NAME).dis: $(OBJDIR)/$(IMAGE_NAME).out
+ $(OBJCOPY) -O binary $< $(OBJDIR)/$(IMAGE_NAME).bin --pad-to 0x`/usr/bin/nm $(OBJDIR)/$(IMAGE_NAME).out | grep "A _sbe_base_end" | cut -d " " -f 1`
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_NAME).dis
+
+#create a linked ELF executable
+$(OBJDIR)/$(IMAGE_NAME).out: $(LINK_OBJS) $(LINK_SCRIPT)
+ $(LD) -e __system_reset -T$(LINK_SCRIPT) -Map $(OBJDIR)/$(IMAGE_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_NAME).out $(LIB_DIRS) $(OBJS) --start-group $(LLIBS) --end-group
+# $(LD) -e __system_reset -T$(LINK_SCRIPT) -Map $(OBJDIR)/$(IMAGE_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_NAME).out $(LIB_DIRS) $(OBJS) -lpk -lp2p #-lcommon
+# $(LD) -e __system_reset -T$(LINK_SCRIPT) -Map $(OBJDIR)/$(IMAGE_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_NAME).out $(LIB_DIRS) $(OBJS) $(LLIBS)
+
+
+#pass the link command file through the C preprocessor to evaluate macros and remove comments
+$(LINK_SCRIPT): link.cmd
+ $(CPP) -E -x c++ -P $(DEFS) link.cmd -o $(LINK_SCRIPT)
+
+#Create an obj directory if needed
+$(LINK_OBJS) $(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ $(BASE_FAPI2_DIR)/tools/ppeParseProcSbeFixed.pl . $(TOOLS_ATTR_DIR)/p9_ppe_attributes1.xml $(ATTRFILES)
+ $(BASE_FAPI2_DIR)/tools/ppeParseAttributeInfo.pl $(PPE_FAPI2_DIR)/include $(TOOLS_ATTR_DIR)/p9_ppe_attributes1.xml $(ATTRFILES)
+ $(BASE_FAPI2_DIR)/tools/ppeCreateAttrGetSetMacros.pl -path $(BASE_FAPI2_DIR)/tools -inc $(PPE_FAPI2_DIR)/include -src $(PPE_FAPI2_DIR)/src
+ $(BASE_FAPI2_DIR)/tools/ppeCreateIfAttrService.pl $(PPE_FAPI2_DIR)/include $(TOOLS_ATTR_DIR)/p9_ppe_attributes1.xml $(ATTRFILES)
+ mkdir -p $(OBJDIR)
+
+.PHONY: clean topfixedheaders $(PKLIB) $(P2PLIB) $(SBEFWLIB) $(PPELIB) $(FAPI2LIB) $(CACHELIB) $(CORELIB) $(PERVLIB) $(HWPLIB)
+
+ATTRFILES += $(TOOLS_ATTR_DIR)/perv_attributes.xml
+ATTRFILES += $(TOOLS_ATTR_DIR)/proc_attributes.xml
+ATTRFILES += $(TOOLS_ATTR_DIR)/ex_attributes.xml
+ATTRFILES += $(TOOLS_ATTR_DIR)/eq_attributes.xml
+ATTRFILES += $(TOOLS_ATTR_DIR)/core_attributes.xml
+
+topfixedheaders:
+ $(BASE_FAPI2_DIR)/tools/ppeParseProcSbeFixed.pl . $(TOOLS_ATTR_DIR)/p9_ppe_attributes1.xml $(ATTRFILES)
+
+attrids:
+ $(BASE_FAPI2_DIR)/tools/ppeParseAttributeInfo.pl $(PPE_FAPI2_DIR)/include $(TOOLS_ATTR_DIR)/p9_ppe_attributes1.xml $(ATTRFILES)
+
+platattr:
+ $(BASE_FAPI2_DIR)/tools/ppeCreateAttrGetSetMacros.pl --path $(BASE_FAPI2_DIR)/tools --inc $(PPE_FAPI2_DIR)/include --src $(PPE_FAPI2_DIR)/src
+
+attrserv:
+ $(BASE_FAPI2_DIR)/tools/ppeCreateIfAttrService.pl $(PPE_FAPI2_DIR)/include $(TOOLS_ATTR_DIR)/p9_ppe_attributes1.xml $(ATTRFILES)
+
+
+#Build macro-specific kernel code
+$(PKLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(PK_MAKE_DIR)
+
+#Build macro-specific kernel code
+$(SBEFWLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(SBEFW_MAKE_DIR)
+
+
+#Build the code that is common for all processors (PPEs and 405)
+$(PPELIB):
+ @echo "Processing ppelibmakefile"
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(LIB_MAKE_DIR)
+
+#Build the cache exit code shared with the SBE
+$(CACHELIB):
+ @echo "Processing cache makefile"
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(CACHE_MAKE_DIR)
+
+#Build the core exit code shared with the SBE
+$(CORELIB):
+ @echo "Processing core makefile"
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(CORE_MAKE_DIR)
+
+#Build the perv code
+$(PERVLIB):
+ @echo "Processing perv makefile"
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(PERV_MAKE_DIR)
+
+#Build the comming HWP lib procedures
+$(HWPLIB):
+ @echo "Processing HWP lib makefile"
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(HWPLIB_MAKE_DIR)
+
+#Build the FAPI2 library
+$(FAPI2LIB):
+ @echo "Processing fapi2 makefile"
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(FAPI2_MAKE_DIR)/src
+
+ifdef P2P_ENABLE
+$(P2PLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(P2P_SRCDIR)
+endif
+
+# collect all of the trace hash files for this image into a single trexStringFile
+.PHONY : tracehash
+tracehash:
+ mkdir -p $(OBJDIR)
+ $(THASH) -c -d $(OBJDIR) -s $(OBJDIR)/trexStringFile
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+ rm $(TOP-FIXED-HEADERS)
+ rm *.dump
+
+
+dump:
+ objdump -s $(OBJDIR)/$(IMAGE_NAME).out > $(IMAGE_NAME).dump
+
+#Add dependencies to header files
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/sbe/image/base_main.C b/src/ppe/sbe/image/base_main.C
new file mode 100644
index 0000000..92cf13b
--- /dev/null
+++ b/src/ppe/sbe/image/base_main.C
@@ -0,0 +1,91 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/base_main.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file base_main.c
+/// \brief base program that creates and starts a thread
+///
+/// This file is a placeholder code in order to compile. I will be replaced in future by the code placed into the .text section.
+
+extern "C" {
+#include "pk.h"
+#include "pk_trace.h"
+#include "base_ppe_demo.h"
+#include "sbe_xip_image.h"
+}
+#define KERNEL_STACK_SIZE 256
+#define MAIN_THREAD_STACK_SIZE 256
+
+uint8_t G_kernel_stack[KERNEL_STACK_SIZE];
+uint8_t G_main_thread_stack[MAIN_THREAD_STACK_SIZE];
+PkThread G_main_thread;
+
+// A simple thread that just increments a local variable and sleeps
+void main_thread(void* arg)
+{
+
+ while(1)
+ {
+
+ pk_sleep(PK_SECONDS(1));
+
+ }
+}
+
+
+// The main function is called by the boot code (after initializing some
+// registers)
+int main(int argc, char **argv)
+{
+ // initializes kernel data (stack, threads, timebase, timers, etc.)
+ pk_initialize((PkAddress)G_kernel_stack,
+ KERNEL_STACK_SIZE,
+ 0,
+ 500000000);
+
+
+ //Initialize the thread control block for G_main_thread
+ pk_thread_create(&G_main_thread,
+ (PkThreadRoutine)main_thread,
+ (void*)NULL,
+ (PkAddress)G_main_thread_stack,
+ (size_t)MAIN_THREAD_STACK_SIZE,
+ (PkThreadPriority)1);
+
+
+
+ //Make G_main_thread runnable
+ pk_thread_resume(&G_main_thread);
+
+ // Start running the highest priority thread.
+ // This function never returns
+ pk_start_threads();
+
+ return 0;
+}
diff --git a/src/ppe/sbe/image/base_ppe_demo.c b/src/ppe/sbe/image/base_ppe_demo.c
new file mode 100644
index 0000000..0e8ea55
--- /dev/null
+++ b/src/ppe/sbe/image/base_ppe_demo.c
@@ -0,0 +1,44 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/base_ppe_demo.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file base_ppe_demo.c
+/// \brief example code to include into fixed section
+///
+/// demo function to include into fixed section. Can be replaced as soon as
+/// real functions are available
+
+#include "base_ppe_demo.h"
+#include "pk.h"
+#include "pk_trace.h"
+
+void base_ppe_demo_func(const char* str)
+{
+ PK_TRACE("TESTFUNCTION");
+}
diff --git a/src/ppe/sbe/image/base_ppe_demo.h b/src/ppe/sbe/image/base_ppe_demo.h
new file mode 100644
index 0000000..5447b0c
--- /dev/null
+++ b/src/ppe/sbe/image/base_ppe_demo.h
@@ -0,0 +1,43 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/base_ppe_demo.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file base_ppe_demo.h
+/// \brief routine to be placed into the fixed section.
+///
+/// this routing is a demonstration for functions to be placed into the fixed
+/// fixed section
+#ifndef __BASE_PPE_DEMO_H__
+#define __BASE_PPE_DEMO_H__
+
+/// this is a demo function whose pointer is placed into the fixed section
+/// @param str demo string
+void base_ppe_demo_func(const char*);
+
+#endif // __BASE_PPE_DEMO_H__
diff --git a/src/ppe/sbe/image/base_ppe_header.S b/src/ppe/sbe/image/base_ppe_header.S
new file mode 100644
index 0000000..b694bbe
--- /dev/null
+++ b/src/ppe/sbe/image/base_ppe_header.S
@@ -0,0 +1,220 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/base_ppe_header.S $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file base_ppe_header.S
+/// \brief code to create header, toc, strings, fixed and fixed_toc sections
+///
+/// function SbeXipHeader creates header section, function .proc_sbe_fixed
+/// creates fixed, fixed_toc sections
+#include "sbe_xip_image.h"
+#include "proc_sbe_fixed.H"
+
+
+#define PORE_SPACE_UNDEFINED 0xffff
+#define PORE_SPACE_OCI 0x8000
+#define PORE_SPACE_PNOR 0x800b
+#define PORE_SPACE_OTPROM 0x0001
+#define PORE_SPACE_SEEPROM 0x800c
+#define PORE_SPACE_PIBMEM 0x0008
+
+
+
+ .macro ..checku, x:req, bits:req, err="Unsigned value too large"
+
+ .if (((\bits) <= 0) || ((\bits) > 63))
+ .error "The number of bits must be in the range 0 < bits < 64"
+ .endif
+
+ .iflt (\x)
+ .error "An unsigned value is required here"
+ .endif
+
+ .ifgt ((\x) - (0xffffffffffffffff >> (64 - (\bits))))
+ .error "\err"
+ .endif
+
+ .endm
+
+ .macro ..check_u16, u16
+ ..checku (\u16), 16, "Unsigned immediate is larger than 16 bits"
+ .endm
+
+
+ .macro ..set_default_space, s
+ ..check_u16 (\s)
+ .set _PGAS_DEFAULT_SPACE, (\s)
+ .endm
+
+ .macro ..check_default_space
+ .if (_PGAS_DEFAULT_SPACE == PORE_SPACE_UNDEFINED)
+ .error "The PGAS default address space has not been defined"
+ .endif
+ .endm
+
+
+ .macro .quada, offset:req
+ ..check_default_space
+ .long _PGAS_DEFAULT_SPACE
+ .long (\offset)
+ .endm
+
+
+// .macro SbeXipHeader, magic, link_address, entry_point, image_size
+
+ .macro SbeXipSection, s:req, alignment=1, empty=0
+__\s\()_section:
+ .if \empty
+ .long 0
+ .long 0
+ .else
+ .long _\s\()_offset
+ .long _\s\()_size
+ .endif
+ .byte (\alignment)
+ .byte 0, 0, 0
+ .endm
+
+
+ .macro SbeXipHeader, magic, link_address, entry_point, image_size
+
+ .section .header, "a", @progbits
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Identification - 8-byte aligned; 8 Entries; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__magic:
+ .quad (\magic)
+__entry_offset:
+ .quad ((\entry_point) - (\link_address))
+__link_address:
+ .quada (\link_address)
+__header_64_reserved:
+ .quad 0, 0, 0, 0, 0
+
+ .xip_toc magic, SBE_XIP_UINT64, __magic
+ .xip_toc entry_offset, SBE_XIP_UINT64, __entry_offset
+ .xip_toc link_address, SBE_XIP_UINT64, __link_address
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Section Table - 8-byte aligned; 16 entries; Not TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+ SbeXipSection header
+ SbeXipSection fixed, 8
+ SbeXipSection fixed_toc, 8
+ SbeXipSection ipl_text, 4
+ SbeXipSection ipl_data, 8
+ SbeXipSection text, 4
+ SbeXipSection data, 8
+ SbeXipSection toc, 4
+ SbeXipSection strings
+ SbeXipSection halt, 4, empty=1
+ SbeXipSection pibmem0, 8, empty=1
+ SbeXipSection dcrings, 8, empty=1
+ SbeXipSection rings, 8, empty=1
+ SbeXipSection slw, 128, empty=1
+ SbeXipSection fit, empty=1
+ SbeXipSection ffdc, 8, empty=1
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Other Information - 4-byte aligned; 8 entries; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__image_size:
+ .long (\image_size)
+__build_date:
+ .long 0
+__build_time:
+ .long 0
+__header_32_reserved:
+ .long 0, 0, 0, 0, 0
+
+ .xip_toc image_size, SBE_XIP_UINT32, __image_size
+ .xip_toc build_date, SBE_XIP_UINT32, __build_date
+ .xip_toc build_time, SBE_XIP_UINT32, __build_time
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Other Information - 1-byte aligned; 8 entries; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__header_version:
+ .byte SBE_XIP_HEADER_VERSION
+__toc_normalized:
+ .byte 0
+__toc_sorted:
+ .byte 0
+__header_8_reserved:
+ .byte 0, 0, 0, 0, 0
+
+ .xip_toc header_version, SBE_XIP_UINT8, __header_version
+ .xip_toc toc_normalized, SBE_XIP_UINT8, __toc_normalized
+ .xip_toc toc_sorted, SBE_XIP_UINT8, __toc_sorted
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Strings; 64 characters allocated; TOC-Indexed
+ //////////////////////////////////////////////////////////////////////
+
+__build_user:
+ .asciz "unknown " # 16 Characters allocated
+__build_host:
+ .asciz "unknown " # 24 characters allocated
+__header_string_reserved:
+ .space 24, 0
+
+ .xip_toc build_user, SBE_XIP_STRING, __build_user
+ .xip_toc build_host, SBE_XIP_STRING, __build_host
+
+
+ .endm
+
+
+ .section .fixed, "a", @progbits
+ .section .fixed_toc, "a", @progbits
+ .section .ipl_data, "a", @progbits
+ .section .ipl_text, "a", @progbits
+
+ .section .toc, "a", @progbits
+ .section .strings, "aS", @progbits
+
+ ..set_default_space PORE_SPACE_SEEPROM
+ SbeXipHeader SBE_SEEPROM_MAGIC, 0xFFF00000, 0xFFF00C78, _sbe_base_size
+
+ // Create the .fixed section
+ .proc_sbe_fixed_proc_chip
+ .proc_sbe_fixed_perv
+ .proc_sbe_fixed_core
+ .proc_sbe_fixed_ex
+ .proc_sbe_fixed_eq
diff --git a/src/ppe/sbe/image/fapi_sbe_common.H b/src/ppe/sbe/image/fapi_sbe_common.H
new file mode 100644
index 0000000..aebd089
--- /dev/null
+++ b/src/ppe/sbe/image/fapi_sbe_common.H
@@ -0,0 +1,71 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/fapi_sbe_common.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file fapi_sbe_common.H
+/// \brief provides several preprocessor macros used functions in fixed secion.
+///
+/// Several preprocessor macros are required to have different definitions in
+/// C, C++ and SBE assembly procedures. These common forms are collected here.
+
+#ifndef __FAPI_SBE_COMMON_H
+#define __FAPI_SBE_COMMON_H
+
+/// Several preprocessor macros are required to have different definitions in
+/// C, C++ and SBE assembly procedures. These common forms are collected here.
+
+#if defined __ASSEMBLER__
+
+#define CONST_UINT8_T(name, expr) .set name, (expr)
+#define CONST_UINT32_T(name, expr) .set name, (expr)
+#define CONST_UINT64_T(name, expr) .set name, (expr)
+
+#define ULL(x) x
+
+#elif defined __cplusplus
+
+#include <stdint.h>
+
+#define CONST_UINT8_T(name, expr) const uint8_t name = (expr);
+#define CONST_UINT32_T(name, expr) const uint32_t name = (expr);
+#define CONST_UINT64_T(name, expr) const uint64_t name = (expr);
+
+#define ULL(x) x##ull
+
+#else // C code
+
+// CONST_UINT[8,3,64]_T() can't be used in C code/headers; Use
+//
+// #define <symbol> <value> [ or ULL(<value>) for 64-bit constants
+
+#define ULL(x) x##ull
+
+#endif // __ASSEMBLER__
+
+#endif // __FAPI_SBE_COMMON_H
diff --git a/src/ppe/sbe/image/img_defs.mk b/src/ppe/sbe/image/img_defs.mk
new file mode 100644
index 0000000..240c5db
--- /dev/null
+++ b/src/ppe/sbe/image/img_defs.mk
@@ -0,0 +1,336 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/sbe/image/img_defs.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Make header for SBE image build
+#
+# Settings to for SBE image file build
+#
+# IMG_INCLUDES : Aplication-specific header search paths
+#
+# DEFS : A string of -D<symbol>[=<value>] to control compilation
+#
+# PK : Default ..; The path to the PK source code.
+# The default is set for building the PK
+# subdirectories.
+#
+# PK_THREAD_SUPPORT : (0/1, default 1); Compile PK thread and
+# semaphore suppprt
+#
+# PK_TIMER_SUPPORT : (0/1, default 1); Compile PK timer suppprt
+#
+# GCC-O-LEVEL : The optimization level passed to GCC (default -Os). May
+# also be defined empty (GCC-O-LEVEL=) to disable
+# optimization. This variable can also be used to pass
+# any other non-default setting to GCC, e.g.
+# make GCC-O-LEVEL="-Os -fno-branch-count-reg"
+#
+# GCC-TOOL-PREFIX : The full path (including executable file prefixes) to
+# the GCC cross-development tools to use. The default is
+# "ppcnf-mcp5-"
+#
+# CTEPATH : This variable defaults to the afs/awd CTE tool
+# installation - The PORE binutils are stored there. If
+# you are not in Austin be sure to define CTEPATH in
+# your .profile.
+#
+# OBJDIR : target directory for all generated files
+
+IMAGE_NAME := sbe_main
+
+PPE_TYPE := std
+
+ifndef IMAGE_SRCDIR
+export IMAGE_SRCDIR = $(abspath .)
+endif
+
+ifndef CACHE_SRCDIR
+export CACHE_SRCDIR = $(abspath ../../hwp/cache)
+endif
+
+ifndef CORE_SRCDIR
+export CORE_SRCDIR = $(abspath ../../hwp/core)
+endif
+
+ifndef PERV_SRCDIR
+export PERV_SRCDIR = $(abspath ../../hwp/perv)
+endif
+
+ifndef HWPLIB_SRCDIR
+export HWPLIB_SRCDIR = $(abspath ../../hwp/lib)
+
+endif
+
+ifndef IMG_INCLUDES
+export IMG_INCLUDES = -I$(IMAGE_SRCDIR) -I$(CACHE_SRCDIR) -I$(CORE_SRCDIR)
+
+endif
+
+ifndef IMG_INCLUDES
+export IMG_INCLUDES = -I$(IMAGE_SRCDIR) -I$(CACHE_SRCDIR) -I$(CORE_SRCDIR)
+endif
+ifndef BASE_OBJDIR
+export BASE_OBJDIR = $(abspath ../obj)
+endif
+
+export IMG_OBJDIR = $(BASE_OBJDIR)/$(IMAGE_NAME)
+
+ifndef PK_SRCDIR
+export PK_SRCDIR = $(abspath ../../pk)
+endif
+
+ifndef TOOLS_ATTR_DIR
+export TOOLS_ATTR_DIR = $(abspath ../../tools/scripts)
+endif
+
+
+
+ifndef GCC-TOOL-PREFIX
+GCC-TOOL-PREFIX = $(CTEPATH)/tools/gcc405lin/prod/usr/bin/powerpc-linux-
+endif
+
+
+ifndef P2P_SRCDIR
+export P2P_SRCDIR = $(abspath ../../tools/PowerPCtoPPE)
+endif
+
+ifndef PPETRACEPP_DIR
+export PPETRACEPP_DIR = $(abspath ../../tools/ppetracepp)
+endif
+
+ifndef PLAT_FAPI2_DIR
+export PLAT_FAPI2_DIR = $(abspath ../plat)
+endif
+
+
+ifndef PPE_FAPI2_DIR
+export PPE_FAPI2_DIR = $(abspath ../../hwpf/plat)
+endif
+
+ifndef BASE_FAPI2_DIR
+export BASE_FAPI2_DIR = $(abspath /afs/awd/projects/eclipz/lab/p8/u/rembold/ekbgit/hwpf/fapi2)
+endif
+
+
+ifndef CC_ROOT
+export CC_ROOT = ${CTEPATH}/tools/gcc405lin/prod
+endif
+
+
+ifndef GCC-TOOL-PREFIX
+GCC-TOOL-PREFIX = ${CC_ROOT}/usr/bin/powerpc-linux-
+endif
+
+ifndef BINUTILS-TOOL-PREFIX
+BINUTILS-TOOL-PREFIX = $(CTEPATH)/tools/ppetools/prod/powerpc-eabi/bin/
+endif
+
+OBJDIR = $(BASE_OBJDIR)$(SUB_OBJDIR)
+
+CC_ASM = $(GCC-TOOL-PREFIX)gcc
+TCC = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)g++
+CC = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+AS = $(BINUTILS-TOOL-PREFIX)as
+AR = $(BINUTILS-TOOL-PREFIX)ar
+LD = $(BINUTILS-TOOL-PREFIX)ld
+OBJDUMP = $(BINUTILS-TOOL-PREFIX)objdump
+OBJCOPY = $(BINUTILS-TOOL-PREFIX)objcopy
+TCPP = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+THASH = $(PPETRACEPP_DIR)/tracehash.pl
+CPP = $(GCC-TOOL-PREFIX)gcc
+
+ifdef P2P_ENABLE
+PCP = $(P2P_SRCDIR)/ppc-ppe-pcp.py
+endif
+
+
+ifndef CTEPATH
+$(warning The CTEPATH variable is not defined; Defaulting to /afs/awd)
+export CTEPATH = /afs/awd/projects/cte
+endif
+
+ifeq "$(PK_TIMER_SUPPORT)" ""
+PK_TIMER_SUPPORT = 1
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" ""
+PK_THREAD_SUPPORT = 1
+endif
+
+ifeq "$(PK_TRACE_SUPPORT)" ""
+PK_TRACE_SUPPORT = 1
+endif
+
+# Generate a 16bit trace string hash prefix value based on the name of this image. This will form
+# the upper 16 bits of the 32 bit trace hash values.
+ifndef PK_TRACE_HASH_PREFIX
+PK_TRACE_HASH_PREFIX := $(shell echo $(IMAGE_NAME) | md5sum | cut -c1-4 | xargs -i printf "%d" 0x{})
+endif
+
+
+ifndef GCC-O-LEVEL
+#GCC-O-LEVEL = -Os
+#GCC-O-LEVEL = -O -g
+GCC-O-LEVEL = -O
+endif
+
+GCC-DEFS += -DIMAGE_NAME=$(IMAGE_NAME)
+GCC-DEFS += -DPK_TIMER_SUPPORT=$(PK_TIMER_SUPPORT)
+GCC-DEFS += -DPK_THREAD_SUPPORT=$(PK_THREAD_SUPPORT)
+GCC-DEFS += -DPK_TRACE_SUPPORT=$(PK_TRACE_SUPPORT)
+GCC-DEFS += -DPK_TRACE_HASH_PREFIX=$(PK_TRACE_HASH_PREFIX)
+GCC-DEFS += -D__PK__=1
+GCC-DEFS += -D__SBE__=1
+DEFS += $(GCC-DEFS)
+export LD_LIBRARY_PATH = /afs/awd.austin.ibm.com/proj/p3/cte/tools/gcc405lin/vol1/usr/lib
+
+############################################################################
+
+
+INCLUDES += $(IMG_INCLUDES) \
+ -I$(IMAGE_SRCDIR)/../../../include \
+ -I$(PLAT_FAPI2_DIR)/include \
+ -I$(PPE_FAPI2_DIR)/include \
+ -I$(BASE_FAPI2_DIR)/include \
+ -I$(PK_SRCDIR)/../include \
+ -I$(PK_SRCDIR)/$(PPE_TYPE) \
+ -I$(PK_SRCDIR)/../include \
+ -I$(PK_SRCDIR)/kernel \
+ -I$(PK_SRCDIR)/ppe \
+ -I$(PK_SRCDIR)/ppe42 \
+ -I$(PK_SRCDIR)/trace
+
+PIPE-CFLAGS = -pipe -Wa,-m405
+
+GCC-CFLAGS += -g -Wall -Werror -Wno-error=unused-label \
+ -msoft-float -mcpu=405 -mmulhw \
+ -meabi -msdata=eabi \
+ -ffreestanding \
+ -fno-common \
+ -fsigned-char \
+ -fno-inline-functions-called-once \
+ -ffixed-r11 \
+ -ffixed-r12 \
+ -ffixed-r14 \
+ -ffixed-r15 \
+ -ffixed-r16 \
+ -ffixed-r17 \
+ -ffixed-r18 \
+ -ffixed-r19 \
+ -ffixed-r20 \
+ -ffixed-r21 \
+ -ffixed-r22 \
+ -ffixed-r23 \
+ -ffixed-r24 \
+ -ffixed-r25 \
+ -ffixed-r26 \
+ -ffixed-r27 \
+ -ffixed-cr1 \
+ -ffixed-cr2 \
+ -ffixed-cr3 \
+ -ffixed-cr4 \
+ -ffixed-cr5 \
+ -ffixed-cr6 \
+ -ffixed-cr7
+
+
+CFLAGS = -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES)
+
+
+CPPFLAGS = -E -std=c++11
+#CPPFLAGS = -E
+
+ASFLAGS = -mppe42
+
+ifdef P2P_ENABLE
+#use this to disable optimizations (fused compare/branch etc.)
+PCP-FLAG =
+
+#use this to enable optimizations
+#PCP-FLAG =
+endif
+############################################################################
+
+#override the GNU Make implicit rule for going from a .C to a .o
+%.o: %.C
+
+$(OBJDIR)/%.s: %.C
+ $(TCC) $(PPE-CFLAGS) $(DEFS) -S -std=c++11 -o $@ $<
+
+
+#override the GNU Make implicit rule for going from a .c to a .o
+%.o: %.c
+
+$(OBJDIR)/%.s: %.c
+ $(CC) $(PPE-CFLAGS) $(DEFS) -S -o $@ $<
+
+#override the GNU Make implicit rule for going from a .S to a .o
+%.o: %.S
+
+$(OBJDIR)/%.s: %.S
+ $(TCPP) $(PPE-CFLAGS) $(DEFS) $(CPPFLAGS) -o $@ $<
+.PRECIOUS: $(OBJDIR)/%.s
+
+ifndef P2P_ENABLE
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.s
+ $(AS) $(ASFLAGS) -o $@ $<
+
+else
+
+$(OBJDIR)/%.es: $(OBJDIR)/%.s
+ $(PCP) $(PCP-FLAG) -f $<
+.PRECIOUS: $(OBJDIR)/%.es
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.es
+ $(AS) $(ASFLAGS) -o $@ $<
+
+endif
+
+# From the GNU 'Make' manual - these scripts uses the preprocessor to
+# create dependency files (*.d), then mungs them slightly to make them
+# work as Make targets. The *.d files are include-ed in the
+# subdirectory Makefiles.
+
+$(OBJDIR)/%.d: %.C
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.c
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ echo "$(INCLUDES)"; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.S
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
diff --git a/src/ppe/sbe/image/link.cmd b/src/ppe/sbe/image/link.cmd
new file mode 100644
index 0000000..8c75f1c
--- /dev/null
+++ b/src/ppe/sbe/image/link.cmd
@@ -0,0 +1,115 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/link.cmd $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#ifndef INITIAL_STACK_SIZE
+#define INITIAL_STACK_SIZE 256
+#endif
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+SECTIONS
+{
+ . = 0xfff00000;
+ _sbe_base_origin = . - 0;
+ ////////////////////////////////
+ // Header
+ ////////////////////////////////
+ . = ALIGN(1); _header_origin = .; _header_offset = . - _sbe_base_origin; .header . : { *(.header) } _header_size = . - _header_origin;
+
+ ////////////////////////////////
+ // FIXED
+ ////////////////////////////////
+ . = ALIGN(512); _fixed_origin = .; _fixed_offset = . - _sbe_base_origin; .fixed . : { *(.fixed) } _fixed_size = . - _fixed_origin;
+
+ ////////////////////////////////
+ // FIXED_TOC
+ ////////////////////////////////
+ . = ALIGN(8); _fixed_toc_origin = .; _fixed_toc_offset = . - _sbe_base_origin; .fixed_toc . : { *(.fixed_toc) } _fixed_toc_size = . - _fixed_toc_origin;
+
+ ////////////////////////////////
+ // IPL_TEXT
+ ////////////////////////////////
+ . = ALIGN(4); _ipl_text_origin = .; _ipl_text_offset = . - _sbe_base_origin; .ipl_text . : { *(.ipl_text) } _ipl_text_size = . - _ipl_text_origin;
+
+ ////////////////////////////////
+ // IPL_DATA
+ ////////////////////////////////
+ . = ALIGN(8); _ipl_data_origin = .; _ipl_data_offset = . - _sbe_base_origin; .ipl_data . : { *(.ipl_data) } _ipl_data_size = . - _ipl_data_origin;
+
+ ////////////////////////////////
+ // TEXT
+ ////////////////////////////////
+ . = ALIGN(4); _text_origin = .; _text_offset = . - _sbe_base_origin; .text . : {. = ALIGN(512); *(.vectors) *(.text) *(.eh_frame) } _text_size = . - _text_origin;
+
+ ////////////////////////////////
+ // DATA
+ ////////////////////////////////
+ . = ALIGN(8); _data_origin = .; _data_offset = . - _sbe_base_origin; .data . : { *(.data) *(.comment) *(.rodata*)} _data_size = . - _data_origin;
+
+ ////////////////////////////////
+ // TOC
+ ////////////////////////////////
+ . = ALIGN(4); _toc_origin = .; _toc_offset = . - _sbe_base_origin; .toc . : { *(.toc) } _toc_size = . - _toc_origin;
+
+ ////////////////////////////////
+ // STRING
+ ////////////////////////////////
+ . = ALIGN(1); _strings_origin = .; _strings_offset = . - _sbe_base_origin; .strings . : { *(.strings) } _strings_size = . - _strings_origin;
+
+// . = ALIGN(8);
+// _sbe_base_size = . - _sbe_base_origin;
+// _sbe_base_end = . - 0;
+
+
+ _RODATA_SECTION_BASE = .;
+
+
+ _SDA2_BASE_ = .;
+
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+ // SDA sections .sdata and .sbss must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA_BASE_ = .;
+
+ .sbss . : { *(.sbss) }
+ .sdata . : { *(.sdata) }
+
+
+ _PK_INITIAL_STACK_LIMIT = .;
+ . = . + INITIAL_STACK_SIZE;
+ _PK_INITIAL_STACK = . - 1;
+
+
+ . = ALIGN(8);
+ _sbe_base_size = . - _sbe_base_origin;
+ _sbe_base_end = . - 0;
+
+
+}
diff --git a/src/ppe/sbe/image/p9_sbe.H b/src/ppe/sbe/image/p9_sbe.H
new file mode 100644
index 0000000..b5118c1
--- /dev/null
+++ b/src/ppe/sbe/image/p9_sbe.H
@@ -0,0 +1,53 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/p9_sbe.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __P9_SBE_H
+#define __P9_SBE_H
+
+/// \file p9_sbe.H
+/// \brief A header to be included into all SBE assembler files and C++
+/// hardware procedures that interact with SBE images.
+///
+/// This header #include-s all generally useful headers required for SBE code
+/// development as well as defining other needed facilities. Note that any
+/// sub-includes must be done in an assembler-safe way.
+
+#include "sbe_common.H"
+//#include "p9_scom_addresses.H"
+//#include "p9_istep_num.H"
+
+// The #include of fapiHwpReturnCodes.H must be made here (instead of in
+// sbe_common.H) to guarantee that the P9-local copy is used.
+//#include "fapiHwpReturnCodes.H"
+
+#ifdef __ASSEMBLER__
+
+ // p9_sbe.H 'recursively' inserts itself into any hook code extracted
+ // from an assembly context that includes p9_sbe.H.
+
+ ##`#include "p9_sbe.H"
+
+#endif // __ASSEMBLER__
+
+#endif // __P9_SBE_H
diff --git a/src/ppe/sbe/image/proc_sbe_fixed.H b/src/ppe/sbe/image/proc_sbe_fixed.H
new file mode 100644
index 0000000..304b868
--- /dev/null
+++ b/src/ppe/sbe/image/proc_sbe_fixed.H
@@ -0,0 +1,189 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/proc_sbe_fixed.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file proc_sbe_fixed.H
+/// \brief Define the layout of fixed-position data in the P9 SBE reference
+/// and IPL images
+///
+/// Contains struct ProcSbeFixed which contains functions, rings and
+/// attributes whose pointers are stored in the fixed and fixed_toc section
+///
+/// This file defines the layout of the special .fixed data section of P9 SBE
+/// reference and IPL images. The .fixed section is guaranteed to appear at a
+/// fixed offset from the beginning of the image, containing data required to
+/// be manipulated when images are resident in non-volatile memories, thereby
+/// avoiding having to search the TOC. Data manipulated during in-memory image
+/// processing can always be easily located using the SBE-XIP TOC APIs. All
+/// of the data stored in .fixed can also still be referenced via the SBE-XIP
+/// TOC.
+///
+/// This header file can be #include-ed into either C or SBE assembly language
+/// source code. In C, it creates simple structures 'ProcChipAttributes',
+/// 'PervAttributes', 'CoreAttributes', 'EQAttributes' and 'EXAttributes' that
+/// contain attribute information that are sized per XML definition per entry.
+///
+/// PPE image data is always stored big-endian, so applications on little-endian
+/// hosts will need to perform the appropriate endian converison when reading or
+/// writing images via this header.
+///
+/// In assembler code, this header creates macros '.proc_sbe_fixed_proc_chip',
+/// '.proc_sbe_fixed_perv', '.proc_sbe_fixed_core', '.proc_sbe_fixed_ex',
+/// '.proc_sbe_fixed_eq', that is expanded exactly once in the file
+/// 'sbe_base_header.S', creating the actual data allocation of the data
+/// equivalent to the C structure. Assembler code references the data symbols
+/// as normal.
+///
+/// To simplify programming a 'mini-TOC' is also provided for this data in
+/// the .fixed_toc section. This section is comprised of SbeXipHashedToc
+/// structures. When a symbol is indedxed in .fixed, a blank SbeXipHashedToc
+/// stucture is added to .fixed_toc. During image normalization the array of
+/// SbeXipHashedToc is filled in as each symbol in .fixed is re-indexed into
+/// .fixed_toc.
+
+#ifndef __PROC_SBE_FIXED_H__
+#define __PROC_SBE_FIXED_H__
+
+#include "p9_sbe.H"
+#include "plat_target_parms.H"
+#include "fapi2AttributeIds.H"
+
+
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_proc_chip
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_proc_chip_attributes
+G_proc_chip_attributes:
+#else
+extern "C" {
+namespace fapi2attr {
+typedef struct ProcChipAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_proc_chip.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} ProcChipAttributes;
+} // fapi2
+} // C
+#endif
+
+///
+/// Pervasive Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_perv
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_perv_attributes
+G_perv_attributes:
+#else
+namespace fapi2attr {
+typedef struct PervAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_perv.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} PervAttributes;
+} // fapi2
+#endif
+
+///
+/// Core (EC) Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_core
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_core_attributes
+G_core_attributes:
+#else
+namespace fapi2attr {
+typedef struct CoreAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_core.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} CoreAttributes;
+} // fapi2
+#endif
+
+///
+/// EX Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_ex
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_ex_attributes
+G_ex_attributes:
+#else
+namespace fapi2attr {
+typedef struct EXAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_ex.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} EXAttributes;
+} // fapi2
+#endif
+
+///
+/// EQ Target Attributes
+#ifdef __ASSEMBLER__
+ .macro .proc_sbe_fixed_eq
+ .section .fixed, "a", @progbits
+ .balign 8
+ .global G_eq_attributes
+G_eq_attributes:
+#else
+namespace fapi2attr {
+typedef struct EQAttributes_t {
+#endif
+
+#include "proc_sbe_fixed_eq.H"
+
+#ifdef __ASSEMBLER__
+ .endm
+#else
+} EQAttributes;
+} // fapi2
+#endif
+
+
+#endif // __PROC_SBE_FIXED_H__
diff --git a/src/ppe/sbe/image/sbe_common.H b/src/ppe/sbe/image/sbe_common.H
new file mode 100644
index 0000000..a4489df
--- /dev/null
+++ b/src/ppe/sbe/image/sbe_common.H
@@ -0,0 +1,601 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/sbe_common.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SBE_COMMON_H
+#define __SBE_COMMON_H
+
+// $Id: Exp $
+
+/// \file sbe_common.H
+
+/// \brief This header contains #include-s and macro definitions common to P8
+/// and Centaur SBE code development. It is #include-ed into p8_sbe.H and
+/// cen_sbe.H which have other setup specific to each environment.
+
+
+#include "sbe_link.H"
+#include "sbe_xip_image.h"
+//#include "sbe_xip_header.H"
+
+/// Macros for generating the .fixed section
+///
+/// The CPP macros PROC_SBE_FIXED_UINT64[_VECTOR] generate equivalent code
+/// depending on whether they are being called from assembler (where they
+/// actually create the .fixed section data) or from C (where they specifiy a
+/// C-structure form of the contents of the .fixed section.
+///
+/// In assembler each invocation also creates space in the .fixed_toc section
+/// for a fixed TOC entry. Unlike the normal TOC no data is generated for
+/// .fixed_toc by the data declaration. Instead, the fixed TOC table is
+/// filled in during image normalization by normalizeToc (sbe_xip_image.c)
+/// which requires that there be one and only one fixed TOC entery allocated
+/// per TOC entry referencing the .fixed section. This means that in the
+/// current implementation it is not possible to create .fixed_toc entries
+/// for addresses or for data stored in sections other than .fixed.
+
+#ifdef __ASSEMBLER__
+
+ .macro proc_sbe_fixed_uint8, symbol:req, tnumber=1, elements=1
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .byte 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_UINT8, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int8, symbol:req, tnumber=1, elements=1
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .byte 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_INT8, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_uint16, symbol:req, tnumber=1, elements=1
+ .balign 2
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .long 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_UINT16, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int16, symbol:req, tnumber=1, elements=1
+ .balign 2
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .long 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_INT16, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_uint32, symbol:req, tnumber=1, elements=1
+ .balign 4
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .long 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_UINT32, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int32, symbol:req, tnumber=1, elements=1
+ .balign 4
+ .global \symbol
+\symbol\():
+
+ .rept ((\tnumber)*(\elements))
+ .long 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_INT32, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_uint64, symbol:req, tnumber=1, elements=1
+ .balign 8
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .quad 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_UINT64, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_int64, symbol:req, tnumber=1, elements=1
+ .balign 8
+ .global \symbol
+\symbol\():
+ .rept ((\tnumber)*(\elements))
+ .quad 0
+ .endr
+
+ .xip_toc \symbol, SBE_XIP_INT64, \symbol, (\elements)
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+ .macro proc_sbe_fixed_quadia, symbol:req, space:req, address:req
+ .global \symbol
+\symbol\():
+ .quadia (\space), (\address)
+
+ .xip_toc \symbol, SBE_XIP_UINT64, \symbol
+
+ .pushsection .fixed_toc
+ .space 8
+ .popsection
+
+ .endm
+
+
+#define PROC_SBE_FIXED_UINT8(symbol) \
+ proc_sbe_fixed_uint8 symbol
+
+#define PROC_SBE_FIXED_INT8(symbol) \
+ proc_sbe_fixed_int8 symbol
+
+#define PROC_SBE_FIXED_UINT16(symbol) \
+ proc_sbe_fixed_uint16 symbol
+
+#define PROC_SBE_FIXED_INT16(symbol) \
+ proc_sbe_fixed_int16 symbol
+
+#define PROC_SBE_FIXED_UINT32(symbol) \
+ proc_sbe_fixed_uint32 symbol
+
+#define PROC_SBE_FIXED_INT32(symbol) \
+ proc_sbe_fixed_int32 symbol
+
+#define PROC_SBE_FIXED_UINT64(symbol) \
+ proc_sbe_fixed_uint64 symbol
+
+#define PROC_SBE_FIXED_INT64(symbol) \
+ proc_sbe_fixed_int64 symbol
+
+#define PROC_SBE_FIXED_UINT8_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint8 symbol, elements
+
+#define PROC_SBE_FIXED_INT8_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int8 symbol, elements
+
+#define PROC_SBE_FIXED_UINT16_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint16 symbol, elements
+
+#define PROC_SBE_FIXED_INT16_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int16 symbol, elements
+
+#define PROC_SBE_FIXED_UINT32_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint32 symbol, elements
+
+#define PROC_SBE_FIXED_INT32_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int32 symbol, elements
+
+#define PROC_SBE_FIXED_UINT64_VECTOR(symbol, elements) \
+ proc_sbe_fixed_uint64 symbol, elements
+
+#define PROC_SBE_FIXED_INT64_VECTOR(symbol, elements) \
+ proc_sbe_fixed_int64 symbol, elements
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint8 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT8_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int8 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint16 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT16_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int16 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint32 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT32_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int32 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_uint64 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_INT64_VECTOR_2(symbol, dim1, dim2 ) \
+ proc_sbe_fixed_int64 symbol, dim1 * dim2
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_INT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, dim1 * dim2 * dim3
+
+// Non-Chip Target Attributes
+
+#define PROC_SBE_FIXED_TARGET_UINT8(symbol, tnumber) \
+ proc_sbe_fixed_uint8 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT8(symbol, tnumber) \
+ proc_sbe_fixed_int8 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT16(symbol, tnumber) \
+ proc_sbe_fixed_uint16 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT16(symbol, tnumber) \
+ proc_sbe_fixed_int16 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT32(symbol, tnumber) \
+ proc_sbe_fixed_uint32 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT32(symbol, tnumber) \
+ proc_sbe_fixed_int32 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT64(symbol, tnumber) \
+ proc_sbe_fixed_uint64 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_INT64(symbol, tnumber) \
+ proc_sbe_fixed_int64 symbol, tnumber
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint8 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int8 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint16 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int16 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint32 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int32 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_uint64 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR(symbol, tnumber, elements) \
+ proc_sbe_fixed_int64 symbol, tnumber * elements
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint8 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int8 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint16 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int16 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint32 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int32 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_uint64 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ proc_sbe_fixed_int64 symbol, tnumber * dim1 * dim2
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint8 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint16 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint32 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ proc_sbe_fixed_uint64 symbol, tnumber * dim1 * dim2 * dim3
+
+#define PROC_SBE_FIXED_QUADIA(symbol, space, address) \
+ proc_sbe_fixed_quadia symbol, (space), (address)
+
+
+#else // __ASSEMBLER__ (eg the C portion)
+
+#define PROC_SBE_FIXED_UINT8(symbol) \
+ uint8_t symbol
+
+#define PROC_SBE_FIXED_INT8(symbol) \
+ int8_t symbol
+
+#define PROC_SBE_FIXED_UINT16(symbol) \
+ uint16_t symbol
+
+#define PROC_SBE_FIXED_INT16(symbol) \
+ int16_t symbol
+
+#define PROC_SBE_FIXED_UINT32(symbol) \
+ uint32_t symbol
+
+#define PROC_SBE_FIXED_INT32(symbol) \
+ int32_t symbol
+
+#define PROC_SBE_FIXED_UINT64(symbol) \
+ uint64_t symbol
+
+#define PROC_SBE_FIXED_INT64(symbol) \
+ int64_t symbol
+
+#define PROC_SBE_FIXED_UINT8_VECTOR(symbol, elements) \
+ uint8_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT8_VECTOR(symbol, elements) \
+ int8_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT16_VECTOR(symbol, elements) \
+ uint16_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT16_VECTOR(symbol, elements) \
+ int16_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT32_VECTOR(symbol, elements) \
+ uint32_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT32_VECTOR(symbol, elements) \
+ int32_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT64_VECTOR(symbol, elements) \
+ uint64_t symbol[elements]
+
+#define PROC_SBE_FIXED_INT64_VECTOR(symbol, elements) \
+ int64_t symbol[elements]
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_2(symbol, dim1, dim2 ) \
+ uint8_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT8_VECTOR_2(symbol, dim1, dim2 ) \
+ int8_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_2(symbol, dim1, dim2 ) \
+ uint16_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT16_VECTOR_2(symbol, dim1, dim2 ) \
+ int16_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_2(symbol, dim1, dim2 ) \
+ uint32_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT32_VECTOR_2(symbol, dim1, dim2 ) \
+ int32_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_2(symbol, dim1, dim2 ) \
+ uint64_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_INT64_VECTOR_2(symbol, dim1, dim2 ) \
+ int64_t symbol[dim1][dim2]
+
+#define PROC_SBE_FIXED_UINT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint8_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT8_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int8_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_UINT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint16_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT16_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int16_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_UINT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint32_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT32_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int32_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_UINT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ uint64_t symbol[dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_INT64_VECTOR_3(symbol, dim1, dim2, dim3 ) \
+ int64_t symbol[dim1][dim2][dim3]
+
+// Non-Chip Target Attributes
+
+#define PROC_SBE_FIXED_TARGET_UINT8(symbol, tnumber) \
+ uint8_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT8(symbol, tnumber) \
+ int8_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT16(symbol, tnumber) \
+ uint16_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT16(symbol, tnumber) \
+ int16_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT32(symbol, tnumber) \
+ uint32_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT32(symbol, tnumber) \
+ int32_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT64(symbol, tnumber) \
+ uint64_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_INT64(symbol, tnumber) \
+ int64_t symbol[tnumber]
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR(symbol, tnumber, elements) \
+ uint8_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR(symbol, tnumber, elements) \
+ int8_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR(symbol, tnumber, elements) \
+ uint16_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR(symbol, tnumber, elements) \
+ int16_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR(symbol, tnumber, elements) \
+ uint32_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR(symbol, tnumber, elements) \
+ int32_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR(symbol, tnumber, elements) \
+ uint64_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR(symbol, tnumber, elements) \
+ int64_t symbol[tnumber][elements]
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint8_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int8_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint16_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int16_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint32_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int32_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ uint64_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_2(symbol, tnumber, dim1, dim2 ) \
+ int64_t symbol[tnumber][dim1][dim2]
+
+#define PROC_SBE_FIXED_TARGET_UINT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint8_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT8_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int8_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_UINT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint16_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT16_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int16_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_UINT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint32_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT32_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int32_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_UINT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ uint64_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_TARGET_INT64_VECTOR_3(symbol, tnumber, dim1, dim2, dim3 ) \
+ int64_t symbol[tnumber][dim1][dim2][dim3]
+
+#define PROC_SBE_FIXED_QUADIA(symbol, space, address) uint64_t symbol
+
+#endif // __ASSEMBLER__
+
+#endif // __SBE_COMMON_H
diff --git a/src/ppe/sbe/image/sbe_link.H b/src/ppe/sbe/image/sbe_link.H
new file mode 100644
index 0000000..5635f39
--- /dev/null
+++ b/src/ppe/sbe/image/sbe_link.H
@@ -0,0 +1,77 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/sbe_link.H $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SBE_LINK_H
+#define __SBE_LINK_H
+
+// $Id: Exp $
+
+/// \file sbe_link.H
+/// \brief Constants required for linking SBE code images
+///
+/// This header contains those cpp manifest constants required for processing
+/// the linker scripts used to generate SBE code images. They may also be
+/// useful for PPE assembler programming so they are included in sbe.H as
+/// well.
+///
+/// The link address of OTPROM code as a byte-address
+///
+/// The OTPROM can be addressed both as an I2C slave and as a direct PIB
+/// slave. The I2C slave is at PIB local address 0x0 and the PIB memory
+/// interface is at local address 0x8000. SBE/IPL uses the PIB addressing
+/// mode, so the OTPROM image is linked at 0x40000 (the byte-address
+/// equivalent of 0x8000).
+#define OTPROM_ORIGIN 0x40000
+
+/// The amount of memory contained in each OTPROM macro
+#define OTPROM_BLOCK_SIZE 4096
+
+/// The amount of memory reserved for OTPROM code
+///
+/// This amount is exclusive of physical OTPROM memory reserved for compressed
+/// scan ring images.
+#define OTPROM_CODE_SIZE (1 * OTPROM_BLOCK_SIZE)
+
+/// The link address of the P9 SBE Base image
+#define SBE_BASE_ORIGIN 0xFFFF0000
+
+/// The physical address offset where SBE-SEEPROM code is loaded
+///
+/// This address *must* be a constant known to the OTPROM code.
+#define SBE_SEEPROM_LOAD_ADDRESS 0x2000
+
+/// The offset (in bytes) of the .fixed section in P9 SBE-XIP images
+#define SBE_XIP_FIXED_OFFSET 512
+
+/// The link address of the PIBMEM image
+#define PIBMEM_ORIGIN 0
+
+/// The amount of space available in the PIBMEM, in bytes (3KB)
+#define PIBMEM_SIZE (64 * 1024)
+
+/// The offset (in bytes) of the .fixed section in P9 SBE-XIP images
+#define SBE_XIP_FIXED_OFFSET 512
+
+#endif // __SBE_LINK_H
+
diff --git a/src/ppe/sbe/image/sbe_xip_image.h b/src/ppe/sbe/image/sbe_xip_image.h
new file mode 100644
index 0000000..9340fcb
--- /dev/null
+++ b/src/ppe/sbe/image/sbe_xip_image.h
@@ -0,0 +1,1786 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/image/sbe_xip_image.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sbe_xip_image.h
+/// \brief definition of structs in sections
+///
+/// Contains struct ProcSbeFixed which contains functions, rings and
+/// attributes whose pointers are stored in the fixed and fixed_toc section
+/// Everything related to creating and manipulating SBE-XIP binary images
+
+#ifndef __SBE_XIP_IMAGE_H
+#define __SBE_XIP_IMAGE_H
+
+#include "fapi_sbe_common.H"
+
+/// Current version (fields, layout, sections) of the SBE_XIP header
+///
+/// If any changes are made to this file or to sbe_xip_header.H, please update
+/// the header version and follow-up on all of the error messages.
+
+#define SBE_XIP_HEADER_VERSION 8
+
+/// \defgroup sbe_xip_magic_numbers SBE-XIP magic numbers
+///
+/// An SBE-XIP magic number is a 64-bit constant. The 4 high-order bytes
+/// contain the ASCII characters "XIP " and identify the image as an SBE-XIP
+/// image, while the 4 low-order bytes identify the type of the image.
+///
+/// @{
+
+#define SBE_XIP_MAGIC 0x58495020 // "XIP "
+#define SBE_BASE_MAGIC ULL(0x5849502042415345) // "XIP BASE"
+#define SBE_SEEPROM_MAGIC ULL(0x584950205345504d) // "XIP SEPM"
+#define SBE_CENTAUR_MAGIC ULL(0x58495020434e5452) // "XIP CNTR"
+
+/// @}
+
+
+/// \defgroup sbe_xip_sections SBE-XIP Image Section Indexes
+///
+/// These constants define the order that the SbeXipSection structures appear
+/// in the header, which is not necessarily the order the sections appear in
+/// the binary image. Given that SBE-XIP image contents are tightly
+/// controlled, we use this simple indexing scheme for the allowed sections
+/// rather than a more general approach, e.g., allowing arbitrary sections
+/// identified by their names.
+///
+/// @{
+
+// -*- DO NOT REORDER OR EDIT THIS SET OF CONSTANTS WITHOUT ALSO EDITING -*-
+// -*- THE ASSEMBLER LAYOUT IN sbe_xip_header.H. -*-
+
+#define SBE_XIP_SECTION_HEADER 0
+#define SBE_XIP_SECTION_FIXED 1
+#define SBE_XIP_SECTION_FIXED_TOC 2
+#define SBE_XIP_SECTION_IPL_TEXT 3
+#define SBE_XIP_SECTION_IPL_DATA 4
+#define SBE_XIP_SECTION_TEXT 5
+#define SBE_XIP_SECTION_DATA 6
+#define SBE_XIP_SECTION_TOC 7
+#define SBE_XIP_SECTION_STRINGS 8
+#define SBE_XIP_SECTION_HALT 9
+#define SBE_XIP_SECTION_PIBMEM0 10
+#define SBE_XIP_SECTION_DCRINGS 11
+#define SBE_XIP_SECTION_RINGS 12
+#define SBE_XIP_SECTION_SLW 13
+#define SBE_XIP_SECTION_FIT 14
+#define SBE_XIP_SECTION_FFDC 15
+
+#define SBE_XIP_SECTIONS 16
+
+/// @}
+
+
+/// \defgroup sbe_xip_validate() ignore masks.
+///
+/// These defines, when matched in sbe_xip_validate(), cause the validation
+/// to skip the check of the corresponding property. The purpose is to more
+/// effectively debug images that may be damaged and which have excess info
+/// before or after the image. The latter will be the case when dumping the
+/// image as a memory block without knowing where the image starts and ends.
+///
+/// @{
+
+#define SBE_XIP_IGNORE_FILE_SIZE (uint32_t)0x00000001
+#define SBE_XIP_IGNORE_ALL (uint32_t)0x80000000
+
+/// @}
+
+
+#ifndef __ASSEMBLER__
+
+/// Applications can expand this macro to create an array of section names.
+#define SBE_XIP_SECTION_NAMES(var) \
+ const char* var[] = { \
+ ".header", \
+ ".fixed", \
+ ".fixed_toc", \
+ ".ipl_text", \
+ ".ipl_data", \
+ ".text", \
+ ".data", \
+ ".toc", \
+ ".strings", \
+ ".halt", \
+ ".pibmem0", \
+ ".dcrings", \
+ ".rings", \
+ ".slw", \
+ ".fit", \
+ ".ffdc", \
+ }
+
+/// Applications can use this macro to safely index the array of section
+/// names.
+#define SBE_XIP_SECTION_NAME(var, n) \
+ ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ? \
+ "Bug : Invalid SBE-XIP section name" : var[n])
+
+
+#endif /* __ASSEMBLER__ */
+
+
+/// Maximum section alignment for SBE-XIP sections
+#define SBE_XIP_MAX_SECTION_ALIGNMENT 128
+
+/// \defgroup sbe_xip_toc_types SBE-XIP Table of Contents data types
+///
+/// These are the data types stored in the \a iv_type field of the SbeXipToc
+/// objects. These must be defined as manifest constants because they are
+/// required to be recognized as manifest constants in C (as opposed to C++)
+/// code.
+///
+/// NB: The 0x0 code is purposefully left undefined to catch bugs.
+///
+/// @{
+
+/// Data is a single unsigned byte
+#define SBE_XIP_UINT8 0x01
+
+/// Data is a 32-bit unsigned integer
+#define SBE_XIP_UINT32 0x02
+
+/// Data is a 64-bit unsigned integer
+#define SBE_XIP_UINT64 0x03
+
+/// Data is a 0-byte terminated ASCII string
+#define SBE_XIP_STRING 0x04
+
+/// Data is an address
+#define SBE_XIP_ADDRESS 0x05
+
+/// The maximum type number
+#define SBE_XIP_MAX_TYPE_INDEX 0x05
+
+/// Applications can expand this macro to get access to string forms of the
+/// SBE-XIP data types if desired.
+#define SBE_XIP_TYPE_STRINGS(var) \
+ const char* var[] = { \
+ "Illegal 0 Code", \
+ "SBE_XIP_UINT8", \
+ "SBE_XIP_UINT32", \
+ "SBE_XIP_UINT64", \
+ "SBE_XIP_STRING", \
+ "SBE_XIP_ADDRESS", \
+ }
+
+/// Applications can expand this macro to get access to abbreviated string
+/// forms of the SBE-XIP data types if desired.
+#define SBE_XIP_TYPE_ABBREVS(var) \
+ const char* var[] = { \
+ "Illegal 0 Code", \
+ "u8 ", \
+ "u32", \
+ "u64", \
+ "str", \
+ "adr", \
+ }
+
+/// Applications can use this macro to safely index either array of SBE-XIP
+/// type strings.
+#define SBE_XIP_TYPE_STRING(var, n) \
+ (((n) > (sizeof(var) / sizeof(char*))) ? \
+ "Invalid SBE-XIP type specification" : var[n])
+
+/// @}
+
+
+/// Final alignment constraint for SBE-XIP images.
+///
+/// PORE images are required to be multiples of 8 bytes in length, to
+/// gaurantee that the PoreVe will be able to complete any 8-byte load/store.
+#define SBE_XIP_FINAL_ALIGNMENT 8
+
+
+////////////////////////////////////////////////////////////////////////////
+// C Definitions
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+} /* So __cplusplus doesn't mess w/auto-indent */
+#endif
+
+/// SBE-XIP Section information
+///
+/// This structure defines the data layout of section table entries in the
+/// SBE-XIP image header.
+
+// -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO -*-
+// -*- EDITING THE ASSEMBLER LAYOUT IN sbe_xip_header.H -*-
+
+typedef struct {
+
+ /// The offset (in bytes) of the section from the beginning of the image
+ ///
+ /// In normalized images the section offset will always be 0 if the
+ /// section size is also 0.
+ uint32_t iv_offset;
+
+ /// The size of the section in bytes, exclusive of alignment padding
+ ///
+ /// This is the size of the program-significant data in the section,
+ /// exclusive of any alignment padding or reserved or extra space. The
+ /// alignment padding (reserved space) is not represented explicitly, but
+ /// is only implied by the offset of any subsequent non-empty section, or
+ /// in the case of the final section in the image, the image size.
+ ///
+ /// Regardless of the \a iv_offset, if the \a iv_size of a section is 0 it
+ /// should be considered "not present" in the image. In normalized images
+ /// the section offset will always be 0 if the section size is also 0.
+ uint32_t iv_size;
+
+ /// The required initial alignment for the section offset
+ ///
+ /// The PORE and the applications using SBE-XIP images have strict
+ /// alignment/padding requirements. The PORE does not handle any type of
+ /// unaligned instruction or data fetches. Some sections and subsections
+ /// must also be POWER cache-line aligned. The \a iv_alignment applies to
+ /// the first byte of the section. PORE images are also required to be
+ /// multiples of 8 bytes in length, to gaurantee that the PoreVe will be
+ /// able to complete any 8-byte load/store. These constraints are checked
+ /// by sbe_xip_validate() and enforced by sbe_xip_append(). The alignment
+ /// constraints may force a section to be padded, which may create "holes"
+ /// in the image as explained in the comments for the \a iv_size field.
+ ///
+ /// Note that alignment constraints are always checked relative to the
+ /// first byte of the image for in-memory images, not relative to the host
+ /// address. Alignment specifications are required to be a power-of-2.
+ uint8_t iv_alignment;
+
+ /// Reserved structure alignment padding; Pad to 12 bytes
+ uint8_t iv_reserved8[3];
+
+} SbeXipSection;
+
+/// The SbeXipSection structure is created by assembler code and is expected
+/// to have the same size in C code. This constraint is checked in
+/// sbe_xip_validate().
+#define SIZE_OF_SBE_XIP_SECTION 12
+
+
+/// SBE-XIP binary image header
+///
+/// This header occupies the initial bytes of an SBE-XIP binary image.
+/// The header contents are documented here, however the structure is actually
+/// defined in the file sbe_xip_header.S, and these two definitions must be
+/// kept consistent.
+///
+/// The header is a fixed-format representation of the most critical
+/// information about the image. The large majority of information about the
+/// image and its contents are available through the searchable table of
+/// contents. PORE code itself normally accesses the data directly through
+/// global symbols.
+///
+/// The header only contains information 1) required by OTPROM code (e.g., the
+/// entry point); 2) required by search and updating APIs (e.g., the
+/// locations and sizes of all of the sections.); a few pieces of critical
+/// meta-data (e.g., information about the image build process).
+///
+/// Any entries that are accessed by PORE code are required to be 64 bits, and
+/// will appear at the beginning of the header.
+///
+/// The header also contains bytewise offsets and sizes of all of the sections
+/// that are assembled to complete the image. The offsets are relative to the
+/// start of the image (where the header is loaded). The sizes include any
+/// padding inserted by the link editor to guarantee section alignment.
+///
+/// Every field of the header is also accesssible through the searchable table
+/// of contents as documented in sbe_xip_header.S.
+
+// -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO -*-
+// -*- EDITING THE ASSEMBLER LAYOUT IN sbe_xip_header.S, AND WITHOUT -*-
+// -*- UPDATING THE sbe_xip_translate_header() API IN sbe_xip_image.c. -*-
+
+typedef struct {
+
+ //////////////////////////////////////////////////////////////////////
+ // Identification - 8-byte aligned; 8 entries
+ //////////////////////////////////////////////////////////////////////
+
+ /// Contains SBE_XIP_MAGIC to identify an SBE-XIP image
+ uint64_t iv_magic;
+
+ /// The offset of the SBE-XIP entry point from the start of the image
+ uint64_t iv_entryOffset;
+
+ /// The base address used to link the image, as a full relocatable PORE
+ /// address
+ uint64_t iv_linkAddress;
+
+ /// Reserved for future expansion
+ uint64_t iv_reserved64[5];
+
+ //////////////////////////////////////////////////////////////////////
+ // Section Table - 4-byte aligned; 16 entries
+ //////////////////////////////////////////////////////////////////////
+
+ SbeXipSection iv_section[SBE_XIP_SECTIONS];
+
+ //////////////////////////////////////////////////////////////////////
+ // Other information - 4-byte aligned; 8 entries
+ //////////////////////////////////////////////////////////////////////
+
+ /// The size of the image (including padding) in bytes
+ uint32_t iv_imageSize;
+
+ /// Build date generated by `date +%Y%m%d`, e.g., 20110630
+ uint32_t iv_buildDate;
+
+ /// Build time generated by `date +%H%M`, e.g., 0756
+ uint32_t iv_buildTime;
+
+ /// Reserved for future expansion
+ uint32_t iv_reserved32[5];
+
+ //////////////////////////////////////////////////////////////////////
+ // Other Information - 1-byte aligned; 8 entries
+ //////////////////////////////////////////////////////////////////////
+
+ /// Header format version number
+ uint8_t iv_headerVersion;
+
+ /// Indicates whether the image has been normalized (0/1)
+ uint8_t iv_normalized;
+
+ /// Indicates whether the TOC has been sorted to speed searching (0/1)
+ uint8_t iv_tocSorted;
+
+ /// Reserved for future expansion
+ uint8_t iv_reserved8[5];
+
+ //////////////////////////////////////////////////////////////////////
+ // Strings; 64 characters allocated
+ //////////////////////////////////////////////////////////////////////
+
+ /// Build user, generated by `id -un`
+ char iv_buildUser[16];
+
+ /// Build host, generated by `hostname`
+ char iv_buildHost[24];
+
+ /// Reserved for future expansion
+ char iv_reservedChar[24];
+
+} SbeXipHeader;
+
+
+
+/// A C-structure form of the SBE-XIP Table of Contents (TOC) entries
+///
+/// The .toc section consists entirely of an array of these structures.
+/// TOC entries are never accessed by PORE code.
+///
+/// These structures store indexing information for global data required to be
+/// manipulated by external tools. The actual data is usually allocated in a
+/// data section and manipulated by the SBE code using global or local symbol
+/// names. Each TOC entry contains a pointer to a keyword string naming the
+/// data, the address of the data (or the data itself), the data type,
+/// meta-information about the data, and for vectors the vector size.
+
+// -*- DO NOT REORDER OR EDIT THIS STRUCTURE DEFINITION WITHOUT ALSO -*-
+// -*- EDITING THE ASSEMBLER MACROS (BELOW) THAT CREATE THE TABLE OF -*-
+// -*- CONTENTS ENTRIES. -*-
+
+typedef struct {
+
+ /// A pointer to a 0-byte terminated ASCII string identifying the data.
+ ///
+ /// When allocated by the .xip_toc macro this is a pointer to the string
+ /// form of the symbol name for the global or local symbol associated with
+ /// the data which is allocated in the .strings section. This pointer is
+ /// not aligned.
+ ///
+ /// When the image is normalized this pointer is replaced by the offset of
+ /// the string in the .strings section.
+ uint32_t iv_id;
+
+ /// A 32-bit pointer locating the data
+ ///
+ /// This field is initially populated by the link editor. For scalar,
+ /// vector and string types this is the final relocated address of the
+ /// first byte of the data. For address types, this is the relocated
+ /// address. When the image is normalized, these addresses are converted
+ /// into the equivalent offsets from the beginning of the section holding
+ /// the data.
+ uint32_t iv_data;
+
+ /// The type of the data; See \ref sbe_xip_toc_types.
+ uint8_t iv_type;
+
+ /// The section containing the data; See \ref sbe_xip_sections.
+ uint8_t iv_section;
+
+ /// The number of elements for vector types, otherwise 1 for scalar types
+ /// and addresses.
+ ///
+ /// Vectors are naturally limited in size, e.g. to the number of cores,
+ /// chips in a node, DD-levels etc. If \a iv_elements is 0 then no bounds
+ /// checking is done on get/set accesses of the data.
+ uint8_t iv_elements;
+
+ /// Structure alignment padding; Pad to 12 bytes
+ uint8_t iv_pad;
+
+} SbeXipToc;
+
+/// The SbeXipToc structure is created by assembler code and is expected
+/// to have the same size in C code. This constraint is checked in
+/// sbe_xip_validate().
+#define SIZE_OF_SBE_XIP_TOC 12
+
+
+/// A C-structure form of hashed SBE-XIP Table of Contents (TOC) entries
+///
+/// This structure was introduced in order to allow a small TOC for the .fixed
+/// section to support minimum-sized SEEPROM images in which the global TOC
+/// and all strings have been stripped out. In this structure the index
+/// string has been replaced by a 32-bit hash, and there is no longer a record
+/// of the original data name other then the hash. The section of the data is
+/// assumed to be .fixed, with a maximum 16-bit offset.
+///
+/// These structures are created when entries are made in the .fixed section.
+/// They are created empty, then filled in during image normalization.
+///
+/// This structure allows the sbe_xip_get*() and sbe_xip_set*() APIs to work
+/// even on highly-stripped SEEPROM images.
+
+typedef struct {
+
+ /// A 32-bit hash (FNV-1a) of the Id string.
+ uint32_t iv_hash;
+
+ /// The offset in bytes from the start of the (implied) section of the data
+ uint16_t iv_offset;
+
+ /// The type of the data; See \ref sbe_xip_toc_types.
+ uint8_t iv_type;
+
+ /// The number of elements for vector types, otherwise 1 for scalar types
+ /// and addresses.
+ ///
+ /// Vectors are naturally limited in size, e.g. to the number of cores,
+ /// chips in a node, DD-levels etc. If \a iv_elements is 0 then no bounds
+ /// checking is done on get/set accesses of the data.
+ uint8_t iv_elements;
+
+} SbeXipHashedToc;
+
+/// The SbeXipHashedToc structure is created by assembler code and is expected
+/// to have the same size in C code. This constraint is checked in
+/// sbe_xip_validate().
+#define SIZE_OF_SBE_XIP_HASHED_TOC 8
+
+
+/// A decoded TOC entry for use by applications
+///
+/// This structure is a decoded form of a normalized TOC entry, filled in by
+/// the sbe_xip_decode_toc() and sbe_xip_find() APIs. This structure is
+/// always returned with data elements in host-endian format.
+///
+/// In the event that the TOC has been removed from the image, this structure
+/// will also be returned by sbe_xip_find() with information populated from
+/// the .fixed_toc section if possible. In this case the field \a iv_partial
+/// will be set and only the fields \a iv_address, \a iv_imageData, \a iv_type
+/// and \a iv_elements will be populated (all other fields will be set to 0).
+///
+/// \note Only special-purpose applications will ever need to use this
+/// structure given that the higher-level APIs sbe_xip_get_*() and
+/// sbe_xip_set_*() are provided and should be used if possible, especially
+/// given that the information may be truncated as described above.
+
+typedef struct {
+
+ /// A pointer to the associated TOC entry as it exists in the image
+ ///
+ /// If \a iv_partial is set this field is returned as 0.
+ SbeXipToc* iv_toc;
+
+ /// The full relocatable PORE address
+ ///
+ /// All relocatable addresses are computed from the \a iv_linkAddress
+ /// stored in the header. For scalar and string data, this is the
+ /// relocatable address of the data. For address-only entries, this is
+ /// the indexed address itself.
+ uint64_t iv_address;
+
+ /// A host pointer to the first byte of text or data within the image
+ ///
+ /// For scalar or string types this is a host pointer to the first byte of
+ /// the data. For code pointers (addresses) this is host pointer to the
+ /// first byte of code. Note that any use of this field requires the
+ /// caller to handle conversion of the data to host endian-ness if
+ /// required. Only 8-bit and string data can be used directly on all
+ /// hosts.
+ void* iv_imageData;
+
+ /// The item name
+ ///
+ /// This is a pointer in host memory to a string that names the TOC entry
+ /// requested. This field is set to a pointer to the ID string of the TOC
+ /// entry inside the image. If \a iv_partial is set this field is returned
+ /// as 0.
+ char* iv_id;
+
+ /// The data type, one of the SBE_XIP_* constants
+ uint8_t iv_type;
+
+ /// The number of elements in a vector
+ ///
+ /// This field is set from the TOC entry when the TOC entry is
+ /// decoded. This value is stored as 1 for scalar declarations, and may be
+ /// set to 0 for vectors with large or undeclared sizes. Otherwise it is
+ /// used to bounds check indexed accesses.
+ uint8_t iv_elements;
+
+ /// Is this record only partially populated?
+ ///
+ /// This field is set to 0 normally, and only set to 1 if a lookup is made
+ /// in an image that only has the fixed TOC and the requested Id hashes to
+ /// the fixed TOC.
+ uint8_t iv_partial;
+
+} SbeXipItem;
+
+
+/// Prototype entry in the .halt section
+///
+/// The .halt section is generated by the 'reqhalt' macro. This structure
+/// associates the address of each halt with the string form of the FAPI
+/// return code associated with the halt. The string form is used because the
+/// FAPI error return code is not constant. The .halt section is 4-byte
+/// aligned, and each address/string entry is always padded to a multiple of 4
+/// bytes.
+///
+/// In the .halt section the \a iv_string may be any length, thus the size of
+/// each actual record is variable (although guaranteed to always be a
+/// multiple of 4 bytes). Although the C compiler might natuarlly align
+/// instances of this structure on a 64-bit boundary, the APIs that allow
+/// access to the .halt section assume that the underlying machine can do
+/// non-aligned loads from a pointer to this structure.
+
+typedef struct {
+
+ /// The 64-bit relocatable address of the halt
+ ///
+ /// This is the address found in the PC (Status Register bits 16:63) when
+ /// the PORE halts. The full 64-bit form is used rather than the simple
+ /// 32-bit offset to support merging SEEPROM and PIBMEM .halt sections in
+ /// the SEEPROM IPL images.
+ uint64_t iv_address;
+
+ /// A C-prototype for a variable-length 0-terminated ASCII string
+ ///
+ /// This is a prototype only to simplify C programming. The actual string
+ /// may be any length.
+ char iv_string[4];
+
+} SbeXipHalt;
+
+
+/// Validate an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_size The putative size of the image
+///
+/// \param[in] i_maskIgnores Array of ignore bits representing which properties
+/// should not be checked for in sbe_xip_validate2().
+///
+/// This API should be called first by all applications that manipulate
+/// SBE-XIP images in host memory. The magic number is validated, and
+/// the image is checked for consistency of the section table and table of
+/// contents. The \a iv_imageSize field of the header must also match the
+/// provided \a i_size parameter. Validation does not modify the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_validate(void* i_image, const uint32_t i_size);
+
+int
+sbe_xip_validate2(void* i_image, const uint32_t i_size, const uint32_t i_maskIgnores);
+
+
+/// Normalize the SBE-XIP image
+///
+/// \param[in] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// SBE-XIP images must be normalized before any other APIs are allowed to
+/// operate on the image. Since normalization modifies the image, an explicit
+/// call to normalize the image is required. Briefly, normalization modifies
+/// the TOC entries created by the final link to simplify search, updates,
+/// modification and relocation of the image. Normalization is explained in
+/// the written documentation of the SBE-XIP binary format. Normalization does
+/// not modify the size of the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_normalize(void* io_image);
+
+
+/// Return the size of an SBE-XIP image from the image header
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[out] o_size A pointer to a variable returned as the size of the
+/// image in bytes, as recorded in the image header.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_image_size(void* i_image, uint32_t* o_size);
+
+
+/// Locate a section table entry and translate into host format
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_sectionId Identifies the section to be queried. See \ref
+/// sbe_xip_sections.
+///
+/// \param[out] o_hostSection Updated to contain the section table entry
+/// translated to host byte order.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_section(const void* i_image,
+ const int i_sectionId,
+ SbeXipSection* o_hostSection);
+
+
+/// Endian translation of an SbeXipHeader object
+///
+/// \param[out] o_hostHeader The destination object.
+///
+/// \param[in] i_imageHeader The source object.
+///
+/// Translation of a SbeXipHeader includes translation of all data members
+/// including traslation of the embedded section table. This translation
+/// works even if \a o_src == \a o_dest, i.e., in the destructive case.
+void
+sbe_xip_translate_header(SbeXipHeader* o_hostHeader,
+ const SbeXipHeader* i_imageHeader);
+
+
+/// Get scalar data from an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// requested.
+///
+/// \param[out] o_data A pointer to an 8-byte integer to receive the scalar
+/// data. Assuming the item is located this variable is assigned by the call.
+/// In the event of an error the final state of \a o_data is not specified.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// \a i_id, assigning \a o_data from the image if the item is found and is a
+/// scalar value. Scalar values include 8- 32- and 64-bit integers and PORE
+/// addresses. Image data smaller than 64 bits are extracted as unsigned
+/// types, and it is the caller's responsibility to cast or convert the
+/// returned data as appropriate.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_scalar(void *i_image, const char* i_id, uint64_t* o_data);
+
+
+/// Get an integral element from a vector held in an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// requested.
+///
+/// \param[in] i_index The index of the vector element to return.
+///
+/// \param[out] o_data A pointer to an 8-byte integer to receive the
+/// data. Assuming the item is located this variable is assigned by the call.
+/// In the event of an error the final state of \a o_data is not specified.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the \a i_index
+/// element of the item named \a i_id, assigning \a o_data from the image if
+/// the item is found, is a vector of an integral type, and the \a i_index is
+/// in bounds. Vector elements smaller than 64 bits are extracted as unsigned
+/// types, and it is the caller's responsibility to cast or convert the
+/// returned data as appropriate.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_element(void *i_image,
+ const char* i_id,
+ const uint32_t i_index,
+ uint64_t* o_data);
+
+
+/// Get string data from an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// requested.
+///
+/// \param[out] o_data A pointer to a character pointer. Assuming the
+/// item is located this variable is assigned by the call to point to the
+/// string as it exists in the \a i_image. In the event of an error the final
+/// state of \a o_data is not specified.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// \a i_id, assigning \a o_data if the item is found and is a string. It is
+/// the caller's responsibility to copy the string from the \a i_image memory
+/// space if necessary.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_get_string(void *i_image, const char* i_id, char** o_data);
+
+
+/// Directly read 64-bit data from the image based on a PORE address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_poreAddress A relocatable PORE address contained in the
+/// image, presumably of an 8-byte data area. The \a i_poreAddress is
+/// required to be 8-byte aligned, otherwise the SBE_XIP_ALIGNMENT_ERROR code
+/// is returned.
+///
+/// \param[out] o_data The 64 bit data in host format that was found at \a
+/// i_poreAddress.
+///
+/// This API is provided for applications that need to manipulate SBE-XIP
+/// images in terms of their relocatable PORE addresses. The API checks that
+/// the \a i_poreAddress is properly aligned and contained in the image, then
+/// reads the contents of \a i_poreAddress into \a o_data, performing
+/// image-to-host endianess conversion if required.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_read_uint64(const void *i_image,
+ const uint64_t i_poreAddress,
+ uint64_t* o_data);
+
+
+/// Set scalar data in an SBE-XIP image
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory.
+/// The image is assumed to be consistent with the information contained in
+/// the header regarding the presence of and sizes of all sections. The image
+/// is also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// to be modified.
+///
+/// \param[in] i_data The new scalar data.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// by \a i_id, updating the image from \a i_data if the item is found, has
+/// a scalar type and can be modified. For this API the scalar types include
+/// 8- 32- and 64-bit integers. Although PORE addresses are considered a
+/// scalar type for sbe_xip_get_scalar(), PORE addresses can not be modified
+/// by this API. The caller is responsible for ensuring that the \a i_data is
+/// of the correct size for the underlying data element in the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_set_scalar(void* io_image, const char* i_id, const uint64_t i_data);
+
+
+/// Set an integral element in a vector held in an SBE-XIP image
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// to be updated.
+///
+/// \param[in] i_index The index of the vector element to update.
+///
+/// \param[out] i_data The new vector element.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the \a i_index
+/// element of the item named \a i_id, update the image from \a i_data if the
+/// item is found, is a vector of an integral type, and the \a i_index is in
+/// bounds. The caller is responsible for ensuring that the \a i_data is of
+/// the correct size for the underlying data element in the image.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_set_element(void *i_image,
+ const char* i_id,
+ const uint32_t i_index,
+ const uint64_t i_data);
+
+
+/// Set string data in an SBE-XIP image
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A pointer to a 0-terminated ASCII string naming the item
+/// to be modified.
+///
+/// \param[in] i_data A pointer to the new string data.
+///
+/// This API searches the SBE-XIP Table of Contents (TOC) for the item named
+/// \a i_id, which must be a string variable. If found, then the string data
+/// in the image is overwritten with \a i_data. Strings are held 0-terminated
+/// in the image, and the SBE-XIP format does not maintain a record of the
+/// amount of memory allocated for an individual string. If a string is
+/// overwritten by a shorter string then the 'excess' storage is effectively
+/// lost. If the length of \a i_data is longer that the current strlen() of
+/// the string data then \a i_data is silently truncated to the first
+/// strlen(old_string) characters.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_set_string(void *io_image, const char* i_id, const char* i_data);
+
+
+/// Directly write 64-bit data into the image based on a PORE address
+///
+/// \param[in, out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_poreAddress A relocatable PORE address contained in the
+/// image, presumably of an 8-byte data area. The \a i_poreAddress is
+/// required to be 8-byte aligned, otherwise the SBE_XIP_ALIGNMENT_ERROR code
+/// is returned.
+///
+/// \param[in] i_data The 64 bit data in host format to be written to \a
+/// i_poreAddress.
+///
+/// This API is provided for applications that need to manipulate SBE-XIP
+/// images in terms of their relocatable PORE addresses. The API checks that
+/// the \a i_poreAddress is properly aligned and contained in the image, then
+/// updates the contents of \a i_poreAddress with \a i_data, performing
+/// host-to-image endianess conversion if required.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_write_uint64(void *io_image,
+ const uint64_t i_poreAddress,
+ const uint64_t i_data);
+
+
+/// Map over an SBE-XIP image Table of Contents
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_fn A pointer to a function to call on each TOC entry. The
+/// function has the prototype:
+///
+/// \code
+/// int (*i_fn)(void* io_image,
+/// const SbeXipItem* i_item,
+/// void* io_arg)
+/// \endcode
+///
+/// \param[in,out] io_arg The private argument of \a i_fn.
+///
+/// This API iterates over each entry of the TOC, calling \a i_fn with
+/// pointers to the image, an SbeXipItem* pointer, and a private argument. The
+/// iteration terminates either when all TOC entries have been mapped, or \a
+/// i_fn returns a non-zero code.
+///
+/// \retval 0 Success; All TOC entries were mapped, including the case that
+/// the .toc section is empty.
+///
+/// \retval non-0 May be either one of the SBE-XIP image error codes (see \ref
+/// sbe_xip_image_errors), or a non-zero code from \a i_fn. Since the standard
+/// SBE_XIP return codes are > 0, application-defined codes should be < 0.
+int
+sbe_xip_map_toc(void* io_image,
+ int (*i_fn)(void* io_image,
+ const SbeXipItem* i_item,
+ void* io_arg),
+ void* io_arg);
+
+
+/// Find an SBE-XIP TOC entry
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_id A 0-byte terminated ASCII string naming the item to be
+/// searched for.
+///
+/// \param[out] o_item If the search is successful, then the object
+/// pointed to by \a o_item is filled in with the decoded form of the
+/// TOC entry for \a i_id. If the API returns a non-0 error code then the
+/// final state of the storage at \a o_item is undefined. This parameter may
+/// be suppied as 0, in which case sbe_xip_find() serves as a simple predicate
+/// on whether an item is indexded in the TOC.
+///
+/// This API searches the TOC of a normalized SBE-XIP image for the item named
+/// \a i_id, and if found, fills in the structure pointed to by \a
+/// o_item with a decoded form of the TOC entry. If the item is not found,
+/// the following two return codes may be considered non-error codes:
+///
+/// - SBE_XIP_ITEM_NOT_FOUND : No TOC record for \a i_id was found.
+///
+/// - SBE_XIP_DATA_NOT_PRESENT : The item appears in the TOC, however the
+/// section containing the data is no longer present in the image.
+///
+/// If the TOC section has been deleted from the image, then the search is
+/// restricted to the abbreviated TOC that indexes data in the .fixed section.
+/// In this case the \a o_item structure is marked with a 1 in the \a
+/// iv_partial field since the abbreviated TOC can not populate the entire
+/// SbeXipItem structure.
+///
+/// \note This API should typically only be used as a predicate, not as a way
+/// to access the image via the returned SbeXipItem structure. To obtain data
+/// from the image or update data in the image use the sbe_xip_get_*() and
+/// sbe_xip_set_*() APIs respectively.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_find(void* i_image,
+ const char* i_id,
+ SbeXipItem* o_item);
+
+
+/// Map over an SBE-XIP image .halt section
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_fn A pointer to a function to call on each entry in .halt.
+/// The function has the prototype:
+///
+/// \code
+/// int (*i_fn)(void* io_image,
+/// const uint64_t i_poreAddress,
+/// const char* i_rcString,
+/// void* io_arg)
+///
+/// \endcode
+///
+/// \param[in,out] io_arg The private argument of \a i_fn.
+///
+/// This API iterates over each entry of the .halt section, calling \a i_fn
+/// with each HALT address, the string form of the return code associated with
+/// that HALT address, and a private argument. The iteration terminates either
+/// when all .halt entries have been mapped, or \a i_fn returns a non-zero
+/// code. The \a i_poreAddddress passed to \a i_fn is the full 48-bit
+/// relocatable PORE address.
+///
+/// \retval 0 Success, including the case that the image has no .halt section.
+///
+/// \retval non-0 May be either one of the SBE-XIP image error codes (see \ref
+/// sbe_xip_image_errors), or any non-zero code from \a i_fn. Since the
+/// standard SBE_XIP return codes are \> 0, application-defined codes should
+/// be \< 0.
+int
+sbe_xip_map_halt(void* io_image,
+ int (*i_fn)(void* io_image,
+ const uint64_t i_poreAddress,
+ const char* i_rcString,
+ void* io_arg),
+ void* io_arg);
+
+
+/// Get the string from of a HALT code from an SBE-XIP image .halt section
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_poreAddress This is the 48-bit address found in the PC when
+/// the PORE halts. This address is actually 4 bytes beyond the actual HALT
+/// instruction, however for simplicity this is the address used to index the
+/// HALT.
+///
+/// \param[out] o_rcString The caller provides the address of a string-pointer
+/// variable which is updated with a pointer to the string form of the halt
+/// code associated with \a i_poreAddress (assuming a successful completion).
+///
+/// \retval 0 Success
+///
+/// \revtal SBE_XIP_ITEM_NOT_FOUND The \a i_poreAddress is not associated
+/// with a halt code in .halt.
+///
+/// \revtal Other See \ref sbe_xip_image_errors
+int
+sbe_xip_get_halt(void* io_image,
+ const uint64_t i_poreAddress,
+ const char** o_rcString);
+
+
+/// Delete a section from an SBE-XIP image in host memory
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_sectionId Identifies the section to be deleted. See \ref
+/// sbe_xip_sections.
+///
+/// This API effectively deletes a section from an SBE-XIP image held in host
+/// memory. Unless the requested section \a i_section is already empty, only
+/// the final (highest address offset) section of the image may be deleted.
+/// Deleting the final section of the image means that the section size is set
+/// to 0, and the size of the image recorded in the header is reduced by the
+/// section size. Any alignment padding of the now-last section is also
+/// removed.
+///
+/// \note This API does not check for or warn if other sections in the image
+/// reference the deleted section.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_delete_section(void* io_image, const int i_sectionId);
+
+
+#ifndef PPC_HYP
+
+/// Duplicate a section from an SBE-XIP image in host memory
+///
+/// \param[in,out] i_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections.
+///
+/// \param[in] i_sectionId Identifies the section to be duplicated. See \ref
+/// sbe_xip_sections.
+///
+/// \param[out] o_duplicate At exit, points to the newly allocated and
+/// initialized duplicate of the given section. The caller is responsible for
+/// free()-ing this memory when no longer required.
+///
+/// \param[out] o_size At exit, contains the size (in bytes) of the duplicated
+/// section.
+///
+/// This API creates a bytewise duplicate of a non-empty section into newly
+/// malloc()-ed memory. At exit \a o_duplicate points to the duplicate, and \a
+/// o_size is set the the size of the duplicated section. The caller is
+/// responsible for free()-ing the memory when no longer required. The
+/// pointer at \a o_duplicate is set to NULL (0) and the \a o_size is set to 0
+/// in the event of any failure.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_duplicate_section(const void* i_image,
+ const int i_sectionId,
+ void** o_duplicate,
+ uint32_t* o_size);
+
+#endif // PPC_HYP
+
+
+/// Append binary data to an SBE-XIP image held in host memory
+///
+/// \param[in,out] io_image A pointer to an SBE-XIP image in host memory. The
+/// image is assumed to be consistent with the information contained in the
+/// header regarding the presence of and sizes of all sections. The image is
+/// also required to have been normalized.
+///
+/// \param[in] i_sectionId Identifies the section to contain the new data.
+///
+/// \param[in] i_data A pointer to the data to be appended to the image. If
+/// this pointer is NULL (0), then the effect is as if \a i_data were a
+/// pointer to an \a i_size array of 0 bytes.
+///
+/// \param[in] i_size The size of the data to be appended in bytes. If \a
+/// i_data is 0, then this is the number of bytes to clear.
+///
+/// \param[in] i_allocation The size of the memory region containing the
+/// image, measured from the first byte of the image. The call will fail if
+/// appending the new data plus any alignment padding would overflow the
+/// allocated memory.
+///
+/// \param[out] o_sectionOffset If non-0 at entry, then the API updates the
+/// location pointed to by \a o_sectionOffset with the offset of the first
+/// byte of the appended data within the indicated section. This return value
+/// is invalid in the event of a non-0 return code.
+///
+/// This API copies data from \a i_data to the end of the indicated \a
+/// i_section. The section \a i_section must either be empty, or must be the
+/// final (highest address) section in the image. If the section is initially
+/// empty and \a i_size is non-0 then the section is created at the end of the
+/// image. The size of \a i_section and the size of the image are always
+/// adjusted to reflect the newly added data. This is a simple binary copy
+/// without any interpretation (e.g., endian-translation) of the copied data.
+/// The caller is responsible for insuring that the host memory area
+/// containing the SBE-XIP image is large enough to hold the newly appended
+/// data without causing addressing errors or buffer overrun errors.
+///
+/// The final parameter \a o_sectionOffset is optional, and may be passed as
+/// NULL (0) if the application does not require the information. This return
+/// value is provided to simplify typical use cases of this API:
+///
+/// - A scan program is appended to the image, or a run-time data area is
+/// allocated and cleared at the end of the image.
+///
+/// - Pointer variables in the image are updated with PORE addresses obtained
+/// via sbe_xip_section2pore(), or
+/// other procedure code initializes a newly allocated and cleared data area
+/// via host addresses obtained from sbe_xip_section2host().
+///
+/// Regarding alignment, note that the SBE-XIP format requires that sections
+/// maintain an initial alignment that varies by section, and the API will
+/// enforce these alignment constraints for all sections created by the API.
+/// All alignment is relative to the first byte of the image (\a io_image) -
+/// \e not to the current in-memory address of the image. By specification
+/// SBE-XIP images must be loaded at a 4K alignment in order for PORE hardware
+/// relocation to work, however the APIs don't require this 4K alignment for
+/// in-memory manipulation of images. Images to be executed on PoreVe will
+/// normally require at least 8-byte final aligment in order to guarantee that
+/// the PoreVe can execute an 8-byte fetch or load/store of the final
+/// doubleword.
+///
+/// \note If the TOC section is modified then the image is marked as having an
+/// unsorted TOC.
+///
+/// \note If the call fails for any reason (other than a bug in the API
+/// itself) then the \a io_image data is returned unmodified.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_append(void* io_image,
+ const int i_sectionId,
+ const void* i_data,
+ const uint32_t i_size,
+ const uint32_t i_allocation,
+ uint32_t* o_sectionOffset);
+
+
+/// Convert an SBE-XIP section offset to a relocatable PORE address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory
+///
+/// \param[in] i_sectionId A valid SBE-XIP section identifier; The section
+/// must be non-empty.
+///
+/// \param[in] i_offset An offset (in bytes) within the section. At least one
+/// byte at \a i_offset must be currently allocated in the section.
+///
+/// \param[in] o_poreAddress The equivalent relocatable PORE address is
+/// returned via this pointer. Since valid PORE addresses are always either
+/// 4-byte (code) or 8-byte (data) aligned, this API checks the aligment of
+/// the translated address and returns SBE_XIP_ALIGNMENT_ERROR if the PORE
+/// address is not at least 4-byte aligned. Note that the translated address
+/// is still returned even if incorrectly aligned.
+///
+/// This API is typically used to translate section offsets returned from
+/// sbe_xip_append() into relocatable PORE addresses.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_section2pore(const void* i_image,
+ const int i_sectionId,
+ const uint32_t i_offset,
+ uint64_t* o_poreAddress);
+
+
+/// Convert an SBE-XIP relocatable PORE address to a host memory address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_poreAddress A relocatable PORE address putatively addressing
+/// relocatable memory contained in the image.
+///
+/// \param[out] o_hostAddress The API updates the location pointed to by \a
+/// o_hostAddress with the host address of the memory addressed by \a
+/// i_poreAddress. In the event of an error (non-0 return code) the final
+/// content of \a o_hostAddress is undefined.
+///
+/// This API is typically used to translate relocatable PORE addresses stored
+/// in the SBE-XIP image into the equivalent host address of the in-memory
+/// image, allowing host-code to manipulate arbitrary data structures in the
+/// image. If the \a i_poreAddress does not refer to memory within the image
+/// (as determined by the link address and image size) then the
+/// SBE_XIP_INVALID_ARGUMENT error code is returned.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_pore2host(const void* i_image,
+ const uint64_t i_poreAddress,
+ void** o_hostAddress);
+
+
+/// Convert an SBE-XIP relocatable PORE address to section Id and offset
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory.
+///
+/// \param[in] i_poreAddress A relocatable PORE address putatively addressing
+/// relocatable memory contained in the image.
+///
+/// \param[out] o_section The API updates the location pointed to by \a
+/// o_section with the section Id of the memory addressed by \a
+/// i_poreAddress. In the event of an error (non-0 return code) the final
+/// content of \a o_section is undefined.
+///
+/// \param[out] o_offset The API updates the location pointed to by \a
+/// o_offset with the byte offset of the memory addressed by \a i_poreAddress
+/// within \a o_section. In the event of an error (non-0 return code) the
+/// final content of \a o_offset is undefined.
+///
+/// This API is typically used to translate relocatable PORE addresses stored
+/// in the SBE-XIP image into the equivalent section + offset form, allowing
+/// host-code to manipulate arbitrary data structures in the image. If the \a
+/// i_poreAddress does not refer to memory within the image (as determined by
+/// the link address and image size) then the SBE_XIP_INVALID_ARGUMENT error
+/// code is returned.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_pore2section(const void* i_image,
+ const uint64_t i_poreAddress,
+ int* o_section,
+ uint32_t* o_offset);
+
+
+/// Convert an in-memory SBE-XIP host address to a relocatable PORE address
+///
+/// \param[in] i_image A pointer to an SBE-XIP image in host memory
+///
+/// \param[in] i_hostAddress A host address addressing data within the image.
+///
+/// \param[out] o_poreAddress The API updates the location pointed to by \a
+/// o_poreAddress with the equivelent relocatable PORE address of the memory
+/// addressed by i_hostAddress. Since valid PORE addresses are always either
+/// 4-byte (code) or 8-byte (data) aligned, this API checks the aligment of
+/// the translated address and returns SBE_XIP_ALIGNMENT_ERROR if the PORE
+/// address is not at least 4-byte aligned. Note that the translated address
+/// is still returned evn if incorrectly aligned.
+///
+/// This API is provided as a convenient way to convert host memory addresses
+/// for an in-memory SBE-XIP image into PORE addresses correctly relocated for
+/// the image, for example to update pointer variables in the image. If the
+/// \a i_hostAddress does not refer to memory within the image (as determined
+/// by the image address and image size) then the SBE_XIP_INVALID_ARGUMENT
+/// error code is returned.
+///
+/// \retval 0 Success
+///
+/// \retval non-0 See \ref sbe_xip_image_errors
+int
+sbe_xip_host2pore(const void* i_image,
+ void* i_hostAddress,
+ uint64_t* o_poreAddress);
+
+
+/// \defgroup sbe_xip_image_errors Error codes from SBE-XIP image APIs
+///
+/// @{
+
+/// A putative SBE-XIP image does not have the correct magic number, or
+/// contains some other major inconsistency.
+#define SBE_XIP_IMAGE_ERROR 1
+
+/// The TOC may be missing, partially present or may have an alignment problem.
+#define SBE_XIP_TOC_ERROR 2
+
+/// A named item was not found in the SBE-XIP TOC, or a putative HALT address
+/// is not associated with a halt code in .halt.
+#define SBE_XIP_ITEM_NOT_FOUND 3
+
+/// A named item appears in the SBE-XIP TOC, but the data is not present in
+/// the image. This error can occur if sections have been deleted from the
+/// image.
+#define SBE_XIP_DATA_NOT_PRESENT 4
+
+/// A named item appears in the SBE-XIP TOC, but the data can not be
+/// modified. This error will occur if an attempt is made to modify an
+/// address-only entry.
+#define SBE_XIP_CANT_MODIFY 5
+
+/// A direct or implied argument is invalid, e.g. an illegal data type or
+/// section identifier, or an address not contained within the image.
+#define SBE_XIP_INVALID_ARGUMENT 6
+
+/// A data type mismatch or an illegal type was specified or implied for an
+/// operation.
+#define SBE_XIP_TYPE_ERROR 7
+
+/// A bug in an SBE-XIP image API
+#define SBE_XIP_BUG 8
+
+/// The image must first be normalized with sbe_xip_normalize().
+#define SBE_XIP_NOT_NORMALIZED 9
+
+/// Attempt to delete a non-empty section that is not the final section of the
+/// image, or an attempt to append data to a non-empty section that is not the
+/// final section of the image, or an attempt to operate on an empty section
+/// for those APIs that prohibit this.
+#define SBE_XIP_SECTION_ERROR 10
+
+/// An address translation API returned a PORE address that was not at least
+/// 4-byte aligned, or alignment violations were observed by
+/// sbe_xip_validate() or sbe_xip_append().
+#define SBE_XIP_ALIGNMENT_ERROR 11
+
+/// An API that performs dynamic memory allocation was unable to allocate
+/// memory.
+#define SBE_XIP_NO_MEMORY 12
+
+/// Attempt to get or set a vector element with an index that is outside of
+/// the declared bounds of the vector.
+#define SBE_XIP_BOUNDS_ERROR 13
+
+/// Attempt to grow the image past its defined memory allocation
+#define SBE_XIP_WOULD_OVERFLOW 14
+
+/// Error associated with the disassembler occured.
+#define SBE_XIP_DISASSEMBLER_ERROR 15
+
+/// hash collision creating the .fixed_toc section
+#define SBE_XIP_HASH_COLLISION 16
+
+/// Applications can expand this macro to declare an array of string forms of
+/// the error codes if desired.
+#define SBE_XIP_ERROR_STRINGS(var) \
+ const char* var[] = { \
+ "Success", \
+ "SBE_XIP_IMAGE_ERROR", \
+ "SBE_XIP_TOC_ERROR", \
+ "SBE_XIP_ITEM_NOT_FOUND", \
+ "SBE_XIP_DATA_NOT_PRESENT", \
+ "SBE_XIP_CANT_MODIFY", \
+ "SBE_XIP_INVALID_ARGUMENT", \
+ "SBE_XIP_TYPE_ERROR", \
+ "SBE_XIP_BUG", \
+ "SBE_XIP_NOT_NORMALIZED", \
+ "SBE_XIP_SECTION_ERROR", \
+ "SBE_XIP_ALIGNMENT_ERROR", \
+ "SBE_XIP_NO_MEMORY", \
+ "SBE_XIP_BOUNDS_ERROR", \
+ "SBE_XIP_WOULD_OVERFLOW", \
+ "SBE_XIP_DISASSEMBLER_ERROR", \
+ "SBE_XIP_HASH_COLLISION", \
+ }
+
+/// Applications can use this macro to safely index the array of error
+/// strings.
+#define SBE_XIP_ERROR_STRING(var, n) \
+ ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ? \
+ "Bug : Invalid SBE-XIP error code" : var[n])
+
+/// @}
+
+/// Disassembler error codes.
+#define DIS_IMAGE_ERROR 1
+#define DIS_MEMORY_ERROR 2
+#define DIS_DISASM_ERROR 3
+#define DIS_RING_NAME_ADDR_MATCH_SUCCESS 4
+#define DIS_RING_NAME_ADDR_MATCH_FAILURE 5
+#define DIS_TOO_MANY_DISASM_WARNINGS 6
+#define DIS_DISASM_TROUBLES 7
+
+#define DIS_ERROR_STRINGS(var) \
+ const char* var[] = { \
+ "Success", \
+ "DIS_IMAGE_ERROR", \
+ "DIS_MEMORY_ERROR", \
+ "DIS_DISASM_ERROR", \
+ "DIS_RING_NAME_ADDR_MATCH_SUCCESS", \
+ "DIS_RING_NAME_ADDR_MATCH_FAILURE", \
+ "DIS_TOO_MANY_DISASM_WARNINGS", \
+ "DIS_DISASM_TROUBLES", \
+ }
+
+#define DIS_ERROR_STRING(var, n) \
+ ((((n) < 0) || ((n) > (int)(sizeof(var) / sizeof(char*)))) ? \
+ "Bug : Invalid DIS error code" : var[n])
+
+#if 0
+{ /* So __cplusplus doesn't mess w/auto-indent */
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __ASSEMBLER__
+
+
+////////////////////////////////////////////////////////////////////////////
+// Assembler Definitions
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __ASSEMBLER__
+
+/// Create an XIP TOC entry
+///
+/// \param[in] index The string form of the \a index symbol is created and
+/// linked from the TOC entry to allow external search procedures to locate
+/// the \a address.
+///
+/// \param[in] type One of the SBE_XIP_* type constants; See \ref
+/// sbe_xip_toc_types.
+///
+/// \param[in] address The address of the idexed code or data; This wlll
+/// typically be a symbol.
+///
+/// \param[in] elements <Optional> For vector types, number of elements in the
+/// vector, which is limited to an 8-bit unsigned integer. This parameter
+/// defaults to 1 which indicates a scalar type. Declaring a vector with 0
+/// elements disables bounds checking on vector accesses, and can be used if
+/// very large or indeterminate sized vectors are required. The TOC format
+/// does not support vectors of strings or addresses.
+///
+/// The \c .xip_toc macro creates a XIP Table of Contents (TOC) structure in
+/// the \c .toc section, as specified by the parameters. This macro is
+/// typically not used directly in assembly code. Instead programmers should
+/// use .xip_quad, .xip_quada, .xip_quadia, .xip_address, .xip_string or
+/// .xip_cvs_revision.
+
+ .macro .xip_toc, index:req, type:req, address:req, elements=1
+
+ .if (((\type) < 1) || ((\type) > SBE_XIP_MAX_TYPE_INDEX))
+ .error ".xip_toc : Illegal type index"
+ .endif
+
+ // First push into the .strings section to lay down the
+ // string form of the index name under a local label.
+
+ .pushsection .strings
+7667862:
+ .asciz "\index"
+ .popsection
+
+ // Now the 12-byte TOC entry is created. Push into the .toc section
+ // and lay down the first 4 bytes which are always a pointer to the
+ // string just declared. The next 4 bytes are the address of the data
+ // (or the address itself in the case of address types). The final 4
+ // bytes are the type, section (always 0 prior to normalization),
+ // number of elements, and a padding byte.
+
+ .pushsection .toc
+
+ .long 7667862b, (\address)
+ .byte (\type), 0, (\elements), 0
+
+ .popsection
+
+ .endm
+
+
+/// Allocate and initialize 64-bit global scalar or vector data and create the
+/// TOC entry.
+///
+/// \param[in] symbol The name of the scalar or vector; this name is also used
+/// as the TOC index of the data.
+///
+/// \param[in] init The initial value of (each element of) the data.
+/// This is a 64-bit integer; To allocate address pointers use .xip_quada.
+///
+/// \param[in] elements The number of 64-bit elements in the data structure,
+/// defaulting to 1, with a maximum value of 255.
+///
+/// \param[in] section The section where the data will be allocated,
+/// default depends on the memory space
+
+ .macro .xip_quad, symbol:req, init:req, elements=1, section
+
+ ..xip_quad_helper .quad, \symbol, (\init), (\elements), \section
+
+ .endm
+
+
+/// Allocate and initialize 64-bit global scalar or vector data containing a
+/// relocatable address in and create the TOC entry.
+///
+/// \param[in] symbol The name of the scalar or vector; this name is also used
+/// as the TOC index of the data.
+///
+/// \param[in] init The initial value of (each element of) the data. This
+/// will typically be a symbolic address. If the intention is to define an
+/// address that will always be filled in later by image manipulation tools,
+/// then use the .xip_quad macro with a 0 initial value.
+///
+/// \param[in] elements The number of 64-bit elements in the data structure,
+/// defaulting to 1, with a maximum value of 255.
+///
+/// \param[in] section The section where the data will be allocated,
+/// default depends on the memory space
+
+ .macro .xip_quada, symbol:req, offset:req, elements=1, section
+
+ ..xip_quad_helper .quada, \symbol, (\offset), (\elements), \section
+
+ .endm
+
+
+/// Helper for .xip_quad and .xip_quada
+
+ .macro ..xip_quad_helper, directive, symbol, init, elements, section
+
+ .if (((\elements) < 1) || ((\elements) > 255))
+ .error "The number of vector elements must be in the range 1..255"
+ .endif
+
+ ..xip_pushsection \section
+ .balign 8
+
+ .global \symbol
+\symbol\():
+ .rept (\elements)
+ \directive (\init)
+ .endr
+
+ .popsection
+
+ .xip_toc \symbol, SBE_XIP_UINT64, \symbol, (\elements)
+
+ .endm
+
+
+/// Allocate and initialize 64-bit global scalar or vector data containing
+/// full 64-bit addresses and create a TOC entry
+///
+/// \param[in] symbol The name of the scalar or vector; this name is also used
+/// as the TOC index of the data.
+///
+/// \param[in] space A valid PORE memory space descriptor
+///
+/// \param[in] offset A 32-bit relocatable offset
+///
+/// \param[in] elements The number of 64-bit elements in the data structure,
+/// defaulting to 1, with a maximum value of 255.
+///
+/// \param[in] section The section where the data will be allocated,
+/// default depends on the memory space
+
+ .macro .xip_quadia, symbol:req, space:req, offset:req, \
+ elements=1, section
+
+ .if (((\elements) < 1) || ((\elements) > 255))
+ .error "The number of vector elements must be in the range 1..255"
+ .endif
+
+ ..xip_pushsection \section
+ .balign 8
+
+ .global \symbol
+\symbol\():
+ .rept (\elements)
+ .quadia (\space), (\offset)
+ .endr
+
+ .popsection
+
+ .xip_toc \symbol, SBE_XIP_UINT64, \symbol, (\elements)
+
+ .endm
+
+/// Default push into .ipl_data unless in an OCI space, then .data
+
+ .macro ..xip_pushsection, section
+
+ .ifnb \section
+ .pushsection \section
+ .else
+ .if (_PGAS_DEFAULT_SPACE == PORE_SPACE_OCI)
+ .pushsection .data
+ .else
+ .pushsection .ipl_data
+ .endif
+ .endif
+
+ .balign 8
+
+ .endm
+
+/// Allocate and initialize a string in .strings
+///
+/// \param[in] index The string will be stored in the TOC using this index
+/// symbol.
+///
+/// \param[in] string The string to be allocated in .strings. String space is
+/// fixed once allocated. Strings designed to be overwritten by external tools
+/// should be allocated to be as long as eventually needed (e.g., by a string
+/// of blanks.)
+
+ .macro .xip_string, index:req, string:req
+
+ .pushsection .strings
+7874647:
+ .asciz "\string"
+ .popsection
+
+ .xip_toc \index, SBE_XIP_STRING, 7874647b
+
+ .endm
+
+
+/// Allocate and initialize a CVS Revison string in .strings
+///
+/// \param[in] index The string will be stored in the TOC using this index
+/// symbol.
+///
+/// \param[in] string A CVS revision string to be allocated in .strings. CVS
+/// revision strings are formatted by stripping out and only storing the
+/// actual revision number :
+///
+/// \code
+/// "$Revision <n>.<m> $" -> "<n>.<m>"
+/// \endcode
+
+
+ .macro .xip_cvs_revision, index:req, string:req
+
+ .pushsection .strings
+7874647:
+ ..cvs_revision_string "\string"
+ .popsection
+
+ .xip_toc \index, SBE_XIP_STRING, 7874647b
+
+ .endm
+
+
+/// Shorthand to create a TOC entry for an address
+///
+/// \param[in] index The symbol will be indexed as this name
+///
+/// \param[in] symbol <Optional> The symbol to index; by default the same as
+/// the index.
+
+ .macro .xip_address, index:req, symbol
+
+ .ifb \symbol
+ .xip_toc \index, SBE_XIP_ADDRESS, \index
+ .else
+ .xip_toc \index, SBE_XIP_ADDRESS, \symbol
+ .endif
+
+ .endm
+
+
+/// Edit and allocate a CVS revision string
+///
+/// CVS revision strings are formatted by stripping out and only storing the
+/// actual revision number :
+/// \code
+/// "$Revision <n>.<m> $" -> "<n>.<m>"
+/// \endcode
+
+ .macro ..cvs_revision_string, rev:req
+ .irpc c, \rev
+ .ifnc "\c", "$"
+ .ifnc "\c", "R"
+ .ifnc "\c", "e"
+ .ifnc "\c", "v"
+ .ifnc "\c", "i"
+ .ifnc "\c", "s"
+ .ifnc "\c", "i"
+ .ifnc "\c", "o"
+ .ifnc "\c", "n"
+ .ifnc "\c", ":"
+ .ifnc "\c", " "
+ .ascii "\c"
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endif
+ .endr
+ .byte 0
+ .endm
+
+#endif // __ASSEMBLER__
+
+#endif // __SBE_XIP_TOC_H
diff --git a/src/ppe/sbe/image/topfiles.mk b/src/ppe/sbe/image/topfiles.mk
new file mode 100644
index 0000000..bfcb577
--- /dev/null
+++ b/src/ppe/sbe/image/topfiles.mk
@@ -0,0 +1,35 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/sbe/image/topfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+TOP-C-SOURCES = base_ppe_demo.c
+TOP-CPP-SOURCES =
+TOP-S-SOURCES = base_ppe_header.S
+
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_perv.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_proc_chip.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_core.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_ex.H
+TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_eq.H
+
+TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-CPP-SOURCES:.C=.o) $(TOP-S-SOURCES:.S=.o)
diff --git a/src/ppe/sbe/sample/Makefile b/src/ppe/sbe/sample/Makefile
new file mode 100644
index 0000000..8bf74a0
--- /dev/null
+++ b/src/ppe/sbe/sample/Makefile
@@ -0,0 +1,100 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/sbe/sample/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+#remove this once we have a real compiler
+export P2P_ENABLE = 1
+
+#Pull in the definitions that affect all makefiles for this image
+include img_defs.mk
+
+#Pull in object file names for the top directory
+include topfiles.mk
+
+ifdef P2P_ENABLE
+include $(P2P_SRCDIR)/p2pfiles.mk
+endif
+
+PK_MAKE_DIR := $(PK_SRCDIR)/$(PPE_TYPE)
+OBJS := $(addprefix $(OBJDIR)/, $(TOP_OBJECTS))
+PKLIB := $(OBJDIR)/pk/libpk.a
+
+LIB_DIRS = -L$(OBJDIR)/pk #-L$(OBJDIR)/commonlib
+LINK_OBJS = $(OBJS) $(PKLIB) #$(COMMONLIB)
+LINK_SCRIPT = $(addprefix $(OBJDIR)/, linkscript)
+
+ifdef P2P_ENABLE
+P2PLIB := $(OBJDIR)/p2p/libp2p.a
+LIB_DIRS += -L$(OBJDIR)/p2p
+LINK_OBJS += $(P2PLIB)
+endif
+
+#default target is to make a binary application image
+#This removes all unecessary headers from the ELF executable
+$(OBJDIR)/$(IMAGE_NAME).bin $(OBJDIR)/$(IMAGE_NAME).dis: $(OBJDIR)/$(IMAGE_NAME).out
+ $(OBJCOPY) -O binary $< $(OBJDIR)/$(IMAGE_NAME).bin
+ $(OBJDUMP) -S $< > $(OBJDIR)/$(IMAGE_NAME).dis
+
+#create a linked ELF executable
+$(OBJDIR)/$(IMAGE_NAME).out: $(LINK_OBJS) $(LINK_SCRIPT)
+ $(LD) -e __system_reset -T$(LINK_SCRIPT) -Map $(OBJDIR)/$(IMAGE_NAME).map -Bstatic -o $(OBJDIR)/$(IMAGE_NAME).out $(LIB_DIRS) $(OBJS) -lpk -lp2p #-lcommon
+
+#pass the link command file through the C preprocessor to evaluate macros and remove comments
+$(LINK_SCRIPT): link.cmd
+ $(CPP) -E -x c++ -P $(DEFS) link.cmd -o $(LINK_SCRIPT)
+
+#Create an obj directory if needed
+$(LINK_OBJS) $(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+.PHONY: clean $(PKLIB) $(P2PLIB)
+
+#Build macro-specific kernel code
+$(PKLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(PK_MAKE_DIR)
+
+#Build the code that is common for all processors (PPEs and 405)
+#$(COMMONLIB):
+# $(MAKE) -I $(IMAGE_SRCDIR) -C $(COMMONLIB_SRCDIR)
+
+ifdef P2P_ENABLE
+$(P2PLIB):
+ $(MAKE) -I $(IMAGE_SRCDIR) -C $(P2P_SRCDIR)
+endif
+
+# collect all of the trace hash files for this image into a single trexStringFile
+.PHONY : tracehash
+tracehash:
+ mkdir -p $(OBJDIR)
+ $(THASH) -c -d $(OBJDIR) -s $(OBJDIR)/trexStringFile
+
+#clean the kernel directory first, then the application level clean
+clean:
+ rm -fr $(OBJDIR)
+
+#Add dependencies to header files
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/src/ppe/sbe/sample/img_defs.mk b/src/ppe/sbe/sample/img_defs.mk
new file mode 100644
index 0000000..7211acb
--- /dev/null
+++ b/src/ppe/sbe/sample/img_defs.mk
@@ -0,0 +1,265 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/sbe/sample/img_defs.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# Make header for GPE PK builds
+#
+# The application may define the following variables to control the
+# build process:
+#
+# IMG_INCLUDES : Aplication-specific header search paths
+#
+# DEFS : A string of -D<symbol>[=<value>] to control compilation
+#
+# PK : Default ..; The path to the PK source code.
+# The default is set for building the PK
+# subdirectories.
+#
+# PK_THREAD_SUPPORT : (0/1, default 1); Compile PK thread and
+# semaphore suppprt
+#
+# PK_TIMER_SUPPORT : (0/1, default 1); Compile PK timer suppprt
+#
+# SIMICS_ENVIRONMENT : (0/1, current default 0); Compile for Simics
+#
+# SIMICS_MAGIC_PANIC : (0/1, current default 0); Use Simics Magic
+# breakpoint for PK_PANIC() instead of PowerPC trap.
+# Note that Simics does not model trap correctly in
+# external debug mode.
+#
+# GCC-O-LEVEL : The optimization level passed to GCC (default -Os). May
+# also be defined empty (GCC-O-LEVEL=) to disable
+# optimization. This variable can also be used to pass
+# any other non-default setting to GCC, e.g.
+# make GCC-O-LEVEL="-Os -fno-branch-count-reg"
+#
+# GCC-TOOL-PREFIX : The full path (including executable file prefixes) to
+# the GCC cross-development tools to use. The default is
+# "ppcnf-mcp5-"
+#
+# CTEPATH : This variable defaults to the afs/awd CTE tool
+# installation - The PORE binutils are stored there. If
+# you are not in Austin be sure to define CTEPATH in
+# your .profile.
+#
+# OBJDIR : target directory for all generated files
+
+IMAGE_NAME := sample_ppe
+
+PPE_TYPE := ppe
+
+ifndef IMAGE_SRCDIR
+export IMAGE_SRCDIR = $(abspath .)
+endif
+
+ifndef IMG_INCLUDES
+export IMG_INCLUDES = -I$(IMAGE_SRCDIR)
+endif
+
+ifndef BASE_OBJDIR
+export BASE_OBJDIR = $(abspath ../../../obj)
+endif
+
+export IMG_OBJDIR = $(BASE_OBJDIR)/$(IMAGE_NAME)
+
+ifndef PK_SRCDIR
+export PK_SRCDIR = $(abspath ../../pk)
+endif
+
+ifndef GCC-TOOL-PREFIX
+#GCC-TOOL-PREFIX = $(CTEPATH)/tools/ppcgcc/prod/bin/powerpc-linux-
+GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/output/host/usr/bin/powerpc64-linux-
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/buildroot/output/host/usr/bin/powerpc-linux-
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/op-build/output/host/usr/powerpc64-buildroot-linux-gnu/bin/
+#GCC-TOOL-PREFIX = /afs/bb/u/rembold/openpower/opcustom/op-build/buildroot/output/host/usr/bin/powerpc-linux-
+endif
+
+ifndef BINUTILS-TOOL-PREFIX
+BINUTILS-TOOL-PREFIX = $(CTEPATH)/tools/ppetools/prod/powerpc-eabi/bin/
+endif
+
+ifndef P2P_SRCDIR
+export P2P_SRCDIR = $(abspath ../../tools/PowerPCtoPPE)
+endif
+
+ifndef PPETRACEPP_DIR
+export PPETRACEPP_DIR = $(abspath ../../tools/ppetracepp)
+endif
+
+OBJDIR = $(BASE_OBJDIR)$(SUB_OBJDIR)
+
+
+CC_ASM = $(GCC-TOOL-PREFIX)gcc
+TCC = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+CC = $(GCC-TOOL-PREFIX)gcc
+AS = $(BINUTILS-TOOL-PREFIX)as
+AR = $(BINUTILS-TOOL-PREFIX)ar
+LD = $(BINUTILS-TOOL-PREFIX)ld
+OBJDUMP = $(BINUTILS-TOOL-PREFIX)objdump
+OBJCOPY = $(BINUTILS-TOOL-PREFIX)objcopy
+TCPP = $(PPETRACEPP_DIR)/ppetracepp $(GCC-TOOL-PREFIX)gcc
+THASH = $(PPETRACEPP_DIR)/tracehash.pl
+CPP = $(GCC-TOOL-PREFIX)gcc
+
+ifdef P2P_ENABLE
+PCP = $(P2P_SRCDIR)/ppc-ppe-pcp.py
+endif
+
+
+ifndef CTEPATH
+$(warning The CTEPATH variable is not defined; Defaulting to /afs/awd)
+export CTEPATH = /afs/awd/projects/cte
+endif
+
+ifeq "$(PK_TIMER_SUPPORT)" ""
+PK_TIMER_SUPPORT = 1
+endif
+
+ifeq "$(PK_THREAD_SUPPORT)" ""
+PK_THREAD_SUPPORT = 1
+endif
+
+ifeq "$(PK_TRACE_SUPPORT)" ""
+PK_TRACE_SUPPORT = 1
+endif
+
+# Generate a 16bit trace string hash prefix value based on the name of this image. This will form
+# the upper 16 bits of the 32 bit trace hash values.
+ifndef PK_TRACE_HASH_PREFIX
+PK_TRACE_HASH_PREFIX := $(shell echo $(IMAGE_NAME) | md5sum | cut -c1-4 | xargs -i printf "%d" 0x{})
+endif
+
+
+ifndef GCC-O-LEVEL
+#GCC-O-LEVEL = -Os
+GCC-O-LEVEL = -O -g
+endif
+
+GCC-DEFS += -DIMAGE_NAME=$(IMAGE_NAME)
+GCC-DEFS += -DPK_TIMER_SUPPORT=$(PK_TIMER_SUPPORT)
+GCC-DEFS += -DPK_THREAD_SUPPORT=$(PK_THREAD_SUPPORT)
+GCC-DEFS += -DPK_TRACE_SUPPORT=$(PK_TRACE_SUPPORT)
+GCC-DEFS += -DPK_TRACE_HASH_PREFIX=$(PK_TRACE_HASH_PREFIX)
+GCC-DEFS += -D__PK__=1
+DEFS += $(GCC-DEFS)
+
+############################################################################
+
+INCLUDES += $(IMG_INCLUDES) \
+ -I$(PK_SRCDIR)/kernel -I$(PK_SRCDIR)/ppe42 -I$(PK_SRCDIR)/trace \
+ -I$(PK_SRCDIR)/$(PPE_TYPE) -I$(PK_SRCDIR)/../include \
+ -I$(PK_SRCDIR)/../tools/ppetracepp
+
+PIPE-CFLAGS = -pipe -Wa,-m405
+
+GCC-CFLAGS += -Wall -fsigned-char -msoft-float \
+ -mcpu=405 -m32 -mmulhw -mmultiple \
+ -meabi -msdata=eabi \
+ -ffreestanding -fno-common -Werror \
+ -fno-inline-functions-called-once \
+ -ffixed-r11 -ffixed-r12 \
+ -ffixed-r14 -ffixed-r15 -ffixed-r16 -ffixed-r17 \
+ -ffixed-r18 -ffixed-r19 -ffixed-r20 -ffixed-r21 \
+ -ffixed-r22 -ffixed-r23 -ffixed-r24 -ffixed-r25 \
+ -ffixed-r26 -ffixed-r27 \
+ -ffixed-cr1 -ffixed-cr2 -ffixed-cr3 -ffixed-cr4 \
+ -ffixed-cr5 -ffixed-cr6 -ffixed-cr7 #-lstdc++
+
+
+CFLAGS = -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES)
+
+CPPFLAGS = -E
+
+ASFLAGS = -mppe42
+
+ifdef P2P_ENABLE
+#use this to disable optimizations (fused compare/branch etc.)
+PCP-FLAG =
+
+#use this to enable optimizations
+#PCP-FLAG =
+endif
+############################################################################
+
+#override the GNU Make implicit rule for going from a .C to a .o
+%.o: %.C
+
+$(OBJDIR)/%.s: %.C
+ $(TCC) $(CFLAGS) $(DEFS) -S -o $@ $<
+
+
+#override the GNU Make implicit rule for going from a .c to a .o
+%.o: %.c
+
+$(OBJDIR)/%.s: %.c
+ $(TCC) $(CFLAGS) $(DEFS) -S -o $@ $<
+
+#override the GNU Make implicit rule for going from a .S to a .o
+%.o: %.S
+
+$(OBJDIR)/%.s: %.S
+ $(TCPP) $(CFLAGS) $(DEFS) $(CPPFLAGS) -o $@ $<
+.PRECIOUS: $(OBJDIR)/%.s
+
+ifndef P2P_ENABLE
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.s
+ $(AS) $(ASFLAGS) -o $@ $<
+
+else
+
+$(OBJDIR)/%.es: $(OBJDIR)/%.s
+ $(PCP) $(PCP-FLAG) -f $<
+.PRECIOUS: $(OBJDIR)/%.es
+
+$(OBJDIR)/%.o: $(OBJDIR)/%.es
+ $(AS) $(ASFLAGS) -o $@ $<
+
+endif
+
+# From the GNU 'Make' manual - these scripts uses the preprocessor to
+# create dependency files (*.d), then mungs them slightly to make them
+# work as Make targets. The *.d files are include-ed in the
+# subdirectory Makefiles.
+
+$(OBJDIR)/%.d: %.C
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.c
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+$(OBJDIR)/%.d: %.S
+ @set -e; rm -f $@; \
+ echo -n "$(OBJDIR)/" > $@.$$$$; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
diff --git a/src/ppe/sbe/sample/link.cmd b/src/ppe/sbe/sample/link.cmd
new file mode 100644
index 0000000..c3bff22
--- /dev/null
+++ b/src/ppe/sbe/sample/link.cmd
@@ -0,0 +1,92 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/sample/link.cmd $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#ifndef INITIAL_STACK_SIZE
+#define INITIAL_STACK_SIZE 256
+#endif
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+MEMORY
+{
+ sram : ORIGIN = 0xFFF40000, LENGTH = 0xc0000
+}
+
+SECTIONS
+{
+ . = 0xfff40000;
+ .text : {. = ALIGN(512); *(.vectors) *(.text)} > sram
+
+ ////////////////////////////////
+ // Read-only Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _RODATA_SECTION_BASE = .;
+
+ // SDA2 constant sections .sdata2 and .sbss2 must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA2_BASE_ = .;
+ .sdata2 . : { *(.sdata2) } > sram
+ .sbss2 . : { *(.sbss2) } > sram
+
+ // Other read-only data.
+
+ .rodata . : { *(.rodata*) *(.got2) } > sram
+
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+ ////////////////////////////////
+ // Read-write Data
+ ////////////////////////////////
+
+ . = ALIGN(8);
+ _DATA_SECTION_BASE = .;
+
+ // SDA sections .sdata and .sbss must be adjacent to each
+ // other. Our SDATA sections are small so we'll use strictly positive
+ // offsets.
+
+ _SDA_BASE_ = .;
+ .sdata . : { *(.sdata) } > sram
+ .sbss . : { *(.sbss) } > sram
+
+ // Other read-write data
+ // It's not clear why boot.S is generating empty .glink,.iplt
+
+ .rela . : { *(.rela*) } > sram
+ .rwdata . : { *(.data) *(.bss) } > sram
+// .iplt . : { *(.iplt) } > sram
+
+ _PK_INITIAL_STACK_LIMIT = .;
+ . = . + INITIAL_STACK_SIZE;
+ _PK_INITIAL_STACK = . - 1;
+
+}
diff --git a/src/ppe/sbe/sample/pk_scom.c b/src/ppe/sbe/sample/pk_scom.c
new file mode 100644
index 0000000..6b2c0b9
--- /dev/null
+++ b/src/ppe/sbe/sample/pk_scom.c
@@ -0,0 +1,236 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/sample/pk_scom.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pk_scom.c
+/// \brief Lowest level SCOM definitions.
+///
+/// A fapi-level SCOM should call these functions.
+///
+/// Todo:
+/// - Poll PCB master for SCOM completion.
+/// - Return error code of SCOM fails.
+/// - Return error code if SCOM input parms violate rules.
+
+#include "pk.h"
+#include "pk_scom.h"
+
+uint32_t putscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t i_data)
+{
+ uint32_t l_cid=0;
+
+ // CMO-Declaring variables tied to specific registers enables us to protect
+ // the SCOM data and address variables used in the new stvd and lvd 64-bit
+ // data instructions. This protection is needed since the new instructions
+ // are not yet properly considered by the compiler.
+ // l_dataH is used to represent the "beginning" of the 64-bit data in d8
+ // (i.e., r8+r9).
+ uint32_t register l_dataH asm("r8")=0;
+ uint32_t register l_dataL asm("r9")=0;
+ uint32_t register l_addr_eff asm("r10")=0;
+ uint32_t register l_scratch asm("r31")=0;
+
+ if (i_chiplet_id)
+ {
+ // Accommodate two different ways of supplying the chiplet ID:
+ // 0xNN000000: Only bits in high-order two nibbles : Valid
+ // 0x000000NN: Only bits in low-order two nibbles : Valid
+ //
+ if ((i_chiplet_id & 0xFF000000) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in high-order two nibbles.
+ l_cid = i_chiplet_id;
+ }
+ else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in low-order two nibbles. Convert to high-order.
+ l_cid = i_chiplet_id << 24;
+ }
+ else
+ {
+ // Invalid: Invalid type of chiplet ID
+ PK_TRACE("putscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id);
+ return 1; //CMO-improve Return sensible rc here.
+ }
+
+ l_addr_eff = (i_address & 0x00FFFFFF) | l_cid;
+ }
+ else
+ {
+ // Chiplet ID is zero. Accept address as is.
+ // This is useful for PIB addresses and non-EX chiplets, and even for
+ // EX chiplets if the fully qualified EX chiplet addr is already known.
+ l_addr_eff = i_address;
+
+ }
+
+ l_dataH = (uint32_t)(i_data>>32);
+ l_dataL = (uint32_t)(i_data);
+
+ // CMO-The following sequence forces usage of l_dataH/L and l_addr_eff
+ // and thus the population of them as well.
+ // Further note that unless l_dataH/L are placed right before the following
+ // sequence, more specifically, if they're placed at the top of putscom(),
+ // r8, or l_dataH, might be overwritten in the if(chiplet_id) section.
+ // Secondly, we test l_addr_eff for non-zero through the CR0 register
+ // (which was populated in the "mr." instruction.) This is to convince the
+ // compiler that we actually used l_addr_eff for something.
+ // At present the test result causes no action except to execute the stvd
+ // instruction in either case.
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_dataH) );
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_dataL) );
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_addr_eff) );
+ asm volatile ( \
+ "beq 0x4 \n" );
+
+
+/* asm volatile ( \
+ "stw %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+*/
+ // CMO-This instruction is not fully supported by the compiler (as of
+ // 20150108):
+ // - Correct: It is correctly translated into the proper OP code
+ // format.
+ // - Incorrect: The compiler does not seem to recognize the usage
+ // of the two l_xyz variables in that it doesn't
+ // know prior to this command that the registers that
+ // contain the values of l_xyz need to be protected
+ // up to this point. Thus, we are forced to use those
+ // two l_xyz variables in some dummy instructions just
+ // before this point in order to protect them.
+ asm volatile ( \
+ "stvd %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+
+ // CMO-TBD
+ // Check PIB response code in 0x00001007(17:19)
+ // Translate PIB rc to PK rc
+ // Does this rc get reset to zero on success?
+ // Do we need to check this rc prior to issuing the SCOM?
+
+ return 0;
+}
+
+
+uint32_t getscom( uint32_t i_chiplet_id, uint32_t i_address, uint64_t *o_data)
+{
+ uint32_t l_cid=0;
+
+ // CMO-Declaring variables tied to specific registers enables us to protect
+ // the SCOM data and address variables used in the new stvd and lvd 64-bit
+ // data instructions. This protection is needed since the new instructions
+ // are not yet properly considered by the compiler.
+ // l_dataH is used to represent the "beginning" of the 64-bit data in d8
+ // (i.e., r8+r9).
+ uint32_t register l_dataH asm("r8")=0;
+ uint32_t register l_dataL asm("r9")=0;
+ uint32_t register l_addr_eff asm("r10")=0;
+ uint32_t register l_scratch asm("r31")=0;
+
+ if (i_chiplet_id)
+ {
+ // Accommodate two different ways of supplying the chiplet ID:
+ // 0xNN000000: Only bits in high-order two nibbles : Valid
+ // 0x000000NN: Only bits in low-order two nibbles : Valid
+ //
+ if ((i_chiplet_id & 0xFF000000) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in high-order two nibbles.
+ l_cid = i_chiplet_id;
+ }
+ else if ((i_chiplet_id & 0x000000FF) == i_chiplet_id)
+ {
+ // Valid: Chiplet ID in low-order two nibbles. Convert to high-order.
+ l_cid = i_chiplet_id << 24;
+ }
+ else
+ {
+ // Invalid: Invalid type of chiplet ID
+ PK_TRACE("getscom() : Invalid value of i_chiplet_id (=0x%08X)",i_chiplet_id);
+ return 1; //CMO-improve Return sensible rc here.
+ }
+
+ l_addr_eff = (i_address & 0x00FFFFFF) | l_cid;
+ }
+ else
+ {
+ // Chiplet ID is zero. Accept address as is.
+ // This is useful for PIB addresses and non-EX chiplets, and even for
+ // EX chiplets if the fully qualified EX chiplet addr is already known.
+ l_addr_eff = i_address;
+ }
+
+ // CMO-The following sequence forces usage of l_addr_eff and thus the
+ // population of it as well.
+ // Secondly, we test l_addr_eff for non-zero through the CR0 register
+ // (which was populated in the "mr." instruction.) This is to convince the
+ // compiler that we actually used l_addr_eff for something.
+ // At present the test result causes no action except to execute the lvd
+ // instruction in either case.
+ asm volatile ( \
+ "mr. %0, %1 \n" \
+ : "=r"(l_scratch) \
+ : "r"(l_addr_eff) );
+ asm volatile ( \
+ "beq 0x4 \n" );
+
+ asm volatile ( \
+ "lvd %[data], 0(%[effective_address]) \n" \
+ : [data]"=r"(l_dataH) \
+ : [effective_address]"r"(l_addr_eff) );
+
+ // CMO-The following sequence moves the read data, in l_dataH/L, into the
+ // 64-bit o_data location.
+ asm volatile ( \
+ "stw %0, 0(%1) \n" \
+ : "=r"(l_dataH) \
+ : "r"(o_data) );
+ asm volatile ( \
+ "stw %0, 4(%1) \n" \
+ : "=r"(l_dataL) \
+ : "r"(o_data) );
+
+ // CMO-TBD
+ // Check PIB response code in 0x00001007(17:19)
+ // Translate PIB rc to PK rc
+
+ return 0;
+}
diff --git a/src/ppe/sbe/sample/pk_scom.h b/src/ppe/sbe/sample/pk_scom.h
new file mode 100644
index 0000000..f558abf
--- /dev/null
+++ b/src/ppe/sbe/sample/pk_scom.h
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/sample/pk_scom.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sample_main.c
+/// \brief Sample program that creates and starts a thread
+///
+/// This file demonstrates how to create a thread and run it. It also provides
+/// an example of how to add traces to the code.
+
+#ifndef __PK_SCOM_H__
+#define __PK_SCOM_H__
+
+/// SCOM operations return non-zero error codes that may or may not indicate
+/// an actual error, depending on which SCOM is begin accessed. This error
+/// code is returned as the value of get/putscom(). The error code value
+/// increases with teh severity of the error.
+#define CFAM_FSI_STATUS_0x00001007 0x00001007
+typedef union cfam_fsi_status_reg {
+ uint64_t value;
+ struct {
+ uint64_t ignore_fields1 : 17 ;
+ uint64_t pib_error_code : 3 ;
+ uint64_t igore_fields2 : 44 ;
+ } fields;
+} cfam_fsi_status_reg_t;
+
+#define PCB_ERROR_NONE 0
+#define PCB_ERROR_RESOURCE_OCCUPIED 1
+#define PCB_ERROR_CHIPLET_OFFLINE 2
+#define PCB_ERROR_PARTIAL_GOOD 3
+#define PCB_ERROR_ADDRESS_ERROR 4
+#define PCB_ERROR_CLOCK_ERROR 5
+#define PCB_ERROR_PACKET_ERROR 6
+#define PCB_ERROR_TIMEOUT 7
+
+uint32_t putscom( uint32_t i_chiplet, uint32_t i_address, uint64_t i_data);
+
+uint32_t getscom( uint32_t i_chiplet, uint32_t i_address, uint64_t *o_data);
+
+#endif // __PK_SCOM_H__
diff --git a/src/ppe/sbe/sample/pk_trace_wrap.c b/src/ppe/sbe/sample/pk_trace_wrap.c
new file mode 100644
index 0000000..4237b29
--- /dev/null
+++ b/src/ppe/sbe/sample/pk_trace_wrap.c
@@ -0,0 +1,33 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/sample/pk_trace_wrap.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "pk_trace_wrap.h"
+#include "pk.h"
+#include "pk_trace.h"
+
+
+void pk_trace_wrap(const char* str)
+{
+ PK_TRACE("testsetest");
+}
diff --git a/src/ppe/sbe/sample/pk_trace_wrap.h b/src/ppe/sbe/sample/pk_trace_wrap.h
new file mode 100644
index 0000000..f3c8ac6
--- /dev/null
+++ b/src/ppe/sbe/sample/pk_trace_wrap.h
@@ -0,0 +1,31 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/sample/pk_trace_wrap.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __PK_WRAP_WRAP_H__
+#define __PK_WRAP_WRAP__H__
+
+
+void pk_trace_wrap(const char*);
+
+#endif // __PK_WRAP_WRAP_H__
diff --git a/src/ppe/sbe/sample/sample_main.C b/src/ppe/sbe/sample/sample_main.C
new file mode 100644
index 0000000..0d59138
--- /dev/null
+++ b/src/ppe/sbe/sample/sample_main.C
@@ -0,0 +1,123 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/sbe/sample/sample_main.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sample_main.c
+/// \brief Sample program that creates and starts a thread
+///
+/// This file demonstrates how to create a thread and run it. It also provides
+/// an example of how to add traces to the code.
+extern "C" {
+#include "pk.h"
+#include "pk_trace.h"
+#include "pk_scom.h"
+#include "pk_trace_wrap.h"
+}
+#define KERNEL_STACK_SIZE 256
+#define MAIN_THREAD_STACK_SIZE 256
+
+
+
+uint8_t G_kernel_stack[KERNEL_STACK_SIZE];
+uint8_t G_main_thread_stack[MAIN_THREAD_STACK_SIZE];
+PkThread G_main_thread;
+
+class Thetest {
+
+ public:
+ int i;
+
+};
+
+// A simple thread that just increments a local variable and sleeps
+void main_thread(void* arg)
+{
+ //Thetest mytest;
+
+ //mytest.i = 0;
+
+ //std::cout << "sdfds" << std::endl;
+
+ uint16_t a = 0;
+
+ pk_trace_wrap("sdfsdf");
+ //PK_TRACE("thread started");
+
+
+ while(1)
+ {
+ // PK_TRACE can take up to 4 parameters
+ // (not including the format string)
+ //PK_TRACE("thread seconds = %d", a);
+ pk_sleep(PK_SECONDS(1));
+
+ uint64_t i_data = 0x0110;
+
+ putscom(0x33333, 0x11111, i_data);
+
+ getscom(0x33333, 0x11111, &i_data);
+
+ a++;
+ }
+}
+
+
+// The main function is called by the boot code (after initializing some
+// registers)
+int main(int argc, char **argv)
+{
+ // initializes kernel data (stack, threads, timebase, timers, etc.)
+ pk_initialize((PkAddress)G_kernel_stack,
+ KERNEL_STACK_SIZE,
+ 0,
+ 500000000);
+
+ //PK_TRACE("Kernel init completed");
+
+ //Initialize the thread control block for G_main_thread
+ pk_thread_create(&G_main_thread,
+ (PkThreadRoutine)main_thread,
+ (void*)NULL,
+ (PkAddress)G_main_thread_stack,
+ (size_t)MAIN_THREAD_STACK_SIZE,
+ (PkThreadPriority)1);
+
+ //PK_TRACE_BIN("G_main_thread", &G_main_thread, sizeof(G_main_thread));
+
+ //Make G_main_thread runnable
+ pk_thread_resume(&G_main_thread);
+
+ //PK_TRACE("Starting thread(s)");
+
+ // Start running the highest priority thread.
+ // This function never returns
+ pk_start_threads();
+
+ return 0;
+}
diff --git a/src/ppe/sbe/sample/topfiles.mk b/src/ppe/sbe/sample/topfiles.mk
new file mode 100644
index 0000000..b3ee1e2
--- /dev/null
+++ b/src/ppe/sbe/sample/topfiles.mk
@@ -0,0 +1,30 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/sbe/sample/topfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+TOP-C-SOURCES = pk_trace_wrap.c pk_scom.c
+TOP-CPP-SOURCES = sample_main.C
+TOP-S-SOURCES =
+
+
+TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-CPP-SOURCES:.C=.o) $(TOP-S-SOURCES:.S=.o)
diff --git a/src/ppe/tools/PowerPCtoPPE/Makefile b/src/ppe/tools/PowerPCtoPPE/Makefile
new file mode 100644
index 0000000..421f98e
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/Makefile
@@ -0,0 +1,47 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+export SUB_OBJDIR = /p2p
+
+include img_defs.mk
+include p2pfiles.mk
+
+OBJS := $(addprefix $(OBJDIR)/, $(P2P_OBJECTS))
+
+libp2p.a: $(OBJS)
+ $(AR) crs $(OBJDIR)/libp2p.a $(OBJDIR)/*.o
+
+.PHONY: clean p2p
+p2p: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
+
diff --git a/src/ppe/tools/PowerPCtoPPE/p2p-test-gen.py b/src/ppe/tools/PowerPCtoPPE/p2p-test-gen.py
new file mode 100755
index 0000000..c736600
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/p2p-test-gen.py
@@ -0,0 +1,171 @@
+#!/usr/bin/python2.6
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/p2p-test-gen.py $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# \file p2p-test-gen.py
+# \brief this program generates random constructed test cases
+# in the form of input file consumed by ppc-ppe-pcp.py
+# \usage create a file named 'test.s' and make sure it has at
+# least one blank line before executing this program.
+
+import fileinput
+import random
+
+DotLabel = ['', 'Label:', '.Label']
+
+Comments = ['', '// Comments', '/* Comments */']
+
+TabSpace = ['', '\t', ' ', '\t ', ' \t', ' \t ']
+
+RegLabel = ['', '%r']
+
+Register = [0,1,2,3,4,5,6,7,8,9,10,13,28,29,30,31]
+
+TestEnable = [0,1,2,3]
+
+TestBook = {'eieio' : 0,
+ 'isync' : 0,
+ 'icbi' : 0,
+ 'icbt' : 0,
+ 'stbux' : 3,
+ 'sthux' : 3,
+ 'stwux' : 3,
+ 'lbzux' : 3,
+ 'lhzux' : 3,
+ 'lwzux' : 3,
+ 'lha' : 2,
+ 'lhau' : 2,
+ 'lhax' : 3,
+ 'lhaux' : 3,
+ 'mulhhw' : 3,
+ 'mulhhwu' : 3,
+ 'mulhw' : 3,
+ 'mulhwu' : 3,
+ 'mullw' : 3,
+ 'mulli' : 1,
+ 'divw' : 3,
+ 'divwu' : 3,
+ 'lmw' : 2,
+ 'stmw' : 2,
+ 'lwz' : 4,
+ 'stw' : 4,
+ 'cmplw' : 5,
+ 'cmpw' : 5,
+ 'cmpwi' : 5}
+
+BranchList = ['bc', 'bcl', 'blt', 'bltl', 'ble', 'blel', 'bgt', 'bgtl', 'bge',
+ 'bgel', 'beq', 'beql', 'bne', 'bnel']
+
+def p2p_test():
+ for line in fileinput.input('test.s', inplace=1):
+ print '// start generating test cases:',
+ for opcode,format in TestBook.iteritems():
+ opcode += ' '
+ if random.randint(1, 10) > 5:
+ print random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0] +\
+ random.sample(TabSpace,1)[0]
+ else:
+ print random.sample(TabSpace,1)[0] + random.sample(DotLabel,1)[0] +\
+ random.sample(TabSpace,1)[0]
+ if format == 0 in TestEnable:
+ print random.sample(TabSpace,1)[0] + opcode +\
+ random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0]
+ if format == 3 in TestEnable:
+ regs = random.sample(Register, 3)
+ reg_field = random.sample(RegLabel,1)[0] + str(regs[0]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ random.sample(RegLabel,1)[0] + str(regs[1]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ random.sample(RegLabel,1)[0] + str(regs[2])
+ print random.sample(TabSpace,1)[0] + opcode +\
+ random.sample(TabSpace,1)[0] + reg_field +\
+ random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0]
+ if format == 1 in TestEnable:
+ regs = random.sample(Register, 2)
+ reg_field = random.sample(RegLabel,1)[0] + str(regs[0]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ random.sample(RegLabel,1)[0] + str(regs[1]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ str(random.randint(-128, 128))
+ print random.sample(TabSpace,1)[0] + opcode +\
+ random.sample(TabSpace,1)[0] + reg_field +\
+ random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0]
+ if format == 2 in TestEnable:
+ regs = random.sample(Register, 2)
+ reg_field = random.sample(RegLabel,1)[0] + str(regs[0]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ str(random.randint(-128, 128)) +\
+ '(' + random.sample(RegLabel,1)[0] + str(regs[1]) + ')'
+ print random.sample(TabSpace,1)[0] + opcode +\
+ random.sample(TabSpace,1)[0] + reg_field +\
+ random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0]
+ if format == 4 in TestEnable:
+ for i in [1,2]:
+ regs = random.sample(Register, 2)
+ reg_field = random.sample(RegLabel,1)[0] + str(regs[0]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ str(random.randint(-128, 128)) +\
+ '(' + random.sample(RegLabel,1)[0] + str(regs[1]) + ')'
+ print random.sample(TabSpace,1)[0] + opcode +\
+ random.sample(TabSpace,1)[0] + reg_field +\
+ random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0]
+ if format == 5 in TestEnable:
+ if 'i' in opcode:
+ regs = random.sample(Register, 1)
+ reg_field = random.sample(RegLabel,1)[0] + str(regs[0]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ random.sample(RegLabel,1)[0] +\
+ str(random.randint(-128, 128))
+ else:
+ regs = random.sample(Register, 2)
+ reg_field = random.sample(RegLabel,1)[0] + str(regs[0]) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ random.sample(RegLabel,1)[0] + str(regs[1])
+ print random.sample(TabSpace,1)[0] + opcode +\
+ random.sample(TabSpace,1)[0] + reg_field +\
+ random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0]
+ branch = random.sample(BranchList, 1)[0] + ' '
+ if 'bc' in branch:
+ reg_field = random.sample(TabSpace,1)[0] +\
+ str(random.randint(0, 15)) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ str(random.randint(0, 7)) + ',' +\
+ random.sample(TabSpace,1)[0] +\
+ str(random.randint(-128, 128)) +\
+ random.sample(TabSpace,1)[0]
+ else:
+ reg_field = random.sample(TabSpace,1)[0] +\
+ str(random.randint(-128, 128)) +\
+ random.sample(TabSpace,1)[0]
+ print random.sample(TabSpace,1)[0] + branch +\
+ random.sample(TabSpace,1)[0] + reg_field +\
+ random.sample(TabSpace,1)[0] + random.sample(Comments,1)[0]
+ fileinput.close()
+
+if __name__ == '__main__':
+ p2p_test()
+
+
+
diff --git a/src/ppe/tools/PowerPCtoPPE/p2pfiles.mk b/src/ppe/tools/PowerPCtoPPE/p2pfiles.mk
new file mode 100644
index 0000000..0f64982
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/p2pfiles.mk
@@ -0,0 +1,38 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/p2pfiles.mk $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# @file p2pfiles.mk
+#
+# @brief mk for including P2P support library object files
+#
+
+##########################################################################
+# Object Files
+##########################################################################
+P2P-S-SOURCES = ppe42_mulhw.S ppe42_mulhwu.S ppe42_mullw.S \
+ ppe42_divw.S ppe42_divwu.S
+
+P2P_OBJECTS = $(P2P-S-SOURCES:.S=.o)
+
+
diff --git a/src/ppe/tools/PowerPCtoPPE/ppc-ppe-pcp.py b/src/ppe/tools/PowerPCtoPPE/ppc-ppe-pcp.py
new file mode 100755
index 0000000..1d6635f
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/ppc-ppe-pcp.py
@@ -0,0 +1,1007 @@
+#!/usr/bin/python2.6
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/ppc-ppe-pcp.py $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# \file ppc-ppe-pcp.py
+# \brief PPC405 Assembly to PPE42 Assembly Post-Compiler Processor (P2P)
+#
+# ---------------------------------------------------------------
+# Revision History
+# ---------------------------------------------------------------
+# 10-07-2014: project completed
+# daviddu added optimization profile support
+#
+# 10-06-2014: added fused compare and branch supprot
+# daviddu added support for combining two ld/st into one double word
+# added support to insert branch upon .p2align directive
+#
+# 09-27-2014: added subroutine support for mul* and div*
+# daviddu added virtual double word replacing multiple word support
+#
+# 09-13-2014: initial version
+# daviddu only instruction inline replacement is supported
+# ---------------------------------------------------------------
+
+P2P_VERSION = "10-07-2014" # version number as last modified date
+P2P_PPC_EXT = '.s' # PPC Assembly filename extension
+P2P_PPE_EXT = '.es' # PPE Assembly filename extension
+P2P_PPE_PRE = '__ppe42_' # PPE Assembly subroutine prefix
+
+import sys
+import os
+import re
+import fnmatch
+import fileinput
+
+# ---------------------------------------------------------------
+# PPC405 Assembly to PPE42 Assembly Post-Compiler Processor (P2P)
+# ---------------------------------------------------------------
+#
+# Description:
+#
+# This post-compiler processor will take PPC405 assembly file(s) produced
+# by powerpc-linux-gcc or hand coded and replace some of the instructions
+# supported by PPC405 ISA but not PPE42 ISA with a set of instructions
+# supported by PPE42 ISA. Outcome of this program is PPE42 assembly file(s).
+#
+# Assumptions:
+#
+# - Input/Output File Name Extension:
+#
+# PPC405 assembly file generated by powerpc-linux-gcc has filename extension
+# defined by "P2P_PPC_EXT" global variable, while PPE42 assembly file
+# consumed by PPE Assembler has filename extension defined by "P2P_PPE_EXT"
+# global variable. Both should be consistant with Makefile rules.
+#
+# - Registers:
+#
+# Instructions in input file should only use registers supported by PPE,
+# that is R0-R10,R13,R28-R31 for GPRs and PPE only SPRs(for example, PPE
+# only has CR0 instead of CR0-7).
+#
+# GCC flag -ffixed can be used to enforce compiler to not use certain
+# registers if compiler generates input files to this script. Note certian
+# optimization level, such as -Os, of GGC will still use certain registers
+# regardless if -ffixed flag is used. Furthermore, compiler should not
+# generate multiple word instructions(lmw/stmw) that covers the registers
+# forbidden to use by -ffixed flag.
+#
+# Example of using -ffixed flag in this case:
+# -ffixed-r11 -ffixed-r12 -ffixed-r14 -ffixed-r15 \
+# -ffixed-r16 -ffixed-r17 -ffixed-r18 -ffixed-r19 \
+# -ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \
+# -ffixed-r24 -ffixed-r25 -ffixed-r26 -ffixed-r27 \
+# -ffixed-cr1 -ffixed-cr2 -ffixed-cr3 -ffixed-cr4 \
+# -ffixed-cr5 -ffixed-cr6 -ffixed-cr7
+#
+# - Instructions:
+#
+# Instructions in input file should only use PowerPC 405 instructions
+# covered by "PowerPC 405-S Embedded Processor Core" manual; however,
+# there is an assumption on certain catalog of instructions will never be
+# generated by power-linux-gcc compiler(or disabled by compiler switch).
+#
+# Also, compiler should generate extended mnemonics instead of its base
+# instruction when extended mnemonics fits.
+#
+# Via -falign-labels=n and -O2 or -O3, the compiler inserts .p2align
+# directive to help instruction alignment for best cache performance.
+#
+# - Assembly Syntax:
+#
+# There should be only white spaces before instruction mnemonics, in
+# another word, all inline comments should be put behind the instrution.
+#
+# "Label:" and an instruction should not be on the same line, hand coded
+# assembly should be consistant to this same compiler output format.
+#
+# Depandences:
+#
+# In order to utilize assembly subroutines implemented for supporting
+# missing instructions of multiplication and division in PPE42 ISA, a given
+# library(with assembly files and header) must be compiled and linked with
+# any source code that use this program to generate PPE binary.
+#
+# Usage:
+#
+# ./<ThisScript> -f <a filename with path> --- process single file
+# ./<ThisScript> -d <a directory path> --- process multiple files
+# ./<ThisScript> -h --- detailed usage on other flags
+# ./<ThisScript> -v --- version of the program
+# ./<ThisScript> -d <a directory path> -s --- perform result profiling
+#
+# Functions:
+#
+# p2p_main - main function, parse options and arguments
+# p2p_onefile - processing single PPC Assembly File
+# p2p_combine - processing two PPC instructions in input file
+# p2p_replace - processing single PPC instruction in input file
+#
+# Data Structures:
+#
+# ReplaceRules = { ppc_op : [rule, ppe_op] }
+# CombineRules = { ppc_op : [rule, ppe_op] }
+# FuseBranches = [ list of branches qualified for fusing with compares ]
+#
+#------------------------------------------------------------------------------
+# ReplaceRules: [ 'r', 'u', 'a', 'h', 's', 'o', 'd', 'm' ]
+#-------|-------------------------|--------------------------------------------
+# Rule | Example (PPC to PPE) | Description
+#-------|-------------------------|--------------------------------------------
+# 'r' | [ppc] ppc_op RT, RA, RB | simply 'replace' ppc opcode with ppe opcode
+# 0 0 | [ppe] ppe_op RT, RA, RB | while the operands, if any, stay the same
+#-------|-------------------------|--------------------------------------------
+# 'ru' | [ppc] ppc_op RT, RA, RB | on top of 'r' rule, emulate 'update' by
+# | [ppe] ppe_op RT, RA, RB | appending "add" instruction after the
+# +1 +1 | add RA, RA, RB | original instruction to update RA
+#-------|-------------------------|--------------------------------------------
+# 'ra' | [ppc] ppc_op RT, D(RA) | on top of 'r' rule, emulate 'algebraic' by
+# | [ppe] ppe_op RT, D(RA) | appending "extsh" instruction after the
+# +1 +1 | extsh RT, RT | original instruction to sign-extend RT
+#-------|-------------------------|--------------------------------------------
+# 'rau' | [ppc] ppc_op RT, RA, RB | combining rule 'r', 'a', and 'u' above.
+# | [ppe] ppe_op RT, RA, RB | Note: there is no requirement on whether
+# | add RA, RA, RB | rule 'a' or rule 'u' should be applied
+# +2 +2 | extsh RT, RT | first, the outcome should be the same.
+#-------|-------------------------|--------------------------------------------
+# 'h' | [ppc] ppc_op RT, RA, RB | rule of 'halfword' multiplication
+# | [ppe] srwi RA, 16 | emulate multiply "high halfword" with
+# | srwi RB, 16 | multiply "low halfword" by shifting
+# +2 +2 | ppe_op RT, RA, RB | the operands first
+#-------|-------------------------|--------------------------------------------
+# 's' | [ppc] ppc_op RT, RA, RB | emulate word multiply and divide
+# | [ppe] stwu R1, -24(R1)| instructions with calling 'subroutines'
+# | stvd D3, 8(R1) | implemented in ppe42_mul.S and ppe42_div.S
+# | mflr R3 |
+# | stw R3, 16(R1) | Calling Conventions:(SS = Stack Size)
+# | mr R3, RA |
+# | mr R4, RB | Caller is responsible for
+# | bl target | 1) create stack frame
+# | mr RT, R3 | 2) save off R3 and R4 to stack
+# | lwz R3, 16(R1) | 3) save off link register to stack
+# | mtlr R3 | 4) put operands into R3, R4 before branch
+# | lvd D3, 8(R1) | 5) put result in R3 to RT after branch
+# | lwz R1, 0(R1) | 6) restore link register from stack
+# | | 7) restore R3 and R4 from stack
+# | [sub] stwu R1, -SS(R1) | 8) remove the stack frame
+# | <save volatile> |
+# | (subroutine body) | Callee is responsible for
+# | <restore volatile>| 1) create and remove stack frame
+# | lwz R1, 0(R1) | 2) save and restore volatile registers
+# +X +Y | blr | 3) subroutine will not touch LR again
+#-------|-------------------------|--------------------------------------------
+# 'o' | [ppc] ppc_op[o] RT ... | rule of 'o' form for overflow
+# | [ppe] ppe_op RT ... | Note: "mullwo", "divwo" and "divwuo" each
+# | <inst specific> | has unique setting for XER[OV,SO] if OE = 1
+#-------|-------------------------|--------------------------------------------
+# 'd' | [ppc] ppc_op[.] RT ... | rule of '.' or 'dot' form for recording
+# | [ppe] ppe_op RT ... | using "cmpwli" to emulate the [.] form
+# | cmpwli RT, 0 | to the instruction result and CR0 fields
+#-------|-------------------------|--------------------------------------------
+# 'm' | [ppc] ppc_op RT, D(RA) | emulate PowerPC load/store multiple word
+# | [ppe] ppe_op DT, D(RA) | instructions with PPE specific
+# | (doubleword ld/st)| 'virtual doubleword' instructions if target
+# | or | address is 8-byte aligned; otherwise, using
+# | (singleword ld/st)| single word instructions instead or mix both
+# | or | Note only RA == R1/R2/R13 will always meet
+# -1 -1 | (single & double) | alignment requirement of virtual doubleword
+#-------|-------------------------|--------------------------------------------
+#
+ReplaceRules = {#ppc_op : [ rule | ppe_op ]
+ #----------------------------
+ #synchronization instructions
+ 'eieio' : [ 'r', 'sync' ],
+ 'isync' : [ 'r', 'nop' ],
+ 'icbi' : [ 'r', 'nop' ],
+ 'icbt' : [ 'r', 'nop' ],
+ 'mtcr' : [ 'r', 'mtcr0'],
+ #load/store with [u/x/a] form
+ 'stbux' : [ 'ru', 'stbx' ],
+ 'sthux' : [ 'ru', 'sthx' ],
+ 'stwux' : [ 'ru', 'stwx' ],
+ 'lbzux' : [ 'ru', 'lbzx' ],
+ 'lhzux' : [ 'ru', 'lhzx' ],
+ 'lwzux' : [ 'ru', 'lwzx' ],
+ 'lha' : [ 'ra', 'lhz' ],
+ 'lhau' : [ 'ra', 'lhzu' ],
+ 'lhax' : [ 'ra', 'lhzx' ],
+ 'lhaux' : [ 'rau', 'lhzx' ],
+ #multiply/divide with [./o] form
+ 'mulhhw' : [ 'h', 'mullhw' ],
+ 'mulhhw.' : [ 'h', 'mullhw.' ],
+ 'mulhhwu' : [ 'h', 'mullhwu' ],
+ 'mulhhwu.': [ 'h', 'mullhwu.' ],
+ 'mulhw' : [ 's', 'mulhw' ],
+ 'mulhw.' : [ 'sd', 'mulhw' ],
+ 'mulhwu' : [ 's', 'mulhwu' ],
+ 'mulhwu.' : [ 'sd', 'mulhwu' ],
+ 'mullw' : [ 's', 'mullw' ],
+ 'mullw.' : [ 'sd', 'mullw' ],
+ 'mullwo' : [ 'so', 'mullw' ],
+ 'mullwo.' : [ 'sod', 'mullw' ],
+ 'mulli' : [ 's', 'mullw' ],
+ 'divw' : [ 's', 'divw' ],
+ 'divw.' : [ 'sd', 'divw' ],
+ 'divwo' : [ 'so', 'divw' ],
+ 'divwo.' : [ 'sod', 'divw' ],
+ 'divwu' : [ 's', 'divwu' ],
+ 'divwu.' : [ 'sd', 'divwu' ],
+ 'divwuo' : [ 'so', 'divwu' ],
+ 'divwuo.' : [ 'sod', 'divwu' ],
+ #load/store multiple word(Rx-R31)
+ 'lmw' : [ 'm', 'lvd,lwz' ],
+ 'stmw' : [ 'm', 'stvd,stw' ]}
+
+
+#------------------------------------------------------------------------------
+# CombineRules: [ 'f', 'v', 'l' ]
+#-------|-------------------------|--------------------------------------------
+# 'f' | [ppc] ppc_op(cmp*) | rule for 'fusing' adjacent pair of compare
+# | ppc_op(b*) | and branch(PPE specific). Note: only
+# -1 0 | [ppe] ppe_op(cmp*b*) | extended mnemonics of compares are handled
+#-------|-------------------------|--------------------------------------------
+# 'v' | [ppc] ppc_op(lwz/stw) | rule for combining double word aligned
+# | ppc_op(lwz/stw) | load/store pairs into signle 'virtual'
+# -1 -1 | [ppe] ppe_op(lvd/stvd) | double word instructions(PPE specific)
+#-------|-------------------------|--------------------------------------------
+# 'l' | [ppc] .p2align | compiler will insert ".p2align" directive to
+# | Label: | help instructions align from label to label.
+# | [ppe] b Label | then assembler will insert "nop" on .p2align
+# | .p2align | directive. a "branch" to skip the nops will
+# 0 -1 | Label: | improve the performance while still aligned
+#-------|-------------------------|--------------------------------------------
+#
+CombineRules = {#ppc_op : [ rule | ppe_cp ]
+ #--------------------------
+ #8byte aligned loads/stores
+ 'lwz' : [ 'v', 'lvd' ],
+ 'stw' : [ 'v', 'stvd' ],
+ #compares fusable to branch
+ 'cmplw' : [ 'f', 'cmplw' ],
+ 'cmpw' : [ 'f', 'cmpw' ],
+ 'cmpwi' : [ 'f', 'cmpwi' ],
+ #'.p2align' before 'label:'
+ '.p2align' : [ 'l', 'b' ]}
+
+
+#------------------------------------------------------------------------------
+# FuseBranches: [ Branches can be fused into cmp*b* ]
+#------------------------------------------------------------------------------
+#
+FuseBranches = ['bc', 'bcl',
+ 'blt', 'bltl', 'ble', 'blel',
+ 'bgt', 'bgtl', 'bge', 'bgel',
+ 'beq', 'beql', 'bne', 'bnel']
+
+
+# -----------------------------------------------------------------------------
+# p2p_replace:
+# process each line(filtered) in the assembly file to replace PPC instruction
+# to supported PPE instruction(s)
+#
+# Arguments:
+# string: line - assembly file line to be replaced
+# ppc_op - detected PPC opcode that needs to be replaced
+# Return:
+# boolean: True - Return without Error
+# False - Error Detected
+# Variables:
+# string: inst, rule, ppe_op, newline, temp_op
+# double_inst, single_inst, virtual_reg, base_offset, address_reg
+# Subroutine:
+# NONE
+# -----------------------------------------------------------------------------
+def p2p_replace(line, ppc_op):
+
+ # parse PPC instruction as in I or D form with opcode and upto 3 operands:
+ # possible forms: opcode
+ # opcode RT, RA, RB
+ # opcode RT, RA, IM
+ # opcode RT, D(RA)
+ # inst.group(0) : <whole instruction>
+ # inst.group(1) : " "
+ # inst.group(2) : Opcode(.)
+ # inst.group(3) : " "
+ # inst.group(4) : GPR
+ # inst.group(5) : " , "
+ # inst.group(6) : GPR or Immediate(D)
+ # inst.group(7) : " , " or " ( "
+ # inst.group(8) : GPR or Immediate(IM)
+ # inst.group(9) : " ) "
+ inst = re.search(r"([\s]*)([a-zA-Z\.]+)([\s]*)([%r0-9]*)([\s,]*)([%r0-9\-]*)([\s,\(]*)([%r0-9\-]*)([\s\)]*)", line)
+
+ # detect an error
+ if inst is None or ppc_op != inst.group(2):
+ return False
+
+ # look up rule to process the instruction
+ rule, ppe_op = ReplaceRules[ppc_op]
+
+ # if enabled, put a mark in the output file
+ if P2P_COMMENT: print "#P2P(%s):" % rule + line,
+
+ # start cases of replacing PPC instruction with PPE instruction(s)
+ #---r------------------------------------------------------------------------
+ if 'r' in rule:
+
+ # replace opcode under rule 'r' and rewrite the instruction
+ newline = line.replace(ppc_op, ppe_op)
+ print newline,
+
+ # do not continue if there is 'a' or 'u' rule to process on this line
+ if 'u' not in rule and 'a' not in rule:
+ return True
+
+ #---u------------------------------------------------------------------------
+ if 'u' in rule:
+
+ # construct and write "add RA, RA, RB" under rule 'u'
+ newline = inst.group(1) + 'add' + inst.group(3) + inst.group(6) +\
+ inst.group(5) + inst.group(6) + inst.group(7) + inst.group(8)
+ print newline
+
+ # do not continue if there is 'a' rule to process on this line
+ if 'a' not in rule:
+ return True
+
+ #---a------------------------------------------------------------------------
+ if 'a' in rule:
+
+ # construct and write "extsh RT, RT" under rule 'a'
+ newline = inst.group(1) + 'extsh' + inst.group(3) + inst.group(4) +\
+ inst.group(5) + inst.group(4)
+ print newline
+ return True
+
+ #---h------------------------------------------------------------------------
+ if 'h' in rule:
+
+ # construct and write "srwi RA, 16" under rule 'h'
+ newline = inst.group(1) + 'srwi' + inst.group(3) + inst.group(6) +\
+ inst.group(5) + "16"
+ print newline
+
+ # construct and write "srwi RB, 16" under rule 'h'
+ newline = inst.group(1) + 'srwi' + inst.group(3) + inst.group(8) +\
+ inst.group(5) + "16"
+ print newline
+
+ # replace opcode in original instruction and write under rule 'h'
+ newline = line.replace(ppc_op, ppe_op)
+ print newline
+ return True
+
+ #---s------------------------------------------------------------------------
+ if 's' in rule:
+
+ # construct branch target label
+ ppe_op = P2P_PPE_PRE + ppe_op
+
+ # construct and write "stwu R1, -24(R1)" to create the stack frame
+ newline = inst.group(1) + 'stwu' + inst.group(3) + '1' +\
+ inst.group(5) + '-24(1)'
+ print newline
+
+ # construct and write "stvd D3, 8(R1)" to save off R3 and R4
+ newline = inst.group(1) + 'stvd' + inst.group(3) + '3' +\
+ inst.group(5) + '8(1)'
+ print newline
+
+ # construct and write "mflr R3" to fetch the current link address
+ newline = inst.group(1) + 'mflr' + inst.group(3) + '3'
+ print newline
+
+ # construct and write "stw R3, 16(R1)" to save off current LR to stack
+ newline = inst.group(1) + 'stw' + inst.group(3) + '3' +\
+ inst.group(5) + '16(1)'
+ print newline
+
+ # construct and write "mr R3, RA" to copy the operand RA to R3
+ newline = inst.group(1) + 'mr' + inst.group(3) + '3' +\
+ inst.group(5) + inst.group(6)
+ print newline
+
+ # if 'mulli' is detected, using 'li' instead of 'mr' for second operand
+ if ppc_op == 'mulli':
+ temp_op = 'li'
+ else:
+ temp_op = 'mr'
+
+ # construct and write "mr R4, RB" to copy the operand RB to R4
+ # or in 'mulli' case, "li R4, IM" to copy the operand IM to R4
+ newline = inst.group(1) + temp_op + inst.group(3) + '4' +\
+ inst.group(5) + inst.group(8)
+ print newline
+
+ # using branch and link(bl) to branch to subroutine
+ # later subroutine can branch back using branch link register(blr)
+ # Assumption: the subroutine will be responsible for saving
+ # and restoring all the volatilo registers used in the subroutine
+ newline = inst.group(1) + 'bl' + inst.group(3) + ppe_op
+ print newline
+
+ # construct and write "mr RT, R3" to copy the result in R3 to RT
+ newline = inst.group(1) + 'mr' + inst.group(3) + inst.group(4) +\
+ inst.group(5) + '3'
+ print newline
+
+ # construct and write "lwz R3, 16(R1)" to fetch the LR value from stack
+ newline = inst.group(1) + 'lwz' + inst.group(3) + '3' +\
+ inst.group(5) + '16(1)'
+ print newline
+
+ # construct and write "mtlr R3" to restore the link register
+ newline = inst.group(1) + 'mtlr' + inst.group(3) + '3'
+ print newline
+
+ # construct and write "lvd D3, 8(R1)" to restore R3 and R4
+ newline = inst.group(1) + 'lvd' + inst.group(3) + '3' +\
+ inst.group(5) + '8(1)'
+ print newline
+
+ # construct and write "lwz R1, 0(R1)" to destroy the stack frame
+ newline = inst.group(1) + 'lwz' + inst.group(3) + '1' +\
+ inst.group(5) + '0(1)'
+ print newline
+ return True
+
+ #---m------------------------------------------------------------------------
+ if 'm' in rule:
+
+ # parse instruction information
+ # note register can be in either "N" form or "%rN" form
+ double_inst,single_inst = ppe_op.split(',')
+ virtual_reg = int(re.search(r'\d+', inst.group(4)).group())
+ base_offset = int(inst.group(6))
+ address_reg = int(re.search(r'\d+', inst.group(8)).group())
+
+ # consider illegal if multiple word instruction covers non-exist registers
+ if virtual_reg < 28:
+ return False
+
+ # loop until and include GPR31
+ while virtual_reg < 32:
+ # page 270 of 405 manual, only do this for load instructions
+ if virtual_reg == address_reg != 31 and 'l' in single_inst:
+ base_offset += 4
+ virtual_reg += 1
+ continue
+
+ # if other GPRs being address_reg there is no guarantee for alignment
+ if address_reg not in [1,2,13]:
+ # construct and write "lwz/stw RT, D(RA)" for every registers
+ newline = inst.group(1) + single_inst + inst.group(3) +\
+ str(virtual_reg) + inst.group(5) + str(base_offset) +\
+ inst.group(7) + inst.group(8) + inst.group(9)
+ print newline
+ base_offset += 4
+ virtual_reg += 1
+ else:
+ # if base_offset is also aligned with base address in the address_reg
+ # & there are at least two more registers to perform doubleword ld/st
+ if not (base_offset % 8) and (virtual_reg + 1) < 32:
+ # construct and write "lvd/stvd DR, D(RA)" under rule 'v'
+ newline = inst.group(1) + double_inst + inst.group(3) +\
+ str(virtual_reg) + inst.group(5) + str(base_offset) +\
+ inst.group(7) + inst.group(8) + inst.group(9)
+ print newline
+ base_offset += 8
+ virtual_reg += 2
+ # either only one register left or base_offset isnt aligned
+ else:
+ # construct and write "lwz/stwz SR, D(RA)" under rule 'v'
+ newline = inst.group(1) + single_inst + inst.group(3) +\
+ str(virtual_reg) + inst.group(5) + str(base_offset) +\
+ inst.group(7) + inst.group(8) + inst.group(9)
+ print newline
+ base_offset += 4
+ virtual_reg += 1
+ # end of this if-else
+ # end of while loop
+ return True
+ # end of last if
+
+
+# -----------------------------------------------------------------------------
+# p2p_combine:
+# process each two lines(filtered) in the assembly file to combine two PPC
+# instructions to one PPE specific instruction for better performance
+#
+# Arguments:
+# string: first_line - 1st assembly file line to be combined
+# second_line - 2nd assembly file line to be combined
+# first_op - 1st detected PPC opcode that needs to be combined
+# second_op - 2nd detected PPC opcode that needs to be combined
+# Return:
+# boolean: done - True: return without error
+# - False: return with error detected
+# match - True: eventually matched and combined
+# - False: fail to qualify to be combined
+# Variables:
+# string: first_inst, second_inst, rule, ppe_op, newline
+# bo, px_bix, compare_operands, target
+# Subroutine:
+# NONE
+# -----------------------------------------------------------------------------
+def p2p_combine(first_line, second_line, first_op, second_op):
+
+ global P2P_SPACE; global P2P_CYCLE
+ global P2P_COMPARE_BRANCH; global P2P_VIRTUAL_DOUBLE
+
+ # parse PPC instruction as in I or B or D form with opcode and upto 3 operands
+ # possible form : [1st] opcode [CR,] RA, RB
+ # [1st] opcode [CR,] RA, IM
+ # [1st] opcode RT, D(RA)
+ # [2nd] opcode [CR,] Target
+ # [2nd] opcode BO, BI, Target
+ # [2nd] opcode RT, D(RA)
+ # inst.group(0) : <whole instruction>
+ # inst.group(1) : " "
+ # inst.group(2) : Opcode(+/-/.)
+ # inst.group(3) : " "
+ # inst.group(4) : GPR or CR or BO or Target
+ # inst.group(5) : " , "
+ # inst.group(6) : GPR or IM or D(label+offset@sda21) or BI or Target
+ # inst.group(7) : " , " or " ( "
+ # inst.group(8) : GPR or IM or Target
+ # inst.group(9) : " ) "
+ first_inst = re.search(r"([\s]*)([a-zA-Z\+\-\.]+)([\s]*)([%a-zA-Z0-9_\.]*)([\s,]*)([%a-zA-Z0-9_@\.\-\+]*)([\s,\(]*)([%a-zA-Z0-9_\.\-]*)([\)]*)", first_line)
+ second_inst = re.search(r"([\s]*)([a-zA-Z\+\-\.]+)([\s]*)([%a-zA-Z0-9_\.]*)([\s,]*)([%a-zA-Z0-9_@\.\-\+]*)([\s,\(]*)([%a-zA-Z0-9_\.\-]*)([\)]*)", second_line)
+
+ # detect an error
+ if first_inst is None or second_inst is None or \
+ first_op != first_inst.group(2) or second_op not in second_inst.group(2):
+ return False,False
+
+ # look up rule to process the instruction
+ rule, ppe_op = CombineRules[first_op]
+
+ # start cases of combining two PPC instructions into PPE instruction
+ #---f------------------------------------------------------------------------
+ if 'f' in rule:
+
+ if not P2P_COMPARE_BRANCH:
+ return True,False
+
+ # fusing compare and branch
+ ppe_op = ppe_op + second_op
+
+ # for cmpwib* case, there is a difference between
+ # cmpwi SI operand as signed 16-bit integer and then got sign extended and
+ # cmpwib* UIX operand as unsigned 5-bit integer and then got zero extended
+ # thus, will not fuse the two if the integer operand is not in range(0,31)
+ # if cr field is omitted:
+ if ',' in first_inst.group(7):
+ # cr field must be cr0 or 0, error out if it is something else:
+ if '0' not in first_inst.group(4):
+ return False, True
+ if 'i' in first_op and (int(first_inst.group(8)) < 0 or \
+ int(first_inst.group(8)) > 31):
+ return True,False
+ else:
+ compare_operands = first_inst.group(6) + first_inst.group(7) + \
+ first_inst.group(8) + ', '
+ else:
+ if 'i' in first_op and (int(first_inst.group(6)) < 0 or \
+ int(first_inst.group(6)) > 31):
+ return True,False
+ else:
+ compare_operands = first_inst.group(4) + first_inst.group(5) + \
+ first_inst.group(6) + ', '
+
+ # if 'bc' then extract BO,BI fields and convert to PX,BIX fields of 'cmp*b*'
+ # Note CTR decreament and branch always cases are not handled, and
+ # python bin() outputs "0bXXXXX" form so bo[2] is actually BO bit 0
+ # else there is no need for PX,BIX fields for extended mnemonics
+ if 'bc' in second_op:
+ bo = bin(int(second_inst.group(4)))
+
+ # do not handle CRT decreament or branch always cases
+ if bo[4] == 0 or bo[2] == 1:
+ return True,False
+
+ # PX = BO bit 1, BIX = BI = [0,1,2,3] due to only CR0 is used
+ px_bix = bo[3] + second_inst.group(5) + \
+ second_inst.group(6) + second_inst.group(7)
+ target = second_inst.group(8)
+ else:
+ px_bix = ""
+ # if cr field is omitted:
+ if ',' in second_inst.group(5):
+ # cr field must be cr0 or 0, error out if it is something else:
+ if '0' not in second_inst.group(4):
+ return False, True
+ target = second_inst.group(6)
+ else:
+ target = second_inst.group(4)
+
+ # profile: space--, cycle is the same because 1+2==3
+ P2P_SPACE -= 1
+
+ # if enabled, put a mark in the output file
+ if P2P_COMMENT:
+ print "#P2P(%s):" % rule + first_line,
+ print "#P2P(%s):" % rule + second_line,
+
+ # construct and write "cmp*b* [PX,BIX,] RA,RB/IM,target" under 'f' rule
+ newline = first_inst.group(1) + ppe_op + first_inst.group(3) +\
+ px_bix + compare_operands + target
+ print newline
+ return True,True
+
+
+ #---v------------------------------------------------------------------------
+ if 'v' in rule:
+
+ if not P2P_VIRTUAL_DOUBLE:
+ return True,False
+
+ global P2P_VDW_SDA
+
+ # Combinable Conditions:
+ # 1) base address registers must be the same and one of R1/R2/R13
+ # 2) address offsets have to be 8-bytes continuous and aligned
+ # 3) target or source registers must qualify to be double word register
+ # Note: label+offset@sda21 format is coverted to target r13 after link
+ # assume data go in and out r13 or SDA space is always 8-byte aligned
+ # here we only check the continous of address offset and register pair
+ if first_inst.group(8) == second_inst.group(8) in ['1','2','13'] or \
+ ("@sda21" in first_inst.group(6) and \
+ "@sda21" in second_inst.group(6) and \
+ P2P_VDW_SDA):
+
+ if ((first_inst.group(6).replace("@sda21","") + "+4" == \
+ second_inst.group(6).replace("@sda21","") and P2P_VDW_SDA) or \
+ ((first_inst.group(6).isdigit() and \
+ not int(first_inst.group(6)) % 8) and \
+ int(first_inst.group(6)) + 4 == int(second_inst.group(6)))) and \
+ (int(first_inst.group(4)) + 1 == int(second_inst.group(4)) or \
+ (int(first_inst.group(4)) == 31 and \
+ int(second_inst.group(4)) == 0)):
+ newline = first_line.replace(first_op, ppe_op)
+ elif ((second_inst.group(6).replace("@sda21","") + "+4" == \
+ first_inst.group(6).replace("@sda21","") and P2P_VDW_SDA) or \
+ ((second_inst.group(6).isdigit() and \
+ not int(second_inst.group(6)) % 8) and \
+ int(second_inst.group(6)) + 4 == int(first_inst.group(6)))) and \
+ (int(second_inst.group(4)) + 1 == int(first_inst.group(4)) or \
+ (int(second_inst.group(4)) == 31 and \
+ int(first_inst.group(4)) == 0)):
+ newline = second_line.replace(second_op, ppe_op)
+ else:
+ return True,False
+
+ # profile: space--, cycle--(same delay but 1 less from issue)
+ P2P_SPACE -= 1; P2P_CYCLE -= 1
+
+ # if enabled, put a mark in the output file
+ if P2P_COMMENT:
+ print "#P2P(%s):" % rule + first_line,
+ print "#P2P(%s):" % rule + second_line,
+
+ print newline,
+ return True,True
+ else:
+ return True,False
+
+
+# -----------------------------------------------------------------------------
+# p2p_onefile:
+# process single PPC assembly file to convert it into PPE assembly file
+# also filter out non-instruction lines before calling the subroutine
+#
+# Arguments:
+# string: ppcFileName
+# Return:
+# boolean: done - True if file processing completed without error
+# - False if file processing failed due to an error
+# Variables:
+# boolean: match, done
+# string: ppeFileName, line, ppc_op, pre_op, pre_line, section, label
+# integer: line_num, first_label_ln, second_label_ln, misalign
+# Subroutine:
+# p2p_combine
+# p2p_replace
+# -----------------------------------------------------------------------------
+def p2p_onefile(ppcFileName):
+
+ global P2P_SPACE; P2P_SPACE = 0 # profile count
+ global P2P_CYCLE; P2P_CYCLE = 0 # profile count
+
+ if P2P_VERBOSE : print "Translate PPC assembly: " + ppcFileName
+
+ # new PPE assembly file is renamed as <filename>.s
+ ppeFileName = ppcFileName.replace(P2P_PPC_EXT, P2P_PPE_EXT)
+ os.rename(ppcFileName, ppeFileName)
+
+ # initialize storage variables for previous line that needs to be remembered
+ pre_line = ""
+ pre_op = ""
+
+ # use inline file editing, back up original PPC assembly file as <filename>.S
+ for line in fileinput.input(ppeFileName, inplace=1, backup='.405'):
+
+ # in case of "mtmsr 0; isync"
+ line = line.replace('isync','nop')
+
+ # skip blank line
+ if not line.strip():
+ if pre_line:
+ print pre_line,
+ pre_line = ""
+ print line,
+ continue
+
+ # skip comments line
+ if re.search("^[\s]*(//|#)", line):
+ if pre_line:
+ print pre_line,
+ pre_line = ""
+ print line,
+ continue
+
+ # skip .section code except .p2align and label:
+ section = re.search("^[\s]*(\.[0-9a-zA-Z_]+)", line)
+ if section is not None and ':' not in line and \
+ section.group(1) != '.p2align':
+ if pre_line:
+ print pre_line,
+ pre_line = ""
+ print line,
+ continue
+
+ # apply specical 'l' rule in CombineRules for '.p2align' before a 'label:'
+ label = re.search("^[\s]*[\.0-9a-zA-Z_]+[:]+", line)
+ if label is not None:
+ if pre_line and pre_op == '.p2align':
+ second_label_ln = fileinput.lineno()
+ misalign = 8 - (second_label_ln - first_label_ln - 2) % 8
+ if misalign in [3,4,5,6,7]:
+ # profile: same space, but save cycles, branch penalty is 2
+ P2P_CYCLE -= misalign - 2
+ if P2P_COMMENT: print "#P2P(l):"
+ print '\tb ' + label.group(0).split(':')[0]
+ print pre_line,
+ pre_line = ""
+ first_label_ln = fileinput.lineno()
+ if pre_line:
+ print pre_line,
+ pre_line = ""
+ print line,
+ continue
+
+ # extract opcode field from line
+ ppc_op = line.split()[0]
+ done,match = False,False
+
+ # detect the 2nd possible combinable instruction
+ if pre_line and P2P_COMBINE:
+ # ignore +/- signs for branch prediction
+ if '+' in ppc_op or '-' in ppc_op:
+ ppc_op = ppc_op[:-1]
+ if 'cmp' in pre_op and ppc_op in FuseBranches or \
+ 'cmp' not in pre_op and ppc_op == pre_op:
+ done,match = p2p_combine(pre_line, line, pre_op, ppc_op)
+ if not match:
+ print pre_line,
+ else:
+ print pre_line,
+ done,match = True,False
+ pre_line = ""
+
+ # detect the 1st possible combinable instruction
+ if not pre_line and not match and P2P_COMBINE:
+ if ppc_op in CombineRules.keys():
+ pre_op = ppc_op
+ pre_line = line
+ done,match = True,True
+ else:
+ done,match = True,False
+
+ # defect possible replacable instruction
+ if not match:
+ if ppc_op in ReplaceRules.keys() and P2P_REPLACE:
+ done = p2p_replace(line, ppc_op)
+ else:
+ print line,
+ done = True
+
+ # if instruction process is not done due to error
+ if not done:
+ line_num = fileinput.lineno()
+ break
+
+ # close the output file and restore the original input file
+ fileinput.close()
+ os.rename(ppeFileName+'.405', ppcFileName)
+
+ # in case last line of the file qualified to be a pre_line and was not printed
+ if pre_line:
+ f = open(ppeFileName, 'a')
+ f.write(pre_line)
+ f.close()
+
+ # print error debug message
+ if not done:
+ print "Error: target instruction detected at line [%d]:" % line_num
+ print " " + line
+ print " but fail to recognize instruction format."
+ # terminate Makefile or execution if an error is detected
+ sys.exit(1)
+
+ if P2P_COMMENT and P2P_PROFILE:
+ f = open(ppeFileName, 'a')
+ f.write("#P2P: space(%d) cycle(%d)" % (P2P_SPACE,P2P_CYCLE))
+ f.close()
+
+ if P2P_VERBOSE:
+ print "Generated PPE assembly: " + ppeFileName
+ if P2P_PROFILE:
+ print "Optimization Profiling: " + str(P2P_SPACE*4) + " bytes, " +\
+ str(P2P_CYCLE) + " cycles."
+
+
+# -----------------------------------------------------------------------------
+# p2p_profile
+# profiling how much performance and code size are saved by optimization
+#
+# Arguments:
+# string: ppcFileName
+# Return:
+# list: [space, cycle]
+# Variables:
+# string: line, profile
+# Subroutine:
+# None
+# -----------------------------------------------------------------------------
+def p2p_profile(ppcFileName):
+ f = open(ppcFileName.replace(P2P_PPC_EXT, P2P_PPE_EXT), 'r')
+ for line in f:
+ pass
+ f.close()
+ profile = re.search(r"^\#P2P: space\(([0-9\-]+)\) cycle\(([0-9\-]+)\)", line)
+ if profile is not None:
+ return [int(profile.group(1)), int(profile.group(2))]
+ else:
+ return [0,0]
+
+# -----------------------------------------------------------------------------
+# p2p_main:
+# main of this script
+# print usage info
+# parse options and arguments
+# process one file or a directory of files
+# -----------------------------------------------------------------------------
+def p2p_main():
+
+ # command-line option parsing
+ from optparse import OptionParser
+ usage = "usage: %prog [options]"
+ version= "%prog v." + P2P_VERSION
+ parser = OptionParser(usage=usage, version=version)
+ parser.add_option("-d", "--directory", metavar="PATH", dest="ppcPath",
+ help="process all files in a directory given by PATH")
+ parser.add_option("-f", "--filename", metavar="FILE", dest="ppcFile",
+ help="process single file(with path in the filename)")
+ parser.add_option("-p", "--parallel",
+ action="store_true", dest="parallel", default=False,
+ help="processing all files in parallel processes")
+ parser.add_option("-s", "--statistics",
+ action="store_true", dest="profile", default=False,
+ help="optimization profiling, require comment in outputs")
+ parser.add_option("-c", "--combine-only",
+ action="store_false", dest="replace", default=True,
+ help="enable only combine function by disabling replace")
+ parser.add_option("-r", "--replace-only",
+ action="store_false", dest="combine", default=True,
+ help="enable only replace function by disabling combine")
+ parser.add_option("-b", "--compare branch disable",
+ action="store_false", dest="compare_branch", default=True,
+ help="only disabling fused compare branch function")
+ parser.add_option("-v", "--virtual double disable",
+ action="store_false", dest="virtual_double", default=True,
+ help="only disabling fused virtual double function")
+ parser.add_option("-e", "--eabi",
+ action="store_true", dest="vdw_sda", default=False,
+ help="enable virtual double word fusion targeting sda")
+ parser.add_option("-n", "--no-comment",
+ action="store_false", dest="comment", default=True,
+ help="don't leave comment mark in output file")
+ parser.add_option("-q", "--quiet",
+ action="store_false", dest="verbose", default=True,
+ help="don't print status messages to stdout")
+ (options, args) = parser.parse_args()
+ # global program output verbose switch
+ global P2P_VERBOSE; P2P_VERBOSE = options.verbose
+ # leave a comment mark in output files
+ global P2P_COMMENT; P2P_COMMENT = options.comment
+ # space/performance profiling function
+ global P2P_PROFILE; P2P_PROFILE = options.profile
+ # enable instruction replace functions
+ global P2P_REPLACE; P2P_REPLACE = options.replace
+ # enable instruction combine functions
+ global P2P_COMBINE; P2P_COMBINE = options.combine
+ # enable virtual double word fusion targeting sda
+ global P2P_VDW_SDA; P2P_VDW_SDA = options.vdw_sda
+ # enable only fused compare and branch function
+ global P2P_COMPARE_BRANCH; P2P_COMPARE_BRANCH = options.compare_branch
+ # enable only combined virtual double function
+ global P2P_VIRTUAL_DOUBLE; P2P_VIRTUAL_DOUBLE = options.virtual_double
+
+ if P2P_VERBOSE :
+ print "PPC405 Assembly to PPE42 Assembly Post-Compiler Proceesor (P2P)"
+ print "Version: " + P2P_VERSION
+
+ # single file processing
+ if options.ppcFile:
+
+ if P2P_VERBOSE :
+ print "Processing signle file: " + options.ppcFile
+
+ p2p_onefile(options.ppcFile)
+
+ # multiple files processing
+ if options.ppcPath:
+
+ if P2P_VERBOSE :
+ print "Accessing all files at: " + options.ppcPath
+ print "*Parallel Process Mode: " + ("Off", "On")[options.parallel]
+
+ if options.profile:
+ bytes = 0; cycles = 0
+
+ fileList = []
+ for root, subdirs, files in os.walk(options.ppcPath):
+ for file in fnmatch.filter(files, '*'+P2P_PPC_EXT):
+ if options.parallel :
+ fileList.append(os.path.join(root, file))
+ else:
+ if options.profile:
+ space,cycle = p2p_profile(os.path.join(root, file))
+ bytes += space*4
+ cycles += cycle
+ else:
+ p2p_onefile(os.path.join(root, file))
+
+ if options.profile:
+ print "Optimization Profiling: " + str(bytes) + " bytes, " +\
+ str(cycles) + " cycles."
+
+ # parallel processing mode
+ if options.parallel:
+ from multiprocessing import Pool
+ p = Pool()
+ p.map(p2p_onefile, fileList)
+ p.close()
+ p.join()
+
+ if P2P_VERBOSE : print "Done"
+
+
+# -----------------------------------------------------------------------------
+# python main
+if __name__ == '__main__':
+ p2p_main()
+
diff --git a/src/ppe/tools/PowerPCtoPPE/ppe42_divw.S b/src/ppe/tools/PowerPCtoPPE/ppe42_divw.S
new file mode 100644
index 0000000..b1ac5b4
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/ppe42_divw.S
@@ -0,0 +1,232 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/ppe42_divw.S $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+/// \file ppe42_divw.S
+/// \brief PPC405 word division instructions implemented by PPE ISA
+///
+/// This file includes implementation for the following PPC405 instructions
+/// divw RT, RA, RB
+///
+/// Note: PPE ISA specific "fused compare and branch" instructions are used
+///
+/// Revision History:
+/// 09-22-2014: Initial Version by daviddu
+///
+
+ .file "ppe42_divw.S"
+ .section ".text"
+
+ /*
+ ** Code comment notation:
+ **
+ ** msw = most-significant (high-order) word, i.e. bits 0..31
+ ** lsw = least-significant (low-order) word, i.e. bits 32..63
+ ** msh = most-significant (high-order) halfword, i.e. bits 0..15
+ ** lsh = least-significant (low-order) halfword, i.e. bits 16..63
+ **
+ ** LZ = Leading Zeroes
+ ** SD = Significant Digits
+ ** OW = Register is overwritten, previous value is lost,
+ ** correct if previous value is no longer needed.
+ ** FU = Register is not overwritten, but its value is no longer needed,
+ ** in another word, the register is "free for use".
+ **
+ ** PPE GPR Registers are: R0-R10, R13, R28-R31
+ ** Volatile Registers are: R0, R3-R10
+ ** Non-volatile registers are R28-R31
+ */
+
+ /*
+ ** Caling Convention
+ **
+ ** R2 and R13 are never saved or restored. In ABI or EABI application
+ ** these registers are constant. The other touched volatile registers
+ ** will be saved and restored by the subroutines. Note the caller
+ ** wont be saving those registers because these subroutines will be
+ ** instrumented into caller's body without compiler knowledge.
+ **
+ ** Note R3 is not saved and restored because it will be changed for
+ ** return value anyways, the p2p script will make sure to restore it.
+ ** Also CR is hanlded because of compare and branch, but XER/CTR/LR
+ ** are not hanlded because they are untouched by the instructions used.
+ **
+ ** Stack layout:
+ **
+ ** 0x00 -- R1, Dedicated for Stack Pointer
+ ** 0x04 -- slot reserved for LR
+ ** 0x08 -- R4, Volatile, Private
+ ** 0x0c -- R5, Volatile, Private
+ ** 0x10 -- R6, Volatile, Private
+ ** 0x14 -- R7, Volatile, Private
+ ** 0x18 -- R8, Volatile, Private
+ ** 0x1c -- R9, Volatile, Private
+ ** 0x20 -- CR, Condition Register
+ ** 0x24 --
+ **
+ ** 0x28 -- Stack Size, Must be 8-byte aligned
+ */
+
+ /*
+ ** Division Procedures:
+ **
+ ** __ppe42_divwu(dividend, divisor)
+ ** __ppe42_divw(dividend, divisor)
+ **
+ ** R3 = Input parameter, dividend. then Return value, quotient.
+ ** R4 = Input parameter, divisor.
+ ** R5 = Output parameter, quotient.
+ ** R6 = Output parameter, remainder.
+ ** R7 = Temporary register, counter.
+ **
+ ** General Algorithm
+ **
+ ** Using standard shift and subtract method to emulate
+ ** Note: dividend,divisor,quotient,remainder are all 32-bit integers
+ **
+ ** Precondition Check:
+ **
+ ** if (divisor == dividend) {
+ ** quotient = 1;
+ ** remainder = 0;
+ ** }
+ **
+ ** if (divisor == 0) {
+ ** quotient = 0;
+ ** remainder = 0;
+ ** }
+ **
+ ** if (divisor > dividend) {
+ ** quotient = 0;
+ ** remainder = dividend;
+ ** }
+ */
+
+/*****************************************************************************/
+
+ /*
+ ** Divide Word Signed (__ppe42_divw)
+ **
+ ** Using Divide Word Unsigned(divwu) to emulate
+ **
+ ** dd = absolute(dividend);
+ ** dr = absolute(divisor);
+ ** [q,r] = __ppe42_divwu(dd, dr);
+ **
+ ** quotient = q;
+ ** if (dividend < 0) {
+ ** remainder = -r;
+ ** if (divisor > 0)
+ ** quotient = -q;
+ ** }
+ ** else {
+ ** remainder = r;
+ ** if (divisor < 0)
+ ** quotient = -q;
+ ** }
+ */
+
+ .align 2
+ .global __ppe42_divw
+ .type __ppe42_divw, @function
+
+__ppe42_divw:
+
+ stwu %r1, -0x28(%r1) // allocate stack frame
+
+ stvd %d4, 0x08(%r1) // save off r4 & r5 in stack
+ stvd %d6, 0x10(%r1) // save off r6 & r7 in stack
+ stvd %d8, 0x18(%r1) // save off r8 & r9 in stack
+
+ mfcr %r5 // save off cr
+ stw %r5, 0x20(%r1) // store cr in stack
+
+ li %r5, 1 // quotient = 1
+ li %r6, 0 // remainder = 0
+ cmplwbc 1, 2, %r3, %r4, __ppe42_divw_ret // ret(divisor == dividend)
+
+ li %r5, 0 // quotient = 0
+ li %r6, 0 // remainder = 0
+ cmpwibc 1, 2, %r4, 0, __ppe42_divw_ret // ret(divisor == 0)
+
+ cmpwibc 1, 1, %r3, 0, __ppe42_divw_csc // dividend(+) -> csc
+ neg %r3, %r3 // absolute(dividend)
+ li %r5, 1 // note dividend < 0
+
+__ppe42_divw_csc: // <<continue sign check>>
+
+ cmpwibc 1, 1, %r4, 0, __ppe42_divw_uns // divisor(+) -> uns
+ neg %r4, %r4 // absolute(divisor)
+ li %r6, 1 // note divisor < 0
+
+__ppe42_divw_uns: // <<unsigned division>>
+
+ mr %r8, %r5 // remember if dividend > 0
+ xor %r9, %r5, %r6 // remember sign difference
+
+ li %r5, 0 // quotient = 0
+ mr %r6, %r3 // remainder = dividend
+ cmplwbc 1, 0, %r3, %r4, __ppe42_divw_sign // ret(divisor > dividend)
+
+ li %r7, 32 // num_of_bits = 32
+
+__ppe42_divw_sas: // <<shift and subtract loop>>
+
+ slwi %r6, %r6, 1 // remainder <<= 1
+ inslwi %r6, %r3, 1, 31 // remainder[31] = dividend[0]
+ slwi %r3, %r3, 1 // dividend <<= 1
+ slwi %r5, %r5, 1 // quotient <<= 1
+ subi %r7, %r7, 1 // num_of_bits--
+ cmplwbc 1, 0, %r6, %r4, __ppe42_divw_sas // continue(remainder<divisor)
+
+ sub %r6, %r6, %r4 // reminder -= divisor
+ addi %r5, %r5, 1 // quotient++
+ cmpwibc 0, 2, %r7, 0, __ppe42_divw_sas // while(num_of_bits)
+
+__ppe42_divw_sign: // <<sign handling>>
+
+ cmpwibc 1, 2, %r9, 0, __ppe42_divw_csh // if same sign, r5 stays +
+ neg %r5, %r5 // otherwise, neg(r5)
+
+__ppe42_divw_csh: // <<continue sign handling>>
+
+ cmpwibc 1, 2, %r8, 0, __ppe42_divw_ret // if dividend>0, r6 stays +
+ neg %r6, %r6 // otherwise, neg(r6)
+
+__ppe42_divw_ret: // <<return subroutine>>
+
+ mr %r3, %r5 // r3 is the default return
+
+ lwz %r5, 0x20(%r1) // load cr from stack
+ mtcr0 %r5 // restore cr
+
+ lvd %d4, 0x08(%r1) // restore r4 & r5 from stack
+ lvd %d6, 0x10(%r1) // restore r6 & r7 from stack
+ lvd %d8, 0x18(%r1) // restore r8 & r9 from stack
+
+ lwz %r1, 0(%r1) // restore stack pointer
+
+ blr // branch back
+
+ .size __ppe42_divw, .-__ppe42_divw
+
diff --git a/src/ppe/tools/PowerPCtoPPE/ppe42_divwu.S b/src/ppe/tools/PowerPCtoPPE/ppe42_divwu.S
new file mode 100644
index 0000000..98fc5ef
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/ppe42_divwu.S
@@ -0,0 +1,208 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/ppe42_divwu.S $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+/// \file ppe42_divwu.S
+/// \brief PPC405 word division instructions implemented by PPE ISA
+///
+/// This file includes implementation for the following PPC405 instructions
+/// divwu RT, RA, RB
+///
+/// Note: PPE ISA specific "fused compare and branch" instructions are used
+///
+/// Revision History:
+/// 09-22-2014: Initial Version by daviddu
+///
+
+ .file "ppe42_divwu.S"
+ .section ".text"
+
+ /*
+ ** Code comment notation:
+ **
+ ** msw = most-significant (high-order) word, i.e. bits 0..31
+ ** lsw = least-significant (low-order) word, i.e. bits 32..63
+ ** msh = most-significant (high-order) halfword, i.e. bits 0..15
+ ** lsh = least-significant (low-order) halfword, i.e. bits 16..63
+ **
+ ** LZ = Leading Zeroes
+ ** SD = Significant Digits
+ ** OW = Register is overwritten, previous value is lost,
+ ** correct if previous value is no longer needed.
+ ** FU = Register is not overwritten, but its value is no longer needed,
+ ** in another word, the register is "free for use".
+ **
+ ** PPE GPR Registers are: R0-R10, R13, R28-R31
+ ** Volatile Registers are: R0, R3-R10
+ ** Non-volatile registers are R28-R31
+ */
+
+ /*
+ ** Caling Convention
+ **
+ ** R2 and R13 are never saved or restored. In ABI or EABI application
+ ** these registers are constant. The other touched volatile registers
+ ** will be saved and restored by the subroutines. Note the caller
+ ** wont be saving those registers because these subroutines will be
+ ** instrumented into caller's body without compiler knowledge.
+ **
+ ** Note R3 is not saved and restored because it will be changed for
+ ** return value anyways, the p2p script will make sure to restore it.
+ ** Also CR is hanlded because of compare and branch, but XER/CTR/LR
+ ** are not hanlded because they are untouched by the instructions used.
+ **
+ ** Stack layout:
+ **
+ ** 0x00 -- R1, Dedicated for Stack Pointer
+ ** 0x04 -- slot reserved for LR
+ ** 0x08 -- R4, Volatile, Private
+ ** 0x0c -- R5, Volatile, Private
+ ** 0x10 -- R6, Volatile, Private
+ ** 0x14 -- R7, Volatile, Private
+ ** 0x18 -- R8, Volatile, Private
+ ** 0x1c -- R9, Volatile, Private
+ ** 0x20 -- CR, Condition Register
+ ** 0x24 --
+ **
+ ** 0x28 -- Stack Size, Must be 8-byte aligned
+ */
+
+ /*
+ ** Division Procedures:
+ **
+ ** __ppe42_divwu(dividend, divisor)
+ ** __ppe42_divw(dividend, divisor)
+ **
+ ** R3 = Input parameter, dividend. then Return value, quotient.
+ ** R4 = Input parameter, divisor.
+ ** R5 = Output parameter, quotient.
+ ** R6 = Output parameter, remainder.
+ ** R7 = Temporary register, counter.
+ **
+ ** General Algorithm
+ **
+ ** Using standard shift and subtract method to emulate
+ ** Note: dividend,divisor,quotient,remainder are all 32-bit integers
+ **
+ ** Precondition Check:
+ **
+ ** if (divisor == dividend) {
+ ** quotient = 1;
+ ** remainder = 0;
+ ** }
+ **
+ ** if (divisor == 0) {
+ ** quotient = 0;
+ ** remainder = 0;
+ ** }
+ **
+ ** if (divisor > dividend) {
+ ** quotient = 0;
+ ** remainder = dividend;
+ ** }
+ */
+
+/*****************************************************************************/
+
+ /*
+ ** Divide Word Unsigned (__ppe42_divwu)
+ **
+ ** The implementation uses standard shift and subtract approach.
+ ** The following is an example in C. Note the implementation doesnt
+ ** exactly follow the C example.
+ **
+ ** num_of_bits = 32;
+ ** while(num_bits) {
+ ** dbit = (dividend & 0x80000000) >> 31;
+ ** remainder = (remainder << 1) | dbit;
+ ** dividend = dividend << 1;
+ ** quotient = quotient << 1;
+ ** num_of_bits--;
+ ** if(remainder < divisor)
+ ** continue;
+ ** temp = remainder - divisor;
+ ** qbit = !((temp & 0x80000000) >> 31);
+ ** quotient = quotient | qbit;
+ ** remainder = temp;
+ ** }
+ */
+
+ .align 2
+ .global __ppe42_divwu
+ .type __ppe42_divwu, @function
+
+__ppe42_divwu:
+
+ stwu %r1, -0x28(%r1) // allocate stack frame
+
+ stvd %d4, 0x08(%r1) // save off r4 & r5 in stack
+ stvd %d6, 0x10(%r1) // save off r6 & r7 in stack
+ stvd %d8, 0x18(%r1) // save off r8 & r9 in stack
+
+ mfcr %r5 // save off cr
+ stw %r5, 0x20(%r1) // store cr in stack
+
+ li %r5, 1 // quotient = 1
+ li %r6, 0 // remainder = 0
+ cmplwbc 1, 2, %r3, %r4, __ppe42_divwu_ret // ret(divisor == dividend)
+
+ li %r5, 0 // quotient = 0
+ li %r6, 0 // remainder = 0
+ cmpwibc 1, 2, %r4, 0, __ppe42_divwu_ret // ret(divisor == 0)
+
+ li %r5, 0 // quotient = 0
+ mr %r6, %r3 // remainder = dividend
+ cmplwbc 1, 0, %r3, %r4, __ppe42_divwu_ret // ret(divisor > dividend)
+
+ li %r7, 32 // num_of_bits = 32
+
+__ppe42_divwu_sas: // <<shift and subtract loop>>
+
+ slwi %r6, %r6, 1 // remainder <<= 1
+ inslwi %r6, %r3, 1, 31 // remainder[31] = dividend[0]
+ slwi %r3, %r3, 1 // dividend <<= 1
+ slwi %r5, %r5, 1 // quotient <<= 1
+ subi %r7, %r7, 1 // num_of_bits--
+ cmplwbc 1, 0, %r6, %r4, __ppe42_divwu_sas // continue(remainder<divisor)
+
+ sub %r6, %r6, %r4 // reminder -= divisor
+ addi %r5, %r5, 1 // quotient++
+ cmpwibc 0, 2, %r7, 0, __ppe42_divwu_sas // while(num_of_bits)
+
+__ppe42_divwu_ret: // <<return subroutine>>
+
+ mr %r3, %r5 // r3 is the default return
+ lwz %r5, 0x20(%r1) // load cr from stack
+ mtcr0 %r5 // restore cr
+
+ lvd %d4, 0x08(%r1) // restore r4 & r5 from stack
+ lvd %d6, 0x10(%r1) // restore r6 & r7 from stack
+ lvd %d8, 0x18(%r1) // restore r8 & r9 from stack
+
+ lwz %r1, 0(%r1) // restore stack pointer
+
+ blr // branch back
+
+ .size __ppe42_divwu, .-__ppe42_divwu
+
+
diff --git a/src/ppe/tools/PowerPCtoPPE/ppe42_mulhw.S b/src/ppe/tools/PowerPCtoPPE/ppe42_mulhw.S
new file mode 100644
index 0000000..d60ec10
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/ppe42_mulhw.S
@@ -0,0 +1,217 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/ppe42_mulhw.S $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+/// \file ppe42_mulhw.S
+/// \brief PPC405 word multiplication instructions implemented by PPE ISA
+///
+/// This file includes implementation for the following PPC405 instructions
+/// mulhw
+///
+/// Note: PPE ISA specific "fused compare and branch" instructions are used
+///
+/// Revision History:
+/// 09-15-2014: Initial Version by daviddu
+///
+
+ .file "ppe42_mulhw.S"
+ .section ".text"
+
+ /*
+ ** Code comment notation:
+ **
+ ** msw = most-significant (high-order) word, i.e. bits 0..31
+ ** lsw = least-significant (low-order) word, i.e. bits 32..63
+ ** msh = most-significant (high-order) halfword, i.e. bits 0..15
+ ** lsh = least-significant (low-order) halfword, i.e. bits 16..63
+ ** LZ = Leading Zeroes
+ ** SD = Significant Digits
+ ** OW = Register is overwritten, previous value is lost,
+ ** correct if previous value is no longer needed.
+ ** FU = Register is not overwritten, but its value is no longer needed,
+ ** in another word, the register is "free for use".
+ **
+ ** PPE GPR Registers are: R0-R10, R13, R28-R31
+ ** Volatile Registers are: R0, R3-R10
+ ** Non-volatile registers are R28-R31
+ */
+
+ /*
+ ** Caling Convention
+ **
+ ** R2 and R13 are never saved or restored. In ABI or EABI application
+ ** these registers are constant. The other touched volatile registers
+ ** will be saved and restored by the subroutines. Note the caller
+ ** wont be saving those registers because these subroutines will be
+ ** instrumented into caller's body without compiler knowledge.
+ **
+ ** Note R3 is not saved and restored because it will be changed for
+ ** return value anyways, the p2p script will make sure to restore it.
+ ** Also CR is hanlded because of compare and branch, but XER/CTR/LR
+ ** are not hanlded because they are untouched by the instructions used.
+ **
+ ** Stack layout:
+ **
+ ** 0x00 -- R1, Dedicated for Stack Pointer
+ ** 0x04 -- slot reserved for LR
+ ** 0x08 -- R4, Volatile, Private
+ ** 0x0c -- R5, Volatile, Private
+ ** 0x10 -- R6, Volatile, Private
+ ** 0x14 -- R7, Volatile, Private
+ ** 0x18 -- R8, Volatile, Private
+ ** 0x1c -- R9, Volatile, Private
+ ** 0x20 -- CR, Condition Register
+ ** 0x24 --
+ **
+ ** 0x28 -- Stack Size, Must be 8-byte aligned
+ */
+
+ /*
+ ** Multiplication Procedures:
+ **
+ ** __ppe42_mulhwu(U,V)
+ ** __ppe42_mulhw(U,V)
+ ** __ppe42_mullw(U,V)
+ **
+ ** R3:R4 = Input parameter, multipliers: U, V.
+ ** R3 = Output parameter, either product.msh or product.lsh.
+ ** R5-R9 = Temporary registers
+ **
+ ** General Algorithm
+ **
+ ** Using PPC405 ISA instruction 'mullhw' to emulate
+ ** Note: U,V,A,B,C,D,Product are all 32-bit integers(with msh and lsh)
+ **
+ ** U.msh U.lsh
+ ** X V.msh V.lsh
+ ** ------------------------
+ ** A.msh A.lsh
+ ** B.msh B.lsh
+ ** C.msh C.lsh
+ ** D.msh D.lsh
+ ** ------------------------
+ ** Product.msw Product.lsw
+ **
+ ** __ppe42_mulhwu: Return Product.msh (unsigned)
+ ** __ppe42_mulhw: Return Product.msh (signed)
+ ** __ppe42_mullw: Return Product.lsh
+ **
+ ** Precondition Check:
+ **
+ ** if( U == 0 || V == 0 ) return P=0;
+ */
+
+/*****************************************************************************/
+
+ /*
+ ** Multiply High Word Signed (__ppe42_mulhw)
+ **
+ ** Using Multiply High Word Unsigned(mulhwu) to emulate
+ **
+ ** u = absolute(U);
+ ** v = absolute(V);
+ ** p = __ppe42_mulhwu(u, v);
+ ** if( U[0] xor V[0] )
+ ** p = -p
+ */
+
+ .align 2
+ .global __ppe42_mulhw
+ .type __ppe42_mulhw, @function
+
+__ppe42_mulhw:
+
+ stwu %r1, -0x28(%r1) // allocate stack frame
+
+ stvd %d4, 0x08(%r1) // save off r4 & r5 in stack
+ stvd %d6, 0x10(%r1) // save off r6 & r7 in stack
+ stvd %d8, 0x18(%r1) // save off r8 & r9 in stack
+
+ mfcr %r5 // save off cr
+ stw %r5, 0x20(%r1) // store cr in stack
+
+ li %r5, 0 // r5 = 0
+ cmpwibc 1, 2, %r3, 0, __ppe42_mulhw_ret // U=0 -> ret
+ cmpwibc 1, 2, %r4, 0, __ppe42_mulhw_ret // V=0 -> ret
+
+ cmpwibc 1, 1, %r3, 0, __ppe42_mulhw_csc // U>0 -> csc
+ neg %r3, %r3 // absolute(U)
+ li %r5, 1 // U<0 -> r5 = 1
+
+__ppe42_mulhw_csc: // <<continue sign check>>
+
+ li %r6, 0 // V>0 -> r6 = 0
+ cmpwibc 1, 1, %r4, 0, __ppe42_mulhw_uns // V>0 -> uns
+ neg %r4, %r4 // absolute(V)
+ li %r6, 1 // V<0 -> r6 = 1
+
+__ppe42_mulhw_uns: // <<unsigned multiplication>>
+
+ xor %r9, %r5, %r6 // remember sign difference
+
+ extrwi %r5, %r3, 16, 16
+ srwi %r3, %r3, 16
+ extrwi %r6, %r4, 16, 16
+ srwi %r4, %r4, 16
+
+ mullhwu %r7, %r5, %r6
+ srwi %r7, %r7, 16
+
+ mullhwu %r6, %r3, %r6
+ extrwi %r8, %r6, 16, 16
+ srwi %r6, %r6, 16
+ add %r7, %r8, %r7
+
+ mullhwu %r5, %r5, %r4
+ extrwi %r8, %r5, 16, 16
+ srwi %r5, %r5, 16
+ add %r7, %r8, %r7
+
+ srwi %r7, %r7, 16
+ add %r7, %r7, %r6
+ add %r7, %r7, %r5
+
+ mullhwu %r3, %r3, %r4
+ add %r5, %r3, %r7
+
+ cmpwibc 1, 2, %r9, 0, __ppe42_mulhw_ret // if same sign, r5 stays +
+ neg %r5, %r5 // otherwise, neg(r5)
+
+__ppe42_mulhw_ret:
+
+ mr %r3, %r5 // put return value to r3
+
+ lwz %r5, 0x20(%r1) // load cr from stack
+ mtcr0 %r5 // restore cr
+
+ lvd %d4, 0x08(%r1) // restore r4 & r5 from stack
+ lvd %d6, 0x10(%r1) // restore r6 & r7 from stack
+ lvd %d8, 0x18(%r1) // restore r8 & r9 from stack
+
+ lwz %r1, 0(%r1) // restore stack pointer
+
+ blr
+
+ .size __ppe42_mulhw, .-__ppe42_mulhw
+
+
diff --git a/src/ppe/tools/PowerPCtoPPE/ppe42_mulhwu.S b/src/ppe/tools/PowerPCtoPPE/ppe42_mulhwu.S
new file mode 100644
index 0000000..b1f2981
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/ppe42_mulhwu.S
@@ -0,0 +1,226 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/ppe42_mulhwu.S $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+/// \file ppe42_mulhwu.S
+/// \brief PPC405 word multiplication instructions implemented by PPE ISA
+///
+/// This file includes implementation for the following PPC405 instructions
+/// mulhwu
+///
+/// Note: PPE ISA specific "fused compare and branch" instructions are used
+///
+/// Revision History:
+/// 09-15-2014: Initial Version by daviddu
+///
+
+ .file "ppe42_mulhwu.S"
+ .section ".text"
+
+ /*
+ ** Code comment notation:
+ **
+ ** msw = most-significant (high-order) word, i.e. bits 0..31
+ ** lsw = least-significant (low-order) word, i.e. bits 32..63
+ ** msh = most-significant (high-order) halfword, i.e. bits 0..15
+ ** lsh = least-significant (low-order) halfword, i.e. bits 16..63
+ ** LZ = Leading Zeroes
+ ** SD = Significant Digits
+ ** OW = Register is overwritten, previous value is lost,
+ ** correct if previous value is no longer needed.
+ ** FU = Register is not overwritten, but its value is no longer needed,
+ ** in another word, the register is "free for use".
+ **
+ ** PPE GPR Registers are: R0-R10, R13, R28-R31
+ ** Volatile Registers are: R0, R3-R10
+ ** Non-volatile registers are R28-R31
+ */
+
+ /*
+ ** Caling Convention
+ **
+ ** R2 and R13 are never saved or restored. In ABI or EABI application
+ ** these registers are constant. The other touched volatile registers
+ ** will be saved and restored by the subroutines. Note the caller
+ ** wont be saving those registers because these subroutines will be
+ ** instrumented into caller's body without compiler knowledge.
+ **
+ ** Note R3 is not saved and restored because it will be changed for
+ ** return value anyways, the p2p script will make sure to restore it.
+ ** Also CR is hanlded because of compare and branch, but XER/CTR/LR
+ ** are not hanlded because they are untouched by the instructions used.
+ **
+ ** Stack layout:
+ **
+ ** 0x00 -- R1, Dedicated for Stack Pointer
+ ** 0x04 -- slot reserved for LR
+ ** 0x08 -- R4, Volatile, Private
+ ** 0x0c -- R5, Volatile, Private
+ ** 0x10 -- R6, Volatile, Private
+ ** 0x14 -- R7, Volatile, Private
+ ** 0x18 -- R8, Volatile, Private
+ ** 0x1c -- R9, Volatile, Private
+ ** 0x20 -- CR, Condition Register
+ ** 0x24 --
+ **
+ ** 0x28 -- Stack Size, Must be 8-byte aligned
+ */
+
+ /*
+ ** Multiplication Procedures:
+ **
+ ** __ppe42_mulhwu(U,V)
+ ** __ppe42_mulhw(U,V)
+ ** __ppe42_mullw(U,V)
+ **
+ ** R3:R4 = Input parameter, multipliers: U, V.
+ ** R3 = Output parameter, either product.msh or product.lsh.
+ ** R5-R9 = Temporary registers
+ **
+ ** General Algorithm
+ **
+ ** Using PPC405 ISA instruction 'mullhw' to emulate
+ ** Note: U,V,A,B,C,D,Product are all 32-bit integers(with msh and lsh)
+ **
+ ** U.msh U.lsh
+ ** X V.msh V.lsh
+ ** ------------------------
+ ** A.msh A.lsh
+ ** B.msh B.lsh
+ ** C.msh C.lsh
+ ** D.msh D.lsh
+ ** ------------------------
+ ** Product.msw Product.lsw
+ **
+ ** __ppe42_mulhwu: Return Product.msh (unsigned)
+ ** __ppe42_mulhw: Return Product.msh (signed)
+ ** __ppe42_mullw: Return Product.lsh
+ **
+ ** Precondition Check:
+ **
+ ** if( U == 0 || V == 0 ) return P=0;
+ */
+
+/*****************************************************************************/
+
+ /*
+ ** Multiply High Word Unsigned (__ppe42_mulhwu)
+ **
+ ** r5 = U[16:31] or U.lsh | r5 = r3 & 0xffff
+ ** r3 = U[0:15] or U.msh | r3 = r3 >> 16 (r3 OW)
+ ** r6 = V[16:31] or V.lsh | r6 = r4 & 0xffff
+ ** r4 = V[0:15] or V.msh | r4 = r4 >> 16 (r4 OW)
+ **
+ ** 4th column(drop A.lsh):
+ ** A = U.lsh * V.lsh [32] | r7 = r5 * r6
+ ** A = A.msh [16] | r7 = r7 >> 16 (r7 OW)
+ **
+ ** 3rd column(A = A.msh + B.lsh + C.lsh):
+ ** B = U.msh * U.lsh [32] | r6 = r3 * r6 (r6 OW)
+ ** T = B.lsh [16] | r8 = r6 & 0xffff
+ ** B = B.msh [16] | r6 = r6 >> 16 (r6 OW)
+ ** A = T + A [16] | r7 = r8 + r7 (r7 OW, r8 FU)
+ **
+ ** C = U.lsh * V.msh [32] | r5 = r5 * r4 (r5 OW)
+ ** T = C.lsh [16] | r8 = r5 & 0xffff (r8 OW)
+ ** C = C.msh [16] | r5 = r5 >> 16 (r5 OW)
+ ** A = T + A [16] | r7 = r8 + r7 (r7 OW, r8 FU)
+ **
+ ** 2nd column(A = 3rd_carry + B.msh + C.msh):
+ ** A = A.msh [16] | r7 = r7 >> 16 (r7 OW)
+ ** A = A + B [16] | r7 = r7 + r6 (r7 OW, r6 FU)
+ ** A = A + C [16] | r7 = r7 + r5 (r7 OW, r5 FU)
+ **
+ ** 1st column(A = D + A):
+ ** D = U.msh * V.msh [32] | r3 = r3 * r4 (r3 OW, r4 FU)
+ ** P = D + A [32] | r5 = r3 + r7 (r3, r7 FU)
+ **
+ ** Return P(r3=r5) as Product.msw unsigned
+ **
+ ** Note: the implementation can be even shorter, the current
+ ** implementation is ensuring the overflow is avoided
+ ** by always adding 16 bits integer together.
+ */
+
+ .align 2
+ .global __ppe42_mulhwu
+ .type __ppe42_mulhwu, @function
+
+__ppe42_mulhwu:
+
+ stwu %r1, -0x28(%r1) // allocate stack frame
+
+ stvd %d4, 0x08(%r1) // save off r4 & r5 in stack
+ stvd %d6, 0x10(%r1) // save off r6 & r7 in stack
+ stvd %d8, 0x18(%r1) // save off r8 & r9 in stack
+
+ mfcr %r5 // save off cr
+ stw %r5, 0x20(%r1) // store cr in stack
+
+ li %r5, 0 // r5 = 0
+ cmpwibc 1, 2, %r3, 0, __ppe42_mulhwu_ret // U=0 -> ret
+ cmpwibc 1, 2, %r4, 0, __ppe42_mulhwu_ret // V=0 -> ret
+
+ extrwi %r5, %r3, 16, 16
+ srwi %r3, %r3, 16
+ extrwi %r6, %r4, 16, 16
+ srwi %r4, %r4, 16
+
+ mullhwu %r7, %r5, %r6
+ srwi %r7, %r7, 16
+
+ mullhwu %r6, %r3, %r6
+ extrwi %r8, %r6, 16, 16
+ srwi %r6, %r6, 16
+ add %r7, %r8, %r7
+
+ mullhwu %r5, %r5, %r4
+ extrwi %r8, %r5, 16, 16
+ srwi %r5, %r5, 16
+ add %r7, %r8, %r7
+
+ srwi %r7, %r7, 16
+ add %r7, %r7, %r6
+ add %r7, %r7, %r5
+
+ mullhwu %r3, %r3, %r4
+ add %r5, %r3, %r7
+
+__ppe42_mulhwu_ret:
+
+ mr %r3, %r5 // put return value to r3
+
+ lwz %r5, 0x20(%r1) // load cr from stack
+ mtcr0 %r5 // restore cr
+
+ lvd %d4, 0x08(%r1) // restore r4 & r5 from stack
+ lvd %d6, 0x10(%r1) // restore r6 & r7 from stack
+ lvd %d8, 0x18(%r1) // restore r8 & r9 from stack
+
+ lwz %r1, 0(%r1) // restore stack pointer
+
+ blr
+
+ .size __ppe42_mulhwu, .-__ppe42_mulhwu
+
+
diff --git a/src/ppe/tools/PowerPCtoPPE/ppe42_mullw.S b/src/ppe/tools/PowerPCtoPPE/ppe42_mullw.S
new file mode 100644
index 0000000..59b0856
--- /dev/null
+++ b/src/ppe/tools/PowerPCtoPPE/ppe42_mullw.S
@@ -0,0 +1,198 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/PowerPCtoPPE/ppe42_mullw.S $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+/// \file ppe42_mullw.S
+/// \brief PPC405 word multiplication instructions implemented by PPE ISA
+///
+/// This file includes implementation for the following PPC405 instructions
+/// mullw
+///
+/// Note: PPE ISA specific "fused compare and branch" instructions are used
+///
+/// Revision History:
+/// 09-15-2014: Initial Version by daviddu
+///
+
+ .file "ppe42_mullw.S"
+ .section ".text"
+
+ /*
+ ** Code comment notation:
+ **
+ ** msw = most-significant (high-order) word, i.e. bits 0..31
+ ** lsw = least-significant (low-order) word, i.e. bits 32..63
+ ** msh = most-significant (high-order) halfword, i.e. bits 0..15
+ ** lsh = least-significant (low-order) halfword, i.e. bits 16..63
+ ** LZ = Leading Zeroes
+ ** SD = Significant Digits
+ ** OW = Register is overwritten, previous value is lost,
+ ** correct if previous value is no longer needed.
+ ** FU = Register is not overwritten, but its value is no longer needed,
+ ** in another word, the register is "free for use".
+ **
+ ** PPE GPR Registers are: R0-R10, R13, R28-R31
+ ** Volatile Registers are: R0, R3-R10
+ ** Non-volatile registers are R28-R31
+ */
+
+ /*
+ ** Caling Convention
+ **
+ ** R2 and R13 are never saved or restored. In ABI or EABI application
+ ** these registers are constant. The other touched volatile registers
+ ** will be saved and restored by the subroutines. Note the caller
+ ** wont be saving those registers because these subroutines will be
+ ** instrumented into caller's body without compiler knowledge.
+ **
+ ** Note R3 is not saved and restored because it will be changed for
+ ** return value anyways, the p2p script will make sure to restore it.
+ ** Also CR is hanlded because of compare and branch, but XER/CTR/LR
+ ** are not hanlded because they are untouched by the instructions used.
+ **
+ ** Stack layout:
+ **
+ ** 0x00 -- R1, Dedicated for Stack Pointer
+ ** 0x04 -- slot reserved for LR
+ ** 0x08 -- R4, Volatile, Private
+ ** 0x0c -- R5, Volatile, Private
+ ** 0x10 -- R6, Volatile, Private
+ ** 0x14 -- R7, Volatile, Private
+ ** 0x18 -- R8, Volatile, Private
+ ** 0x1c -- R9, Volatile, Private
+ ** 0x20 -- CR, Condition Register
+ ** 0x24 --
+ **
+ ** 0x28 -- Stack Size, Must be 8-byte aligned
+ */
+
+ /*
+ ** Multiplication Procedures:
+ **
+ ** __ppe42_mulhwu(U,V)
+ ** __ppe42_mulhw(U,V)
+ ** __ppe42_mullw(U,V)
+ **
+ ** R3:R4 = Input parameter, multipliers: U, V.
+ ** R3 = Output parameter, either product.msh or product.lsh.
+ ** R5-R9 = Temporary registers
+ **
+ ** General Algorithm
+ **
+ ** Using PPC405 ISA instruction 'mullhw' to emulate
+ ** Note: U,V,A,B,C,D,Product are all 32-bit integers(with msh and lsh)
+ **
+ ** U.msh U.lsh
+ ** X V.msh V.lsh
+ ** ------------------------
+ ** A.msh A.lsh
+ ** B.msh B.lsh
+ ** C.msh C.lsh
+ ** D.msh D.lsh
+ ** ------------------------
+ ** Product.msw Product.lsw
+ **
+ ** __ppe42_mulhwu: Return Product.msh (unsigned)
+ ** __ppe42_mulhw: Return Product.msh (signed)
+ ** __ppe42_mullw: Return Product.lsh
+ **
+ ** Precondition Check:
+ **
+ ** if( U == 0 || V == 0 ) return P=0;
+ */
+
+/*****************************************************************************/
+
+ /*
+ ** Multiply Low Word (__ppe42_mullw)
+ **
+ ** r5 = U[16:31] or U.lsh | r5 = r3 & 0xffff
+ ** r3 = U[0:15] or U.msh | r3 = r3 >> 16 (r3 OW)
+ ** r6 = V[16:31] or V.lsh | r6 = r4 & 0xffff
+ ** r4 = V[0:15] or V.msh | r4 = r4 >> 16 (r4 OW)
+ **
+ ** B = U.msh * V.lsh | r3 = r3 * r6 (r3 OW)
+ ** B = B << 16 | r3 = r3 << 16
+ ** C = U.lsh * V.msh | r4 = r5 * r4 (r4 OW)
+ ** C = C << 16 | r4 = r4 << 16
+ ** A = U.lsh * V.lsh | r5 = r5 * r6 (r5 OW, r6 FU)
+ ** A = A + B | r5 = r5 + r3 (r3 FU)
+ ** P = A + C | r5 = r5 + r4 (r4 FU)
+ **
+ ** Return P(r3=r5) as Product.lsw
+ **
+ ** Note: there is no overflow case with this function
+ */
+
+ .align 2
+ .global __ppe42_mullw
+ .type __ppe42_mullw, @function
+
+__ppe42_mullw:
+
+ stwu %r1, -0x28(%r1) // allocate stack frame
+
+ stvd %d4, 0x08(%r1) // save off r4 & r5 in stack
+ stvd %d6, 0x10(%r1) // save off r6 & r7 in stack
+ stvd %d8, 0x18(%r1) // save off r8 & r9 in stack
+
+ mfcr %r5 // save off cr
+ stw %r5, 0x20(%r1) // store cr in stack
+
+ li %r5, 0 // r5 = 0
+ cmpwibc 1, 2, %r3, 0, __ppe42_mullw_ret // U=0 -> ret
+ cmpwibc 1, 2, %r4, 0, __ppe42_mullw_ret // V=0 -> ret
+
+ extrwi %r5, %r3, 16, 16
+ srwi %r3, %r3, 16
+ extrwi %r6, %r4, 16, 16
+ srwi %r4, %r4, 16
+
+ mullhwu %r3, %r3, %r6
+ slwi %r3, %r3, 16
+
+ mullhwu %r4, %r5, %r4
+ slwi %r4, %r4, 16
+
+ mullhwu %r5, %r5, %r6
+ add %r5, %r5, %r3
+ add %r5, %r5, %r4
+
+__ppe42_mullw_ret:
+
+ mr %r3, %r5 // put return value to r3
+
+ lwz %r5, 0x20(%r1) // load cr from stack
+ mtcr0 %r5 // restore cr
+
+ lvd %d4, 0x08(%r1) // restore r4 & r5 from stack
+ lvd %d6, 0x10(%r1) // restore r6 & r7 from stack
+ lvd %d8, 0x18(%r1) // restore r8 & r9 from stack
+
+ lwz %r1, 0(%r1) // restore stack pointer
+
+ blr
+
+ .size __ppe42_mullw, .-__ppe42_mullw
+
+
diff --git a/src/ppe/tools/ppetracepp/Makefile b/src/ppe/tools/ppetracepp/Makefile
new file mode 100644
index 0000000..0c52586
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/Makefile
@@ -0,0 +1,36 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/ppetracepp/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+all: ppetracepp ppe2fsp
+
+ppetracepp: ppetracepp.C
+ g++ -m32 -O3 -w -g -I./ ppetracepp.C -o ppetracepp
+# g++ -O3 -w -x c++ -fPIC -g -I./ ppetracepp.C -o ppetracepp
+
+ppe2fsp: ppe2fsp.c ppe2fsp_cmd.c
+ gcc -m32 -w -g -I./ -I../../pk/trace ppe2fsp.c ppe2fsp_cmd.c -o ppe2fsp
+
+clean:
+ rm ppetracepp ppe2fsp
+
diff --git a/src/ppe/tools/ppetracepp/fsp-trace b/src/ppe/tools/ppetracepp/fsp-trace
new file mode 100755
index 0000000..1d7c30c
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/fsp-trace
Binary files differ
diff --git a/src/ppe/tools/ppetracepp/jhash.h b/src/ppe/tools/ppetracepp/jhash.h
new file mode 100755
index 0000000..a310f8d
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/jhash.h
@@ -0,0 +1,167 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/ppetracepp/jhash.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _LINUX_JHASH_H
+#define _LINUX_JHASH_H
+
+/* jhash.h: Jenkins hash support.
+ *
+ * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ *
+ * http://burtleburtle.net/bob/hash/
+ *
+ * These are the credits from Bob's sources:
+ *
+ * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+ * hash(), hash2(), hash3, and mix() are externally useful functions.
+ * Routines to test the hash are included if SELF_TEST is defined.
+ * You can use this free for any purpose. It has no warranty.
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ *
+ * I've modified Bob's hash to be useful in the Linux kernel, and
+ * any bugs present are surely my fault. -DaveM
+ */
+
+/* NOTE: Arguments are modified. */
+#define __jhash_mix(a, b, c) \
+{ \
+ a -= b; a -= c; a ^= (c>>13); \
+ b -= c; b -= a; b ^= (a<<8); \
+ c -= a; c -= b; c ^= (b>>13); \
+ a -= b; a -= c; a ^= (c>>12); \
+ b -= c; b -= a; b ^= (a<<16); \
+ c -= a; c -= b; c ^= (b>>5); \
+ a -= b; a -= c; a ^= (c>>3); \
+ b -= c; b -= a; b ^= (a<<10); \
+ c -= a; c -= b; c ^= (b>>15); \
+}
+
+/* The golden ration: an arbitrary value */
+#define JHASH_GOLDEN_RATIO 0x9e3779b9
+
+/* The most generic version, hashes an arbitrary sequence
+ * of bytes. No alignment or length assumptions are made about
+ * the input key.
+ */
+static inline u32 jhash(const void *key, u32 length, u32 initval)
+{
+ u32 a, b, c, len;
+ const u8 *k = (const u8*)key;
+
+ len = length;
+ a = b = JHASH_GOLDEN_RATIO;
+ c = initval;
+
+ while (len >= 12) {
+ a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
+ b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
+ c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
+
+ __jhash_mix(a,b,c);
+
+ k += 12;
+ len -= 12;
+ }
+
+ c += length;
+ switch (len) {
+ case 11: c += ((u32)k[10]<<24);
+ case 10: c += ((u32)k[9]<<16);
+ case 9 : c += ((u32)k[8]<<8);
+ case 8 : b += ((u32)k[7]<<24);
+ case 7 : b += ((u32)k[6]<<16);
+ case 6 : b += ((u32)k[5]<<8);
+ case 5 : b += k[4];
+ case 4 : a += ((u32)k[3]<<24);
+ case 3 : a += ((u32)k[2]<<16);
+ case 2 : a += ((u32)k[1]<<8);
+ case 1 : a += k[0];
+ };
+
+ __jhash_mix(a,b,c);
+
+ return c;
+}
+
+/* A special optimized version that handles 1 or more of u32s.
+ * The length parameter here is the number of u32s in the key.
+ */
+static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
+{
+ u32 a, b, c, len;
+
+ a = b = JHASH_GOLDEN_RATIO;
+ c = initval;
+ len = length;
+
+ while (len >= 3) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ __jhash_mix(a, b, c);
+ k += 3; len -= 3;
+ }
+
+ c += length * 4;
+
+ switch (len) {
+ case 2 : b += k[1];
+ case 1 : a += k[0];
+ };
+
+ __jhash_mix(a,b,c);
+
+ return c;
+}
+
+
+/* A special ultra-optimized versions that knows they are hashing exactly
+ * 3, 2 or 1 word(s).
+ *
+ * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
+ * done at the end is not done here.
+ */
+static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
+{
+ a += JHASH_GOLDEN_RATIO;
+ b += JHASH_GOLDEN_RATIO;
+ c += initval;
+
+ __jhash_mix(a, b, c);
+
+ return c;
+}
+
+static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
+{
+ return jhash_3words(a, b, 0, initval);
+}
+
+static inline u32 jhash_1word(u32 a, u32 initval)
+{
+ return jhash_3words(a, 0, 0, initval);
+}
+
+#endif /* _LINUX_JHASH_H */
diff --git a/src/ppe/tools/ppetracepp/ppe2fsp b/src/ppe/tools/ppetracepp/ppe2fsp
new file mode 100755
index 0000000..ea96923
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/ppe2fsp
Binary files differ
diff --git a/src/ppe/tools/ppetracepp/ppe2fsp.c b/src/ppe/tools/ppetracepp/ppe2fsp.c
new file mode 100755
index 0000000..5613adc
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/ppe2fsp.c
@@ -0,0 +1,534 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/ppetracepp/ppe2fsp.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "pk_trace.h"
+#include "ppe2fsp.h"
+#include "trac_interface.h"
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdint.h>
+
+#define TRACE_BUF_VERSION 0x01 /*!< Trace buffer version */
+#define TRACE_FIELDTRACE 0x4654 /*!< Field Trace - "FT" */
+#define TRACE_FIELDBIN 0x4644 /*!< Binary Field Trace - "FD" */
+
+#define TRAC_TIME_REAL 0 // upper 32 = seconds, lower 32 = nanoseconds
+#define TRAC_TIME_50MHZ 1
+#define TRAC_TIME_200MHZ 2
+#define TRAC_TIME_167MHZ 3 // 166666667Hz
+
+typedef struct
+{
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+ union
+ {
+ uint8_t data[PK_TRACE_MAX_BINARY + 1]; //add 1 byte for padding
+ uint32_t parms[PK_TRACE_MAX_PARMS];
+ };
+ uint32_t size;
+}largest_fsp_entry_t;
+
+typedef struct
+{
+ union
+ {
+ uint8_t binary_data[PK_TRACE_MAX_BINARY + 1];
+ struct
+ {
+ uint8_t rsvd[(PK_TRACE_MAX_BINARY + 1) - (PK_TRACE_MAX_PARMS * sizeof(uint32_t))];
+ uint32_t parms[PK_TRACE_MAX_PARMS];
+ };
+ };
+ PkTraceEntryFooter footer;
+}LargestPpeEntry;
+
+//convert a ppe timestamp to an fsp trace timestamp
+uint64_t ppe2fsp_time(uint64_t ppe_time, uint32_t hz)
+{
+ uint32_t seconds;
+ uint32_t remainder;
+ uint32_t nseconds;
+
+ //convert from ppe ticks to seconds and nanoseconds
+ seconds = ppe_time / hz;
+ remainder = ppe_time - (((uint64_t)seconds) * hz);
+ nseconds = (((uint64_t)remainder) * 1000000000) / hz;
+ return (((uint64_t)seconds) << 32) | nseconds;
+}
+
+//Writes an fsp trace entry to the fsp trace buffer
+fsp_put_entry(trace_buf_head_t* tb, largest_fsp_entry_t* fte, size_t entry_size, uint32_t bytes_left)
+{
+ char* buffer = ((char*)tb) + sizeof(trace_buf_head_t);
+ char* tb_start;
+ char* fte_start;
+ uint32_t copy_bytes;
+
+ if(entry_size <= bytes_left)
+ {
+ tb_start = buffer + bytes_left - entry_size;
+ fte_start = (char*)fte;
+ copy_bytes = entry_size;
+ }
+ else
+ {
+ tb_start = buffer;
+ fte_start = ((char*)fte) + (entry_size - bytes_left);
+ copy_bytes = bytes_left;
+ }
+
+ memcpy(tb_start, fte_start, copy_bytes);
+}
+
+
+//convert a ppe trace entry to an fsp trace entry
+size_t pte2fte(PkTraceBuffer* ptb,
+ LargestPpeEntry* pte,
+ size_t pte_size,
+ largest_fsp_entry_t* fte,
+ uint64_t ppe_time64)
+{
+ size_t entry_size;
+ PkTraceGeneric* pte_footer = &pte->footer.generic;
+ uint32_t format;
+ uint32_t hash32;
+ uint32_t hash32_partial;
+ uint32_t* parm_start;
+ uint32_t parm_bytes;
+ uint64_t fsp_time64;
+
+ //convert the ppe trace time to an fsp trace time
+ fsp_time64 = ppe2fsp_time(ppe_time64, ntohl(ptb->hz));
+
+ //fill in the 64 bit timestamp
+ fte->stamp.tbh = htonl((uint32_t)(fsp_time64 >> 32));
+ fte->stamp.tbl = htonl((uint32_t)(fsp_time64 & 0x00000000ffffffffull));
+
+ //use the ppe instance id as the thread id.
+ fte->stamp.tid = htonl((uint32_t)ntohs(ptb->instance_id));
+
+ //merge the hash prefix and the string_id fields together for a 32 bit hash value
+ hash32 = ((uint32_t)ntohs(ptb->hash_prefix)) << 16;
+ hash32 |= pte_footer->string_id;
+ fte->head.hash = htonl(hash32);
+
+ //generate the 32bit hash value for a partial trace entry in case it's needed
+ hash32_partial = ((uint32_t)ntohs(ptb->hash_prefix)) << 16;
+ hash32_partial |= ntohs(ptb->partial_trace_hash);
+
+ //set the line number to 1
+ fte->head.line = htonl(1);
+
+ //determine the FSP trace format
+ format = PK_GET_TRACE_FORMAT(pte_footer->time_format.word32);
+ if(format == PK_TRACE_FORMAT_BINARY)
+ {
+ fte->head.tag = htons(TRACE_FIELDBIN);
+ }
+ else
+ {
+ fte->head.tag = htons(TRACE_FIELDTRACE);
+ }
+
+ parm_start = (uint32_t*)(((char*)pte) + (sizeof(LargestPpeEntry) - pte_size));
+
+ //fill in the parameters/binary data and size at the end
+ switch(format)
+ {
+
+ case PK_TRACE_FORMAT_TINY:
+ //one or 0 parameters
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = htonl((uint32_t)(pte_footer->parm16));
+ fte->head.length = htons(sizeof(uint32_t));
+ parm_bytes = 0;
+ break;
+
+ case PK_TRACE_FORMAT_BIG:
+ //1 - 4 parameters
+ //
+ //If the trace entry data is incomplete (not all parm data
+ //had been written at the time the trace was captured) then
+ //we will write a trace to the fsp buffer that says
+ //"PARTIAL TRACE ENTRY. HASH_ID = %d"
+ if(pte_footer->complete)
+ {
+ parm_bytes = pte_footer->bytes_or_parms_count * sizeof(uint32_t);
+ fte->head.length = htons(parm_bytes + sizeof(uint32_t));
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ parm_bytes + sizeof(uint32_t);
+ }
+ else
+ {
+ parm_bytes = 0;
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = fte->head.hash; //already corrected for endianess
+ fte->head.hash = htonl(hash32_partial);
+ fte->head.length = htons(sizeof(uint32_t));
+ }
+ break;
+
+ case PK_TRACE_FORMAT_BINARY:
+ //If the trace entry data is incomplete (not all parm data
+ //had been written at the time the trace was captured) then
+ //we will write a trace to the fsp buffer that says
+ //"PARTIAL TRACE ENTRY. HASH_ID = %d"
+ if(pte_footer->complete)
+ {
+ parm_bytes = pte_footer->bytes_or_parms_count;
+ fte->head.length = htons((uint16_t)parm_bytes);
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ parm_bytes;
+
+ //pad to 4 byte boundary
+ entry_size = (entry_size + 3) & ~3;
+ }
+ else
+ {
+ parm_bytes = 0;
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = fte->head.hash;
+ fte->head.hash = htonl(hash32_partial);
+ fte->head.length = htons(sizeof(uint32_t));
+ fte->head.tag = htons(TRACE_FIELDTRACE);
+ }
+ break;
+
+
+ default:
+ entry_size = 0;
+ parm_bytes = 0;
+ break;
+ }
+
+ //copy parameter bytes to the fsp entry if necessary
+ if(parm_bytes)
+ {
+ memcpy(fte->data, parm_start, parm_bytes);
+ }
+
+ //add the entry size to the end
+ if(entry_size)
+ {
+ uint32_t new_entry_size = entry_size + sizeof(uint32_t);
+ *((uint32_t*)(((char*)fte) + entry_size)) = htonl(new_entry_size);
+ entry_size = new_entry_size;
+ }
+
+ return entry_size;
+}
+
+//retrieve a ppe trace entry from a ppe trace buffer
+size_t ppe_get_entry(PkTraceBuffer* tb, uint32_t offset, LargestPpeEntry* pte)
+{
+ uint32_t mask = ntohs(tb->size) - 1;
+ PkTraceEntryFooter* footer;
+ size_t entry_size;
+ size_t parm_size;
+ char* dest = (char*)pte;
+ uint32_t format;
+ uint32_t start_index;
+ uint32_t bytes_left;
+ uint32_t bytes_to_copy;
+
+ //Find the footer in the circular buffer
+ footer = (PkTraceEntryFooter*)(&tb->cb[(offset - sizeof(PkTraceEntryFooter)) & mask]);
+
+ //always correct endianess for the time and string id words
+ pte->footer.generic.time_format.word32 = ntohl(footer->generic.time_format.word32);
+ pte->footer.generic.string_id = ntohs(footer->generic.string_id);
+
+ //only need to byte swap the parm16 value if this is a tiny format
+ pte->footer.generic.parm16 = footer->generic.parm16;
+
+ //use footer data to determine the length of the binary data or parameters
+ format = PK_GET_TRACE_FORMAT(pte->footer.generic.time_format.word32);
+ switch(format)
+ {
+ case PK_TRACE_FORMAT_TINY:
+ pte->footer.generic.parm16 = ntohs(pte->footer.generic.parm16);
+ parm_size = 0;
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ case PK_TRACE_FORMAT_BIG:
+ parm_size = pte->footer.generic.bytes_or_parms_count * sizeof(uint32_t);
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ case PK_TRACE_FORMAT_BINARY:
+ parm_size = pte->footer.generic.bytes_or_parms_count;
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ default:
+ entry_size = 0;
+ parm_size = 0;
+ break;
+ }
+
+ //pad to 8 byte boundary
+ parm_size = (parm_size + 7) & ~0x00000007ul;
+
+ //add the parameter size to the total entry size
+ entry_size += parm_size;
+
+ //copy the entry from the circular buffer to pte
+ start_index = (offset - entry_size) & mask;
+ bytes_left = ntohs(tb->size) - start_index;
+
+ //only copy up to the end of the circular buffer
+ if(parm_size < bytes_left)
+ {
+ bytes_to_copy = parm_size;
+ }
+ else
+ {
+ bytes_to_copy = bytes_left;
+ }
+
+ dest += sizeof(LargestPpeEntry) - entry_size;
+ memcpy(dest, &tb->cb[start_index], bytes_to_copy);
+
+ //now copy the rest of the data starting from the beginning of the
+ //circular buffer.
+ if(bytes_to_copy < parm_size)
+ {
+ memcpy(dest + bytes_to_copy, tb->cb, parm_size - bytes_to_copy);
+ }
+
+ //return the size of the entry
+ return entry_size;
+}
+
+//convert a ppe trace buffer to an fsp trace buffer
+int ppe2fsp(void* in, unsigned long in_size, void* out, unsigned long* io_size)
+{
+ PkTraceBuffer* ptb = (PkTraceBuffer*)in;
+ trace_buf_head_t* ftb = (trace_buf_head_t*)out;
+ uint32_t ppe_bytes_left;
+ uint32_t fsp_bytes_left;
+ int rc = 0;
+ uint32_t ptb_offset;
+ PkTraceEntryFooter* ptb_te;
+ uint64_t ppe_time64;
+ uint32_t fte_size, pte_size;
+ uint32_t fsp_te_count = 0;
+ uint32_t time_diff32, prev_time32, new_time32;
+ PkTraceGeneric* pte_footer;
+ largest_fsp_entry_t fte;
+ LargestPpeEntry pte;
+ uint64_t time_adj64;
+
+ do
+ {
+ if(!ptb || !ftb || !io_size)
+ {
+ rc = P2F_NULL_POINTER;
+ break;
+ }
+
+ if(ntohs(ptb->version) != PK_TRACE_VERSION)
+ {
+ rc = P2F_INVALID_VERSION;
+ break;
+ }
+
+ //check that the input buffer is large enough to have a ppe trace buffer
+ if(in_size < (((uint32_t)(&ptb->cb[0])) - (uint32_t)(ptb)))
+ {
+ rc = P2F_INPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ //initialize some locals
+ fsp_bytes_left = *io_size - sizeof(trace_buf_head_t);
+ ppe_bytes_left = ntohs(ptb->size);
+ ptb_offset = ntohl(ptb->state.offset);
+ if(htonl(1) == 1)
+ {
+ time_adj64 = ptb->time_adj64;
+ }
+ else
+ {
+ time_adj64 = ntohl((uint32_t)(ptb->time_adj64 >> 32));
+ time_adj64 |= ((uint64_t)(ntohl((uint32_t)(ptb->time_adj64 & 0x00000000ffffffff)))) << 32;
+ }
+
+ //make sure the ppe buffer size is a power of two
+ if((ppe_bytes_left - 1) & ppe_bytes_left)
+ {
+ //size is not a power of two
+ rc = P2F_INVALID_INPUT_SIZE;
+ break;
+ }
+
+ //The ppe bytes field should always be a multiple of 8
+ if(ptb_offset & 0x7)
+ {
+ rc = P2F_INVALID_PPE_OFFSET;
+ break;
+ }
+
+ //make sure there is enough room for the fsp header
+ if(*io_size < sizeof(trace_buf_head_t))
+ {
+ rc = P2F_OUTPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+
+
+ //initialize the fsp header
+ ftb->ver = TRACE_BUF_VERSION;
+ ftb->hdr_len = sizeof(trace_buf_head_t);
+ ftb->time_flg = TRAC_TIME_REAL;
+ ftb->endian_flg = 'B'; //big endian
+ memcpy(ftb->comp, ptb->image_str, sizeof(ftb->comp));
+ ftb->times_wrap = htonl(1);
+ ftb->size = htonl(sizeof(trace_buf_head_t) + sizeof(uint32_t));
+ ftb->next_free = htonl(sizeof(trace_buf_head_t));
+ ftb->extracted = htonl(0);
+ ftb->te_count = htonl(0);
+
+ //find the latest timestamp so that we can work back from there
+ ppe_time64 = ((uint64_t)(ntohl(ptb->state.tbu32) & 0xefffffff)) << 32;
+ pte_size = ppe_get_entry(ptb, ptb_offset, &pte);
+ prev_time32 = PK_GET_TRACE_TIME(pte.footer.generic.time_format.word32);
+ ppe_time64 |= prev_time32;
+
+ //process all of the input bytes one trace entry at a time
+ //from newest to oldest (backwards) until we run out of input bytes or
+ //we run out of output space.
+ while(1)
+ {
+ //check if we have enough data for a ppe footer
+ if(ppe_bytes_left < sizeof(PkTraceEntryFooter))
+ {
+ break;
+ }
+
+ //get the next ppe entry
+ pte_size = ppe_get_entry(ptb, ptb_offset, &pte);
+
+ //Stop if there are no more entries to retrieve from the ppe trace buffer
+ if(!pte_size)
+ {
+ break;
+ }
+ pte_footer = &pte.footer.generic;
+
+ //mark the entry as incomplete if we didn't have enough data
+ //for the entire entry
+ if(pte_size > ppe_bytes_left)
+ {
+ pte_footer->complete = 0;
+ ppe_bytes_left = 0;
+ }
+ else
+ {
+ ppe_bytes_left -= pte_size;
+ ptb_offset -= pte_size;
+ }
+
+ //Calculate the 64 bit timestamp for this entry....
+ //On PPE, getting the timestamp is not done atomically with writing
+ //the entry to the buffer. This means that an entry with an older
+ //timestamp could possibly be added to the buffer after an entry
+ //with a newer timestamp. Detect this condition by checking if the
+ //time difference is bigger than the max difference. The max
+ //difference is enforced by the PPE having a trace added on a
+ //shorter time boundary (using a timer).
+ new_time32 = PK_GET_TRACE_TIME(pte_footer->time_format.word32);
+ time_diff32 = prev_time32 - new_time32;
+
+ if(time_diff32 > ntohl(ptb->max_time_change))
+ {
+ time_diff32 = new_time32 - prev_time32;
+ ppe_time64 += time_diff32;
+ }
+ else
+ {
+ ppe_time64 -= time_diff32;
+ }
+
+ //save off the lower 32bit timestamp for the next iteration
+ prev_time32 = new_time32;
+
+ //convert the ppe trace entry to an fsp trace entry
+ fte_size = pte2fte(ptb, &pte, pte_size, &fte, ppe_time64 + time_adj64);
+
+ //fit as much of the entry into the fsp trace buffer as possible
+ fsp_put_entry(ftb, &fte, fte_size, fsp_bytes_left);
+
+ //update the fsp trace entry count
+ fsp_te_count++;
+
+ //stop if there is no more room left in the fsp trace buffer
+ if(fte_size >= fsp_bytes_left)
+ {
+ fsp_bytes_left = 0;
+ ftb->times_wrap = htonl(1);
+ break;
+ }
+ else
+ {
+ fsp_bytes_left -= fte_size;
+ }
+ }//while(1)
+
+
+ //shift the trace data up if there is space to do so
+ if(fsp_bytes_left)
+ {
+ char* dest = ((char*)ftb) + sizeof(trace_buf_head_t);
+ char* src = dest + fsp_bytes_left;
+ size_t data_size = *io_size - sizeof(trace_buf_head_t) - fsp_bytes_left;
+ memmove(dest, src, data_size);
+ }
+
+ //update the fsp header to reflect the true size and entry count
+ ftb->te_count = htonl(fsp_te_count);
+
+ //inform the caller of how many bytes were actually used
+ *io_size -= fsp_bytes_left;
+
+ //shrink the size field to what we actually ended up using
+ ftb->size = htonl(*io_size);
+
+ }while(0);
+
+ return rc;
+}
+
+
+
diff --git a/src/ppe/tools/ppetracepp/ppe2fsp.h b/src/ppe/tools/ppetracepp/ppe2fsp.h
new file mode 100644
index 0000000..d2065be
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/ppe2fsp.h
@@ -0,0 +1,34 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/ppetracepp/ppe2fsp.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+
+#define P2F_NULL_POINTER 1
+#define P2F_INVALID_INPUT_SIZE 2
+#define P2F_INVALID_PPE_OFFSET 3
+#define P2F_OUTPUT_BUFFER_TOO_SMALL 4
+#define P2F_INPUT_BUFFER_TOO_SMALL 5
+#define P2F_INVALID_VERSION 6
+
+int ppe2fsp(void* in, unsigned long in_size, void* out, unsigned long* io_size);
diff --git a/src/ppe/tools/ppetracepp/ppe2fsp_cmd.c b/src/ppe/tools/ppetracepp/ppe2fsp_cmd.c
new file mode 100644
index 0000000..8846a9b
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/ppe2fsp_cmd.c
@@ -0,0 +1,139 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/ppetracepp/ppe2fsp_cmd.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdio.h>
+#include "ppe2fsp.h"
+#include "pk_trace.h"
+
+#define MAX_INPUT_SIZE 0x2040 //8k
+#define MAX_OUTPUT_SIZE (4 * MAX_INPUT_SIZE)
+
+char* inbuf[MAX_INPUT_SIZE];
+char* outbuf[MAX_OUTPUT_SIZE];
+;
+int main(int argc, char** argv)
+{
+ FILE* in;
+ FILE* out;
+ size_t input_size;
+ size_t output_size;
+ size_t bytes_written;
+ int rc = -1;
+
+ do
+ {
+ if(argc > 3)
+ {
+ fprintf(stderr, "Usage: %s [input file] [output file]\n", argv[0]);
+ }
+
+ if(argc < 3)
+ {
+ out = stdout;
+ }
+ else
+ {
+ //open the output file for writing
+ out = fopen(argv[2], "w");
+ if(!out)
+ {
+ perror("failed to open file for writing");
+ break;
+ }
+ }
+
+ if(argc < 2)
+ {
+ in = stdin;
+ }
+ else
+ {
+ //open the input file for reading
+ in = fopen(argv[1], "r");
+ if(!in)
+ {
+ perror("failed to open file for reading");
+ break;
+ }
+ }
+
+ //read the input stream until we reach EOF or the max size
+ input_size = fread(inbuf, 1, MAX_INPUT_SIZE, in);
+ if(!feof(in))
+ {
+ if(ferror(in))
+ {
+ perror("failed to read input file");
+ break;
+ }
+ else
+ {
+ fprintf(stderr, "Input stream exceeds max size of %d bytes. Exiting.\n", MAX_INPUT_SIZE);
+ break;
+ }
+ }
+
+ output_size = MAX_OUTPUT_SIZE;
+
+ //Actual size of output buffer will be set upon successful completion
+ rc = ppe2fsp(inbuf, input_size, outbuf, &output_size);
+ if(rc)
+ {
+ fprintf(stderr, "Failed converting ppe trace to fsp trace. rc = %d\n", rc);
+ if(rc == P2F_INVALID_VERSION)
+ {
+ fprintf(stderr, "PPE trace buffer must be version %d.\n", PK_TRACE_VERSION);
+ }
+ break;
+ }
+
+ rc = -1;
+ //operation was successful. Write out the fsp trace data
+ bytes_written = fwrite(outbuf, 1, output_size, out);
+ if(bytes_written != output_size)
+ {
+ if(ferror(out))
+ {
+ perror("Failed to write output stream");
+ break;
+ }
+ fprintf(stderr, "Failure: Only able to write %d of %d bytes to output stream\n", bytes_written, output_size);
+ break;
+ }
+
+ fclose(in);
+ fclose(out);
+ fclose(stderr);
+
+ rc = 0;
+ }while(0);
+
+ return rc;
+}
+
+
+
+
+
+
diff --git a/src/ppe/tools/ppetracepp/ppetracepp b/src/ppe/tools/ppetracepp/ppetracepp
new file mode 100755
index 0000000..61b5f04
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/ppetracepp
Binary files differ
diff --git a/src/ppe/tools/ppetracepp/ppetracepp.C b/src/ppe/tools/ppetracepp/ppetracepp.C
new file mode 100755
index 0000000..c36cf35
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/ppetracepp.C
@@ -0,0 +1,946 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/ppetracepp/ppetracepp.C $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/*
+# *** ppetracepp - a fsp/common Linux trace pre processor
+# this one replaces the trace strings by the corresponding hash value
+# (i.e. the complete call to trace_ppe_hash is replaced)
+
+# *** Usage
+#
+# prepend compiler call with the call of this pre processor, i.e if you have
+# $(CC) $(CFLAGS) -o $@ $<
+# in your Makefile change it to this:
+# ppetracepp $(CC) $(CFLAGS) -o $@ $<
+# ppetracepp will use "$(CC) -E" to call the C pre processor "cpp".
+# you can set a env var "REALCPP" to the name of a program to select
+# a different programm as cpp
+#
+# ppetracepp creates a file "$target.ppe.hash" with the trace strings and the hash values.
+#
+# to enable debug mode set envvar PPETRACEPPDEBUG to 1 or give '-d' as first arg
+
+# *** Change History
+#
+# 2003-02-26 RBa created from scratch
+# 2003-02-28 RBa add C++ support (C++ interface uses own type for the hash)
+# 2003-05-28 RBa if cc should link instead of compile just call compiler
+# 2003-07-11 AGe Change search alg. slightly and put just format back
+# 2003-07-25 RBa just call gcc if called to link instead to compile
+# eat argument for option -x
+# 2003-11-26 RBa fix c/c++ algo: compile as c++ if realcc=*g++
+# 2004-02-02 RBa remove explicit test whether source file is readable
+# it is obsolete and might lead to an error if afs is used
+# 2004-02-13 RBa add support for dependency generation (-MD/-MG, -MF)
+# don't prepend './' to object filename
+# 2006-04-19 RBa rewrite trace_ppe_write_all support, handle C and C++ the same
+# 2006-05-24 RBa fix handling of missing -o ; add TRAC_PPVER for macro/API version
+# 2006-09-15 RBa add handling of \" in trace format strings ; reduce non-error output
+# put object file in current dir if no -o given
+# 2007-03-22 RBa handle more gcc options (-i) ; protect " in call to shell
+# store output of cpp as "unmodified" output for debug
+# only write string/hash file if strings found
+# 2012-09-24 hlava Rewritten as C program for better build performance (was perl)
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <fcntl.h>
+#include <map>
+#include <vector>
+
+#include <sys/types.h>
+typedef u_int32_t u32 ;
+typedef u_int8_t u8 ;
+#include <jhash.h>
+
+using namespace std;
+
+static string version = "2.0";
+static string macro_version = "1";
+
+static bool debug = false;
+#define dprintf(format, ...) if (debug) { printf(format, ##__VA_ARGS__); fflush(stdout); }
+static map<string,string> hashtab;
+static string hashtype;
+static string hashtype_suffix;
+
+static string tmp;
+static string cmd;
+static FILE* CPP = NULL; // pipe from preprocessor
+static FILE* CC = NULL; // pipe to compiler
+static FILE* DEBUG = NULL;
+static FILE* DEBUGIN = NULL;
+
+//*****************************************************************************
+// replace_substr
+//*****************************************************************************
+void replace_substr(std::string& str, const std::string& oldStr, const std::string& newStr)
+{
+ size_t pos = 0;
+ while((pos = str.find(oldStr, pos)) != std::string::npos)
+ {
+ str.replace(pos, oldStr.length(), newStr);
+ pos += newStr.length();
+ }
+
+}
+
+//*****************************************************************************
+// fileparse
+//*****************************************************************************
+void fileparse(const string& in_str, string& name, string& dir, string& suff)
+{
+ string str(in_str);
+ size_t pos;
+ name = "";
+ dir = "";
+ suff = "";
+ pos = str.find_last_of('.');
+ if (pos != string::npos)
+ {
+ suff = str.substr(pos);
+ str = str.substr(0, pos);
+ }
+ pos = str.find_last_of('/');
+ if (pos != string::npos)
+ {
+ name = str.substr(pos+1);
+ str = str.substr(0, pos+1);
+ }
+ dir = str;
+}
+
+static const size_t TRACE_PPE_HASH_LEN = 13;
+//*****************************************************************************
+// chop_up_line
+//*****************************************************************************
+bool chop_up_line(string& in_line, string& prefix, string& strings, string& salt, string& suffix)
+{
+ // First see if this line matches the pattern we're looking for
+ // Since this will return false 95%+ of the time this function it called, we do it
+ // before doing any other init for performance reasons.
+ size_t pos = in_line.find("trace_ppe_hash");
+ if (pos == string::npos) { return(false); }
+
+ // trace_ppe_hash ( "..." ".." "..." , 2 )
+ // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX
+ // STRINGS: '"' .* '"' space? +
+
+ // Original perl magic incantation:
+ // while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) {
+ // ($prefix, $strings, $salt, $suffix) = ($1, $2, $4, $5);
+ //
+ // Decrypting the magic pattern matching...
+ // (.*?) => $1 = everything up to the word "trace_ppe_hash"
+ // trace_ppe_hash = delimiter
+ // \s*\(\s* = delimiter = <0-n whitespace chars>, left paren, <0-n whitespace chars>
+ // ((".*?(?<!\\)"\s*)+) => $2 = double-quote, some chars up to last closing double-quote ($3 used for nested regex)
+ // ,\s* = delimiter = comma followed by some whitespace
+ // (-?\d+)\s*\)(.*) => $4 and $5
+ // $/) = end of the line input string
+ string line(in_line);
+ prefix = "";
+ strings = "";
+ salt = "";
+ suffix = "";
+ size_t pos1;
+ size_t pos2;
+ size_t pos3;
+
+ pos1 = pos + 14; // pos1 = after "trace_ppe_hash"
+ pos2 = line.find("(", pos1);
+ if (pos2 == string::npos) { return(false); }
+ ++pos2;
+ pos3 = line.find("\"", pos2);
+ if (pos3 == string::npos) { return(false); }
+ dprintf("--------\nchop_up_line: Passed basic checks. line= %s\n", line.c_str());
+ dprintf("pos1=%d, pos2=%d, pos3=%d\n", pos1, pos2, pos3);
+ if ((pos1 != (pos2-1)) && (line.find_first_not_of(" \t", pos1, (pos2-pos1)+1) != string::npos)) { return(false); } //non-whitespace?
+ if ((pos2 != pos3) && (line.find_first_not_of(" \t", pos2, (pos3-pos2)) != string::npos)) { return(false); } //non-whitespace?
+
+ // Get the prefix data
+ dprintf(">chop_up_line(\"%s\",...)\n", line.c_str());
+ prefix = line.substr(0, pos);
+ line = line.substr(pos + TRACE_PPE_HASH_LEN);
+ dprintf(" prefix=\"%s\"\n", prefix.c_str());
+
+ // Get the strings and join/fix them: Store all strings between paired double-quotes up to the
+ // first comma not inside a string
+ pos = line.find_first_of('(');
+ if (pos == string::npos) { return(false); }
+ line = line.substr(pos + 1);
+ strings = "";
+ while(!line.empty())
+ {
+ pos = line.find_first_of(',');
+ pos1 = line.find_first_of('"');
+ if ((pos1 == string::npos) || ((pos != string::npos) && (pos < pos1))) { break; } // found comma before next quote
+ pos2 = line.find_first_of('"', (pos1+1));
+ if (pos2 == string::npos) { return(false); } // unbalanced quotes!
+ while(line[pos2-1] == '\\') // skip escaped quotes in the string (they're not the ending quote)
+ {
+ pos2 = line.find_first_of('"', (pos2+1));
+ if (pos2 == string::npos) { return(false); } // unbalanced quotes!
+ }
+ if (!strings.empty()) { strings += " "; }
+ strings += line.substr(pos1, (pos2-pos1)+1);
+ line = line.substr(pos2+1);
+ }
+ replace_substr(strings, "\" \"", "");
+ replace_substr(strings, "\\\"", "ESCAPEDQUOTE");
+ replace_substr(strings, "\"", "");
+ replace_substr(strings, "ESCAPEDQUOTE", "\"");
+ // Remove trailing whitespace ah20130717
+ pos = strings.find_last_not_of(" \t\n");
+ if ((pos != string::npos) && (pos < (strings.length()-1)))
+ {
+ strings = strings.substr(0, pos+1);
+ }
+
+ dprintf(" strings>%s<\n", strings.c_str());
+
+ // Get the salt
+ pos = line.find(",");
+ if (pos != string::npos) { line = line.substr(pos+1); }
+ pos = line.find_first_of(')');
+ if (pos == string::npos) { return(false); }
+ salt = line.substr(0, pos);
+ line = line.substr(pos+1);
+ //dprintf(" salt=\"%s\"\n", salt.c_str());
+ pos = salt.find_first_not_of(" \t\n");
+ if (pos == string::npos) { return(false); }
+ salt = salt.substr(pos);
+ pos = salt.find_last_not_of(" \t\n");
+ if (pos == string::npos) { return(false); }
+ salt = salt.substr(0, pos+1);
+ dprintf(" salt=\"%s\"\n", salt.c_str());
+
+ // Get the suffix (i.e. the rest)
+ suffix = line;
+ if (suffix[suffix.length()-1] == '\n') { suffix = suffix.substr(0, suffix.length()-1); }
+ dprintf(" suffix=\"%s\"\n<chop_up_line() returning true\n", suffix.c_str());
+
+ return(true);
+}
+
+//*****************************************************************************
+// get_format_string
+//*****************************************************************************
+int get_format_string(const string& in_str, string& format)
+{
+ int format_salt = 0;
+ size_t pos;
+ size_t pos_end;
+ string str(in_str);
+ // (@format_param) = ($strings =~ /(%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn])/g);
+ // $format = join(',', @format_param);
+ // Decrypting the regular expression magic...
+ // (%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn])
+
+ format = "";
+ while(!str.empty())
+ {
+ pos = str.find("%");
+ if (pos == string::npos) { break; }
+ if (pos == (str.length()-1)) { break; } // last char in string? just skip it
+ if (str[pos+1] == '%') // double percent sign? just skip first one
+ {
+ str = str.substr(pos+1);
+ continue;
+ }
+ pos_end = str.find_first_of("cdieEfgGosuxXpn", pos); // find formatting specifier
+ if (pos_end == string::npos)
+ {
+ fprintf(stderr, "ERROR: ppetracepp could not parse trace formatting string \"%s\" in \"%s\"\n", str.c_str(), in_str.c_str());
+ break;
+ }
+
+ if (!format.empty())
+ format += ",";
+ format += str.substr(pos, (pos_end-pos)+1);
+ ++format_salt;
+
+ str = str.substr(pos_end+1);
+ }
+ // Correct for escaped percent signs
+ string temp_str(in_str);
+ while((pos = temp_str.find("%%")) != string::npos)
+ {
+ if (pos < (temp_str.length()-2)) // Not the last thing in the string?
+ {
+ dprintf(" decrementing salt value %d\n", format_salt);
+ --format_salt;
+ temp_str = temp_str.substr(pos+2);
+ }
+ else
+ {
+ temp_str = "";
+ }
+ }
+
+ return(format_salt);
+}
+
+#define BUF_SIZE 40
+//*****************************************************************************
+// get_hash
+//*****************************************************************************
+void get_hash(const string& i_str, const unsigned int salt_num, string& hash32, string& hash16)
+{
+ string str(i_str);
+ unsigned int hash_num = 0;
+ char buf[BUF_SIZE];
+
+ hash16 = "";
+ hash32 = "";
+ dprintf(">get_hash(\"%s\",%d)\n", str.c_str(), salt_num);
+
+ // Call jhash function to get the hash value
+ hash_num = jhash((void*)str.c_str(), str.length(), salt_num);
+ dprintf("jhash() returned: %u\n", hash_num);
+ sprintf(buf, "%u", hash_num & 0x0000ffff);
+ hash16 = buf;
+ sprintf(buf, "%u", ((salt_num << 16) | (hash_num & 0x0000ffff)));
+ hash32 = buf;
+
+ // validate the hash value
+ size_t pos = hash32.find_first_not_of("0123456789");
+ if (pos != string::npos)
+ {
+ fprintf(stderr, "trexhash error: %s\n", hash32.c_str());
+ fprintf(stderr, "for call <<%s>>\n", cmd.c_str());
+ exit(1);
+ }
+
+//removing this since it doesn't seem to have any affect on the output
+#if 0
+ // If hash is empty, use the sum of the ord values in the original string
+ if ((hash == "")||(hash == "0"))
+ {
+ unsigned int len = str.length();
+ unsigned int hash_num = 0;
+ //unsigned char conv_buf[2] = { '\0', '\0' };
+ u_int8_t conv_num;
+ for (unsigned int i=0; i < len; ++i)
+ {
+ //conv_buf[0] = str[i];
+ conv_num = (u_int8_t)str[i];
+ hash_num += (unsigned int)conv_num;
+ }
+ }
+#endif
+
+ dprintf("<get_hash(\"%s\",%d) returned hash: %s\n", str.c_str(), salt_num, hash32.c_str());
+}
+
+//*****************************************************************************
+// parse_line
+//*****************************************************************************
+void parse_line(map<string,string>& rhash, string& line, string& out_line)
+{
+ // NOTE: "line" arg may get modified by this function! Caller must not assume it's unchanged.
+ string format;
+ string prefix;
+ string strings;
+ string tmp;
+ string salt;
+ string hash16;
+ string hash32;
+ int salt_num;
+ int format_salt;
+ string suffix;
+ string write_all_suffix;
+ size_t pos;
+
+ out_line = "";
+ // trace_ppe_hash ( "..." ".." "..." , 2 )
+ // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX
+ // STRINGS: '"' .* '"' space? +
+ //while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) {
+ // Attempt to approximate the above amazing perl regex...
+ while( chop_up_line(line, prefix, strings, salt, suffix) )
+ {
+ //dprintf("\n\nprefix = %s\nstrings = %s\nsalt = %s\nsuffix = %s\n",
+ // prefix.c_str(), strings.c_str(), salt.c_str(), suffix.c_str());
+ // is this a trace_ppe_write_all call?
+ pos = prefix.find("trace_ppe_write_all");
+ if (pos != string::npos)
+ {
+ // yes. replace trace_ppe_hash with hash value and reduced format string
+ format_salt = get_format_string(strings, format);
+ // reduced format string will be added after hash value
+ write_all_suffix = ",\" ";
+ write_all_suffix += format;
+ write_all_suffix += "\"";
+
+ if (!salt.empty())
+ {
+ salt_num = atoi(salt.c_str());
+ }
+ else
+ {
+ salt_num = -1;
+ }
+
+ if (salt_num == -1)
+ {
+ salt_num = format_salt;
+ }
+ else if (salt_num != format_salt)
+ {
+ fprintf(stderr, "ERROR: printf mismatch in '%s': TRACE says %d, format says %d args\n",
+ line.c_str(), salt_num, format_salt);
+ }
+ }
+ else
+ {
+ write_all_suffix = "";
+ salt_num = atoi(salt.c_str());
+ }
+
+ // get the trex hash value for the strings
+ get_hash(strings, salt_num, hash32, hash16);
+
+ // check for duplicate and store the mapping
+ if ((rhash.find(hash32) != rhash.end()) && (rhash[hash32] != strings))
+ {
+ fprintf(stderr, "hash collision: two different strings give the same hash value '%s'\n", hash32.c_str());
+ fprintf(stderr, "%s\n%s\n", strings.c_str(), rhash[hash32].c_str());
+ return;
+ }
+ rhash[hash32] = strings;
+
+ // add the modified line to the output
+ tmp = prefix;
+ tmp += "(";
+ tmp += hashtype;
+ tmp += " ";
+ tmp += hash16;
+ tmp += hashtype_suffix;
+ tmp += ")";
+ tmp += write_all_suffix;
+ out_line += tmp;
+ dprintf("changed call: %s...\n", tmp.c_str());
+ line = suffix;
+ }
+ out_line += line;
+ if (out_line[out_line.length()-1] != '\n')
+ out_line += "\n";
+}
+
+//*****************************************************************************
+// main
+//*****************************************************************************
+int main(int argc, char** argv)
+{
+ char* p_env = getenv("PPETRACEPPDEBUG");
+ if (p_env)
+ debug = true;
+
+
+ int argi = 1;
+ string arg;
+ string optarg;
+ if (argc > 1) arg = argv[1];
+ if ((argc < 2) || (arg == "-h"))
+ {
+ fprintf(stderr, "usage: %s realcompiler compileroptions -o target source\n", argv[0]);
+ exit(9);
+ }
+ string realcc(argv[argi++]);
+ string cctype("c++");
+ bool optx_found = false;
+
+ if (realcc == "-d")
+ {
+ debug = true;
+ realcc = argv[argi++];
+ }
+
+ // wait until -d options is handled before checking $debug
+ dprintf("ppetracepp version %s - API/macro version %s\n", version.c_str(), macro_version.c_str());
+
+ p_env = getenv("REALCPP");
+ string realcpp;
+ if (p_env)
+ realcpp = p_env;
+ if (realcpp.empty())
+ {
+ dprintf("cannot find cpp, using <realcompiler> -E\n");
+ realcpp = realcc;
+ realcpp += " -E";
+ }
+ dprintf("realcpp is %s\n", realcpp.c_str());
+
+//------------------------------------------------------------------------------
+// parse all the arguments
+//------------------------------------------------------------------------------
+string source;
+string object;
+vector<string> ccopts;
+vector<string> cppopts;
+bool dodeps = false;
+string depfile;
+string pfx;
+string sfx;
+int origargi = argi;
+for( ; argi < argc; ++argi)
+{
+ arg = argv[argi];
+ dprintf("Processing argv[%d]: \"%s\"\n", argi, arg.c_str());
+ if (arg.length() > 2)
+ {
+ pfx = arg.substr(0,2);
+ sfx = arg.substr(arg.length()-2);
+ }
+ else
+ {
+ pfx = arg;
+ sfx = arg;
+ }
+ dprintf(" pfx: \"%s\" sfx: \"%s\"\n", pfx.c_str(), sfx.c_str());
+
+ if (pfx == "-o")
+ {
+ if (! object.empty())
+ {
+ fprintf(stderr, "two -o options, aborting\n");
+ exit(1);
+ }
+ if (arg.length() > 2)
+ {
+ object = sfx;
+ }
+ else
+ {
+ object = argv[++argi];
+ }
+ dprintf("object is now %s\n", object.c_str());
+ }
+ else if (arg == "-c")
+ {
+ // don't call cpp with -c, this is for the compiler
+ ccopts.push_back(arg);
+ dprintf("found -c option\n");
+ }
+ else if (pfx == "-l")
+ {
+ // cpp doesn't need library arguments
+ cppopts.push_back(arg);
+ }
+ else if (pfx == "-i")
+ {
+ // option takes an argument, handle it too
+ optarg = argv[argi++];
+ ccopts.push_back(arg);
+ ccopts.push_back(optarg);
+ cppopts.push_back(arg);
+ cppopts.push_back(optarg);
+ dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str());
+ }
+ else if ((arg == "-L") ||
+ (arg == "-I") ||
+ (arg == "-x") ||
+ (arg == "-b") ||
+ (arg == "-B") ||
+ (arg == "-V") ||
+ (arg == "-D") ||
+ (arg == "--param") ||
+ (arg == "-MQ") ||
+ (arg == "-MT"))
+ {
+ // option takes an argument, handle it too
+ optarg = argv[argi++];
+ ccopts.push_back(arg);
+ ccopts.push_back(optarg);
+ cppopts.push_back(arg);
+ cppopts.push_back(optarg);
+ dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str());
+ if (arg == "-x")
+ {
+ // option x sets the language - c or c++
+ if ((optarg != "c") && (optarg != "c++") && (optarg != "assembler-with-cpp"))
+ {
+ fprintf(stderr, "cannot process language '%s', aborting\n", optarg.c_str());
+ exit(1);
+ }
+ cctype = optarg;
+ optx_found = true;
+ }
+ }
+ else if ((arg == "-MD")||(arg == "-MG"))
+ {
+ // gen deps
+ dodeps = true;
+ dprintf("found %s, creating dependencies\n", arg.c_str());
+ }
+ else if (arg == "-MF")
+ {
+ // set dependencies file
+ depfile = argv[argi++];
+ dprintf("set dependencies file to '%s'\n", depfile.c_str());
+ }
+ else if (arg[0] == '-')
+ {
+ // arg starts with - so it's an option
+ ccopts.push_back(arg);
+ cppopts.push_back(arg);
+ dprintf("found option '%s'\n", arg.c_str());
+ }
+ else if ((sfx == ".a") ||
+ (sfx == ".o"))
+ {
+ // an object or archive, ignore this but give it to cc
+ ccopts.push_back(arg);
+ dprintf("found object/archive '%s'\n", arg.c_str());
+ }
+ else if ((sfx == ".c") ||
+ (sfx == ".C") ||
+ (sfx == ".S") ||
+ (arg.substr(arg.length()-4) == ".cpp") ||
+ (arg.substr(arg.length()-4) == ".cxx"))
+ {
+ // the source file(s). we should only get one
+ if (!source.empty())
+ {
+ fprintf(stderr, "don't know to handle two source files, aborting\n");
+ exit(1);
+ }
+ source = arg;
+ // put the - (for read-from-stdin) where the source file was
+ // (order is important!)
+ ccopts.push_back("-");
+ dprintf("found source file %s\n", source.c_str());
+ }
+ else if (access(arg.c_str(), F_OK))
+ {
+ // option but not a file, an unknown option?
+ ccopts.push_back(arg);
+ cppopts.push_back(arg);
+ dprintf("found unknown option '%s'\n", arg.c_str());
+ }
+}
+
+//------------------------------------------------------------------------------
+// set other parameters based on arguments specified
+//------------------------------------------------------------------------------
+if (source.empty())
+{
+ // this might be a call to link a program instead of compile a source (or asm source)
+ dprintf("NOTME: starting as cc '%s ...'\n", realcc.c_str());
+ execvp(realcc.c_str(), &(argv[origargi]));
+ fprintf(stderr, "ERROR: returned from execvp() call to run %s\n", realcc.c_str());
+}
+if (object.empty())
+{
+ dprintf("no object file given, default to source name\n");
+ // gcc builds object name from source name if no -o given, replacing
+ // suffix with .o. The file is placed in the current directory,
+ // not in the source directory!
+ string n;
+ string d;
+ string s;
+ fileparse(source, n, d, s);
+ if (!n.empty() && !s.empty())
+ {
+ object = n + ".o";
+ dprintf("tracpp: guessing object name %s\n", object.c_str());
+ dprintf(" from source name %s\n", source.c_str());
+ }
+ else
+ {
+ fprintf(stderr, "Unable to determine Source File Name\n");
+ exit(1);;
+ }
+}
+
+// set value of trace hash according to language
+// check source file extension if no explicit -x option given
+if (!optx_found)
+{
+ if (realcc.find("g++") != string::npos)
+ {
+ dprintf("compiler language: C++ (from compiler name)\n");
+ cctype = "c++";
+ }
+ else
+ {
+ if (source.substr(source.length()-2) == ".c")
+ {
+ dprintf("compiler language: C (from source file extension)\n");
+ cctype = "c";
+ }
+ else if (source.substr(source.length()-2) == ".S")
+ {
+ dprintf("compiler language: assembly (from source file extension)\n");
+ cctype = "assembler-with-cpp";
+ }
+ else
+ {
+ dprintf("compiler language: C++ (default)\n");
+ cctype = "c++";
+ }
+ }
+}
+else
+{
+ dprintf("compiler language: %s (from option '-x')\n", cctype.c_str());
+}
+
+if (cctype == "c")
+{
+ hashtype = "(unsigned short)";
+ hashtype_suffix = "U";
+}
+else if (cctype == "assembler-with-cpp")
+{
+ hashtype = "";
+ hashtype_suffix = "";
+}
+else
+{
+ hashtype = "(trace_hash_val)";
+ hashtype_suffix = "U";
+}
+// define TRAC_PPETRACEPP for macros
+tmp = "-DTRAC_PPETRACEPP -DTRAC_PPVER=";
+tmp += macro_version;
+cppopts.push_back(tmp);
+if (dodeps)
+{
+ if (depfile.empty())
+ {
+ if ((p_env = getenv("DEPENDENCIES_OUTPUT")) != NULL)
+ {
+ depfile = p_env;
+ }
+ else if ((p_env = getenv("SUNPRO_DEPENDENCIES")) != NULL)
+ {
+ depfile = p_env;
+ }
+ else
+ {
+ depfile = object;
+ if (depfile.substr(depfile.length()-2) == ".o")
+ {
+ depfile = depfile.substr(0, depfile.length()-2);
+ depfile += ".d";
+ }
+ }
+ }
+ tmp = "-MD -MF ";
+ tmp += depfile;
+ cppopts.push_back(tmp);
+}
+
+//------------------------------------------------------------------------------
+// start cpp
+//------------------------------------------------------------------------------
+cmd = realcpp;
+for(vector<string>::iterator p = cppopts.begin(); p != cppopts.end(); ++p)
+{
+ cmd += " ";
+ cmd += *p;
+}
+cmd += " ";
+cmd += source;
+cmd += " -o-";
+dprintf("starting as cpp '%s'\n", cmd.c_str());
+CPP = popen(cmd.c_str(), "r");
+if (CPP == NULL)
+{
+ fprintf(stderr, "cannot start cpp '%s'\n", realcpp.c_str());
+ perror("");
+ exit(1);
+}
+
+//------------------------------------------------------------------------------
+// start cc. manually set language as source file extension not available to cc
+//------------------------------------------------------------------------------
+string type_str = "";
+if (!optx_found)
+{
+ // no option -x given by caller, set manually
+ type_str = "-x ";
+ type_str += cctype;
+}
+cmd = realcc;
+cmd += " ";
+cmd += type_str;
+for(vector<string>::iterator p = ccopts.begin(); p != ccopts.end(); ++p)
+{
+ cmd += " ";
+ cmd += *p;
+}
+cmd += " -o ";
+cmd += object;
+dprintf("starting as cc '%s'\n", cmd.c_str());
+CC = popen(cmd.c_str(), "w");
+if (CC == NULL)
+{
+ fprintf(stderr, "cannot start cc '%s'\n", realcc.c_str());
+ perror("");
+ exit(1);
+}
+
+string modifiedfile;
+string unmodifiedfile;
+if (debug)
+{
+ modifiedfile = object + ".debug";
+ DEBUG = fopen(modifiedfile.c_str(), "w");
+ if (DEBUG == NULL)
+ {
+ string msg = "cannot open file ";
+ msg += modifiedfile;
+ perror(msg.c_str());
+ modifiedfile = "";
+ }
+ else
+ {
+ fprintf(stderr, "writing preprocessed source to %s\n", modifiedfile.c_str());
+ }
+ unmodifiedfile = object + ".debug_in";
+ DEBUGIN = fopen(unmodifiedfile.c_str(), "w");
+ if (DEBUGIN == NULL)
+ {
+ string msg = "cannot open file ";
+ msg += unmodifiedfile;
+ perror(msg.c_str());
+ unmodifiedfile = "";
+ }
+ else
+ {
+ fprintf(stderr, "writing unprocessed source to %s\n", unmodifiedfile.c_str());
+ }
+}
+
+string oldline;
+string newline;
+static const int MAX_BUFFER = 51200;
+char buf[MAX_BUFFER];
+while (!feof(CPP))
+{
+ if (fgets(buf, MAX_BUFFER, CPP) != NULL)
+ {
+ oldline = buf;
+ if (DEBUGIN) { fprintf(DEBUGIN, "%s", oldline.c_str()); }
+ parse_line(hashtab, oldline, newline);
+ //#print "oldline = $oldline";
+ //#print "newline = $newline";
+ if (newline.empty())
+ {
+ fprintf(stderr, "hash error in/with file %s\n", source.c_str());
+ exit(1);
+ }
+ //#print "newline = $newline\n";
+ fprintf(CC, "%s", newline.c_str());
+ if (DEBUG) { fprintf(DEBUG, "%s", newline.c_str()); }
+ }
+}
+if (DEBUG) { fclose(DEBUG); }
+if (DEBUGIN) { fclose(DEBUGIN); }
+int cmd_rc = pclose(CPP);
+if (cmd_rc)
+{
+ fprintf(stderr, "error from cpp\n");
+ if (cmd_rc & 127)
+ {
+ fprintf(stderr, "cpp got signal %d\n", (cmd_rc & 127));
+ exit(1);
+ }
+ else if (cmd_rc >> 8)
+ {
+ fprintf(stderr, "cpp returned %d\n", (cmd_rc >> 8));
+ exit(cmd_rc >> 8);
+ }
+}
+cmd_rc = pclose(CC);
+if (cmd_rc)
+{
+ fprintf(stderr, "error from cc\n");
+ if (cmd_rc & 127)
+ {
+ fprintf(stderr, "cc got signal %d\n", (cmd_rc & 127));
+ exit(1);
+ }
+ else if (cmd_rc >> 8)
+ {
+ fprintf(stderr, "cc returned %d\n", (cmd_rc >> 8));
+ exit(cmd_rc >> 8);
+ }
+}
+
+if (!hashtab.empty())
+{
+ string stringfile = object;
+ stringfile += ".ppe.hash";
+ // open trace string file
+ FILE* TRC = fopen(stringfile.c_str(), "w");
+ if (TRC == NULL)
+ {
+ fprintf(stderr, "cannot write trace string file '%s'\n", stringfile.c_str());
+ exit(1);
+ }
+ dprintf("Writing to file %s\n", stringfile.c_str());
+
+ string pwd;
+ FILE* PWD = popen("pwd", "r");
+ fgets(buf, MAX_BUFFER, PWD);
+ pwd = buf;
+ pclose(PWD);
+ time_t tt = time(NULL);
+ sprintf(buf, "%s", asctime(localtime(&tt)));
+ buf[strlen(buf)-1] = '\0'; // chop off extra newline
+ fprintf(TRC, "#FSP_TRACE_v2|||%s|||BUILD:%s", buf, pwd.c_str());
+
+ string srch_str = "||";
+ srch_str += source;
+ int srch_str_len = srch_str.length();
+ size_t pos;
+ for(map<string,string>::iterator p = hashtab.begin(); p != hashtab.end(); ++p)
+ {
+ pos = (p->second).find(srch_str);
+ if ((pos != string::npos) && ((pos + srch_str_len) == (p->second).length()))
+ {
+ // source file name is already part of the string
+ fprintf(TRC, "%s||%s\n", (p->first).c_str(), (p->second).c_str());
+ }
+ else
+ {
+ fprintf(TRC, "%s||%s||%s\n", (p->first).c_str(), (p->second).c_str(), source.c_str());
+ }
+ //#print TRC "$key||$source||$hashtab{$key}\n";
+ }
+ fclose(TRC);
+}
+else
+{
+ dprintf("No trace calls/strings found, not writing hash file\n");
+}
+} // end main
diff --git a/src/ppe/tools/ppetracepp/trac_interface.h b/src/ppe/tools/ppetracepp/trac_interface.h
new file mode 100755
index 0000000..27215fc
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/trac_interface.h
@@ -0,0 +1,370 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/ppe/tools/ppetracepp/trac_interface.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/******************************************************************************
+// @file trac_interface.h
+// @brief Interface codes for TRAC component.
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section _trac_interface_h trac_interface.h
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * TEAM 06/16/2010 Port
+ * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+ * @pb00E pbavari 03/11/2012 Added correct include file
+ * @at009 859308 alvinwan 10/15/2012 Added tracepp support
+ * @ai005 860268 ailutsar 11/20/2012 Create trace test applet
+ * @rc005 864101 rickylie 12/12/2012 add small circ buffer to handle ISR semaphore conflict
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+#ifndef _TRAC_INTERFACE_H
+#define _TRAC_INTERFACE_H
+
+/** \defgroup Trace Trace Component
+ * Port of the trace code used in the fsp and tpmd.
+ */
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+/**
+ * \defgroup TracMacros Trace Component Macro Interfaces
+ * \ingroup Trace
+ * Used to trace 0 - 5 arguments or a binary buffer when using a hash value.
+ */
+/*@{*/
+
+
+// @at009c - start
+#define TRACE(i_td,i_string,args...) \
+ trace_adal_write_all(i_td,trace_adal_hash(i_string,-1),__LINE__,0,##args)
+
+#define TRACEBIN(i_td,i_string,i_ptr,i_size) \
+ trac_write_bin(i_td,trace_adal_hash(i_string,0),__LINE__,i_ptr,i_size)
+
+#ifndef NO_TRAC_STRINGS
+
+#define FIELD(a) \
+ printf("%s",a)
+
+#define FIELD1(a,b) \
+ printf("%s%lx",a,(unsigned long)b)
+
+#else // NO_TRAC_STRINGS
+
+#define FIELD(a)
+
+#define FIELD1(a,b)
+
+#endif // NO_TRAC_STRINGS
+
+#define SUCCESS 0
+// @at009c - end
+
+
+
+/*@}*/
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#define TRACE_MAX_ARGS 5 /*!< Maximum number of args to trace */
+
+typedef uint32_t trace_hash_val;
+
+// NOTE! Increment this when new components are added!
+#define TRAC_NUM_TRACE_COMPONENTS 1
+
+
+#define TRACE_BUFFER_SIZE 8192 // @ai005a
+
+#define CIRCULAR_BUFFER_SIZE 4 // @rc005a
+
+typedef uint32_t UINT32;
+typedef int32_t INT32;
+typedef uint8_t UCHAR;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef char CHAR;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+typedef int INT;
+typedef void VOID;
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+/*
+ * @brief Structure is put at beginning of all trace buffers
+ */
+typedef struct trace_buf_head {
+ UCHAR ver; /*!< version of this struct (1) */
+ UCHAR hdr_len; /*!< size of this struct in bytes */
+ UCHAR time_flg; /*!< meaning of timestamp entry field */
+ UCHAR endian_flg; /*!< flag for big ('B') or little ('L') endian */
+ CHAR comp[16]; /*!< the buffer name as specified in init call */
+ UINT32 size; /*!< size of buffer, including this struct */
+ UINT32 times_wrap; /*!< how often the buffer wrapped */
+ UINT32 next_free; /*!< offset of the byte behind the latest entry */
+ UINT32 te_count; /*!< Updated each time a trace is done */
+ UINT32 extracted; /*!< Not currently used */
+}trace_buf_head_t;
+
+/*!
+ * @brief Timestamp and thread id for each trace entry.
+ */
+typedef struct trace_entry_stamp {
+ UINT32 tbh; /*!< timestamp upper part */
+ UINT32 tbl; /*!< timestamp lower part */
+ UINT32 tid; /*!< process/thread id */
+}trace_entry_stamp_t;
+
+/*
+ * @brief Structure is used by adal app. layer to fill in trace info.
+ */
+typedef struct trace_entry_head {
+ UINT16 length; /*!< size of trace entry */
+ UINT16 tag; /*!< type of entry: xTRACE xDUMP, (un)packed */
+ UINT32 hash; /*!< a value for the (format) string */
+ UINT32 line; /*!< source file line number of trace call */
+}trace_entry_head_t;
+
+/*
+ * @brief Parameter traces can be all contained in one write.
+ */
+typedef struct trace_entire_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+ UINT32 args[TRACE_MAX_ARGS + 1];
+} trace_entire_entry_t;
+
+
+/*
+ * @brief Binary first writes header and time stamp.
+ */
+typedef struct trace_bin_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+} trace_bin_entry_t;
+
+/**
+ * @brief Used as input to traces to get to correct buffer.
+ */
+typedef trace_buf_head_t * tracDesc_t;
+
+/*
+ * @brief Structure is used to hold array of all trace descriptors
+ */
+typedef struct trace_descriptor_array
+{
+ tracDesc_t *entry; /*!< Pointer to trace descriptor */
+ CHAR *comp; /*!< Pointer to component name */
+}trace_descriptor_array_t;
+
+// @rc005a - start
+typedef struct circular_buf_head
+{
+ UINT32 head; // pointer to head
+ UINT32 tail; // pointer to tail
+ UINT32 entryCount; // nums of entry
+} circular_buf_header_t;
+
+
+typedef struct circular_entire_data {
+ UINT32 len;
+ CHAR comp[4];
+ trace_entire_entry_t entry;
+} circular_entire_data_t;
+
+// @rc005a - end
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+// All TPMF component trace descriptors.
+extern tracDesc_t g_trac_inf; // @at009a
+extern tracDesc_t g_trac_err; // @at009a
+extern tracDesc_t g_trac_imp; // @at009a
+
+extern const trace_descriptor_array_t g_des_array[];
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+
+/**
+ * \defgroup TracIntefaces Trace Component Interfaces for External Use
+ * \ingroup Trace
+ */
+/*@{*/
+
+
+/**
+ * @brief Allocate and initialize all trace buffers in memory.
+ *
+ * This function will allocate memory for each of the pre-defined trace
+ * buffers, initilize the buffers with starting data, and setup the
+ * trace descriptors which each component will use to trace.
+ *
+ * This function must be called first before any components try to trace!
+ *
+ * @return Non-zero return code on error.
+ */
+UINT TRAC_init_buffers(void);
+
+/**
+ * @brief Retrieve full trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the full trace buffer in o_data.
+ *
+ * @param i_td_ptr Trace descriptor of buffer to retrieve.
+ * @param o_data Pre-allocated pointer to where data will be stored.
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_get_buffer(const tracDesc_t i_td_ptr,
+ void *o_data);
+
+/**
+ * @brief Retrieve partial trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the trace buffer (size io_size). This function will copy
+ * in up to io_size in bytes to the buffer and set io_size
+ * to the exact size that is copied in.
+ *
+ * @param i_td_ptr Trace descriptor of buffer to retrieve.
+ * @param o_data Pre-allocated pointer to where data will be stored.
+ * @param io_size Size of trace data to retrieve (input)
+ * Actual size of trace data stored (output)
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_get_buffer_partial(const tracDesc_t i_td_ptr,
+ void *o_data,
+ UINT *io_size);
+
+/**
+ * @brief Retrieve trace descriptor for input component name
+ *
+ * @param i_comp Component name to retrieve trace descriptor for.
+ *
+ * @return Valid trace descriptor on success, NULL on failure.
+ */
+tracDesc_t TRAC_get_td(const char *i_comp);
+
+/**
+ * @brief Reset all trace buffers
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_reset_buf(void);
+
+/*@}*/ // Ending tag for external interface module in doxygen
+
+
+/**
+ * @brief Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_fmt Output format
+ * @param i_line Line number trace is occurring on.
+ * @param i_type trace type. filed or debug.
+ * @param ... parames that are limited to a size of 4 bytes, i.e. int, uint32_t, nnn*
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trace_adal_write_all(tracDesc_t io_td,const trace_hash_val i_hash,
+ const char *i_fmt,const ULONG i_line, const ULONG i_type,...);
+
+
+/**
+ * @brief Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_line Line number trace is occurring on.
+ * @param i_num_args Number of arguments to trace.
+ * @param i_1 Input Parameter 1
+ * @param i_2 Input Parameter 2
+ * @param i_3 Input Parameter 3
+ * @param i_4 Input Parameter 4
+ * @param i_5 Input Parameter 5
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trac_write_int(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const UINT i_num_args,
+ const ULONG i_1,const ULONG i_2,const ULONG i_3,
+ const ULONG i_4,const ULONG i_5
+ );
+
+
+ /**
+ * @brief Trace binary data to buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_line Line number trace is occurring on.
+ * @param i_ptr Pointer to binary data to trace.
+ * @param i_size Size of data to copy from i_ptr.
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trac_write_bin(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const void *i_ptr,
+ const ULONG i_size);
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+#endif //_TRAC_INTERFACE_H
diff --git a/src/ppe/tools/ppetracepp/tracehash.pl b/src/ppe/tools/ppetracepp/tracehash.pl
new file mode 100755
index 0000000..fa24490
--- /dev/null
+++ b/src/ppe/tools/ppetracepp/tracehash.pl
@@ -0,0 +1,897 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/ppe/tools/ppetracepp/tracehash.pl $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# File tracehash.pl created by B J Zander.
+
+use strict;
+
+sub determine_args();
+sub launch_cpp_and_parse($$);
+sub cpp_dir($);
+sub read_string_file();
+sub collect_files($);
+sub assimilate_file($);
+sub hash_strings();
+sub write_string_file();
+sub help();
+
+select (STDERR);
+$| = 1; # Make all prints to STDERR flush the buffer immediately
+select (STDOUT);
+$| = 1; # Make all prints to STDOUT flush the buffer immediately
+
+# Constants
+my $HEAD_SEP = "|||";
+my $HEAD_EYE_CATCHER = "#FSP_TRACE_v";
+my $HEAD_BUILD_FLAG = "BUILD:";
+my $HEAD_VER_FLAG = 2;
+my $BB_STRING_FILE = "/opt/fsp/etc/BB_StringFile";
+
+# Global Variables
+my $debug = 0;
+my $seperator = "&&&&";
+my $file_name = "trexStringFile";
+my $in_sand;
+my ($backing) = $ENV{'bb'};
+my $hash_prog = "trexhash"; #default to in path
+my $build = "";
+my ($sandbox) = $ENV{'SANDBOX'} || "";
+my ($context) = $ENV{'CONTEXT'} || "";
+my ($sandboxbase) = $ENV{'SANDBOXBASE'} || "";
+my ($bb);
+my ($sourcebase) = "$sandboxbase/src";
+my ($version) = $HEAD_VER_FLAG; # default to oldest version
+my ($collect) = 0;
+my ($INCLUDE, $Arg, $file, $dir, $string_file);
+my $args = "";
+
+my $fail_on_collision = 0; # 1 = exit with error if hash collision occurs
+my $hash_filename_too = 0; # 1 = hash is calculated over format string + filename
+
+print "sourcebase = $sourcebase\n" if $debug;
+print "sandbox = $sandbox\n" if $debug;
+print "backing = $backing\n" if $debug;
+print "context = $context\n" if $debug;
+
+if ($context =~ /x86/)
+{
+ $bb = "i586-pc-linux-gnu";
+}
+else
+{
+ $bb = "powerpc-linux";
+}
+
+if(($sourcebase =~ /\w+/) && ($sandbox =~ /\w+/))
+{
+ $INCLUDE = "-I $sandboxbase/export/$context/fips/include -I $backing/export/$context/fips/include -I /opt/fsp/$bb/include/fsp -I/opt/fsp/$bb/include/ -include /opt/fsp/$bb/include/fsp/tracinterface.H";
+}
+else
+{
+ print "Not in Sandbox so guessing Include Paths...\n" if $debug;
+ $INCLUDE = "-I/opt/fsp/i586-pc-linux-gnu/include/fsp -I/opt/fsp/i586-pc-linux-gnu/include/ -include /opt/fsp/i586-pc-linux-gnu/include/fsp/tracinterface.H";
+}
+
+# I/P Series work in ODE sandbox env.
+if ($sandboxbase =~ /\w+/)
+{
+ $in_sand = 1;
+ print "backing = $backing\n" if $debug;
+}
+else
+{
+ $in_sand = 0;
+}
+
+
+
+# Parse the input parameters.
+
+while (@ARGV) {
+ $Arg = shift;
+
+ if ($Arg eq "-h" || $Arg eq "-H") {
+ help();
+ exit(127);
+ }
+ if ($Arg eq "-f") {
+ $file = shift;
+ next;
+ }
+ if ($Arg eq "-d") {
+ $dir = shift;
+ next;
+ }
+ if ($Arg eq "-s") {
+ $string_file = shift;
+ next;
+ }
+ if ($Arg eq "-c") {
+ $collect = 1;
+ next;
+ }
+ if ($Arg eq "-v") {
+ $debug = 1;
+ print "debug on\n" if $debug;
+ next;
+ }
+ if ($Arg eq "-C") { # fail if a hash collision is detected
+ $fail_on_collision = 1;
+ next;
+ }
+ if ($Arg eq "-F") { # hash is calculated over format string + file name
+ $hash_filename_too = 1;
+ next;
+ }
+ if ($Arg eq "-S") {
+ $BB_STRING_FILE = "";
+ next;
+ }
+
+ #just pass it onto compiler
+ $args = $args . " " . $Arg;
+}
+
+print "args = $args\n" if $debug;
+
+if (!$file && !$dir && !$in_sand) {
+ help();
+ exit(127);
+}
+
+#################################
+# M A I N #
+#################################
+
+my $clock = `date`;
+
+$build = $HEAD_EYE_CATCHER . "$HEAD_VER_FLAG" . $HEAD_SEP . $clock . $HEAD_SEP . $HEAD_BUILD_FLAG;
+
+$build =~ s/\n//g;
+
+# Global array to hold the parsed TRAC macro calls.
+my @strings = ();
+
+# Assoc. arrays to hold hash|string values.
+my %string_file_array = ();
+my %hash_strings_array = ();
+
+# Check all provided arguments and look for defaults if not provided by user
+determine_args();
+
+# Scan the appropriate files or directories for TRAC macro calls.
+
+if (defined $dir)
+{
+
+ $build = $build . $dir; # default to put at top of string file
+ if($collect)
+ {
+ collect_files($dir);
+ }
+ else
+ {
+ cpp_dir($dir);
+ # Hash the string that have been scanned.
+ %hash_strings_array = hash_strings();
+ }
+}
+else
+{
+ $build = $build . $file; # default to put at top of string file
+
+ if($collect)
+ {
+ assimilate_file($file);
+ }
+ else
+ {
+ # make sure include path includes directory that file is in
+ if($file =~ /^(.+)\/[^\/]+\.C$/)
+ {
+
+ launch_cpp_and_parse($file,$1);
+ }
+ else
+ {
+ # No path in front of file so it has to be local dir
+ launch_cpp_and_parse($file,"./");
+ }
+ # Hash the string that have been scanned.
+ %hash_strings_array = hash_strings();
+ }
+}
+
+# Read the existing string file into memory.
+%string_file_array = read_string_file();
+
+# Write out the new string file. check for collisions of new/old string here
+write_string_file();
+
+print "Hashing Started at $clock\n";
+$clock = `date`;
+print "Hashing Finished at $clock\n";
+
+exit 0;
+
+
+#################################
+# S U B R O U T I N E S #
+#################################
+
+#=============================================================================
+# Enhance usability by figuring out which build env. we are in
+#=============================================================================
+sub determine_args() {
+
+
+ # Find trexhash program
+ # but only if needed (i.e. not in collect mode)
+ if (!$collect) {
+ my $tmp = `which $hash_prog`;
+ chomp $tmp;
+
+ if ($tmp eq '') {
+ print STDOUT "\nWarning: Program trexhash does not exist in path.\n" if $debug;
+ $hash_prog = "./trexhash";
+
+ $tmp = `which $hash_prog`;
+ chomp $tmp;
+ if ($tmp eq '') {
+ print STDOUT "\nError: Unable to find trexhash \n";
+ exit(127);
+ }
+ }
+ }
+
+ # Verify input values.
+ if ((!defined $file) && (!defined $dir)) {
+ if(!($in_sand))
+ {
+ print STDOUT "\nError: No input directory or file provided as input to scan\n";
+ exit(127);
+ }
+
+ # Assume they want sandbox scanned
+ if($collect)
+ {
+ # collect all string files generated by tracepp and merge
+ $dir = "$sandboxbase/obj/";
+ }
+ else
+ {
+ # generate our own string file by pre-compiling all source code
+ $dir = "$sandboxbase/src/";
+ }
+ print STDOUT "\n-f <file> or -d <dir> not found...scanning $dir by default\n\n";
+ }
+
+ if (!defined $string_file)
+ {
+ if ($in_sand)
+ {
+
+ # Copy the current string file from backing build into our sandbox
+ system ("cp $backing/obj/$file_name $sandboxbase/obj/$file_name")
+ if !(-e "$sandboxbase/obj/$file_name");
+
+ $string_file = "$sandboxbase/obj/$file_name";
+ }
+ else
+ {
+ $string_file = "./$file_name";
+ }
+ print STDOUT "-sf <string_file> not specified, using $string_file instead...\n\n" if $debug;
+
+ }
+
+ # Try Creating the string file
+ `touch $string_file`;
+
+ if (! -f $string_file) {
+ print STDOUT "\nError: File $string_file does not exist. Current directory may not be writable.\n\n";
+ help();
+ exit(127);
+ }
+
+ # Make sure trexStringFile is readable/writeable
+ system("chmod ugo+rw $string_file");
+
+}
+
+#=============================================================================
+# Launch cpp script and grab input from it looking for trace calls.
+#=============================================================================
+sub launch_cpp_and_parse($$) {
+
+ my ($l_loc, $l_dir) = @_;
+
+ print "Processing file $l_loc\n" if $debug;
+ my $cmd = "/usr/bin/cpp $INCLUDE -I $l_dir $args $l_loc|";
+ print "$cmd\n" if $debug;
+ open(FH,"$cmd")
+ or die ("Cannot open $_:$!,stopped");
+
+ # Read through all lines in the file..
+ my $line = <FH>;
+ while (defined $line)
+ {
+ chop $line; # remove EOL
+ $line =~ s/^\s*//; # remove unneccesary beginning white space.
+ $line =~ s/\s*$//; # remove unneccesary ending white space.
+ # Look for lines that are trace macro calls.
+ #if (/(trace_adal_hash)(\()( *)(".+")(,)(\d)/)
+ #if ($line =~ /(.*?)(trace_adal_hash)(\()( *)(".+")(,)(\d)\)+(.*\d.*)/)
+ while($line =~ m/^(.*?)trace_adal_hash\s*\(\s*(("[^"]*"\s*)+),\s*(\d+)\s*\)(.*)$/)
+ {
+ my ($prefix, $strings, $salt, $suffix) = ($1, $2, $4, $5);
+ print STDOUT "$strings $salt\n" if $debug;
+ $strings =~ s/"\s*$//; # remove trailing " and space
+ $strings =~ s/^"//; # remove leading "
+ $strings =~ s/"\s*"//g;
+ # Check to see if it's contained on a single line, or if we
+ # have to combine lines to get a complete trace call.
+
+ # Save the macro call so it can be hashed later..
+ push (@strings, [$l_loc, $strings, $salt]);
+ $line = $suffix; # check rest of line for a second trace call
+ }
+ my $nextline = <FH>;
+ last if !defined $nextline;
+ # if a trace call is spread over multiple lines we have to add the next
+ # line from the source. the only problem is the definition/declaration
+ # of trace_adal_hash: we have to ignore that. we catch that by requiring
+ # a " after the function name. hopefully nobody writes a comment with
+ # a " after the function declaration ...
+ if ($line =~ /trace_adal_hash.*"/) {
+ $line .= $nextline;
+ } else {
+ $line = $nextline;
+ }
+ }
+ close(FH);
+}
+
+#=============================================================================
+# run cpp on all files in this directory and return the output
+#=============================================================================
+sub cpp_dir($) {
+
+ my ($l_dir) = @_;
+ my @dir_entry;
+ my $l_entry;
+
+ # Open the directory and read all entry names.
+ opendir ( DH , "$l_dir")
+ or die ("Cannot open $l_dir: $!, stopped");
+
+ print STDOUT "Processing directory $l_dir\n" if $debug;
+ @dir_entry = readdir(DH);
+ closedir(DH);
+
+ while (@dir_entry) {
+ $l_entry = shift(@dir_entry);
+
+ if ($l_dir =~ m"/$") {
+ $l_entry = "$l_dir$l_entry";
+ }
+ else {
+ $l_entry = "$l_dir/$l_entry";
+ }
+
+ # Is the entry a directory?
+ if (-d $l_entry) {
+
+ if($l_entry =~ m"/?([^/]+)$")
+ {
+ # check dir we are going into
+ print "dir = $1\n" if $debug;
+ # should we recurse into this directory.
+ if ($1 =~ m/^(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ cpp_dir($l_entry);
+ }
+ else
+ {
+ # unable to determine name of dir (no / in filename)
+ # should we recurse into this directory.
+ if ($l_entry =~ m/^(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ cpp_dir($l_entry);
+ }
+ }
+ # Is the entry a file?
+ elsif ((-f $l_entry) && ($l_entry =~ m/\.C$/)) {
+ # it's a file so
+ launch_cpp_and_parse($l_entry,$l_dir);
+ }
+ else {
+ # Not a file or directory so ignore it...
+ }
+ }
+}
+
+#=============================================================================
+# Read in strings from the existing trace string file....
+#=============================================================================
+sub read_string_file() {
+
+ my %o_strings;
+ my ($line) = "";
+ my ($l_hash) = "";
+ my ($l_str) = "";
+ my ($cur_build) = "";
+ my ($l_file) = "";
+
+
+ # Make sure we can open each file.
+ open ( FH , "<$string_file")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "first line in trexStringFile= $line\n" if $debug;
+
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+
+ print "version = $version\n" if $debug;
+
+ #Always put latest version in file
+ $line =~ s/^$HEAD_EYE_CATCHER\d/${HEAD_EYE_CATCHER}${HEAD_VER_FLAG}/;
+
+ # Take previous version in file and use it.
+ $build = $line;
+ chomp($build);
+ $line = <FH>;
+
+ while (defined $line) {
+ chomp $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ else
+ {
+ print "Unknown version of stringfile $version\n";
+ exit(127);
+ }
+ $o_strings{$l_hash} = $l_str . "||" . $l_file;
+ $line = <FH>;
+ }
+
+ }
+ else
+ { # If there is a file then we are dealing with the first
+ # version of trexStringFile so don't look for file name.
+ if ($debug) {
+ print "version 0 stringfile detected: $string_file\n";
+ }
+
+ # there is a file and it doesn't have a header
+ $version = 0;
+
+ while (defined $line) {
+ chomp $line; # remove EOL
+ ($l_hash,$l_str) = split(/\|\|/, $line);
+ $o_strings{$l_hash} =$l_str . "||" . "NO FILE";
+ $line = <FH>;
+ }
+ }
+
+ close(FH);
+
+ #Time to look for a building block string file
+ if($BB_STRING_FILE ne "" and $string_file ne $BB_STRING_FILE and -f $BB_STRING_FILE)
+ {
+
+ # Make sure we can open the file.
+ open ( FH , "<$BB_STRING_FILE")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "first line in BB_StringFile = $line\n" if $debug;
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+
+ $line = <FH>;
+ while (defined $line)
+ {
+ chop $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ #($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ $o_strings{$l_hash} = $l_str . "||" . $l_file ;
+ $line = <FH>;
+ }
+ }
+ else
+ {
+ print "*** ERROR: BB_StringFile '$BB_STRING_FILE' should always have version!!!\n"
+ }
+
+ }
+ else
+ {
+ print "$BB_STRING_FILE is not available\n" if $debug;
+ }
+ #All files are latest version now.
+ $version = $HEAD_VER_FLAG;
+ return %o_strings;
+}
+
+#=============================================================================
+# Read in strings from the existing trace string file....
+#=============================================================================
+sub collect_files($) {
+
+ my ($l_dir) = @_;
+ my (@dir_entry);
+ my ($l_entry) = "";
+
+ # Open the directory and read all entry names.
+ opendir ( DH , "$l_dir")
+ or die ("Cannot open $l_dir: $!, stopped");
+
+ print STDOUT "Processing directory $l_dir\n" if $debug;
+ @dir_entry = readdir(DH);
+ closedir(DH);
+
+ while (@dir_entry) {
+ $l_entry = shift(@dir_entry);
+
+ if ($l_dir =~ m"/$") {
+ $l_entry = "$l_dir$l_entry";
+ }
+ else {
+ $l_entry = "$l_dir/$l_entry";
+ }
+
+ # Is the entry a directory?
+ if (-d $l_entry) {
+
+ # should we recurse into this directory.
+ if ($l_entry =~ m/\/(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ collect_files($l_entry);
+ }
+ # Is the entry a file?
+ elsif ((-f $l_entry) && ($l_entry =~ m"\.hash$")) {
+ # it's a file so
+ assimilate_file($l_entry);
+ }
+ else {
+ # Not a file or directory so ignore it...
+ }
+ }
+
+}
+
+#=============================================================================
+# Read in data from file and add to master one
+#=============================================================================
+sub assimilate_file($) {
+
+ my ($l_loc) = @_;
+
+ my (%o_strings);
+ my ($line) = "";
+ my ($l_hash) = "";
+ my ($l_str) = "";
+ my ($l_file) = "";
+
+ # Make sure we can open each file.
+ open ( FH , "<$l_loc")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "Assimilate: first line in $l_loc = $line" if $debug;
+
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+ if ($version eq "1") {
+ if ($hash_filename_too) {
+ print "*** ERROR: hash_filename_too (-F) isn't possible with trace version 1\n";
+ print " please rebuild all .hash files and global trexStringFile\n";
+ print " version 1 file is '$l_loc'\n";
+ exit(127);
+ }
+ } elsif ($version ne "2") {
+ print "Unknown version of stringfile $version\n";
+ exit(127);
+ }
+
+ $line = <FH>;
+
+
+ while (defined $line) {
+ chop $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ my $newstring = $l_str . "||" . $l_file;
+ if (exists $hash_strings_array{$l_hash}) {
+ my $hashstr1 = $hash_strings_array{$l_hash};
+ my $hashstr2 = $newstring;
+ if (!$hash_filename_too) {
+ # hash was made over format string only, remove file name
+ $hashstr1 =~ s/\|\|.*$//;
+ $hashstr2 = $l_str;
+ }
+ if ($debug) {
+ print "a_f: compare $hashstr1\n",
+ " vs. $hashstr2\n";
+ }
+ if ($hashstr1 ne $hashstr2)
+ {
+ print "*** ERROR: HASH Collision! (a_f)\n",
+ " Two different strings have the same hash value ($l_hash)\n",
+ " String 1: $hash_strings_array{$l_hash}\n",
+ " String 2: $newstring\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ }
+ }
+ $hash_strings_array{$l_hash} = $newstring;
+ $line = <FH>;
+ }
+
+ }
+ else
+ { # If there is a file then we are dealing with the first
+ # version of trexStringFile so don't look for file name.
+ # these files shouldn't be there anymore. we don't check for collisions here
+ if ($debug) {
+ print "version 0 stringfile detected: $string_file\n";
+ }
+
+ if(defined $line)
+ {
+ # there is a file and it doesn't have a header
+ $version = 0;
+ }
+
+ while (defined $line) {
+ chop $line; # remove EOL
+ ($l_hash,$l_str) = split(/\|\|/, $line);
+ $hash_strings_array{$l_hash} = $l_str . "||" . "NO FILE";
+ $line = <FH>;
+ }
+ }
+ $version = $HEAD_VER_FLAG;
+ close(FH);
+}
+
+#=============================================================================
+
+#=============================================================================
+sub hash_strings() {
+
+ my ($hash_val, $l_key, $l_hash, %l_hash_strings);
+ my ($line_feed) = chr(10);
+ my ($l_file_name) = "NO FILENAME";
+ print "\nHashing printf strings.\n\n";
+
+ foreach my $str (@strings) {
+ my $printf_string;
+ $l_file_name = $str->[0];
+ $printf_string = $str->[1];
+ $l_key = $str->[2];
+ print "printf_string = $printf_string\n" if $debug;
+ $printf_string =~ s/"\s?"//g; #multi line traces will have extra " in them
+ $printf_string =~ s/`/\\`/g; # excape '
+ $printf_string =~ s/\\n/$line_feed/g; # escape \n
+ if ($hash_filename_too) {
+ $printf_string .= "||" . $l_file_name;
+ }
+
+ # call the hasher.
+ print "$hash_prog \"$printf_string\" $l_key\n" if $debug;
+ $hash_val = `$hash_prog \"$printf_string\" $l_key`;
+ if ($?) {
+ my ($hp_ret, $hp_sig) = ($? >> 8, $? & 127);
+ if ($hp_sig) {
+ print "*** ERROR: $hash_prog died with signal $hp_sig\n";
+ } elsif ($hp_ret) {
+ print "*** ERROR: $hash_prog returned the error $hp_ret\n";
+ if ($hash_val) {
+ print " error from $hash_prog:\n$hash_val";
+ }
+ }
+ exit(1);
+ }
+ print "printf_string = $printf_string l_key = $l_key hash val = $hash_val\n" if $debug;
+
+ # undo escaping
+ $printf_string =~ s/$line_feed/\\n/g;
+ $printf_string =~ s/\\`/`/g;
+
+ if (exists $l_hash_strings{$hash_val})
+ {
+ # hash val was found before. check if it's the same string
+ # else we have a hash collision
+ my $l_tmp = $l_hash_strings{$hash_val};
+ if (!$hash_filename_too) {
+ $l_tmp =~ s/\|\|.*$//;
+ }
+ if ($l_tmp ne $printf_string)
+ {
+ print "*** ERROR: HASH Collision! (h_s)\n",
+ " Two different strings have the same hash value ($hash_val)\n",
+ " String 1: $l_hash_strings{$hash_val}\n",
+ " String 2: $printf_string (file $l_file_name)\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ }
+ }
+ # this will overwrite an old string with a new one if a collision occurred
+ # but we might want to bail out in this case anyway
+ $printf_string = $printf_string . "||" . $l_file_name;
+ $l_hash_strings{$hash_val} = $printf_string;
+ }
+ return %l_hash_strings;
+}
+#=============================================================================
+
+#=============================================================================
+sub write_string_file() {
+
+ my (@keys) = ();
+ my ($l_key) = "";
+
+ # Combine the contents of the existing string file with the trace calls
+ # that we have just hashed.
+ print STDOUT "\nCombining Hash strings...\n\n";
+
+ @keys = keys(%hash_strings_array);
+
+ foreach $l_key (@keys) {
+ my $l_tmp = $hash_strings_array{$l_key}; # freshly collected strings
+ if (exists $string_file_array{$l_key})
+ { # hash exists in list from trexStringFile
+ my $l_tmp2 = $string_file_array{$l_key};
+ if (!$hash_filename_too) {
+ $l_tmp =~ s/\|\|.*$//;
+ $l_tmp2 =~ s/\|\|.*$//;
+ }
+
+ # Check for hash collisions.
+ if ($l_tmp ne $l_tmp2)
+ {
+ print "*** ERROR: HASH Collision! (w_s_f)\n",
+ " Two different strings have the same hash value ($l_key)\n",
+ " String 1: $hash_strings_array{$l_key}\n",
+ " String 2: $string_file_array{$l_key}\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ # don't fail, write new one
+ }
+ }
+ if($version > 0)
+ {
+ # add/replace the new string to the string_file_array.
+ $string_file_array{$l_key} = $hash_strings_array{$l_key}
+ }
+ else
+ {
+ # old version so only write out format string (not file name to)
+ $string_file_array{$l_key} = $l_tmp;
+ }
+ }
+
+ # Write out the updated string file.
+ print STDOUT "\nWriting updated hash||string file...\n\n";
+
+ @keys = sort(keys(%string_file_array));
+
+ open ( FH , ">$string_file")
+ or die ("Cannot open $_: $!, stopped");
+
+ if($version > 0)
+ {
+ print FH "$build\n"; # only print version if newer then version 0
+ }
+ foreach $l_key (@keys) {
+ print FH "$l_key||$string_file_array{$l_key}\n";
+ }
+ close FH;
+}
+#=============================================================================
+
+#=============================================================================
+# Display command invokation help for this program...
+#=============================================================================
+sub help() {
+ print << "EOF";
+tracehash.pl - create a trace string file from sources or collect tracepp files
+Usage: tracehash.pl [options]
+ General options:
+ -h - Print this help text.
+ -v - Be verbose, tell what's going on (debug output)
+ Operation modes
+ -c - Collect StringFiles created by tracepp and merge.
+ default - Scan source files for trace calls.
+
+Collect mode: tracehash.pl -c [-vFCS] [-d <dir>] [-s <string_file>]
+ tracehash.pl -c [-vFCS] [-f <file>] [-s <string_file>]
+ Collect string files created by tracepp (.hash) from directory tree at
+ <dir> or read them from string file <file> and write to file
+ <string_file>, adding entries already in this file.
+ -f - String file to read and write/add to <string_file>.
+ -d - Start of directory tree to scan for .hash files. Default = .
+ -s - File with trace strings (and hashes) to read from and write to
+ default = ./trexStringFile
+ -F - hash is calculated over trace string and source file name,
+ otherwise without source file name
+ -C - report an error if a hash collisions occurs
+ -S - don't read global FLD-2.2 string file ($BB_STRING_FILE)
+ If tracehash.pl is called in a FipS build sandbox without -d and -f
+ defaults for the sandbox will be used.
+
+Scan mode: tracehash.pl [-vFCS] [-d <dir>] [-s <string_file>] [ccpopts]
+ tracehash.pl [-vFCS] [-f <file>] [-s <string_file>] [cppopts]
+ Scan all files in directory tree <dir> or scan file <file> and write
+ strings to file <string_file>. Strings already in this file will be merged.
+ -f - Source file to scan for trace entries.
+ -d - Source directory to scan for trace entries.
+ -s - File with trace strings (and hashes) to read from and write to.
+ default = ./trexStringFile
+ -F - hash for string was build from format string + source file name
+ -C - report an error if hash collisions occur
+ -S - don't read global FLD-2.2 string file ($BB_STRING_FILE)
+ All other arguments will be passed verbatim to cpp
+EOF
+}
+#=============================================================================
+
OpenPOWER on IntegriCloud