summaryrefslogtreecommitdiffstats
path: root/src/ssx
diff options
context:
space:
mode:
authorStephan Broyles <sbroyles@us.ibm.com>2014-11-05 19:09:37 -0600
committerStephan Broyles <sbroyles@us.ibm.com>2014-11-05 19:22:32 -0600
commit9976c207cdb20871880bd2f4cf123cf4cb6a8b0f (patch)
tree1cf9ed8f23085e6fe3e0e6046fc30dcb7e02ccf2 /src/ssx
parent2f8ce357b89d361b5091d88aea91416011b73ccb (diff)
downloadtalos-occ-9976c207cdb20871880bd2f4cf123cf4cb6a8b0f.tar.gz
talos-occ-9976c207cdb20871880bd2f4cf123cf4cb6a8b0f.zip
Added remaining occ files.
Change-Id: I91a748d3dcf3161a6a3eedcb376fcaf1e4dfe655
Diffstat (limited to 'src/ssx')
-rwxr-xr-xsrc/ssx/pgp/Makefile38
-rwxr-xr-xsrc/ssx/pgp/linkssx.cmd499
-rwxr-xr-xsrc/ssx/pgp/pgp.h328
-rwxr-xr-xsrc/ssx/pgp/pgp_async.c1024
-rwxr-xr-xsrc/ssx/pgp/pgp_async.h1654
-rwxr-xr-xsrc/ssx/pgp/pgp_async_ocb.c953
-rwxr-xr-xsrc/ssx/pgp/pgp_async_pba.c1201
-rwxr-xr-xsrc/ssx/pgp/pgp_async_pore.c644
-rwxr-xr-xsrc/ssx/pgp/pgp_cache.S99
-rw-r--r--src/ssx/pgp/pgp_centaur.c597
-rw-r--r--src/ssx/pgp/pgp_centaur.h254
-rwxr-xr-xsrc/ssx/pgp/pgp_common.h717
-rwxr-xr-xsrc/ssx/pgp/pgp_core.h20
-rw-r--r--src/ssx/pgp/pgp_id.c135
-rw-r--r--src/ssx/pgp/pgp_id.h183
-rwxr-xr-xsrc/ssx/pgp/pgp_init.c340
-rwxr-xr-xsrc/ssx/pgp/pgp_irq.h252
-rwxr-xr-xsrc/ssx/pgp/pgp_irq_init.c155
-rwxr-xr-xsrc/ssx/pgp/pgp_ocb.c335
-rwxr-xr-xsrc/ssx/pgp/pgp_ocb.h88
-rwxr-xr-xsrc/ssx/pgp/pgp_pba.c460
-rwxr-xr-xsrc/ssx/pgp/pgp_pba.h358
-rwxr-xr-xsrc/ssx/pgp/pgp_pmc.c366
-rwxr-xr-xsrc/ssx/pgp/pgp_pmc.h105
-rwxr-xr-xsrc/ssx/pgp/pgp_pore.h39
-rwxr-xr-xsrc/ssx/pgp/pgp_sramctl.h18
-rwxr-xr-xsrc/ssx/pgp/pgp_trace.h155
-rwxr-xr-xsrc/ssx/pgp/pgp_vrm.h223
-rwxr-xr-xsrc/ssx/pgp/registers/centaur_firmware_registers.h1496
-rwxr-xr-xsrc/ssx/pgp/registers/centaur_register_addresses.h66
-rw-r--r--src/ssx/pgp/registers/fasti2c_firmware_registers.h232
-rw-r--r--src/ssx/pgp/registers/fasti2c_register_addresses.h27
-rw-r--r--src/ssx/pgp/registers/i2cengine_firmware_registers.h710
-rw-r--r--src/ssx/pgp/registers/i2cengine_register_addresses.h33
-rwxr-xr-xsrc/ssx/pgp/registers/icp_firmware_registers.h189
-rwxr-xr-xsrc/ssx/pgp/registers/icp_register_addresses.h24
-rwxr-xr-xsrc/ssx/pgp/registers/mcs_firmware_registers.h161
-rwxr-xr-xsrc/ssx/pgp/registers/mcs_register_addresses.h46
-rwxr-xr-xsrc/ssx/pgp/registers/ocb_firmware_registers.h2668
-rwxr-xr-xsrc/ssx/pgp/registers/ocb_register_addresses.h148
-rwxr-xr-xsrc/ssx/pgp/registers/oha_firmware_registers.h1248
-rwxr-xr-xsrc/ssx/pgp/registers/oha_register_addresses.h39
-rwxr-xr-xsrc/ssx/pgp/registers/pba_firmware_registers.h2184
-rwxr-xr-xsrc/ssx/pgp/registers/pba_register_addresses.h94
-rwxr-xr-xsrc/ssx/pgp/registers/pc_firmware_registers.h442
-rwxr-xr-xsrc/ssx/pgp/registers/pc_register_addresses.h61
-rwxr-xr-xsrc/ssx/pgp/registers/pcbs_firmware_registers.h2477
-rwxr-xr-xsrc/ssx/pgp/registers/pcbs_register_addresses.h74
-rw-r--r--src/ssx/pgp/registers/pibmem_firmware_registers.h264
-rw-r--r--src/ssx/pgp/registers/pibmem_register_addresses.h30
-rwxr-xr-xsrc/ssx/pgp/registers/plb_arbiter_firmware_registers.h215
-rwxr-xr-xsrc/ssx/pgp/registers/plb_arbiter_register_addresses.h28
-rwxr-xr-xsrc/ssx/pgp/registers/pmc_firmware_registers.h3140
-rwxr-xr-xsrc/ssx/pgp/registers/pmc_register_addresses.h116
-rwxr-xr-xsrc/ssx/pgp/registers/pore_firmware_registers.h906
-rwxr-xr-xsrc/ssx/pgp/registers/pore_register_addresses.h130
-rw-r--r--src/ssx/pgp/registers/sbe_firmware_registers.h906
-rw-r--r--src/ssx/pgp/registers/sbe_register_addresses.h48
-rwxr-xr-xsrc/ssx/pgp/registers/sensors_firmware_registers.h668
-rwxr-xr-xsrc/ssx/pgp/registers/sensors_register_addresses.h47
-rwxr-xr-xsrc/ssx/pgp/registers/sramctl_firmware_registers.h211
-rwxr-xr-xsrc/ssx/pgp/registers/sramctl_register_addresses.h30
-rwxr-xr-xsrc/ssx/pgp/registers/tod_firmware_registers.h58
-rwxr-xr-xsrc/ssx/pgp/registers/tod_register_addresses.h22
-rw-r--r--src/ssx/pgp/registers/tpc_firmware_registers.h213
-rw-r--r--src/ssx/pgp/registers/tpc_register_addresses.h30
-rwxr-xr-xsrc/ssx/pgp/ssx.mk424
-rwxr-xr-xsrc/ssx/pgp/ssx_port.h19
-rwxr-xr-xsrc/ssx/pgp/ssxpgpfiles.mk37
-rwxr-xr-xsrc/ssx/ppc32/Makefile33
-rwxr-xr-xsrc/ssx/ppc32/div64.S255
-rw-r--r--src/ssx/ppc32/gnu/stubs-32.h21
-rwxr-xr-xsrc/ssx/ppc32/ppc32.h171
-rwxr-xr-xsrc/ssx/ppc32/ppc32_asm.h408
-rwxr-xr-xsrc/ssx/ppc32/ppc32_gcc.c309
-rwxr-xr-xsrc/ssx/ppc32/ppc32_gcc.h75
-rwxr-xr-xsrc/ssx/ppc32/savegpr.S78
-rwxr-xr-xsrc/ssx/ppc32/ssxppc32files.mk29
-rwxr-xr-xsrc/ssx/ppc405/Makefile40
-rwxr-xr-xsrc/ssx/ppc405/ppc405.h771
-rwxr-xr-xsrc/ssx/ppc405/ppc405_boot.S242
-rw-r--r--src/ssx/ppc405/ppc405_breakpoint.S103
-rwxr-xr-xsrc/ssx/ppc405/ppc405_cache.h113
-rwxr-xr-xsrc/ssx/ppc405/ppc405_cache_core.c115
-rwxr-xr-xsrc/ssx/ppc405/ppc405_cache_init.S314
-rwxr-xr-xsrc/ssx/ppc405/ppc405_context.h594
-rwxr-xr-xsrc/ssx/ppc405/ppc405_core.c183
-rwxr-xr-xsrc/ssx/ppc405/ppc405_dcr.h55
-rwxr-xr-xsrc/ssx/ppc405/ppc405_exceptions.S832
-rwxr-xr-xsrc/ssx/ppc405/ppc405_init.c80
-rwxr-xr-xsrc/ssx/ppc405/ppc405_irq.h342
-rwxr-xr-xsrc/ssx/ppc405/ppc405_irq_core.c49
-rwxr-xr-xsrc/ssx/ppc405/ppc405_irq_init.c169
-rwxr-xr-xsrc/ssx/ppc405/ppc405_lib_core.c42
-rwxr-xr-xsrc/ssx/ppc405/ppc405_mmu.c474
-rwxr-xr-xsrc/ssx/ppc405/ppc405_mmu.h170
-rwxr-xr-xsrc/ssx/ppc405/ppc405_mmu_asm.S73
-rwxr-xr-xsrc/ssx/ppc405/ppc405_msr.h85
-rwxr-xr-xsrc/ssx/ppc405/ppc405_spr.h319
-rwxr-xr-xsrc/ssx/ppc405/ppc405_thread_init.S126
-rwxr-xr-xsrc/ssx/ppc405/ssx_port_types.h44
-rwxr-xr-xsrc/ssx/ppc405/ssxppc405files.mk53
-rwxr-xr-xsrc/ssx/ssx/Makefile25
-rwxr-xr-xsrc/ssx/ssx/ssx.h126
-rwxr-xr-xsrc/ssx/ssx/ssx_api.h888
-rwxr-xr-xsrc/ssx/ssx/ssx_core.c81
-rwxr-xr-xsrc/ssx/ssx/ssx_init.c159
-rwxr-xr-xsrc/ssx/ssx/ssx_kernel.h281
-rwxr-xr-xsrc/ssx/ssx/ssx_macros.h119
-rwxr-xr-xsrc/ssx/ssx/ssx_semaphore_core.c331
-rwxr-xr-xsrc/ssx/ssx/ssx_semaphore_init.c84
-rwxr-xr-xsrc/ssx/ssx/ssx_stack_init.c87
-rwxr-xr-xsrc/ssx/ssx/ssx_thread_core.c946
-rwxr-xr-xsrc/ssx/ssx/ssx_thread_init.c140
-rwxr-xr-xsrc/ssx/ssx/ssx_timer_core.c447
-rwxr-xr-xsrc/ssx/ssx/ssx_timer_init.c124
-rwxr-xr-xsrc/ssx/ssx/ssxssxfiles.mk35
117 files changed, 41841 insertions, 0 deletions
diff --git a/src/ssx/pgp/Makefile b/src/ssx/pgp/Makefile
new file mode 100755
index 0000000..417a452
--- /dev/null
+++ b/src/ssx/pgp/Makefile
@@ -0,0 +1,38 @@
+# $Id: Makefile,v 1.2 2013/12/12 16:12:28 bcbrock Exp $
+
+# This Makefile compiles all of the SSX code required for the PgP port
+# of SSX. See the "ssx.mk" file in this directory.
+
+include ssx.mk
+include ssxpgpfiles.mk
+
+
+ifeq "$(SSX_TIMER_SUPPORT)" "1"
+PGP_OBJECTS += ${PGP-TIMER-C-SOURCES:.c=.o} ${PGP-TIMER-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(SSX_THREAD_SUPPORT)" "1"
+PGP_OBJECTS += ${PGP-THREAD-C-SOURCES:.c=.o} ${PGP-THREAD-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PGP_ASYNC_SUPPORT)" "1"
+PGP_OBJECTS += ${PGP-ASYNC-C-SOURCES:.c=.o} ${PGP-ASYNC-S-SOURCES:.S=.o}
+endif
+
+
+all: local
+ $(MAKE) -I ../pgp -C ../ssx
+ $(MAKE) -I ../pgp -C ../ppc405
+
+local: $(PGP_OBJECTS)
+
+
+.PHONY : clean
+clean:
+ rm -f *.o *.d *.d.* *.ps *.pdf
+ $(MAKE) -I ../pgp -C ../ssx clean
+ $(MAKE) -I ../pgp -C ../ppc405 clean
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(PGP_OBJECTS:.o=.d)
+endif
diff --git a/src/ssx/pgp/linkssx.cmd b/src/ssx/pgp/linkssx.cmd
new file mode 100755
index 0000000..0556a03
--- /dev/null
+++ b/src/ssx/pgp/linkssx.cmd
@@ -0,0 +1,499 @@
+// $Id: linkssx.cmd,v 1.2 2014/03/14 16:33:45 bcbrock Exp $
+
+// This linker script creates SRAM images of SSX applications for PgP. This
+// script is processed through the C proprocessor to create
+// configuration-dependent images.
+//
+// All sections with different MMU protection properties are 1KB-aligned, even
+// when linked in real-addressing mode.
+//
+// NB: According to *info* manual for ld, it should not be necessary to specify
+// the '.' in the section commands, e.g.,
+//
+// .data.startup . : { *(.data.startup) } > sram
+//
+// However without these the sections are not aligned properly, as the linker
+// seems to ignore the LC and move the section 'backwards' until it abuts
+// (aligned) with the previous one.
+//
+// Info on PPC binaries:
+// http://devpit.org/wiki/Debugging_PowerPC_ELF_Binaries
+
+// Need to do this so that elf32-powerpc is not modified!
+#undef powerpc
+
+#ifndef INITIAL_STACK_SIZE
+#define INITIAL_STACK_SIZE 2000
+#endif
+
+OUTPUT_FORMAT(elf32-powerpc);
+
+// Define the beginning of SRAM, the location of the PowerPC exception
+// vectors (must be 64K-aligned) and the location of the boot branch.
+
+// 512 KB SRAM at the top of the 32-bit address space
+
+#define origin 0xfff80000
+#define vectors 0xfff80000
+#define reset 0xffffffec
+#define sram_available (reset - origin)
+#define sram_size 0x00080000
+
+// The SRAM controller aliases the SRAM at 8 x 128MB boundaries to support
+// real-mode memory attributes using DCCR, ICCR etc. Noncacheable access is
+// the next-to-last 128MB PPC405 region. Write-though access is the
+// next-to-next-to-last 128MB PPC405 region
+
+#define noncacheable_offset 0x08000000
+#define noncacheable_origin (origin - 0x08000000)
+
+#define writethrough_offset 0x10000000
+#define writethrough_origin (origin - 0x10000000)
+
+// Define SSX kernel text sections to be packed into nooks and crannies of
+// the exception vector area. An option is provided _not_ to pack, to help
+// better judge the best way to pack. Note that any code eligible for packing
+// is considered 'core' code that will be needed by the application at
+// runtime. Any header data is _always_ packed into .vectors_0000 however.
+//
+// Note that in order to support MMU protection, we can't pack data along
+// with the text. All of the packed data sections are thus left empty.
+
+
+// .vectors_0000
+
+#define text_0000 \
+*(.vectors_0000)
+
+#define data_0000
+
+
+// .vectors_0100
+
+#define text_0100 \
+ppc405_core.o(.text) \
+ppc405_irq_core.o(.text)
+
+#define data_0100
+
+
+// .vectors_0c00
+
+#if SSX_TIMER_SUPPORT
+#define text_0c00_conditional
+#else
+#define text_0c00_conditional
+#endif
+
+
+#define text_0c00 \
+text_0c00_conditional \
+ppc405_cache_core.o(.text)
+
+#define data_0c00
+
+
+// .vectors_0f00
+
+#if SSX_TIMER_SUPPORT
+
+#if SSX_THREAD_SUPPORT
+#define text_0f00_conditional \
+ssx_timer_init.o(.text) \
+ssx_timer_core.o(.text) \
+ssx_semaphore_core.o(.text)
+#endif /* SSX_THREAD_SUPPORT */
+
+#if !SSX_THREAD_SUPPORT
+#define text_0f00_conditional \
+ssx_timer_init.o(.text) \
+ssx_timer_core.o(.text)
+#endif /* !SSX_THREAD_SUPPORT */
+
+#else /* SSX_TIMER_SUPPORT */
+
+#define text_0f00_conditional
+#endif /* SSX_TIMER_SUPPORT */
+
+#define text_0f00 \
+text_0f00_conditional
+
+#define data_0f00
+
+// .vectors_2000
+
+#if SSX_THREAD_SUPPORT
+#define thread_text \
+ssx_thread_init.o(.text) \
+ssx_thread_core.o(.text) \
+ppc405_irq_init.o(.text) \
+ppc405_thread_init.o(.text) \
+ssx_semaphore_init.o(.text)
+#else
+#define thread_text
+#endif
+
+#if PPC405_MMU_SUPPORT
+#define mmu_text \
+ppc405_mmu.o(.text)\
+ppc405_mmu_asm.o(.text)
+#else
+#define mmu_text
+#endif
+
+#define text_2000 \
+pgp_irq_init.o(.text) \
+ppc405_cache_init.o(.text) \
+ppc405_breakpoint.o(.text) \
+pgp_cache.o(.text) \
+ssx_stack_init.o(.text) \
+thread_text \
+mmu_text \
+pgp_async.o(.text) \
+pgp_async_pore.o(.text) \
+pgp_async_ocb.o(.text) \
+pgp_async_pba.o(.text) \
+pgp_pmc.o(.text) \
+pgp_ocb.o(.text) \
+pgp_pba.o(.text) \
+pgp_id.o(.text) \
+pgp_centaur.o(.text) \
+ppc405_lib_core.o(.text) \
+ssx_core.o(.text) \
+
+#define data_2000
+
+// .vectors_0000 is always packed with header information
+
+#define pack_0000 text_0000 data_0000
+#define nopack_0000
+
+#ifndef NO_PACK_SSX
+
+#define pack_0100 text_0100 data_0100
+#define nopack_0100
+
+#define pack_0c00 text_0c00 data_0c00
+#define nopack_0c00
+
+#define pack_0f00 text_0f00 data_0f00
+#define nopack_0f00
+
+#define pack_2000 text_2000 data_2000
+#define nopack_2000
+
+#else
+
+#define pack_0100
+#define nopack_0100 text_0100 data_0100
+
+#define pack_0c00
+#define nopack_0c00 text_0c00 data_0c00
+
+#define pack_0f00
+#define nopack_0f00 text_0f00 data_0f00
+
+#define pack_2000
+#define nopack_2000 text_2000 data_2000
+
+#endif
+
+#define init_text \
+ssx_init.o(.text) \
+ppc405_boot.o(.text) \
+ppc405_init.o(.text) \
+pgp_init.o(.text)
+
+// Define memory areas.
+
+MEMORY
+{
+ sram : ORIGIN = origin, LENGTH = sram_available
+ noncacheable : ORIGIN = noncacheable_origin, LENGTH = sram_available
+ writethrough : ORIGIN = writethrough_origin, LENGTH = sram_available
+ boot : ORIGIN = reset, LENGTH = 20
+}
+
+// NB: The code that sets up the MMU assumes that the linker script provides a
+// standard set of symbols that define the base address and size of each
+// expected section. Any section with a non-0 size will be mapped in the MMU
+// using protection attributes appropriate for the section. All sections
+// requiring different MMU attributes must be 1KB-aligned.
+
+SECTIONS
+{
+ . = origin;
+ . = vectors;
+
+ _MEMORY_ORIGIN = .;
+ _MEMORY_SIZE = sram_size;
+
+ ////////////////////////////////
+ // Text0
+ ////////////////////////////////
+
+ // Low-memory kernel code and any other code that would benefit from being
+ // resident in lower-latency SRAM
+
+ _TEXT0_SECTION_BASE = .;
+ _PPC405_VECTORS_BASE = .;
+
+ .exceptions . : {
+ ___vectors = .;
+ ppc405_exceptions.o(.vectors_0000)
+ pack_0000
+ . = ___vectors + 0x0100;
+ ppc405_exceptions.o(.vectors_0100)
+ pack_0100
+ . = ___vectors + 0x0c00;
+ ppc405_exceptions.o(.vectors_0c00)
+ pack_0c00
+ . = ___vectors + 0x0f00;
+ ppc405_exceptions.o(.vectors_0f00)
+ pack_0f00
+ . = ___vectors + 0x2000;
+ ppc405_exceptions.o(.vectors_2000)
+ pack_2000
+ } > sram
+
+ // If we're not packing, then place 'core' code immediately after the
+ // exception vectors.
+
+ .nopack . : { nopack_0000 nopack_0100 nopack_0c00 nopack_0f00 nopack_2000 } > sram
+
+ . = ALIGN(1024);
+ _TEXT0_SECTION_SIZE = . - _TEXT0_SECTION_BASE;
+
+ ////////////////////////////////
+ // Noncacheable and Write-through Data
+ ////////////////////////////////
+
+ // Non-cacheable and write-through data is placed in low memory to
+ // improve latency. PORE-private text and data is also placed here. PORE
+ // text and data are segregated to enable relocated PORE disassembly of
+ //.text.pore. PORE text is read-only to OCC, however PORE data is writable
+ // by OCC to allow shared data structures (e.g., PTS).
+
+ // When running without the MMU we need to carefully arrange things such
+ // that the noncacheable and writethrough data is linked at the correct
+ // aliased VMA while remaining loaded in contiguous LMA addresses.
+
+#if PPC405_MMU_SUPPORT
+
+#define ALIASED_SECTION(s) s . : {*(s)} > sram
+
+#else
+
+#define ALIASED_SECTION(s) \
+ _LMA = . + _lma_offset; \
+ s . : AT (_LMA) {*(s)}
+
+#endif
+
+#if !PPC405_MMU_SUPPORT
+ . = . - noncacheable_offset;
+ _lma_offset = noncacheable_offset;
+#endif
+
+ _NONCACHEABLE_RO_SECTION_BASE = .;
+
+ ALIASED_SECTION(.noncacheable_ro)
+ ALIASED_SECTION(.text.pore)
+
+ . = ALIGN(1024);
+ _NONCACHEABLE_RO_SECTION_SIZE = . - _NONCACHEABLE_RO_SECTION_BASE;
+
+
+ _NONCACHEABLE_SECTION_BASE = .;
+
+ ALIASED_SECTION(.noncacheable)
+ ALIASED_SECTION(.data.pore)
+
+ . = ALIGN(1024);
+ _NONCACHEABLE_SECTION_SIZE = . - _NONCACHEABLE_SECTION_BASE;
+
+
+#if !PPC405_MMU_SUPPORT
+ . = . + noncacheable_offset - writethrough_offset;
+ _lma_offset = writethrough_offset;
+#endif
+
+
+ _WRITETHROUGH_SECTION_BASE = .;
+
+ ALIASED_SECTION(.writethrough)
+
+ . = ALIGN(1024);
+ _WRITETHROUGH_SECTION_SIZE = . - _WRITETHROUGH_SECTION_BASE;
+
+#if !PPC405_MMU_SUPPORT
+ . = . + writethrough_offset;
+#endif
+
+
+ ////////////////////////////////
+ // Read-only Data
+ ////////////////////////////////
+
+ // Accesses of read-only data may or may not benefit from being in fast
+ // SRAM - we'll give it the benefit of the doubt.
+
+ _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
+
+ // The .rodata.vclcommand section contains read-only VclCommandRecord for
+ // the benefit of the vcl_console() command interpreter.
+
+ _VCL_COMMAND_SECTION_BASE = .;
+ .rodata.vclcommand . : { *(.rodata.vclcommand) } > sram
+ _VCL_COMMAND_SECTION_SIZE = . - _VCL_COMMAND_SECTION_BASE;
+
+ // The .rodata.vclthread section contains read-only VclThreadRecord for the
+ // benefit of the thread command.
+
+ _VCL_THREAD_SECTION_BASE = .;
+ .rodata.vclthread . : { *(.rodata.vclthread) } > sram
+ _VCL_THREAD_SECTION_SIZE = . - _VCL_THREAD_SECTION_BASE;
+
+ // The .rodata.vclpackage section contains read-only char* pointers for the
+ // benefit of the package command.
+
+ _VCL_PACKAGE_SECTION_BASE = .;
+ .rodata.vclpackage . : { *(.rodata.vclpackage) } > sram
+ _VCL_PACKAGE_SECTION_SIZE = . - _VCL_PACKAGE_SECTION_BASE;
+
+ // Other read-only data.
+
+ .rodata . : { *(.rodata*) *(.got2) } > sram
+
+ . = ALIGN(1024);
+ _RODATA_SECTION_SIZE = . - _RODATA_SECTION_BASE;
+
+ ////////////////////////////////
+ // Text1
+ ////////////////////////////////
+
+ // The default text section
+
+ _TEXT1_SECTION_BASE = .;
+
+ // Initialization text. If we ever do a scheme to get rid of
+ // initialization text then this will have to be moved if we're also doing
+ // MMU protection.
+
+ .itext . : { init_text } > sram
+
+ // Other text
+ // It's not clear why boot.S is generating empty .glink,.iplt
+
+ .otext . : { *(.text) *(.text.startup)} > sram
+ .glink . : { *(.glink) } > sram
+
+ . = ALIGN(1024);
+ _TEXT1_SECTION_SIZE = . - _TEXT1_SECTION_BASE;
+
+ ////////////////////////////////
+ // Read-write Data
+ ////////////////////////////////
+
+ _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
+
+
+ // Initialization-only data. This includes the stack of main, the data
+ // structures declared by INITCALL, and any other data areas that can be
+ // reclaimed to the heap after initialization.
+ //
+ // NB: If we ever do reclaim this space, we need to modify the concept of
+ // executable free space.
+
+ _INIT_ONLY_DATA_BASE = .;
+
+ _SSX_INITIAL_STACK_LIMIT = .;
+ . = . + INITIAL_STACK_SIZE;
+ _SSX_INITIAL_STACK = . - 1;
+
+ _INITCALL_SECTION_BASE = .;
+ .data.initcall . : { *(.data.initcall) } > sram
+ _INITCALL_SECTION_SIZE = . - _INITCALL_SECTION_BASE;
+
+ .data.startup . : { *(.data.startup) } > sram
+
+ _INIT_ONLY_DATA_SIZE = . - _INIT_ONLY_DATA_BASE;
+
+ ////////////////////////////////
+ // Free Space
+ ////////////////////////////////
+
+ // If the configuration allows executing from free space - i.e.,
+ // malloc()-ing a buffer and loading and executing code from it - then the
+ // free space is separated and aligned so that it can be marked executable.
+ // Otherwise it is simply read/write like the normal data sections.
+
+#ifndef EXECUTABLE_FREE_SPACE
+#define EXECUTABLE_FREE_SPACE 0
+#endif
+
+#if PPC405_MMU_SUPPORT && EXECUTABLE_FREE_SPACE
+ . = ALIGN(1024);
+#endif
+
+ // The free space available to the program starts here. This space does
+ // not include the initial stack used by the boot loader and main(). The
+ // initial stack space is considered part of the free 'section' for MMU
+ // purposes. Free space is always 8-byte aligned.
+ //
+ // Note that there is no data after _SSX_FREE_START. When binary images
+ // are created they can be padded to _SSX_FREE_START to guarantee
+ // that .bss and COMMON data are zeroed, and that the images contain an
+ // even multiple of 8 bytes (required for HW loaders).
+
+ . = ALIGN(8);
+ _EX_FREE_SECTION_BASE = .;
+ _SSX_FREE_START = .;
+
+#if EXECUTABLE_FREE_SPACE
+ _DATA_SECTION_SIZE = . - _DATA_SECTION_BASE;
+ _EX_FREE_SECTION_SIZE = 0 - _EX_FREE_SECTION_BASE;
+#else
+ _DATA_SECTION_SIZE = 0 - _DATA_SECTION_BASE;
+ _EX_FREE_SECTION_SIZE = 0;
+#endif
+
+ ////////////////////////////////
+ // Applet areas
+ ////////////////////////////////
+
+ // These symbols are currently unused, but required to be defined.
+
+ _APPLET0_SECTION_BASE = 0;
+ _APPLET0_SECTION_SIZE = 0;
+ _APPLET1_SECTION_BASE = 0;
+ _APPLET1_SECTION_SIZE = 0;
+
+ // The final 16 bytes of memory are reserved for the hardware boot branch
+
+ _SSX_FREE_END = reset - 1;
+}
+
diff --git a/src/ssx/pgp/pgp.h b/src/ssx/pgp/pgp.h
new file mode 100755
index 0000000..fb99e4f
--- /dev/null
+++ b/src/ssx/pgp/pgp.h
@@ -0,0 +1,328 @@
+#ifndef __PGP_H__
+#define __PGP_H__
+
+// $Id: pgp.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp.h
+/// \brief The PgP environment for SSX.
+
+// This is a 'circular' reference in SSX, but included here to simplify PGAS
+// programming.
+
+#ifndef CHIP_PGP
+#define CHIP_PGP
+#include "ppc405.h"
+#endif
+
+// Can't include this here due to ordering issues. It's included in
+// ppc405_irq.h.
+// #include "pgp_irq.h"
+
+// Required for MMU Map declarations
+#include "ppc405_mmu.h"
+
+#include "pgp_common.h"
+#include "pgp_core.h"
+#include "pgp_trace.h"
+#include "pgp_ocb.h"
+#include "pgp_pba.h"
+#include "pgp_pore.h"
+#include "pgp_pmc.h"
+#include "pgp_sramctl.h"
+#include "pgp_vrm.h"
+#include "pgp_id.h"
+#include "pgp_centaur.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"
+
+#include "mcs_register_addresses.h"
+#include "mcs_firmware_registers.h"
+
+#include "centaur_firmware_registers.h"
+#include "centaur_register_addresses.h"
+
+#include "tpc_register_addresses.h"
+#include "tpc_firmware_registers.h"
+
+#include "oha_register_addresses.h"
+#include "oha_firmware_registers.h"
+
+
+// Include other driver headers
+
+#include "pgp_async.h"
+
+/// \defgroup memory_map Real-mode memory map setup for SRAM-resident applications
+///
+/// Below are the interpretations of the default settings of the real-mode
+/// memory control registers. All of the settings can be overridden as
+/// compile switches for special test purposes.
+///
+/// The final 128MB of memory (the SRAM) is mapped both I- and
+/// D-cacheable. The other 7 high-memory regions aliased by the SRAM remain
+/// uncacheable, however SRAM alias region 29 is marked write-through.
+///
+/// Low memory addresses (direct-map Mainstore via PBA) are I-cacheable
+/// but not D-cacheable to improve predicatability of execution times.
+/// However, we should not execute from mainstore after initialization.
+///
+/// OCI register space (Segment '0b01') is marked guarded and non-cacheable.
+///
+/// All memory is big-endian.
+///
+/// @{
+
+#ifndef PPC405_ICCR_INITIAL
+#define PPC405_ICCR_INITIAL 0xff000001
+#endif
+
+#ifndef PPC405_DCCR_INITIAL
+#define PPC405_DCCR_INITIAL 0x00000001
+#endif
+
+#ifndef PPC405_DCWR_INITIAL
+#define PPC405_DCWR_INITIAL 0x00000004
+#endif
+
+#ifndef PPC405_SGR_INITIAL
+#define PPC405_SGR_INITIAL 0x00ff0000
+#endif
+
+#ifndef PPC405_SU0R_INITIAL
+#define PPC405_SU0R_INITIAL 0x00000000
+#endif
+
+#ifndef PPC405_SLER_INITIAL
+#define PPC405_SLER_INITIAL 0x00000000
+#endif
+
+/// @}
+
+
+/// PgP always runs from a memory image
+
+#define SSX_RUN_FROM_MEMORY 1
+
+/// This is the initial value of Cache Control Register 0 (CCR0) for PgP.
+/// This definition can be overridden by the application.
+///
+/// The default setting:
+///
+/// - Enables parity checking in the caches and TLBs. The parity mode is not
+/// modified and defaults to 'imprecise'.
+///
+/// - Enables ICU prefetching for cacheable regions (Subject to final
+/// performance evaluation). Non-cacheable regions are not prefetched.
+///
+/// - Gives highest PLB priority to ICU fetches. This setting can be
+/// overriden by scan-only dials in the PgP design which force a fixed
+/// priority on the ICU.
+///
+/// - Sets priority bit 1 to '1' for DCU operations. The DCU sets priority
+/// bit 0 automatically. This setting can also be overridden by scan-only
+/// dials that force a fixed priority on the DCU
+///
+/// Other options can be set at run time with the API \c ppc405_ccr0_modify().
+
+#ifndef PPC405_CCR0_INITIAL
+#define PPC405_CCR0_INITIAL \
+ (CCR0_DPE | CCR0_IPE | CCR0_TPE | \
+ CCR0_PFC | \
+ CCR0_IPP0 | CCR0_IPP1 | \
+ CCR0_DPP1)
+#endif
+
+
+#ifndef __ASSEMBLER__
+
+/// \page noncacheable_support Non-cacheable modes for PgP
+///
+/// In order to support evaluation of cache management strategies on
+/// performance, DMA buffers read/written by DMA devices can be declared as
+/// NONCACHEABLE or NONCACHEABLE_RO, and DMA buffers read by DMA devices can
+/// be declared as WRITETHROUGH. However the code still does an explicit
+/// FLUSH of these buffers before activating DMA devices. The configuration
+/// option NONCACHEABLE_SUPPORT determines how NONCACHEABLE, NONCACAHEABLE_RO,
+/// WRITETHROUGH and FLUSH are defined.
+///
+/// When noncacheable support is configured, the linker will link the
+/// noncacheable and writethrough sections at a fixed offset from cacheable
+/// address, depending on where SSX is loaded. Non-cacheable read-only
+/// sections are enforced only if PPC405_MMU_SUPPORT is also configured.
+/// Writethrogh sections are assumed to be read-write.
+///
+/// PGP_HIGH_MEMORY_LOAD
+///
+/// cacheable : 0xfff8000 - 0xffffffff
+/// noncacheable : 0xf7f8000 - 0xf7ffffff [cacheable - 128MB]
+/// writethrough : 0xeff8000 - 0xefffffff [cacheable - 256MB]
+
+
+#ifndef NONCACHEABLE_SUPPORT
+#define NONCACHEABLE_SUPPORT 0
+#endif
+
+
+/// Declare an aligned data structure in a noncacheable RO section
+///
+/// This macro declares an aligned data structure in a noncacheable read-only
+/// section. The linker requires that data allocated in non-default sections
+/// be initialized - so an initialization declaration for at least one element
+/// of the data structure is required. Use a value of 8 as the default
+/// alignment.
+///
+/// See \ref noncacheable_support
+
+#if NONCACHEABLE_SUPPORT
+
+#define NONCACHEABLE_RO(declaration, alignment, initialization) \
+ declaration __attribute__ \
+ ((section (".noncacheable_ro"), aligned (alignment))) = initialization
+
+#else
+
+#define NONCACHEABLE_RO(declaration, alignment, initialization) \
+ declaration __attribute__ \
+ ((aligned (alignment))) = initialization
+
+#endif /* NONCACHEABLE_SUPPORT */
+
+
+/// Declare an aligned data structure in a noncacheable RW section
+///
+/// This macro declares an aligned data structure in a noncacheable read-write
+/// section. The linker requires that data allocated in non-default sections
+/// be initialized - so an initialization declaration for at least one element
+/// of the data structure is required. Use a value of 8 as the default
+/// alignment.
+///
+/// See \ref noncacheable_support
+
+#if NONCACHEABLE_SUPPORT
+
+#define NONCACHEABLE(declaration, alignment, initialization) \
+ declaration __attribute__ \
+ ((section (".noncacheable"), aligned (alignment))) = initialization
+
+#else
+
+#define NONCACHEABLE(declaration, alignment, initialization) \
+ declaration __attribute__ \
+ ((aligned (alignment))) = initialization
+
+#endif /* NONCACHEABLE_SUPPORT */
+
+
+/// Declare an aligned data structure in a write-through section
+///
+/// This macro declares an aligned data structure in a write-throgh section.
+/// The linker requires that data allocated in non-default sections be
+/// initialized - so an initialization declaration for at least one element of
+/// the data structure is required. Use a value of 8 as the default
+/// alignment.
+///
+/// See \ref noncacheable_support
+
+#if NONCACHEABLE_SUPPORT
+
+#define WRITETHROUGH(declaration, alignment, initialization) \
+ declaration __attribute__ \
+ ((section (".writethrough"), aligned (alignment))) = initialization
+
+#else
+
+#define WRITETHROUGH(declaration, alignment, initialization) \
+ declaration __attribute__ \
+ ((aligned (alignment))) = initialization
+
+#endif /* NONCACHEABLE_SUPPORT */
+
+
+/// Flush/invalidate a region of memory
+
+#if NONCACHEABLE_SUPPORT
+#define FLUSH(p, n) do {} while (0)
+#define INVALIDATE(p, n) do {} while (0)
+#else
+#define FLUSH(p, n) do {dcache_flush((p), (n));} while (0)
+#define INVALIDATE(p, n) do {dcache_invalidate((p), (n));} while (0)
+#endif /* NONCACHEABLE_SUPPORT */
+
+
+/// The type of linker symbols
+///
+/// C++ and current GCC versions do not allow us to declare (C++) or take the
+/// address of (C) a symbol of type void, which was an acceptable way to
+/// declare linker symbols in earlier versions of GCC. However if we declare
+/// them of type 'char' or another integral type, the compiler will try to
+/// make references to this 'data' appear to be in the small data areas (since
+/// we're compiling with the PPC EABI), which causes the link to fail since
+/// the symbols are actually defined in many different sections. The solution
+/// is to declare them to be external references of a bogus type,
+/// SsxLinkerSymbol, which is too large (9 bytes) to be stored in the small
+/// data area.
+///
+/// This type definition is considered a required definition for a port of
+/// SSX.
+
+typedef struct {
+ char bogus[9];
+} SsxLinkerSymbol;
+
+// Symbols defined by linkssx.cmd, used during MMU setup, byte-pool setup, and
+// other purposes.
+
+extern SsxLinkerSymbol _MEMORY_ORIGIN;
+extern SsxLinkerSymbol _MEMORY_SIZE;
+extern SsxLinkerSymbol _TEXT0_SECTION_BASE;
+extern SsxLinkerSymbol _TEXT0_SECTION_SIZE;
+extern SsxLinkerSymbol _TEXT1_SECTION_BASE;
+extern SsxLinkerSymbol _TEXT1_SECTION_SIZE;
+extern SsxLinkerSymbol _RODATA_SECTION_BASE;
+extern SsxLinkerSymbol _RODATA_SECTION_SIZE;
+extern SsxLinkerSymbol _NONCACHEABLE_RO_SECTION_BASE;
+extern SsxLinkerSymbol _NONCACHEABLE_RO_SECTION_SIZE;
+extern SsxLinkerSymbol _NONCACHEABLE_SECTION_BASE;
+extern SsxLinkerSymbol _NONCACHEABLE_SECTION_SIZE;
+extern SsxLinkerSymbol _WRITETHROUGH_SECTION_BASE;
+extern SsxLinkerSymbol _WRITETHROUGH_SECTION_SIZE;
+extern SsxLinkerSymbol _DATA_SECTION_BASE;
+extern SsxLinkerSymbol _DATA_SECTION_SIZE;
+extern SsxLinkerSymbol _EX_FREE_SECTION_BASE;
+extern SsxLinkerSymbol _EX_FREE_SECTION_SIZE;
+extern SsxLinkerSymbol _APPLET0_SECTION_BASE;
+extern SsxLinkerSymbol _APPLET0_SECTION_SIZE;
+extern SsxLinkerSymbol _APPLET1_SECTION_BASE;
+extern SsxLinkerSymbol _APPLET1_SECTION_SIZE;
+extern SsxLinkerSymbol _SSX_FREE_START;
+extern SsxLinkerSymbol _SSX_FREE_END;
+
+// Global MMU maps to allow remapping certain regions
+
+extern Ppc405MmuMap G_ex_free_mmu_map;
+extern Ppc405MmuMap G_applet0_mmu_map;
+extern Ppc405MmuMap G_applet1_mmu_map;
+
+#endif /* __ASSEMBLER__ */
+
+// PgP defines a private version of dcache_flush_all() that uses the undefined
+// OCI space at 0x80000000; See dcache_flush_all() in pgp_cache.S.
+
+#define USE_GENERIC_DCACHE_FLUSH_ALL 0
+#define PGP_FLUSH_ZERO_ADDRESS 0x80000000
+#define PGP_FLUSH_ZERO_DCCR 0x00008000
+
+#endif /* __PGP_H__ */
diff --git a/src/ssx/pgp/pgp_async.c b/src/ssx/pgp/pgp_async.c
new file mode 100755
index 0000000..3bf9a63
--- /dev/null
+++ b/src/ssx/pgp/pgp_async.c
@@ -0,0 +1,1024 @@
+// $Id: pgp_async.c,v 1.4 2014/02/14 12:18:05 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_async.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_async.c
+/// \brief Support for asynchronous request queuing and callback mechanisms
+///
+/// This file implements device drivers for asynchronous requests. The model
+/// for devices like the PORE engines and the PBA block copy engines is that
+/// the application creates self-contained requests for jobs to run on the
+/// engine. The application then schedules the request and continues normal
+/// processing, or threads can request to simply block in place until the
+/// request finishes. Queue management is handled in the interrupt handler
+/// for the engine. As each queued job finishes, the next request (if any) is
+/// started on the engine and the optional callback is invoked or scheduled.
+///
+/// The application can either use a polling protocol or the asynchronous
+/// callback mechanism to determine the state of the request. A timeout
+/// mechanism is also provided that cancels or kills a job that does not
+/// complete within a fixed time. Error handling in the event that the request
+/// does not complete in time or has failed is standardized by the
+/// implementation, but can be overridden by the application.
+///
+/// Asynchronous request interrupt handlers can run either as critical or
+/// noncritical handlers. Some engines may support queuing requests that
+/// complete immediately; therefore the kernel context of the callback may be
+/// either a thread or interupt context, and in general, callbacks should not
+/// make assumptions about the kernel context when they run.
+///
+/// If the callback is non-NULL and the request was created with \c
+/// ASYNC_CALLBACK_IMMEDIATE, the callback is then immediately invoked in the
+/// current context. In general, immediate callbacks should be short and sweet
+/// (to reduce interrupt latency) and should not make SSX kernel calls.
+///
+/// If the request has a non-NULL callback and was created with \c
+/// ASYNC_CALLBACK_DEFERRED then the callback will be deferred to a
+/// noncritical interrupt context. Deferred callbacks are queued, then run
+/// later in response to a reserved IPI. Deferred callbacks always run as
+/// noncritical interrupt handlers with noncritical interrupts \e enabled,
+/// similar to SSX timer callbacks.
+///
+/// If the request has a non-null callback and was created with \c
+/// ASYNC_CALLBACK_NONCRITICAL, then the callback will be run immediately from
+/// a noncritical handler or thread environment, or deferred from a critical
+/// interrupt context. Similar to immediate callbacks, callbacks marked
+/// noncritical should be short and sweet (to reduce interrupt latency), but
+/// may make SSX kernel calls.
+///
+/// Regardless of whether the callback is critical or noncritical, the
+/// callback is coded as a normal C or assembler subroutine with a single
+/// void* argument.
+///
+/// As a programming shortcut, the AsyncRequest includes a semaphore object.
+/// A special AsyncRequest option ASYNC_REQUEST_BLOCKING indicates that the
+/// thread scheduling the request should block on the semaphore of the
+/// AsyncRequest (with SSX_WAIT_FOREVER) until the request is complete. Note
+/// that a separate callback can be specified even if ASYNC_REQUEST_BLOCKING
+/// is specified.
+///
+/// Requests are always timestamped. The \a start_time field of the request is
+/// set from the SSX timebase when the request is first 'run' on the device.
+/// Request types that may require multiple back-to-back 'runs' (like PBA
+/// block copies with more than 4K data) only record the initial 'run'. The \a
+/// end_time field of the request is set from the SSX timebase when the job
+/// finishes on the hardware, but before any callback is run. These
+/// timestamps cover time intervals not visible to the application; The
+/// application is responsible for timestamping the period between request
+/// queing and the \a start_time, and between the \a end_time and callback
+/// completion if required. The timestamps can be robustly recovered from the
+/// request using the API async_request_timestamps_get().
+///
+/// This is largely a generic implementation, designed to reduce code space by
+/// allowing the PORE, PBA and OCB drivers to use the same generic data
+/// structures and code. This is supported by the 'single-inheritence class
+/// hierarchy' described in the comments for pgp_async.h.
+///
+/// <b> Request Completion and Callback States </b>
+///
+/// The application can determine what happend to the job by observing the
+/// request state and callback return code when the request becomes idle.
+/// A request is not considered idle until the job has run to completion or
+/// been aborted, any callback has been run, any timeout has been cancelled,
+/// and any thread pending on request completion has been maxde runnable.
+///
+/// Normally the application should see the request state (\a request->state)
+/// ASYNC_REQUEST_STATE_COMPLETE and a callback return code
+/// (\a request=->callback_rc) of 0 which indicates that the job and callback
+/// both completed normally. If the request did not complete normally it
+/// could be due to one of several reasons. For further analysis the request
+/// also includes a field \a abort_state that records the state the job was in
+/// when it was aborted (i.e., cancelled, killed, timed out or error-out).
+///
+/// <b> Timeout Semantics </b>
+///
+/// Any timeout other than SSX_WAIT_FOREVER specifies a timeout covering the
+/// interval spanning the time a job is scheduled until the time the job
+/// completes on the hardware. If the job is still wating to execute when it
+/// times out then the job is simply removed from the queue and marked as
+/// having timed out. If the job is running when it times out then the job is
+/// forceably removed from the hardware, which may have unintended or
+/// indeterminate consequences. The application may need to consider whether
+/// it is safe to continue after a forced timeout.
+///
+/// Specifying a timeout involves quite a bit of overhead, since a timer needs
+/// to be scheduled and cancelled each time a job is run. If the interrupt
+/// handler for a device is a critical handler then the timeout cancellation
+/// will need to be deferred to the callback queue, potentially increasing
+/// overhead even further.
+///
+/// <b> Implementation Notes </b>
+///
+/// - The \e queue objects will normally be global data structures that
+/// persist throughout the life of the application.
+///
+/// - The \e request objects may be either global or local data
+/// structures. However, since \e request objects are not copied, and pointers
+/// to them are stored in the \e queue objects, \a request objects should not
+/// be allocated on the stack if the stack frame could become invalid before
+/// the request completes.
+///
+/// \todo Once all function is developed and tested, convert interrupt
+/// handling to fast-mode assembler routines.
+
+#include "ssx.h"
+
+
+////////////////////////////////////////////////////////////////////////////
+// Global Data
+////////////////////////////////////////////////////////////////////////////
+
+/// Queue of deferred callbacks
+
+static SsxDeque G_async_callback_queue;
+
+
+////////////////////////////////////////////////////////////////////////////
+// FFDC
+////////////////////////////////////////////////////////////////////////////
+
+/// Collect FFDC for the PLB (OCI) arbiter
+///
+/// \param ffdc A pointer to an OciFfdc structure to be filled in.
+///
+/// \param master_id The PLB (OCI) master Id of the master of interest.
+///
+/// Note: The PEAR and PESR hold error information for all OCI masters
+/// _except_ the OCC ICU and DCU. ICU and DCU errors are in the STO_PESR and
+/// STO_PEAR. Currently there is no need to collect those DCRs for 'async'
+/// errors.
+
+void
+oci_ffdc(OciFfdc* ffdc, int master_id)
+{
+ uint32_t pesr_lock_mask;
+
+ ffdc->pearl.value = mfdcr(PLB_PEARL);
+ ffdc->pesr.value = mfdcr(PLB_PESR);
+
+ pesr_lock_mask = 0x30000000 >> (4 * master_id);
+ if (ffdc->pesr.value & pesr_lock_mask) {
+ ffdc->mine = 1;
+ mtdcr(PLB_PESR, pesr_lock_mask);
+ } else {
+ ffdc->mine = 0;
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// AsyncQueue
+////////////////////////////////////////////////////////////////////////////
+
+// Start an asynchronous request on the device with timestamping. This will
+// always be called from a critical section, and any timestamp is collected
+// immediately before the request is kicked off on the device. Devices like
+// the BCE engines and the OCB queue drivers may run the same request multiple
+// times to get all of the data moved. Therefore the initial timestamp is only
+// captured the first time the request is run on the device.
+
+static inline int
+async_request_run(AsyncRequest *request)
+{
+ if (request->state != ASYNC_REQUEST_STATE_RUNNING) {
+ request->start_time = ssx_timebase_get();
+ }
+ request->state = ASYNC_REQUEST_STATE_RUNNING;
+ return request->run_method(request);
+}
+
+
+// Create (initialize) a generic AsyncQueue
+//
+// This is an internal API used to initialize generic request queues. The
+// caller is assumed to have done all error checking on the parameters.
+//
+// This is a simple initialization that resets the queues and sets the state
+// to QUEUE_STATE_IDLE. This routine should only be called on uninitialized
+// AsyncQueue objects.
+
+int
+async_queue_create(AsyncQueue *queue, AsyncEngine engine)
+{
+ ssx_deque_sentinel_create(&(queue->deque));
+ queue->current = 0;
+ queue->engine = engine;
+ queue->state = ASYNC_QUEUE_STATE_IDLE;
+
+ return 0;
+}
+
+
+// Generic completion of a request. This is called both by async_handler()
+// and async_request_deque().
+
+static void
+async_request_complete(AsyncRequest *request)
+{
+ SsxMachineContext ctx;
+ AsyncRequestCallback callback;
+ int completed;
+
+ // Handle callbacks and deferred processing of the job that just
+ // finished. No callback is easy. If the job does have a callback
+ // that we can execute immediately then that is done immediately.
+ // Note that 'completed' here means only that the callback is complete.
+
+ callback = request->callback;
+ if (!callback) {
+
+ completed = 1;
+
+ } else if ((request->options & ASYNC_CALLBACK_IMMEDIATE) ||
+ ((request->options & ASYNC_CALLBACK_NONCRITICAL) &&
+ !__ssx_kernel_context_critical_interrupt())) {
+
+ request->state = ASYNC_REQUEST_STATE_CALLBACK_RUNNING;
+ request->callback_rc = callback(request->arg);
+ completed = 1;
+
+ } else {
+
+ request->state = ASYNC_REQUEST_STATE_CALLBACK_QUEUED;
+ completed = 0;
+ }
+
+
+ // If the callback completed then we go ahead and cancel any timeout
+ // and/or wake the thread if possible. In critical interrupt contexts
+ // we always have to defer these operations, so we may lose 'complete'
+ // status.
+
+ if (completed &&
+ ((request->timeout != SSX_WAIT_FOREVER) ||
+ (request->options & ASYNC_REQUEST_BLOCKING))) {
+
+ if (__ssx_kernel_context_critical_interrupt()) {
+
+ request->state = ASYNC_REQUEST_STATE_POSTPROCESSING;
+ completed = 0;
+
+ } else {
+ if (request->timeout != SSX_WAIT_FOREVER) {
+ ssx_timer_cancel(&(request->timer));
+ }
+ if (request->options & ASYNC_REQUEST_BLOCKING) {
+ ssx_semaphore_post(&(request->sem));
+ }
+ }
+ }
+
+
+ // A truly completed job gets its completion state here. Otherwise we
+ // have to schedule the deferred postprocessing.
+
+ if (completed) {
+
+ request->state = request->completion_state;
+
+ } else {
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ if (request->options & ASYNC_CALLBACK_PRIORITY) {
+ ssx_deque_push_front(&G_async_callback_queue,
+ &(request->deque));
+ } else {
+ ssx_deque_push_back(&G_async_callback_queue,
+ &(request->deque));
+ }
+
+ ssx_critical_section_exit(&ctx);
+ ssx_irq_status_set(PGP_IRQ_ASYNC_IPI, 1);
+ }
+}
+
+
+// The generic handler for asynchonous device completion.
+//
+// This handler processes completions of generic device requests, as well as
+// the initial running of jobs when the queue is idle. Error completions are
+// initially handled by async_error_handler() which then calls async_handler()
+// to finish the failed job and start the next job if possible. The initial
+// device handler must manage interrupts and provide a method to run the
+// 'current' job in the queue. The engine-specific handler may also iterate
+// the current job until it is complete - this handler should only be called
+// when the current job is complete.
+//
+// Some engines may have jobs that can complete immediately. This handler
+// iterates over jobs in the queue as long as the run method of the current
+// job returns the code -ASYNC_REQUEST_COMPLETE.
+//
+// NB : Normally this call is made from an interrupt handler, however it may
+// be called from job scheduling code if the engine is idle. Regardless, the
+// caller must insure that any call for a queue is protected against
+// interrupts for that queue.
+
+void
+async_handler(AsyncQueue *queue)
+{
+ AsyncRequest *finished, *current;
+ int rc;
+
+ // This loop is repeated as long as any job started in a loop completes
+ // immediately.
+
+ do {
+
+ // This API may be called on an idle queue, which indicates that we
+ // should simply start the job on the head of the queue. Otherwise
+ // save a pointer to the job that just finished and update its
+ // end_time.
+
+ if (queue->state == ASYNC_QUEUE_STATE_IDLE) {
+
+ finished = 0;
+
+ } else {
+
+ finished = (AsyncRequest *)(queue->current);
+
+ if (SSX_ERROR_CHECK_KERNEL && (finished == 0)) {
+ SSX_PANIC(ASYNC_PHANTOM_INTERRUPT);
+ }
+
+ finished->end_time = ssx_timebase_get();
+
+ }
+
+
+ // If the queue is in an error state we will not schedule any further
+ // jobs on this queue. Otherwise we start the next job running on the
+ // engine.
+
+ if (queue->state == ASYNC_QUEUE_STATE_ERROR) {
+
+ queue->current = 0;
+ rc = 0;
+
+ } else {
+
+ current = (AsyncRequest *)ssx_deque_pop_front(&(queue->deque));
+ queue->current = current;
+
+ if (current) {
+ queue->state = ASYNC_QUEUE_STATE_RUNNING;
+ rc = async_request_run(current);
+ } else {
+ queue->state = ASYNC_QUEUE_STATE_IDLE;
+ rc = 0;
+ }
+ }
+
+
+ // If no job just finished, continue with the loop. If the job we
+ // just enqueued finished immediately it will be 'finished' on the
+ // next loop (it would have given an rc ==
+ // -ASYNC_REQUEST_COMPLETE). Otherwise complete the request.
+
+ if (finished != 0) {
+
+ async_request_complete(finished);
+ }
+
+ } while (rc == -ASYNC_REQUEST_COMPLETE);
+}
+
+
+/// Schedule (queue for execution) a generic asynchronous request.
+///
+/// \param request An initialized and idle AsyncRequest
+///
+///
+/// The request is queued for execution with all of the parameters provided
+/// when the request was created. It is considered an error to (re)schedule a
+/// request that is currently scheduled, running, or has the callback queued or
+/// in execution. Requests either need to be idle, or must be explicitly
+/// cancelled or killed before thay can be (re)scheduled. Because engine queue
+/// interrupt handlers may run as critical interrupts, this routine operates in
+/// a short \c SSX_CRITICAL critical section.
+///
+/// If the request is made to an otherwise empty queue then the async_handler()
+/// must also be called immediately to begin the job. This will extend the
+/// critical section slightly. This routine will not start a request on a
+/// queue that has halted due to an error. The request will simply be enqueued
+/// in that case.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_SCHEDULE The \a request is NULL (0).
+///
+/// \retval -ASYNC_REQUEST_NOT_IDLE The \a request is (still) active in some
+/// way at entry.
+///
+/// \retval -ASYNC_REQUEST_NOT_COMPLETE This code is returned for requests that
+/// do not complete successfully, but only if ASYNC_REQUEST_BLOCKING is
+/// specified. The caller will need to examine the request state if necessary
+/// to determine whether the request failed, was cancelled or timed out.
+///
+/// \todo Consider making the critical section priority depend on the device
+/// queue priority here, by adding a priority field to the queue. Without this
+/// we always have to run the async_handler() in an SSX_CRITICAL critical
+/// section.
+
+int
+async_request_schedule(AsyncRequest *request)
+{
+ SsxMachineContext ctx = SSX_THREAD_MACHINE_CONTEXT_DEFAULT; // For GCC
+ AsyncQueue *queue;
+ int rc;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(request == 0, ASYNC_INVALID_OBJECT_SCHEDULE);
+ }
+
+ rc = 0;
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ do {
+
+ // Check to insure the request is idle (which check must be done in
+ // the critical section), then start any required timeout.
+
+ if (SSX_ERROR_CHECK_API) {
+ if (!async_request_is_idle(request)) {
+ rc = -ASYNC_REQUEST_NOT_IDLE;
+ break;
+ }
+ }
+
+ if (request->timeout != SSX_WAIT_FOREVER) {
+ rc = ssx_timer_schedule(&(request->timer), request->timeout, 0);
+ if (rc) break;
+ }
+
+
+ // Enqueue the request and initialize the request state.
+
+ queue = request->queue;
+
+ if (request->options & ASYNC_REQUEST_PRIORITY) {
+ ssx_deque_push_front(&(queue->deque), &(request->deque));
+ } else {
+ ssx_deque_push_back(&(queue->deque), &(request->deque));
+ }
+
+ request->state = ASYNC_REQUEST_STATE_QUEUED;
+ request->completion_state = ASYNC_REQUEST_STATE_COMPLETE;
+ request->callback_rc = 0;
+
+
+ // If the queue is idle, call the async_handler() to start the job.
+ // Then block the calling thread if required.
+
+ if (queue->state == ASYNC_QUEUE_STATE_IDLE) {
+ async_handler(queue);
+ }
+
+ if (request->options & ASYNC_REQUEST_BLOCKING) {
+ rc = ssx_semaphore_pend(&(request->sem), SSX_WAIT_FOREVER);
+ if (rc) break;
+
+ if (!async_request_completed(request)) {
+ rc = -ASYNC_REQUEST_NOT_COMPLETE;
+ break;
+ }
+ }
+
+ } while (0);
+
+ ssx_critical_section_exit(&ctx);
+
+ return rc;
+}
+
+
+// The generic error handler
+//
+// This is a generic handler called in response to an error interrupt or
+// timeout. This handler calls a request-specific error method to stop the
+// hardware device, collect FFDC and make the hardware device runnable again
+// if possible. Then the current request is marked as having failed, and the
+// generic async_handler() is called which will start the next job (if any)
+// and take care of the callbacks for the failed request. If the error
+// method returns a non-0 return code then the error is non-recoverable and
+// the queue is marked with the error state.
+
+void
+async_error_handler(AsyncQueue* queue, uint8_t completion_state)
+{
+ AsyncRequest *finished;
+
+ finished = (AsyncRequest *)(queue->current);
+
+ if (SSX_ERROR_CHECK_KERNEL && (finished == 0)) {
+ SSX_PANIC(ASYNC_PHANTOM_ERROR);
+ }
+
+ if (finished->error_method) {
+ if (finished->error_method(finished)) {
+ queue->state = ASYNC_QUEUE_STATE_ERROR;
+ }
+ }
+ finished->abort_state = finished->state;
+ finished->completion_state = completion_state;
+ async_handler(queue);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// AsyncRequest
+////////////////////////////////////////////////////////////////////////////
+
+// Dequeue a queued AsyncRequest
+//
+// This is an internal API, always called from an SSX_CRITICAL critical
+// section. The request is known to be queued in one of the async queues. It
+// is removed from the queue and its state is updated.
+
+static void
+async_request_dequeue(AsyncRequest* request, uint8_t completion_state)
+{
+ ssx_deque_delete((SsxDeque*)request);
+ request->abort_state = request->state;
+ request->completion_state = completion_state;
+ async_request_complete(request);
+}
+
+
+// Time out an AsyncRequest
+//
+// This is an internal API, the timer callback used to time out long-running
+// AsyncRequest.
+//
+// This timer callback must run in an SSX_CRITICAL critical section to
+// guarantee atomic access to the AsyncRequest object.
+
+static void
+async_timeout(void* arg)
+{
+ AsyncRequest *request = (AsyncRequest*)arg;
+ SsxMachineContext ctx;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ // The behavior at timeout depends on the mode. We'll handle the cases
+ // from easiest to hardest.
+
+ if (request->state & ASYNC_REQUEST_CALLBACK_GROUP) {
+
+ // If the request has already queued or is running the callback (which
+ // could happen due to interrupt interleaving) then the request is
+ // already finished, and it will eventually make a (redundant) call to
+ // ssx_timer_cancel() to cancel the timer. So there's nothing to do.
+
+
+ } else if (request->state & ASYNC_REQUEST_IDLE_GROUP) {
+
+ // If the request is idle we panic - This can't happen as it would
+ // indicate that the timer was not cancelled when the request
+ // finished.
+
+ SSX_PANIC(ASYNC_TIMEOUT_BUG);
+
+
+ } else if (request->state & ASYNC_REQUEST_QUEUED_GROUP) {
+
+ // If the request is still in the queue then we can simply cancel it,
+ // which includes running the callback.
+
+ async_request_dequeue(request, ASYNC_REQUEST_STATE_TIMED_OUT);
+
+
+ } else if (request->state & ASYNC_REQUEST_RUNNING_GROUP) {
+
+ // If the request is running on the hardware, then we need to call
+ // the async_error_handler() to remove the job and restart the
+ // hardware, which includes running the callback.
+
+ async_error_handler(request->queue, ASYNC_REQUEST_STATE_TIMED_OUT);
+
+
+ } else {
+
+ SSX_PANIC(ASYNC_INVALID_STATE);
+
+ }
+
+ ssx_critical_section_exit(&ctx);
+}
+
+
+// Create (initialize) a generic AsyncRequest
+//
+// This is an internal API used to initialize generic requests. However this
+// API does some error checking, and any errors will be returned by the
+// higher-level call.
+//
+// \retval -ASYNC_INVALID_OBJECT_REQUEST The \a request or \a queue was
+/// null (0).
+//
+// \retval -ASYNC_INVALID_OPTIONS The \a options argument contains invalid
+// options, or more than one callback protocol was selected.
+//
+// \retval -ASYNC_INVALID_ARGUMENT The \a run_method was null.
+//
+// \retval -ASYNC_CALLBACK_PROTOCOL_UNSPECIFIED The request includes a
+// non-NULL callback, but no protocol for running the callback was specified.
+
+int
+async_request_create(AsyncRequest *request,
+ AsyncQueue *queue,
+ AsyncRunMethod run_method,
+ AsyncErrorMethod error_method,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((request == 0) || (queue == 0),
+ ASYNC_INVALID_OBJECT_REQUEST);
+ SSX_ERROR_IF((options & ~ASYNC_GENERIC_OPTIONS) ||
+ (__builtin_popcount(options & ASYNC_CALLBACK_OPTIONS) > 1),
+ ASYNC_INVALID_OPTIONS);
+ SSX_ERROR_IF(run_method == 0, ASYNC_INVALID_ARGUMENT);
+ SSX_ERROR_IF((callback != 0) &&
+ ((options & ASYNC_CALLBACK_OPTIONS) == 0),
+ ASYNC_CALLBACK_PROTOCOL_UNSPECIFIED);
+ }
+
+ ssx_deque_element_create(&(request->deque));
+ request->queue = queue;
+ request->run_method = run_method;
+ request->error_method = error_method;
+ request->timeout = timeout;
+ request->state = ASYNC_REQUEST_STATE_INITIALIZED;
+ request->callback = callback;
+ request->arg = arg;
+ request->options = options;
+
+ if (request->timeout != SSX_WAIT_FOREVER) {
+ ssx_timer_create(&(request->timer), async_timeout, (void*)request);
+ }
+
+ if (options & ASYNC_REQUEST_BLOCKING) {
+ ssx_semaphore_create(&(request->sem), 0, 1);
+ }
+
+
+ return 0;
+}
+
+
+/// Get timestamps from an AsyncRequest object
+///
+/// \param request A pointer to an AsyncRequest
+///
+/// \param start_time A pointer to a location to get the \a start_time of the
+/// request, or NULL (0) if this data is not required.
+///
+/// \param end_time A pointer to a location to get the \a end_time of the
+/// request, or NULL (0) is this data is not required.
+///
+/// \retval 0 The request contains valid timestamps and they have been
+/// returned.
+///
+/// \retval -ASYNC_INVALID_TIMESTAMPS The caller's timestamps have been
+/// updated, but the timestamps are fully or partially invalid. This could be
+/// due to several reasons:
+///
+/// - The request has never been scheduled
+/// - The request has been scheduled but has not completed on the device
+/// - For space/time reasons, timestamps are not supported
+
+int
+async_request_timestamps_get(AsyncRequest* request,
+ SsxTimebase* start_time,
+ SsxTimebase* end_time)
+{
+ int rc;
+ SsxMachineContext ctx;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ if (start_time) {
+ *start_time = request->start_time;
+ }
+ if (end_time) {
+ *end_time = request->end_time;
+ }
+
+ if ((request->state & ASYNC_REQUEST_IDLE_GROUP) &&
+ (request->state != ASYNC_REQUEST_STATE_INITIALIZED)) {
+ rc = 0;
+ } else {
+ rc = -ASYNC_INVALID_TIMESTAMPS;
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return rc;
+}
+
+
+/// Compute the latency of an AsyncRequest
+///
+/// \param request A pointer to an AsyncRequest
+///
+/// \param latency A pointer to a location to receive the latency (end time -
+/// start time) computed from the timestamps of \a request.
+///
+/// \retval 0 The request contains valid timestamps and they have been
+/// returned.
+///
+/// \retval -ASYNC_INVALID_TIMESTAMPS The latancy has been computed but may be
+/// invalid. This could be due to several reasons:
+///
+/// - The request has never been scheduled
+/// - The request has been scheduled but has not completed on the device
+/// - For space/time reasons, timestamps are not supported
+
+int
+async_request_latency(AsyncRequest* request, SsxTimebase* latency)
+{
+ int rc;
+ SsxTimebase start, end;
+
+ rc = async_request_timestamps_get(request, &start, &end);
+ *latency = end - start;
+ return rc;
+}
+
+
+// Dump an AsyncRequest
+
+void
+async_request_printk(AsyncRequest *request)
+{
+ printk("----------------------------------------\n");
+ printk("-- AsyncRequest @ %p\n", request);
+ printk("-- deque = %p\n", &(request->deque));
+ printk("-- start_time = 0x%016llx\n", request->start_time);
+ printk("-- end_time = 0x%016llx\n", request->end_time);
+ printk("-- sem = %p\n", &(request->sem));
+ printk("-- queue = %p\n", request->queue);
+ printk("-- run_method = %p\n", request->run_method);
+ printk("-- error_method = %p\n", request->error_method);
+ printk("-- callback = %p\n", request->callback);
+ printk("-- arg = %p\n", request->arg);
+ printk("-- state = 0x%02x\n", request->state);
+ printk("-- completion_state = 0x%02x\n", request->completion_state);
+ printk("-- options = 0x%04x\n", request->options);
+ printk("----------------------------------------\n");
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// Callback Queue
+////////////////////////////////////////////////////////////////////////////
+
+SSX_IRQ_FAST2FULL(async_callback_handler, async_callback_handler_full);
+
+// The handler for the asynchronous callback queue
+//
+// This is a full-mode noncritical interrupt handler. It is activated to run
+// 1) all deferred callbacks, and 2) noncritical callbacks invoked from
+// critical interrupt handlers, and 3) Thread-unblock and/or timeout-cancel
+// requests that needed to be deferred to a noncritical context. The callback
+// is enqueued in the SsxDeque passed as the private argument, and an IPI is
+// used to activate this handler.
+//
+// This handler runs each callback in order. Since the callback queue may be
+// managed by critical interrupt handlers we need to disable critical
+// interrupts when popping the next element from the queue.
+//
+// Deferred callbacks are run with noncritical interrupts \e enabled, similar
+// to how timer callbacks are run.
+//
+// Noncritical callbacks that were deferred here (by being invoked from a
+// critical handler) run with interrupts \e disabled, to be consistent with
+// the expected environment. Interrupts are then renabled briefly for
+// interrupt latency mitigation.
+//
+// Note that NULL callbacks may be enqueued here but only in the state
+// ASYNC_REQUEST_STATE_POSTPROCESSING.
+
+// The handler runs with its own IRQ disabled to avoid infinite interrupt
+// loops caused by enabling interrupt preemption. The IRQ status can only be
+// cleared inside an SSX_CRITICAL critical section. For efficiency we only do
+// this when we know that no more callbacks are queued.
+
+// Final request completion has been broken out into a generic routine,
+// async_request_finalize(). This routine is also called by the PTS
+// completion queue handler, which handles its requests ion a slightly
+// different way from the other async handlers.
+
+void
+async_request_finalize(AsyncRequest* request)
+{
+ if (request->state == ASYNC_REQUEST_STATE_CALLBACK_QUEUED) {
+
+ request->state = ASYNC_REQUEST_STATE_CALLBACK_RUNNING;
+
+ if (request->options & ASYNC_CALLBACK_DEFERRED) {
+
+ ssx_interrupt_preemption_enable();
+ request->callback_rc = request->callback(request->arg);
+
+ } else {
+
+ request->callback_rc = request->callback(request->arg);
+ ssx_interrupt_preemption_enable();
+ }
+ ssx_interrupt_preemption_disable();
+ }
+
+ request->state = request->completion_state;
+
+ if (request->timeout != SSX_WAIT_FOREVER) {
+ ssx_timer_cancel(&(request->timer));
+ }
+
+ if (request->options & ASYNC_REQUEST_BLOCKING) {
+ ssx_semaphore_post(&(request->sem));
+ }
+}
+
+
+void
+async_callback_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ SsxMachineContext ctx;
+ SsxDeque *queue = (SsxDeque *)arg;
+ AsyncRequest *request;
+
+ ssx_irq_disable(irq);
+
+ do {
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ request = (AsyncRequest *)ssx_deque_pop_front(queue);
+ if (!request) {
+ ssx_irq_status_clear(irq);
+ break;
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ async_request_finalize(request);
+
+ } while (1);
+
+ ssx_critical_section_exit(&ctx);
+ ssx_irq_enable(irq);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// Initialization
+////////////////////////////////////////////////////////////////////////////
+
+// These initialization routines are for boot-time initialization, or
+// test-mode reinitialization of interface parameters when the interface is
+// known to be idle. They are not robust enough for mid-application
+// reset/reprogramming of the asynchronous interfaces in the event of errors.
+
+// For the interrupt setup, whether or not the interrupt is enabled at the
+// exit of setup depends on the particular driver being initialized.
+
+void
+async_edge_handler_setup(SsxIrqHandler handler,
+ void *arg,
+ SsxIrqId irq,
+ int priority)
+{
+ ssx_irq_disable(irq);
+ ssx_irq_setup(irq,
+ SSX_IRQ_POLARITY_ACTIVE_HIGH,
+ SSX_IRQ_TRIGGER_EDGE_SENSITIVE);
+ ssx_irq_handler_set(irq, handler, arg, priority);
+ ssx_irq_status_clear(irq);
+}
+
+
+void
+async_level_handler_setup(SsxIrqHandler handler,
+ void *arg,
+ SsxIrqId irq,
+ int priority,
+ int polarity)
+{
+ ssx_irq_disable(irq);
+ ssx_irq_setup(irq,
+ polarity,
+ SSX_IRQ_TRIGGER_LEVEL_SENSITIVE);
+ ssx_irq_handler_set(irq, handler, arg, priority);
+}
+
+
+void
+async_callbacks_initialize(SsxDeque *queue, SsxIrqId irq)
+{
+ ssx_deque_sentinel_create(queue);
+ async_edge_handler_setup(async_callback_handler,
+ (void *)queue,
+ irq, SSX_NONCRITICAL);
+ ssx_irq_enable(irq);
+}
+
+
+/// Create all of the PgP asynchronous request structures and install and
+/// activate the interrupt handlers.
+
+void
+async_initialize()
+{
+ // This is the callback queue used e.g. when critical interrupts need to
+ // run non-critical callbacks.
+
+ async_callbacks_initialize(&G_async_callback_queue, PGP_IRQ_ASYNC_IPI);
+
+ // PORE
+
+ async_pore_initialize(&G_pore_gpe0_queue, ASYNC_ENGINE_PORE_GPE0);
+ async_pore_initialize(&G_pore_gpe1_queue, ASYNC_ENGINE_PORE_GPE1);
+ async_pore_initialize(&G_pore_slw_queue, ASYNC_ENGINE_PORE_SLW);
+
+#if CONFIGURE_PTS
+ // PTS
+
+ async_pts_initialize(&G_pts_gpe0_queue, ASYNC_ENGINE_PORE_GPE0);
+ async_pts_initialize(&G_pts_gpe1_queue, ASYNC_ENGINE_PORE_GPE1);
+#endif
+
+ // BCE
+
+ async_bce_initialize(&G_pba_bcde_queue,
+ ASYNC_ENGINE_BCDE,
+ PGP_IRQ_PBA_BCDE_ATTN);
+
+ async_bce_initialize(&G_pba_bcue_queue,
+ ASYNC_ENGINE_BCUE,
+ PGP_IRQ_PBA_BCUE_ATTN);
+
+ // OCB
+
+ async_ocb_initialize(&(G_ocb_read_queue[0]),
+ ASYNC_ENGINE_OCB_PUSH0,
+ G_ocb_read0_buffer,
+ OCB_READ0_LENGTH,
+ OCB_READ0_PROTOCOL);
+
+ async_ocb_initialize(&(G_ocb_read_queue[1]),
+ ASYNC_ENGINE_OCB_PUSH1,
+ G_ocb_read1_buffer,
+ OCB_READ1_LENGTH,
+ OCB_READ1_PROTOCOL);
+
+ async_ocb_initialize(&(G_ocb_read_queue[2]),
+ ASYNC_ENGINE_OCB_PUSH2,
+ G_ocb_read2_buffer,
+ OCB_READ2_LENGTH,
+ OCB_READ2_PROTOCOL);
+
+ async_ocb_initialize(&(G_ocb_write_queue[0]),
+ ASYNC_ENGINE_OCB_PULL0,
+ G_ocb_write0_buffer,
+ OCB_WRITE0_LENGTH,
+ OCB_WRITE0_PROTOCOL);
+
+ async_ocb_initialize(&(G_ocb_write_queue[1]),
+ ASYNC_ENGINE_OCB_PULL1,
+ G_ocb_write1_buffer,
+ OCB_WRITE1_LENGTH,
+ OCB_WRITE1_PROTOCOL);
+
+ async_ocb_initialize(&(G_ocb_write_queue[2]),
+ ASYNC_ENGINE_OCB_PULL2,
+ G_ocb_write2_buffer,
+ OCB_WRITE2_LENGTH,
+ OCB_WRITE2_PROTOCOL);
+
+ // PBAX
+
+ async_pbax_initialize(&G_pbax_read_queue[0],
+ ASYNC_ENGINE_PBAX_PUSH0,
+ PGP_IRQ_PBA_OCC_PUSH0,
+ G_pbax_read0_buffer,
+ PBAX_READ0_LENGTH,
+ PBAX_READ0_PROTOCOL);
+
+ async_pbax_initialize(&G_pbax_read_queue[1],
+ ASYNC_ENGINE_PBAX_PUSH1,
+ PGP_IRQ_PBA_OCC_PUSH1,
+ G_pbax_read1_buffer,
+ PBAX_READ1_LENGTH,
+ PBAX_READ1_PROTOCOL);
+}
diff --git a/src/ssx/pgp/pgp_async.h b/src/ssx/pgp/pgp_async.h
new file mode 100755
index 0000000..ecd3ae2
--- /dev/null
+++ b/src/ssx/pgp/pgp_async.h
@@ -0,0 +1,1654 @@
+#ifndef __PGP_ASYNC_H__
+#define __PGP_ASYNC_H__
+
+// $Id: pgp_async.h,v 1.2 2014/02/03 01:30:34 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_async.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_async.h
+/// \brief Support for asynchronous request/callback mechanisms
+///
+/// The data structures defined here provide a 'C' implementation of multiple
+/// single-inheritance class hierarchies. The 'subclasses' always include the
+/// 'superclass' as the initial element of the structure, allowing subclass
+/// pointers to be safely cast to the superclass, and vice-versa (assuming
+/// that the subclass is known). One benefit of this approach is that it
+/// allows code sharing between requests targeting PORE-GPE, PORE-SW,
+/// PBA-BCDE, PBA-BCUE and the deferred callback queue.
+///
+/// The 'class hierarchy' :
+///
+/// SsxDeque
+/// AsyncRequest
+/// PoreRequest
+/// PoreFixed
+/// PoreFlex
+/// BceRequest
+/// OcbRequest
+/// Pbaxrequest
+///
+/// AsyncQueue
+/// PoreQueue
+/// BceQueue
+/// OcbQueue
+/// PbaxQueue
+///
+/// \bug We may need to redo how we start jobs since writing the EXE-TRIGGER
+/// does not guarantee a restart from a good state, although if we get our CCB
+/// request through it will.
+
+
+// PgP Execution engines for the purposes of the generic request mechanism.
+
+#define ASYNC_ENGINE_ANONYMOUS 0x00
+
+#define ASYNC_ENGINE_PORE 0x10
+#define ASYNC_ENGINE_PORE_GPE0 0x10
+#define ASYNC_ENGINE_PORE_GPE1 0x11
+#define ASYNC_ENGINE_PORE_SLW 0x12
+
+#define ASYNC_ENGINE_BCE 0x20
+#define ASYNC_ENGINE_BCDE 0x20
+#define ASYNC_ENGINE_BCUE 0x21
+
+// Indirect channel 3 no longer supports push/pull queues and they have been
+// removed.
+#define ASYNC_ENGINE_OCB 0x40
+#define ASYNC_ENGINE_OCB_PUSH0 0x41
+#define ASYNC_ENGINE_OCB_PUSH1 0x42
+#define ASYNC_ENGINE_OCB_PUSH2 0x43
+#define ASYNC_ENGINE_OCB_PULL0 0x45
+#define ASYNC_ENGINE_OCB_PULL1 0x46
+#define ASYNC_ENGINE_OCB_PULL2 0x47
+
+#define ASYNC_ENGINE_PBAX 0x80
+#define ASYNC_ENGINE_PBAX_PUSH0 0x81
+#define ASYNC_ENGINE_PBAX_PUSH1 0x82
+
+
+#ifndef __ASSEMBLER__
+
+typedef uint8_t AsyncEngine;
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// FFDC Structures
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+/// FFDC from the PLB (OCI) arbiter
+///
+/// The PLB arbiter records errors from all OCI masters, including the address
+/// of the transaction that caused the error. The PLB arbiter is set up to
+/// 'lock' the first error data until the lock is reset. This structure is
+/// included in all of the unit FFDC structures for peripherals that can
+/// master on the OCI (SLW/GPE/OCB/PBA). Note that OCI errors from the 405
+/// core will cause an immediate machine check exception.
+
+typedef struct {
+
+ /// PLB arbiter Error Address Register Low
+ ///
+ /// This is the address of the last PLB timeout or other error recorded in
+ /// the PEARL. This is an error for the unit in question only if the
+ /// \a mine data member is non-zero.
+ plb_pearl_t pearl;
+
+ /// PLB arbiter Error Status Register
+ ///
+ /// The PESR at the time of the error.
+ plb_pesr_t pesr;
+
+ /// Is the unit in question responsible for the error address recorded in
+ /// the PEARL?
+ int mine;
+
+} OciFfdc;
+
+void
+oci_ffdc(OciFfdc* ffdc, int master_id);
+
+#endif // __ASSEMBLER__
+
+
+////////////////////////////////////////////////////////////////////////////
+// AsyncRequest
+////////////////////////////////////////////////////////////////////////////
+
+/// \defgroup async_request_states ASYNC Request States
+///
+/// Request states for async requests are group into 5 logical states for
+/// error handling and timeout handling purposes.
+///
+/// - Queued Group : Queued requests are still waiting to execute in the device queue,
+/// so these requests can be cancelled simply by removing them from the queue.
+///
+/// - Running Group : Running requests are running on the hardware, so killing
+/// these jobs may require a forced stop and restart of the device.
+///
+/// - Callback Group : By specification callbacks are always run if provided,
+/// even if a job dies or is timed out. This includes post-processing only
+/// work like unblocking blocked threads. These processes are not interrupted.
+///
+/// - Idle Group : These jobs are no longer in process, and their states are
+/// final.
+///
+/// Only idle requests can be (re)scheduled. Only jobs in the Queued or
+/// Running states can time out. Once the job has moved to the Callback group
+/// it is considered complete as far as timeout processing is concerned.
+///
+/// @{
+
+/// The request is waiting in the queue
+#define ASYNC_REQUEST_STATE_QUEUED 0x10
+
+
+/// The request is running on the hardware
+#define ASYNC_REQUEST_STATE_RUNNING 0x20
+
+
+/// The request is complete but a deferred callback has yet to run
+#define ASYNC_REQUEST_STATE_CALLBACK_QUEUED 0x40
+
+/// The request callback is running
+#define ASYNC_REQUEST_STATE_CALLBACK_RUNNING 0x41
+
+/// Thread unblocking and/or timeout cancellation has been deferred to a
+/// noncritical interrupt context.
+#define ASYNC_REQUEST_STATE_POSTPROCESSING 0x42
+
+
+/// The request has been initialized but never run
+#define ASYNC_REQUEST_STATE_INITIALIZED 0x80
+
+/// The request failed due to an error signalled by hardware
+#define ASYNC_REQUEST_STATE_FAILED 0x81
+
+/// The request completed normally
+#define ASYNC_REQUEST_STATE_COMPLETE 0x82
+
+/// The application cancelled the request
+#define ASYNC_REQUEST_STATE_CANCELLED 0x83
+
+/// The request timed out
+#define ASYNC_REQUEST_STATE_TIMED_OUT 0x84
+
+
+#define ASYNC_REQUEST_QUEUED_GROUP 0x10
+#define ASYNC_REQUEST_RUNNING_GROUP 0x20
+#define ASYNC_REQUEST_CALLBACK_GROUP 0x40
+#define ASYNC_REQUEST_IDLE_GROUP 0x80
+
+/// @}
+
+
+/// \defgroup async_request_options ASYNC Request Options
+///
+/// These are the option flags for the \a options field of the AsyncRequest.
+/// These are generic options applicable to all requests.
+///
+/// @{
+
+#define ASYNC_CALLBACK_IMMEDIATE 0x0001
+#define ASYNC_CALLBACK_DEFERRED 0x0002
+#define ASYNC_CALLBACK_NONCRITICAL 0x0004
+#define ASYNC_CALLBACK_OPTIONS 0x0007
+
+#define ASYNC_REQUEST_PRIORITY 0x0008
+#define ASYNC_CALLBACK_PRIORITY 0x0010
+
+#define ASYNC_REQUEST_BLOCKING 0x0020
+
+#define ASYNC_GENERIC_OPTIONS 0x003f
+
+/// @}
+
+#ifndef __ASSEMBLER__
+
+struct AsyncRequest;
+struct AsyncQueue;
+
+typedef int (*AsyncRunMethod)(struct AsyncRequest *request);
+
+typedef int (*AsyncErrorMethod)(struct AsyncRequest *request);
+
+typedef int (*AsyncRequestCallback)(void *);
+
+/// A generic request for the asynchronous request drivers
+///
+/// Note: Normally the application will not explicitly manipulate this
+/// structure, but will instead manipulate derived structures.
+///
+/// A request is queued for a particular engine, with a callback to be
+/// executed once the request has been processed by the engine. The \a
+/// callback may be NULL, but at a minimum the requestor can observe the \a
+/// state of the request to determine the state of request processing. If a
+/// deferred callback is requested, then once processing is done the generic
+/// handler will requeue the request in a callback queue.
+///
+/// The \a run_method is a "pure virtual" function of this class. The \a
+/// run_method encapsulates the procedure for starting a job on the
+/// engine. The \a run_method may make assumptions about and use data
+/// contained in the AsyncQueue class used to queue the requests.
+///
+/// The \a error_method is also "pure virtual" function of this class. The \a
+/// error_method encapsulates the procedure for collecting FFDC and preparing
+/// the engine to run the next job. The \a error_method may make assumptions
+/// about and use data contained in the AsyncQueue class used to queue the
+/// requests. If the \a error_method returns a non-0 code then the error is
+/// considered fatal and the queue stops.
+
+typedef struct AsyncRequest {
+
+ /// Generic queue management - the "base class"
+ SsxDeque deque;
+
+ /// The time the job was started on the hardware.
+ ///
+ /// For jobs requiring multiple passes on the hardware, e.g., BCE jobs
+ /// that move more data than the PBA supports with a single pass, this
+ /// time is the time the first hardware pass started. In this case the
+ /// interval time computed as the difference with \a start_time includes
+ /// interrupt handling overhead required to process the completion/restart
+ /// of intermediate passes.
+ ///
+ /// This timestamp is inserted into the request by the generic routine
+ /// async_request_run().
+ SsxTimebase start_time;
+
+ /// The time the job finished on the hardware.
+ ///
+ /// This timestamp is inserted into the request by the generic routine
+ /// async_handler().
+ SsxTimebase end_time;
+
+ /// A semaphore for thread-mode requests to block on if desired.
+ SsxSemaphore sem;
+
+ /// A timer used for timeout management
+ SsxTimer timer;
+
+ /// The engine queue the request is/was scheduled on
+ struct AsyncQueue *queue;
+
+ /// The "virtual" run method for the class
+ AsyncRunMethod run_method;
+
+ /// The "virtual" error handler method for the class
+ AsyncErrorMethod error_method;
+
+ /// The routine Called (or deferred) with the \a arg parameter once
+ /// the engine has completed the request.
+ ///
+ /// The callback may be NULL (0), in which case the \a arg parameter
+ /// is ignored, and the only status available to the requestor is the
+ /// request \a state.
+ AsyncRequestCallback callback;
+
+ /// The argument of the callback
+ void *arg;
+
+ /// The timeout value
+ ///
+ /// AsyncRequest objects with \a timeout other than SSX_WAIT_FOREVER are
+ /// governed by a private watchdog timer that will cancel a queued job or
+ /// kill a running job if the hardware operation does not complete before
+ /// it times out.
+ SsxInterval timeout;
+
+ /// The return value of the callback (if any) is stored here
+ ///
+ /// The success or failure of the callback is recorded here; it is not
+ /// recorded in the \a state variable. If there is no callback this field
+ /// will always read as 0 at job completion.
+ int callback_rc;
+
+ /// Options controlling request processing
+ uint8_t options;
+
+ /// The current state of the request
+ ///
+ /// This field is declared volatile because applications may poll this
+ /// field which is set asynchronously by the async interrupt handlers, and
+ /// optimizing compilers transform polling a variable into an infinite
+ /// loop if the variable is not set on the initial test!
+ volatile uint8_t state;
+
+ /// The state of the request when the request was aborted
+ ///
+ /// This field is valid when the state of the request is read as
+ /// ASYNC_REQUEST_STATE_FAILED, ASYNC_REQUEST_STATE_CANCELLED, or
+ /// ASYNC_REQUEST_STATE_TIMED_OUT. This field records the state of the
+ /// job when it was forceably cancelled or killed either due to the
+ /// application's request or due to a hardware error or timeout.
+ uint8_t abort_state;
+
+ /// The completion state of the request.
+ ///
+ /// This is the state that will be reported when the request completes and
+ /// the callback has been run. Normally this is
+ /// ASYNC_REQUEST_STATE_COMPLETE. However the specification requires that
+ /// even jobs that terminate due to an errors, timeouts or being cancelled
+ /// or killed must run their callbacks. In this case this variable will be
+ /// set to ASYNC_REQUEST_STATE_FAILED, ASYNC_REQUEST_STATE_TIMED_OUT,
+ /// ASYNC_REQUEST_STATE_CANCELLED or ASYNC_REQUEST_STATE_KILLED
+ /// respectively.
+ uint8_t completion_state;
+
+} AsyncRequest;
+
+
+int
+async_request_create(AsyncRequest *request,
+ struct AsyncQueue *queue,
+ AsyncRunMethod run_method,
+ AsyncErrorMethod error_method,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options);
+
+void
+async_request_finalize(AsyncRequest* request);
+
+
+/// Check that an asynchronous request is idle
+///
+/// \param request An initialized request
+///
+/// A request is considered idle if it is not attached to any of the
+/// asynchronous request queues, \e or the request has terminated with an
+/// error. This includes requests that have never been scheduled, have
+/// completed or been cancelled or killed. Only idle requests can be
+/// rescheduled.
+///
+/// \retval 0 The request is not idle
+///
+/// \retval 1 The request is idle
+
+static inline int
+async_request_is_idle(AsyncRequest *request)
+{
+ return (request->state & ASYNC_REQUEST_IDLE_GROUP) != 0;
+}
+
+
+/// Check an asynchronous request for successful completion
+///
+/// \param request A request that had been previosuly scheduled
+///
+/// Note that a request is not considered complete until both the engine job
+/// has finshed without error and any callback has run to completion. Thus
+/// jobs that have error-ed out, been cancelled or killed will be idle (and
+/// rescheduleable), but not complete.
+///
+/// \retval 0 The request has not yet completed successfully
+///
+/// \retval 1 The request has completed successfully.
+
+static inline int
+async_request_completed(AsyncRequest *request)
+{
+ return (request->state == ASYNC_REQUEST_STATE_COMPLETE);
+}
+
+
+int
+async_request_timestamps_get(AsyncRequest* request,
+ SsxTimebase* start_time,
+ SsxTimebase* end_time);
+
+int
+async_request_latency(AsyncRequest* request, SsxTimebase* latency);
+
+
+void
+async_request_printk(AsyncRequest *request);
+
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// AsyncQueue
+////////////////////////////////////////////////////////////////////////////
+
+#define ASYNC_QUEUE_STATE_IDLE 0x00
+#define ASYNC_QUEUE_STATE_RUNNING 0x01
+#define ASYNC_QUEUE_STATE_ERROR 0x02
+
+#ifndef __ASSEMBLER__
+
+/// A generic asynchronous request queue
+///
+/// Note: This structure is normally not manipulated directly by application
+/// code, but only by the device drivers.
+///
+/// Request queues support 2 priorities - Normal and High. Normal priority
+/// requests are queued FIFO order, while high-priority requests are queued
+/// LIFO order. Requests queued with high priority always execute before any
+/// queued with normal priority, however there is no concept of preemption of
+/// a currently running request.
+///
+/// Because high-priority requests are queued in LIFO order, multiple
+/// high-priority jobs will run in the reverse order from which they were
+/// enqueued.
+
+typedef struct AsyncQueue {
+
+ /// The sentinel of the request queue
+ SsxDeque deque;
+
+ /// The currently running request, or NULL (0)
+ AsyncRequest* current;
+
+ /// The engine associated with the queue.
+ AsyncEngine engine;
+
+ /// The state of the queue
+ uint8_t state;
+
+} AsyncQueue;
+
+
+int
+async_queue_create(AsyncQueue* queue, AsyncEngine engine);
+
+void
+async_handler(AsyncQueue* queue);
+
+int
+async_request_schedule(AsyncRequest* request);
+
+void
+async_error_handler(AsyncQueue* queue, uint8_t completion_state);
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// Async Initialization
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+void
+async_edge_handler_setup(SsxIrqHandler handler,
+ void *arg,
+ SsxIrqId irq,
+ int priority);
+
+void
+async_level_handler_setup(SsxIrqHandler handler,
+ void *arg,
+ SsxIrqId irq,
+ int priority,
+ int polarity);
+
+void
+async_callbacks_initialize(SsxDeque *queue, SsxIrqId irq);
+
+
+#endif // __ASSEMBLER__
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreRequest
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+struct PoreQueue;
+
+/// PORE FFDC
+///
+/// The PORE engine has 208 bytes of programmer-visible state - too much to
+/// allocate in every PoreRequest on the off-chance that a request may fail.
+/// This PoreFfdc structure is designed to capture a reasonble amount of data
+/// in the case of failure of a PoreFlex request, which does not include any
+/// PORE error handlers. This structure is currently 48 bytes.
+///
+/// The most common recoverable errors are expected to be erroneous PIB
+/// responses from deconfigured (garded) cores. These will show up as Error
+/// event 0 and can be debugged from the debug registers. We also include the
+/// instruction buffer registers to help debug error 2 - instruction
+/// fetch/decode errors.
+///
+/// To get a full picture in the event of OCI execution phase errors (error
+/// 1), the PORE memory-space address registers are captured. We also capture
+/// FFDC from the PLB arbiter, which can be used to debug illegal address-type
+/// problems.
+
+typedef struct {
+
+ /// FFDC from the PLB (OCI) arbiter
+ OciFfdc oci_ffdc;
+
+ /// PORE Debug Registers
+ ///
+ /// - [0] Contains PIB address and PIB return code
+ /// - [1] Contains failing PC and error status bits
+ uint64_t debug[2];
+
+ /// PORE Memory-space address registers.
+ ///
+ /// We only save the low-order 32 bits of each - the high-order bits are
+ /// implied/ignored for OCI-attached engines. If OCC managed the SBE then
+ /// we would require the high-order bits in an FFDC dump.
+ uint32_t address[2];
+
+ /// PORE Instruction buffer 0-2
+ ///
+ /// - [0] Contains the opcode and register/short operands
+ /// - [1:2] Contain the 64-bit immediate
+ uint32_t ibuf[3];
+
+} PoreFfdc;
+
+
+/// A PORE branch immediate address instruction, used in PORE jump tables.
+typedef struct {
+ uint32_t word[3];
+} PoreBraia;
+
+
+void
+pore_braia_create(PoreBraia* instr, uint32_t address);
+
+
+/// A request to run a PORE program
+///
+/// A PORE request extends the generic AsyncRequest request by the addition of
+/// several fields required to be set up in the engine before the job is run,
+/// including the program parameter for the routine. The PoreRequest is an
+/// internal class that is re-typed to create the PoreFixed and PoreFlex
+/// request classes, which differ only slightly in their behavior.
+///
+/// As long as the request is known to be idle the application is free to
+/// change the \a parameter value between executions of the PORE program,
+/// e.g., to do ping-pong buffer management. None of the other fields should
+/// be directly modified by the application.
+
+typedef struct {
+
+ /// The generic request
+ AsyncRequest request;
+
+ /// Error information
+ PoreFfdc ffdc;
+
+ /// The PORE Jump Table
+ PoreBraia* table;
+
+ /// The initial value of the high-order 32 bits of the ERROR_MASK register
+ uint32_t error_mask;
+
+ /// The entry point address of the routine.
+ ///
+ /// For PoreFlex this entry point will be non-0 and will be inserted into
+ /// D0, as PoreFlex jobs are kicked off by BRAD. For PoreFixed this
+ /// parameter will be zero and ignored.
+ uint32_t entry_point;
+
+ /// The single parameter of the PORE program - EXE-Trigger[32:63]
+ uint32_t parameter;
+
+ /// The high-order 32 bits of EXE-Trigger used to kick off the program.
+ ///
+ /// For PoreFlex this field is always 0, as PoreFlex only uses table entry
+ /// 0 which contains a BRAD. For PoreFixed this encodes the address of
+ /// the table entry to kick off.
+ uint32_t exe_trigger;
+
+} PoreRequest;
+
+
+typedef PoreRequest PoreFlex;
+
+typedef PoreRequest PoreFixed;
+
+int
+pore_run_method(AsyncRequest* request);
+
+int
+pore_error_method(AsyncRequest* request);
+
+#endif /* __ASSEMBLER__ */
+
+/// The (fixed) number of PORE jump table error handler slots
+#define PORE_ERROR_SLOTS 5
+
+/// The maximum number of PORE jump table EXE_TRIGGER slots
+#define PORE_TRIGGER_SLOTS 16
+
+/// Compute the address of error handler BRAIA entry n of a PORE branch table
+#define PORE_ERROR_BRANCH(table, n) ((table) + ((n) * 12))
+
+/// Compute the address of entry point BRAIA entry n of a PORE branch table
+#define PORE_ENTRY_BRANCH(table, n) \
+ ((table) + (((PORE_ERROR_SLOTS) + (n)) * 12))
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreFlex
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+int
+pore_flex_create(PoreFlex* request,
+ struct PoreQueue* queue,
+ PoreEntryPoint entry_point,
+ uint32_t parameter,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options);
+
+
+/// See async_request_schedule() for documentation.
+static inline int
+pore_flex_schedule(PoreFlex* request)
+{
+ return async_request_schedule((AsyncRequest *)request);
+}
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreFixed
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+int
+pore_fixed_create(PoreFixed *request,
+ struct PoreQueue *queue,
+ PoreBraia* table,
+ uint32_t error_mask,
+ int start_vector,
+ uint32_t parameter,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options);
+
+/// See async_request_schedule() for documentation.
+static inline int
+pore_fixed_schedule(PoreFixed *request)
+{
+ return async_request_schedule((AsyncRequest *)request);
+}
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreQueue
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+/// A PORE engine queue
+///
+/// A PORE queue consists of a generic AsyncQueue to manage jobs on the
+/// engine, the OCI base address of the PORE control register space of the
+/// engine, and interrupt information.
+
+typedef struct PoreQueue {
+
+ /// The generic request queue - the "base class"
+ AsyncQueue queue;
+
+ /// The base address of the OCI control register space for this engine.
+ uint32_t oci_base;
+
+ /// The IRQ associated with normal completion on the engine
+ ///
+ /// \todo Due to header reference ordering we can't define this as SsxIrqId
+ uint8_t irq;
+
+ /// The IRQ associated with error completion on the engine
+ ///
+ /// \todo Due to header reference ordering we can't define this as SsxIrqId
+ uint8_t error_irq;
+
+ /// The OCI master number of this engine; See pore_error_method()
+ uint8_t oci_master;
+
+} PoreQueue;
+
+
+int
+pore_queue_create(PoreQueue *queue,
+ int engine);
+
+#endif /* ASSEMBLER */
+
+
+////////////////////////////////////////////////////////////////////////////
+// PBA FFDC Structures
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+/// Common FFDC collected for each PBA subunit in the event that a particular
+/// subunit is implicated in an error. This structure contains generic
+/// data that may be useful in diagnosing any PBA error. Instances of this
+/// structure are embedded in higher-level structures for the PBA bridge, BCE
+/// engines, and PBAX mechanism.
+
+typedef struct {
+
+ /// FFDC from the PLB (OCI) arbiter
+ OciFfdc oci_ffdc;
+
+ /// The PBA MODE register
+ pba_mode_t mode;
+
+ /// The PBA FIR
+ pba_fir_t fir;
+
+ /// PBA Error Report 0
+ pba_errpt0_t errpt0;
+
+ /// PBA Error Report 1
+ pba_errpt1_t errpt1;
+
+ /// PBA Error Report 2
+ pba_errpt2_t errpt2;
+
+ /// PBA Read Buffer Valid Status
+ pba_rbufvaln_t rbufval[PBA_READ_BUFFERS];
+
+ /// PBA Write Buffer Valid Status
+ pba_wbufvaln_t wbufval[PBA_WRITE_BUFFERS];
+
+ /// PBA BARs
+ pba_barn_t bar[PBA_BARS];
+
+ /// PBA BAR masks
+ pba_barmskn_t barmsk[PBA_BARS];
+
+ /// Error status - non-0 if this structure contains error data
+ int error;
+
+} PbaCommonFfdc;
+
+
+/// FFDC collected for generic PBA bridge errors
+///
+/// These types of errors will almost certainly be attributable to the
+/// PORE-SLW or PORE-GPE, since the OCC is normally not allowed to perform
+/// direct bridge operations after OCC initialization. This structure extends
+/// the common PBA FFDC with information on how the slaves were programmed.
+
+typedef struct {
+
+ /// Common FFDC
+ PbaCommonFfdc common;
+
+ /// PBA Slave reset register
+ pba_slvrst_t slvrst;
+
+ /// PBA Slave control registers
+ pba_slvctln_t slvctl[PBA_SLAVES];
+
+} PbaBridgeFfdc;
+
+
+/// FFDC collected for the PBA BCUE/BCDE
+///
+/// The BCDE/BCUE control and status registers have identical layouts.
+/// Similar to the way the drivers are coded, the BCDE register forms are used
+/// to declare the structures.
+
+typedef struct {
+
+ /// Common FFDC
+ PbaCommonFfdc common;
+
+ /// BCE control register
+ pba_bcde_ctl_t ctl;
+
+ /// BCE setup register
+ pba_bcde_set_t set;
+
+ /// BCE PowerBus setup register
+ pba_bcde_pbadr_t pbadr;
+
+ /// BCE status register
+ pba_bcde_stat_t stat;
+
+} BceFfdc;
+
+
+/// FFDC collected for PBAX send errors
+
+typedef struct {
+
+ /// Common FFDC
+ PbaCommonFfdc common;
+
+ /// PBAX configuration register
+ pba_xcfg_t xcfg;
+
+ /// PBAX send transaction register
+ pba_xsndtx_t xsndtx;
+
+ /// PBAX send status register
+ pba_xsndstat_t xsndstat;
+
+} PbaxSendFfdc;
+
+
+/// FFDC collected for PBAX receive errors
+
+typedef struct {
+
+ /// Common FFDC
+ PbaCommonFfdc common;
+
+ /// PBAX configuration register
+ pba_xcfg_t xcfg;
+
+ /// PBAX receive status register
+ pba_xrcvstat_t xrcvstat;
+
+ /// PBAX push base registers
+ pba_xshbrn_t xshbrn[PBAX_QUEUES];
+
+ /// PBAX push control/status registers
+ pba_xshcsn_t xshcsn[PBAX_QUEUES];
+
+} PbaxReceiveFfdc;
+
+
+/// A single global structure containing FFDC for all PBA functions
+
+typedef struct {
+
+ /// FFDC for the generic bridge
+ PbaBridgeFfdc bridge;
+
+ /// FFDC for the BCDE
+ BceFfdc bcde;
+
+ /// FFDC for the BCUE
+ BceFfdc bcue;
+
+ /// FFDC for PBAX send
+ PbaxSendFfdc pbax_send;
+
+ /// FFDC for PBAX receive
+ PbaxReceiveFfdc pbax_receive;
+
+} PbaUnitFfdc;
+
+#endif // __ASSEMBLER__
+
+////////////////////////////////////////////////////////////////////////////
+// BceRequest
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+struct BceQueue;
+
+/// A request to move data through the PBA BCUE or BCDE
+///
+/// From a programming and control perspective the Block Copy Download Engine
+/// (BCDE) and Upload Engine (BCUE) are identical - they simply move a given
+/// number of 128-byte cache lines from/to system memory to/from SRAM.
+///
+/// Although the PBA BCE hardware can only move a maximum of 4KB at a time
+/// through the channel, the software layer allows any amount of data to be
+/// moved as a single request.
+
+typedef struct {
+
+ /// The generic request
+ AsyncRequest request;
+
+ /// FFDC collected in the event of an error in the request
+ BceFfdc ffdc;
+
+ /// Initial bridge address for read (BCDE) or write (BCUE) data. This
+ /// field is not modified by the drivers.
+ uint32_t bridge_address;
+
+ /// Initial OCI address for read (BCUE) or write (BCDE) data. This
+ /// field is not modified by the drivers.
+ uint32_t oci_address;
+
+ /// Number of bytes to move. This field is not modified by the drivers.
+ ///
+ /// Note that the PBA moves data in sets of 128 bytes (the PowerBus
+ /// cache line size). This field will always be a multiple of 128.
+ size_t bytes;
+
+ /// The next bridge address for read (BCDE) or write (BCUE) data. This
+ /// field is modified by the drivers as each maximum 4K block is copied.
+ uint32_t next_bridge_address;
+
+ /// Initial OCI address for read (BCUE) or write (BCDE) data. This
+ /// field is modified by the drivers as each maximum 4K block is copied.
+ uint32_t next_oci_address;
+
+ /// The number of bytes remaining to be moved.
+ size_t remaining;
+
+ /// The extended address, as a 64-bit PowerBus address
+ ///
+ /// Bits 23:36 of the field define bits 23:36 of the final PowerBus
+ /// address, subject to the final mask selection. This field is cleared by
+ /// the default constructor, and must be explicitly set if an extended
+ /// address is needed.
+ pba_extended_address_t extended_address;
+
+} BceRequest;
+
+int
+bce_request_create(BceRequest *request,
+ struct BceQueue *queue,
+ uint32_t bridge_address,
+ uint32_t oci_address,
+ size_t bytes,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options);
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// BceQueue
+////////////////////////////////////////////////////////////////////////////
+
+// NB: This assignment ordering is assumed by static initialization code.
+// These constants are used as array indices.
+
+#define BCE_ENGINE_BCDE 0
+#define BCE_ENGINE_BCUE 1
+
+#define BCE_ENGINES 2
+
+#ifndef __ASSEMBLER__
+
+
+/// A PBA Block Copy Engine queue
+///
+/// A PBA block copy request queue consists of a generic AsyncQueue to manage
+/// jobs on the engine and the PBA engine id. The BCDE and BCUE can use the
+/// same driver because their control interfaces are identical.
+
+typedef struct BceQueue {
+
+ /// The generic request queue
+ AsyncQueue queue;
+
+ /// The engine id of the BCE engine for control register address lookup
+ int engine;
+
+} BceQueue;
+
+
+int
+bce_queue_create(BceQueue *queue,
+ int engine);
+
+
+int
+bce_request_schedule(BceRequest *request);
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// PbaxRequest
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+struct PbaxQueue;
+
+/// A request to move data through a PBAX circular queue
+///
+/// The PBAX circular queues are modeled after the OCB circular queues. The
+/// queues are named and documented in the hardware specifications from the
+/// perspective of the PowerBus as "PUSH" queues. Here we name and document
+/// the queues from the perspective of OCC firmware as "READ" queues. Note
+/// that there are no PBAX "WRITE" queues. The PBAX write mechanism handles
+/// only a single datum at a time and has no interrupt. PBAX writes are
+/// handled by the pbax_send() and _pbax_send() APIs.
+///
+/// The PBAX queues support data buffers of from 8 to 256 bytes with an 8-byte
+/// granularity. The PBAX hardware requires that the data buffers be aligned
+/// to a power-of-2 boundary greater than or equal to the buffer size.
+/// The async drivers allow specification of any multiple of 8 bytes to read
+/// and handle all of the queue and split-request management.
+///
+/// Note : As long as the PbaxRequest is idle, the application is free to
+/// directly change the \a data and \a bytes fields to read/write different
+/// numbers of bytes to/from different locations the next time the request is
+/// scheduled.
+///
+/// The PBAX queues support both 'lazy' and 'aggressive' interrupt protocols.
+/// The aggressive protocols generate interrupts whenever read data is
+/// available. The lazy protocols require a full read buffer to trigger an
+/// interrupt. A lazy read protocol with a buffer size > 1 demands that
+/// communcations always consist of a known number of doublewords equal to the
+/// buffer size. For free-form communications an aggressive read protocol must
+/// be used.
+
+typedef struct {
+
+ /// The generic request
+ AsyncRequest request;
+
+ /// Initial pointer to the data area to hold read data.
+ ///
+ /// This field is not modified by the drivers. The application may modify
+ /// this field any time the PbaxRequest is idle.
+ uint64_t *data;
+
+ /// Number of bytes to move, which must be a multiple of 8.
+ ///
+ /// This field is not modified by the drivers. The application may modify
+ /// this field any time the PbaxRequest is idle.
+ size_t bytes;
+
+ /// Pointer to where to put the next read data.
+ ///
+ /// The application should never modify this field.
+ void* current;
+
+ /// Number of bytes remaining to be moved.
+ ///
+ /// The application should never modify this field.
+ size_t remaining;
+
+} PbaxRequest;
+
+
+int
+pbax_request_create(PbaxRequest *request,
+ struct PbaxQueue *queue,
+ uint64_t *data,
+ size_t bytes,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options);
+
+
+int
+pbax_request_schedule(PbaxRequest *request);
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// PbaxQueue
+////////////////////////////////////////////////////////////////////////////
+
+// NB: This assignment ordering is assumed by static initialization code in
+// pgp_async.c - these constants are used as array indices.
+
+#define PBAX_ENGINE_PUSH0 0
+#define PBAX_ENGINE_PUSH1 1
+
+#define PBAX_ENGINES 2
+
+#ifndef __ASSEMBLER__
+
+extern const SsxAddress pba_xshcsn[];
+extern const SsxAddress pba_xshbrn[];
+extern const SsxAddress pba_xshincn[];
+
+
+/// A PBAX Circular buffer queue
+///
+/// A PBAX circular buffer queue consists of a generic AsyncQueue to manage
+/// jobs on the engine, a pointer to the data area and the PBAX engine id.
+
+typedef struct PbaxQueue {
+
+ /// The generic request queue
+ AsyncQueue queue;
+
+ /// The base of the circular queue data area
+ ///
+ /// This data area must satisfy stringent alignment constraints; See the
+ /// documentation for PbaxRequest.
+ uint64_t *cq_base;
+
+ /// The number of 8-byte entries in the queue.
+ ///
+ /// This is included here to simplify APIs; The length is also encoded in
+ /// the PBAXSHCSn register for the queue.
+ size_t cq_entries;
+
+ /// The interrupt protocol implemented by the queue.
+ ///
+ /// This will either be PBAX_INTERRUPT_PROTOCOL_LAZY or
+ /// PBAX_INTERRUPT_PROTOCOL_AGGRESSIVE.
+ int protocol;
+
+ /// The engine id for lookup of OCI control register addresses.
+ int engine;
+
+ /// The IRQ associated with normal completion on the engine
+ ///
+ /// \todo Due to header reference ordering we can't define this as SsxIrqId
+ uint8_t irq;
+
+} PbaxQueue;
+
+
+int
+pbax_queue_create(PbaxQueue *queue,
+ int engine,
+ uint64_t *cq_base,
+ size_t cq_entries,
+ int protocol);
+
+int
+pbax_queue_disable(PbaxQueue *queue);
+
+int
+pbax_queue_enable(PbaxQueue *queue);
+
+int
+pbax_read(PbaxQueue* queue, void* buf, size_t bytes, size_t* read);
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// OcbRequest
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+/// OCB FFDC
+///
+/// This structure is used to store FFDC in two cases. 1) When an error can be
+/// reasonably attributed to an OCB channel under the control of OCC, and 2)
+/// general errors signalled by the OCB direct bridge. Due to the myriad ways
+/// that OCB channels can be used the FFDC for OCB direct bridge errors is
+/// stored globally rather than with particular requests or queues.
+///
+/// The OcbFfdc includes the PLB arbiter PEARL and PESR register state.
+/// This state is only collected if the error status indicates an OCI timeout
+/// for this channel.
+///
+/// Any error reasonably attributable to a channel will capture the FFDC and
+/// then disable the channel since any further communication through the
+/// channel must be considered compromised.
+
+typedef struct {
+
+ /// FFDC from the OCI (PLB) arbiter
+ OciFfdc oci_ffdc;
+
+ /// A copy of the OCB OCC_LFIR register at the time of the error
+ ocb_occlfir_t fir;
+
+ /// A copy of the OCB Control/Status register for the channel at the time
+ /// of the error.
+ ///
+ /// This field will be set to 0 for generic OCB bridge errors
+ ocb_ocbcsrn_t csr;
+
+ /// A copy of the OCB Stream Push Base [n] Register at the time of the
+ /// failure
+ ///
+ /// This field will be set to 0 for generic OCB bridge errors
+ ocb_ocbshbrn_t shbr;
+
+ /// A copy of the OCB Stream Push Control/Status [n] Register at the time
+ /// of the failure
+ ///
+ /// This field will be set to 0 for generic OCB bridge errors
+ ocb_ocbshcsn_t shcs;
+
+ /// A copy of the OCB Stream Pull Base [n] Register at the time of the
+ /// failure
+ ///
+ /// This field will be set to 0 for generic OCB bridge errors
+ ocb_ocbslbrn_t slbr;
+
+ /// A copy of the OCB Stream Pull Control/Status [n] Register at the time
+ /// of the failure
+ ///
+ /// This field will be set to 0 for generic OCB bridge errors
+ ocb_ocbslcsn_t slcs;
+
+ /// Is this record valid (does it contain captured error information)?
+ int error;
+
+} OcbFfdc;
+
+
+/// OCB Unit FFDC
+///
+/// Contains FFDC structures for each channel and the direct bridge
+
+typedef struct {
+
+ OcbFfdc channel[OCB_INDIRECT_CHANNELS];
+ OcbFfdc bridge;
+
+} OcbUnitFfdc;
+
+
+/// Global FFDC for OCB
+
+extern OcbUnitFfdc G_ocb_ffdc;
+
+
+struct OcbQueue;
+
+/// A request to move data through an OCB circular queue
+///
+/// The OCB circular queues are named and documented in the hardware specs
+/// from the perspective of the PIB - "PUSH" and "PULL" queues. Here we name
+/// and document the queues from the perspective of OCC firmware - "READ" and
+/// "WRITE" queues. The request is generic and becomes either a read or write
+/// request simply by which queue it is scheduled on.
+///
+/// The circular queues only support 8-byte granularity, require that the data
+/// areas be 8- or 32-byte aligned, and only support up to 256 byte
+/// queues. However the async drivers allow specification of any multiple of 8
+/// bytes to read or write, and handle all of the queue and split-request
+/// management.
+///
+/// Note : As long as the OcbRequest is idle, the application is free to
+/// directly change the \a data and \a bytes fields to read/write different
+/// numbers of bytes to/from different locations the next time the request is
+/// scheduled.
+///
+/// OCB requests always complete in an interrupt context. The OCB queues
+/// support both 'lazy' and 'aggressive' interrupt protocols. The aggressive
+/// protocols generate interrupts whenever read data is available or write
+/// space is available. The lazy protocols require a full read buffer or
+/// empty write buffer to trigger an interrupt. A lazy read protocol with a
+/// buffer size > 1 demands that communcations always consist of a known
+/// number of doublewords. For free-form communications an aggressive read
+/// protocol must be used. On average, an aggressive write protocol will
+/// shorten blocking periods of writers, and can guarantee that data is in the
+/// queue whenever data is avilable. Lazy write protocols will be preferred
+/// when reducing interrupt overhead is more important than reducing blocking
+/// time.
+///
+/// Completion of write requests does not guarantee that the communication
+/// partner has received the data, but simply that the data has been queued
+/// for reception and the caller may reuse/refill the data buffer if required.
+
+typedef struct {
+
+ /// The generic request
+ AsyncRequest request;
+
+ /// Initial pointer to the data to be moved for write data, or the
+ /// data area to hold read data. This field is not modified by the drivers.
+ uint64_t *data;
+
+ /// Number of bytes to move. This field is not modified by the drivers.
+ size_t bytes;
+
+ /// Pointer to data yet to be moved for write, or where to put the next
+ /// read data.
+ uint64_t* current;
+
+ /// Number of bytes remaining to be moved.
+ size_t remaining;
+
+} OcbRequest;
+
+
+int
+ocb_request_create(OcbRequest *request,
+ struct OcbQueue *queue,
+ uint64_t *data,
+ size_t bytes,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options);
+
+
+int
+ocb_request_schedule(OcbRequest *request);
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// OcbQueue
+////////////////////////////////////////////////////////////////////////////
+
+// NB: This assignment ordering is assumed by static initialization code in
+// pgp_async.c - these constants are used as array indices. The code also
+// assumes this ordering for the access of G_ocb_ocbsesn[], and for
+// determining whether the engine is a PUSH or PULL queue.
+// Note: push/pull queues for channel 3 have been deleted
+
+#define OCB_ENGINE_PUSH0 0
+#define OCB_ENGINE_PULL0 1
+#define OCB_ENGINE_PUSH1 2
+#define OCB_ENGINE_PULL1 3
+#define OCB_ENGINE_PUSH2 4
+#define OCB_ENGINE_PULL2 5
+
+#define OCB_ENGINES 6
+
+#ifndef __ASSEMBLER__
+
+/// An OCB Circular buffer queue
+///
+/// A OCB circular buffer queue consists of a generic AsyncQueue to manage
+/// jobs on the engine, a pointer to the data area and the OCB engine id.
+
+typedef struct OcbQueue {
+
+ /// The generic request queue
+ AsyncQueue queue;
+
+ /// The base of the circular queue data area - must be 8-byte aligned
+ uint64_t *cq_base;
+
+ /// The length of the queue in terms of the number of 8-byte entries in
+ /// the queue.
+ ///
+ /// This is for informational purposes only. The length is also encoded
+ /// in the OCBSxCSn register for the queue.
+ size_t cq_length;
+
+ /// The engine id for lookup of OCI control register addresses.
+ int engine;
+
+ /// The IRQ associated with normal completion on the engine
+ ///
+ /// \todo Due to header reference ordering we can't define this as SsxIrqId
+ uint8_t irq;
+
+} OcbQueue;
+
+
+int
+ocb_queue_create(OcbQueue *queue,
+ int engine,
+ uint64_t *cq_base,
+ size_t cq_length,
+ int protocol);
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// Miscellaneous/Initialization
+////////////////////////////////////////////////////////////////////////////
+
+// Error codes
+
+#define ASYNC_INVALID_OBJECT_REQUEST 0x00279600
+#define ASYNC_INVALID_OBJECT_SCHEDULE 0x00279601
+#define ASYNC_INVALID_OBJECT_OCB_REQUEST 0x00279602
+#define ASYNC_INVALID_OBJECT_OCB_QUEUE 0x00279603
+#define ASYNC_INVALID_OBJECT_PBAX_REQUEST 0x00279604
+#define ASYNC_INVALID_OBJECT_PBAX_DISABLE 0x00279605
+#define ASYNC_INVALID_OBJECT_PBAX_QUEUE 0x00279606
+#define ASYNC_INVALID_OBJECT_BCE_REQUEST 0x00279607
+#define ASYNC_INVALID_OBJECT_BCE_QUEUE 0x00279608
+#define ASYNC_INVALID_OBJECT_PORE_REQUEST 0x00279609
+#define ASYNC_INVALID_OBJECT_PORE_QUEUE 0x0027960a
+#define ASYNC_INVALID_OBJECT_PTS_REQUEST 0x0027960b
+#define ASYNC_INVALID_OBJECT_PTS_THREAD 0x0027960c
+#define ASYNC_INVALID_OBJECT_PTS_QUEUE 0x0027960d
+#define ASYNC_INVALID_OBJECT_PTS_START 0x0027960e
+#define ASYNC_INVALID_OBJECT_PTS_SCHEDULE 0x0027960f
+#define ASYNC_INVALID_ARGUMENT 0x00279610
+#define ASYNC_INVALID_ARGUMENT_OCB_READ 0x00279611
+#define ASYNC_INVALID_ARGUMENT_OCB_WRITE 0x00279612
+#define ASYNC_INVALID_ARGUMENT_OCB_QUEUE 0x00279613
+#define ASYNC_INVALID_ARGUMENT_OCB_QUEUE2 0x00279614
+#define ASYNC_INVALID_ARGUMENT_OCB_REQUEST 0x00279615
+#define ASYNC_INVALID_ARGUMENT_OCB_SCHEDULE 0x00279616
+#define ASYNC_INVALID_ARGUMENT_BCE_SCHEDULE 0x00279617
+#define ASYNC_INVALID_ARGUMENT_PBAX_READ 0x00279618
+#define ASYNC_INVALID_ARGUMENT_PBAX_REQUEST 0x00279619
+#define ASYNC_INVALID_ARGUMENT_PBAX_SCHEDULE 0x0027961a
+#define ASYNC_INVALID_ARGUMENT_PBAX_QUEUE 0x0027961b
+#define ASYNC_INVALID_ARGUMENT_PORE_REQUEST 0x0027961c
+#define ASYNC_INVALID_ARGUMENT_PTS_THREAD 0x0027961d
+#define ASYNC_INVALID_ARGUMENT_PTS_REQUEST 0x0027961e
+#define ASYNC_INVALID_ENGINE_OCB 0x0027961f
+#define ASYNC_INVALID_ENGINE_PBAX 0x00279620
+#define ASYNC_INVALID_ENGINE_BCE 0x00279621
+#define ASYNC_INVALID_ENGINE_PORE 0x00279622
+#define ASYNC_INVALID_ENGINE_PTS 0x00279623
+#define ASYNC_INVALID_OPTIONS 0x00279624
+#define ASYNC_INVALID_ASSIGNMENT 0x00279625
+#define ASYNC_CALLBACK_PROTOCOL_UNSPECIFIED 0x00279626
+#define ASYNC_REQUEST_NOT_IDLE 0x00279627
+#define ASYNC_REQUEST_NOT_IDLE_PTS 0x00279628
+#define ASYNC_REQUEST_COMPLETE 0x00279629
+#define ASYNC_INVALID_TIMESTAMPS 0x0027962a
+#define ASYNC_OCB_ERROR_READ_OLD 0x0027962b
+#define ASYNC_OCB_ERROR_READ_NEW 0x0027962c
+#define ASYNC_OCB_ERROR_WRITE_OLD 0x0027962d
+#define ASYNC_OCB_ERROR_WRITE_NEW 0x0027962e
+#define ASYNC_PBAX_ERROR_OLD 0x0027962f
+#define ASYNC_PBAX_ERROR_NEW 0x00279630
+#define ASYNC_REQUEST_NOT_COMPLETE 0x00279631
+#define ASYNC_REQUEST_NOT_COMPLETE_PTS 0x00279632
+
+// Panic codes
+
+#define ASYNC_PORE_FIXED_INVARIANT 0x00279633
+#define ASYNC_PHANTOM_INTERRUPT 0x00279634
+#define ASYNC_PHANTOM_INTERRUPT_OCB 0x00279635
+#define ASYNC_PHANTOM_INTERRUPT_BCE 0x00279636
+#define ASYNC_PHANTOM_INTERRUPT_PBAX 0x00279637
+#define ASYNC_SCOM_ERROR 0x00279638
+#define ASYNC_TIMEOUT_BUG 0x00279639
+#define ASYNC_INVALID_STATE 0x0027963a
+#define ASYNC_PHANTOM_ERROR 0x0027963b
+#define ASYNC_BUG_PORE_AT_CREATE 0x0027963c
+#define ASYNC_BUG_PTS_AT_CREATE 0x0027963d
+#define ASYNC_BUG_PTS_AT_RUN 0x0027963e
+
+////////////////////////////////////////////////////////////////////////////
+// Global Data and Constants
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+// PORE Queues
+
+extern PoreQueue G_pore_gpe0_queue;
+extern PoreQueue G_pore_gpe1_queue;
+extern PoreQueue G_pore_slw_queue;
+
+/// Define a PORE branch table. All error slots are always defined, but space
+/// can be saved if not all of the entry points are required.
+#define PORE_TABLE(var, slots) PoreBraia var[PORE_ERROR_SLOTS + (slots)]
+
+
+// PTS Queues
+//
+// These queues are only defined if CONFIGURE_PTS is non-zero. CONFIGURE_PTS
+// is 0 by default.
+
+#ifndef CONFIGURE_PTS
+#define CONFIGURE_PTS 0
+#endif
+
+#if CONFIGURE_PTS
+#include "pgp_async_pts.h"
+extern PtsQueue G_pts_gpe0_queue;
+extern PtsQueue G_pts_gpe1_queue;
+#endif
+
+
+// OCB Queues and FFDC
+
+// OCB circular queue naming is confusing, because PUSH/PULL are defined from
+// the perspective of the PIB. This driver uses the terms read/write
+// respectively and represents the hardware from the perspective of code
+// running on OCC.
+
+// OCB read/write queue lengths are defined in terms of doublewords, and must
+// be in a small defined range. Two meaningful interrupt protocols are
+// possible for a queue: 'LAZY' allows read/write queues to fill/empty
+// respectively before an interrupt is signalled. 'AGRESSIVE' signals an
+// interrupt whenever there is data to be read or a free slot to put write
+// data.
+
+// In a production system the lengths and protocols will likely vary based on
+// the particular application and the characteristics of the communication
+// partner. By default the queues take on their maximum lengths. Read queues
+// use the aggressive protocol which allows free-form communication. Write
+// queues use lazy protoclols which reduces interrupt overhead. Different
+// effective lengths and the interrupt protocols can be changed later if
+// desired - assuming the queues are idle when the changes are made.
+
+#define OCB_PUSH_PULL_LENGTH_MIN 1
+#define OCB_PUSH_PULL_LENGTH_MAX 32
+
+#define OCB_INTERRUPT_PROTOCOL_LAZY 0
+#define OCB_INTERRUPT_PROTOCOL_AGGRESSIVE 1
+
+#define OCB_READ0_LENGTH OCB_PUSH_PULL_LENGTH_MAX
+#define OCB_READ1_LENGTH OCB_PUSH_PULL_LENGTH_MAX
+#define OCB_READ2_LENGTH OCB_PUSH_PULL_LENGTH_MAX
+
+#define OCB_WRITE0_LENGTH OCB_PUSH_PULL_LENGTH_MAX
+#define OCB_WRITE1_LENGTH OCB_PUSH_PULL_LENGTH_MAX
+#define OCB_WRITE2_LENGTH OCB_PUSH_PULL_LENGTH_MAX
+
+#define OCB_READ0_PROTOCOL OCB_INTERRUPT_PROTOCOL_AGGRESSIVE
+#define OCB_READ1_PROTOCOL OCB_INTERRUPT_PROTOCOL_AGGRESSIVE
+#define OCB_READ2_PROTOCOL OCB_INTERRUPT_PROTOCOL_AGGRESSIVE
+
+#define OCB_WRITE0_PROTOCOL OCB_INTERRUPT_PROTOCOL_LAZY
+#define OCB_WRITE1_PROTOCOL OCB_INTERRUPT_PROTOCOL_LAZY
+#define OCB_WRITE2_PROTOCOL OCB_INTERRUPT_PROTOCOL_LAZY
+
+extern OcbUnitFfdc G_ocb_ffdc;
+
+extern OcbQueue G_ocb_read_queue[];
+extern OcbQueue G_ocb_write_queue[];
+
+extern uint64_t G_ocb_read0_buffer[];
+extern uint64_t G_ocb_read1_buffer[];
+extern uint64_t G_ocb_read2_buffer[];
+
+extern uint64_t G_ocb_write0_buffer[];
+extern uint64_t G_ocb_write1_buffer[];
+extern uint64_t G_ocb_write2_buffer[];
+
+
+// PBA Queues
+
+/// Block Copy Upload (OCI -> PowerBus) Engine job queue;
+extern BceQueue G_pba_bcue_queue;
+
+/// Block Copy Download Engine (PowerBus -> OCI) job queue;
+extern BceQueue G_pba_bcde_queue;
+
+
+// PBAX Queues
+
+// PBAX circular queue naming is confusing, because "PUSH" is defined from the
+// perspective of the PowerBus. This driver uses the term "READ" and
+// represents the hardware from the perspective of code running on OCC.
+
+// PBAX read queue lengths are defined in terms of 8-byte doublewords, and
+// must be in a small defined range. Two meaningful interrupt protocols are
+// possible for a queue: 'LAZY' allows read queues to fill before an interrupt
+// is signalled. 'AGRESSIVE' signals an interrupt whenever there is data to
+// be read.
+
+// In a production system the lengths and protocols will likely vary based on
+// the particular application and the characteristics of the communication
+// partner. By default the queues take on their maximum lengths. Read queues
+// use the aggressive protocol which allows free-form communication. Different
+// effective lengths and the interrupt protocols can be changed later if
+// desired - assuming the queues are idle when the changes are made.
+
+#define PBAX_PUSH_LENGTH_MIN 1
+#define PBAX_PUSH_LENGTH_MAX 32
+
+#define PBAX_INTERRUPT_PROTOCOL_LAZY 0
+#define PBAX_INTERRUPT_PROTOCOL_AGGRESSIVE 1
+
+#define PBAX_READ0_LENGTH PBAX_PUSH_LENGTH_MAX
+#define PBAX_READ1_LENGTH PBAX_PUSH_LENGTH_MAX
+
+#define PBAX_READ0_PROTOCOL PBAX_INTERRUPT_PROTOCOL_AGGRESSIVE
+#define PBAX_READ1_PROTOCOL PBAX_INTERRUPT_PROTOCOL_AGGRESSIVE
+
+/// Job queues for the PBAX circular buffers
+extern PbaxQueue G_pbax_read_queue[];
+
+
+// PBAX read buffers must be cache-line aligned since they are invalidated,
+// and furthermore must be aligned to the next higher power-of-two of their
+// lengths. Some minor efficiencies could probably be obtained by a policy
+// that buffers be held in non-cacheable storage (and subsequent modifications
+// to the device driver code).
+//
+// Due to linker restrictions, only initialized data areas can be aligned.
+
+
+#define _PBAX_ALIGN_(length) \
+ (((length) <= 4) ? 32 : \
+ (((length) <= 8) ? 64 : \
+ (((length) <= 16) ? 128 : 256)))
+
+#define PBAX_CQ_READ_BUFFER(buffer, length) \
+ uint64_t buffer[length] \
+ __attribute__ ((aligned (_PBAX_ALIGN_(length)))) = {0}
+
+
+extern uint64_t G_pbax_read0_buffer[];
+extern uint64_t G_pbax_read1_buffer[];
+
+
+// Initialization APIs
+
+void
+async_pore_initialize(PoreQueue *queue, int engine);
+
+void
+async_bce_initialize(BceQueue *queue, int engine, SsxIrqId irq);
+
+
+void
+async_ocb_initialize(OcbQueue *queue, int engine,
+ uint64_t *buffer, size_t length, int protocol);
+
+
+void
+async_pbax_initialize(PbaxQueue *queue, int engine, SsxIrqId irq,
+ uint64_t *buffer, size_t length, int protocol);
+
+
+void
+async_initialize();
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PGP_ASYNC_H__ */
diff --git a/src/ssx/pgp/pgp_async_ocb.c b/src/ssx/pgp/pgp_async_ocb.c
new file mode 100755
index 0000000..b9ef4b8
--- /dev/null
+++ b/src/ssx/pgp/pgp_async_ocb.c
@@ -0,0 +1,953 @@
+// $Id: pgp_async_ocb.c,v 1.2 2014/02/03 01:30:34 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_async_ocb.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_async_ocb.c
+/// \brief Async driver code for OCB
+
+#include "ssx.h"
+
+
+////////////////////////////////////////////////////////////////////////////
+// Global Data
+////////////////////////////////////////////////////////////////////////////
+
+OcbUnitFfdc G_ocb_ffdc = {{{{{0}}}}};
+
+OcbQueue G_ocb_read_queue[OCB_INDIRECT_CHANNELS];
+OcbQueue G_ocb_write_queue[OCB_INDIRECT_CHANNELS];
+
+
+#if OCB_READ0_LENGTH % CACHE_LINE_SIZE
+#error "OCB read buffer 0 alignment error"
+#endif
+#if OCB_READ1_LENGTH % CACHE_LINE_SIZE
+#error "OCB read buffer 1 alignment error"
+#endif
+#if OCB_READ2_LENGTH % CACHE_LINE_SIZE
+#error "OCB read buffer 2 alignment error"
+#endif
+#if OCB_READ3_LENGTH % CACHE_LINE_SIZE
+#error "OCB read buffer 3 alignment error"
+#endif
+
+// OCB circular queue write buffers must be 8-byte aligned per hardware
+// restrictions, whereas read buffers are cache-line aligned and must be an
+// even multiple of the cache line size since they must be invalidated. Some
+// minor efficiencies could probably be obtained by a policy that CQ buffers
+// be held in non-cacheable storage (and subsequent modifications to the
+// device driver code).
+//
+// Due to linker restrictions, only initialized data areas can be aligned.
+
+#define OCB_CQ_WRITE_BUFFER(buffer, length) \
+ uint64_t buffer[length] __attribute__ ((aligned (8))) = {0}
+
+#define OCB_CQ_READ_BUFFER(buffer, length) \
+ uint64_t buffer[length] __attribute__ ((aligned (CACHE_LINE_SIZE))) = {0}
+
+
+OCB_CQ_READ_BUFFER(G_ocb_read0_buffer, OCB_READ0_LENGTH);
+OCB_CQ_READ_BUFFER(G_ocb_read1_buffer, OCB_READ1_LENGTH);
+OCB_CQ_READ_BUFFER(G_ocb_read2_buffer, OCB_READ2_LENGTH);
+
+OCB_CQ_WRITE_BUFFER(G_ocb_write0_buffer, OCB_WRITE0_LENGTH);
+OCB_CQ_WRITE_BUFFER(G_ocb_write1_buffer, OCB_WRITE1_LENGTH);
+OCB_CQ_WRITE_BUFFER(G_ocb_write2_buffer, OCB_WRITE2_LENGTH);
+
+
+////////////////////////////////////////////////////////////////////////////
+// Local Data
+////////////////////////////////////////////////////////////////////////////
+
+/// \todo These addresses could/should simply be stored with the queue objects
+/// to avoid these static data declarations.
+
+/// OCB Stream Push/Pull Control/Status Register addresses
+
+static const SsxAddress G_ocb_ocbsxcsn[OCB_ENGINES] =
+ {OCB_OCBSHCS0, OCB_OCBSLCS0,
+ OCB_OCBSHCS1, OCB_OCBSLCS1,
+ OCB_OCBSHCS2, OCB_OCBSLCS2};
+
+/// OCB Stream Push/Pull Base Register addresses
+
+static const SsxAddress G_ocb_ocbsxbrn[OCB_ENGINES] =
+ {OCB_OCBSHBR0, OCB_OCBSLBR0,
+ OCB_OCBSHBR1, OCB_OCBSLBR1,
+ OCB_OCBSHBR2, OCB_OCBSLBR2};
+
+
+/// OCB Stream Push/Pull Increment Register addresses
+
+static const SsxAddress G_ocb_ocbsxin[OCB_ENGINES] =
+ {OCB_OCBSHI0, OCB_OCBSLI0,
+ OCB_OCBSHI1, OCB_OCBSLI1,
+ OCB_OCBSHI2, OCB_OCBSLI2};
+
+
+/// OCB Stream Error Status; There is only one register per OCB channel
+
+const SsxAddress G_ocb_ocbsesn[OCB_ENGINES / 2] =
+ {OCB_OCBSES0, OCB_OCBSES1, OCB_OCBSES2};
+
+
+////////////////////////////////////////////////////////////////////////////
+// OcbRequest
+////////////////////////////////////////////////////////////////////////////
+
+// Collect FFDC for an OCB channel
+//
+// This is an internal API, called either due to an OCB error interrupt or a
+// read/write error detected during the operation. See the comments for
+// OcbFfdc for a description of why this particular set of data is collected.
+// The special channel number -1 is used to denote the direct bridge.
+//
+// OCB FFDC collection procedure:
+//
+// - Collect the OCBSCR<n> for indirect channels
+//
+// - Collect PUSH/PULL queue setup for indirect channels and disable the queues.
+//
+// - Collect the OCB FIR
+//
+// - Collect FFDC from the PLB (OCI) arbiter
+//
+// FFDC is only collected for the first error, until the error flag is reset.
+
+static void
+ocb_ffdc(int channel)
+{
+ OcbFfdc* ffdc;
+
+ if (channel < 0) {
+ ffdc = &(G_ocb_ffdc.bridge);
+ } else {
+ ffdc = &(G_ocb_ffdc.channel[channel]);
+ }
+
+ if (ffdc->error == 0) {
+
+ if (channel < 0) {
+
+ memset(ffdc, 0, sizeof(OcbFfdc));
+
+ } else {
+
+ getscom(OCB_OCBCSRN(channel), &(ffdc->csr.value));
+
+ ffdc->shbr.value = in32(OCB_OCBSHBRN(channel));
+ ffdc->shcs.value = in32(OCB_OCBSHCSN(channel));
+ ffdc->slbr.value = in32(OCB_OCBSLBRN(channel));
+ ffdc->slcs.value = in32(OCB_OCBSLCSN(channel));
+
+ out32(OCB_OCBSHCSN(channel),
+ ffdc->shcs.value & ~OCB_OCBSHCSN_PUSH_ENABLE);
+ out32(OCB_OCBSLCSN(channel),
+ ffdc->slcs.value & ~OCB_OCBSLCSN_PULL_ENABLE);
+
+ }
+
+ getscom(OCB_OCCLFIR, &(ffdc->fir.value));
+
+ oci_ffdc(&(ffdc->oci_ffdc), OCI_MASTER_ID_OCB);
+
+ ffdc->error = 1;
+ }
+}
+
+
+/// Non-blocking read from an OCB PUSH (read) queue
+///
+/// \param queue The target OcbQueue
+///
+/// \param buf The caller's data buffer to receive the read data
+///
+/// \param bytes The maximum number of bytes to read. This value must be an
+/// even multiple of 8, as this API always reads multiples of 8 bytes.
+///
+/// \param read The number of bytes actually copied from the device buffer to
+/// the caller's buffer. This may be returned as any value from 0 to \a
+/// bytes in multiples of 8 bytes.
+///
+/// ocb_read() implements a non-blocking copy of data from an OCB read (PUSH)
+/// queue data area to the caller's data area, with the side effect of
+/// advancing the hardware queue pointers. ocb_read() does not implement
+/// locking, critical sections or any other type of synchronization for access
+/// to the OCB queue data - that is the responsibility of the caller.
+///
+/// ocb_read() may return an error code. This may indicate a preexisting
+/// error in the queue, or may be an error resulting from the current read.
+/// In either event any read data should be considered corrupted.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_OCB_READ The number of \a bytes is not
+/// an even multiple of 8.
+///
+/// \retval -ASYNC_OCB_ERROR_READ_OLD or -ASYNC_OCB_ERROR_READ_NEW This code
+/// indicates an error associated with the OCB channel represented by the queue.
+
+int
+ocb_read(OcbQueue *queue, void* buf, size_t bytes, size_t* read)
+{
+ ocb_ocbshcsn_t csr;
+ ocb_ocbsesn_t ses;
+ unsigned qlen, read_ptr, write_ptr, to_read;
+ uint64_t *pcq, *pbuf;
+ int rc;
+
+ do {
+
+ rc = 0;
+ *read = 0;
+
+ // If pre-existing errors exist then immediately abort the read.
+
+ if (G_ocb_ffdc.channel[queue->engine / 2].error) {
+ rc = -ASYNC_OCB_ERROR_READ_OLD;
+ break;
+ }
+
+ if (bytes % 8) {
+ rc = -ASYNC_INVALID_ARGUMENT_OCB_READ;
+ break;
+ }
+
+ // Determine the number of doubleword entries remaining to be read in
+ // the queue. The driver does not keep state, but instead reinterprets
+ // the control/status register each time ocb_read() is called.
+
+ // This may be confusing - remember that 'push' and 'pull' are from
+ // the PIB perspective - here we use 'read' and 'write' from OCC's
+ // perspective.
+
+ csr.value = in32(G_ocb_ocbsxcsn[queue->engine]);
+
+ qlen = csr.fields.push_length + 1;
+ read_ptr = csr.fields.push_read_ptr;
+
+ if (csr.fields.push_empty) {
+ break;
+
+ } else if (csr.fields.push_full) {
+ to_read = qlen;
+
+ } else {
+ write_ptr = csr.fields.push_write_ptr;
+ if (read_ptr > write_ptr) {
+ to_read = qlen - (read_ptr - write_ptr);
+ } else {
+ to_read = write_ptr - read_ptr;
+ }
+ }
+
+ // Copy the data from the CQ memory area to the user's buffer. For
+ // simplicty of dealing with cache management each doubleword invokes
+ // a line invalidate before refetching the fresh data from
+ // memory. Alignment requirements enforced on the data buffer
+ // guarantee the buffers are cache-line aligned and each doubleword is
+ // fully contained in a single D-cache line.
+ //
+ // Here the code models the evolution of the read_ptr as each datum is
+ // copied from the queue.
+
+ pbuf = (uint64_t*)buf;
+ while (bytes && to_read--) {
+
+ read_ptr++;
+ if (read_ptr == qlen) {
+ read_ptr = 0;
+ }
+ pcq = queue->cq_base + read_ptr;
+
+ dcache_invalidate_line(pcq);
+ *pbuf++ = *pcq;
+ out32(G_ocb_ocbsxin[queue->engine], 0);
+
+ bytes -= 8;
+ *read += 8;
+ }
+ } while (0);
+
+ // Check for underflow errors. If found, collect FFDC.
+
+ ses.value = in32(G_ocb_ocbsesn[queue->engine / 2]);
+ if (ses.fields.push_read_underflow) {
+ ocb_ffdc(queue->engine / 2);
+ rc = -ASYNC_OCB_ERROR_READ_NEW;
+ }
+
+ return rc;
+}
+
+
+/// Non-blocking write to an OCB PULL (write) queue
+///
+/// \param queue The target OcbQueue
+///
+/// \param buf The caller's data buffer containing the write data
+///
+/// \param bytes The maximum number of bytes to write. This value must be an
+/// even multiple of 8, as this API always writes multiples of 8 bytes.
+///
+/// \param written The number of bytes actually copied from the caller's buffer to
+/// the device buffer. This may be returned as any value from 0 to \a
+/// bytes in multiples of 8 bytes.
+///
+/// ocb_write() implements a non-blocking copy of data to an OCB write (PULL)
+/// queue, with the side effect of advancing the hardware queue pointers.
+/// ocb_write() does not implement locking, critical sections or any other
+/// type of synchronization for access to the OCB queue data - that is the
+/// responsibility of the caller.
+///
+/// ocb_write() may return an error code. This may indicate a preexisting
+/// error in the queue, or may be an error resulting from the current write.
+/// In either event any write data should be considered corrupted/nondelivered.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_OCB_WRITE The number of \a bytes is not
+/// an even multiple of 8.
+///
+/// \retval -ASYNC_OCB_ERROR_WRITE_OLD or -ASYNC_OCB_ERROR_WRITE_NEW This code
+/// indicates an error associated with the OCB channel represented by the queue.
+
+int
+ocb_write(OcbQueue *queue, void* buf, size_t bytes, size_t* written)
+{
+ ocb_ocbslcsn_t csr;
+ ocb_ocbsesn_t ses;
+ unsigned qlen, read_ptr, write_ptr, free;
+ uint64_t *pcq, *pbuf;
+ int rc;
+
+ do {
+
+ rc = 0;
+ *written = 0;
+
+ // Pre-existing errors immediately abort the read.
+
+ if (G_ocb_ffdc.channel[queue->engine / 2].error) {
+ rc = -ASYNC_OCB_ERROR_WRITE_OLD;
+ break;
+ }
+
+ if (bytes % 8) {
+ rc = -ASYNC_INVALID_ARGUMENT_OCB_WRITE;
+ break;
+ }
+
+ // Determine the number of free doubleword entries remaining in the
+ // queue. The driver does not keep state, but instead reinterprets the
+ // control/status register each time the write method is called.
+
+ // This is confusing - remember that 'push' and 'pull' are from the PIB
+ // perspective - here we use 'read' and 'write' from OCC's perspective.
+
+ csr.value = in32(G_ocb_ocbsxcsn[queue->engine]);
+
+ qlen = csr.fields.pull_length + 1;
+ write_ptr = csr.fields.pull_write_ptr;
+
+ if (csr.fields.pull_full) {
+ break;
+ }
+
+ if (csr.fields.pull_empty) {
+ free = qlen;
+ } else {
+ read_ptr = csr.fields.pull_read_ptr;
+ if (write_ptr > read_ptr) {
+ free = qlen - (write_ptr - read_ptr);
+ } else {
+ free = read_ptr - write_ptr;
+ }
+ }
+
+ // Copy the data into the CQ memory area. For simplicty of dealing
+ // with cache management each doubleword invokes a line flush before
+ // incrementing the hardware pointer. Alignment requirements enforced
+ // on the data buffer guarantee each doubleword is fully contained in
+ // a single D-cache line.
+ //
+ // Here the code models the evolution of the write_ptr as each datum is
+ // copied into the queue.
+
+ pbuf = (uint64_t*)buf;
+ while (bytes && free--) {
+
+ write_ptr++;
+ if (write_ptr == qlen) {
+ write_ptr = 0;
+ }
+ pcq = queue->cq_base + write_ptr;
+
+ *pcq = *pbuf++;
+ dcache_flush_line(pcq);
+ in32(G_ocb_ocbsxin[queue->engine]);
+
+ bytes -= 8;
+ *written += 8;
+ }
+ } while (0);
+
+ // Check for overflow. If found, collect FFDC.
+
+ ses.value = in32(G_ocb_ocbsesn[queue->engine / 2]);
+ if (ses.fields.pull_write_overflow) {
+ ocb_ffdc(queue->engine / 2);
+ rc = -ASYNC_OCB_ERROR_WRITE_NEW;
+ }
+
+ return rc;
+}
+
+
+// This is the internal 'run method' for reading through an OCB circular
+// queue. The run method simply enables the IRQ. The interrupt handler reads
+// data from the queue and leaves the interrupt enabled until the read is
+// satisfied.
+
+static int
+ocb_read_method(AsyncRequest *async_request)
+{
+ OcbRequest *request = (OcbRequest*)async_request;
+ OcbQueue *queue = (OcbQueue*)(async_request->queue);
+ int rc;
+
+ if (request->bytes == 0) {
+ rc = -ASYNC_REQUEST_COMPLETE;
+ } else {
+ ssx_irq_enable(queue->irq);
+ rc = 0;
+ }
+ return rc;
+}
+
+
+// This is the internal 'run method' for writing through an OCB circular
+// queue. The run method simply enables the IRQ. The interrupt handler writes
+// data from the queue and leaves the interrupt enabled until the write is
+// satisfied.
+
+static int
+ocb_write_method(AsyncRequest *async_request)
+{
+ OcbRequest *request = (OcbRequest *)async_request;
+ OcbQueue *queue = (OcbQueue*)(async_request->queue);
+ int rc;
+
+ if (request->bytes == 0) {
+ rc = -ASYNC_REQUEST_COMPLETE;
+ } else {
+ ssx_irq_enable(queue->irq);
+ rc = 0;
+ }
+ return rc;
+}
+
+
+// The async error method for OCB
+//
+// Collect FFDC. The return of -1 will disable the channel associated with
+// the request.
+
+static int
+ocb_async_error_method(AsyncRequest *request)
+{
+ OcbQueue *queue = (OcbQueue*)(request->queue);
+ ocb_ffdc(queue->engine / 2);
+ return -1;
+}
+
+
+/// Create a request for an OCB circular queue
+///
+/// \param request An uninitialized or otherwise idle OcbRequest.
+///
+/// \param queue An async queue for an OCB circular buffer. The queue \a
+/// engine determines whether this is a read or write request.
+///
+/// \param data A pointer to the data to be moved (for write) or where the
+/// data should be placed (for read).
+///
+/// \param bytes The number of bytes of data to move. The OCB
+/// circular buffers always move multiples of 8 bytes, and the number of bytes
+/// must be a multiple of 8. Higher-level abstractions will have to take care
+/// of cases where the numbers of bytes are not multiples of 8.
+///
+/// \param timeout If not specified as SSX_WAIT_FOREVER, then this request
+/// will be governed by a private watchdog timer that will cancel a queued job
+/// or kill a running job if the hardware operation does not complete before
+/// it times out.
+///
+/// \param callback The callback to execute when the data move completes, or
+/// NULL (0) to indicate no callback.
+///
+/// \param arg The parameter to the callback routine; ignored if the \a
+/// callback is NULL.
+///
+/// \param options Options to control request priority, callback context and
+/// blocking.
+///
+/// This routine has no way to know if the OcbRequest structure is currently
+/// in use, so this API should only be called on uninitialized or otherwise
+/// idle OcbRequest structures.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_OCB_REQUEST The \a request or \a queue were NULL (0), or
+/// the \a queue is not an initialized OcbQueue.
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_OCB_REQUEST The \a data pointer is
+/// NULL (0), or the number of bytes is not a multiple of 8.
+///
+/// See async_request_create() for other errors that may be returned by this
+/// call.
+
+int
+ocb_request_create(OcbRequest *request,
+ OcbQueue *queue,
+ uint64_t *data,
+ size_t bytes,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options)
+{
+ int rc;
+ AsyncRunMethod run_method = 0; // Make GCC Happy
+ AsyncQueue *async_queue = (AsyncQueue *)queue;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((request == 0) ||
+ (queue == 0) ||
+ !(async_queue->engine & ASYNC_ENGINE_OCB),
+ ASYNC_INVALID_OBJECT_OCB_REQUEST);
+ SSX_ERROR_IF((data == 0) ||
+ (bytes % 8),
+ ASYNC_INVALID_ARGUMENT_OCB_REQUEST);
+ }
+
+ switch (async_queue->engine) {
+
+ case ASYNC_ENGINE_OCB_PULL0:
+ case ASYNC_ENGINE_OCB_PULL1:
+ case ASYNC_ENGINE_OCB_PULL2:
+ run_method = ocb_write_method;
+ break;
+
+ case ASYNC_ENGINE_OCB_PUSH0:
+ case ASYNC_ENGINE_OCB_PUSH1:
+ case ASYNC_ENGINE_OCB_PUSH2:
+ run_method = ocb_read_method;
+ break;
+ }
+
+ rc = async_request_create(&(request->request),
+ async_queue,
+ run_method,
+ ocb_async_error_method,
+ timeout,
+ callback,
+ arg,
+ options);
+
+ request->data = data;
+ request->bytes = bytes;
+
+ return rc;
+}
+
+
+/// Schedule a request on an OCB circular queue.
+///
+/// \param request An initialized OcbRequest
+///
+/// Note : As long as the OcbRequest is idle, the application is free to
+/// directly change the \a data and \a bytes fields to read/write different
+/// numbers of bytes to/from different locations the next time the request is
+/// scheduled.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_OCB_SCHEDULE The number of \a bytes
+/// currently requested is not a multiple of 8.
+///
+/// See async_request_schedule() for documentation of other errors
+
+int
+ocb_request_schedule(OcbRequest *request)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((request->bytes % 8), ASYNC_INVALID_ARGUMENT_OCB_SCHEDULE);
+ }
+
+ request->current = request->data;
+ request->remaining = request->bytes;
+
+ return async_request_schedule((AsyncRequest *)request);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// OcbQueue
+////////////////////////////////////////////////////////////////////////////
+
+/// Reset an OCB circular PUSH (read) queue
+///
+/// This API is normally used during initialization, and assumes that all of
+/// the parameters are valid. It resets and reprograms the hardware
+/// associated with an OCB circular buffer to be consistent with the queue
+/// engine, base address, length and interrupt protocol. The queue is enabled
+/// and its interrupts are disabled. Any data in the queue will be silently
+/// lost.
+///
+/// Note that this API \e does \e not put the OCB channel into circular mode -
+/// the communication method is controlled by the communication partner.
+///
+/// The function of this routine is to write a new value into the OCB Stream
+/// Push Control/Status register, which as a side effect resets the circular
+/// buffer. The base register is also set up.
+
+void
+ocb_read_engine_reset(OcbQueue *queue, size_t cq_length, int protocol)
+{
+ ocb_ocbshcsn_t cs;
+
+ // Disable interrupts and disable and clear the queue. The queue length
+ // field is updated (for informational purposes). Interrupts will be
+ // re-enabled when requests are made for the queue.
+
+ ssx_irq_disable(queue->irq);
+
+ queue->cq_length = cq_length;
+
+ cs.value = 0;
+ out32(G_ocb_ocbsxcsn[queue->engine], cs.value);
+
+
+ // Reinitialize the data buffer base address register
+
+ out32(G_ocb_ocbsxbrn[queue->engine], (uint32_t)(queue->cq_base));
+
+
+ // Reprogram and reenable/reset the queue
+
+ if (protocol == OCB_INTERRUPT_PROTOCOL_LAZY) {
+ cs.fields.push_intr_action = OCB_INTR_ACTION_FULL;
+ } else {
+ cs.fields.push_intr_action = OCB_INTR_ACTION_NOT_EMPTY;
+ }
+
+ cs.fields.push_length = cq_length - 1;
+ cs.fields.push_enable = 1;
+
+ out32(G_ocb_ocbsxcsn[queue->engine], cs.value);
+}
+
+
+/// Reset an OCB circular PULL (write) queue
+///
+/// This API is normally used during initialization, and assumes that all of
+/// the parameters are valid. It resets and reprograms the hardware
+/// associated with an OCB circular buffer to be consistent with the queue
+/// engine, base address, length and interrupt protocol. The queue is enabled
+/// and its interrupts are disabled. Any data in the queue will be silently
+/// lost.
+///
+/// Note that this API \e does \e not put the OCB channel into circular mode -
+/// the communication method is controlled by the communication partner.
+///
+/// The function of this routine is to write a new value into the OCB Stream
+/// Pull Control/Status register, which as a side effect resets the circular
+/// buffer. The base register is also set up.
+
+void
+ocb_write_engine_reset(OcbQueue *queue, size_t cq_length, int protocol)
+{
+ ocb_ocbslcsn_t cs;
+
+ // Disable interrupts and disable and clear the queue. The queue length
+ // field is updated (for informational purposes). Interrupts will be
+ // re-enabled when requests are made for the queue.
+
+ ssx_irq_disable(queue->irq);
+
+ queue->cq_length = cq_length;
+
+ cs.value = 0;
+ out32(G_ocb_ocbsxcsn[queue->engine], cs.value);
+
+
+ // Reinitialize the data buffer base address register
+
+ out32(G_ocb_ocbsxbrn[queue->engine], (uint32_t)(queue->cq_base));
+
+
+ // Reprogram and reenable/reset the queue
+
+ if (protocol == OCB_INTERRUPT_PROTOCOL_LAZY) {
+ cs.fields.pull_intr_action = OCB_INTR_ACTION_EMPTY;
+ } else {
+ cs.fields.pull_intr_action = OCB_INTR_ACTION_NOT_FULL;
+ }
+
+ cs.fields.pull_length = cq_length - 1;
+ cs.fields.pull_enable = 1;
+
+ out32(G_ocb_ocbsxcsn[queue->engine], cs.value);
+}
+
+
+/// Create (initialize) an OcbQueue
+///
+/// \param queue An uninitialized or otherwise idle OcbQueue
+///
+/// \param engine A valid OCB engine id
+///
+/// \param cq_base The base address of the circular queue data area for the
+/// queue. This address must be 8-byte aligned for write queues. Read queues
+/// must be cache-line aligned and a multiple of the cache line in size.
+///
+/// \param cq_length The length of the circular queue measured in 8-byte
+/// increments.
+///
+/// \param protocol The interrupt protocol, either OCB_PUSH_PULL_PROTOCOL_LAZY
+/// or OCB_PUSH_PULL_PROTOCOL_AGGRESSIVE. Lazy means that read queues only
+/// interrupt when empty, and write queues only interrupt when full.
+/// Agressive means that read queues interrupt when not empty and write queues
+/// interrupt when not full. In general the lazy read protocol will only work
+/// for 1) queues of length 1, where lazy == aggressive, and 2) protocols
+/// where a known fixed number of 8-byte entries is always expected to be
+/// received.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_OCB_QUEUE The \a queue was NULL (0).
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_OCB_QUEUE The \a cq_base is not properly
+/// aligned, or the \a cq_length is invalid, or the \a protocol is invalid.
+///
+/// \retval -ASYNC_INVALID_ENGINE_OCB The \a engine is not an OCB engine.
+///
+/// Other errors may be returned by async_queue_create().
+
+int
+ocb_queue_create(OcbQueue *queue,
+ int engine,
+ uint64_t *cq_base,
+ size_t cq_length,
+ int protocol)
+{
+ AsyncQueue *async_queue = (AsyncQueue *)queue;
+ int align_mask = 0;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(queue == 0, ASYNC_INVALID_OBJECT_OCB_QUEUE);
+ SSX_ERROR_IF((cq_length < OCB_PUSH_PULL_LENGTH_MIN) ||
+ (cq_length > OCB_PUSH_PULL_LENGTH_MAX) ||
+ ((protocol != OCB_INTERRUPT_PROTOCOL_LAZY) &&
+ (protocol != OCB_INTERRUPT_PROTOCOL_AGGRESSIVE)),
+ ASYNC_INVALID_ARGUMENT_OCB_QUEUE);
+ }
+
+ queue->cq_base = cq_base;
+ queue->cq_length = cq_length;
+
+ switch (engine) {
+
+ // These are the read engines from OCC's perspective.
+
+ case ASYNC_ENGINE_OCB_PUSH0:
+ queue->irq = PGP_IRQ_STRM0_PUSH;
+ queue->engine = OCB_ENGINE_PUSH0;
+ goto read_engine;
+
+ case ASYNC_ENGINE_OCB_PUSH1:
+ queue->irq = PGP_IRQ_STRM1_PUSH;
+ queue->engine = OCB_ENGINE_PUSH1;
+ goto read_engine;
+
+ case ASYNC_ENGINE_OCB_PUSH2:
+ queue->irq = PGP_IRQ_STRM2_PUSH;
+ queue->engine = OCB_ENGINE_PUSH2;
+ goto read_engine;
+
+ read_engine:
+ align_mask = CACHE_LINE_SIZE - 1;
+ async_queue_create(async_queue, engine);
+ ocb_read_engine_reset(queue, cq_length, protocol);
+ break;
+
+ // These are the write engines from OCC's perspective.
+
+ case ASYNC_ENGINE_OCB_PULL0:
+ queue->irq = PGP_IRQ_STRM0_PULL;
+ queue->engine = OCB_ENGINE_PULL0;
+ goto write_engine;
+
+ case ASYNC_ENGINE_OCB_PULL1:
+ queue->irq = PGP_IRQ_STRM1_PULL;
+ queue->engine = OCB_ENGINE_PULL1;
+ goto write_engine;
+
+ case ASYNC_ENGINE_OCB_PULL2:
+ queue->irq = PGP_IRQ_STRM2_PULL;
+ queue->engine = OCB_ENGINE_PULL2;
+ goto write_engine;
+
+ write_engine:
+ align_mask = 8 - 1;
+ async_queue_create(async_queue, engine);
+ ocb_write_engine_reset(queue, cq_length, protocol);
+ break;
+
+ default:
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(1, ASYNC_INVALID_ENGINE_OCB);
+ }
+ }
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(((uint32_t)cq_base & align_mask) != 0,
+ ASYNC_INVALID_ARGUMENT_OCB_QUEUE2);
+ }
+
+ return 0;
+}
+
+
+// The interrupt handler for asynchronous OCB CQ requests
+//
+// The circular buffer interupts are level sensitive, active high. There is
+// really no way to 'clear' them as they indicate a permanent status - so
+// instead they need to be enabled and disabled. Interrupts are enabled by the
+// run methods and disabled by the interrupt handlers once all data has been
+// transferred (or in the event of an error).
+//
+// This interrupt handler can process up to 256 bytes at once, plus the
+// overhead of scheduling the next job when this one completes. If interrupt
+// latency becomes a problem then this process could be run with interrupt
+// preemption enabled.
+
+SSX_IRQ_FAST2FULL(ocb_async_handler, ocb_async_handler_full);
+
+void
+ocb_async_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ AsyncQueue *async_queue = (AsyncQueue*)arg;
+ OcbQueue *queue = (OcbQueue*)async_queue;
+ OcbRequest *request = (OcbRequest*)(async_queue->current);
+ size_t processed;
+ int rc;
+
+ if (SSX_ERROR_CHECK_KERNEL && (request == 0)) {
+ SSX_PANIC(ASYNC_PHANTOM_INTERRUPT_OCB);
+ }
+
+ if (queue->engine % 2) {
+ rc = ocb_write(queue, request->current, request->remaining, &processed);
+ } else {
+ rc = ocb_read(queue, request->current, request->remaining, &processed);
+ }
+
+ if (rc) {
+
+ ssx_irq_disable(queue->irq);
+ async_error_handler(async_queue, ASYNC_REQUEST_STATE_FAILED);
+
+ } else if (processed == request->remaining) {
+
+ ssx_irq_disable(queue->irq);
+ async_handler(async_queue);
+
+ } else {
+
+ request->current += (processed / 8);
+ request->remaining -= processed;
+ }
+}
+
+
+// The interrupt handler for the OCB error interrupt.
+//
+// There is one interrupt that covers all OCB indirect channels as well as the
+// direct bridge. When this interrupt fires we try to determine which unit is
+// responsible. If the error appears to be associated with a job running as
+// part of the async mechanism then we let the async_error_handler() mechanism
+// operate, otherwise simply collect FFDC. The \a error field of the FFDC
+// structure stops non-queued read/write requests. Note that we kill both read
+// and write jobs without regard to the error.
+//
+// If the error is due to the direct bridge we collect FFDC, but can't really
+// do anything else.
+
+/// \todo What action to take for bridge errors?
+
+
+SSX_IRQ_FAST2FULL(ocb_error_handler, ocb_error_handler_full);
+
+void
+ocb_error_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ ocb_occlfir_t fir;
+ int channel;
+ AsyncQueue* queue;
+
+ ssx_irq_status_clear(irq);
+
+ getscom(OCB_OCCLFIR, &(fir.value));
+
+ for (channel = 0; channel < OCB_INDIRECT_CHANNELS; channel++) {
+ if (fir.value & (OCB_OCCLFIR_OCB_IDC0_ERROR >> channel)) {
+
+ queue = (AsyncQueue*)(&(G_ocb_read_queue[channel]));
+ if (queue->state == ASYNC_QUEUE_STATE_RUNNING) {
+ async_error_handler(queue, ASYNC_REQUEST_STATE_FAILED);
+ } else {
+ ocb_ffdc(channel);
+ }
+
+ queue = (AsyncQueue*)(&(G_ocb_write_queue[channel]));
+ if (queue->state == ASYNC_QUEUE_STATE_RUNNING) {
+ async_error_handler(queue, ASYNC_REQUEST_STATE_FAILED);
+ } else {
+ ocb_ffdc(channel);
+ }
+ }
+ }
+
+ if (fir.fields.ocb_db_oci_timeout |
+ fir.fields.ocb_db_oci_read_data_parity |
+ fir.fields.ocb_db_oci_slave_error |
+ fir.fields.ocb_pib_addr_parity_err |
+ fir.fields.ocb_db_pib_data_parity_err) {
+
+ ocb_ffdc(-1);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// Initialization
+////////////////////////////////////////////////////////////////////////////
+
+void
+async_ocb_initialize(OcbQueue *queue, int engine,
+ uint64_t *buffer, size_t length, int protocol)
+{
+ ocb_queue_create(queue, engine, buffer, length, protocol);
+ async_level_handler_setup(ocb_async_handler,
+ (void *)queue,
+ queue->irq,
+ SSX_NONCRITICAL,
+ SSX_IRQ_POLARITY_ACTIVE_HIGH);
+ // Driver manages IRQ enable/disable
+}
diff --git a/src/ssx/pgp/pgp_async_pba.c b/src/ssx/pgp/pgp_async_pba.c
new file mode 100755
index 0000000..14b5619
--- /dev/null
+++ b/src/ssx/pgp/pgp_async_pba.c
@@ -0,0 +1,1201 @@
+// $Id: pgp_async_pba.c,v 1.2 2014/02/03 01:30:34 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_async_pba.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_async_pba.c
+/// \brief Async device drivers for the PBA block copy engines and PBAX
+
+#include "ssx.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Global Data
+////////////////////////////////////////////////////////////////////////////
+
+BceQueue G_pba_bcue_queue;
+BceQueue G_pba_bcde_queue;
+
+PbaxQueue G_pbax_read_queue[PBAX_QUEUES];
+
+
+////////////////////////////////////////////////////////////////////////////
+// Local Data
+////////////////////////////////////////////////////////////////////////////
+
+
+/// Combined FFDC for all PBA subunits
+static PbaUnitFfdc G_pba_ffdc = {{{{{0}}}}};
+
+
+PBAX_CQ_READ_BUFFER(G_pbax_read0_buffer, PBAX_READ0_LENGTH);
+PBAX_CQ_READ_BUFFER(G_pbax_read1_buffer, PBAX_READ1_LENGTH);
+
+// The generic driver code stores an engine-specfic engine ID in the
+// queue. Here arrays are set up that contain the OCI control register
+// addresses for an engine indexed by the queue-specific value.
+//
+/// \todo Once the designers actually define register addresses, see about
+/// modifying these tables to be macros instead.
+///
+/// \todo Actually, why don't we just store this data directly in the queue?
+
+/// PBA BCDE/BCUE PowerBus BAR[0..31]
+static const SsxAddress G_bce_pbadr[BCE_ENGINES] =
+ {PBA_BCDE_PBADR, PBA_BCUE_PBADR};
+
+/// PBA BCDE/BCUE OCI BAR
+static const SsxAddress G_bce_ocibar[BCE_ENGINES] =
+ {PBA_BCDE_OCIBAR, PBA_BCUE_OCIBAR};
+
+/// PBA BCDE/BCUE SET register
+static const SsxAddress G_bce_set[BCE_ENGINES] =
+ {PBA_BCDE_SET, PBA_BCUE_SET};
+
+/// PBA BCDE/BCUE Control register
+static const SsxAddress G_bce_ctl[BCE_ENGINES] =
+ {PBA_BCDE_CTL, PBA_BCUE_CTL};
+
+/// PBA BCDE/BCUE Status register
+static const SsxAddress G_bce_stat[BCE_ENGINES] =
+ {PBA_BCDE_STAT, PBA_BCUE_STAT};
+
+/// PBAX Push Queue Control/Status Register addresses
+static const SsxAddress G_pba_xshcsn[PBAX_ENGINES] =
+ {PBA_XSHCS0, PBA_XSHCS1};
+
+/// PBAX Push Queue Base Register addresses
+static const SsxAddress G_pba_xshbrn[PBAX_ENGINES] =
+ {PBA_XSHBR0, PBA_XSHBR1};
+
+/// PBAX Push Queue Increment Register addresses
+static const SsxAddress G_pba_xshincn[PBAX_ENGINES] =
+ {PBA_XSHINC0, PBA_XSHINC1};
+
+
+////////////////////////////////////////////////////////////////////////////
+// PBA FFDC Structures
+////////////////////////////////////////////////////////////////////////////
+
+// NB: Collection of FFDC for PBA will be very time consuming due to the large
+// amount of information required to fully diagnose any problem. This will be
+// done in a critical interrupt so it may have some impact on micro-timescale
+// realtime operations.
+
+// Collect PBA common FFDC
+//
+// Most of this is just collection of all of the setup registers required to
+// diagnose problems with the bridge and block copy engines. Not all of this
+// data is required for PBAX errors but we collect it anyway.
+//
+// FFDC is only collected for the first error, until the error flag is reset.
+
+static void
+pba_common_ffdc(PbaCommonFfdc* ffdc)
+{
+ int i;
+
+ if (ffdc->error == 0) {
+
+ oci_ffdc(&(ffdc->oci_ffdc), OCI_MASTER_ID_PBA);
+
+ ffdc->mode.value = in64(PBA_MODE);
+
+ for (i = 0; i < PBA_READ_BUFFERS; i++) {
+ getscom(PBA_RBUFVALN(i), &(ffdc->rbufval[i].value));
+ }
+
+ for (i = 0; i < PBA_WRITE_BUFFERS; i++) {
+ getscom(PBA_WBUFVALN(i), &(ffdc->wbufval[i].value));
+ }
+
+ for (i = 0; i < PBA_BARS; i++) {
+ getscom(PBA_BARN(i), &(ffdc->bar[i].value));
+ getscom(PBA_BARMSKN(i), &(ffdc->barmsk[i].value));
+ }
+
+ getscom(PBA_FIR, &(ffdc->fir.value));
+ getscom(PBA_ERRPT0, &(ffdc->errpt0.value));
+ getscom(PBA_ERRPT1, &(ffdc->errpt1.value));
+ getscom(PBA_ERRPT2, &(ffdc->errpt2.value));
+
+ ffdc->error = 1;
+ }
+}
+
+
+// Collect FFDC for generic PBA bridge errors
+//
+// This extends the common collection with PBA slave control/status
+// information.
+
+static void
+pba_bridge_ffdc(PbaBridgeFfdc* ffdc)
+{
+ int i;
+
+ if (ffdc->common.error == 0) {
+
+ pba_common_ffdc(&(ffdc->common));
+
+ ffdc->slvrst.value = in64(PBA_SLVRST);
+
+ for (i = 0; i > PBA_SLAVES; i++) {
+ ffdc->slvctl[i].value = in64(PBA_SLVCTLN(i));
+ }
+ }
+}
+
+
+// Collect FFDC for a particular Block Copy Engine
+//
+// The engine ID here is either 0 (BCDE) or 1 (BCUE)
+
+static void
+bce_ffdc(BceFfdc* ffdc, int engine)
+{
+ if (ffdc->common.error == 0) {
+
+ pba_common_ffdc(&(ffdc->common));
+
+ ffdc->ctl.value = in64(G_bce_ctl[engine]);
+ ffdc->set.value = in64(G_bce_set[engine]);
+ ffdc->pbadr.value = in64(G_bce_pbadr[engine]);
+ ffdc->stat.value = in64(G_bce_stat[engine]);
+ }
+}
+
+
+// Collect FFDC for PBAX send
+
+static void
+pbax_send_ffdc(PbaxSendFfdc* ffdc)
+{
+ if (ffdc->common.error == 0) {
+
+ pba_common_ffdc(&(ffdc->common));
+
+ ffdc->xcfg.value = in64(PBA_XCFG);
+ ffdc->xsndtx.value = in64(PBA_XSNDTX);
+ ffdc->xsndstat.value = in64(PBA_XSNDSTAT);
+ }
+}
+
+
+// Collect FFDC for PBAX receive
+//
+// The drivers currently do not distinguish errors between the two receive
+// queues as the hardware design does not provide a clean separation.
+
+static void
+pbax_receive_ffdc(PbaxReceiveFfdc* ffdc)
+{
+ int i;
+
+ if (ffdc->common.error == 0) {
+
+ pba_common_ffdc(&(ffdc->common));
+
+ ffdc->xcfg.value = in64(PBA_XCFG);
+ ffdc->xrcvstat.value = in64(PBA_XRCVSTAT);
+
+ for (i = 0; i < PBAX_ENGINES; i++) {
+ ffdc->xshbrn[i].value = in64(PBA_XSHBRN(i));
+ ffdc->xshcsn[i].value = in64(PBA_XSHCSN(i));
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// BceRequest
+////////////////////////////////////////////////////////////////////////////
+
+// Start a request running on a PBA Block Copy Engine
+//
+// \param queue A BceQueue upcast to an AsyncQueue
+//
+// \param request A BceRequest upcast to an AsyncRequest
+//
+// This routine takes a Bce objects cast to Async objects so that it can be
+// called from the generic Async interrupt handler.
+//
+// This is an internal API. This routine must be called from a context where
+// critical interrupts are disabled. Prior to this call, scheduling code will
+// have installed the new request as the \a current request of the queue, and
+// marked both the queue and the request as running.
+//
+// The PBA driver handles requests that require multiple runs of the PBA to
+// complete the request. Starting a PBA job requires setting up 3 registers,
+// hitting the "go" bit, and computing the amount of work remaining.
+//
+// Note that PBA will signal an error and lock up the system if the START bit
+// is written while a BC-engine is running.
+
+// Recall that the engines have identical control structures with identical
+// relative offsets between registers. So we use BCDE offsets and BCDE
+// register layout structures, but they work for BCUE as well.
+
+static int
+bce_async_run_method(AsyncRequest *async_request)
+{
+ BceQueue *queue = (BceQueue *)(async_request->queue);
+ BceRequest *request = (BceRequest *)async_request;
+ int rc, engine;
+ pba_bcde_pbadr_t pbadr;
+ pba_bcde_set_t set;
+ pba_bcde_ctl_t ctl;
+ size_t to_write;
+
+
+ if (request->remaining == 0) {
+
+ rc = -ASYNC_REQUEST_COMPLETE;
+
+ } else {
+
+ to_write = MIN(request->remaining, PBA_BCE_SIZE_MAX);
+
+ // Create the address offset register. The PowerBus offset is the
+ // cache-line address of the stored offset (ex the OCI region bits).
+
+ pbadr.value = 0;
+
+ pbadr.fields.pb_offset =
+ (request->next_bridge_address & 0x3FFFFFFF) /
+ POWERBUS_CACHE_LINE_SIZE;
+
+ pbadr.fields.extaddr =
+ request->extended_address.fields.extended_address;
+
+ // Create the setup register
+
+ set.value = 0;
+
+ set.fields.copy_length = to_write / POWERBUS_CACHE_LINE_SIZE;
+
+ // Set the START bit
+
+ ctl.value = PBA_BCDE_CTL_START;
+
+ // Start the BCE
+
+ engine = queue->engine;
+ out64(G_bce_pbadr[engine], pbadr.value);
+ out32(G_bce_ocibar[engine], request->next_oci_address);
+ out32(G_bce_set[engine], set.words.high_order);
+ out32(G_bce_ctl[engine], ctl.words.high_order);
+
+ // Update the work remaining to be done.
+
+ request->remaining -= to_write;
+ if (request->remaining != 0) {
+ request->next_bridge_address += to_write;
+ request->next_oci_address += to_write;
+ }
+
+ rc = 0;
+ }
+
+ return rc;
+}
+
+
+// The async error method for Block Copy Engines
+//
+// Collect FFDC and stop the engine. The return of -1 will disable the
+// channel associated with the request. The application will need to decide
+// whether to restart the queue.
+
+static int
+bce_async_error_method(AsyncRequest *request)
+{
+ BceQueue *queue = (BceQueue*)(request->queue);
+ int engine = queue->engine;
+
+ if (engine == BCE_ENGINE_BCDE) {
+
+ bce_ffdc(&(G_pba_ffdc.bcde), engine);
+ out32(PBA_BCDE_CTL, PBA_BCDE_CTL_STOP >> 32);
+
+ } else {
+
+ bce_ffdc(&(G_pba_ffdc.bcue), engine);
+ out32(PBA_BCUE_CTL, PBA_BCUE_CTL_STOP >> 32);
+
+ }
+
+ return -1;
+}
+
+
+/// Create a request for a PBA Block Copy engine
+///
+/// \param request An uninitialized or otherwise idle BceRequest.
+///
+/// \param queue An initialized BceQueue.
+///
+/// \param bridge_address The 32-bit bridge address that is translated to
+/// a PowerBus address associated with the copy. This address must be a
+/// PowerBus cache (128-byte) aligned address.
+///
+/// \param oci_address The 32-bit OCI address associated with the copy. This
+/// address must be 128-byte aligned.
+///
+/// \param bytes The number of bytes to move. This must be a multiple of 128,
+/// and the size must not obviously overflow the OCI address or the bridge
+/// address.
+///
+/// \param timeout If not specified as SSX_WAIT_FOREVER, then this request
+/// will be governed by a private watchdog timer that will cancel a queued job
+/// or kill a running job if the hardware operation does not complete before
+/// it times out.
+///
+/// \param callback The callback to execute when the PBA copy completes, or
+/// NULL (0) to indicate no callback.
+///
+/// \param arg The parameter to the callback routine; ignored if the \a
+/// callback is NULL.
+///
+/// \param options Options to control request priority and callback context.
+///
+/// Note that the setup for the BC engines includes an extended address and a
+/// PowerBus maximum priority. This API sets these to
+/// the default values in the request. If non-default values are required,
+/// they will need to be installed in the structure explicitly before
+/// scheduling.
+///
+/// This routine has no way to know if the BceRequest structure is currently
+/// in use, so this API should only be called on uninitialized or otherwise
+/// idle GpeRequest structures.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_BCE_REQUEST The \a request was NULL (0),
+/// or the \a queue was NULL (0) or not a BceQueue.
+///
+/// See async_request_create() for other errors that may be returned by this
+/// call.
+
+int
+bce_request_create(BceRequest *request,
+ BceQueue *queue,
+ uint32_t bridge_address,
+ uint32_t oci_address,
+ size_t bytes,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options)
+{
+ int rc;
+ AsyncQueue *async_queue = (AsyncQueue *)queue;
+
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((request == 0) ||
+ (queue == 0) ||
+ !(async_queue->engine & ASYNC_ENGINE_BCE),
+ ASYNC_INVALID_OBJECT_BCE_REQUEST);
+ }
+
+ rc = async_request_create(&(request->request),
+ async_queue,
+ bce_async_run_method,
+ bce_async_error_method,
+ timeout,
+ callback,
+ arg,
+ options);
+
+ request->bridge_address = bridge_address;
+ request->oci_address = oci_address;
+ request->bytes = bytes;
+ request->extended_address.value = 0;
+
+ return rc;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// BceQueue
+////////////////////////////////////////////////////////////////////////////
+
+/// Create (initialize) a BceQueue
+///
+/// \param queue An uninitialized of otherwise idle BceQueue
+///
+/// \param engine Either ASYNC_ENGINE_PBA_BCDE or ASYNC_ENGINE_PBA_BCUE
+///
+/// This API initializes the BceQueue structure based on the engine
+/// provided. There is really no special hardware initialization required as
+/// the BC-engines are pretty simple data movers.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_BCE_QUEUE The \a queue was NULL (0).
+///
+/// \retval -ASYNC_INVALID_ENGINE_BCE The \a engine is not a PBA engine.
+
+int
+bce_queue_create(BceQueue *queue,
+ int engine)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(queue == 0, ASYNC_INVALID_OBJECT_BCE_QUEUE);
+ }
+
+ switch (engine) {
+
+ case ASYNC_ENGINE_BCDE:
+ async_queue_create(&(queue->queue), engine);
+ queue->engine = BCE_ENGINE_BCDE;
+ break;
+
+ case ASYNC_ENGINE_BCUE:
+ async_queue_create(&(queue->queue), engine);
+ queue->engine = BCE_ENGINE_BCUE;
+ break;
+
+ default:
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR(ASYNC_INVALID_ENGINE_BCE);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+
+/// Schedule a request on a PBA block-copy engine
+///
+/// Note : As long as the BceRequest is idle, the application is free to
+/// directly change the \a bridge_address, \a oci_address and \a bytes fields to
+/// read/write different numbers of bytes to/from different locations the next
+/// time the request is scheduled.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_BCE_SCHEDULE Either the \a bridge_address
+/// is not 128-byte aligned, or the OCI address is not 128-byte aligned, or the
+/// number of bytes is not a multiple of 128.
+///
+/// See async_request_schedule() for documentation of other errors
+
+int
+bce_request_schedule(BceRequest *request)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((request->bridge_address % POWERBUS_CACHE_LINE_SIZE) ||
+ (request->oci_address % POWERBUS_CACHE_LINE_SIZE) ||
+ (request->bytes % POWERBUS_CACHE_LINE_SIZE),
+ ASYNC_INVALID_ARGUMENT_BCE_SCHEDULE);
+ }
+
+ request->next_bridge_address = request->bridge_address;
+ request->next_oci_address = request->oci_address;
+ request->remaining = request->bytes;
+
+ return async_request_schedule((AsyncRequest *)request);
+}
+
+
+// The interrupt handler for asynchronous PBA Block Copy requests
+//
+// BC-engine 'done' interrupts are level-sensitive active high, so they need
+// to be cleared in the PBA by writing a 0 to the CTL register. We also get
+// the PBA 'done' even when jobs are killed, but the cancel/kill code is
+// responsible for setting the \a completion_state of the request.
+//
+// We only go to the generic handler once all data has been transferred.
+
+SSX_IRQ_FAST2FULL(bce_async_handler, bce_async_handler_full);
+
+void
+bce_async_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ AsyncQueue *async_queue = (AsyncQueue *)arg;
+ AsyncRequest *async_current = (AsyncRequest *)async_queue->current;
+ BceQueue *queue = (BceQueue *)async_queue;
+
+ out32(G_bce_ctl[queue->engine], 0);
+
+ if (SSX_ERROR_CHECK_KERNEL && (async_current == 0)) {
+ SSX_PANIC(ASYNC_PHANTOM_INTERRUPT_BCE);
+ }
+
+ if (async_current->run_method(async_current) == -ASYNC_REQUEST_COMPLETE) {
+ async_handler(async_queue);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// PbaxRequest
+////////////////////////////////////////////////////////////////////////////
+
+/// Non-blocking read from a PBAX PUSH (read) queue
+///
+/// \param queue The target PbaxQueue
+///
+/// \param buf The caller's data buffer to receive the read data
+///
+/// \param bytes The maximum number of bytes to read. This value should be an
+/// even multiple of 8, as this API always reads multiples of 8 bytes.
+///
+/// \param read The number of bytes actually copied from the device buffer to
+/// the caller's buffer. This may be returned as any value from 0 to \a
+/// bytes in multiples of 8 bytes.
+///
+/// pbax_read() implements a non-blocking copy of data from a PBAX read (PUSH)
+/// queue data area to the caller's data area, with the side effect of
+/// advancing the hardware queue pointers. pbax_read() does not implement
+/// locking, critical sections or any other type of synchronization for access
+/// to the PBAX queue data.
+///
+/// pbax_read() returns the error code -ASYNC_PBAX_ERROR_OLD or
+/// -ASYNC_PBAX_ERROR_NEW if PBAX receive error status is asserted.
+/// The error return code may be disjoint from the actual
+/// read: If data is available it may be copied to the caller's buffer, but
+/// this data should always be considered corrupted in the event of an error
+/// return code.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_PBAX_READ The number of \a bytes is not
+/// an even multiple of 8.
+///
+/// \retval -ASYNC_PBAX_ERROR_OLD The PBA shows pre-existing error status
+///
+/// \retval -ASYNC_PBAX_ERROR_NEW The PBA shows current error status
+///
+/// \todo Once the HW design is finalized, we might consider modifying the
+/// error behavior to only return an error status if the receive error was
+/// associated with this particular queue.
+
+int
+pbax_read(PbaxQueue* queue, void* buf, size_t bytes, size_t* read)
+{
+ pba_xshcsn_t csr;
+ pba_xrcvstat_t rsr;
+ unsigned qlen, read_ptr, write_ptr, to_read;
+ uint64_t *pcq, *pbuf;
+ int rc;
+
+ do {
+
+ rc = 0;
+ *read = 0;
+
+ // If pre-existing errors exist then immediately abort the read.
+
+ rsr.words.high_order = in32(PBA_XRCVSTAT);
+ if (rsr.fields.rcv_error) {
+ pbax_receive_ffdc(&(G_pba_ffdc.pbax_receive));
+ rc = -ASYNC_PBAX_ERROR_OLD;
+ break;
+ }
+
+ if (bytes % 8) {
+ rc = -ASYNC_INVALID_ARGUMENT_PBAX_READ;
+ break;
+ }
+
+ // Determine the number of doubleword entries remaining to be read in
+ // the queue. The driver does not keep state, but instead reinterprets
+ // the control/status register each time the read method is called.
+
+ // This may be confusing - remember that 'push' is from the PowerBus
+ // perspective - here we use 'read' from OCC's perspective.
+
+ csr.words.high_order = in32(G_pba_xshcsn[queue->engine]);
+
+ qlen = csr.fields.push_length + 1;
+ read_ptr = csr.fields.push_read_ptr;
+
+ if (csr.fields.push_empty) {
+ break;
+
+ } else if (csr.fields.push_full) {
+ to_read = qlen;
+
+ } else {
+ write_ptr = csr.fields.push_write_ptr;
+ if (read_ptr > write_ptr) {
+ to_read = qlen - (read_ptr - write_ptr);
+ } else {
+ to_read = write_ptr - read_ptr;
+ }
+ }
+
+ // Copy the data from the CQ memory area. For simplicty of dealing with
+ // cache management each doubleword invokes a line invalidate before
+ // refetching the fresh data from memory. Alignment requirements enforced
+ // on the data buffer guarantee the buffers are cache-line aligned and
+ // each doubleword is fully contained in a single D-cache line.
+ //
+ // Here the code models the evolution of the read_ptr as each datum is
+ // copied from the queue.
+
+ pbuf = (uint64_t*) buf;
+ while (bytes && to_read--) {
+
+ read_ptr++;
+ if (read_ptr == qlen) {
+ read_ptr = 0;
+ }
+ pcq = queue->cq_base + read_ptr;
+
+ dcache_invalidate_line(pcq);
+ *pbuf++ = *pcq;
+ out32(G_pba_xshincn[queue->engine], 0);
+
+ bytes -= 8;
+ *read += 8;
+ }
+ } while(0);
+
+ // Check for errors that occurred during the read
+
+ rsr.words.high_order = in32(PBA_XRCVSTAT);
+ if (rsr.fields.rcv_error) {
+ pbax_receive_ffdc(&(G_pba_ffdc.pbax_receive));
+ rc = -ASYNC_PBAX_ERROR_NEW;
+ }
+
+ return rc;
+}
+
+
+// This is the internal 'run method' for reading through a PBAX circular
+// queue. The run method simply enables the IRQ. The interrupt handler reads
+// data from the queue and leaves the interrupt enabled until the read is
+// satisfied.
+
+int
+pbax_read_method(AsyncRequest *async_request)
+{
+ PbaxRequest *request = (PbaxRequest*)async_request;
+ PbaxQueue *queue = (PbaxQueue*)(async_request->queue);
+ int rc;
+
+ if (request->bytes == 0) {
+ rc = -ASYNC_REQUEST_COMPLETE;
+ } else {
+ ssx_irq_enable(queue->irq);
+ rc = 0;
+ }
+ return rc;
+}
+
+
+// The async error method for PBAX
+//
+// Collect FFDC.
+
+static int
+pbax_async_error_method(AsyncRequest *request)
+{
+ pbax_receive_ffdc(&(G_pba_ffdc.pbax_receive));
+ return -1;
+}
+
+
+/// Create a request for a PBAX read queue
+///
+/// \param request An uninitialized or otherwise idle PbaxRequest.
+///
+/// \param queue An async queue for a PBAX read buffer.
+///
+/// \param data A pointer to the data to where the data should be placed.
+///
+/// \param bytes The (maximum) number of bytes of data to move. The PBAX read
+/// queues always move multiples of 8 bytes, and the number of bytes must be a
+/// multiple of 8. Higher-level abstractions will have to take care of cases
+/// where the "actual" numbers of bytes are not multiples of 8.
+///
+/// \param timeout If not specified as SSX_WAIT_FOREVER, then this request
+/// will be governed by a private watchdog timer that will cancel a queued job
+/// or kill a running job if the hardware operation does not complete before
+/// it times out.
+///
+/// \param callback The callback to execute when the read completes, or
+/// NULL (0) to indicate no callback.
+///
+/// \param arg The parameter to the callback routine; ignored if the \a
+/// callback is NULL.
+///
+/// \param options Options to control request priority, callback context and
+/// blocking. See the documentation for the PbaxRequest object for information
+/// on the special ASYNC_NONBLOCKING_READ option.
+///
+/// This routine has no way to know if the PbaxRequest structure is currently
+/// in use, so this API should only be called on uninitialized or otherwise
+/// idle PbaxRequest structures.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_PBAX_REQUEST The \a request or \a queue
+/// were NULL (0), or the \a queue is not an initialized PbaxQueue.
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_PBAX_REQUEST The \a data pointer is
+/// NULL (0), or the number of bytes is not a multiple of 8.
+///
+/// See async_request_create() for other errors that may be returned by this
+/// call.
+
+int
+pbax_request_create(PbaxRequest* request,
+ PbaxQueue* queue,
+ uint64_t* data,
+ size_t bytes,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void* arg,
+ int options)
+{
+ int rc;
+ AsyncQueue* async_queue = (AsyncQueue*)queue;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((request == 0) ||
+ (queue == 0) ||
+ !(async_queue->engine & ASYNC_ENGINE_PBAX),
+ ASYNC_INVALID_OBJECT_PBAX_REQUEST);
+ SSX_ERROR_IF((data == 0) ||
+ (bytes % 8),
+ ASYNC_INVALID_ARGUMENT_PBAX_REQUEST);
+ }
+
+ rc = async_request_create(&(request->request),
+ async_queue,
+ pbax_read_method,
+ pbax_async_error_method,
+ timeout,
+ callback,
+ arg,
+ options);
+
+ request->data = data;
+ request->bytes = bytes;
+
+ return rc;
+}
+
+
+/// Schedule a request on a PBAX read queue
+///
+/// Note : As long as the PbaxRequest is idle, the application is free to
+/// directly change the \a data and \a bytes fields to read different numbers of
+/// bytes into different locations the next time the request is scheduled.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_PBAX_SCHEDULE The number of \a bytes
+/// currently requested is not a multiple of 8.
+///
+/// See async_request_schedule() for documentation of other errors
+
+int
+pbax_request_schedule(PbaxRequest *request)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((request->bytes % 8),ASYNC_INVALID_ARGUMENT_PBAX_SCHEDULE);
+ }
+
+ request->current = request->data;
+ request->remaining = request->bytes;
+
+ return async_request_schedule((AsyncRequest *)request);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// PbaxQueue
+////////////////////////////////////////////////////////////////////////////
+
+/// Disable a PBAX circular PUSH (read) queue
+///
+/// \param queue An initialized PbaxQueue object.
+///
+/// Disable the PBAX recieve mechanism for a particular PBAX receive queue.
+/// Interrupts are disabled, and any data managed by the queue is effectively
+/// lost.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_PBAX_DISABLE The \a queue is NULL (0)
+/// or otherwise invalid.
+
+int
+pbax_queue_disable(PbaxQueue *queue)
+{
+ pba_xshcsn_t cs;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(queue == 0, ASYNC_INVALID_OBJECT_PBAX_DISABLE);
+ }
+
+ ssx_irq_disable(queue->irq);
+
+ cs.value = 0;
+ out32(G_pba_xshcsn[queue->engine], cs.value);
+
+ return 0;
+}
+
+
+/// Enable a PBAX circular PUSH (read) queue
+///
+/// \param queue An initialized PbaxQueue object.
+///
+/// This API reprograms the queue hardware in accordance with the values
+/// present in the \a queue structure, and enables the queue to accept data.
+/// Any previous record of data present in the queue will be lost. The queue
+/// interrupt is also disabled by this API.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_PBAX_DISABLE The \a queue is NULL (0)
+/// or otherwise invalid.
+
+int
+pbax_queue_enable(PbaxQueue *queue)
+{
+ int rc;
+ pba_xshcsn_t cs;
+
+ rc = pbax_queue_disable(queue);
+
+ if (!rc) {
+
+ // Reinitialize the data buffer base address register and
+ // reprogram/re-enable the queue.
+
+ out32(G_pba_xshbrn[queue->engine], (uint32_t)(queue->cq_base));
+
+ cs.value = 0;
+
+ if (queue->protocol == PBAX_INTERRUPT_PROTOCOL_LAZY) {
+ cs.fields.push_intr_action = PBAX_INTR_ACTION_FULL;
+ } else {
+ cs.fields.push_intr_action = PBAX_INTR_ACTION_NOT_EMPTY;
+ }
+
+ cs.fields.push_length = queue->cq_entries - 1;
+ cs.fields.push_enable = 1;
+
+ out32(G_pba_xshcsn[queue->engine], cs.words.high_order);
+ }
+ return 0;
+}
+
+
+/// Create (initialize) a PbaxQueue abstraction
+///
+/// \param queue An uninitialized or otherwise idle PbaxQueue
+///
+/// \param engine A valid PBAX engine id
+///
+/// \param cq_base The base address of the circular queue data area for the
+/// queue. This address must be aligned to the next higher power-of-two of the
+/// buffer size, with a minimum alignment of a cache line.
+///
+/// \param cq_entries The number of 8-byte entries in the queue
+///
+/// \param protocol The interrupt protocol, either PBAX_PUSH_PROTOCOL_LAZY or
+/// PBAX_PUSH_PROTOCOL_AGGRESSIVE. Lazy means that read queues only interrupt
+/// when full, and agressive means that read queues interrupt whenever they
+/// are not empty. In general the lazy read protocol will only work for 1)
+/// queues of length 1, where lazy == aggressive, and 2) protocols where a
+/// known fixed number of 8-byte entries is always expected to be received.
+///
+/// This API simply creates the PbaxQueue abstraction in the software space;
+/// The API does not modify any harwdare state. To enable/disable the PBAX
+/// hardware read queue use pbax_queue_enable().
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_PBAX_QUEUE The \a queue was NULL (0).
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_PBAX_QUEUE The \a cq_base is not properly
+/// aligned, or the \a cq_length is invalid, or the \a protocol is invalid.
+///
+/// \retval -ASYNC_INVALID_ENGINE_PBAX The \a engine is not an PBAX engine.
+///
+/// Other errors may be returned by async_queue_create().
+
+int
+pbax_queue_create(PbaxQueue *queue,
+ int engine,
+ uint64_t *cq_base,
+ size_t cq_entries,
+ int protocol)
+{
+ AsyncQueue *async_queue = (AsyncQueue *)queue;
+
+ if (SSX_ERROR_CHECK_API) {
+ uint32_t align_mask =
+ POW2_32(MAX(CEILING_LOG2(cq_entries * 8),
+ LOG_CACHE_LINE_SIZE)) - 1;
+
+ SSX_ERROR_IF(queue == 0, ASYNC_INVALID_OBJECT_PBAX_QUEUE);
+ SSX_ERROR_IF((((uint32_t)(cq_base) & align_mask) != 0) ||
+ (cq_entries < PBAX_PUSH_LENGTH_MIN) ||
+ (cq_entries > PBAX_PUSH_LENGTH_MAX) ||
+ ((protocol != PBAX_INTERRUPT_PROTOCOL_LAZY) &&
+ (protocol != PBAX_INTERRUPT_PROTOCOL_AGGRESSIVE)),
+ ASYNC_INVALID_ARGUMENT_PBAX_QUEUE);
+ }
+
+ queue->cq_base = cq_base;
+ queue->cq_entries = cq_entries;
+ queue->protocol = protocol;
+
+ switch (engine) {
+
+ case ASYNC_ENGINE_PBAX_PUSH0:
+ queue->irq = PGP_IRQ_PBA_OCC_PUSH0;
+ queue->engine = PBAX_ENGINE_PUSH0;
+ break;
+
+ case ASYNC_ENGINE_PBAX_PUSH1:
+ queue->irq = PGP_IRQ_PBA_OCC_PUSH1;
+ queue->engine = PBAX_ENGINE_PUSH1;
+ break;
+
+ default:
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(1, ASYNC_INVALID_ENGINE_PBAX);
+ }
+ }
+
+ async_queue_create(async_queue, engine);
+
+ return 0;
+}
+
+
+// The interrupt handler for asynchronous PBAX requests
+//
+// The circular buffer interupts are level sensitive, active high. There is
+// really no way to 'clear' them as they indicate a permanent status - so
+// instead they need to be enabled and disabled. This is done by the read
+// method. (Note that one could make them edge-triggered, but in general
+// device drivers [including this one] would not work correctly if they were
+// programmed that way.)
+//
+// This interrupt handler can process up to 256 bytes at once, plus the
+// overhead of scheduling the next job when this one completes. If interrupt
+// latency becomes a problem then this process could be run with interrupt
+// preemption enabled.
+
+SSX_IRQ_FAST2FULL(pbax_async_handler, pbax_async_handler_full);
+
+void
+pbax_async_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ AsyncQueue* async_queue = (AsyncQueue*)arg;
+ PbaxQueue* queue = (PbaxQueue*)async_queue;
+ PbaxRequest* request = (PbaxRequest*)(async_queue->current);
+ size_t read;
+ int rc;
+
+ if (SSX_ERROR_CHECK_KERNEL && (request == 0)) {
+ SSX_PANIC(ASYNC_PHANTOM_INTERRUPT_PBAX);
+ }
+
+ rc = pbax_read(queue, request->current, request->remaining, &read);
+
+ if (rc) {
+
+ ssx_irq_disable(queue->irq);
+ async_error_handler(async_queue, ASYNC_REQUEST_STATE_FAILED);
+
+ } else if (read == request->remaining) {
+
+ ssx_irq_disable(queue->irq);
+ async_handler(async_queue);
+
+ } else {
+
+ request->current += (read / 8);
+ request->remaining -= read;
+ }
+}
+
+
+// The interrupt handler for the PBA error interrupt.
+//
+// There is one error interrupt that covers all PBA function - the generic
+// bridge, block copy engines and PBAX buffers. The PBA error pulses whenever
+// new error bits are logged in the PBA FIR, so it is possible for OCC to log
+// errors independently for the bridge, BCE and PBAX.
+//
+// When the PBA error interrupt fires we try to determine which unit is
+// responsible for the error and take appropriate action. The analysis is
+// currently not very deep, however it is not clear whether it is worth the
+// time and code space required to do more than this.
+//
+// - If the error appears to be associated with either a BCDE or BCUE job
+// running as part of the async mechanism then we let the
+// async_error_handler() mechanism operate. As a side effect the indicated
+// queue will be disabled. Note that further analysis (and storage space)
+// might allow jobs to be restarted on that engine, but this is currently not
+// done.
+//
+// - If the error appears to be associated with a PBAX send then the PBAX send
+// mechanism is already effectively disabled by the fact that the send status
+// register shows an error. FFDC is simply collected in this case.
+//
+// - If the error appears to be associated with a PBAX receive mechanism then
+// both receive queues are stopped. The receive may or may not be using the
+// job queues (the application may be polling using pbax_read()).
+//
+// If the error is due to the direct bridge we collect FFDC, but can't really
+// do anything else. Since OCC will not use the PBA bridge at run time
+// (except for lab-mode applications) this error is due either to a PORE
+// engine or FSP using the dedicated trusted channel to mainstore.
+//
+// This code is assumed to be activated as a critical interrupt.
+
+/// \todo What to do for generic PBA errors?
+
+SSX_IRQ_FAST2FULL(pba_error_handler, pba_error_handler_full);
+
+void
+pba_error_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ pba_fir_t fir;
+ pba_bcde_stat_t bcde_stat;
+ pba_bcue_stat_t bcue_stat;
+ pba_xsndstat_t xsndstat;
+ pba_xrcvstat_t xrcvstat;
+ int channel;
+ AsyncQueue* queue;
+
+ ssx_irq_status_clear(irq);
+
+ getscom(PBA_FIR, &(fir.value));
+ bcde_stat.words.high_order = in32(PBA_BCDE_STAT);
+ bcue_stat.words.high_order = in32(PBA_BCUE_STAT);
+ xsndstat.words.high_order = in32(PBA_XSNDSTAT);
+ xrcvstat.words.high_order = in32(PBA_XRCVSTAT);
+
+ queue = (AsyncQueue*)(&G_pba_bcde_queue);
+ if (bcde_stat.fields.error &&
+ (queue->state == ASYNC_QUEUE_STATE_RUNNING)) {
+ async_error_handler(queue, ASYNC_REQUEST_STATE_FAILED);
+ }
+
+ queue = (AsyncQueue*)(&G_pba_bcue_queue);
+ if (bcue_stat.fields.error &&
+ (queue->state == ASYNC_QUEUE_STATE_RUNNING)) {
+ async_error_handler(queue, ASYNC_REQUEST_STATE_FAILED);
+ }
+
+ if (xsndstat.fields.snd_error) {
+ pbax_send_ffdc(&G_pba_ffdc.pbax_send);
+ }
+
+ if (xrcvstat.fields.rcv_error) {
+ for (channel = 0; channel < PBAX_CHANNELS; channel++) {
+ queue = (AsyncQueue*)(&G_pbax_read_queue[channel]);
+ if (queue->state == ASYNC_REQUEST_STATE_RUNNING) {
+ async_error_handler(queue, ASYNC_REQUEST_STATE_FAILED);
+ } else {
+ pbax_receive_ffdc(&G_pba_ffdc.pbax_receive);
+ }
+ }
+ }
+
+ // Any FIR bits not already attributable to previously handled errors are
+ // assumed to be due to the generic bridge.
+
+ if (fir.value &
+ (
+ PBA_FIR_OCI_APAR_ERR ||
+ PBA_FIR_PB_RDADRERR_FW ||
+ PBA_FIR_PB_RDDATATO_FW ||
+ PBA_FIR_PB_SUE_FW ||
+ PBA_FIR_PB_UE_FW ||
+ PBA_FIR_PB_CE_FW ||
+ PBA_FIR_OCI_SLAVE_INIT ||
+ PBA_FIR_OCI_WRPAR_ERR ||
+ PBA_FIR_OCI_REREQTO ||
+ PBA_FIR_PB_UNEXPCRESP ||
+ PBA_FIR_PB_UNEXPDATA ||
+ PBA_FIR_PB_PARITY_ERR ||
+ PBA_FIR_PB_WRADRERR_FW ||
+ PBA_FIR_PB_BADCRESP ||
+ PBA_FIR_PB_ACKDEAD_FW ||
+ PBA_FIR_PB_CRESPTO ||
+ // PBA_FIR_BCUE_SETUP_ERR ||
+ // PBA_FIR_BCUE_PB_ACK_DEAD ||
+ // PBA_FIR_BCUE_PB_ADRERR ||
+ // PBA_FIR_BCUE_OCI_DATAERR ||
+ // PBA_FIR_BCDE_SETUP_ERR ||
+ // PBA_FIR_BCDE_PB_ACK_DEAD ||
+ // PBA_FIR_BCDE_PB_ADRERR ||
+ // PBA_FIR_BCDE_RDDATATO_ERR ||
+ // PBA_FIR_BCDE_SUE_ERR ||
+ // PBA_FIR_BCDE_UE_ERR ||
+ // PBA_FIR_BCDE_CE ||
+ // PBA_FIR_BCDE_OCI_DATAERR ||
+ PBA_FIR_INTERNAL_ERR ||
+ PBA_FIR_ILLEGAL_CACHE_OP ||
+ PBA_FIR_OCI_BAD_REG_ADDR ||
+ // PBA_FIR_AXPUSH_WRERR ||
+ // PBA_FIR_AXRCV_DLO_ERR ||
+ // PBA_FIR_AXRCV_DLO_TO ||
+ // PBA_FIR_AXRCV_RSVDATA_TO ||
+ // PBA_FIR_AXFLOW_ERR ||
+ // PBA_FIR_AXSND_DHI_RTYTO ||
+ // PBA_FIR_AXSND_DLO_RTYTO ||
+ // PBA_FIR_AXSND_RSVTO ||
+ // PBA_FIR_AXSND_RSVERR ||
+ PBA_FIR_FIR_PARITY_ERR ||
+ PBA_FIR_FIR_PARITY_ERR2
+ )
+ ) {
+
+ pba_bridge_ffdc(&(G_pba_ffdc.bridge));
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// Initialization
+////////////////////////////////////////////////////////////////////////////
+
+void
+async_bce_initialize(BceQueue *queue, int engine, SsxIrqId irq)
+{
+ bce_queue_create(queue, engine);
+ async_level_handler_setup(bce_async_handler,
+ (void *)queue,
+ irq,
+ SSX_CRITICAL,
+ SSX_IRQ_POLARITY_ACTIVE_HIGH);
+ ssx_irq_enable(irq);
+}
+
+
+void
+async_pbax_initialize(PbaxQueue *queue, int engine, SsxIrqId irq,
+ uint64_t *buffer, size_t length, int protocol)
+{
+ pbax_queue_create(queue, engine, buffer, length, protocol);
+ pbax_queue_enable(queue);
+ async_level_handler_setup(pbax_async_handler,
+ (void *)queue,
+ irq,
+ SSX_NONCRITICAL,
+ SSX_IRQ_POLARITY_ACTIVE_HIGH);
+ // Driver or application manages IRQ enable/disable
+}
+
+
diff --git a/src/ssx/pgp/pgp_async_pore.c b/src/ssx/pgp/pgp_async_pore.c
new file mode 100755
index 0000000..5f9b425
--- /dev/null
+++ b/src/ssx/pgp/pgp_async_pore.c
@@ -0,0 +1,644 @@
+// $Id: pgp_async_pore.c,v 1.5 2014/05/14 13:35:43 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_async_pore.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_async_pore.c
+/// \brief PgP "async" drivers for PORE engines
+
+#include "ssx.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Global Data
+////////////////////////////////////////////////////////////////////////////
+
+// The PORE queue objects.
+
+PoreQueue G_pore_gpe0_queue;
+PoreQueue G_pore_gpe1_queue;
+PoreQueue G_pore_slw_queue;
+
+
+////////////////////////////////////////////////////////////////////////////
+// Local Data
+////////////////////////////////////////////////////////////////////////////
+
+/// PoreFlex entry point - See G_pore_flex_table.
+
+static uint32_t G_pore_flex_entry0 = PORE_BRAD_D0;
+
+
+/// Entry 0 of the PoreFlex branch table
+///
+/// This variable is the only thing we represent of the branch table for PORE
+/// flex requests. PoreFlex requests are forbidden from using PORE error
+/// handlers. Therefore they don't require the 60 redundant bytes of error
+/// handler entry points. They also only run trigger slot 0, and begin
+/// execution with a BRAD D0, so the only thing we represent is a single BRAD
+/// D0 instruction.
+
+static uint32_t* G_pore_flex_table = &G_pore_flex_entry0 - (PORE_ERROR_SLOTS * 3);
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreQueue
+////////////////////////////////////////////////////////////////////////////
+
+/// Create (initialize) a PoreQueue
+///
+/// \param queue An uninitialized of otherwise idle PoreQueue
+///
+/// \param engine The identifier of a PORE engine associated with this queue.
+///
+/// This API initializes the PoreQueue structure and also initializes the
+/// underlying PORE hardware to run in the OCC environment. Neither the
+/// branch table nor the error modes are specified here - those are considered
+/// application-specific functions that are set up each time a job is run on
+/// the engine.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_PORE_QUEUE The \a queue was NULL (0).
+///
+/// \retval -ASYNC_INVALID_ENGINE_PORE The \a engine is not a (valid)
+/// PORE engine.
+
+int
+pore_queue_create(PoreQueue *queue, int engine)
+{
+ pore_control_t control;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(queue == 0, ASYNC_INVALID_OBJECT_PORE_QUEUE);
+ SSX_ERROR_IF(!(engine & ASYNC_ENGINE_PORE), ASYNC_INVALID_ENGINE_PORE);
+ }
+
+ async_queue_create(&(queue->queue), engine);
+
+ switch (engine) {
+
+ case ASYNC_ENGINE_PORE_GPE0:
+ queue->oci_base = PORE_GPE0_OCI_BASE;
+ queue->irq = PGP_IRQ_PORE_GPE0_COMPLETE;
+ queue->error_irq = PGP_IRQ_PORE_GPE0_ERROR;
+ queue->oci_master = OCI_MASTER_ID_PORE_GPE;
+ break;
+
+ case ASYNC_ENGINE_PORE_GPE1:
+ queue->oci_base = PORE_GPE1_OCI_BASE;
+ queue->irq = PGP_IRQ_PORE_GPE1_COMPLETE;
+ queue->error_irq = PGP_IRQ_PORE_GPE1_ERROR;
+ queue->oci_master = OCI_MASTER_ID_PORE_GPE;
+ break;
+
+ case ASYNC_ENGINE_PORE_SLW:
+ queue->oci_base = PORE_SLW_OCI_BASE;
+ queue->irq = PGP_IRQ_PORE_SW_COMPLETE;
+ queue->error_irq = PGP_IRQ_PORE_SW_ERROR;
+ queue->oci_master = OCI_MASTER_ID_PORE_SLW;
+ break;
+
+ default:
+ SSX_PANIC(ASYNC_BUG_PORE_AT_CREATE);
+ }
+
+ // PORE engine setup
+ //
+ // Force the PORE to stop and set it up for OCC control. Neither the
+ // breakpoint address nor the trap enable setting are modified in case
+ // they are being controlled from Simics or a hardware debugger ab initio.
+ //
+ // Register field settings:
+ //
+ // The scanclk ratio is not modified.
+ // The EXE-Trigger register is unlocked
+ // The freeze action is not modified
+ // Instruction parity is ignored
+ // The PIB parity checking setting is not modified
+ // The TRAP enable is not modified
+ // The breakpoint address is not modified
+
+ control.value = in64(queue->oci_base + PORE_CONTROL_OFFSET);
+
+ control.fields.start_stop = 1;
+ control.fields.lock_exe_trig= 0;
+ control.fields.check_parity = 0;
+
+ out64(queue->oci_base + PORE_CONTROL_OFFSET, control.value);
+
+ return 0;
+}
+
+
+// The interrupt handler for asynchronous PORE errors
+//
+// The PORE interrupts are disabled here, then cleared and re-enabled when the
+// next job runs. This is to protect against "phantom" interrupts caused by
+// PORE freeze-on-checkstop behavior.
+
+SSX_IRQ_FAST2FULL(pore_async_error_handler, pore_async_error_handler_full);
+
+void
+pore_async_error_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ PoreQueue* queue = (PoreQueue*)arg;
+
+ ssx_irq_disable(queue->irq);
+ ssx_irq_disable(queue->error_irq);
+
+ async_error_handler((AsyncQueue *)arg, ASYNC_REQUEST_STATE_FAILED);
+}
+
+
+// The interrupt handler for asynchronous PORE requests
+//
+// The PORE interrupts are disabled here, then cleared and re-enabled when the
+// next job runs. This is to protect against "phantom" interrupts caused by
+// PORE freeze-on-checkstop behavior.
+//
+// Note that if the system checkstops and freezes the PORE we will get a
+// normal completion interrupt. Therefore we have to check to see if the
+// completion is associated with a freeze, and if so, fail the job.
+
+SSX_IRQ_FAST2FULL(pore_async_handler, pore_async_handler_full);
+
+void
+pore_async_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ PoreQueue* queue = (PoreQueue*)arg;
+ pore_status_t status;
+
+ status.value = in64(queue->oci_base + PORE_STATUS_OFFSET);
+ if (status.fields.freeze_action) {
+
+ pore_async_error_handler_full(arg, irq, priority);
+
+ } else {
+
+ ssx_irq_disable(queue->irq);
+ ssx_irq_disable(queue->error_irq);
+
+ async_handler((AsyncQueue *)arg);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreRequest
+////////////////////////////////////////////////////////////////////////////
+
+/// Create (initialize) the PoreRequest base class
+///
+/// \param request An uninitialized or otherwise idle PoreRequest.
+///
+/// \param queue An initialized PoreQueue
+///
+/// \param table The PORE branch table to install prior to kicking off the
+/// engine. All PoreFlex jobs use a common (stubbed) table. PoreFixed jobs
+/// must supply a fully-formed table.
+///
+/// \param error_mask The initial value of the PORE ERROR_MASK register to be
+/// installed before kicking off the engine.
+///
+/// \param entry_point The entry point address of the routine. For PoreFlex
+/// this entry point will be non-0 and will be inserted into D0, as PoreFlex
+/// jobs are kicked off by BRAD D0. For PoreFixed this parameter will be zero
+/// and ignored.
+///
+/// \param start_vector The TBAR start vector to execute. This will always be
+/// 0 for PoreFlex.
+///
+/// \param parameter The single 32-bit parameter to the PORE program. This
+/// value is stored in the low-order part of the \c EXE_TRIGGER register
+/// prior to initiating the PORE program. (This part of the \c EXE_TRIGGER
+/// register is referred to as the 'Chiplet Select Mask' in PORE docs., as
+/// this is the hardware usage for hardware-initiated PORE-SLW routines.)
+///
+/// \param timeout If not specified as SSX_WAIT_FOREVER, then this request
+/// will be governed by a private watchdog timer that will cancel a queued job
+/// or kill a running job if the hardware operation does not complete before
+/// it times out.
+///
+/// \param callback The callback to execute when the PORE program completes,
+/// or NULL (0) to indicate no callback.
+///
+/// \param arg The parameter to the callback routine; ignored if the \a
+/// callback is NULL.
+///
+/// \param options Options to control request priority and callback context.
+///
+/// This routine has no way to know if the PoreRequest structure is currently
+/// in use, so this API should only be called on uninitialized or otherwise
+/// idle PoreRequest structures.
+///
+/// \retval 0 Success
+///
+/// \retval -ASYNC_INVALID_OBJECT_PORE_REQUEST The \a request was NULL (0)
+/// or the \a queue was NULL (0) or not a PoreQueue.
+///
+/// \retval -ASYNC_INVALID_ARGUMENT_PORE_REQUEST The \a start_vector is invalid or any of
+/// the parameters that represent OCI addresses are not 4-byte aligned, , or
+/// the \a table was null.
+///
+/// See async_request_create() for other errors that may be returned by this
+/// call.
+
+int
+pore_request_create(PoreRequest *request,
+ PoreQueue *queue,
+ PoreBraia* table,
+ uint32_t error_mask,
+ uint32_t entry_point,
+ int start_vector,
+ uint32_t parameter,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options)
+{
+ AsyncQueue *async_queue = (AsyncQueue *)queue;
+ int rc;
+ pore_exe_trigger_t etr;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(!(async_queue->engine & ASYNC_ENGINE_PORE),
+ ASYNC_INVALID_OBJECT_PORE_REQUEST);
+ SSX_ERROR_IF((start_vector < 0) ||
+ (start_vector >= PORE_TRIGGER_SLOTS) ||
+ ((uint32_t) table % 4) ||
+ (entry_point % 4) ||
+ (table == 0),
+ ASYNC_INVALID_ARGUMENT_PORE_REQUEST);
+ }
+
+ rc = async_request_create(&(request->request),
+ async_queue,
+ pore_run_method,
+ pore_error_method,
+ timeout,
+ callback,
+ arg,
+ options);
+
+ if (!rc) {
+ request->table = table;
+ request->error_mask = error_mask;
+ request->entry_point = entry_point;
+ request->parameter = parameter;
+ etr.value = 0;
+ etr.fields.start_vector = start_vector;
+ request->exe_trigger = etr.words.high_order;
+ }
+
+ return rc;
+}
+
+
+// Start a PoreRequest on a PORE
+//
+// \param async_request A PoreRequest upcast to an AsyncRequest.
+//
+// This is an internal API. At entry both the completion and error interrupts
+// are disabled and may show status that needs to be cleared before they are
+// re-enabled.
+//
+// This routine implements a simple procedure:
+//
+// - Check to make sure the PORE is not frozen due to a checkstop, and if so,
+// collect FFDC and immediately fail the job.
+//
+// Otherwise:
+//
+// - Reset the PORE engine to clear up any error status that may remain from
+// the last job .
+// - Install the TBAR (Table Base Address Register) from the request as an OCI
+// address
+// - Set the EMR (Error Mask Register) from the request
+// - Install the parameter (ETR[32:63])
+// - If the entry point is non-0 then this is a PoreFlex job that is kicked
+// off by a BRAD D0, and the entry point is installed in D0 as a full OCI
+// address.
+// - Clear pending interrupt status
+// - Hit ETR[0:31] to start the job.
+// - Enable interrupts.
+//
+// If the PORE is frozen due to a system checkstop we fail the job immediately
+// right here. Note that there is still a small window where the system may
+// checkstop and the PORE may freeze after this check. Unfortunately the PORE
+// design locks out register writes while frozen, and instead of reporting
+// write access attempts as bus errors, silently ignores them and simply sets
+// a FIR bit. Originally the "frozen" check was done last to shrink the
+// window, however this practically guarantees these FIRs in a checkstopped
+// system (which the FW team finds problematic), so the check was moved to the
+// front of the procedure. (SW256621).
+//
+// Note that PORE interrupts remain masked unless the job starts successfully.
+
+int
+pore_run_method(AsyncRequest *async_request)
+{
+ PoreQueue *queue = (PoreQueue*)(async_request->queue);
+ PoreRequest *request = (PoreRequest*)async_request;
+ pore_status_t status;
+ pore_reset_t reset;
+ uint32_t oci_base;
+ int rc;
+
+ oci_base = queue->oci_base;
+
+ status.value = in64(oci_base + PORE_STATUS_OFFSET);
+ if (status.fields.freeze_action) {
+
+ pore_error_method(async_request);
+ async_request->completion_state = ASYNC_REQUEST_STATE_FAILED;
+ rc = -ASYNC_REQUEST_COMPLETE;
+
+ } else {
+
+ reset.value = 0;
+ reset.fields.fn_reset = 1;
+ out32(oci_base + PORE_RESET_OFFSET, reset.value);
+
+ out32(oci_base + PORE_TABLE_BASE_ADDR_OFFSET, PORE_ADDRESS_SPACE_OCI);
+ out32(oci_base + PORE_TABLE_BASE_ADDR_OFFSET + 4,
+ (uint32_t)(request->table));
+ out32(oci_base + PORE_ERROR_MASK_OFFSET, request->error_mask);
+ out32(oci_base + PORE_EXE_TRIGGER_OFFSET + 4, request->parameter);
+
+ if (request->entry_point != 0) {
+ out32(oci_base + PORE_SCRATCH1_OFFSET, PORE_ADDRESS_SPACE_OCI);
+ out32(oci_base + PORE_SCRATCH1_OFFSET + 4, request->entry_point);
+ }
+
+ ssx_irq_status_clear(queue->irq);
+ ssx_irq_status_clear(queue->error_irq);
+
+ out32(oci_base + PORE_EXE_TRIGGER_OFFSET, request->exe_trigger);
+
+ ssx_irq_enable(queue->irq);
+ ssx_irq_enable(queue->error_irq);
+ rc = 0;
+ }
+
+ return rc;
+}
+
+
+// PORE FFDC collection
+//
+// \param async_request A PoreRequest upcast to an AsyncRequest
+//
+// This is an internal API, called from an interrupt context when a PORE
+// engine signals an error interrupt. See the comments for PoreFfdc for a
+// description of why this particular set of data is collected.
+//
+// PORE error handling procedure:
+//
+// - Collect FFDC from the PLB arbiter
+//
+// - Collect FFDC from the failing engine
+//
+// Currently all PORE errors are treated as recoverable
+
+/// \todo Consider analyzing the errors to determine if the error should be
+/// considered fatal.
+
+int
+pore_error_method(AsyncRequest *async_request)
+{
+ PoreQueue *queue = (PoreQueue*)(async_request->queue);
+ PoreRequest *request = (PoreRequest*)async_request;
+ uint32_t oci_base;
+ PoreFfdc* ffdc;
+
+ oci_base = queue->oci_base;
+ ffdc = &(request->ffdc);
+
+ oci_ffdc(&(ffdc->oci_ffdc), queue->oci_master);
+
+ ffdc->debug[0] = in64(oci_base + PORE_DBG0_OFFSET);
+ ffdc->debug[1] = in64(oci_base + PORE_DBG1_OFFSET);
+ ffdc->address[0] = in32(oci_base + PORE_OCI_BASE_ADDRESS0_OFFSET + 4);
+ ffdc->address[1] = in32(oci_base + PORE_OCI_BASE_ADDRESS1_OFFSET + 4);
+ ffdc->ibuf[0] = in32(oci_base + PORE_IBUF_01_OFFSET);
+ ffdc->ibuf[1] = in32(oci_base + PORE_IBUF_01_OFFSET + 4);
+ ffdc->ibuf[2] = in32(oci_base + PORE_IBUF_2_OFFSET);
+
+ return 0;
+}
+
+
+/// Create (initialize) a PoreBraia branch table entry
+///
+/// \param instr A pointer to the BRAIA instruction to initialize. Use the
+/// macros PORE_ERROR_BRANCH(table, n) and PORE_ENTRY_BRANCH(table, n) to
+/// select one of 5 error branches or one of 16 entry point branches in a PORE
+/// branch table.
+///
+/// \param address The 32-bit OCI address of the error routine or entry point.
+///
+/// This routine initializes the given entry of a PORE branch table with an
+/// OCI-based BRAIA instruction, them flushes the entry from the D-Cache.
+
+// Note that we don't know the alignment of the jump table, so we need to
+// flush both the first and last jump address to ensure that the BRAI is
+// completely flushed. This assumes (correctly) that uint32_t are at least
+// 4-byte aligned.
+
+void
+pore_braia_create(PoreBraia* instr, uint32_t address) {
+ instr->word[0] = PORE_BRAI;
+ instr->word[1] = PORE_ADDRESS_SPACE_OCI;
+ instr->word[2] = address;
+ dcache_flush_line(&(instr->word[0]));
+ dcache_flush_line(&(instr->word[2]));
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreFlex
+////////////////////////////////////////////////////////////////////////////
+
+/// Create (initialize) a flex-mode PORE request
+///
+/// \param request An uninitialized or otherwise idle PoreFlex.
+///
+/// \param queue A pointer to a PoreQueue
+///
+/// \param entry_point The entry point of the PORE program. This must be a
+/// 32-bit, 4-byte aligned byte address in OCI space. The PoreEntryPoint
+/// typedef is provided to declare external PORE entry points. Note that an \a
+/// entry_point of 0 is considered an error - although it \e is conceivably a
+/// legal OCI address in mainstore via the PBA.
+///
+/// \param timeout If not specified as SSX_WAIT_FOREVER, then this request
+/// will be governed by a private watchdog timer that will cancel a queued job
+/// or kill a running job if the hardware operation does not complete before
+/// it times out.
+///
+/// \param parameter The single 32-bit parameter to the PORE program. This
+/// value is stored in the high-order part of the \c EXE_TRIGGER register
+/// prior to initiating the PORE program. (This part of the \c EXE_TRIGGER
+/// register is referred to as the 'Chiplet Select Mask' in PORE docs., as
+/// this is the hardware usage for hardware-initiated PORE-SLW routines.)
+///
+/// \param callback The callback to execute when the PORE program completes,
+/// or NULL (0) to indicate no callback.
+///
+/// \param arg The parameter to the callback routine; ignored if the \a
+/// callback is NULL.
+///
+/// \param options Options to control request priority and callback context.
+///
+/// This routine has no way to know if the PoreFlex structure is currently
+/// in use, so this API should only be called on uninitialized or
+/// otherwise idle PoreFlex structures.
+///
+/// \retval 0 Success
+///
+/// See pore_request_create() for error return codes that may be returned by
+/// this call.
+
+int
+pore_flex_create(PoreFlex *request,
+ PoreQueue *queue,
+ PoreEntryPoint entry_point,
+ uint32_t parameter,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options)
+{
+ uint32_t emr;
+
+ // PoreFlex jobs run w/o error handlers, and ignore sleeping cores. All
+ // errors are signalled on both error outputs of all PORE engines.
+
+ emr = (PORE_ERROR_MASK_ENABLE_ERR_OUTPUT0 |
+ PORE_ERROR_MASK_ENABLE_ERR_OUTPUT1 |
+ PORE_ERROR_MASK_ENABLE_ERR_OUTPUT2 |
+ PORE_ERROR_MASK_ENABLE_ERR_OUTPUT3 |
+ PORE_ERROR_MASK_ENABLE_ERR_OUTPUT4 |
+ PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT0 |
+ PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT1 |
+ PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT2 |
+ PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT3 |
+ PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT4 |
+ PORE_ERROR_MASK_STOP_EXE_ON_ERROR0 |
+ PORE_ERROR_MASK_STOP_EXE_ON_ERROR1 |
+ PORE_ERROR_MASK_STOP_EXE_ON_ERROR2 |
+ PORE_ERROR_MASK_STOP_EXE_ON_ERROR3 |
+ PORE_ERROR_MASK_STOP_EXE_ON_ERROR4) >> 32;
+
+ return pore_request_create((PoreRequest*)request,
+ queue,
+ (PoreBraia*)G_pore_flex_table,
+ emr,
+ (uint32_t)entry_point,
+ 0,
+ parameter,
+ timeout,
+ callback,
+ arg,
+ options);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// PoreFixed
+////////////////////////////////////////////////////////////////////////////
+
+/// Create (initialize) a fixed-mode PORE request
+///
+/// \param request An uninitialized or otherwise idle PoreFixed request.
+///
+/// \param queue A PoreQueue capable of running fixed requests.
+///
+/// \param table A PORE branch table containing all of the error handler and
+/// entry point assignments required for the request.
+///
+/// \param error_mask A value that will be loaded into the high-order 32-bits
+/// of the PORE Error Mask Register to control error behavior.
+///
+/// \param start_vector The branch table slot reserved for this request.
+///
+/// \param parameter The single 32-bit parameter to the PORE program. This
+/// value is stored in the high-order part of the \c EXE_TRIGGER register
+/// prior to initiating the PORE program. (This part of the \c EXE_TRIGGER
+/// register is referred to as the 'Chiplet Select Mask' in PORE docs., as
+/// this is the hardware usage for hardware-initiated PORE-SLW routines.)
+///
+/// \param timeout If not specified as SSX_WAIT_FOREVER, then this request
+/// will be governed by a private watchdog timer that will cancel a queued job
+/// or kill a running job if the hardware operation does not complete before
+/// it times out.
+///
+/// \param callback The callback to execute when the PORE program completes,
+/// or NULL (0) to indicate no callback.
+///
+/// \param arg The parameter to the callback routine; ignored if the \a
+/// callback is NULL.
+///
+/// \param options Options to control request priority and callback context.
+///
+/// This routine has no way to know if the PoreFixed structure is currently
+/// in use, so this API should only be called on uninitialized or
+/// otherwise idle PoreFlex structures.
+///
+/// \retval 0 Success
+///
+/// See pore_request_create() for error return codes that may be returned by
+/// this call.
+
+int
+pore_fixed_create(PoreFixed *request,
+ PoreQueue *queue,
+ PoreBraia* table,
+ uint32_t error_mask,
+ int start_vector,
+ uint32_t parameter,
+ SsxInterval timeout,
+ AsyncRequestCallback callback,
+ void *arg,
+ int options)
+{
+ return pore_request_create((PoreRequest*)request,
+ queue,
+ table,
+ error_mask,
+ 0,
+ start_vector,
+ parameter,
+ timeout,
+ callback,
+ arg,
+ options);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// Initialization
+////////////////////////////////////////////////////////////////////////////
+
+// Due to the fact that PORE signals a "complete" interrupt on a freeze event
+// (i.e., a checkstop, even if PORE is not running), we can not enable PORE
+// interrupts globally. They need to be carefully managed to avoid "phantom
+// interrupt" panics from async_handler().
+
+void
+async_pore_initialize(PoreQueue *queue,int engine)
+{
+ pore_queue_create(queue, engine);
+ async_edge_handler_setup(pore_async_handler,
+ (void *)queue,
+ queue->irq, SSX_CRITICAL);
+ async_edge_handler_setup(pore_async_error_handler,
+ (void *)queue,
+ queue->error_irq, SSX_CRITICAL);
+}
+
+
+
diff --git a/src/ssx/pgp/pgp_cache.S b/src/ssx/pgp/pgp_cache.S
new file mode 100755
index 0000000..4208f59
--- /dev/null
+++ b/src/ssx/pgp/pgp_cache.S
@@ -0,0 +1,99 @@
+// $Id: pgp_cache.S,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_cache.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_cache.S
+/// \brief Cache-management specific to PGP
+
+#include "ssx.h"
+
+/// \fn void dcache_flush_all()
+/// \brief Flush the entire D-Cache by 0-filling and invalidating
+///
+/// This API is necessary whenever it is required to change data cacheability
+/// after boot. This API operates in an SSX_SUPERCRITICAL critical section.
+/// This API always issues a sync() after the flush.
+///
+/// This API runs with data translation disabled. This is necessary for
+/// correctness, and also obviates the need to check whether a cache entry is
+/// valid before flushing the entry.
+///
+/// This algorithm works by filling the cache with 0s to displace any dirty
+/// lines. Then the cache is invalidated. In PgP the first 16 KB of the
+/// 0x80000000 address range are used as the zero-fill range. This memory is
+/// not mapped on the OCI so these lines must never escape the D-cache.
+///
+/// Note: Our Simics model includes this 16K memory area since Simics does not
+/// default to having a cache. Since we run PgP with the MMU enabled and we
+/// don't MMU-map this area, memory addressing bugs should not be able to slip
+/// through.
+#ifdef DOXYGEN_ONLY
+void dcache_flush_all();
+#endif
+/// \cond
+
+ .global_function dcache_flush_all
+dcache_flush_all:
+
+ ## %r3 used as scratch throughout
+
+ ## %r11 holds the original DCCR throughout
+ ## %r12 holds the original MSR throughout
+
+ ## Enter a super-critical section and go to real mode
+
+ _ssx_critical_section_enter SSX_SUPERCRITICAL, %r12, %r3
+
+ mfmsr %r3
+ _clrbit %r3, %r3, MSR_DR_BIT
+ mtmsr %r3
+ isync
+
+ ## Save the DCCR, and make 0x80000000 cacheable. This is necessary for
+ ## DCBZ to work.
+
+ mfdccr %r11
+ _liwa %r3, PGP_FLUSH_ZERO_DCCR
+ or %r3, %r3, %r11
+ mtdccr %r3
+ isync
+
+ ## Fill the cache with 0, displacing any dirty lines
+
+ li %r3, DCACHE_LINES
+ mtctr %r3
+ _liwa %r3, PGP_FLUSH_ZERO_ADDRESS
+1:
+ dcbz %r0, %r3
+ addi %r3, %r3, CACHE_LINE_SIZE
+ bdnz 1b
+
+ sync
+
+ ## Now invalidate the cache
+
+ li %r3, DCACHE_LINES
+ mtctr %r3
+ _liwa %r3, PGP_FLUSH_ZERO_ADDRESS
+1:
+ dcbi %r0, %r3
+ addi %r3, %r3, CACHE_LINE_SIZE
+ bdnz 1b
+
+ ## Restore the DCCR and MSR and return
+
+ mtdccr %r11
+ isync
+
+ _ssx_critical_section_exit %r12
+
+ blr
+
+ .epilogue dcache_flush_all
+
+/// \endcond
+
diff --git a/src/ssx/pgp/pgp_centaur.c b/src/ssx/pgp/pgp_centaur.c
new file mode 100644
index 0000000..a47600a
--- /dev/null
+++ b/src/ssx/pgp/pgp_centaur.c
@@ -0,0 +1,597 @@
+// $Id: pgp_centaur.c,v 1.2 2013/12/13 23:01:15 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_centaur.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_centaur.c
+/// \brief Support for Centaur access and configuration from OCC.
+///
+/// Generic PBA generated PowerBus Address in pictures and words:
+///
+/// \code
+///
+/// 1 2 3 4 5 6
+/// 0123456789012345678901234567890123456789012345678901234567890123
+/// | | | | | | | | | | | | | | |
+///
+/// ..............B-------BX------------XO-----OA------------------A
+///
+/// .: Unused
+/// B: Direct from PBA BAR, bits 14:22
+/// X: If PBA BAR MASK 23:36 == 0, then PBA BAR 23:36
+/// Else Extended Address 0:13
+/// O: If PBA BAR MASK 37:43 == 0, then PBA BAR 37:43
+/// Else OCI Address 5:11
+/// A: OCI Address 12:31
+///
+/// \endcode
+///
+/// The OCI address always selects the low-order 20 bits of the PowerBus
+/// address, i.e., the window size is always a multiple of 1MB. The PBA BAR
+/// mask allows up to a 128MB window into main memory without using the
+/// extended address. The extended address allows OCC to address up to 2^41
+/// bytes by manipulating the extended address, assuming PHYP sets up the mask
+/// correctly.
+///
+///
+/// Centaur in-band SCOM, sensor cache and SYNC addressing in pictures and words:
+///
+/// \code
+///
+/// 1 2 3 4 5 6
+/// 0123456789012345678901234567890123456789012345678901234567890123
+/// | | | | | | | | | | | | | | |
+///
+/// ..............B-------BX------------XO-----OA------------------A - See Above
+/// ..............M-----------M10S------------------------------S000 - SCOM
+/// ..............M-----------M1100000000000000000000000000000000000 - Sensor cache
+/// ..............M-----------M1110000000000000000000000000000000000 - Sync
+///
+/// .: Unused
+/// M: The base address of the Centaur, taken from the MCS MCFGPR.
+/// O: 1 Signifies that this access comes from the OCC.
+/// S: The 32-bit SCOM address
+/// 0: Zero
+///
+/// \endcode
+///
+/// In order to access the Centaur for in-band SCOM, the PBA BAR MASK must
+/// extend at least from bit 29 down to bit 43, in order to allow the OCC to
+/// generate these addresses. In practice the mask must allow all configured
+/// Centaur to be accessed. This means that all Centaur in-band address bits
+/// not controllable by OCC through the mask must be equal.
+///
+/// Note that the SCOM address must be split between the extended address and
+/// the OCI address.
+///
+/// We assume (and verify) that MCMODE0(36) will always be set which means
+/// that bit 27 is a flag indicating whether an access comes from FSP or
+/// OCC. All OCC (GPE) accesses set this flag to 1.
+
+#include "ssx.h"
+#include "gpe_scom.h"
+
+#if defined(VERIFICATION) || defined(LAB_VALIDATION)
+#define PRINTD(...) printk(__VA_ARGS__)
+#else
+#define PRINTD(...)
+#endif
+
+CentaurConfiguration G_centaurConfiguration
+SECTION_ATTRIBUTE(".noncacheable_ro") = {.configRc = CENTAUR_NOT_CONFIGURED};
+
+const uint16_t _pgp_mcs_offset[PGP_NMCS] = {
+ 0x0800, 0x0880, 0x0900, 0x0980, 0x0c00, 0x0c80, 0x0d00, 0x0d80
+};
+
+
+// All GpeScomParms structures are required to be noncacheable, so we have to
+// allocate a static instance rather than using the stack. For simplicity the
+// single-entry scomList_t required to collect the Centaur device IDs is
+// allocated statically as well.
+
+static GpeScomParms S_parms SECTION_ATTRIBUTE(".noncacheable") = {0};
+static scomList_t S_scomList SECTION_ATTRIBUTE(".noncacheable") = {{{0}}};
+
+int
+_centaur_configuration_create(int i_bar, int i_slave, int i_setup)
+{
+ CentaurConfiguration config;
+ int i, designatedSync, diffInit;
+ int64_t rc; /* Must be copied to global struct. */
+ mcfgpr_t mcfgpr;
+ mcsmode0_t mcsmode0;
+ pba_slvctln_t slvctl;
+ uint64_t diffMask, addrAccum, bar, mask, base;
+ PoreFlex request;
+
+ // Start by clearing the local structure and setting the error flag.
+ memset(&config, 0, sizeof(config));
+ config.configRc = CENTAUR_NOT_CONFIGURED;
+
+ designatedSync = -1;
+
+ do {
+ // Basic consistency checks
+
+ if ((i_bar < 0) || (i_bar >= PBA_BARS) ||
+ (i_slave < 0) || (i_slave >= PBA_SLAVES)) {
+
+ rc = CENTAUR_INVALID_ARGUMENT;
+ break;
+ }
+
+
+ // Create the setups for the GPE procedures. The 'dataParms' are the
+ // setup for accessing the Centaur sensor cache. The 'scomParms' are
+ // the setup for accessing Centaur SCOMs.
+
+ rc = gpe_pba_parms_create(&(config.dataParms),
+ PBA_SLAVE_PORE_GPE,
+ PBA_WRITE_TTYPE_CI_PR_W,
+ PBA_WRITE_TTYPE_DC,
+ PBA_READ_TTYPE_CL_RD_NC);
+ if (rc) {
+ rc = CENTAUR_DATA_SETUP_ERROR;
+ break;
+ }
+
+ rc = gpe_pba_parms_create(&(config.scomParms),
+ PBA_SLAVE_PORE_GPE,
+ PBA_WRITE_TTYPE_CI_PR_W,
+ PBA_WRITE_TTYPE_DC,
+ PBA_READ_TTYPE_CI_PR_RD);
+ if (rc) {
+ rc = CENTAUR_SCOM_SETUP_ERROR;
+ break;
+ }
+
+
+ // Go into each MCS on the chip, and for all enabled MCS get a couple
+ // of SCOMs and check configuration items for correctness. If any of
+ // the Centaur are configured, exactly one of the MCS must be
+ // designated to receive the SYNC commands.
+
+ // Note that the code uniformly treats SCOM failures of the MCFGPR
+ // registers as an unconfigured Centaur. This works both for Murano,
+ // which only defines the final 4 MCS, as well as for our VBU models
+ // where some of the "valid" MCS are not in the simulation models.
+
+ for (i = 0; i < PGP_NCENTAUR; i++) {
+
+ rc = _getscom(MCS_ADDRESS(MCFGPR, i), &(mcfgpr.value),
+ SCOM_TIMEOUT);
+ if (rc) {
+ rc = 0;
+ config.baseAddress[i] = 0;
+ continue;
+ }
+
+ if (!mcfgpr.fields.mcfgprq_valid) continue;
+
+ rc = _getscom(MCS_ADDRESS(MCSMODE0, i), &(mcsmode0.value),
+ SCOM_TIMEOUT);
+ if (rc) {
+ PRINTD("Unexpected rc = 0x%08x SCOMing MCSMODE0(%d)\n",
+ (uint32_t)rc, i);
+ rc = CENTAUR_MCSMODE0_SCOM_FAILURE;
+ break;
+ }
+
+
+ // We require that the MCFGRP_19_IS_HO_BIT be set in the mode
+ // register. We do not support the option of this bit not being
+ // set, and all of our procedures will set bit 19 of the PowerBus
+ // address to indicate that OCC is making the access.
+
+ if (!mcsmode0.fields.mcfgrp_19_is_ho_bit) {
+
+ PRINTD("MCSMODE0(%d).mcfgrp_19_is_ho_bit == 0\n", i);
+ rc = CENTAUR_MCSMODE0_19_FAILURE;
+ break;
+ }
+
+
+ // The 14-bit base-address is moved to begin at bit 14 in the
+ // 64-bit PowerBus address. The low-order bit of this address (bit
+ // 19 mentioned above which is bit 27 as an address bit) must be 0
+ // - otherwise there is confusion over who's controlling this
+ // bit.
+
+ config.baseAddress[i] =
+ ((uint64_t)(mcfgpr.fields.mcfgprq_base_address)) <<
+ (64 - 14 - 14);
+
+ if (config.baseAddress[i] & 0x0000001000000000ull) {
+
+ PRINTD("Centaur base address %d has bit 27 set\n", i);
+ rc = CENTAUR_ADDRESS_27_FAILURE;
+ break;
+ }
+
+
+ // If this MCS is configured to be the designated SYNC unit, it
+ // must be the only one.
+
+ if (mcsmode0.fields.enable_centaur_sync) {
+
+ if (designatedSync > 0) {
+
+ PRINTD("Both MCS %d and %d are designated "
+ "for Centaur Sync\n",
+ designatedSync, i);
+ rc = CENTAUR_MULTIPLE_DESIGNATED_SYNC;
+ break;
+
+ } else {
+
+ designatedSync = i;
+ }
+ }
+
+
+ // Add the Centaur to the configuration
+
+ config.config |= (CHIP_CONFIG_MCS(i) | CHIP_CONFIG_CENTAUR(i));
+ }
+
+ if (rc) break;
+
+
+ // If Centaur are configured, make sure at least one of the MCS will
+ // handle the SYNC. If so, convert its base address into an address
+ // for issuing SYNC commands by setting bits 27 (OCC) 28 and 29
+ // (Sync), then insert this address into the extended address field of
+ // a PBA slave control register image. gsc_scom_centaur() then merges
+ // this extended address into the PBA slave control register (which
+ // has been set up for Centaur SCOM) to do the SYNC.
+
+ // In the override mode (i_setup > 1) we tag the first valid MCS
+ // to recieve the sync if the firmware has not set it up correctly.
+
+ if (config.config) {
+
+ if (designatedSync < 0) {
+
+ if (i_setup <= 1) {
+
+ PRINTD("No MCS is designated for Centaur SYNC\n");
+ rc = CENTAUR_NO_DESIGNATED_SYNC;
+ break;
+
+ } else {
+
+ designatedSync =
+ cntlz32(left_justify_mcs_config(config.config));
+
+ rc = _getscom(MCS_ADDRESS(MCSMODE0, designatedSync),
+ &(mcsmode0.value),
+ SCOM_TIMEOUT);
+ if (rc) {
+ PRINTD("Unexpected rc = 0x%08x SCOMing MCSMODE0(%d)\n",
+ (uint32_t)rc, designatedSync);
+ rc = CENTAUR_MCSMODE0_SCOM_FAILURE;
+ break;
+ }
+
+ mcsmode0.fields.enable_centaur_sync = 1;
+
+ rc = _putscom(MCS_ADDRESS(MCSMODE0, designatedSync),
+ mcsmode0.value,
+ SCOM_TIMEOUT);
+ if (rc) {
+ PRINTD("Unexpected rc = 0x%08x SCOMing MCSMODE0(%d)\n",
+ (uint32_t)rc, designatedSync);
+ rc = CENTAUR_MCSMODE0_SCOM_FAILURE;
+ break;
+ }
+ }
+ }
+
+ base = config.baseAddress[designatedSync] | 0x0000001c00000000ull;
+
+ slvctl.value = 0;
+ slvctl.fields.extaddr = (base & 0x000001fff8000000ull) >> 27;
+
+ config.syncSlaveControl = slvctl.value;
+ }
+
+
+ // At this point we have one or more enabled MCS and they pass the
+ // initial configuration sniff test. We can now implement the option
+ // to configure the PBA BAR and BAR MASK correctly to allow access to
+ // these Centaur. We do this by computing the minimum BAR mask that
+ // covers all of the Centaur base addresses. This is done by
+ // accumulating a difference mask of the base addresses and finding
+ // the first set bit in the mask.
+ //
+ // Note that we do the configuration here on demand, but always do the
+ // correctness checking as the next step.
+
+ if (i_setup && (config.config != 0)) {
+
+ diffInit = 0;
+ diffMask = 0; /* GCC happiness */
+ addrAccum = 0; /* GCC happiness */
+
+ for (i = 0; i < PGP_NCENTAUR; i++) {
+
+ if (config.baseAddress[i] != 0) {
+
+ if (!diffInit) {
+
+ diffInit = 1;
+ diffMask = 0;
+ addrAccum = config.baseAddress[i];
+
+ } else {
+
+ diffMask |=
+ (config.baseAddress[i] ^ addrAccum);
+ addrAccum |= config.baseAddress[i];
+ }
+
+ if (0) {
+
+ // Debug
+
+ printk("i:%d baseAddress: 0x%016llx "
+ "diffMask: 0x%016llx, addrAccum: 0x%016llx\n",
+ i, config.baseAddress[i], diffMask, addrAccum);
+ }
+ }
+ }
+
+ // The mask must cover all differences - and must also have at
+ // least bit 27 set. The mask register contains only the mask. The
+ // BAR is set to the accumulated address outside of the mask. The
+ // BAR also contains a scope field which defaults to 0 (Nodal
+ // Scope) for Centaur inband access.
+
+ diffMask |= 0x0000001000000000ull;
+ mask =
+ ((1ull << (64 - cntlz64(diffMask))) - 1) &
+ PBA_BARMSKN_MASK_MASK;
+
+ rc = _putscom(PBA_BARMSKN(i_bar), mask, SCOM_TIMEOUT);
+ if (rc) {
+ PRINTD("Unexpected rc = 0x%08x SCOMing PBA_BARMSKN(%d)\n",
+ (uint32_t)rc, i_bar);
+ rc = CENTAUR_BARMSKN_PUTSCOM_FAILURE;
+ break;
+ }
+
+ rc = _putscom(PBA_BARN(i_bar), addrAccum & ~mask, SCOM_TIMEOUT);
+ if (rc) {
+ PRINTD("Unexpected rc = 0x%08x SCOMing PBA_BARN(%d)\n",
+ (uint32_t)rc, i_bar);
+ rc = CENTAUR_BARN_PUTSCOM_FAILURE;
+ break;
+ }
+ }
+
+
+ // Do an independent check that every Centaur base address
+ // can be generated by the combination of the current BAR and
+ // BAR Mask, along with the initial requirement that the mask must
+ // include at least bits 27:43.
+
+ if (config.config != 0) {
+
+ rc = _getscom(PBA_BARN(i_bar), &bar, SCOM_TIMEOUT);
+ if (rc) {
+ PRINTD("Unexpected rc = 0x%08x SCOMing PBA_BARN(%d)\n",
+ (uint32_t)rc, i_bar);
+ rc = CENTAUR_BARN_GETSCOM_FAILURE;
+ break;
+ }
+
+ rc = _getscom(PBA_BARMSKN(i_bar), &mask, SCOM_TIMEOUT);
+
+ if (rc) {
+ PRINTD("Unexpected rc = 0x%08x SCOMing PBA_BARMSKN(%d)\n",
+ (uint32_t)rc, i_bar);
+ rc = CENTAUR_BARMSKN_GETSCOM_FAILURE;
+ break;
+ }
+
+ bar = bar & PBA_BARN_ADDR_MASK;
+ mask = mask & PBA_BARMSKN_MASK_MASK;
+
+ if ((mask & 0x0000001ffff00000ull) != 0x0000001ffff00000ull) {
+
+ PRINTD("PBA BAR mask (%d) does not cover bits 27:43\n", i_bar);
+ rc = CENTAUR_MASK_ERROR;
+ break;
+ }
+
+ for (i = 0; i < PGP_NCENTAUR; i++) {
+
+ if (config.baseAddress[i] != 0) {
+
+ if ((config.baseAddress[i] & ~mask) !=
+ (bar & ~mask)) {
+
+ PRINTD("BAR/Mask (%d) error for MCS/Centaur %d\n"
+ " base = 0x%016llx\n"
+ " bar = 0x%016llx\n"
+ " mask = 0x%016llx\n",
+
+ i_bar, i, config.baseAddress[i], bar, mask);
+ rc = CENTAUR_BAR_MASK_ERROR;
+ break;
+ }
+ }
+ }
+
+ if (rc) break;
+ }
+
+
+ // At this point the structure is initialized well-enough that it can
+ // be used by gpe_scom_centaur(). We run gpe_scom_centaur() to collect
+ // the CFAM ids of the chips. Prior to this we copy our local copy
+ // into the global read-only data structure. (Note that GPE can DMA
+ // under the OCC TLB memory protection.) In order for
+ // gpe_scom_centaur() to run the global configuration must be valid
+ // (configRc == 0) - so we provisionally mark it valid (and will
+ // invalidate it later if errors occur here).
+
+ // Note however that if no Centaur are present then we're already
+ // done.
+
+ // It's assumed that this procedure is being run before threads have
+ // started, therefore we must poll for completion of the GPE program.
+ // Assuming no contention for GPE1 this procedure should take a few
+ // microseconds at most to complete.
+
+ if (0) {
+
+ // Debug for Simics - only enable MCS 5
+
+ config.baseAddress[0] =
+ config.baseAddress[1] =
+ config.baseAddress[2] =
+ config.baseAddress[3] =
+ config.baseAddress[4] =
+ config.baseAddress[6] =
+ config.baseAddress[7] = 0;
+ }
+
+
+ config.configRc = 0;
+ memcpy_real(&G_centaurConfiguration, &config, sizeof(config));
+
+ if (config.config == 0) break;
+
+ S_scomList.scom = CENTAUR_DEVICE_ID;
+ S_scomList.commandType = GPE_SCOM_READ_VECTOR;
+ S_scomList.pData = G_centaurConfiguration.deviceId;
+
+ S_parms.scomList = CAST_POINTER(uint64_t, &S_scomList);
+ S_parms.entries = 1;
+ S_parms.options = 0;
+
+ pore_flex_create(&request,
+ &G_pore_gpe1_queue,
+ gpe_scom_centaur,
+ (uint32_t)(&S_parms),
+ SSX_MILLISECONDS(10), /* Timeout */
+ 0, 0, 0);
+
+ rc = pore_flex_schedule(&request);
+
+ if (rc) break;
+
+ while (!async_request_is_idle((AsyncRequest*)(&request)));
+
+ if (!async_request_completed((AsyncRequest*)(&request)) ||
+ (S_parms.rc != 0)) {
+
+ PRINTD("gpe_scom_centaur() for CENTAUR_DEVICE_ID failed:\n"
+ " Async state = 0x%02x\n"
+ " gpe_scom_centaur() rc = %u\n"
+ " gpe_scom_centaur() errorIndex = %d\n",
+ ((AsyncRequest*)(&request))->state,
+ S_parms.rc, S_parms.errorIndex);
+
+ rc = CENTAUR_READ_TPC_ID_FAILURE;
+ }
+
+ if (0) {
+
+ // Debug
+
+ slvctl.value = G_gsc_lastSlaveControl;
+
+ PRINTD("centaur_configuration_create:Debug\n"
+ " Last SCOM (PowerBus) address = 0x%016llx\n"
+ " Last Slave Control = 0x%016llx\n"
+ " Extended Address (positioned) = 0x%016llx\n"
+ " Last OCI Address = 0x%016llx\n",
+ G_gsc_lastScomAddress,
+ G_gsc_lastSlaveControl,
+ (unsigned long long)(slvctl.fields.extaddr) <<
+ (64 - 23 - 14),
+ G_gsc_lastOciAddress);
+ }
+
+ } while (0);
+
+ // Copy the final RC into the global structure and done.
+
+ memcpy_real(&(G_centaurConfiguration.configRc), &rc, sizeof(rc));
+
+ return rc;
+}
+
+
+// For now we have to handle configuring the PBA BAR and mask, and designating
+// a SYNC if the firmware forgot to.
+
+int
+centaur_configuration_create(void)
+{
+ return _centaur_configuration_create(PBA_BAR_CENTAUR,
+ PBA_SLAVE_PORE_GPE,
+ 2);
+}
+
+
+uint32_t mb_id(int i_mb)
+{
+ uint32_t rv;
+ centaur_device_id_t id;
+
+ if ((i_mb < 0) || (i_mb >= PGP_NCENTAUR) ||
+ (G_centaurConfiguration.configRc != 0)) {
+
+ rv = (uint32_t)-1;
+
+ } else {
+
+ id.value = G_centaurConfiguration.deviceId[i_mb];
+ rv = id.fields.cfam_id;
+ }
+
+ return rv;
+}
+
+
+uint8_t mb_chip_type(int i_mb)
+{
+ uint8_t rv;
+ cfam_id_t id;
+
+ if ((id.value = mb_id(i_mb)) == -1) {
+
+ rv = (uint8_t)-1;
+
+ } else {
+
+ rv = id.chipType;
+ }
+
+ return rv;
+}
+
+
+uint8_t mb_ec_level(int i_mb)
+{
+ uint8_t rv;
+ cfam_id_t id;
+
+ if ((id.value = mb_id(i_mb)) == -1) {
+
+ rv = (uint8_t)-1;
+
+ } else {
+
+ rv = (id.majorEc << 4) | id.minorEc;
+ }
+
+ return rv;
+}
diff --git a/src/ssx/pgp/pgp_centaur.h b/src/ssx/pgp/pgp_centaur.h
new file mode 100644
index 0000000..8c2ccee
--- /dev/null
+++ b/src/ssx/pgp/pgp_centaur.h
@@ -0,0 +1,254 @@
+#ifndef __PGP_CENTAUR_H__
+#define __PGP_CENTAUR_H__
+
+// $Id: pgp_centaur.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_centaur.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_centaur.h
+/// \brief Support for Centaur access and configuration from OCC.
+
+#include "gpe_pba.h"
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/// Compute the address of an MCS unit register from an index
+///
+/// The MCS units have a bizarre PIB addressing scheme. This macro generates
+/// MCS unit PIB addresses from a register name (w/o unit/index prefix),
+/// assuming a valid index in the range 0:7. In the big sceheme of things it
+/// probably saves space and time to do this with a table lookup rather than
+/// generating the code to compute the address modification. (If we ever need
+/// these in assembler code we'll have to implement a macro).
+
+#define MCS_ADDRESS(reg, index) (MCS0_##reg | _pgp_mcs_offset[index])
+
+extern const uint16_t _pgp_mcs_offset[PGP_NMCS];
+
+
+/// A description of the current Centaur configuration
+///
+/// \note Because this structure is read by the GPE engine it is strongly
+/// recommended to allocate instances of this structure in non-cacheable data
+/// sections, with the caveat that data structures assigned to non-default
+/// data sections must always be initialized. For example:
+///
+/// \code
+///
+/// CentaurConfiguration G_centaurConfiguration
+/// SECTION_ATTRIBUTE(".noncacheable_ro") =
+/// {.configRc = CENTAUR_NOT_CONFIGURED};
+///
+/// \endcode
+
+typedef struct {
+
+ /// Centaur base addresses for in-band operations
+ ///
+ /// These base addresses are used by GPE programs so it is most convenient
+ /// to store the entire 64 bits, even though only bits 23:26 of the base
+ /// address can be manipulated through the PBA BARs and BAR masks. A 0
+ /// value indicates an unconfigured Centaur (MCS).
+ uint64_t baseAddress[PGP_NCENTAUR];
+
+ /// Contents of Centaur device id registers
+ ///
+ /// These are the device ID SCOMs (0x000f000f) read from configured
+ /// Centaur during initialization. A 0 value indicates an unconfigured
+ /// Centaur. These values are deconstructed by the memory buffer (mb)
+ /// APIs mb_id(), mb_chip_type() and mb_ec_level().
+ uint64_t deviceId[PGP_NCENTAUR];
+
+ /// A "chip configuration" bit mask denoting valid Centaur
+ ///
+ /// It shoud always be true that a bit denoting a configured Centaur is
+ /// associated with a non-0 \a baseAddress and vice-versa.
+ ChipConfig config;
+
+ /// The image of the PBA slave control register to use for the SYNC command
+ ///
+ /// The PowerBus address used to accomplish a Centaur SYNC is
+ /// constant. To simplify the procedures the PBA slave control register
+ /// (containing the extended address portion of the address) is
+ /// pre-computed and stored here.
+ ///
+ /// \note One and Only one of the MCS units can be targeted with SYNC
+ /// commands. The design includes a private bus connecting all MCS on the
+ /// chip that allows this "SYNC master" to broadcast the SYNC to all other
+ /// MCS on the chip.
+ uint64_t syncSlaveControl;
+
+ /// A GpePbaParms parameter block for gpe_mem_data()
+ ///
+ /// This parameter block is set up in advance and used by the GPE
+ /// procedure gpe_mem_data(). Given the complexity of accessing Centaur
+ /// sensors and SCOM through the PBA it is simpler to set these up ahead
+ /// of time and simply have the GPE procedures access preconfigured global
+ /// data. The \a dataParms and \a scomParms members are distinguished by
+ /// the different way the PBA slave needs to be configured to access
+ /// either the Centaur sensor cache or Centaur SCOMs.
+ GpePbaParms dataParms;
+
+ /// A GpePbaParms parameter block for gpe_scom_centaur().
+ GpePbaParms scomParms;
+
+ /// The final return code from centaur_configuration_create().
+ ///
+ /// If initialization fails then this value can be used to diagnose what
+ /// happend. This field should be statically initialized to a non-0 value
+ /// (CENTAUR_NOT_CONFIGURED) and can then be checked against 0 to
+ /// determine if the structure has been correctly initialized.
+ int64_t configRc;
+
+} CentaurConfiguration;
+
+/// The global CentaurConfiguration created during initialization
+extern CentaurConfiguration G_centaurConfiguration;
+
+#else // __ASSEMBLER__
+
+ .set CENTAUR_CONFIGURATION_BASE_ADDRESS, 0x0
+
+ .set CENTAUR_CONFIGURATION_DEVICE_ID, \
+ (CENTAUR_CONFIGURATION_BASE_ADDRESS + (8 * PGP_NCENTAUR))
+
+ .set CENTAUR_CONFIGURATION_CONFIG, \
+ (CENTAUR_CONFIGURATION_DEVICE_ID + (8 * PGP_NCENTAUR))
+
+ .set CENTAUR_CONFIGURATION_SYNC_SLAVE_CONTROL, \
+ (CENTAUR_CONFIGURATION_CONFIG + 8)
+
+ .set CENTAUR_CONFIGURATION_DATA_PARMS, \
+ (CENTAUR_CONFIGURATION_SYNC_SLAVE_CONTROL + 8)
+
+ .set CENTAUR_CONFIGURATION_SCOM_PARMS, \
+ (CENTAUR_CONFIGURATION_DATA_PARMS + SIZEOF_GPEPBAPARMS)
+
+ .set CENTAUR_CONFIGURATION_CONFIG_RC, \
+ (CENTAUR_CONFIGURATION_SCOM_PARMS + SIZEOF_GPEPBAPARMS)
+
+ .set SIZEOF_CENTAUR_CONFIGURATION, \
+ (CENTAUR_CONFIGURATION_CONFIG_RC + 8)
+
+#endif // __ASSEMBLER__
+
+
+#ifndef __ASSEMBLER__
+
+/// Error return codes set/returned by centaur_configuration_create()
+
+enum CentaurConfigurationCreateRc{
+
+ CENTAUR_INVALID_ARGUMENT = 0x007ccc01,
+ CENTAUR_MCSMODE0_SCOM_FAILURE = 0x007ccc02,
+ CENTAUR_MCSMODE0_19_FAILURE = 0x007ccc03,
+ CENTAUR_ADDRESS_27_FAILURE = 0x007ccc04,
+ CENTAUR_MULTIPLE_DESIGNATED_SYNC = 0x007ccc05,
+ CENTAUR_NO_DESIGNATED_SYNC = 0x007ccc06,
+ CENTAUR_BAR_MASK_ERROR = 0x007ccc07,
+ CENTAUR_CONFIGURATION_FAILED = 0x007ccc08,
+ CENTAUR_DATA_SETUP_ERROR = 0x007ccc09,
+ CENTAUR_SCOM_SETUP_ERROR = 0x007ccc0a,
+ CENTAUR_NOT_CONFIGURED = 0x007ccc0b,
+ CENTAUR_MASK_ERROR = 0x007ccc0c,
+ CENTAUR_READ_TPC_ID_FAILURE = 0x007ccc0d,
+ CENTAUR_BARMSKN_PUTSCOM_FAILURE = 0x007ccc0e,
+ CENTAUR_BARN_PUTSCOM_FAILURE = 0x007ccc0f,
+ CENTAUR_BARMSKN_GETSCOM_FAILURE = 0x007ccc10,
+ CENTAUR_BARN_GETSCOM_FAILURE = 0x007ccc11,
+};
+
+
+/// Create (initialize) G_centaurConfiguration
+///
+/// G_centaurConfiguration is a global structure used by GPE procedures to
+/// access Centaur, and the mb_*() APIs to return CFAM-id type information
+/// about the Centaurs.
+///
+/// To complete Centaur configuration requires running the GPE program
+/// gpe_scom_centaur() on PORE-GPE1 to collect the TPC device Ids of the
+/// Centaur chips. This means that the "async" drivers must be set up prior to
+/// the call. We assume this API will be called before threads have started,
+/// thus it will poll the async request for completion. Assuming no other GPE
+/// programs are scheduled this should take a few microseconds at most.
+///
+/// \returns Either 0 for success or an element of the
+/// CentaurConfigurationCreateRc enumeration.
+int
+centaur_configuration_create(void);
+
+
+/// Create (initialize) G_centaurConfiguration (Internal API)
+///
+/// \param[in] i_bar The index of the PBA BAR reserved for access to
+/// Centaur. This will normally be passed as the constant PBA_BAR_CENTAUR but
+/// is allowed to be variable for special cases.
+///
+/// \param[in] i_slave The index of the PBA slave reserved for access from the
+/// GPE complex. This will normally be passed as the constant
+/// PBA_SLAVE_PORE_GPE but is allowed to be variable for special cases.
+///
+/// \param[in] i_setup If non-0, then this procedure will set up the PBA BAR
+/// correctly for access to Centaur. If > 1, then the procedure will also
+/// designate an MCS to recieve the Centaur SYNC if the firmware failed to do
+/// so.
+///
+/// This API must be run early in the initialization flow, likely before the
+/// real-time loop is activated. The API first scans the MBS configuration for
+/// correctness and (optionally) sets up the PBA BAR and mask for access to
+/// Centaur. The API then runs the gpe_scom_centaur() procedure to get the
+/// CFAM Id from each configured Centaur.
+///
+/// \note Normally we would implement test/bringup workarounds like the \a
+/// i_setup parameter separately, however the setup of Centaur is at a level
+/// of complexity where it makes sense to implement this override in a
+/// mainline procedure.
+int
+_centaur_configuration_create(int i_bar, int i_slave, int i_setup);
+
+
+/// Get a Centaur (MB) CFAM Chip Id
+///
+/// \param[in] i_mb The index (0..PGP_NCENTAUR - 1) of the memory buffer being
+/// queried.
+///
+/// \returns A 32-bit value to be compared against the enumeration of known
+/// CFAM ids. See \ref pgp_cfam_chip_ids. If the \a i_mb is invalid or the
+/// Centaur is not configured or the G_centaurConfiguration is not valid then
+/// (uint32_t)-1 is returned.
+uint32_t mb_id(int i_mb);
+
+
+/// Get a Centaur (MB) Chip Type
+///
+/// \param[in] i_mb The index (0..PGP_NCENTAUR - 1) of the memory buffer being
+/// queried.
+///
+/// \returns An 8-bit value to be compared against the enumeration of known
+/// CFAM chip types. See \ref pgp_cfam_chip_types. If the \a i_mb is invalid
+/// or the Centaur is not configured or the G_centaurConfiguration is not
+/// valid then (uint8_t)-1 is returned.
+uint8_t mb_chip_type(int i_mb);
+
+
+/// Get a Centaur (MB) CFAM Chip EC Level
+///
+/// \param[in] i_mb The index (0..PGP_NCENTAUR - 1) of the memory buffer being
+/// queried.
+///
+/// \returns An 8-bit value; The high-order nibble is the major EC level and
+/// the low-order nibble is the minor EC level. For example a value of 0x21
+/// indicates DD 2.1. If the \a i_mb is invalid or the Centaur is not
+/// configured or the G_centaurConfiguration is not valid then (uint8_t)-1 is
+/// returned.
+uint8_t mb_ec_level(int i_mb);
+
+#endif // __ASSEMBLER
+
+#endif // __PGP_CENTAUR_H__
diff --git a/src/ssx/pgp/pgp_common.h b/src/ssx/pgp/pgp_common.h
new file mode 100755
index 0000000..305f7c2
--- /dev/null
+++ b/src/ssx/pgp/pgp_common.h
@@ -0,0 +1,717 @@
+#ifndef __PGP_COMMON_H__
+#define __PGP_COMMON_H__
+
+// $Id: pgp_common.h,v 1.4 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_common.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_common.h
+/// \brief Common header for SSX and PMX versions of PgP
+///
+/// This header is maintained as part of the SSX port for PgP, 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 SSX. Do not edit in -*-
+// -*- the PMX area as your edits will be lost. -*-
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+extern unsigned int g_ocb_timer_divider; //grm
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+// Configuration
+////////////////////////////////////////////////////////////////////////////
+
+#define PGP_NCORES 16
+#define PGP_NCORE_PARTITIONS 4
+#define PGP_NMCS 8
+#define PGP_NCENTAUR 8
+#define PGP_NTHREADS 8
+#define PGP_NDTSCPM 4
+
+#ifndef PROCESSOR_EC_LEVEL
+#define MURANO_DD10 1
+#else
+#define MURANO_DD10 0
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////
+// Clocking
+////////////////////////////////////////////////////////////////////////////
+//
+// The SSX timebase is driven by the pervasive clock, which is nest / 4. This
+// will typically be 600MHz, but may be 500MHz for power-constrained system
+// designs.
+
+/// The pervasive hang timer divider used for the OCB timer
+///
+/// This is supposed to yield an approximately 1us timer, however for MURANO
+/// DD10 we need to use an approximate 64us timer
+
+#if MURANO_DD10
+#define OCB_TIMER_DIVIDER_DEFAULT (64 * 512)
+#else
+#define OCB_TIMER_DIVIDER_DEFAULT 512
+#endif
+
+/// This is set to the above default at compile time but may be updated
+/// at run time. grm
+#define OCB_TIMER_DIVIDER g_ocb_timer_divider
+
+/// The OCB timer frequency
+#define OCB_TIMER_FREQUENCY_HZ (SSX_TIMEBASE_FREQUENCY_HZ / OCB_TIMER_DIVIDER)
+
+/// The pervasive hang timer divider used for the PMC (same as OCB timer)
+#define PMC_TIMER_DIVIDER OCB_TIMER_DIVIDER
+
+/// The PMC hang pulse frequency
+#define PMC_HANG_PULSE_FREQUENCY_HZ \
+ (SSX_TIMEBASE_FREQUENCY_HZ / PMC_TIMER_DIVIDER)
+
+/// The pervasive hang timer divider for PCBS 'fast' timers
+///
+/// This timer yeilds an approximate 100ns pulse with a 2.4 GHz pervasive clock
+#define PCBS_FAST_TIMER_DIVIDER 64
+
+/// The pervasive hang timer divider for PCBS 'slow' timers
+///
+/// This timer yeilds an approximate 1us pulse with a 2.4 GHz pervasive clock
+#define PCBS_SLOW_TIMER_DIVIDER 512
+
+/// The PCBS slow divider frequency
+#define PCBS_SLOW_HANG_PULSE_FREQUENCY_HZ \
+ (SSX_TIMEBASE_FREQUENCY_HZ / PCBS_SLOW_TIMER_DIVIDER)
+
+/// The PCBS occ heartbeat pulse is predivided in hardware by 64
+#define PCBS_HEARTBEAT_DIVIDER \
+ (PCBS_SLOW_TIMER_DIVIDER * 64)
+
+/// The PCBS heartbeat pulse frequency
+#define PCBS_HEARTBEAT_PULSE_FREQUENCY_HZ \
+ (SSX_TIMEBASE_FREQUENCY_HZ / PCBS_HEARTBEAT_DIVIDER)
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// OCI
+////////////////////////////////////////////////////////////////////////////
+
+// OCI Master Id assigments - required for PBA slave programming. These Ids
+// also appear as bits 12:15 of the OCI register space addresses of the OCI
+// registers for each device that contains OCI-addressable registers (GPE,
+// PMC, PBA, SLW and OCB).
+
+#define OCI_MASTER_ID_PORE_GPE 0
+#define OCI_MASTER_ID_PMC 1
+#define OCI_MASTER_ID_PBA 2
+#define OCI_MASTER_ID_UNUSED 3
+#define OCI_MASTER_ID_PORE_SLW 4
+#define OCI_MASTER_ID_OCB 5
+#define OCI_MASTER_ID_OCC_ICU 6
+#define OCI_MASTER_ID_OCC_DCU 7
+
+
+////////////////////////////////////////////////////////////////////////////
+// IRQ
+////////////////////////////////////////////////////////////////////////////
+
+// The OCB interrupt controller consists of 2 x 32-bit controllers. Unlike
+// PPC ASICs, the OCB controllers are _not_ cascaded. The combined
+// controllers are presented to the application as if there were a single
+// 64-bit interrupt controller, while the code underlying the abstraction
+// manipulates the 2 x 32-bit controllers independently.
+//
+// Note that the bits named *RESERVED* are actually implemented in the
+// controller, but the interrupt input is tied low. That means they can also
+// be used as IPI targets. Logical bits 32..63 are not implemented.
+
+#define PGP_IRQ_DEBUGGER 0 /* 0x00 */
+#define PGP_IRQ_TRACE_TRIGGER 1 /* 0x01 */
+#define PGP_IRQ_OCC_ERROR 2 /* 0x02 */
+#define PGP_IRQ_PBA_ERROR 3 /* 0x03 */
+#define PGP_IRQ_SRT_ERROR 4 /* 0x04 */
+#define PGP_IRQ_PORE_SW_ERROR 5 /* 0x05 */
+#define PGP_IRQ_PORE_GPE0_FATAL_ERROR 6 /* 0x06 */
+#define PGP_IRQ_PORE_GPE1_FATAL_ERROR 7 /* 0x07 */
+#define PGP_IRQ_PORE_SBE_FATAL_ERROR 8 /* 0x08 */
+#define PGP_IRQ_PMC_ERROR 9 /* 0x09 */
+#define PGP_IRQ_OCB_ERROR 10 /* 0x0a */
+#define PGP_IRQ_SPIPSS_ERROR 11 /* 0x0b */
+#define PGP_IRQ_CHECK_STOP 12 /* 0x0c */
+#define PGP_IRQ_PMC_MALF_ALERT 13 /* 0x0d */
+#define PGP_IRQ_ADU_MALF_ALERT 14 /* 0x0e */
+#define PGP_IRQ_EXTERNAL_TRAP 15 /* 0x0f */
+#define PGP_IRQ_OCC_TIMER0 16 /* 0x10 */
+#define PGP_IRQ_OCC_TIMER1 17 /* 0x11 */
+#define PGP_IRQ_PORE_GPE0_ERROR 18 /* 0x12 */
+#define PGP_IRQ_PORE_GPE1_ERROR 19 /* 0x13 */
+#define PGP_IRQ_PORE_SBE_ERROR 20 /* 0x14 */
+#define PGP_IRQ_PMC_INTERCHIP_MSG_RECV 21 /* 0x15 */
+#define PGP_IRQ_RESERVED_22 22 /* 0x16 */
+#define PGP_IRQ_PORE_GPE0_COMPLETE 23 /* 0x17 */
+#define PGP_IRQ_PORE_GPE1_COMPLETE 24 /* 0x18 */
+#define PGP_IRQ_ADCFSM_ONGOING 25 /* 0x19 */
+#define PGP_IRQ_RESERVED_26 26 /* 0x1a */
+#define PGP_IRQ_PBA_OCC_PUSH0 27 /* 0x1b */
+#define PGP_IRQ_PBA_OCC_PUSH1 28 /* 0x1c */
+#define PGP_IRQ_PBA_BCDE_ATTN 29 /* 0x1d */
+#define PGP_IRQ_PBA_BCUE_ATTN 30 /* 0x1e */
+#define PGP_IRQ_RESERVED_31 31 /* 0x1f */
+
+#define PGP_IRQ_RESERVED_32 32 /* 0x20 */
+#define PGP_IRQ_RESERVED_33 33 /* 0x21 */
+#define PGP_IRQ_STRM0_PULL 34 /* 0x22 */
+#define PGP_IRQ_STRM0_PUSH 35 /* 0x23 */
+#define PGP_IRQ_STRM1_PULL 36 /* 0x24 */
+#define PGP_IRQ_STRM1_PUSH 37 /* 0x25 */
+#define PGP_IRQ_STRM2_PULL 38 /* 0x26 */
+#define PGP_IRQ_STRM2_PUSH 39 /* 0x27 */
+#define PGP_IRQ_STRM3_PULL 40 /* 0x28 */
+#define PGP_IRQ_STRM3_PUSH 41 /* 0x29 */
+#define PGP_IRQ_RESERVED_42 42 /* 0x2a */
+#define PGP_IRQ_RESERVED_43 43 /* 0x2b */
+#define PGP_IRQ_PMC_VOLTAGE_CHANGE_ONGOING 44 /* 0x2c */
+#define PGP_IRQ_PMC_PROTOCOL_ONGOING 45 /* 0x2d */
+#define PGP_IRQ_PMC_SYNC 46 /* 0x2e */
+#define PGP_IRQ_PMC_PSTATE_REQUEST 47 /* 0x2f */
+#define PGP_IRQ_RESERVED_48 48 /* 0x30 */
+#define PGP_IRQ_RESERVED_49 49 /* 0x31 */
+#define PGP_IRQ_PMC_IDLE_EXIT 50 /* 0x32 */
+#define PGP_IRQ_PORE_SW_COMPLETE 51 /* 0x33 */
+#define PGP_IRQ_PMC_IDLE_ENTER 52 /* 0x34 */
+#define PGP_IRQ_RESERVED_53 53 /* 0x35 */
+#define PGP_IRQ_PMC_INTERCHIP_MSG_SEND_ONGOING 54 /* 0x36 */
+#define PGP_IRQ_OCI2SPIVID_ONGOING 55 /* 0x37 */
+#define PGP_IRQ_PMC_OCB_O2P_ONGOING 56 /* 0x38 */
+#define PGP_IRQ_PSSBRIDGE_ONGOING 57 /* 0x39 */
+#define PGP_IRQ_PORE_SBE_COMPLETE 58 /* 0x3a */
+#define PGP_IRQ_IPI0 59 /* 0x3b */
+#define PGP_IRQ_IPI1 60 /* 0x3c */
+#define PGP_IRQ_IPI2 61 /* 0x3d */
+#define PGP_IRQ_IPI3 62 /* 0x3e */
+#define PGP_IRQ_RESERVED_63 63 /* 0x3f */
+
+
+// Please keep the string definitions up-to-date as they are used for
+// reporting in the Simics simulation.
+
+#define PGP_IRQ_STRINGS(var) \
+ const char* var[64] = { \
+ "PGP_IRQ_DEBUGGER", \
+ "PGP_IRQ_TRACE_TRIGGER", \
+ "PGP_IRQ_OCC_ERROR", \
+ "PGP_IRQ_PBA_ERROR", \
+ "PGP_IRQ_SRT_ERROR", \
+ "PGP_IRQ_PORE_SW_ERROR", \
+ "PGP_IRQ_PORE_GPE0_FATAL_ERROR", \
+ "PGP_IRQ_PORE_GPE1_FATAL_ERROR", \
+ "PGP_IRQ_PORE_SBE_FATAL_ERROR", \
+ "PGP_IRQ_PMC_ERROR", \
+ "PGP_IRQ_OCB_ERROR", \
+ "PGP_IRQ_SPIPSS_ERROR", \
+ "PGP_IRQ_CHECK_STOP", \
+ "PGP_IRQ_PMC_MALF_ALERT", \
+ "PGP_IRQ_ADU_MALF_ALERT", \
+ "PGP_IRQ_EXTERNAL_TRAP", \
+ "PGP_IRQ_OCC_TIMER0", \
+ "PGP_IRQ_OCC_TIMER1", \
+ "PGP_IRQ_PORE_GPE0_ERROR", \
+ "PGP_IRQ_PORE_GPE1_ERROR", \
+ "PGP_IRQ_PORE_SBE_ERROR", \
+ "PGP_IRQ_PMC_INTERCHIP_MSG_RECV", \
+ "PGP_IRQ_RESERVED_22", \
+ "PGP_IRQ_PORE_GPE0_COMPLETE", \
+ "PGP_IRQ_PORE_GPE1_COMPLETE", \
+ "PGP_IRQ_ADCFSM_ONGOING", \
+ "PGP_IRQ_RESERVED_26", \
+ "PGP_IRQ_PBA_OCC_PUSH0", \
+ "PGP_IRQ_PBA_OCC_PUSH1", \
+ "PGP_IRQ_PBA_BCDE_ATTN", \
+ "PGP_IRQ_PBA_BCUE_ATTN", \
+ "PGP_IRQ_RESERVED_31", \
+ "PGP_IRQ_RESERVED_32", \
+ "PGP_IRQ_RESERVED_33", \
+ "PGP_IRQ_STRM0_PULL", \
+ "PGP_IRQ_STRM0_PUSH", \
+ "PGP_IRQ_STRM1_PULL", \
+ "PGP_IRQ_STRM1_PUSH", \
+ "PGP_IRQ_STRM2_PULL", \
+ "PGP_IRQ_STRM2_PUSH", \
+ "PGP_IRQ_STRM3_PULL", \
+ "PGP_IRQ_STRM3_PUSH", \
+ "PGP_IRQ_RESERVED_42", \
+ "PGP_IRQ_RESERVED_43", \
+ "PGP_IRQ_PMC_VOLTAGE_CHANGE_ONGOING", \
+ "PGP_IRQ_PMC_PROTOCOL_ONGOING", \
+ "PGP_IRQ_PMC_SYNC", \
+ "PGP_IRQ_PMC_PSTATE_REQUEST", \
+ "PGP_IRQ_RESERVED_48", \
+ "PGP_IRQ_RESERVED_49", \
+ "PGP_IRQ_PMC_IDLE_EXIT", \
+ "PGP_IRQ_PORE_SW_COMPLETE", \
+ "PGP_IRQ_PMC_IDLE_ENTER", \
+ "PGP_IRQ_RESERVED_53", \
+ "PGP_IRQ_PMC_INTERCHIP_MSG_SEND_ONGOING", \
+ "PGP_IRQ_OCI2SPIVID_ONGOING", \
+ "PGP_IRQ_PMC_OCB_O2P_ONGOING", \
+ "PGP_IRQ_PSSBRIDGE_ONGOING", \
+ "PGP_IRQ_PORE_SBE_COMPLETE", \
+ "PGP_IRQ_IPI0", \
+ "PGP_IRQ_IPI1", \
+ "PGP_IRQ_IPI2", \
+ "PGP_IRQ_IPI3 (ASYNC-IPI)", \
+ "PGP_IRQ_RESERVED_63" \
+ };
+
+
+/// This constant is used to define the size of the table of interrupt handler
+/// structures as well as a limit for error checking. The entire 64-bit
+/// vector is now in use.
+
+#define PPC405_IRQS 64
+
+
+// Note: All standard-product IPI uses are declared here to avoid conflicts
+// Validation- and lab-only IPI uses are documented in validation.h
+
+/// The deferred callback queue interrupt
+///
+/// This IPI is reserved for use of the async deferred callback mechanism.
+/// This IPI is used by both critical and noncritical async handlers to
+/// activate the deferred callback mechanism.
+#define PGP_IRQ_ASYNC_IPI PGP_IRQ_IPI3
+
+
+/// The PTS completion queue intererupt
+///
+/// This IPI is reserved for use of the PTS completion queues. A single
+/// interrupt serves PTS for both GPE0 and GPE1. Note that as defined here,
+/// PTS completion takes precedence over other ASYNC processing, however in
+/// reality they both run callbacks preemptible so they will tend to be more
+/// or less at the same priority. If this is a problem then they could be
+/// combined onto a single interrupt and handled with the appropriate priority
+/// in the async_callback_handler_full().
+
+#define PGP_IRQ_PTS_IPI PGP_IRQ_IPI2
+
+
+#ifndef __ASSEMBLER__
+
+/// This expression recognizes only those IRQ numbers that have named
+/// (non-reserved) interrupts in the OCB interrupt controller.
+
+// There are so many invalid interrupts now that it's a slight improvement in
+// code size to let the compiler optimize the invalid IRQs to a bit mask for
+// the comparison.
+
+#define PGP_IRQ_VALID(irq) \
+ ({unsigned __irq = (unsigned)(irq); \
+ ((__irq < PPC405_IRQS) && \
+ ((PGP_IRQ_MASK64(__irq) & \
+ (PGP_IRQ_MASK64(PGP_IRQ_RESERVED_22) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_26) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_31) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_32) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_33) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_42) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_43) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_48) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_49) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_53) | \
+ PGP_IRQ_MASK64(PGP_IRQ_RESERVED_63))) == 0));})
+
+/// This is a 32-bit mask, with big-endian bit (irq % 32) set.
+#define PGP_IRQ_MASK32(irq) (((uint32_t)0x80000000) >> ((irq) % 32))
+
+/// This is a 64-bit mask, with big-endian bit 'irq' set.
+#define PGP_IRQ_MASK64(irq) (0x8000000000000000ull >> (irq))
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// OCB
+////////////////////////////////////////////////////////////////////////////
+
+/// The base address of the OCI control register space
+#define OCI_REGISTER_SPACE_BASE 0x40000000
+
+/// The base address of the entire PIB port mapped by the OCB. The
+/// OCB-contained PIB registers are based at OCB_PIB_BASE.
+#define OCB_PIB_SLAVE_BASE 0x00060000
+
+/// The size of the OCI control register address space
+///
+/// There are at most 8 slaves, each of which maps 2**16 bytes of register
+/// address space.
+#define OCI_REGISTER_SPACE_SIZE POW2_32(19)
+
+/// This macro converts an OCI register space address into a PIB address as
+/// seen through the OCB direct bridge.
+#define OCI2PIB(addr) ((((addr) & 0x0007ffff) >> 3) + OCB_PIB_SLAVE_BASE)
+
+
+// OCB communication channel constants
+
+#define OCB_INDIRECT_CHANNELS 4
+
+#define OCB_RW_READ 0
+#define OCB_RW_WRITE 1
+
+#define OCB_STREAM_MODE_DISABLED 0
+#define OCB_STREAM_MODE_ENABLED 1
+
+#define OCB_STREAM_TYPE_LINEAR 0
+#define OCB_STREAM_TYPE_CIRCULAR 1
+
+#define OCB_INTR_ACTION_FULL 0
+#define OCB_INTR_ACTION_NOT_FULL 1
+#define OCB_INTR_ACTION_EMPTY 2
+#define OCB_INTR_ACTION_NOT_EMPTY 3
+
+#ifndef __ASSEMBLER__
+
+// These macros select OCB interrupt controller registers based on the IRQ
+// number.
+
+#define OCB_OIMR_AND(irq) (((irq) & 0x20) ? OCB_OIMR1_AND : OCB_OIMR0_AND)
+#define OCB_OIMR_OR(irq) (((irq) & 0x20) ? OCB_OIMR1_OR : OCB_OIMR0_OR)
+
+#define OCB_OISR(irq) (((irq) & 0x20) ? OCB_OISR1 : OCB_OISR0)
+#define OCB_OISR_AND(irq) (((irq) & 0x20) ? OCB_OISR1_AND : OCB_OISR0_AND)
+#define OCB_OISR_OR(irq) (((irq) & 0x20) ? OCB_OISR1_OR : OCB_OISR0_OR)
+
+#define OCB_OIEPR(irq) (((irq) & 0x20) ? OCB_OIEPR1 : OCB_OIEPR0)
+#define OCB_OITR(irq) (((irq) & 0x20) ? OCB_OITR1 : OCB_OITR0)
+#define OCB_OCIR(irq) (((irq) & 0x20) ? OCB_OCIR1 : OCB_OCIR0)
+#define OCB_OUDER(irq) (((irq) & 0x20) ? OCB_OUDER1 : OCB_OUDER0)
+
+#endif /* __ASSEMBLER__ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// PMC
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+/// A Pstate type
+///
+/// Pstates are signed, but our register access macros operate on unsigned
+/// values. To avoid bugs, Pstate register fields should always be extracted
+/// to a variable of type Pstate. If the size of Pstate variables ever
+/// changes we will have to revisit this convention.
+typedef int8_t Pstate;
+
+/// A DPLL frequency code
+///
+/// DPLL frequency codes moved from 8 to 9 bits going from P7 to P8
+typedef uint16_t DpllCode;
+
+/// A VRM11 VID code
+typedef uint8_t Vid11;
+
+#endif /* __ASSEMBLER__ */
+
+/// The minimum Pstate
+#define PSTATE_MIN -128
+
+/// The maximum Pstate
+#define PSTATE_MAX 127
+
+/// The minimum \e legal DPLL frequency code
+///
+/// This is ~1GHz with a 33.3MHz tick frequency.
+#define DPLL_MIN 0x01e
+
+/// The maximum DPLL frequency code
+#define DPLL_MAX 0x1ff
+
+/// The minimum \a legal (non-power-off) VRM11 VID code
+#define VID11_MIN 0x02
+
+/// The maximum \a legal (non-power-off) VRM11 VID code
+#define VID11_MAX 0xfd
+
+
+////////////////////////////////////////////////////////////////////////////
+// PCB
+////////////////////////////////////////////////////////////////////////////
+
+/// Convert a core chiplet 0 SCOM address to the equivalent address for any
+/// other core chiplet.
+///
+/// Note that it is unusual to address core chiplet SCOMs directly. Normally
+/// this is done as part of a GPE program where the program iterates over core
+/// chiplets, using the chiplet-0 address + a programmable offset held in a
+/// chiplet address register. Therefore the only address macro defined is the
+/// chiplet-0 address. This macro is used for the rare cases of explicit
+/// getscom()/ putscom() to a particular chiplet.
+
+#define CORE_CHIPLET_ADDRESS(addr, core) ((addr) + ((core) << 24))
+
+
+// PCB Error codes
+
+#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
+
+// PCB Multicast modes
+
+#define PCB_MULTICAST_OR 0
+#define PCB_MULTICAST_AND 1
+#define PCB_MULTICAST_SELECT 2
+#define PCB_MULTICAST_COMPARE 4
+#define PCB_MULTICAST_WRITE 5
+
+/// \defgroup pcb_multicast_groups PCB Multicast Groups
+///
+/// Technically the multicast groups are programmable; This is the multicast
+/// grouping established by proc_sbe_chiplet_init().
+///
+/// - Group 0 : All functional chiplets (PRV PB XBUS ABUS PCIE TPCEX)
+/// - Group 1 : All functional EX chiplets (no cores)
+/// - Group 2 : All functional EX chiplets (core only)
+/// - Group 3 : All functional chiplets except pervasive (PRV)
+///
+/// @{
+
+#define MC_GROUP_ALL 0
+#define MC_GROUP_EX 1
+#define MC_GROUP_EX_CORE 2
+#define MC_GROUP_ALL_BUT_PRV 3
+
+/// @}
+
+
+/// Convert any SCOM address to a multicast address
+#define MC_ADDRESS(address, group, mode) \
+ (((address) & 0x00ffffff) | ((0x40 | ((mode) << 3) | (group)) << 24))
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// PBA
+////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////
+// Macros for fields of PBA_MODECTL
+////////////////////////////////////
+
+/// The 64KB OCI HTM marker space is enabled by default at 0x40070000
+///
+/// See the comments for pgp_trace.h
+
+#define PBA_OCI_MARKER_BASE 0x40070000
+
+
+// SSX Kernel reserved trace addresses, see pgp_trace.h.
+
+#define SSX_TRACE_CRITICAL_IRQ_ENTRY_BASE 0xf000
+#define SSX_TRACE_CRITICAL_IRQ_EXIT_BASE 0xf100
+#define SSX_TRACE_NONCRITICAL_IRQ_ENTRY_BASE 0xf200
+#define SSX_TRACE_NONCRITICAL_IRQ_EXIT_BASE 0xf300
+#define SSX_TRACE_THREAD_SWITCH_BASE 0xf400
+#define SSX_TRACE_THREAD_SLEEP_BASE 0xf500
+#define SSX_TRACE_THREAD_WAKEUP_BASE 0xf600
+#define SSX_TRACE_THREAD_SEMAPHORE_PEND_BASE 0xf700
+#define SSX_TRACE_THREAD_SEMAPHORE_POST_BASE 0xf800
+#define SSX_TRACE_THREAD_SEMAPHORE_TIMEOUT_BASE 0xf900
+#define SSX_TRACE_THREAD_SUSPENDED_BASE 0xfa00
+#define SSX_TRACE_THREAD_DELETED_BASE 0xfb00
+#define SSX_TRACE_THREAD_COMPLETED_BASE 0xfc00
+#define SSX_TRACE_THREAD_MAPPED_RUNNABLE_BASE 0xfd00
+#define SSX_TRACE_THREAD_MAPPED_SEMAPHORE_PEND_BASE 0xfe00
+#define SSX_TRACE_THREAD_MAPPED_SLEEPING_BASE 0xff00
+
+
+// Please keep the string definitions up to date as they are used for
+// reporting in the Simics simulation.
+
+#define SSX_TRACE_STRINGS(var) \
+ const char* var[16] = { \
+ "Critical IRQ Entry ", \
+ "Critical IRQ Exit ", \
+ "Noncritical IRQ Entry ", \
+ "Noncritical IRQ Exit ", \
+ "Thread Switch ", \
+ "Thread Blocked : Sleep ", \
+ "Thread Unblocked : Wakeup ", \
+ "Thread Blocked : Semaphore ", \
+ "Thread Unblocked : Semaphore ", \
+ "Thread Unblocked : Sem. Timeout", \
+ "Thread Suspended ", \
+ "Thread Deleted ", \
+ "Thread Completed ", \
+ "Thread Mapped Runnable ", \
+ "Thread Mapped Semaphore Pend. ", \
+ "Thread Mapped Sleeping ", \
+ };
+
+
+// PBA transaction sizes for the block copy engines
+
+#define PBA_BCE_OCI_TRANSACTION_32_BYTES 0
+#define PBA_BCE_OCI_TRANSACTION_64_BYTES 1
+#define PBA_BCE_OCI_TRANSACTION_8_BYTES 2
+
+
+// PBAX communication channel constants
+
+#define PBAX_CHANNELS 2
+
+#define PBAX_INTR_ACTION_FULL 0
+#define PBAX_INTR_ACTION_NOT_FULL 1
+#define PBAX_INTR_ACTION_EMPTY 2
+#define PBAX_INTR_ACTION_NOT_EMPTY 3
+
+
+// PBA Write Buffer fields
+
+#define PBA_WBUFVALN_STATUS_EMPTY 0x01
+#define PBA_WBUFVALN_STATUS_GATHERING 0x02
+#define PBA_WBUFVALN_STATUS_WAIT 0x04
+#define PBA_WBUFVALN_STATUS_WRITING 0x08
+#define PBA_WBUFVALN_STATUS_CRESPERR 0x10
+
+
+////////////////////////////////////////////////////////////////////////////
+// VRM
+////////////////////////////////////////////////////////////////////////////
+
+// These are the command types recognized by the VRMs
+
+#define VRM_WRITE_VOLTAGE 0x0
+#define VRM_READ_STATE 0xc
+#define VRM_READ_VOLTAGE 0x3
+
+// Voltage rail designations for the read voltage command
+#define VRM_RD_VDD_RAIL 0x0
+#define VRM_RD_VCS_RAIL 0x1
+
+
+////////////////////////////////////////////////////////////////////////////
+// OHA
+////////////////////////////////////////////////////////////////////////////
+
+// Power proxy trace record idle state encodings. These encodings are unique
+// to the Power proxy trace record.
+
+#define PPT_IDLE_NON_IDLE 0x0
+#define PPT_IDLE_NAP 0x1
+#define PPT_IDLE_LIGHT_SLEEP 0x2
+#define PPT_IDLE_FAST_SLEEP 0x3
+#define PPT_IDLE_DEEP_SLEEP 0x4
+#define PPT_IDLE_LIGHT_WINKLE 0x5
+#define PPT_IDLE_FAST_WINKLE 0x6
+#define PPT_IDLE_DEEP_WINKLE 0x7
+
+
+////////////////////////////////////////////////////////////////////////////
+// PC
+////////////////////////////////////////////////////////////////////////////
+
+// SPRC numbers for PC counters. The low-order 3 bits are always defined as
+// 0. The address can also be modified by OR-ing in 0x400 to indicate
+// auto-increment addressing. Note that the frequency-sensitivity counters
+// are called "workrate" counters in the hardware documentation.
+//
+// Notes on the throttle counters:
+//
+// SPRN_IFU_THROTTLE_COUNTER
+// Cycles the IFU throttle was actually blocking fetch
+//
+// <= if_pc_didt_throttle_blocked
+//
+// SPRN_ISU_THROTTLE_COUNTER
+// Cycles that ISU throttle was active and modeably IFU throttle request
+// was not
+//
+// <= sd_pc_uthrottle_active AND
+// (NOT scom_isuonly_count_mode OR NOT trigger_didt_throttle)
+//
+// SPRN_IFU_ACTIVE_COUNTER
+// Cycles that IFU throttle active input is asserted
+//
+// <= if_pc_didt_throttle_active
+
+
+/// \note The OCC SPRC/SPRD hardware has a bug that makes it such that the OCC
+/// SPRC increments whenever the OCC SPRD is accessed, regardless of the
+/// setting of the SPRN_PC_AUTOINCREMENT bit. This bug won't be fixed.
+
+#define SPRN_CORE_INSTRUCTION_DISPATCH 0x200
+#define SPRN_CORE_INSTRUCTION_COMPLETE 0x208
+#define SPRN_CORE_FREQUENCY_SENSITIVITY_BUSY 0x210
+#define SPRN_CORE_FREQUENCY_SENSITIVITY_FINISH 0x218
+#define SPRN_CORE_RUN_CYCLE 0x220
+#define SPRN_CORE_RAW_CYCLE 0x228
+#define SPRN_CORE_MEM_HIER_A 0x230
+#define SPRN_CORE_MEM_HIER_B 0x238
+#define SPRN_CORE_MEM_C_LPAR(p) (0x240 + (8 * (p)))
+#define SPRN_WEIGHTED_INSTRUCTION_PROCESSING 0x260
+#define SPRN_WEIGHTED_GPR_REGFILE_ACCESS 0x268
+#define SPRN_WEIGHTED_VRF_REGFILE_ACCESS 0x270
+#define SPRN_WEIGHTED_FLOATING_POINT_ISSUE 0x278
+#define SPRN_WEIGHTED_CACHE_READ 0x280
+#define SPRN_WEIGHTED_CACHE_WRITE 0x288
+#define SPRN_WEIGHTED_ISSUE 0x290
+#define SPRN_WEIGHTED_CACHE_ACCESS 0x298
+#define SPRN_WEIGHTED_VSU_ISSUE 0x2a0
+#define SPRN_WEIGHTED_FXU_ISSUE 0x2a8
+
+#define SPRN_THREAD_RUN_CYCLES(t) (0x2b0 + (0x20 * (t)))
+#define SPRN_THREAD_INSTRUCTION_COMPLETE(t) (0x2b8 + (0x20 * (t)))
+#define SPRN_THREAD_MEM_HIER_A(t) (0x2c0 + (0x20 * (t)))
+#define SPRN_THREAD_MEM_HIER_B(t) (0x2c8 + (0x20 * (t)))
+
+#define SPRN_IFU_THROTTLE_COUNTER 0x3b0
+#define SPRN_ISU_THROTTLE_COUNTER 0x3b8
+#define SPRN_IFU_ACTIVE_COUNTER 0x3c0
+
+#define SPRN_PC_AUTOINCREMENT 0x400
+
+
+////////////////////////////////////////////////////////////////////////////
+// Centaur
+////////////////////////////////////////////////////////////////////////////
+
+// DIMM sensor status codes
+
+/// The next sampling period began before this sensor was read or the master
+/// enable is off, or the individual sensor is disabled. If the subsequent
+/// read completes on time, this will return to valid reading. Sensor data may
+/// be accurate, but stale. If due to a stall, the StallError FIR will be
+/// set.
+#define DIMM_SENSOR_STATUS_STALLED 0
+
+/// The sensor data was not returned correctly either due to parity
+/// error or PIB bus error code. Will return to valid if the next PIB
+/// access to this sensor is valid, but a FIR will be set; Refer to FIR
+/// for exact error. Sensor data should not be considered valid while
+/// this code is present.
+#define DIMM_SENSOR_STATUS_ERROR 1
+
+/// Sensor data is valid, and has been valid since the last time this
+/// register was read.
+#define DIMM_SENSOR_STATUS_VALID_OLD 2
+
+/// Sensor data is valid and has not yet been read by a SCOM. The status code
+/// return to DIMM_SENSOR_STATUS_VALID_OLD after this register is read.
+#define DIMM_SENSOR_STATUS_VALID_NEW 3
+
+
+#endif /* __PGP_COMMON_H__ */
diff --git a/src/ssx/pgp/pgp_core.h b/src/ssx/pgp/pgp_core.h
new file mode 100755
index 0000000..59edb26
--- /dev/null
+++ b/src/ssx/pgp/pgp_core.h
@@ -0,0 +1,20 @@
+#ifndef __PGP_CORE_H__
+#define __PGP_CORE_H__
+
+// $Id: pgp_core.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_core.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_core.h
+/// \brief PgP core units header. Local and mechanically generated macros.
+
+#include "pc_register_addresses.h"
+#include "pc_firmware_registers.h"
+#include "sensors_register_addresses.h"
+#include "sensors_firmware_registers.h"
+
+#endif /* __PGP_CORE_H__ */
diff --git a/src/ssx/pgp/pgp_id.c b/src/ssx/pgp/pgp_id.c
new file mode 100644
index 0000000..0b4d4d7
--- /dev/null
+++ b/src/ssx/pgp/pgp_id.c
@@ -0,0 +1,135 @@
+// $Id: pgp_id.c,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_id.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_id.h
+/// \brief PgP chip and EC-level identification + chip configuration
+
+#include "ssx.h"
+#include "pgp_config.h"
+
+
+// Note: These cached variables are all declared as 64 bits, noncacheable so
+// that that they are also available as-is to PORE programs.
+
+uint64_t G_node_id SECTION_ATTRIBUTE(".noncacheable") = 0;
+uint64_t G_chip_id SECTION_ATTRIBUTE(".noncacheable") = 0;
+uint64_t G_cfam_id SECTION_ATTRIBUTE(".noncacheable") = 0;
+uint64_t G_cfam_chip_type SECTION_ATTRIBUTE(".noncacheable") = 0;
+uint64_t G_cfam_ec_level SECTION_ATTRIBUTE(".noncacheable") = 0;
+
+void
+_pgp_get_ids(void)
+{
+ tpc_gp0_t gp0;
+ tpc_device_id_t deviceId;
+ cfam_id_t cfamId;
+
+ getscom(TPC_GP0, &(gp0.value));
+ G_node_id = gp0.fields.tc_node_id_dc;
+ G_chip_id = gp0.fields.tc_chip_id_dc;
+
+ getscom(TPC_DEVICE_ID, &(deviceId.value));
+ G_cfam_id = cfamId.value = deviceId.fields.cfam_id;
+ G_cfam_chip_type = cfamId.chipType;
+ G_cfam_ec_level = (cfamId.majorEc << 4) | cfamId.minorEc;
+}
+
+
+uint8_t
+node_id(void)
+{
+ return G_node_id;
+}
+
+uint8_t
+chip_id(void)
+{
+ return G_chip_id;
+}
+
+uint32_t
+cfam_id(void)
+{
+ return G_cfam_id;
+}
+
+uint8_t
+cfam_chip_type(void)
+{
+ return G_cfam_chip_type;
+}
+
+uint8_t
+cfam_ec_level(void)
+{
+ return G_cfam_ec_level;
+}
+
+
+// The chiplet configuration is computed by doing a "select-mode" multicast to
+// the all-functional-chiplets-core group. Correctness here depends on the
+// convention that the "select" bit number will always be 0. We check just to
+// be sure. Since this is called from initialization code there is no recourse
+// here except to panic in the event of error.
+
+// Note: Ex-chiplets start at chiplet 16 and are left-justified in the
+// ChipConfig.
+
+
+ChipConfig G_chip_configuration SECTION_ATTRIBUTE(".noncacheable") = 0;
+uint64_t G_core_configuration SECTION_ATTRIBUTE(".noncacheable") = 0;
+
+/// \bug This API currently only computes the core configuration. It needs to
+/// be extended to also compute the MC and Centaur configuration.
+///
+/// \bug in Simics we're doing this based on the PMC_CORE_DECONFIGURATION_REG
+/// pending Simics support for the base pervasive functionality
+
+void
+_pgp_get_chip_configuration(void)
+{
+ if (SIMICS_ENVIRONMENT) {
+
+ pmc_core_deconfiguration_reg_t pcdr;
+
+ pcdr.value = in32(PMC_CORE_DECONFIGURATION_REG);
+ G_chip_configuration =
+ ~((uint64_t)(pcdr.fields.core_chiplet_deconf_vector) << 48);
+
+ } else {
+
+ uint64_t select, configuration;
+ int rc;
+
+ rc = getscom(0x000f0008, &select); /* TP CHIPLET SELECT */
+ if (rc) SSX_PANIC(PGP_ID_SCOM_ERROR_SELECT);
+ if (select != 0) SSX_PANIC(PGP_ID_SELECT_ERROR);
+
+ rc = getscom(MC_ADDRESS(0x000f0012,
+ MC_GROUP_EX_CORE,
+ PCB_MULTICAST_SELECT),
+ &configuration);
+ if (rc) SSX_PANIC(PGP_ID_SCOM_ERROR_CONFIG);
+
+ G_chip_configuration = (configuration << 16) & 0xffff000000000000ull;
+ }
+
+ G_core_configuration = G_chip_configuration & 0xffff000000000000ull;
+}
+
+
+uint32_t core_configuration(void)
+{
+ return G_core_configuration >> 32;
+}
+
+
+
+
+
+
diff --git a/src/ssx/pgp/pgp_id.h b/src/ssx/pgp/pgp_id.h
new file mode 100644
index 0000000..2b0ecab
--- /dev/null
+++ b/src/ssx/pgp/pgp_id.h
@@ -0,0 +1,183 @@
+#ifndef __PGP_ID_H__
+#define __PGP_ID_H__
+
+// $Id: pgp_id.h,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_id.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_id.h
+/// \brief PgP chip and EC-level identification + chip configuration
+///
+/// During initialization the device identification SCOM registers are read
+/// and cached.
+///
+/// The node and chip ids are read from TPC_GP0 and stored as global
+/// variables, accessible through the node_id() and chip_id() APIs. The
+/// global variables are available to PORE programs.
+///
+/// The TPC_DEVICE_ID register is also read, deconstructed and stored in
+/// global variables. APIs defined here provide access to the fields of the
+/// device identification to support run-time behavior based on the chip type
+/// and EC level of the POWER8 chip containing the OCC. The global variables
+/// are available to PORE programs.
+///
+/// - cfam_id() : Obtain the full chip identification as a 32-bit CFAM id
+/// - cfam_chip_type() : Obtain the 8-bit CFAM chip type
+/// - cfam_ec_level() : Obtain an 8-bit CFAM EC level
+///
+/// For example, to identify a chip as Murano DD1.0, one could use either
+/// method shown below:
+///
+/// \code
+///
+/// if (cfam_id() == CFAM_CHIP_ID_MURANO_10) { ... }
+///
+/// if ((cfam_chip_type() == CFAM_CHIP_TYPE_MURANO) &&
+/// (cfam_ec_level() == 0x10)) { ... }
+///
+/// \encode
+
+// Error/Panic Codes
+
+#define PGP_ID_SCOM_ERROR_SELECT 0x00747401
+#define PGP_ID_SCOM_ERROR_CONFIG 0x00747402
+#define PGP_ID_SELECT_ERROR 0x00747403
+
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include "tpc_firmware_registers.h"
+#include "pgp_config.h"
+
+
+/// Get TPC device identification (internal API, called once from __pgp_setup().
+void
+_pgp_get_ids(void);
+
+/// Get the TPC Node Id
+uint8_t node_id(void);
+
+/// Get the TPC Chip Id
+uint8_t chip_id(void);
+
+/// Get the CFAM Chip Id
+///
+/// \returns A 32-bit value to be compared against the enumeration of known
+/// CFAM ids. See \ref pgp_cfam_chip_ids.
+uint32_t cfam_id(void);
+
+/// Get the CFAM Chip Type
+///
+/// \returns An 8-bit value to be compared against the enumeration of known
+/// CFAM chip types. See \ref pgp_cfam_chip_types.
+uint8_t cfam_chip_type(void);
+
+/// Get the CFAM Chip EC Level
+///
+/// \returns An 8-bit value; The high-order nibble is the major EC level and
+/// the low-order nibble is the minor EC level. Fore example a value of 0x21
+/// indicates DD 2.1.
+uint8_t cfam_ec_level(void);
+
+
+/// Compute the chip configuration (internal API, called once from __pgp_setup().
+void
+_pgp_get_chip_configuration(void);
+
+/// Get the core configuration
+///
+/// The return value is a 32 bit integer with big-endian bits set to indicate
+/// valid cores.
+uint32_t
+core_configuration(void);
+
+
+#endif // __ASSEMBLER__
+
+
+/// \defgroup pgp_cfam_chip_types PGP CFAM Chip Types (Including Centaur)
+///
+/// The CFAM Chip Type is an 8-bit value that uniquely identfies a chip
+/// architecture.
+///
+/// @{
+
+#define CFAM_CHIP_TYPE_CENTAUR 0xe9
+#define CFAM_CHIP_TYPE_VENICE 0xea
+#define CFAM_CHIP_TYPE_MURANO 0xef
+
+/// @}
+
+
+/// \defgroup pgp_cfam_chip_ids PGP CFAM Chip Ids (Including Centaur)
+///
+/// The CFAM Chip ID is a 32-bit value that uniquely identfies a chip and its
+/// EC level.
+///
+/// The reference:
+///
+/// - https://eclipz.pok.ibm.com/sys/ras/docs/cfam_ids.txt
+///
+/// The interpretation:
+///
+/// MlmCC049
+///
+/// M - Major EC (RIT-A) level
+/// l - 2:Austin, 6:Poughkeepsie
+/// m - Minor EC (RIT-B) level
+/// CC - 0xE9:Centaur, 0xEA:Venice, 0xEF:Murano
+/// 049 - IBM (Except for buggy 0x001 in Murano DD1.X)
+///
+/// @{
+
+#define CFAM_CHIP_ID_VENICE_10 0x120ea049
+#define CFAM_CHIP_ID_VENICE_20 0x220ea049
+#define CFAM_CHIP_ID_VENICE_21 0x221ea049
+
+#define CFAM_CHIP_ID_MURANO_10 0x120ef001
+#define CFAM_CHIP_ID_MURANO_11 0x121ef001
+#define CFAM_CHIP_ID_MURANO_12 0x122ef001
+#define CFAM_CHIP_ID_MURANO_13 0x123ef001
+#define CFAM_CHIP_ID_MURANO_20 0x220ef049
+#define CFAM_CHIP_ID_MURANO_21 0x221ef049
+
+#define CFAM_CHIP_ID_CENTAUR_10 0x160e9049
+#define CFAM_CHIP_ID_CENTAUR_20 0x260e9049
+
+
+#ifndef __ASSEMBLER__
+
+/// The CFAM ID as a set of fields
+
+typedef union {
+#ifdef _BIG_ENDIAN
+ struct {
+ uint32_t majorEc : 4;
+ uint32_t location : 4;
+ uint32_t minorEc : 4;
+ uint32_t chipType : 8;
+ uint32_t vendor : 12;
+ };
+#else
+ struct {
+ uint32_t vendor : 12;
+ uint32_t chipType : 8;
+ uint32_t minorEc : 4;
+ uint32_t location : 4;
+ uint32_t majorEc : 4;
+ };
+#endif // _BIG_ENDIAN
+ uint32_t value;
+
+} cfam_id_t;
+
+#endif // __ASSEMBLER__
+
+/// @}
+
+#endif // __PGP_ID_H__
diff --git a/src/ssx/pgp/pgp_init.c b/src/ssx/pgp/pgp_init.c
new file mode 100755
index 0000000..4e28014
--- /dev/null
+++ b/src/ssx/pgp/pgp_init.c
@@ -0,0 +1,340 @@
+// $Id: pgp_init.c,v 1.2 2014/03/14 16:34:34 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_init.c
+/// \brief SSX initialization for PgP
+///
+/// The entry points in this routine are used during initialization. This
+/// code space can be deallocated and reassigned after application
+/// initialization if required.
+
+#include "ssx.h"
+#include "pgp_vrm.h"
+#include "simics_stdio.h"
+#include "string_stream.h"
+
+#if USE_RTX_IO
+// This file is not avilable to OCC FW builds
+#include "rtx_stdio.h"
+#endif
+
+// We need to make sure that the PLB arbiter is set up correctly to obtain
+// highest performance in the PgP environment, and that PLB error reporting is
+// appropriate.
+
+// The PLB arbiter is configured to support fair arbitration of equal-priority
+// requests, however we don't set priorities here. The default settings have
+// been found to be acceptible so far. We do enable arbiter pipelining however.
+
+// We do set the "plbarb_lockerr" bit so that the PLB arbiter will trap and
+// hold the first PLB timeout address.
+
+static void
+plb_arbiter_setup()
+{
+ plb_pacr_t pacr;
+ ocb_ocichsw_t oo;
+
+ pacr.value = 0;
+ pacr.fields.ppm = 1; /* Fair arbitration */
+ pacr.fields.hbu = 1; /* High bus utilization */
+ pacr.fields.rdp = 1; /* 2-deep read pipelining */
+ pacr.fields.wrp = 1; /* 2-deep write pipelining */
+ mtdcr(PLB_PACR, pacr.value);
+
+ oo.value = in32(OCB_OCICHSW);
+ oo.fields.plbarb_lockerr = 1;
+ out32(OCB_OCICHSW, oo.value);
+}
+
+
+#if PPC405_MMU_SUPPORT
+
+#include "ppc405_mmu.h"
+
+// MMU regions
+//
+// The linker script provides a standard set of symbols that define the base
+// address and size of each expected section. Any section with a non-0 size
+// will be mapped in the MMU using protection attributes appropriate for the
+// section. All sections requiring different MMU attributes must be
+// 1KB-aligned. The OCI control register space is fixed and also mapped by
+// the same mechanism.
+//
+// By default, caching is enabled for all sections other than the sections
+// explicitly cache-inhibited. Configuration options are provided to disable
+// caching of text, data and both. Note that sections that (may) contain code
+// and data will be marked cache-inhibited if either text or data is globally
+// configured as cache-inhibited. Also note that "writethrough" can only be
+// defined on cacheable data sections.
+
+#ifdef CACHE_INHIBIT_ALL
+#define CACHE_INHIBIT_TEXT 1
+#define CACHE_INHIBIT_DATA 1
+#endif
+
+#if CACHE_INHIBIT_TEXT
+#define TEXT_CACHEABILITY_FLAG TLBLO_I
+#else
+#define TEXT_CACHEABILITY_FLAG 0
+#endif
+
+#if CACHE_INHIBIT_DATA
+#define DATA_CACHEABILITY_FLAG TLBLO_I
+#define WRITETHROUGH_FLAG 0
+#else
+#define DATA_CACHEABILITY_FLAG 0
+#define WRITETHROUGH_FLAG TLBLO_W
+#endif
+
+
+// This structure contains all of the fields necessary to create a MMU
+// mapping.
+
+typedef struct {
+ SsxAddress base;
+ size_t size;
+ uint32_t tlbhi_flags;
+ uint32_t tlblo_flags;
+ Ppc405MmuMap* map;
+} MmuRegion;
+
+// The section table along with (default) MMU characteristics. Global
+// Ppc405MmuMap variables are defined for certain sections so that those
+// mappings may be later modified.
+
+Ppc405MmuMap G_ex_free_mmu_map;
+Ppc405MmuMap G_applet0_mmu_map;
+Ppc405MmuMap G_applet1_mmu_map;
+
+static const MmuRegion mmu_regions[] = {
+
+ {(SsxAddress)&_TEXT0_SECTION_BASE,
+ (size_t)&_TEXT0_SECTION_SIZE,
+ 0, TEXT_CACHEABILITY_FLAG | TLBLO_EX, 0} ,
+
+ {(SsxAddress)&_TEXT1_SECTION_BASE,
+ (size_t)&_TEXT1_SECTION_SIZE,
+ 0, TEXT_CACHEABILITY_FLAG | TLBLO_EX, 0} ,
+
+ {(SsxAddress)&_RODATA_SECTION_BASE,
+ (size_t)&_RODATA_SECTION_SIZE,
+ 0, DATA_CACHEABILITY_FLAG, 0} ,
+
+ {(SsxAddress)&_NONCACHEABLE_RO_SECTION_BASE,
+ (size_t)&_NONCACHEABLE_RO_SECTION_SIZE,
+ 0, TLBLO_I, 0} ,
+
+ {(SsxAddress)&_NONCACHEABLE_SECTION_BASE,
+ (size_t)&_NONCACHEABLE_SECTION_SIZE,
+ 0, TLBLO_I | TLBLO_WR, 0} ,
+
+ {(SsxAddress)&_WRITETHROUGH_SECTION_BASE,
+ (size_t)&_WRITETHROUGH_SECTION_SIZE,
+ 0, DATA_CACHEABILITY_FLAG | WRITETHROUGH_FLAG | TLBLO_WR, 0} ,
+
+ {(SsxAddress)&_DATA_SECTION_BASE,
+ (size_t)&_DATA_SECTION_SIZE,
+ 0, DATA_CACHEABILITY_FLAG | TLBLO_WR, 0} ,
+
+ {(SsxAddress)&_EX_FREE_SECTION_BASE,
+ (size_t)&_EX_FREE_SECTION_SIZE,
+ 0, DATA_CACHEABILITY_FLAG | TEXT_CACHEABILITY_FLAG | TLBLO_EX | TLBLO_WR,
+ &G_ex_free_mmu_map},
+
+ {(SsxAddress)&_APPLET0_SECTION_BASE,
+ (size_t)&_APPLET0_SECTION_SIZE,
+ 0, DATA_CACHEABILITY_FLAG | TEXT_CACHEABILITY_FLAG | TLBLO_WR | TLBLO_EX,
+ &G_applet0_mmu_map},
+
+ {(SsxAddress)&_APPLET1_SECTION_BASE,
+ (size_t)&_APPLET1_SECTION_SIZE,
+ 0, DATA_CACHEABILITY_FLAG | TEXT_CACHEABILITY_FLAG | TLBLO_WR | TLBLO_EX,
+ &G_applet1_mmu_map},
+
+ {(SsxAddress)OCI_REGISTER_SPACE_BASE,
+ (size_t)OCI_REGISTER_SPACE_SIZE,
+ 0, TLBLO_WR | TLBLO_I | TLBLO_G, 0} ,
+};
+
+/// PgP MMU setup
+///
+/// Run down the mmu_regions[] array and map all regions with non-0 sizes.
+/// These are direct maps, setting the effective address to the physical
+/// address. Once the MMU is set up MMU protection is enabled.
+///
+/// Any OCC mappings of PBA space will have to be done elsewhere, as these
+/// memory areas are controlled by pHyp, and the product firmware has no plans
+/// to access main memory from the OCC.
+
+static void
+pgp_mmu_setup()
+{
+ int i, regions;
+
+ ppc405_mmu_reset();
+
+ regions = sizeof(mmu_regions) / sizeof(MmuRegion);
+ for (i = 0; i < regions; i++) {
+ if (mmu_regions[i].size != 0) {
+ ppc405_mmu_map(mmu_regions[i].base,
+ mmu_regions[i].base,
+ mmu_regions[i].size,
+ mmu_regions[i].tlbhi_flags,
+ mmu_regions[i].tlblo_flags,
+ mmu_regions[i].map);
+ }
+ }
+
+ ppc405_mmu_start();
+}
+
+#endif /* PPC405_MMU_SUPPORT */
+
+
+// I/O Initialization
+//
+// Initialize the SSX/Simics/Verification Serial I/O channels. This is done
+// early in the initialization to allow initialization code to use printk().
+// If the application does not select one of the I/O methods then 'ssxout'
+// defaults to the NULL stream and 'stdin', 'stdout' and 'stderr' are
+// undefined.
+
+#if USE_TRACE_IO || USE_EPM_IO
+
+WrappingStream G_ssxout
+SECTION_ATTRIBUTE(".noncacheable") = {{0}};
+
+uint8_t G_ssxout_buffer[SSXOUT_TRACE_BUFFER_SIZE]
+SECTION_ATTRIBUTE(".noncacheable") = {0};
+
+#endif // USE_TRACE_IO || USE_EPM_IO
+
+static void
+io_setup()
+{
+ //NB: These I/O options are listed in priority order - multiple options may
+ //be selected.
+#if USE_TRACE_IO
+
+ // If the application chooses to use trace buffer output, the application
+ // must define SSXOUT_TRACE_BUFFER_SIZE, and all output streams are merged
+ // into a single trace buffer which locks low-level file operations in an
+ // SSX_CRITICAL critical secton.
+
+ /// \todo Split trace I/O mode into multiple streams
+
+ wrapping_stream_create(&G_ssxout, &G_ssxout_buffer,
+ SSXOUT_TRACE_BUFFER_SIZE,
+ SSX_FILE_OP_LOCK_CRITICAL);
+
+ stdout = (FILE *)(&G_ssxout);
+ stderr = (FILE *)(&G_ssxout);
+ ssxout = (FILE *)(&G_ssxout);
+
+#elif USE_EPM_IO
+
+ linear_stream_create(&G_ssxout, &G_ssxout_buffer,
+ SSXOUT_TRACE_BUFFER_SIZE,
+ SSX_FILE_OP_LOCK_CRITICAL);
+
+ stdout = (FILE *)(&G_ssxout);
+ stderr = (FILE *)(&G_ssxout);
+ ssxout = (FILE *)(&G_ssxout);
+
+#elif USE_RTX_IO
+
+ rtx_stdin_create(&rtx_stdin);
+ rtx_stdout_create(&rtx_stdout);
+ rtx_stderr_create(&rtx_stderr);
+
+ stdin = (FILE *)(&rtx_stdin);
+ stdout = (FILE *)(&rtx_stdout);
+ stderr = (FILE *)(&rtx_stderr);
+ ssxout = (FILE *)(&rtx_stdout);
+
+ printf("Initialize the RTX stdio.\n");
+ printf("RTX stdin is not implemented.\n");
+
+#elif USE_SIMICS_IO
+
+ simics_stdin_create(&simics_stdin);
+ simics_stdout_create(&simics_stdout);
+ simics_stderr_create(&simics_stderr);
+
+ stdin = (FILE *)(&simics_stdin);
+ stdout = (FILE *)(&simics_stdout);
+ stderr = (FILE *)(&simics_stderr);
+ ssxout = (FILE *)(&simics_stdout);
+
+#endif // I/O Configuration
+}
+
+
+/// PgP environment initial setup.
+///
+/// This is setup common to all PgP applications. This setup takes place
+/// during boot, before main() is called.
+
+void
+__pgp_setup()
+{
+ // All OCB interrupts are masked. The SSX/PPC405 Boot code masks PPC405
+ // PIT, FIT, and Watchdog interrupts. All interrupts are also initially
+ // set up as noncritical, non-debugged, edge-triggered, active-high, and
+ // their status is cleared. This clarifies IPL debugging as it eliminates
+ // spurious "asserted" interrupts until the firmware comes in and actually
+ // sets up the interrupt.
+
+ out32(OCB_OIMR0, 0xffffffff); /* Masked */
+ out32(OCB_OIMR1, 0xffffffff);
+ out32(OCB_OITR0, 0xffffffff); /* Edge */
+ out32(OCB_OITR1, 0xffffffff);
+ out32(OCB_OIEPR0, 0xffffffff); /* Active High */
+ out32(OCB_OIEPR1, 0xffffffff);
+ out32(OCB_OCIR0, 0); /* Noncritical */
+ out32(OCB_OCIR1, 0);
+ out32(OCB_OISR0_AND, 0); /* Clear Status */
+ out32(OCB_OISR1_AND, 0);
+ out32(OCB_OUDER0, 0); /* No Unconditional Debug Event */
+ out32(OCB_OUDER1, 0);
+ out32(OCB_ODHER0, 0); /* No Debug Halt Event */
+ out32(OCB_ODHER1, 0);
+
+ // Setup requires SCOM, which requires a timeout. Therefore we need to set
+ // up a default timebase frequency, which may be overridden during
+ // ssx_initialize().
+
+ __ssx_timebase_frequency_hz = 600000000;
+ __ssx_timebase_frequency_khz = 600000;
+ __ssx_timebase_frequency_mhz = 600;
+
+ // Set up I/O. This is done early in the initialization so that
+ // initialization drivers can use printk().
+
+ io_setup();
+
+ // Cache the device identification and chip configuration
+ _pgp_get_ids();
+ _pgp_get_chip_configuration();
+
+ // Set up the PLB arbiter
+
+ plb_arbiter_setup();
+
+ // If the MMU is enabled the base image MMU programming is set up, and the
+ // MMU is activated.
+
+#if PPC405_MMU_SUPPORT
+ pgp_mmu_setup();
+#endif
+
+ // The PgP Async drivers are initialized.
+
+ async_initialize();
+}
diff --git a/src/ssx/pgp/pgp_irq.h b/src/ssx/pgp/pgp_irq.h
new file mode 100755
index 0000000..f45ed52
--- /dev/null
+++ b/src/ssx/pgp/pgp_irq.h
@@ -0,0 +1,252 @@
+#ifndef __PGP_IRQ_H__
+#define __PGP_IRQ_H__
+
+// $Id: pgp_irq.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_irq.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_irq.h
+/// \brief PPC405-PgP Interrupt handling for SSX
+///
+/// The PgP 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 PGP 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 PGP interrupt
+/// controller contains a 'mask' register, unlike other 405 interrupt
+/// controllers that have an 'enable' register. The PgP mask and status
+/// registers also have atomic AND/OR function so that it is never necessary
+/// to enter a critical section to enable/disable/clear interrupts and
+/// interrupt status.
+
+#include "pgp_common.h"
+#include "ocb_register_addresses.h"
+
+#ifndef __ASSEMBLER__
+
+/// Enable an interrupt by clearing the mask bit.
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+inline void
+ssx_irq_enable(SsxIrqId irq)
+{
+ out32(OCB_OIMR_AND(irq), ~PGP_IRQ_MASK32(irq));
+}
+
+
+/// Disable an interrupt by setting the mask bit.
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+inline void
+ssx_irq_disable(SsxIrqId irq)
+{
+ out32(OCB_OIMR_OR(irq), PGP_IRQ_MASK32(irq));
+}
+
+
+/// Clear interrupt status with an AND mask. Only meaningful for
+/// edge-triggered interrupts.
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+inline void
+ssx_irq_status_clear(SsxIrqId irq)
+{
+ out32(OCB_OISR_AND(irq), ~PGP_IRQ_MASK32(irq));
+}
+
+
+/// Get IRQ status as a 0 or non-0 integer
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+inline int
+ssx_irq_status_get(SsxIrqId irq)
+{
+ return (in32(OCB_OISR(irq)) & PGP_IRQ_MASK32(irq)) != 0;
+}
+
+
+/// Set or clear interrupt status explicitly.
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+inline void
+ssx_irq_status_set(SsxIrqId irq, int value)
+{
+ if (value) {
+ out32(OCB_OISR_OR(irq), PGP_IRQ_MASK32(irq));
+ } else {
+ out32(OCB_OISR_AND(irq), ~PGP_IRQ_MASK32(irq));
+ }
+}
+
+
+void
+ssx_irq_debug_set(SsxIrqId irq, int value);
+
+#endif /* __ASSEMBLER__ */
+
+/// \page pgp_irq_macros PgP IRQ API Assembler Macros
+///
+/// These macros encapsulate the SSX API for the PgP interrupt
+/// controller. These macros require 2 scratch registers in addition to the \c
+/// irq parameter register passed into the handler from SSX interrupt
+/// dispatch. These macros also modift CR0.
+///
+/// \arg \c rirq A register that holds the \c irq parameter passed to
+/// the handler from SSX 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 _ssx_irq_enable \a rirq, \a rmask, \a raddr - Enable an \c irq. \n
+/// \b _ssx_irq_disable \a rirq, \a rmask, \a raddr - Disable an \c irq. \n
+/// \b _ssx_irq_status_clear \a rirq, \a rmask, \a raddr - Clear \c irq
+/// interrupt status. \n
+/// \b _ssx_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 _pgp_irq_or_mask, rirq:req, rmask:req
+ .two_unique \rirq, \rmask
+ lis \rmask, 0x8000
+ srw \rmask, \rmask, \rirq
+ .endm
+
+ .macro _pgp_irq_and_mask, rirq:req, rmask:req
+ .two_unique \rirq, \rmask
+ _pgp_irq_or_mask \rirq, \rmask
+ not \rmask, \rmask
+ .endm
+
+
+ .macro _ssx_irq_enable, rirq:req, rmask:req, raddr:req
+ .three_unique \rirq, \rmask, \raddr
+
+ andi. \raddr, \rirq, 0x20
+ clrlwi \raddr, \rirq, 27
+ _pgp_irq_and_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OIMR0_AND
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OIMR1_AND
+999:
+ eieio
+ .endm
+
+
+ .macro _ssx_irq_disable, rirq:req, rmask:req, raddr:req
+ .three_unique \rirq, \rmask, \raddr
+
+ andi. \raddr, \rirq, 0x20
+ clrlwi \raddr, \rirq, 27
+ _pgp_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 _ssx_irq_status_clear, rirq:req, rmask:req, raddr:req
+ .three_unique \rirq, \rmask, \raddr
+
+ andi. \raddr, \rirq, 0x20
+ clrlwi \raddr, \rirq, 27
+ _pgp_irq_and_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OISR0_AND
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OISR1_AND
+999:
+ eieio
+ .endm
+
+
+ .macro _ssx_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
+ _pgp_irq_or_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OISR0_OR
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OISR1_OR
+
+ .else
+
+ _pgp_irq_and_mask \raddr, \rmask
+ bne- 888f
+ _stwi \rmask, \raddr, OCB_OISR0_AND
+ b 999f
+888:
+ _stwi \rmask, \raddr, OCB_OISR1_AND
+ .endif
+
+999:
+ eieio
+ .endm
+
+#endif /* __ASSEMBLER__ */
+
+/// \endcond
+
+#endif /* __PGP_IRQ_H__ */
diff --git a/src/ssx/pgp/pgp_irq_init.c b/src/ssx/pgp/pgp_irq_init.c
new file mode 100755
index 0000000..6719766
--- /dev/null
+++ b/src/ssx/pgp/pgp_irq_init.c
@@ -0,0 +1,155 @@
+// $Id: pgp_irq_init.c,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_irq_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_irq_init.c
+/// \brief PGP IRQ initialization code for SSX
+///
+/// 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 "ssx.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 SSX allows this API to be called from any context, and changes
+/// to the interrupt controller are made from an SSX_CRITICAL critical
+/// section.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_IRQ_SETUP One or more arguments are invalid,
+/// including an invalid \a irq, or invalid \a polarity or \a trigger parameters.
+
+int
+ssx_irq_setup(SsxIrqId irq,
+ int polarity,
+ int trigger)
+{
+ SsxMachineContext ctx;
+ uint32_t oitr, oeipr;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(!PGP_IRQ_VALID(irq) ||
+ !((polarity == SSX_IRQ_POLARITY_ACTIVE_HIGH) ||
+ (polarity == SSX_IRQ_POLARITY_ACTIVE_LOW)) ||
+ !((trigger == SSX_IRQ_TRIGGER_LEVEL_SENSITIVE) ||
+ (trigger == SSX_IRQ_TRIGGER_EDGE_SENSITIVE)),
+ SSX_INVALID_ARGUMENT_IRQ_SETUP);
+ }
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ oeipr = in32(OCB_OIEPR(irq));
+ if (polarity == SSX_IRQ_POLARITY_ACTIVE_HIGH) {
+ out32(OCB_OIEPR(irq), oeipr | PGP_IRQ_MASK32(irq));
+ } else {
+ out32(OCB_OIEPR(irq), oeipr & ~PGP_IRQ_MASK32(irq));
+ }
+
+ oitr = in32(OCB_OITR(irq));
+ if (trigger == SSX_IRQ_TRIGGER_EDGE_SENSITIVE) {
+ out32(OCB_OITR(irq), oitr | PGP_IRQ_MASK32(irq));
+ } else {
+ out32(OCB_OITR(irq), oitr & ~PGP_IRQ_MASK32(irq));
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// (Re)define the IRQ handler and priority for an interrupt.
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// Note that SSX allows this API to be called from any context, and changes
+/// to the interrupt controller are made from an SSX_CRITICAL critical
+/// section.
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_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
+ssx_irq_handler_set(SsxIrqId irq,
+ SsxIrqHandler handler,
+ void *arg,
+ int priority)
+{
+ SsxMachineContext ctx;
+ uint32_t ocir;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(!PGP_IRQ_VALID(irq) ||
+ (handler == 0) ||
+ !((priority == SSX_NONCRITICAL) ||
+ (priority == SSX_CRITICAL)),
+ SSX_INVALID_ARGUMENT_IRQ_HANDLER);
+ }
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ ocir = in32(OCB_OCIR(irq));
+ if (priority == SSX_CRITICAL) {
+ out32(OCB_OCIR(irq), ocir | PGP_IRQ_MASK32(irq));
+ } else {
+ out32(OCB_OCIR(irq), ocir & ~PGP_IRQ_MASK32(irq));
+ }
+
+ __ppc405_irq_handlers[irq].handler = handler;
+ __ppc405_irq_handlers[irq].arg = arg;
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// Set or clear interrupt debug mode explicitly.
+
+void
+ssx_irq_debug_set(SsxIrqId irq, int value)
+{
+ SsxMachineContext ctx;
+ uint32_t ouder;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ ouder = in32(OCB_OUDER(irq));
+ if (value) {
+ out32(OCB_OUDER(irq), ouder | PGP_IRQ_MASK32(irq));
+ } else {
+ out32(OCB_OUDER(irq), ouder & ~PGP_IRQ_MASK32(irq));
+ }
+
+ ssx_critical_section_exit(&ctx);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ssx/pgp/pgp_ocb.c b/src/ssx/pgp/pgp_ocb.c
new file mode 100755
index 0000000..e39475e
--- /dev/null
+++ b/src/ssx/pgp/pgp_ocb.c
@@ -0,0 +1,335 @@
+// $Id: pgp_ocb.c,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_ocb.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_ocb.c
+/// \brief OCB-related drivers for PgP
+
+#include "ssx.h"
+
+//use compile-time default in case the OCB timer is never used -- grm
+unsigned int g_ocb_timer_divider = OCB_TIMER_DIVIDER_DEFAULT;
+
+/// Reset an OCB timer
+///
+/// \param timer A valid OCB timer index
+///
+/// \param auto_reload A non-0 value indicates to run the timer in auto-reload
+/// mode.
+///
+/// \param timeout_ns The timeout specified in nanoseconds. The actual timeout
+/// will be rounded down to the underlying timer tick, with a minimum 1 tick
+/// timeout. However if the \a timeout_ns argument is explicity 0, then the
+/// timer wil be initialized with a 0 timeout, effectively disabling the
+/// timer.
+///
+/// Reseting an OCB timer means rewriting the timer control register with a
+/// potentially new auto-reload enable and new timeout value. This API also
+/// clears any pending timer interrupt status.
+///
+/// \retval 0 Success
+///
+/// \retval -OCB_INVALID_ARGUMENT_TIMER Causes include illegal timer
+/// numbers and illegal or unrepresntable timeouts.
+
+// Note that OCB_TIMER_FREQUENCY_HZ is in the range of 1-2 MHz.
+
+int
+ocb_timer_reset(int timer,
+ int auto_reload,
+ int timeout_ns)
+{
+ ocb_otrn_t otr;
+ int ticks;
+
+ //printk("ocb_timer_reset(%d, %d, %d)\n",
+ // timer, auto_reload, timeout_ns);
+
+ if (timeout_ns != 0) {
+ ticks = MAX(1, timeout_ns / (1000000000 / OCB_TIMER_FREQUENCY_HZ));
+ } else {
+ ticks = 0;
+ }
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((timer < 0) ||
+ (timer >= OCB_TIMERS) ||
+ (timeout_ns < 0) ||
+ (ticks != ((uint16_t)ticks)),
+ OCB_INVALID_ARGUMENT_TIMER);
+ }
+
+ otr.value = 0;
+
+ otr.fields.timeout = 1;
+ otr.fields.control = 1;
+ otr.fields.auto_reload = (auto_reload != 0);
+ otr.fields.timer = ticks;
+
+ out32(OCB_OTRN(timer), otr.value);
+
+ return 0;
+}
+
+
+/// Set up an OCB timer and interrupt handler
+///
+/// \param timer A valid OCB timer index
+///
+/// \param auto_reload A non-0 value indicates to run the timer in auto-reload
+/// mode.
+///
+/// \param timeout_ns The timeout specified in nanoseconds. The actual timeout
+/// will rounded down to the underlying timer tick, with a minimum 1 tick
+/// timeout. However if the \a timeout_ns argument is explicity 0, then the
+/// timer wil be initialized with a 0 timeout, effectively disabling the
+/// timer.
+///
+/// \param handler The interrupt handler for the timer interrupt
+///
+/// \param arg The private argument of the interrupt handler
+///
+/// \param priority The SSX/PPC405 interrupt priority to assign to the
+/// interrupt.
+///
+/// This API sets up and starts the timer and unmasks the timer
+/// interrupt. Once set up, the timer can be reset using ocb_timer_reset(). As
+/// a fine point of the specification, if a timer interrupt is already pending
+/// when this API is invoked then that interrupt will be cleared. Only the
+/// next interrupt (corresponding to the new programming) will be serviced by
+/// the newly installed handler.
+///
+/// Note that the interrupt handler is responsible for clearing the timer
+/// interrupt status. An API ocb_timer_status_clear() is available for this.
+///
+/// \retval 0 Success
+///
+/// \retval -OCB_INVALID_ARGUMENT_TIMER Causes include illegal timer
+/// numbers and illegal or unrepresntable timeouts.
+///
+/// Other errors may be returned by the underlying calls to SSX routines that
+/// set up interrupts.
+
+int
+ocb_timer_setup(int timer,
+ int auto_reload,
+ int timeout_ns,
+ SsxIrqHandler handler,
+ void *arg,
+ int priority)
+{
+ int rc;
+ tpc_hpr2_t l_hpr2;
+
+ do
+ {
+ //Read Hang Pulse Register 2 to get the log base 2 of the ocb clock divider -- grm
+ rc = getscom(TPC_HPR2, &l_hpr2.value);
+ if(rc)
+ {
+ break;
+ }
+
+ g_ocb_timer_divider = 1 << l_hpr2.fields.hang_pulse_reg;
+
+ //printk("ocb_timer_setup(%d, %d, %d, %p, %p, %d)\n",
+ // timer, auto_reload, timeout_ns,
+ // handler, arg, priority);
+
+ ssx_irq_disable(PGP_IRQ_OCC_TIMER0 + timer);
+
+ ssx_irq_setup(PGP_IRQ_OCC_TIMER0 + timer,
+ SSX_IRQ_POLARITY_ACTIVE_HIGH,
+ SSX_IRQ_TRIGGER_LEVEL_SENSITIVE);
+
+ ssx_irq_handler_set(PGP_IRQ_OCC_TIMER0 + timer,
+ handler,
+ arg,
+ priority);
+
+ rc = ocb_timer_reset(timer, auto_reload, timeout_ns);
+
+ ssx_irq_enable(PGP_IRQ_OCC_TIMER0 + timer);
+ }while(0);
+
+ return rc;
+}
+
+
+/// Generate an core interrupt via the PSI Host Bridge
+///
+/// Setting OCB_OCCMISC.core_ext_int to 1 causes a wire to pulse to the PSI
+/// Host Bridge to allow the presentation of an external interrupt to a core
+/// thread. The core thread to be interrupted is controlled by the XIVR - OCC
+/// register, SCOM 02010916. Normally the hypervisor will set up the PSI Host
+/// Bridge. This procedure allows OCC to send an interrupt to the hypervisor.
+///
+/// \retval 0 Success
+
+// The interrupt is generated by causing a 0->1 transation on
+// OCB_OCCMISC.core_ext_intr. This is implemented here using the WAND/WOR
+// forms of the register.
+
+int
+ocb_core_interrupt()
+{
+ ocb_occmisc_t oo;
+
+ oo.value = 0;
+ oo.fields.core_ext_intr = 1;
+ out32(OCB_OCCMISC_AND, ~oo.value);
+ out32(OCB_OCCMISC_OR, oo.value);
+
+ return 0;
+}
+
+
+/// Procedure to setup a linear window on an indirect channel
+///
+///
+/// Since the linear window access is restricted to the SRAM region of
+/// OCI space, Bits 0:4 of the base parameter are don't care and will be
+/// overwritten with b'11000'
+///
+///
+/// \todo double check SRAM region restriction
+///
+/// \param channel The indirect channel to use, in the range 0..2.
+///
+/// \param base The 32-bit PowerBus base address where the block starts. This
+/// address must be aligned to the \a log_size.
+///
+/// \param log_size The base 2 logarithm of the block size, in bytes. The
+/// minimum size is 8B (2**3), the maximum size is 32KB (2**15)
+///
+///
+/// \retval 0 Success
+///
+/// \retval OCB_INVALID_ARGUMENT_LW_INIT One or more of the parameter
+/// restrictions were violated.
+///
+/// \retval OCB_SCOM_ERROR An attempt to write a PBA SCOM register to set up
+/// the BARs produced a non-zero return code.
+
+int
+ocb_linear_window_initialize(int channel, uint32_t base, int log_size)
+{
+ uint32_t mask ;
+ ocb_ocblwcrn_t ocblwcrn;
+ ocb_ocblwsbrn_t ocblwsbrn;
+
+ // create mask for checking
+ mask = (0x1ull << log_size) - 1;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((channel < 0) ||
+ (channel > 2) ||
+ (log_size < OCB_LW_LOG_SIZE_MIN) ||
+ (log_size > OCB_LW_LOG_SIZE_MAX) ||
+ ((base & mask) != 0),
+ OCB_INVALID_ARGUMENT_LW_INIT);
+ }
+
+ // now invert mask for use in ocb linear window setup
+ mask = ~mask;
+
+
+ // Configure OCB Linear Write Control Register
+ ocblwcrn.fields.linear_window_enable = 1;
+ // base 13:28 (16 bits)
+ ocblwcrn.fields.linear_window_bar = (base >> 3) & 0xFFFF;
+ // mask 17:28 (12 bits)
+ ocblwcrn.fields.linear_window_mask = (mask >> 3) & 0xFFF;
+ out32(OCB_OCBLWCRN(channel), ocblwcrn.value);
+
+ // Configure OCB Linear Window Write Base Register
+ ocblwsbrn.fields.linear_window_region = 3; // SRAM only
+ // \todo: Are there constants for the OCI regions?
+ // base 2:9 (8 bits)
+ ocblwsbrn.fields.linear_window_base = (base >> 19) & 0xFF;
+ out32(OCB_OCBLWSBRN(channel), ocblwsbrn.value);
+
+ return 0 ;
+}
+
+/// Procedure to disable a linear window on an indirect channel
+///
+/// This procedure will disable the linear window while maintaining
+/// the linear_window_bar and linear_window_mask settings
+///
+/// \param channel The indirect channel to disable, in the range 0..2.
+///
+/// \retval 0 Success
+///
+/// \retval OCB_INVALID_ARGUMENT_LW_DISABLE One or more of the parameter
+/// restrictions were violated.
+///
+
+int
+ocb_linear_window_disable(int channel)
+{
+ ocb_ocblwcrn_t ocblwcrn;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((channel < 0) ||
+ (channel > 2),
+ OCB_INVALID_ARGUMENT_LW_DISABLE);
+ }
+
+ ocblwcrn.value = in32(OCB_OCBLWCRN(channel));
+ // Configure OCB Linear Write Control Register
+ ocblwcrn.fields.linear_window_enable = 0;
+ out32(OCB_OCBLWCRN(channel), ocblwcrn.value);
+
+ return 0 ;
+}
+
+
+/// Procedure for setting up untrusted mode for an indirect channel
+///
+/// Note that the OCC FW is expected to enable the channel for FSP
+/// access. As an untrusted master, the FSP cannot configure this
+/// in a chip running in trusted mode. The SBE is considered a trusted
+/// master.
+///
+///
+/// \param channel The indirect channel to use, in the range 0..2
+/// Note that this bit is not used for indirect channel 3.
+///
+///
+/// \param allow_untrusted Enable untrusted PIB masters
+/// access to the indirect channel being configured. If allow_untrusted is
+/// not enabled and the chip is running in trusted mode, then any untrusted
+/// PIB master will get an offline return code when attempting to write
+/// the indirect channel. 0 = Disable, 1 = Enable
+///
+/// \retval 0 Success
+///
+/// \retval OCB_INVALID_ARGUMENT_UNTRUST One or more of the parameter
+/// restrictions were violated.
+///
+
+
+int
+ocb_allow_untrusted_initialize(int channel, int allow_untrusted)
+{
+ ocb_ocbicrn_t ocbicrn;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((channel < 0) ||
+ (channel > 2) ||
+ (allow_untrusted < 0) ||
+ (allow_untrusted > 1),
+ OCB_INVALID_ARGUMENT_UNTRUST);
+ }
+
+ // Configure allow_unsecure_pib_masters bit
+ ocbicrn.fields.allow_unsecure_pib_masters = allow_untrusted;
+ out32(OCB_OCBICRN(channel), ocbicrn.value);
+
+ return 0 ;
+}
diff --git a/src/ssx/pgp/pgp_ocb.h b/src/ssx/pgp/pgp_ocb.h
new file mode 100755
index 0000000..fd36c9a
--- /dev/null
+++ b/src/ssx/pgp/pgp_ocb.h
@@ -0,0 +1,88 @@
+#ifndef __PGP_OCB_H__
+#define __PGP_OCB_H__
+
+// $Id: pgp_ocb.h,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_ocb.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_ocb.h
+/// \brief OCB unit header. Local and mechanically generated macros and APIs.
+
+#include "ssx.h"
+#include "ppc32.h"
+
+#include "pgp_common.h"
+#include "ocb_register_addresses.h"
+#include "ocb_firmware_registers.h"
+
+#include "ppc405_irq.h"
+
+#define OCB_TIMER0 0
+#define OCB_TIMER1 1
+
+#define OCB_TIMERS 2
+
+#define OCB_TIMER_ONE_SHOT 0
+#define OCB_TIMER_AUTO_RELOAD 1
+
+#define OCB_LW_LOG_SIZE_MIN 3
+#define OCB_LW_LOG_SIZE_MAX 15
+
+#define OCB_INVALID_ARGUMENT_TIMER 0x00622001
+#define OCB_INVALID_ARGUMENT_LW_INIT 0x00622002
+#define OCB_INVALID_ARGUMENT_LW_DISABLE 0x00622003
+#define OCB_INVALID_ARGUMENT_UNTRUST 0x00622004
+
+#ifndef __ASSEMBLER__
+
+int
+ocb_timer_reset(int timer,
+ int auto_reload,
+ int timeout_ns);
+
+#ifdef OCC
+int
+ocb_timer_setup(int timer,
+ int auto_reload,
+ int timeout_ns,
+ SsxIrqHandler handler,
+ void *arg,
+ int priority) INIT_SECTION;
+#else
+int
+ocb_timer_setup(int timer,
+ int auto_reload,
+ int timeout_ns,
+ SsxIrqHandler handler,
+ void *arg,
+ int priority);
+#endif
+
+/// Clear OCB timer status based on the IRQ
+///
+/// This API can be called from OCB timer interrupt handlers, using the IRQ
+/// provided to the handler. No error checks are provided.
+
+static inline void
+ocb_timer_status_clear(SsxIrqId irq)
+{
+ out32(OCB_OTRN(irq - PGP_IRQ_OCC_TIMER0), OCB_OTRN_TIMEOUT);
+}
+
+int
+ocb_linear_window_initialize(int channel, uint32_t base, int log_size);
+
+int
+ocb_linear_window_disable(int channel);
+
+int
+ocb_allow_untrusted_initialize(int channel, int allow_untrusted);
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PGP_OCB_H__ */
diff --git a/src/ssx/pgp/pgp_pba.c b/src/ssx/pgp/pgp_pba.c
new file mode 100755
index 0000000..0f5d2d9
--- /dev/null
+++ b/src/ssx/pgp/pgp_pba.c
@@ -0,0 +1,460 @@
+// $Id: pgp_pba.c,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_pba.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_pba.c
+/// \brief procedures for pba setup and operation.
+
+#include "ssx.h"
+#include "pgp_pba.h"
+#include "pgp_pmc.h"
+#include "pgp_common.h"
+#include "polling.h"
+
+
+// Internal API to set up a PBA BAR
+
+static int
+pba_bar_set(int idx, uint64_t pb_base, uint8_t pb_scope)
+{
+ int rc ;
+ pba_barn_t bar ;
+
+ bar.fields.cmd_scope = pb_scope ;
+ bar.fields.addr = pb_base >> PBA_LOG_SIZE_MIN ;
+
+ rc = putscom(PBA_BARN(idx), bar.value);
+
+ return rc ;
+}
+
+
+// Internal API to set up a PBA BAR Mask. The mask covers bits 23:43, address
+// bits 44:63 are always allowed.
+
+static int
+pba_barmask_set(int idx, uint64_t mask)
+{
+ int rc ;
+ pba_barmskn_t barmask ;
+
+ barmask.value = mask & 0x000001FFFFF00000ull;
+
+ rc = putscom(PBA_BARMSKN(idx), barmask.value);
+
+ return rc ;
+}
+
+
+/// Procedure to allocate a PowerBus address block using the bridge.
+///
+/// \param idx The BAR set to use, in the range 0..3.
+///
+/// \param base The 50-bit PowerBus base address where the block starts. This
+/// address must be aligned to the \a log_size.
+///
+/// \param log_size The base 2 logarithm of the block size, in bytes. The
+/// minimum size is 1MB (2**20), the maximum size is 2TB (2**41)
+///
+/// This is a validation/test procedure only, since setting up the PBA BARs is
+/// normally reserved to pHyp and FSP. If the MMU is enabled and the PBA
+/// mapping will be referenced by the 405, then an MMU mapping will also have
+/// to be created (separately) for the block.
+///
+/// This procedure is not the complete setup for large memory areas. Memory
+/// areas that require the extended address will have to set that up
+/// separately.
+///
+/// \retval 0 Success
+///
+/// \retval PBA_INVALID_ARGUMENT_BARSET One or more of the parameter
+/// restrictions were violated.
+///
+/// \retval PBA_SCOM_ERROR1 or PBA_SCOM_ERROR2 An attempt to write a PBA SCOM
+/// register to set up the BARs produced a non-zero return code.
+
+int
+pba_barset_initialize(int idx, uint64_t base, int log_size)
+{
+ uint64_t mask ;
+
+ mask = (0x1ull << log_size) - 1;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((idx < 0) ||
+ (idx > 3) ||
+ (log_size < PBA_LOG_SIZE_MIN) ||
+ (log_size > PBA_LOG_SIZE_MAX) ||
+ ((base & mask) != 0),
+ PBA_INVALID_ARGUMENT_BARSET);
+ }
+
+ if (pba_bar_set(idx, base, PBA_POWERBUS_COMMAND_SCOPE_DEFAULT)) {
+ SSX_ERROR(PBA_SCOM_ERROR1);
+ }
+ if (pba_barmask_set(idx, mask)) {
+ SSX_ERROR(PBA_SCOM_ERROR2);
+ }
+
+ return 0 ;
+}
+
+
+// polling() function for PBA Slave reset
+//
+// Slave reset for PBA is a complex issue, especially in cases where the
+// entity requesting the reset may be executing from main memory, i.e.
+// continuing to read to or write from the slave being reset. To work around
+// potential issues if the 405 is attempting to reset its own slave, the code
+// that polls for reset is PowerBus cache-line aligned, and we re-hit the
+// reset button each time we get an unsuccessful poll for the reset being
+// done. This should guarantee that the slave will go to reset status as soon
+// as any PowerBus blockages (if any) clear and the master stops either
+// reading or writing the slave port. For details see HW228485.
+int
+_pba_slave_reset_poll(void* arg, int* done) ALIGNED_ATTRIBUTE(128);
+
+int
+_pba_slave_reset_poll(void* arg, int* done)
+{
+ int id;
+ pba_slvrst_t psr;
+
+ id = (int)arg;
+
+ psr.value = 0;
+ psr.fields.set = PBA_SLVRST_SET(id);
+ out64(PBA_SLVRST, psr.value);
+
+ psr.value = in64(PBA_SLVRST);
+ *done = !(psr.fields.in_prog & PBA_SLVRST_IN_PROG(id));
+
+ return 0;
+}
+
+
+/// Reset a PBA slave with explicit timeout.
+///
+/// \param id A PBA slave id in the range 0..3
+///
+/// \param timeout A value of SsxInterval type. The special value
+/// SSX_WAIT_FOREVER indicates no timeout.
+///
+/// \param sleep A value of SsxInterval type. Callers using the explicit
+/// timeout form can request that the thread sleeps between polls; See
+/// documentation for the polling() API.
+///
+/// This form of pba_slave_reset() gives the caller control over timeouts,
+/// sleeping and error handling.
+///
+/// \retval 0 Success
+///
+/// \retval -PBA_INVALID_ARGUMENT_RESET The slave \a id parameter
+/// is invalid.
+///
+/// \retval -PBA_SLVRST_TIMED_OUT1 The procedure timed out waiting for the PBA
+/// to reset the slave.
+
+
+int
+_pba_slave_reset(int id, SsxInterval timeout, SsxInterval sleep)
+{
+ int rc, closureRc;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((id < 0) || (id >= PBA_SLAVES),
+ PBA_INVALID_ARGUMENT_RESET);
+ }
+
+ rc = polling(&closureRc, _pba_slave_reset_poll, (void*)id, timeout, sleep);
+ if (rc == POLLING_TIMEOUT) {
+ rc = -PBA_SLVRST_TIMED_OUT1;
+ }
+
+ return rc;
+}
+
+
+/// Reset a PBA slave with a default timeout
+///
+/// \param id A PBA slave id in the range 0..3
+///
+/// PBA slaves must be reset before being reprogrammed. Resetting a slave
+/// also flushes any write buffers and invalidates any read buffers associated
+/// with the slave. This procedure is for initialization/bringup/test only;
+/// it has a non-deterministic run time due to the PowerBus so should not be
+/// run as part of a hard real-time loop.
+///
+/// \retval 0 Success
+///
+/// \retval -SSX_INVALID_ARGUMENT_PBA_RESET The slave \a id parameter is
+/// invalid.
+///
+/// \retval -PBA_SLVRST_TIMED_OUT2 The procedure timed out waiting for the PBA
+/// to reset the slave.
+
+int
+pba_slave_reset(int id)
+{
+ int rc;
+
+ rc = _pba_slave_reset(id, PBA_SLAVE_RESET_TIMEOUT, 0);
+ if (rc) {
+ SSX_ERROR(PBA_SLVRST_TIMED_OUT2);
+ }
+
+ return rc;
+}
+
+
+/// Configure the PBAX mechanism
+///
+/// \param master If non-0, then this OCC will assume the role of the PBAX
+/// master processor in the power domain. To avoid PBAX livelock there can
+/// only be a single master in any power domain, and only the master is
+/// allowed to issue PBAX broadcast transactions.
+///
+/// \param node The PBAX Node Id of this OCC
+///
+/// \param chip The PBAX Chip Id of this OCC
+///
+/// \param group_mask A bit mask indicating the broadcast group(s) (power
+/// domain(s)) that this OCC belongs to.
+///
+/// This API sets up certain fields of the PBA_XCFG register according to the
+/// parameters. Other fields in the register controlling hardware timeouts and
+/// performance monitoring are unchanged.
+///
+/// \retval 0 Success
+///
+/// \retval -PBAX_INVALID_ARGUMENT_CONFIG One of the arguments is
+/// not valid for some reason.
+
+int
+pbax_configure(int master, int node, int chip, int group_mask)
+{
+ pba_xcfg_t pxc;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((node < 0) ||
+ (node >= PBAX_NODES) ||
+ (chip < 0) ||
+ (chip >= PBAX_CHIPS) ||
+ (group_mask < 0) ||
+ (group_mask > PBAX_GROUP_MASK_MAX),
+ PBAX_INVALID_ARGUMENT_CONFIG);
+ }
+ pxc.value = in64(PBA_XCFG);
+ pxc.fields.reservation_en = (master != 0);
+ pxc.fields.rcv_nodeid = node;
+ pxc.fields.rcv_chipid = chip;
+ pxc.fields.rcv_brdcst_group = group_mask;
+ out64(PBA_XCFG, pxc.value);
+ return 0;
+}
+
+
+/// Create a PBAX abstract target
+///
+/// \param target An uninitialized or otherwise idle PbaxTarget object
+///
+/// \param type The transmission type, either PBAX_UNICAST or PBAX_BROADCAST
+///
+/// \param scope The PowerBus scope, either PBAX_GROUP or PBAX_SYSTEM
+///
+/// \param queue The receive queue index on the target, either 0 or 1
+///
+/// \param node The PBAX Node Id of the target
+///
+/// \param chip_or_group Either the PBAX Chip Id of the target (for unicast),
+/// or the PBAX Group Id of the target (for broadcast)
+///
+/// Create an abstraction of a communication target for PBAX send operations,
+/// for use with the _pbax_send() and _pbax_send() APIs. This API has no
+/// knowledge of how the PBAX is configured, and therefore accepts all node,
+/// chip and broadcast group ids as valid. However this API does assume that
+/// all broadcast transactions are "real-time" and require a reservation.
+///
+/// \retval 0 Success
+///
+/// \retval -PBAX_INVALID_OBJECT The \a target parameter is NULL (0) or
+/// otherwise invalid.
+///
+/// \retval -PBAX_INVALID_ARGUMENT_TARGET One or more of the arguments
+/// is invalid.
+
+int
+pbax_target_create(PbaxTarget* target,
+ int type, int scope, int queue,
+ int node, int chip_or_group)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(target == 0, PBAX_INVALID_OBJECT);
+ SSX_ERROR_IF(((type != PBAX_UNICAST) && (type != PBAX_BROADCAST)) ||
+ ((scope != PBAX_GROUP) && (scope != PBAX_SYSTEM)) ||
+ ((queue < 0) || (queue >= PBAX_QUEUES)),
+ PBAX_INVALID_ARGUMENT_TARGET);
+ }
+
+ target->target.value = 0;
+ target->target.fields.snd_scope = scope;
+ target->target.fields.snd_qid = queue;
+ target->target.fields.snd_type = type;
+ target->target.fields.snd_reservation = (type == PBAX_BROADCAST);
+ target->target.fields.snd_nodeid = node;
+ target->target.fields.snd_chipid = chip_or_group;
+
+ return 0;
+}
+
+
+
+/// Use PBAX to send 64 bits to a target with a caller-specified timeout
+///
+/// \param target An abstract PBAX target object
+///
+/// \param data The data to send
+///
+/// \param timeout The caller's timeout represented as an
+/// SsxInterval. Use SSX_WAIT_FOREVER to indicate the caller is willing to
+/// wait forever. A \a timeout of 0 indicates that the caller is not
+/// willing to wait at all, and the call will either succeed immediately or
+/// immediately return -PBAX_TIMEOUT.
+///
+/// The PBAX mechanism has a single outgoing channel that must be shared by
+/// all processes that need to send messages using PBAX. Since messages sent
+/// over PBAX may require an unknown amount of time to complete (due to
+/// PowerBus traffic and blockages), this driver implements an agressive
+/// policy that allows a sender to initiate a send transaction without waiting
+/// for the final completion status. However this opens a window where a
+/// subsequent writer may find the PBAX send mechanism already in use. Here
+/// the new sender is obligated to busy-wait until the send mechanism is free,
+/// as the PBAX send does not include an interrupt notification.
+///
+/// This form of the PBAX send operation accepts an explicit \a timeout value
+/// as previously described. The timeout represents the amount of time that
+/// the caller is willing to wait for a busy PBAX send mechanism to become
+/// free. The PBAX hardware also includes mechanisms to time out the hardware
+/// and modeably interrupt OCC in the event of lack of progress.
+///
+/// <em> This API does not operate in a critical section or enforce any
+/// synchronization protocol. Synchronization and software timeout management
+/// in the case of multiple senders is the responsibility of the
+/// application. </em>
+///
+/// Unlike most other driver APIs this API can not be configured to "panic",
+/// but instead always terminates with a 0 return code or an error status.
+///
+/// \retval 0 Success. Success only means that a transaction was sucessfully
+/// initiated on an idle PBAX send machine.
+///
+/// \retval -PBAX_TIMEOUT The caller-specified timeout expired before the PBAX
+/// send machine became free, but the PBAX send machine does not show error
+/// status.
+///
+/// \retval -PBAX_SEND_ERROR The PBAXSNDSTAT.snd_error bit is asserted. It
+/// is expected that this error will cause the PBA error interrupt to fire -
+/// FFDC is collected by the interrupt handler.
+
+int
+_pbax_send(PbaxTarget* target, uint64_t data, SsxInterval timeout)
+{
+ pba_xsndstat_t pss;
+ SsxTimebase start;
+ int rc, timed_out;
+
+ // The PBAX is always polled at least twice to guarantee that we always
+ // poll once after a timeout - unless the caller explicitly requested a 0
+ // timeout.
+
+ start = 0;
+ timed_out = 0;
+ do {
+ pss.words.high_order = in32(PBA_XSNDSTAT);
+ if (pss.fields.snd_error) {
+ rc = -PBAX_SEND_ERROR;
+ break;
+ }
+ if (!pss.fields.snd_in_progress) {
+ rc = 0;
+ break;
+ }
+ if (start == 0) {
+ start = ssx_timebase_get();
+ }
+ if ((timeout == 0) || timed_out) {
+ rc = -PBAX_SEND_TIMEOUT;
+ break;
+ }
+ timed_out =
+ ((timeout != SSX_WAIT_FOREVER) &&
+ ((ssx_timebase_get() - start) > timeout));
+ } while (1);
+
+ // Configure the send engine and initiate the write, which is kicked off
+ // by writing the high-order word of the send data register.
+
+ if (!rc) {
+ out32(PBA_XSNDTX, target->target.words.high_order);
+ out32(PBA_XSNDDAT + 4, data & 0xffffffff);
+ out32(PBA_XSNDDAT, data >> 32);
+ }
+
+ return rc;
+}
+
+
+/// Use PBAX to send 64 bits to a target with a default timeout
+///
+/// \param target An abstract PBAX target object
+///
+/// \param data The data to send
+///
+/// This form of the PBAX send operation uses a default timeout, and may be
+/// configured to panic in the event of timeouts or send errors. See
+/// _pbax_send() for the specification of the underlying API.
+///
+/// <em> This API does not operate in a critical section or enforce any
+/// synchronization protocol. Synchronization and software timeout management
+/// in the case of multiple senders is the responsibility of the
+/// application. </em>
+///
+/// \retval 0 Success. Success only means that a transaction was sucessfully
+/// initiated on an idle PBAX send machine.
+///
+/// \retval -PBAX_TIMEOUT The caller-specified timeout expired before the PBAX
+/// send machine became free.
+///
+/// \retval -PBAX_SEND_ERROR The PBAXSNDSTAT.snd_error bit is asserted.
+
+int
+pbax_send(PbaxTarget* target, uint64_t data)
+{
+ int rc;
+
+ rc = _pbax_send(target, data, PBAX_SEND_DEFAULT_TIMEOUT);
+ if (rc) {
+ if (rc == -PBAX_SEND_TIMEOUT) {
+ SSX_ERROR(PBAX_SEND_TIMEOUT);
+ } else {
+ SSX_ERROR(PBAX_SEND_ERROR);
+ }
+ }
+ return rc;
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ssx/pgp/pgp_pba.h b/src/ssx/pgp/pgp_pba.h
new file mode 100755
index 0000000..647c334
--- /dev/null
+++ b/src/ssx/pgp/pgp_pba.h
@@ -0,0 +1,358 @@
+#ifndef __PGP_PBA_H__
+#define __PGP_PBA_H__
+
+// $Id: pgp_pba.h,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_pba.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_pba.h
+/// \brief PBA unit header. Local and mechanically generated macros.
+
+/// \todo Add Doxygen grouping to constant groups
+
+#include "pba_register_addresses.h"
+#include "pba_firmware_registers.h"
+
+#define POWERBUS_CACHE_LINE_SIZE 128
+#define LOG_POWERBUS_CACHE_LINE_SIZE 7
+
+/// The PBA OCI region is always either 0 or 3
+#define PBA_OCI_REGION 0
+
+// It is assumed the the PBA BAR sets will be assigned according to the
+// following scheme. There are still many open questions concerning PBA
+// setup.
+
+/// The number of PBA Base Address Registers (BARS)
+#define PBA_BARS 4
+
+#define PBA_BAR_CHIP 0
+#define PBA_BAR_NODE 2
+#define PBA_BAR_SYSTEM 3
+#define PBA_BAR_CENTAUR 1
+
+#define PBA_BAR_OCC 0 /* OCC image (HOMER) */
+#define PBA_BAR_PORE_SLW 2 /* Redundant mapping for SLW offset into HOMER */
+
+// Standard PBA slave assignments, set up by FAPI procedure prior to releasing
+// OCC from reset.
+
+/// The number of PBA slaves
+#define PBA_SLAVES 4
+
+#define PBA_SLAVE_PORE_GPE 0 /* GPE0/1, but only 1 can access mainstore */
+#define PBA_SLAVE_OCC 1 /* 405 I- and D-cache */
+#define PBA_SLAVE_PORE_SLW 2
+#define PBA_SLAVE_OCB 3
+
+/// The maximum number of bytes a PBA block-copy engine can transfer at once
+#define PBA_BCE_SIZE_MAX 4096
+
+/// The base-2 log of the minimum PBA translation window size in bytes
+#define PBA_LOG_SIZE_MIN 20
+
+/// The base-2 log of the maximum PBA translation window size in bytes
+///
+/// Note that windows > 2**27 bytes require the extended address.
+#define PBA_LOG_SIZE_MAX 41
+
+/// The number of PBA slaves
+#define PBA_SLAVES 4
+
+/// The number of PBA read buffers
+#define PBA_READ_BUFFERS 6
+
+/// The number of PBA write buffers
+#define PBA_WRITE_BUFFERS 2
+
+
+////////////////////////////////////
+// Macros for fields of PBA_SLVCTLn
+////////////////////////////////////
+
+// PBA write Ttypes
+
+#define PBA_WRITE_TTYPE_DMA_PR_WR 0x0 /// DMA Partial Write
+#define PBA_WRITE_TTYPE_LCO_M 0x1 /// L3 LCO for IPL, Tsize denotes chiplet.
+#define PBA_WRITE_TTYPE_ATOMIC_RMW 0x2 /// Atomic operations
+#define PBA_WRITE_TTYPE_CACHE_INJECT 0x3 /// Cache inject after IPL
+#define PBA_WRITE_TTYPE_CI_PR_W 0x4 /// Cache-inhibited partial write for Centaur putscom().
+
+#define PBA_WRITE_TTYPE_DC PBA_WRITE_TTYPE_DMA_PR_WR // Don't care
+
+
+// PBA write Tsize is only required for PBA_WRITE_TTYPE_LCO_M (where it
+// actually specifies a core chiplet id) and PBA_WRITE_TTYPE_ATOMIC_RMW.
+
+#define PBA_WRITE_TSIZE_CHIPLET(chiplet) (chiplet)
+
+#define PBA_WRITE_TSIZE_ARMW_ADD 0x03
+#define PBA_WRITE_TSIZE_ARMW_AND 0x13
+#define PBA_WRITE_TSIZE_ARMW_OR 0x23
+#define PBA_WRITE_TSIZE_ARMW_XOR 0x33
+
+#define PBA_WRITE_TSIZE_DC 0x0
+
+
+// PBA write gather timeouts are defined in terms of the number of 'pulses'. A
+// pulse occurs every 64 OCI cycles. The timing of the last write of a
+// sequence is variable, so the timeout will occur somewhere between (N - 1) *
+// 64 and N * 64 OCI cycles. If write gather timeouts are disabled, the PBA
+// holds the data until some condition occurs that causes it to disgorge the
+// data. Slaves using cache-inhibited partial write never gather write
+// data. Note from spec. : "Write gather timeouts must NOT be disabled if
+// multiple masters are enabled to write through the PBA". The only case
+// where write gather timeouts will be disabled is for the IPL-time injection
+// of data into the L3 caches. Note that disabling write-gathering timeouts is
+// different from disabling write-gathering altogether with the
+// SLVCTL.dis_write_gather setting.
+
+#define PBA_WRITE_GATHER_TIMEOUT_DISABLE 0x0
+#define PBA_WRITE_GATHER_TIMEOUT_2_PULSES 0x4
+#define PBA_WRITE_GATHER_TIMEOUT_4_PULSES 0x5
+#define PBA_WRITE_GATHER_TIMEOUT_8_PULSES 0x6
+#define PBA_WRITE_GATHER_TIMEOUT_16_PULSES 0x7
+
+/// PBA write gather timeout don't care assignment - see gpe_pba_parms_create()
+#define PBA_WRITE_GATHER_TIMEOUT_DC -1
+
+
+// PBA read Ttype
+
+#define PBA_READ_TTYPE_CL_RD_NC 0x0 /// Cache line read
+#define PBA_READ_TTYPE_CI_PR_RD 0x1 /// Cache-inhibited partial read for Centaur getscom().
+
+/// PBA read TTYPE don't care assignment
+#define PBA_READ_TTYPE_DC PBA_READ_TTYPE_CL_RD_NC
+
+
+// PBA read prefetch options
+
+#define PBA_READ_PREFETCH_AUTO_EARLY 0x0 /// Aggressive prefetch
+#define PBA_READ_PREFETCH_NONE 0x1 /// No prefetch
+#define PBA_READ_PREFETCH_AUTO_LATE 0x2 /// Non-aggressive prefetch
+
+/// PBA read prefetch don't care assignment - see gpe_pba_parms_create()
+#define PBA_READ_PREFETCH_DC -1
+
+
+// PBA PowerBus command scope and priority, and PBA defaults
+
+/// Nodal, Local Node
+#define POWERBUS_COMMAND_SCOPE_NODAL 0x0
+
+/// Group, Local 4-chip, (aka, node pump)
+#define POWERBUS_COMMAND_SCOPE_GROUP 0x1
+
+/// System, All units in the system
+#define POWERBUS_COMMAND_SCOPE_SYSTEM 0x2
+
+/// RGP, All units in the system (aka, system pump)
+#define POWERBUS_COMMAND_SCOPE_RGP 0x3
+
+/// Foreign, All units on the local chip, local SMP, and remote chip (pivot
+/// nodes), In P8, only 100 and 101 are valid.
+#define POWERBUS_COMMAND_SCOPE_FOREIGN0 0x4
+
+/// Foreign, All units on the local chip, local SMP, and remote chip (pivot
+/// nodes), In P8, only 100 and 101 are valid.
+#define POWERBUS_COMMAND_SCOPE_FOREIGN1 0x5
+
+
+/// Default command scope for BCDE/BCUE transfers
+#define PBA_POWERBUS_COMMAND_SCOPE_DEFAULT POWERBUS_COMMAND_SCOPE_NODAL
+
+
+
+// Abstract fields of the PBA Slave Reset register used in pba_slave_reset(),
+// which checks 'n' for validity.p
+
+#define PBA_SLVRST_SET(n) (4 + (n))
+#define PBA_SLVRST_IN_PROG(n) (0x8 >> (n))
+
+/// The default timeout for pba_slave_reset().
+///
+/// Currently the procedure pba_slave_reset() is thought to be an
+/// initialization-only and/or lab-only procedure, so this long polling
+/// timeout is not a problem.
+#ifndef PBA_SLAVE_RESET_TIMEOUT
+#define PBA_SLAVE_RESET_TIMEOUT SSX_MICROSECONDS(100)
+#endif
+
+
+// PBA Error/Panic codes
+
+#define PBA_SCOM_ERROR1 0x00722001
+#define PBA_SCOM_ERROR2 0x00722002
+#define PBA_SLVRST_TIMED_OUT1 0x00722003
+#define PBA_SLVRST_TIMED_OUT2 0x00722004
+#define PBA_INVALID_ARGUMENT_BARSET 0x00779005
+#define PBA_INVALID_ARGUMENT_RESET 0x00779006
+#define PBAX_INVALID_ARGUMENT_CONFIG 0x00779007
+#define PBAX_INVALID_ARGUMENT_TARGET 0x00779008
+#define PBAX_INVALID_OBJECT 0x00722009
+
+#ifndef __ASSEMBLER__
+
+/// The PBA extended address in the form of a 'firmware register'
+///
+/// The extended address covers only bits 23:36 of the 50-bit PowerBus address.
+
+typedef union pba_extended_address {
+
+ uint64_t value;
+ uint32_t word[2];
+ struct {
+ uint64_t reserved0 : 23;
+ uint64_t extended_address : 14;
+ uint64_t reserved1 : 27;
+ } fields;
+} pba_extended_address_t;
+
+
+int
+pba_barset_initialize(int idx, uint64_t base, int log_size);
+
+int
+_pba_slave_reset(int id, SsxInterval timeout, SsxInterval sleep);
+
+int
+pba_slave_reset(int id);
+
+
+////////////////////////////////////////////////////////////////////////////
+// PBAX
+////////////////////////////////////////////////////////////////////////////
+
+// PBAX error/panic codes
+
+#define PBAX_SEND_TIMEOUT 0x00722901
+#define PBAX_SEND_ERROR 0x00722902
+#define PBAX_RECEIVE_ERROR 0x00722903
+
+/// The number of receive queues implemented by PBAX
+#define PBAX_QUEUES 2
+
+/// The number of PBAX Node Ids
+#define PBAX_NODES 8
+
+/// The number of PBAX Chip Ids (and group Ids)
+#define PBAX_CHIPS 8
+#define PBAX_GROUPS PBAX_CHIPS
+
+/// The maximum legal PBAX group mask
+#define PBAX_GROUP_MASK_MAX 0xff
+
+// PBAX Send Message Scope
+
+#define PBAX_GROUP 1
+#define PBAX_SYSTEM 2
+
+// PBAX Send Type
+
+#define PBAX_UNICAST 0
+#define PBAX_BROADCAST 1
+
+// Default timeout for pbax_send()
+
+#ifndef PBAX_SEND_DEFAULT_TIMEOUT
+#define PBAX_SEND_DEFAULT_TIMEOUT SSX_MICROSECONDS(30)
+#endif
+
+/// An abstract target for PBAX send operations
+///
+/// This structure contains an abstraction of a communication target for PBAX
+/// send operations. An application using PBAX to transmit data first creates
+/// an instance of the PbaxTarget for each abstract target using
+/// pbax_target_create(), then calls pbax_send() or _pbax_send() with a
+/// PbaxTarget and an 8-byte data packet to effect a transmission.
+///
+/// For applications that use GPE programs to implement PBAX sends, a pointer
+/// to this object could also be passed to the GPE program.
+
+typedef struct {
+
+ /// The abstract target
+ ///
+ /// pbax_target_create() condenses the target parameters into a copy of
+ /// the PBAXSNDTX register used to configure the transmission.
+ pba_xsndtx_t target;
+
+} PbaxTarget;
+
+
+int
+pbax_target_create(PbaxTarget* target,
+ int type, int scope, int queue,
+ int node, int chip_or_group);
+
+int
+pbax_configure(int master, int node, int chip, int group_mask);
+
+int
+_pbax_send(PbaxTarget* target, uint64_t data, SsxInterval timeout);
+
+int
+pbax_send(PbaxTarget* target, uint64_t data);
+
+
+/// Enable the PBAX send mechanism
+
+static inline void
+pbax_send_enable(void)
+{
+ pba_xcfg_t pxc;
+
+ pxc.words.high_order = in32(PBA_XCFG);
+ pxc.fields.pbax_en = 1;
+ out32(PBA_XCFG, pxc.words.high_order);
+
+}
+
+
+/// Disable the PBAX send mechanism
+
+static inline void
+pbax_send_disable(void)
+{
+ pba_xcfg_t pxc;
+
+ pxc.words.high_order = in32(PBA_XCFG);
+ pxc.fields.pbax_en = 0;
+ out32(PBA_XCFG, pxc.words.high_order);
+
+}
+
+
+/// Clear the PBAX send error condition
+
+static inline void
+pbax_clear_send_error(void)
+{
+ pba_xcfg_t pxc;
+
+ pxc.words.high_order = in32(PBA_XCFG);
+ pxc.fields.snd_reset = 1;
+ out32(PBA_XCFG, pxc.words.high_order);
+}
+
+
+/// Clear the PBAX receive error condition
+
+static inline void
+pbax_clear_receive_error(void)
+{
+ pba_xcfg_t pxc;
+
+ pxc.words.high_order = in32(PBA_XCFG);
+ pxc.fields.rcv_reset = 1;
+ out32(PBA_XCFG, pxc.words.high_order);
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PGP_PBA_H__ */
diff --git a/src/ssx/pgp/pgp_pmc.c b/src/ssx/pgp/pgp_pmc.c
new file mode 100755
index 0000000..bf3673b
--- /dev/null
+++ b/src/ssx/pgp/pgp_pmc.c
@@ -0,0 +1,366 @@
+// $Id: pgp_pmc.c,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_pmc.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_pmc.c
+/// \brief PgP procedures and support for PMC operations
+///
+/// <b> SCOM Operations </b>
+///
+/// The PMC provides an indirect bridge from the OCI to the PIB/PCB. OCC
+/// firmware therefore has the ability to do immediate putscom()/getscom()
+/// operations in addition to the capabilities provided by the PORE-GPE
+/// engines. In PgP, SCOM latency from OCC is expected to be in the range of
+/// 150 - 1000 ns. The maximum latency of a PIB operation has a hard upper
+/// bound derived from the hardware implementation. The putscom()/getscom()
+/// drivers here take advantage of this upper bound and implement tight
+/// timeouts, enforced by polling the timebase while waiting for the SCOM
+/// operations to complete.
+///
+/// The latencies are small enough and so well understood that the
+/// getscom()/putscom() procedures operate in SSX_CRITICAL critical
+/// sections. There should be no problem for thread-based procedures to be
+/// written using getscom()/putscom() directly - in fact for short procedures
+/// it may be less overhead to use getscom()/putscom() than queuing a PORE-GPE
+/// program. All mainline procedures used by hard real-time code should
+/// remain as PORE-GPE programs however.
+///
+/// SCOM operations return non-zero error codes that may or may not indicate
+/// an actual error, depending on which SCOM is being accessed. This error
+/// code (or 0 for success) is returned as the value of getscom()/putscom().
+/// The error severity increases with the severity of the error:
+/// \code
+///
+/// #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
+/// \endcode
+///
+/// The default configuration variable SCOM_ERROR_LIMIT defines the maximum
+/// error code that will be returned - error codes above the limit (plus hard
+/// timeouts and other protocol errors) cause an immediate kernel panic. In
+/// the event of a non-0 error code, getscom() always sets the returned data
+/// to 0.
+///
+/// In addition to getscom()/putscom() that implement the above defined error
+/// protocols, the raw APIs _getscom()/_putscom() are also available and
+/// allow the application full control over timeouts and error handling on a
+/// SCOM-by-SCOM basis.
+///
+/// \bug Modify getscom/putscom to return the SSX error codes rather than
+/// 1-7.
+///
+/// \bug Implement and use a generic poll_with_timeout(f, arg, t)
+
+#include "ssx.h"
+#include "pgp_pmc.h"
+
+
+////////////////////////////////////////////////////////////////////////////
+// SCOM
+////////////////////////////////////////////////////////////////////////////
+
+// Common SCOM polling loop with software timeout. The PMC is always polled
+// at least twice to guarantee that we always poll once after a timeout.
+
+static int
+poll_scom(SsxInterval timeout, pmc_o2p_ctrl_status_reg_t *cs)
+{
+ SsxTimebase start;
+ int timed_out;
+
+ start = ssx_timebase_get();
+ timed_out = 0;
+ do {
+ cs->value = in32(PMC_O2P_CTRL_STATUS_REG);
+ if (!(cs->fields.o2p_ongoing)) {
+ break;
+ }
+ if (timed_out) {
+ return -SCOM_TIMEOUT_ERROR;
+ }
+ timed_out =
+ ((timeout != SSX_WAIT_FOREVER) &&
+ ((ssx_timebase_get() - start) > timeout));
+ } while (1);
+
+ return 0;
+}
+
+
+/// A raw getscom() through the PMC OCI/PIB bridge
+///
+/// \param address A standard 32-bit SCOM address, including multicast
+/// addresses.
+///
+/// \param data Points to a container for the returned data.
+///
+/// \param timeout The software timeout as an SSX interval (timebase ticks),
+/// or the special value SSX_WAIT_FOREVER to indicate no software timeout.
+///
+/// This routine executes in an SSX_CRITICAL critical section.
+///
+/// Unlike most other APIs, this API returns both positive and negative error
+/// codes, as well as the 0 code for success. In the event of PCB errors, the
+/// returned \a data is obtained from the PMC O2P data registers. In the
+/// event of non-PCB errors, the caller \a data is not modified.
+///
+/// If the transaction experiences a software timeout (controlled by the \a
+/// timeout parameter) or a protocol error, the PMC PIB master will be left in
+/// a state in which it is illegal to perform further SCOM access through the
+/// PMC until the ongoing transaction is finished.
+///
+/// \retval 0 Success
+///
+///\ retval 1-7 A PCB error code. See \c pcb_common.h
+///
+/// \retval -SCOM_TIMEOUT_ERROR The software timeout specified by the \a
+/// timeout parameter expired before the transaction completed.
+///
+/// retval -SCOM_PROTOCOL_ERROR_GETSCOM_BUSY The PMC SCOM engine was busy when
+/// the call was made.
+
+int
+_getscom(uint32_t address, uint64_t *data, SsxInterval timeout)
+{
+ pmc_o2p_addr_reg_t addr;
+ pmc_o2p_ctrl_status_reg_t cs;
+ SsxMachineContext ctx;
+ Uint64 data64;
+ int rc;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ // Check for a transaction already ongoing
+
+ cs.value = in32(PMC_O2P_CTRL_STATUS_REG);
+ if (cs.fields.o2p_ongoing) {
+ ssx_critical_section_exit(&ctx);
+ return -SCOM_PROTOCOL_ERROR_GETSCOM_BUSY;
+ }
+
+ // Start the read. The 'read' bit is forced into the address. Writing
+ // the PMC_O2P_ADDR_REG starts the read.
+
+ addr.value = address;
+ addr.fields.o2p_read_not_write = 1;
+ out32(PMC_O2P_ADDR_REG, addr.value);
+
+ // Polling and return.
+
+ rc = poll_scom(timeout, &cs);
+
+ data64.word[0] = in32(PMC_O2P_RECV_DATA_HI_REG);
+ data64.word[1] = in32(PMC_O2P_RECV_DATA_LO_REG);
+ *data = data64.value;
+
+ ssx_critical_section_exit(&ctx);
+
+ if (rc) {
+ return rc;
+ } else {
+ return cs.fields.o2p_scresp;
+ }
+}
+
+
+/// getscom() through the PMC OCI/PIB bridge
+///
+/// \param address A standard 32-bit SCOM address, including multicast
+/// addresses.
+///
+/// \param data Points to a container for the returned data.
+///
+/// This routine executes in an SSX_CRITICAL critical section.
+///
+/// Unlike most other APIs, this API returns positive error
+/// codes, as well as the 0 code for success. In the event of PCB errors, the
+/// returned \a data is set to 0.
+///
+/// If the transaction experiences a software timeout (controlled by the \a
+/// timeout parameter), a protocol error, or a PCB error greater than the
+/// configuration constant SCOM_ERROR_LIMIT this routine causes a kernel
+/// panic. This may leave the PMC PIB master in a state in which it is illegal
+/// to perform further SCOM access through the PMC (until the ongoing
+/// transaction is finished.)
+///
+/// \retval 0 Success
+///
+///\ retval 1-7 A PCB error code. See \c pcb_common.h
+
+int
+getscom(uint32_t address, uint64_t *data)
+{
+ int rc;
+
+ rc = _getscom(address, data, SCOM_TIMEOUT);
+ if (rc == 0) {
+ return 0;
+ }
+
+ if ((rc > 0) && (rc <= SCOM_ERROR_LIMIT)) {
+ *data = 0;
+ } else {
+
+ printk("getscom(0x%08x, %p) : Failed with error %d\n",
+ address, data, rc);
+
+ if (rc > 0) {
+ switch (rc) {
+ case 1: SSX_PANIC(SCOM_PCB_ERROR_1_GETSCOM); break;
+ case 2: SSX_PANIC(SCOM_PCB_ERROR_2_GETSCOM); break;
+ case 3: SSX_PANIC(SCOM_PCB_ERROR_3_GETSCOM); break;
+ case 4: SSX_PANIC(SCOM_PCB_ERROR_4_GETSCOM); break;
+ case 5: SSX_PANIC(SCOM_PCB_ERROR_5_GETSCOM); break;
+ case 6: SSX_PANIC(SCOM_PCB_ERROR_6_GETSCOM); break;
+ default: SSX_PANIC(SCOM_PCB_ERROR_7_GETSCOM); break;
+ }
+ } else if (rc == -SCOM_TIMEOUT_ERROR) {
+ SSX_PANIC(SCOM_TIMEOUT_ERROR_GETSCOM);
+ } else {
+ SSX_PANIC(SCOM_PROTOCOL_ERROR_GETSCOM);
+ }
+ }
+
+ return rc;
+}
+
+
+/// A raw putscom() through the PMC OCI/PIB bridge
+///
+/// \param address A standard 32-bit SCOM address, including multicast
+/// addresses.
+///
+/// \param data The SCOM write data
+///
+/// \param timeout The software timeout as an SSX interval (timebase ticks),
+/// or the special value SSX_WAIT_FOREVER to indicate no timeout.
+///
+/// This routine executes in an SSX_CRITICAL critical section.
+///
+/// Unlike most other APIs, this API returns both positive and negative error
+/// codes, as well as the 0 code for success.
+///
+/// If the transaction experiences a software timeout (controlled by the \a
+/// timeout parameter) or a protocol error, the PMC PIB master will be left in
+/// a state in which it is illegal to perform further SCOM access through the
+/// PMC until the ongoing transaction is finished.
+///
+/// \retval 0 Success
+///
+/// \retval 1-7 A PCB error code. See \c pcb_common.h
+///
+/// \retval -SCOM_TIMEOUT The software timeout specified by the \a timeout
+/// parameter expired before the transaction completed.
+///
+/// \retval -SCOM_PROTOCOL_ERROR_PUTSCOM_BUSY The PMC SCOM engine was busy when
+/// the call was made.
+
+int
+_putscom(uint32_t address, uint64_t data, SsxInterval timeout)
+{
+ pmc_o2p_addr_reg_t addr;
+ pmc_o2p_ctrl_status_reg_t cs;
+ SsxMachineContext ctx;
+ Uint64 data64;
+ int rc;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ // Check for a transaction already ongoing
+
+ cs.value = in32(PMC_O2P_CTRL_STATUS_REG);
+ if (cs.fields.o2p_ongoing) {
+ ssx_critical_section_exit(&ctx);
+ return -SCOM_PROTOCOL_ERROR_PUTSCOM_BUSY;
+ }
+
+ // Start the write. The 'write' bit is cleared in the address. Here the
+ // PIB write starts when the PMC_O2P_SEND_DATA_LO_REG is written.
+
+ addr.value = address;
+ addr.fields.o2p_read_not_write = 0;
+ out32(PMC_O2P_ADDR_REG, addr.value);
+
+ data64.value = data;
+ out32(PMC_O2P_SEND_DATA_HI_REG, data64.word[0]);
+ out32(PMC_O2P_SEND_DATA_LO_REG, data64.word[1]);
+
+ // Poll and return.
+
+ rc = poll_scom(timeout, &cs);
+
+ ssx_critical_section_exit(&ctx);
+
+ if (rc) {
+ return rc;
+ } else {
+ return cs.fields.o2p_scresp;
+ }
+}
+
+
+/// putscom() through the PMC OCI/PIB bridge
+///
+/// \param address A standard 32-bit SCOM address, including multicast
+/// addresses.
+///
+/// \param data The SCOM write data.
+///
+/// This routine executes in an SSX_CRITICAL critical section.
+///
+/// Unlike most other APIs, this API returns positive error
+/// codes, as well as the 0 code for success.
+///
+/// If the transaction experiences a software timeout (controlled by the \a
+/// timeout parameter), a protocol error, or a PCB error greater than the
+/// configuration constant SCOM_ERROR_LIMIT this routine causes a kernel
+/// panic. This may leave the PMC PIB master in a state in which it is illegal
+/// to perform further SCOM access through the PMC (until the ongoing
+/// transaction is finished.)
+///
+/// \retval 0 Success
+///
+/// \retval 1-7 A PCB error code. See \c pcb_common.h
+
+int
+putscom(uint32_t address, uint64_t data)
+{
+ int rc;
+
+ rc = _putscom(address, data, SCOM_TIMEOUT);
+
+ if ((rc == 0) || ((rc > 0) && (rc <= SCOM_ERROR_LIMIT))) {
+ return rc;
+ }
+
+ printk("putscom(0x%08x, 0x%016llx) : Failed with error %d\n",
+ address, data, rc);
+
+ if (rc > 0) {
+ switch (rc) {
+ case 1: SSX_PANIC(SCOM_PCB_ERROR_1_PUTSCOM); break;
+ case 2: SSX_PANIC(SCOM_PCB_ERROR_2_PUTSCOM); break;
+ case 3: SSX_PANIC(SCOM_PCB_ERROR_3_PUTSCOM); break;
+ case 4: SSX_PANIC(SCOM_PCB_ERROR_4_PUTSCOM); break;
+ case 5: SSX_PANIC(SCOM_PCB_ERROR_5_PUTSCOM); break;
+ case 6: SSX_PANIC(SCOM_PCB_ERROR_6_PUTSCOM); break;
+ default: SSX_PANIC(SCOM_PCB_ERROR_7_PUTSCOM); break;
+ }
+ } else if (rc == -SCOM_TIMEOUT_ERROR) {
+ SSX_PANIC(SCOM_TIMEOUT_ERROR_PUTSCOM);
+ } else {
+ SSX_PANIC(SCOM_PROTOCOL_ERROR_PUTSCOM);
+ }
+
+ return rc;
+}
diff --git a/src/ssx/pgp/pgp_pmc.h b/src/ssx/pgp/pgp_pmc.h
new file mode 100755
index 0000000..1b372db
--- /dev/null
+++ b/src/ssx/pgp/pgp_pmc.h
@@ -0,0 +1,105 @@
+#ifndef __PGP_PMC_H__
+#define __PGP_PMC_H__
+
+// $Id: pgp_pmc.h,v 1.2 2014/02/03 01:30:35 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_pmc.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_pmc.h
+/// \brief PgP procedures and support for PMC operations
+
+#include "ssx.h"
+
+#include "pgp_common.h"
+#include "pmc_register_addresses.h"
+#include "pmc_firmware_registers.h"
+
+////////////////////////////////////////////////////////////////////////////
+// SCOM
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+int
+_getscom(uint32_t address, uint64_t *data, SsxInterval timeout);
+
+int
+getscom(uint32_t address, uint64_t *data);
+
+int
+_putscom(uint32_t address, uint64_t data, SsxInterval timeout);
+
+int
+putscom(uint32_t address, uint64_t data);
+
+#endif /* __ASSEMBLER__ */
+
+// Error/Panic Codes
+
+#define SCOM_PCB_ERROR_1_GETSCOM 0x00726601
+#define SCOM_PCB_ERROR_2_GETSCOM 0x00726602
+#define SCOM_PCB_ERROR_3_GETSCOM 0x00726603
+#define SCOM_PCB_ERROR_4_GETSCOM 0x00726604
+#define SCOM_PCB_ERROR_5_GETSCOM 0x00726605
+#define SCOM_PCB_ERROR_6_GETSCOM 0x00726606
+#define SCOM_PCB_ERROR_7_GETSCOM 0x00726607
+#define SCOM_PCB_ERROR_1_PUTSCOM 0x00726608
+#define SCOM_PCB_ERROR_2_PUTSCOM 0x00726609
+#define SCOM_PCB_ERROR_3_PUTSCOM 0x0072660a
+#define SCOM_PCB_ERROR_4_PUTSCOM 0x0072660b
+#define SCOM_PCB_ERROR_5_PUTSCOM 0x0072660c
+#define SCOM_PCB_ERROR_6_PUTSCOM 0x0072660d
+#define SCOM_PCB_ERROR_7_PUTSCOM 0x0072660e
+
+#define SCOM_TIMEOUT_ERROR 0x00726610
+#define SCOM_TIMEOUT_ERROR_GETSCOM 0x00726611
+#define SCOM_TIMEOUT_ERROR_PUTSCOM 0x00726612
+#define SCOM_PROTOCOL_ERROR_GETSCOM 0x00726613
+#define SCOM_PROTOCOL_ERROR_PUTSCOM 0x00726614
+#define SCOM_PROTOCOL_ERROR_GETSCOM_BUSY 0x00726615
+#define SCOM_PROTOCOL_ERROR_PUTSCOM_BUSY 0x00726616
+
+
+/// The default timeout for getscom()/putscom()
+///
+/// This timeout is enforced by the firmware to guarantee a timeout regardless
+/// of the hardware setup.
+///
+/// The expectation is that the PgP hardware will be set up to enforce a PCB
+/// timeout of 8K cycles, or 16.384us @ 500 MHz. A timeout only occurs if
+/// someone erroneously issues a SCOM for a chiplet that does not exist. If
+/// this happens, then all other SCOMS waiting for the timed-out SCOM to
+/// finish will have to wait as well. Aside from the timeout error, the
+/// hardware arbitration and hard latency calculations guarantee that a SCOM
+/// from any master will complete in under 1us, regardless of PCB utilization.
+///
+/// Assuming that the PCB timeout is a rare event that will only happen when a
+/// console user types an illegal address for getscom/putscom, then we should
+/// be able to use 17us as a hard upper bound for a soft timeout. In practice
+/// this software timeout should never be observed - if it is, then something
+/// (either the setup, hardware or firmware) must be broken.
+
+#ifndef SCOM_TIMEOUT
+#define SCOM_TIMEOUT SSX_MICROSECONDS(17)
+#endif
+
+
+/// The default getscom()/putscom() error limit.
+///
+/// This defines the maximum PCB error return code which will not cause
+/// getscom()/putscom() to panic. The choice of this error limit is
+/// application dependent. For lab applications we should never try to SCOM a
+/// partial-good chiplet, so the limit is set at PCB_ERROR_CHIPLET_OFFLINE.
+/// For production applications it may be that notification of garded cores is
+/// late, so production code may need to handle PCB_ERROR_PARTIAL_GOOD as
+/// well.
+
+#ifndef SCOM_ERROR_LIMIT
+#define SCOM_ERROR_LIMIT PCB_ERROR_CHIPLET_OFFLINE
+#endif
+
+#endif // __PGP_PMC_H__
diff --git a/src/ssx/pgp/pgp_pore.h b/src/ssx/pgp/pgp_pore.h
new file mode 100755
index 0000000..e40ccac
--- /dev/null
+++ b/src/ssx/pgp/pgp_pore.h
@@ -0,0 +1,39 @@
+#ifndef __PGP_PORE_H__
+#define __PGP_PORE_H__
+
+// $Id: pgp_pore.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_pore.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_pore.h
+/// \brief PORE unit header. Local and mechanically generated macros.
+
+#include "pore_register_addresses.h"
+#include "pore_firmware_registers.h"
+
+/// The parameter for GPE-protocol triggering is the low-order word of the
+/// EXE_TRIGGER register
+#define PORE_EXE_PARAMETER_OFFSET (PORE_EXE_TRIGGER_OFFSET + 4)
+
+/// The PORE OCI address space descriptor
+#define PORE_ADDRESS_SPACE_OCI 0x8000
+
+/// The PORE BRAI opcode
+#define PORE_BRAI 0xa2000000
+
+/// The PORE BRAD D0 opcode
+#define PORE_BRAD_D0 0x38500000
+
+
+#ifndef __ASSEMBLER__
+
+/// The putative type of PORE program entry points - to make GCC happy
+typedef void *(PoreEntryPoint)(void);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PGP_PORE_H__ */
diff --git a/src/ssx/pgp/pgp_sramctl.h b/src/ssx/pgp/pgp_sramctl.h
new file mode 100755
index 0000000..fe2ed69
--- /dev/null
+++ b/src/ssx/pgp/pgp_sramctl.h
@@ -0,0 +1,18 @@
+#ifndef __PGP_SRAMCTL_H__
+#define __PGP_SRAMCTL_H__
+
+// $Id: pgp_sramctl.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_sramctl.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_sramctl.h
+/// \brief SRAMCTL unit header. Local and mechanically generated macros.
+
+#include "sramctl_register_addresses.h"
+#include "sramctl_firmware_registers.h"
+
+#endif /* __PGP_SRAMCTL_H__ */
diff --git a/src/ssx/pgp/pgp_trace.h b/src/ssx/pgp/pgp_trace.h
new file mode 100755
index 0000000..3544ce0
--- /dev/null
+++ b/src/ssx/pgp/pgp_trace.h
@@ -0,0 +1,155 @@
+#ifndef __PGP_TRACE_H__
+#define __PGP_TRACE_H__
+
+// $Id: pgp_trace.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_trace.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_trace.h
+/// \brief Implementation of SSX_TRACE macros for PgP
+///
+/// Kernel and application tracing uses the PBA "OCI Marker Space", a 64KB OCI
+/// register space implemented by PBA. When enabled in the PBA, any OCI write
+/// transactions of any size are ACK'ed by the PBA and the data is ignored.
+/// This creates an OCI transaction record that can be captured by the NHTM
+/// for later analysis.
+///
+/// SSX provides a generic SSX_TRACE() macro that accepts a single
+/// parameter. On PgP, valid parameters are integers in the range
+/// 0x0,...,0xffff. The PgP SSX kernel reserves trace addresses
+/// 0xe000,...,0xffff for kernel event traces. Applications are free to use
+/// the other trace addresses in the range 0x0000,...,0xdfff as they see fit.
+///
+/// Application tracing is globally disabled by default, and is enabled by
+/// defining the switch SSX_TRACE_ENABLE=1. Kernel event tracing is also
+/// globally disabled by default, and is enabled by defining the switch
+/// SSX_KERNEL_TRACE_ENABLE=1. Kernel event tracing adds overhead to every
+/// interrupt handler and kernel API so should probably remain disabled unless
+/// required.
+///
+/// The Simics PBA model supports trace reporting, either to stdout or to a
+/// file. To enable trace reporting set pba->trace_report = 1. To capture
+/// traces to a file other than stdout, set pba->trace_file = \<filename\>. The
+/// Simics model understands SSX kernel trace events and produces a readable
+/// commentary of kernel traces events - user events will be reported simply
+/// as the integer tag.
+
+#include "pgp_common.h"
+
+/// Output an OCI Trace Marker
+///
+/// See the comments for the file pgp_trace.h
+
+#if SSX_TRACE_ENABLE
+#define SSX_TRACE(event) out8(PBA_OCI_MARKER_BASE + (event), 0)
+#endif
+
+#if SSX_KERNEL_TRACE_ENABLE
+
+// Note: The *BASE constants are defined in pgp_common.h
+
+#define SSX_KERNEL_TRACE(event) out8(PBA_OCI_MARKER_BASE + (event), 0)
+
+#define SSX_TRACE_THREAD_SLEEP(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_SLEEP_BASE + priority)
+
+#define SSX_TRACE_THREAD_WAKEUP(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_WAKEUP_BASE + priority)
+
+#define SSX_TRACE_THREAD_SEMAPHORE_PEND(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_SEMAPHORE_PEND_BASE + priority)
+
+#define SSX_TRACE_THREAD_SEMAPHORE_POST(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_SEMAPHORE_POST_BASE + priority)
+
+#define SSX_TRACE_THREAD_SEMAPHORE_TIMEOUT(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_SEMAPHORE_TIMEOUT_BASE + priority)
+
+#define SSX_TRACE_THREAD_SUSPENDED(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_SUSPENDED_BASE + priority)
+
+#define SSX_TRACE_THREAD_DELETED(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_DELETED_BASE + priority)
+
+#define SSX_TRACE_THREAD_COMPLETED(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_COMPLETED_BASE + priority)
+
+#define SSX_TRACE_THREAD_MAPPED_RUNNABLE(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_MAPPED_RUNNABLE_BASE + priority)
+
+#define SSX_TRACE_THREAD_MAPPED_SEMAPHORE_PEND(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_MAPPED_SEMAPHORE_PEND_BASE + priority)
+
+#define SSX_TRACE_THREAD_MAPPED_SLEEPING(priority) \
+ SSX_KERNEL_TRACE(SSX_TRACE_THREAD_MAPPED_SLEEPING_BASE + priority)
+
+#endif /* SSX_KERNEL_TRACE_ENABLE */
+
+
+#ifdef __ASSEMBLER__
+
+// NB: CPP macros are not expanded as arguments to .if in GAS macro
+// definitions. That's why e.g. we have to use _liw instead of _liwa.
+
+#if SSX_KERNEL_TRACE_ENABLE
+
+ .macro SSX_TRACE_CRITICAL_IRQ_ENTRY, irqreg, scratch
+ _liw \scratch, (PBA_OCI_MARKER_BASE + SSX_TRACE_CRITICAL_IRQ_ENTRY_BASE)
+ stbx \irqreg, \irqreg, \scratch
+ eieio
+ .endm
+
+ .macro SSX_TRACE_CRITICAL_IRQ_EXIT, scratch0, scratch1
+ _liw \scratch0, (PBA_OCI_MARKER_BASE + SSX_TRACE_CRITICAL_IRQ_EXIT_BASE)
+ mfusprg0 \scratch1
+ extrwi \scratch1, \scratch1, 8, 16
+ stbx \scratch1, \scratch0, \scratch1
+ eieio
+ .endm
+
+ .macro SSX_TRACE_NONCRITICAL_IRQ_ENTRY, irqreg, scratch
+ _liw \scratch, (PBA_OCI_MARKER_BASE + SSX_TRACE_NONCRITICAL_IRQ_ENTRY_BASE)
+ stbx \irqreg, \irqreg, \scratch
+ eieio
+ .endm
+
+ .macro SSX_TRACE_NONCRITICAL_IRQ_EXIT, scratch0, scratch1
+ _liw \scratch0, (PBA_OCI_MARKER_BASE + SSX_TRACE_NONCRITICAL_IRQ_EXIT_BASE)
+ mfusprg0 \scratch1
+ extrwi \scratch1, \scratch1, 8, 16
+ stbx \scratch1, \scratch0, \scratch1
+ eieio
+ .endm
+
+ .macro SSX_TRACE_THREAD_SWITCH, priority, scratch
+ _liw \scratch, (PBA_OCI_MARKER_BASE + SSX_TRACE_THREAD_SWITCH_BASE)
+ stbx \priority, \priority, \scratch
+ eieio
+ .endm
+
+#else /* SSX_KERNEL_TRACE_ENABLE */
+
+ .macro SSX_TRACE_CRITICAL_IRQ_ENTRY, irq, scratch
+ .endm
+
+ .macro SSX_TRACE_CRITICAL_IRQ_EXIT, scratch0, scratch1
+ .endm
+
+ .macro SSX_TRACE_NONCRITICAL_IRQ_ENTRY, irq, scratch
+ .endm
+
+ .macro SSX_TRACE_NONCRITICAL_IRQ_EXIT, scratch0, scratch1
+ .endm
+
+ .macro SSX_TRACE_THREAD_SWITCH, priority, scratch
+ .endm
+
+#endif /* SSX_KERNEL_TRACE_ENABLE */
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PGP_TRACE_H__ */
diff --git a/src/ssx/pgp/pgp_vrm.h b/src/ssx/pgp/pgp_vrm.h
new file mode 100755
index 0000000..aaa6760
--- /dev/null
+++ b/src/ssx/pgp/pgp_vrm.h
@@ -0,0 +1,223 @@
+#ifndef __PGP_VRM_H__
+#define __PGP_VRM_H__
+
+// $Id: pgp_vrm.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/pgp_vrm.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pgp_vrm.h
+/// \brief Header for PgP VRM device drivers. Some constants are also held in
+/// pgp_common.h.
+
+#include "pgp_common.h"
+
+
+#ifndef __ASSEMBLER__
+
+/// VRM Command Header
+///
+/// This structure defines the values written on the SPI interface for
+/// 'read' commands.
+
+//typedef union {
+// uint64_t value;
+// uint32_t word[2];
+// struct {
+// uint64_t address : 4;
+// uint64_t command : 4;
+// } fields;
+//} vrm_command_t;
+
+
+/// VRM Write Transaction Command
+///
+/// The 8-bit \a phase_enable is an 8-bit VRM-11 VID code
+///
+/// The 8-bit \a vcs_offset is an 8-bit signed offset
+
+typedef union {
+ uint64_t value;
+ uint32_t word[2];
+ struct {
+ uint64_t command : 4;
+ uint64_t phase_enable : 4;
+ uint64_t vdd_vid : 8;
+ uint64_t vcs_offset : 8;
+ uint64_t master_crc : 8;
+ } fields;
+} vrm_write_transaction_t;
+
+
+/// VRM Write Transaction Response
+/// writes status is duplicated 3x for the minority detect feature.
+
+typedef union {
+ uint64_t value;
+ uint32_t word[2];
+ struct {
+ uint64_t write_status0 : 8;
+ uint64_t write_status1 : 8;
+ uint64_t write_status2 : 8;
+ uint64_t optional_crc : 8;
+ } fields;
+} vrm_write_resp_t;
+
+
+
+/// VRM Read State Command
+/// reserved field should be sent as 0s
+
+typedef union {
+ uint64_t value;
+ uint32_t word[2];
+ struct {
+ uint64_t command : 4;
+ uint64_t reserved : 20;
+ uint64_t master_crc : 8;
+ } fields;
+} vrm_read_state_t;
+
+
+/// VRM Read State Response
+/// Results are duplicated 3x for the minority detecte feature.
+
+typedef union {
+ uint64_t value;
+ uint32_t word[2];
+ struct {
+ uint64_t read_ready0 : 1;
+ uint64_t minus_nplus1_0 : 1;
+ uint64_t minus_n0 : 1;
+ uint64_t reserved1_0 : 1;
+ uint64_t vrm_fan0 : 1;
+ uint64_t vrm_overtemp0 : 1;
+ uint64_t reserved2_0 : 2;
+ uint64_t read_ready1 : 1;
+ uint64_t minus_nplus1_1 : 1;
+ uint64_t minus_n1 : 1;
+ uint64_t reserved1_1 : 1;
+ uint64_t vrm_fan1 : 1;
+ uint64_t vrm_overtemp1 : 1;
+ uint64_t reserved2_1 : 2;
+ uint64_t read_ready2 : 1;
+ uint64_t minus_nplus1_2 : 1;
+ uint64_t minus_n2 : 1;
+ uint64_t reserved1_2 : 1;
+ uint64_t vrm_fan2 : 1;
+ uint64_t vrm_overtemp2 : 1;
+ uint64_t reserved2_2 : 2;
+ uint64_t slave_crc : 8;
+ } fields;
+} vrm_read_state_resp_t;
+
+/// VRM Read Voltage Command
+/// reserved field should be sent as 0s
+
+typedef union {
+ uint64_t value;
+ uint32_t word[2];
+ struct {
+ uint64_t command : 4;
+ uint64_t rail : 4;
+ uint64_t reserved : 1;
+ uint64_t master_crc : 8;
+ } fields;
+} vrm_read_voltage_t;
+
+
+/// VRM Read Voltage Response
+/// Results are duplicated 3x for the minority detect feature.
+
+typedef union {
+ uint64_t value;
+ uint32_t word[2];
+ struct {
+ uint64_t vid0 : 8;
+ uint64_t vid1 : 8;
+ uint64_t vid2 : 8;
+ uint64_t slave_crc : 8;
+ } fields;
+} vrm_read_voltage_resp_t;
+
+
+/// VRM Read Current 1 Response
+///
+/// The 16-bit current readings come from 12-bit DACS; the DAC output is
+/// right-padded with 0b0000. The current units are 0.025 Ampere.
+
+//typedef union {
+// uint64_t value;
+// uint32_t word[2];
+// struct {
+// uint64_t header : 8;
+// uint64_t read_not_ready : 1;
+// uint64_t minus_nplus1 : 1;
+// uint64_t minus_n : 1;
+// uint64_t reserved0 : 1;
+// uint64_t vrm_fan : 1;
+// uint64_t vrm_overtemp : 1;
+// uint64_t reserved1 : 2;
+// uint64_t vdd_current : 16;
+// uint64_t vcs_current : 16;
+// uint64_t vio_current : 16;
+// } fields;
+//} vrm_read_current_1_t;
+
+
+/// VRM Read Current 2 Response
+///
+/// The 16-bit current readings come from 12-bit DACS; the DAC output is
+/// right-padded with 0b0000. The current units are 0.025 Ampere.
+
+//typedef union {
+// uint64_t value;
+// uint32_t word[2];
+// struct {
+// uint64_t header : 8;
+// uint64_t read_not_ready : 1;
+// uint64_t minus_nplus1 : 1;
+// uint64_t minus_n : 1;
+// uint64_t reserved0 : 1;
+// uint64_t vrm_fan : 1;
+// uint64_t vrm_overtemp : 1;
+// uint64_t reserved1 : 2;
+// uint64_t spare1_current : 16;
+// uint64_t spare2_current : 16;
+// uint64_t spare3_current : 16;
+// } fields;
+//} vrm_read_current_2_t;
+
+#endif /* __ASSEMBLER__ */
+
+// These are the default values for the SPIVRM/O2S interface
+
+#define SPIVRM_BITS 71 /* Actual # of bits minus 1 */
+#define SPIVRM_CPOL 0 /* Clock polarity */
+#define SPIVRM_CPHA 0 /* Clock phase */
+#define SPIVRM_FREQUENCY_HZ 16000000 /* 16 MHz */
+#define SPIVRM_ENABLE_ECC 1
+#define SPIVRM_NPORTS 3 /* Maximum # of ports supported by HW */
+#define SPIVRM_NRAILS 2 /* Maximum # of rails supported by read voltage cmd*/
+#define SPIVRM_ENABLED_PORTS 0x4 /* 3 bit mask, left justified */
+#define SPIVRM_PHASES 15 /* System dependent */
+
+/// Convert an integer index into a VRM designator (mask)
+#define SPIVRM_PORT(i) (1 << (SPIVRM_NPORTS - (i) - 1))
+
+// SPIVRM specific setup defaults
+
+#define SPIVRM_READ_STATUS_DELAY 48 /* Cycles, system dependent */
+#define SPIVRM_ADDRESS 0 /* First 4 bits of SPIVRM packet */
+
+// Default values for the O2S bridge
+
+#define O2S_BRIDGE_ENABLE 1
+#define O2S_READ_DELAY 48 /* Cycles, system dependent */
+#define O2S_ADDRESS 0 /* First 4 bits of O2S packet */
+
+
+#endif /* __PGP_VRM_H__ */
diff --git a/src/ssx/pgp/registers/centaur_firmware_registers.h b/src/ssx/pgp/registers/centaur_firmware_registers.h
new file mode 100755
index 0000000..39f168f
--- /dev/null
+++ b/src/ssx/pgp/registers/centaur_firmware_registers.h
@@ -0,0 +1,1496 @@
+#ifndef __CENTAUR_FIRMWARE_REGISTERS_H__
+#define __CENTAUR_FIRMWARE_REGISTERS_H__
+
+// $Id: centaur_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/centaur_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file centaur_firmware_registers.h
+/// \brief C register structs for the CENTAUR unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union centaur_device_id {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cfam_id : 32;
+ uint64_t module_id : 2;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t module_id : 2;
+ uint64_t cfam_id : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_device_id_t;
+
+
+
+typedef union centaur_mbs_fir_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_fir_reg_t;
+
+
+
+typedef union centaur_mbs_fir_reg_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_fir_reg_and_t;
+
+
+
+typedef union centaur_mbs_fir_reg_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_fir_reg_or_t;
+
+
+
+typedef union centaur_mbs_fir_mask_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_fir_mask_reg_t;
+
+
+
+typedef union centaur_mbs_fir_mask_reg_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_fir_mask_reg_and_t;
+
+
+
+typedef union centaur_mbs_fir_mask_reg_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_fir_mask_reg_or_t;
+
+
+
+typedef union centaur_mbs_fir_action0_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_fir_action0_reg_t;
+
+
+
+typedef union centaur_mbs_firact1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t host_protocol_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t external_timeout : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t lru_error : 1;
+ uint64_t edram_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t internal_scom_error_copy : 1;
+ uint64_t internal_scom_error : 1;
+ uint64_t spare_fir31 : 1;
+ uint64_t spare_fir30 : 1;
+ uint64_t dir_purge_ce : 1;
+ uint64_t srb_buffer_sue : 1;
+ uint64_t srb_buffer_ue : 1;
+ uint64_t srb_buffer_ce : 1;
+ uint64_t occ_inband_write_error : 1;
+ uint64_t occ_inband_read_error : 1;
+ uint64_t host_inband_write_error : 1;
+ uint64_t host_inband_read_error : 1;
+ uint64_t emergency_throttle_set : 1;
+ uint64_t edram_error : 1;
+ uint64_t lru_error : 1;
+ uint64_t dir_all_members_deleted : 1;
+ uint64_t dir_member_deleted : 1;
+ uint64_t dir_ue : 1;
+ uint64_t dir_ce : 1;
+ uint64_t cache_co_sue : 1;
+ uint64_t cache_co_ue : 1;
+ uint64_t cache_co_ce : 1;
+ uint64_t cache_srw_sue : 1;
+ uint64_t cache_srw_ue : 1;
+ uint64_t cache_srw_ce : 1;
+ uint64_t int_parity_error : 1;
+ uint64_t int_buffer_sue : 1;
+ uint64_t int_buffer_ue : 1;
+ uint64_t int_buffer_ce : 1;
+ uint64_t internal_timeout : 1;
+ uint64_t external_timeout : 1;
+ uint64_t invalid_address_error : 1;
+ uint64_t int_protocol_error : 1;
+ uint64_t host_protocol_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbs_firact1_t;
+
+
+
+typedef union centaur_mbscfgq {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t eccbp_exit_sel : 1;
+ uint64_t dram_ecc_bypass_dis : 1;
+ uint64_t mbs_scom_wat_trigger : 1;
+ uint64_t mbs_prq_ref_avoidance_en : 1;
+ uint64_t reserved4_6 : 3;
+ uint64_t occ_deadman_timer_sel : 4;
+ uint64_t sync_fsync_mba_strobe_en : 1;
+ uint64_t hca_timebase_op_mode : 1;
+ uint64_t hca_local_timer_inc_select : 3;
+ uint64_t mbs_01_rdtag_delay : 4;
+ uint64_t mbs_01_rdtag_force_dead_cycle : 1;
+ uint64_t sync_lat_pol_01 : 1;
+ uint64_t sync_lat_adj_01 : 2;
+ uint64_t mbs_23_rdtag_delay : 4;
+ uint64_t mbs_23_rdtag_force_dead_cycle : 1;
+ uint64_t sync_lat_pol_23 : 1;
+ uint64_t sync_lat_adj_23 : 2;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t sync_lat_adj_23 : 2;
+ uint64_t sync_lat_pol_23 : 1;
+ uint64_t mbs_23_rdtag_force_dead_cycle : 1;
+ uint64_t mbs_23_rdtag_delay : 4;
+ uint64_t sync_lat_adj_01 : 2;
+ uint64_t sync_lat_pol_01 : 1;
+ uint64_t mbs_01_rdtag_force_dead_cycle : 1;
+ uint64_t mbs_01_rdtag_delay : 4;
+ uint64_t hca_local_timer_inc_select : 3;
+ uint64_t hca_timebase_op_mode : 1;
+ uint64_t sync_fsync_mba_strobe_en : 1;
+ uint64_t occ_deadman_timer_sel : 4;
+ uint64_t reserved4_6 : 3;
+ uint64_t mbs_prq_ref_avoidance_en : 1;
+ uint64_t mbs_scom_wat_trigger : 1;
+ uint64_t dram_ecc_bypass_dis : 1;
+ uint64_t eccbp_exit_sel : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbscfgq_t;
+
+
+
+typedef union centaur_mbsemerthroq {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t emergency_throttle_ip : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t emergency_throttle_ip : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbsemerthroq_t;
+
+
+
+typedef union centaur_mbsocc01hq {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_01_rd_hit : 32;
+ uint64_t occ_01_wr_hit : 32;
+#else
+ uint64_t occ_01_wr_hit : 32;
+ uint64_t occ_01_rd_hit : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbsocc01hq_t;
+
+
+
+typedef union centaur_mbsocc23hq {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_23_rd_hit : 32;
+ uint64_t occ_23_wr_hit : 32;
+#else
+ uint64_t occ_23_wr_hit : 32;
+ uint64_t occ_23_rd_hit : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbsocc23hq_t;
+
+
+
+typedef union centaur_mbsoccitcq {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_cent_idle_th_cnt : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t occ_cent_idle_th_cnt : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbsoccitcq_t;
+
+
+
+typedef union centaur_mbsoccscanq {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_01_spec_can : 32;
+ uint64_t occ_23_spec_can : 32;
+#else
+ uint64_t occ_23_spec_can : 32;
+ uint64_t occ_01_spec_can : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbsoccscanq_t;
+
+
+
+typedef union centaur_mbarpc0qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cfg_lp2_entry_req : 1;
+ uint64_t cfg_lp2_state : 1;
+ uint64_t cfg_min_max_domains_enable : 1;
+ uint64_t cfg_min_max_domains : 3;
+ uint64_t cfg_pup_avail : 5;
+ uint64_t cfg_pdn_pup : 5;
+ uint64_t cfg_pup_pdn : 5;
+ uint64_t reserved0 : 1;
+ uint64_t cfg_min_domain_reduction_enable : 1;
+ uint64_t cfg_min_domain_reduction_on_time : 10;
+ uint64_t cfg_pup_after_activate_wait_enable : 1;
+ uint64_t cfg_pup_after_activate_wait_time : 8;
+ uint64_t cfg_force_spare_pup : 1;
+ uint64_t _reserved0 : 21;
+#else
+ uint64_t _reserved0 : 21;
+ uint64_t cfg_force_spare_pup : 1;
+ uint64_t cfg_pup_after_activate_wait_time : 8;
+ uint64_t cfg_pup_after_activate_wait_enable : 1;
+ uint64_t cfg_min_domain_reduction_on_time : 10;
+ uint64_t cfg_min_domain_reduction_enable : 1;
+ uint64_t reserved0 : 1;
+ uint64_t cfg_pup_pdn : 5;
+ uint64_t cfg_pdn_pup : 5;
+ uint64_t cfg_pup_avail : 5;
+ uint64_t cfg_min_max_domains : 3;
+ uint64_t cfg_min_max_domains_enable : 1;
+ uint64_t cfg_lp2_state : 1;
+ uint64_t cfg_lp2_entry_req : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbarpc0qn_t;
+
+
+
+typedef union centaur_mba_farb3qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cfg_nm_n_per_mba : 15;
+ uint64_t cfg_nm_n_per_chip : 16;
+ uint64_t cfg_nm_m : 14;
+ uint64_t cfg_nm_ras_weight : 3;
+ uint64_t cfg_nm_cas_weight : 3;
+ uint64_t cfg_nm_per_slot_enabled : 1;
+ uint64_t cfg_nm_count_other_mba_dis : 1;
+ uint64_t _reserved0 : 11;
+#else
+ uint64_t _reserved0 : 11;
+ uint64_t cfg_nm_count_other_mba_dis : 1;
+ uint64_t cfg_nm_per_slot_enabled : 1;
+ uint64_t cfg_nm_cas_weight : 3;
+ uint64_t cfg_nm_ras_weight : 3;
+ uint64_t cfg_nm_m : 14;
+ uint64_t cfg_nm_n_per_chip : 16;
+ uint64_t cfg_nm_n_per_mba : 15;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mba_farb3qn_t;
+
+
+
+typedef union centaur_mbapcn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t mode_hp_sub_cnt : 1;
+ uint64_t mode_lp_sub_cnt : 1;
+ uint64_t mode_static_idle_dly : 5;
+ uint64_t mode_emer_min_max_domain : 3;
+ uint64_t mode_pup_all_wr_pending : 2;
+ uint64_t mode_lp_ref_sim_enq : 1;
+ uint64_t _reserved0 : 51;
+#else
+ uint64_t _reserved0 : 51;
+ uint64_t mode_lp_ref_sim_enq : 1;
+ uint64_t mode_pup_all_wr_pending : 2;
+ uint64_t mode_emer_min_max_domain : 3;
+ uint64_t mode_static_idle_dly : 5;
+ uint64_t mode_lp_sub_cnt : 1;
+ uint64_t mode_hp_sub_cnt : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbapcn_t;
+
+
+
+typedef union centaur_mbasrqn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t emergency_m : 14;
+ uint64_t emergency_n : 15;
+ uint64_t _reserved0 : 35;
+#else
+ uint64_t _reserved0 : 35;
+ uint64_t emergency_n : 15;
+ uint64_t emergency_m : 14;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_mbasrqn_t;
+
+
+
+typedef union centaur_pmu0qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t read_count : 32;
+ uint64_t write_count : 32;
+#else
+ uint64_t write_count : 32;
+ uint64_t read_count : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_pmu0qn_t;
+
+
+
+typedef union centaur_pmu1qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t activate_count : 32;
+ uint64_t pu_counts : 32;
+#else
+ uint64_t pu_counts : 32;
+ uint64_t activate_count : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_pmu1qn_t;
+
+
+
+typedef union centaur_pmu2qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t frame_count : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t frame_count : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_pmu2qn_t;
+
+
+
+typedef union centaur_pmu3qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t low_idle_threshold : 16;
+ uint64_t med_idle_threshold : 16;
+ uint64_t high_idle_threshold : 32;
+#else
+ uint64_t high_idle_threshold : 32;
+ uint64_t med_idle_threshold : 16;
+ uint64_t low_idle_threshold : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_pmu3qn_t;
+
+
+
+typedef union centaur_pmu4qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t base_idle_count : 32;
+ uint64_t low_idle_count : 32;
+#else
+ uint64_t low_idle_count : 32;
+ uint64_t base_idle_count : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_pmu4qn_t;
+
+
+
+typedef union centaur_pmu5qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t med_idle_count : 32;
+ uint64_t high_idle_count : 32;
+#else
+ uint64_t high_idle_count : 32;
+ uint64_t med_idle_count : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_pmu5qn_t;
+
+
+
+typedef union centaur_pmu6qn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t total_gap_counts : 18;
+ uint64_t specific_gap_counts : 18;
+ uint64_t gap_length_adder : 3;
+ uint64_t specific_gap_condition : 4;
+ uint64_t cmd_to_cmd_count : 18;
+ uint64_t command_pattern_to_count : 3;
+#else
+ uint64_t command_pattern_to_count : 3;
+ uint64_t cmd_to_cmd_count : 18;
+ uint64_t specific_gap_condition : 4;
+ uint64_t gap_length_adder : 3;
+ uint64_t specific_gap_counts : 18;
+ uint64_t total_gap_counts : 18;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_pmu6qn_t;
+
+
+
+typedef union centaur_sensor_cache_data0_3 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t crittrip0 : 1;
+ uint64_t abovetrip0 : 1;
+ uint64_t belowtrip0 : 1;
+ uint64_t signbit0 : 1;
+ uint64_t temperature0 : 8;
+ uint64_t temp_frac0 : 2;
+ uint64_t status0 : 2;
+ uint64_t crittrip1 : 1;
+ uint64_t abovetrip1 : 1;
+ uint64_t belowtrip1 : 1;
+ uint64_t signbit1 : 1;
+ uint64_t temperature1 : 8;
+ uint64_t temp_frac1 : 2;
+ uint64_t status1 : 2;
+ uint64_t crittrip2 : 1;
+ uint64_t abovetrip2 : 1;
+ uint64_t belowtrip2 : 1;
+ uint64_t signbit2 : 1;
+ uint64_t temperature2 : 8;
+ uint64_t temp_frac2 : 2;
+ uint64_t status2 : 2;
+ uint64_t crittrip3 : 1;
+ uint64_t abovetrip3 : 1;
+ uint64_t belowtrip3 : 1;
+ uint64_t signbit3 : 1;
+ uint64_t temperature3 : 8;
+ uint64_t temp_frac3 : 2;
+ uint64_t status3 : 2;
+#else
+ uint64_t status3 : 2;
+ uint64_t temp_frac3 : 2;
+ uint64_t temperature3 : 8;
+ uint64_t signbit3 : 1;
+ uint64_t belowtrip3 : 1;
+ uint64_t abovetrip3 : 1;
+ uint64_t crittrip3 : 1;
+ uint64_t status2 : 2;
+ uint64_t temp_frac2 : 2;
+ uint64_t temperature2 : 8;
+ uint64_t signbit2 : 1;
+ uint64_t belowtrip2 : 1;
+ uint64_t abovetrip2 : 1;
+ uint64_t crittrip2 : 1;
+ uint64_t status1 : 2;
+ uint64_t temp_frac1 : 2;
+ uint64_t temperature1 : 8;
+ uint64_t signbit1 : 1;
+ uint64_t belowtrip1 : 1;
+ uint64_t abovetrip1 : 1;
+ uint64_t crittrip1 : 1;
+ uint64_t status0 : 2;
+ uint64_t temp_frac0 : 2;
+ uint64_t temperature0 : 8;
+ uint64_t signbit0 : 1;
+ uint64_t belowtrip0 : 1;
+ uint64_t abovetrip0 : 1;
+ uint64_t crittrip0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_sensor_cache_data0_3_t;
+
+
+
+typedef union centaur_sensor_cache_data4_7 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t crittrip4 : 1;
+ uint64_t abovetrip4 : 1;
+ uint64_t belowtrip4 : 1;
+ uint64_t signbit4 : 1;
+ uint64_t temperature4 : 8;
+ uint64_t temp_frac4 : 2;
+ uint64_t status4 : 2;
+ uint64_t crittrip5 : 1;
+ uint64_t abovetrip5 : 1;
+ uint64_t belowtrip5 : 1;
+ uint64_t signbit5 : 1;
+ uint64_t temperature5 : 8;
+ uint64_t temp_frac5 : 2;
+ uint64_t status5 : 2;
+ uint64_t crittrip6 : 1;
+ uint64_t abovetrip6 : 1;
+ uint64_t belowtrip6 : 1;
+ uint64_t signbit6 : 1;
+ uint64_t temperature6 : 8;
+ uint64_t temp_frac6 : 2;
+ uint64_t status6 : 2;
+ uint64_t crittrip7 : 1;
+ uint64_t abovetrip7 : 1;
+ uint64_t belowtrip7 : 1;
+ uint64_t signbit7 : 1;
+ uint64_t temperature7 : 8;
+ uint64_t temp_frac7 : 2;
+ uint64_t status7 : 2;
+#else
+ uint64_t status7 : 2;
+ uint64_t temp_frac7 : 2;
+ uint64_t temperature7 : 8;
+ uint64_t signbit7 : 1;
+ uint64_t belowtrip7 : 1;
+ uint64_t abovetrip7 : 1;
+ uint64_t crittrip7 : 1;
+ uint64_t status6 : 2;
+ uint64_t temp_frac6 : 2;
+ uint64_t temperature6 : 8;
+ uint64_t signbit6 : 1;
+ uint64_t belowtrip6 : 1;
+ uint64_t abovetrip6 : 1;
+ uint64_t crittrip6 : 1;
+ uint64_t status5 : 2;
+ uint64_t temp_frac5 : 2;
+ uint64_t temperature5 : 8;
+ uint64_t signbit5 : 1;
+ uint64_t belowtrip5 : 1;
+ uint64_t abovetrip5 : 1;
+ uint64_t crittrip5 : 1;
+ uint64_t status4 : 2;
+ uint64_t temp_frac4 : 2;
+ uint64_t temperature4 : 8;
+ uint64_t signbit4 : 1;
+ uint64_t belowtrip4 : 1;
+ uint64_t abovetrip4 : 1;
+ uint64_t crittrip4 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_sensor_cache_data4_7_t;
+
+
+
+typedef union centaur_dts_thermal_sensor_results {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dts0 : 12;
+ uint64_t thermal_trip0 : 2;
+ uint64_t spare0 : 1;
+ uint64_t valid0 : 1;
+ uint64_t dts1 : 12;
+ uint64_t thermal_trip1 : 2;
+ uint64_t spare1 : 1;
+ uint64_t valid1 : 1;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t valid1 : 1;
+ uint64_t spare1 : 1;
+ uint64_t thermal_trip1 : 2;
+ uint64_t dts1 : 12;
+ uint64_t valid0 : 1;
+ uint64_t spare0 : 1;
+ uint64_t thermal_trip0 : 2;
+ uint64_t dts0 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} centaur_dts_thermal_sensor_results_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __CENTAUR_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/centaur_register_addresses.h b/src/ssx/pgp/registers/centaur_register_addresses.h
new file mode 100755
index 0000000..7c9c095
--- /dev/null
+++ b/src/ssx/pgp/registers/centaur_register_addresses.h
@@ -0,0 +1,66 @@
+#ifndef __CENTAUR_REGISTER_ADDRESSES_H__
+#define __CENTAUR_REGISTER_ADDRESSES_H__
+
+// $Id: centaur_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/centaur_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file centaur_register_addresses.h
+/// \brief Symbolic addresses for the CENTAUR unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define CENTAUR_PIB_BASE 0
+#define CENTAUR_DEVICE_ID 0x000f000f
+#define CENTAUR_MBS_FIR_REG 0x02011400
+#define CENTAUR_MBS_FIR_REG_AND 0x02011401
+#define CENTAUR_MBS_FIR_REG_OR 0x02011402
+#define CENTAUR_MBS_FIR_MASK_REG 0x02011403
+#define CENTAUR_MBS_FIR_MASK_REG_AND 0x02011404
+#define CENTAUR_MBS_FIR_MASK_REG_OR 0x02011405
+#define CENTAUR_MBS_FIR_ACTION0_REG 0x02011406
+#define CENTAUR_MBS_FIRACT1 0x02011407
+#define CENTAUR_MBSCFGQ 0x02011411
+#define CENTAUR_MBSEMERTHROQ 0x0201142d
+#define CENTAUR_MBSOCC01HQ 0x02011429
+#define CENTAUR_MBSOCC23HQ 0x0201142a
+#define CENTAUR_MBSOCCITCQ 0x02011428
+#define CENTAUR_MBSOCCSCANQ 0x0201142b
+#define CENTAUR_MBARPC0QN(n) (CENTAUR_MBARPC0Q0 + ((CENTAUR_MBARPC0Q1 - CENTAUR_MBARPC0Q0) * (n)))
+#define CENTAUR_MBARPC0Q0 0x03010434
+#define CENTAUR_MBARPC0Q1 0x03010c34
+#define CENTAUR_MBA_FARB3QN(n) (CENTAUR_MBA_FARB3Q0 + ((CENTAUR_MBA_FARB3Q1 - CENTAUR_MBA_FARB3Q0) * (n)))
+#define CENTAUR_MBA_FARB3Q0 0x03010416
+#define CENTAUR_MBA_FARB3Q1 0x03010c16
+#define CENTAUR_PMU0QN(n) (CENTAUR_PMU0Q0 + ((CENTAUR_PMU0Q1 - CENTAUR_PMU0Q0) * (n)))
+#define CENTAUR_PMU0Q0 0x03010437
+#define CENTAUR_PMU0Q1 0x03010c37
+#define CENTAUR_PMU1QN(n) (CENTAUR_PMU1Q0 + ((CENTAUR_PMU1Q1 - CENTAUR_PMU1Q0) * (n)))
+#define CENTAUR_PMU1Q0 0x03010438
+#define CENTAUR_PMU1Q1 0x03010c38
+#define CENTAUR_PMU2QN(n) (CENTAUR_PMU2Q0 + ((CENTAUR_PMU2Q1 - CENTAUR_PMU2Q0) * (n)))
+#define CENTAUR_PMU2Q0 0x03010439
+#define CENTAUR_PMU2Q1 0x03010c39
+#define CENTAUR_PMU3QN(n) (CENTAUR_PMU3Q0 + ((CENTAUR_PMU3Q1 - CENTAUR_PMU3Q0) * (n)))
+#define CENTAUR_PMU3Q0 0x0301043a
+#define CENTAUR_PMU3Q1 0x03010c3a
+#define CENTAUR_PMU4QN(n) (CENTAUR_PMU4Q0 + ((CENTAUR_PMU4Q1 - CENTAUR_PMU4Q0) * (n)))
+#define CENTAUR_PMU4Q0 0x0301043b
+#define CENTAUR_PMU4Q1 0x03010c3b
+#define CENTAUR_PMU5QN(n) (CENTAUR_PMU5Q0 + ((CENTAUR_PMU5Q1 - CENTAUR_PMU5Q0) * (n)))
+#define CENTAUR_PMU5Q0 0x0301043c
+#define CENTAUR_PMU5Q1 0x03010c3c
+#define CENTAUR_PMU6QN(n) (CENTAUR_PMU6Q0 + ((CENTAUR_PMU6Q1 - CENTAUR_PMU6Q0) * (n)))
+#define CENTAUR_PMU6Q0 0x0301043d
+#define CENTAUR_PMU6Q1 0x03010c3d
+#define CENTAUR_SENSOR_CACHE_DATA0_3 0x020115ca
+#define CENTAUR_SENSOR_CACHE_DATA4_7 0x020115cb
+#define CENTAUR_DTS_THERMAL_SENSOR_RESULTS 0x02050000
+
+#endif // __CENTAUR_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/fasti2c_firmware_registers.h b/src/ssx/pgp/registers/fasti2c_firmware_registers.h
new file mode 100644
index 0000000..4390508
--- /dev/null
+++ b/src/ssx/pgp/registers/fasti2c_firmware_registers.h
@@ -0,0 +1,232 @@
+#ifndef __FASTI2C_FIRMWARE_REGISTERS_H__
+#define __FASTI2C_FIRMWARE_REGISTERS_H__
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+// $Id: fasti2c_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+
+/// \file fasti2c_firmware_registers.h
+/// \brief C register structs for the FASTI2C unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#include <stdint.h>
+
+
+
+typedef union fasti2c_control {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t with_start : 1;
+ uint64_t with_address : 1;
+ uint64_t read_continue : 1;
+ uint64_t with_stop : 1;
+ uint64_t data_length : 4;
+ uint64_t device_address : 7;
+ uint64_t read_not_write : 1;
+ uint64_t speed : 2;
+ uint64_t port_number : 5;
+ uint64_t address_range : 3;
+ uint64_t _reserved0 : 6;
+ uint64_t data0 : 8;
+ uint64_t data1 : 8;
+ uint64_t data2 : 8;
+ uint64_t data3 : 8;
+#else
+ uint64_t data3 : 8;
+ uint64_t data2 : 8;
+ uint64_t data1 : 8;
+ uint64_t data0 : 8;
+ uint64_t _reserved0 : 6;
+ uint64_t address_range : 3;
+ uint64_t port_number : 5;
+ uint64_t speed : 2;
+ uint64_t read_not_write : 1;
+ uint64_t device_address : 7;
+ uint64_t data_length : 4;
+ uint64_t with_stop : 1;
+ uint64_t read_continue : 1;
+ uint64_t with_address : 1;
+ uint64_t with_start : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} fasti2c_control_t;
+
+
+
+typedef union fasti2c_reset {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} fasti2c_reset_t;
+
+
+
+typedef union fasti2c_status {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pib_address_invalid : 1;
+ uint64_t pib_write_invalid : 1;
+ uint64_t pib_read_invalid : 1;
+ uint64_t pib_address_parity_error : 1;
+ uint64_t pib_parity_error : 1;
+ uint64_t lb_parity_error : 1;
+ uint64_t read_data : 32;
+ uint64_t _reserved0 : 6;
+ uint64_t i2c_macro_busy : 1;
+ uint64_t i2c_invalid_command : 1;
+ uint64_t i2c_parity_error : 1;
+ uint64_t i2c_back_end_overrun_error : 1;
+ uint64_t i2c_back_end_access_error : 1;
+ uint64_t i2c_arbitration_lost : 1;
+ uint64_t i2c_nack_received : 1;
+ uint64_t i2c_data_request : 1;
+ uint64_t i2c_command_complete : 1;
+ uint64_t i2c_stop_error : 1;
+ uint64_t i2c_port_busy : 1;
+ uint64_t i2c_interface_busy : 1;
+ uint64_t i2c_fifo_entry_count : 8;
+#else
+ uint64_t i2c_fifo_entry_count : 8;
+ uint64_t i2c_interface_busy : 1;
+ uint64_t i2c_port_busy : 1;
+ uint64_t i2c_stop_error : 1;
+ uint64_t i2c_command_complete : 1;
+ uint64_t i2c_data_request : 1;
+ uint64_t i2c_nack_received : 1;
+ uint64_t i2c_arbitration_lost : 1;
+ uint64_t i2c_back_end_access_error : 1;
+ uint64_t i2c_back_end_overrun_error : 1;
+ uint64_t i2c_parity_error : 1;
+ uint64_t i2c_invalid_command : 1;
+ uint64_t i2c_macro_busy : 1;
+ uint64_t _reserved0 : 6;
+ uint64_t read_data : 32;
+ uint64_t lb_parity_error : 1;
+ uint64_t pib_parity_error : 1;
+ uint64_t pib_address_parity_error : 1;
+ uint64_t pib_read_invalid : 1;
+ uint64_t pib_write_invalid : 1;
+ uint64_t pib_address_invalid : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} fasti2c_status_t;
+
+
+
+typedef union fasti2c_data {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} fasti2c_data_t;
+
+
+
+typedef union fasti2c_ecc_start {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} fasti2c_ecc_start_t;
+
+
+
+typedef union fasti2c_ecc_stop {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} fasti2c_ecc_stop_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __FASTI2C_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/fasti2c_register_addresses.h b/src/ssx/pgp/registers/fasti2c_register_addresses.h
new file mode 100644
index 0000000..b034831
--- /dev/null
+++ b/src/ssx/pgp/registers/fasti2c_register_addresses.h
@@ -0,0 +1,27 @@
+#ifndef __FASTI2C_REGISTER_ADDRESSES_H__
+#define __FASTI2C_REGISTER_ADDRESSES_H__
+
+// $Id: fasti2c_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+
+/// \file fasti2c_register_addresses.h
+/// \brief Symbolic addresses for the FASTI2C unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define FASTI2C_LPCM_PIB_BASE 0x0000000b
+#define FASTI2C_CONTROL_OFFSET 0x00000000
+#define FASTI2C_LPCM_CONTROL 0x0000000b
+#define FASTI2C_RESET_OFFSET 0x00000001
+#define FASTI2C_LPCM_RESET 0x0000000c
+#define FASTI2C_STATUS_OFFSET 0x00000002
+#define FASTI2C_LPCM_STATUS 0x0000000d
+#define FASTI2C_DATA_OFFSET 0x00000003
+#define FASTI2C_LPCM_DATA 0x0000000e
+#define FASTI2C_ECC_START_OFFSET 0x00000004
+#define FASTI2C_LPCM_ECC_START 0x0000000f
+#define FASTI2C_ECC_STOP_OFFSET 0x00000005
+#define FASTI2C_LPCM_ECC_STOP 0x00000010
+
+#endif // __FASTI2C_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/i2cengine_firmware_registers.h b/src/ssx/pgp/registers/i2cengine_firmware_registers.h
new file mode 100644
index 0000000..ed02574
--- /dev/null
+++ b/src/ssx/pgp/registers/i2cengine_firmware_registers.h
@@ -0,0 +1,710 @@
+#ifndef __I2CENGINE_FIRMWARE_REGISTERS_H__
+#define __I2CENGINE_FIRMWARE_REGISTERS_H__
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+// $Id: i2cengine_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+
+/// \file i2cengine_firmware_registers.h
+/// \brief C register structs for the I2CENGINE unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#include <stdint.h>
+
+
+
+typedef union i2cengine_fast_control {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t with_start : 1;
+ uint64_t with_address : 1;
+ uint64_t read_continue : 1;
+ uint64_t with_stop : 1;
+ uint64_t data_length : 4;
+ uint64_t device_address : 7;
+ uint64_t read_not_write : 1;
+ uint64_t speed : 2;
+ uint64_t port_number : 5;
+ uint64_t address_range : 3;
+ uint64_t _reserved0 : 6;
+ uint64_t data0 : 8;
+ uint64_t data1 : 8;
+ uint64_t data2 : 8;
+ uint64_t data3 : 8;
+#else
+ uint64_t data3 : 8;
+ uint64_t data2 : 8;
+ uint64_t data1 : 8;
+ uint64_t data0 : 8;
+ uint64_t _reserved0 : 6;
+ uint64_t address_range : 3;
+ uint64_t port_number : 5;
+ uint64_t speed : 2;
+ uint64_t read_not_write : 1;
+ uint64_t device_address : 7;
+ uint64_t data_length : 4;
+ uint64_t with_stop : 1;
+ uint64_t read_continue : 1;
+ uint64_t with_address : 1;
+ uint64_t with_start : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_fast_control_t;
+
+
+
+typedef union i2cengine_fast_reset {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_fast_reset_t;
+
+
+
+typedef union i2cengine_fast_status {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pib_address_invalid : 1;
+ uint64_t pib_write_invalid : 1;
+ uint64_t pib_read_invalid : 1;
+ uint64_t pib_address_parity_error : 1;
+ uint64_t pib_parity_error : 1;
+ uint64_t lb_parity_error : 1;
+ uint64_t read_data : 32;
+ uint64_t _reserved0 : 6;
+ uint64_t i2c_macro_busy : 1;
+ uint64_t i2c_invalid_command : 1;
+ uint64_t i2c_parity_error : 1;
+ uint64_t i2c_back_end_overrun_error : 1;
+ uint64_t i2c_back_end_access_error : 1;
+ uint64_t i2c_arbitration_lost : 1;
+ uint64_t i2c_nack_received : 1;
+ uint64_t i2c_data_request : 1;
+ uint64_t i2c_command_complete : 1;
+ uint64_t i2c_stop_error : 1;
+ uint64_t i2c_port_busy : 1;
+ uint64_t i2c_interface_busy : 1;
+ uint64_t i2c_fifo_entry_count : 8;
+#else
+ uint64_t i2c_fifo_entry_count : 8;
+ uint64_t i2c_interface_busy : 1;
+ uint64_t i2c_port_busy : 1;
+ uint64_t i2c_stop_error : 1;
+ uint64_t i2c_command_complete : 1;
+ uint64_t i2c_data_request : 1;
+ uint64_t i2c_nack_received : 1;
+ uint64_t i2c_arbitration_lost : 1;
+ uint64_t i2c_back_end_access_error : 1;
+ uint64_t i2c_back_end_overrun_error : 1;
+ uint64_t i2c_parity_error : 1;
+ uint64_t i2c_invalid_command : 1;
+ uint64_t i2c_macro_busy : 1;
+ uint64_t _reserved0 : 6;
+ uint64_t read_data : 32;
+ uint64_t lb_parity_error : 1;
+ uint64_t pib_parity_error : 1;
+ uint64_t pib_address_parity_error : 1;
+ uint64_t pib_read_invalid : 1;
+ uint64_t pib_write_invalid : 1;
+ uint64_t pib_address_invalid : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_fast_status_t;
+
+
+
+typedef union i2cengine_fast_data {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_fast_data_t;
+
+
+
+typedef union i2cengine_fifo_byte {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t data : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t data : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_fifo_byte_t;
+
+
+
+typedef union i2cengine_command {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t with_start : 1;
+ uint64_t with_address : 1;
+ uint64_t read_continue : 1;
+ uint64_t not_used : 1;
+ uint64_t reserved : 4;
+ uint64_t device_address : 7;
+ uint64_t read_not_write : 1;
+ uint64_t length_bytes : 16;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t length_bytes : 16;
+ uint64_t read_not_write : 1;
+ uint64_t device_address : 7;
+ uint64_t reserved : 4;
+ uint64_t not_used : 1;
+ uint64_t read_continue : 1;
+ uint64_t with_address : 1;
+ uint64_t with_start : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_command_t;
+
+
+
+typedef union i2cengine_mode {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t bit_rate_divisor : 15;
+ uint64_t _reserved0 : 1;
+ uint64_t port_number : 6;
+ uint64_t reserved : 6;
+ uint64_t enhanced_mode : 1;
+ uint64_t diagnostic_mode : 1;
+ uint64_t pacing_allow_mode : 1;
+ uint64_t wrap_mode : 1;
+ uint64_t _reserved1 : 32;
+#else
+ uint64_t _reserved1 : 32;
+ uint64_t wrap_mode : 1;
+ uint64_t pacing_allow_mode : 1;
+ uint64_t diagnostic_mode : 1;
+ uint64_t enhanced_mode : 1;
+ uint64_t reserved : 6;
+ uint64_t port_number : 6;
+ uint64_t _reserved0 : 1;
+ uint64_t bit_rate_divisor : 15;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_mode_t;
+
+
+
+typedef union i2cengine_watermark {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 15;
+ uint64_t _reserved0 : 1;
+ uint64_t high_water_mark : 4;
+ uint64_t reserved1 : 4;
+ uint64_t low_water_mark : 4;
+ uint64_t reserved2 : 4;
+ uint64_t _reserved1 : 32;
+#else
+ uint64_t _reserved1 : 32;
+ uint64_t reserved2 : 4;
+ uint64_t low_water_mark : 4;
+ uint64_t reserved1 : 4;
+ uint64_t high_water_mark : 4;
+ uint64_t _reserved0 : 1;
+ uint64_t reserved : 15;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_watermark_t;
+
+
+
+typedef union i2cengine_interrupt_mask {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 16;
+ uint64_t invalid_command : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t data_request : 1;
+ uint64_t command_complete : 1;
+ uint64_t stop_error : 1;
+ uint64_t i2c_busy : 1;
+ uint64_t not_i2c_busy : 1;
+ uint64_t reserved1 : 1;
+ uint64_t scl_eq_1 : 1;
+ uint64_t scl_eq_0 : 1;
+ uint64_t sda_eq_1 : 1;
+ uint64_t sda_eq_0 : 1;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t sda_eq_0 : 1;
+ uint64_t sda_eq_1 : 1;
+ uint64_t scl_eq_0 : 1;
+ uint64_t scl_eq_1 : 1;
+ uint64_t reserved1 : 1;
+ uint64_t not_i2c_busy : 1;
+ uint64_t i2c_busy : 1;
+ uint64_t stop_error : 1;
+ uint64_t command_complete : 1;
+ uint64_t data_request : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t invalid_command : 1;
+ uint64_t reserved : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_interrupt_mask_t;
+
+
+
+typedef union i2cengine_interrupt_condition {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 16;
+ uint64_t invalid_command : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t data_request : 1;
+ uint64_t command_complete : 1;
+ uint64_t stop_error : 1;
+ uint64_t i2c_busy : 1;
+ uint64_t not_i2c_busy : 1;
+ uint64_t reserved1 : 1;
+ uint64_t scl_eq_1 : 1;
+ uint64_t scl_eq_0 : 1;
+ uint64_t sda_eq_1 : 1;
+ uint64_t sda_eq_0 : 1;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t sda_eq_0 : 1;
+ uint64_t sda_eq_1 : 1;
+ uint64_t scl_eq_0 : 1;
+ uint64_t scl_eq_1 : 1;
+ uint64_t reserved1 : 1;
+ uint64_t not_i2c_busy : 1;
+ uint64_t i2c_busy : 1;
+ uint64_t stop_error : 1;
+ uint64_t command_complete : 1;
+ uint64_t data_request : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t invalid_command : 1;
+ uint64_t reserved : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_interrupt_condition_t;
+
+
+
+typedef union i2cengine_interrupts {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 16;
+ uint64_t invalid_command : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t data_request : 1;
+ uint64_t command_complete : 1;
+ uint64_t stop_error : 1;
+ uint64_t i2c_busy : 1;
+ uint64_t not_i2c_busy : 1;
+ uint64_t reserved1 : 1;
+ uint64_t scl_eq_1 : 1;
+ uint64_t scl_eq_0 : 1;
+ uint64_t sda_eq_1 : 1;
+ uint64_t sda_eq_0 : 1;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t sda_eq_0 : 1;
+ uint64_t sda_eq_1 : 1;
+ uint64_t scl_eq_0 : 1;
+ uint64_t scl_eq_1 : 1;
+ uint64_t reserved1 : 1;
+ uint64_t not_i2c_busy : 1;
+ uint64_t i2c_busy : 1;
+ uint64_t stop_error : 1;
+ uint64_t command_complete : 1;
+ uint64_t data_request : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t invalid_command : 1;
+ uint64_t reserved : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_interrupts_t;
+
+
+
+typedef union i2cengine_status {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t invalid_command : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t data_request : 1;
+ uint64_t command_complete : 1;
+ uint64_t stop_error : 1;
+ uint64_t upper_threshold : 6;
+ uint64_t _reserved0 : 1;
+ uint64_t any_i2c_interrupt : 1;
+ uint64_t reserved1 : 3;
+ uint64_t scl_input_lvl : 1;
+ uint64_t sda_input_lvl : 1;
+ uint64_t i2c_port_busy : 1;
+ uint64_t i2c_interface_busy : 1;
+ uint64_t fifo_entry_count : 8;
+ uint64_t _reserved1 : 32;
+#else
+ uint64_t _reserved1 : 32;
+ uint64_t fifo_entry_count : 8;
+ uint64_t i2c_interface_busy : 1;
+ uint64_t i2c_port_busy : 1;
+ uint64_t sda_input_lvl : 1;
+ uint64_t scl_input_lvl : 1;
+ uint64_t reserved1 : 3;
+ uint64_t any_i2c_interrupt : 1;
+ uint64_t _reserved0 : 1;
+ uint64_t upper_threshold : 6;
+ uint64_t stop_error : 1;
+ uint64_t command_complete : 1;
+ uint64_t data_request : 1;
+ uint64_t nack_received_error : 1;
+ uint64_t arbitration_lost_error : 1;
+ uint64_t back_end_access_error : 1;
+ uint64_t back_end_overrun_error : 1;
+ uint64_t lbus_parity_error : 1;
+ uint64_t invalid_command : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_status_t;
+
+
+
+typedef union i2cengine_extended_status {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t table_base_addr : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t table_base_addr : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_extended_status_t;
+
+
+
+typedef union i2cengine_residual_front_end_back_end_length {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t residual_front_end_length : 16;
+ uint64_t residual_back_end_length : 16;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t residual_back_end_length : 16;
+ uint64_t residual_front_end_length : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_residual_front_end_back_end_length_t;
+
+
+
+typedef union i2cengine_immediate_reset_s_scl {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t residual_front_end_length : 16;
+ uint64_t residual_back_end_length : 16;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t residual_back_end_length : 16;
+ uint64_t residual_front_end_length : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_immediate_reset_s_scl_t;
+
+
+
+typedef union i2cengine_immediate_set_s_sda {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t residual_front_end_length : 16;
+ uint64_t residual_back_end_length : 16;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t residual_back_end_length : 16;
+ uint64_t residual_front_end_length : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_immediate_set_s_sda_t;
+
+
+
+typedef union i2cengine_immediate_reset_s_sda {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t field : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t field : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_immediate_reset_s_sda_t;
+
+
+
+typedef union i2cengine_fifo_word {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t data : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t data : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} i2cengine_fifo_word_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __I2CENGINE_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/i2cengine_register_addresses.h b/src/ssx/pgp/registers/i2cengine_register_addresses.h
new file mode 100644
index 0000000..bbe9104
--- /dev/null
+++ b/src/ssx/pgp/registers/i2cengine_register_addresses.h
@@ -0,0 +1,33 @@
+#ifndef __I2CENGINE_REGISTER_ADDRESSES_H__
+#define __I2CENGINE_REGISTER_ADDRESSES_H__
+
+// $Id: i2cengine_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+
+/// \file i2cengine_register_addresses.h
+/// \brief Symbolic addresses for the I2CENGINE unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define I2CENGINE_PIB_BASE 0x00000000
+#define I2CENGINE_FAST_CONTROL 0x00000000
+#define I2CENGINE_FAST_RESET 0x00000001
+#define I2CENGINE_FAST_STATUS 0x00000002
+#define I2CENGINE_FAST_DATA 0x00000003
+#define I2CENGINE_FIFO_BYTE 0x00000004
+#define I2CENGINE_COMMAND 0x00000005
+#define I2CENGINE_MODE 0x00000006
+#define I2CENGINE_WATERMARK 0x00000007
+#define I2CENGINE_INTERRUPT_MASK 0x00000008
+#define I2CENGINE_INTERRUPT_CONDITION 0x00000009
+#define I2CENGINE_INTERRUPTS 0x0000000a
+#define I2CENGINE_STATUS 0x0000000b
+#define I2CENGINE_EXTENDED_STATUS 0x0000000c
+#define I2CENGINE_RESIDUAL_FRONT_END_BACK_END_LENGTH 0x0000000d
+#define I2CENGINE_IMMEDIATE_RESET_S_SCL 0x0000000f
+#define I2CENGINE_IMMEDIATE_SET_S_SDA 0x00000010
+#define I2CENGINE_IMMEDIATE_RESET_S_SDA 0x00000011
+#define I2CENGINE_FIFO_WORD 0x00000012
+
+#endif // __I2CENGINE_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/icp_firmware_registers.h b/src/ssx/pgp/registers/icp_firmware_registers.h
new file mode 100755
index 0000000..4e17a68
--- /dev/null
+++ b/src/ssx/pgp/registers/icp_firmware_registers.h
@@ -0,0 +1,189 @@
+#ifndef __ICP_FIRMWARE_REGISTERS_H__
+#define __ICP_FIRMWARE_REGISTERS_H__
+
+// $Id: icp_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/icp_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file icp_firmware_registers.h
+/// \brief C register structs for the ICP unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union icp_bar {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t icp_bar : 30;
+ uint64_t icp_bar_en : 1;
+ uint64_t _reserved0 : 33;
+#else
+ uint64_t _reserved0 : 33;
+ uint64_t icp_bar_en : 1;
+ uint64_t icp_bar : 30;
+#endif // _BIG_ENDIAN
+ } fields;
+} icp_bar_t;
+
+#endif // __ASSEMBLER__
+#define ICP_BAR_ICP_BAR_MASK SIXTYFOUR_BIT_CONSTANT(0xfffffffc00000000)
+#define ICP_BAR_ICP_BAR_EN SIXTYFOUR_BIT_CONSTANT(0x0000000200000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union icp_mode0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t priority : 8;
+ uint64_t reserved0 : 1;
+ uint64_t scope_initial : 3;
+ uint64_t reserved1 : 1;
+ uint64_t no_hang2status : 1;
+ uint64_t oper_disable_hang : 1;
+ uint64_t oper_hang_div : 5;
+ uint64_t reserved2 : 2;
+ uint64_t data_disable_hang : 1;
+ uint64_t data_hang_div : 5;
+ uint64_t backoff_disable : 1;
+ uint64_t fwd_que_fwd_conv_disable : 1;
+ uint64_t disa_wait4cresp_mode4ris : 1;
+ uint64_t disa_auto_no_retry4ris : 1;
+ uint64_t disa_retry_mode4ris : 1;
+ uint64_t hang_on_addr_error : 1;
+ uint64_t eoi_correction : 2;
+ uint64_t max_load_count : 4;
+ uint64_t max_store_count : 4;
+ uint64_t reserved3 : 3;
+ uint64_t enable_inject : 1;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t enable_inject : 1;
+ uint64_t reserved3 : 3;
+ uint64_t max_store_count : 4;
+ uint64_t max_load_count : 4;
+ uint64_t eoi_correction : 2;
+ uint64_t hang_on_addr_error : 1;
+ uint64_t disa_retry_mode4ris : 1;
+ uint64_t disa_auto_no_retry4ris : 1;
+ uint64_t disa_wait4cresp_mode4ris : 1;
+ uint64_t fwd_que_fwd_conv_disable : 1;
+ uint64_t backoff_disable : 1;
+ uint64_t data_hang_div : 5;
+ uint64_t data_disable_hang : 1;
+ uint64_t reserved2 : 2;
+ uint64_t oper_hang_div : 5;
+ uint64_t oper_disable_hang : 1;
+ uint64_t no_hang2status : 1;
+ uint64_t reserved1 : 1;
+ uint64_t scope_initial : 3;
+ uint64_t reserved0 : 1;
+ uint64_t priority : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} icp_mode0_t;
+
+#endif // __ASSEMBLER__
+#define ICP_MODE0_PRIORITY_MASK SIXTYFOUR_BIT_CONSTANT(0xff00000000000000)
+#define ICP_MODE0_SCOPE_INITIAL_MASK SIXTYFOUR_BIT_CONSTANT(0x0070000000000000)
+#define ICP_MODE0_NO_HANG2STATUS SIXTYFOUR_BIT_CONSTANT(0x0004000000000000)
+#define ICP_MODE0_OPER_DISABLE_HANG SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#define ICP_MODE0_OPER_HANG_DIV_MASK SIXTYFOUR_BIT_CONSTANT(0x0001f00000000000)
+#define ICP_MODE0_DATA_DISABLE_HANG SIXTYFOUR_BIT_CONSTANT(0x0000020000000000)
+#define ICP_MODE0_DATA_HANG_DIV_MASK SIXTYFOUR_BIT_CONSTANT(0x000001f000000000)
+#define ICP_MODE0_BACKOFF_DISABLE SIXTYFOUR_BIT_CONSTANT(0x0000000800000000)
+#define ICP_MODE0_FWD_QUE_FWD_CONV_DISABLE SIXTYFOUR_BIT_CONSTANT(0x0000000400000000)
+#define ICP_MODE0_DISA_WAIT4CRESP_MODE4RIS SIXTYFOUR_BIT_CONSTANT(0x0000000200000000)
+#define ICP_MODE0_DISA_AUTO_NO_RETRY4RIS SIXTYFOUR_BIT_CONSTANT(0x0000000100000000)
+#define ICP_MODE0_DISA_RETRY_MODE4RIS SIXTYFOUR_BIT_CONSTANT(0x0000000080000000)
+#define ICP_MODE0_HANG_ON_ADDR_ERROR SIXTYFOUR_BIT_CONSTANT(0x0000000040000000)
+#define ICP_MODE0_EOI_CORRECTION_MASK SIXTYFOUR_BIT_CONSTANT(0x0000000030000000)
+#define ICP_MODE0_MAX_LOAD_COUNT_MASK SIXTYFOUR_BIT_CONSTANT(0x000000000f000000)
+#define ICP_MODE0_MAX_STORE_COUNT_MASK SIXTYFOUR_BIT_CONSTANT(0x0000000000f00000)
+#define ICP_MODE0_ENABLE_INJECT SIXTYFOUR_BIT_CONSTANT(0x0000000000010000)
+#ifndef __ASSEMBLER__
+
+
+typedef union icp_iir {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t inject_target_core : 16;
+ uint64_t inject_target_thread : 8;
+ uint64_t reserved0 : 8;
+ uint64_t inject_level : 4;
+ uint64_t reserved1 : 4;
+ uint64_t inject_priority : 8;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t inject_priority : 8;
+ uint64_t reserved1 : 4;
+ uint64_t inject_level : 4;
+ uint64_t reserved0 : 8;
+ uint64_t inject_target_thread : 8;
+ uint64_t inject_target_core : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} icp_iir_t;
+
+#endif // __ASSEMBLER__
+#define ICP_IIR_INJECT_TARGET_CORE_MASK SIXTYFOUR_BIT_CONSTANT(0xffff000000000000)
+#define ICP_IIR_INJECT_TARGET_THREAD_MASK SIXTYFOUR_BIT_CONSTANT(0x0000ff0000000000)
+#define ICP_IIR_INJECT_LEVEL_MASK SIXTYFOUR_BIT_CONSTANT(0x00000000f0000000)
+#define ICP_IIR_INJECT_PRIORITY_MASK SIXTYFOUR_BIT_CONSTANT(0x0000000000ff0000)
+#ifndef __ASSEMBLER__
+
+#endif // __ASSEMBLER__
+#endif // __ICP_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/icp_register_addresses.h b/src/ssx/pgp/registers/icp_register_addresses.h
new file mode 100755
index 0000000..7cb8350
--- /dev/null
+++ b/src/ssx/pgp/registers/icp_register_addresses.h
@@ -0,0 +1,24 @@
+#ifndef __ICP_REGISTER_ADDRESSES_H__
+#define __ICP_REGISTER_ADDRESSES_H__
+
+// $Id: icp_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/icp_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file icp_register_addresses.h
+/// \brief Symbolic addresses for the ICP unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define ICP_PIB_BASE 0x020109c0
+#define ICP_BAR 0x020109ca
+#define ICP_MODE0 0x020109cb
+#define ICP_IIR 0x020109cc
+
+#endif // __ICP_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/mcs_firmware_registers.h b/src/ssx/pgp/registers/mcs_firmware_registers.h
new file mode 100755
index 0000000..b71b888
--- /dev/null
+++ b/src/ssx/pgp/registers/mcs_firmware_registers.h
@@ -0,0 +1,161 @@
+#ifndef __MCS_FIRMWARE_REGISTERS_H__
+#define __MCS_FIRMWARE_REGISTERS_H__
+
+// $Id: mcs_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/mcs_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file mcs_firmware_registers.h
+/// \brief C register structs for the MCS unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union mcfgpr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t mcfgprq_valid : 1;
+ uint64_t reserved0 : 5;
+ uint64_t mcfgprq_base_address : 14;
+ uint64_t _reserved0 : 44;
+#else
+ uint64_t _reserved0 : 44;
+ uint64_t mcfgprq_base_address : 14;
+ uint64_t reserved0 : 5;
+ uint64_t mcfgprq_valid : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} mcfgpr_t;
+
+#endif // __ASSEMBLER__
+#define MCFGPR_MCFGPRQ_VALID SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define MCFGPR_MCFGPRQ_BASE_ADDRESS_MASK SIXTYFOUR_BIT_CONSTANT(0x03fff00000000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union mcsmode0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t enable_cmd_byp_stutter : 1;
+ uint64_t reserved1 : 1;
+ uint64_t enable_ns_rd_ao_sfu_for_dcbz : 1;
+ uint64_t enable_centaur_local_checkstop_command : 1;
+ uint64_t l3_prefetch_retry_threshold : 4;
+ uint64_t number_of_cl_entries_reserved_for_read : 4;
+ uint64_t number_of_cl_entries_reserved_for_mirrored_ops : 4;
+ uint64_t number_of_cl_entries_reserved_for_writes : 4;
+ uint64_t number_of_cl_entries_reserved_for_cp_writes : 4;
+ uint64_t number_of_cl_entries_reserved_for_cp_ig : 4;
+ uint64_t number_of_cl_entries_reserved_for_htm_ops : 4;
+ uint64_t number_of_cl_entries_reserved_for_ha_assist : 4;
+ uint64_t mcfgrp_19_is_ho_bit : 1;
+ uint64_t cl_channel_timeout_forces_channel_fail : 1;
+ uint64_t enable_fault_line_for_global_checkstop : 1;
+ uint64_t reserved39 : 5;
+ uint64_t address_collision_modes : 9;
+ uint64_t include_cp_ig_in_cp_write_fullness_group : 1;
+ uint64_t enable_dmawr_cmd_bit : 1;
+ uint64_t enable_read_lsfr_data : 1;
+ uint64_t force_channel_fail : 1;
+ uint64_t disable_read_crc_ecc_bypass_taken : 1;
+ uint64_t disable_cl_ao_queueus : 1;
+ uint64_t address_select_lfsr_value : 2;
+ uint64_t enable_centaur_sync : 1;
+ uint64_t write_data_buffer_ecc_check_disable : 1;
+ uint64_t write_data_buffer_ecc_correct_disable : 1;
+#else
+ uint64_t write_data_buffer_ecc_correct_disable : 1;
+ uint64_t write_data_buffer_ecc_check_disable : 1;
+ uint64_t enable_centaur_sync : 1;
+ uint64_t address_select_lfsr_value : 2;
+ uint64_t disable_cl_ao_queueus : 1;
+ uint64_t disable_read_crc_ecc_bypass_taken : 1;
+ uint64_t force_channel_fail : 1;
+ uint64_t enable_read_lsfr_data : 1;
+ uint64_t enable_dmawr_cmd_bit : 1;
+ uint64_t include_cp_ig_in_cp_write_fullness_group : 1;
+ uint64_t address_collision_modes : 9;
+ uint64_t reserved39 : 5;
+ uint64_t enable_fault_line_for_global_checkstop : 1;
+ uint64_t cl_channel_timeout_forces_channel_fail : 1;
+ uint64_t mcfgrp_19_is_ho_bit : 1;
+ uint64_t number_of_cl_entries_reserved_for_ha_assist : 4;
+ uint64_t number_of_cl_entries_reserved_for_htm_ops : 4;
+ uint64_t number_of_cl_entries_reserved_for_cp_ig : 4;
+ uint64_t number_of_cl_entries_reserved_for_cp_writes : 4;
+ uint64_t number_of_cl_entries_reserved_for_writes : 4;
+ uint64_t number_of_cl_entries_reserved_for_mirrored_ops : 4;
+ uint64_t number_of_cl_entries_reserved_for_read : 4;
+ uint64_t l3_prefetch_retry_threshold : 4;
+ uint64_t enable_centaur_local_checkstop_command : 1;
+ uint64_t enable_ns_rd_ao_sfu_for_dcbz : 1;
+ uint64_t reserved1 : 1;
+ uint64_t enable_cmd_byp_stutter : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} mcsmode0_t;
+
+#endif // __ASSEMBLER__
+#define MCSMODE0_ENABLE_CMD_BYP_STUTTER SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define MCSMODE0_ENABLE_NS_RD_AO_SFU_FOR_DCBZ SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define MCSMODE0_ENABLE_CENTAUR_LOCAL_CHECKSTOP_COMMAND SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define MCSMODE0_L3_PREFETCH_RETRY_THRESHOLD_MASK SIXTYFOUR_BIT_CONSTANT(0x0f00000000000000)
+#define MCSMODE0_MCFGRP_19_IS_HO_BIT SIXTYFOUR_BIT_CONSTANT(0x0000000008000000)
+#define MCSMODE0_CL_CHANNEL_TIMEOUT_FORCES_CHANNEL_FAIL SIXTYFOUR_BIT_CONSTANT(0x0000000004000000)
+#define MCSMODE0_ENABLE_FAULT_LINE_FOR_GLOBAL_CHECKSTOP SIXTYFOUR_BIT_CONSTANT(0x0000000002000000)
+#define MCSMODE0_ADDRESS_COLLISION_MODES_MASK SIXTYFOUR_BIT_CONSTANT(0x00000000000ff800)
+#define MCSMODE0_INCLUDE_CP_IG_IN_CP_WRITE_FULLNESS_GROUP SIXTYFOUR_BIT_CONSTANT(0x0000000000000400)
+#define MCSMODE0_ENABLE_DMAWR_CMD_BIT SIXTYFOUR_BIT_CONSTANT(0x0000000000000200)
+#define MCSMODE0_ENABLE_READ_LSFR_DATA SIXTYFOUR_BIT_CONSTANT(0x0000000000000100)
+#define MCSMODE0_FORCE_CHANNEL_FAIL SIXTYFOUR_BIT_CONSTANT(0x0000000000000080)
+#define MCSMODE0_DISABLE_READ_CRC_ECC_BYPASS_TAKEN SIXTYFOUR_BIT_CONSTANT(0x0000000000000040)
+#define MCSMODE0_DISABLE_CL_AO_QUEUEUS SIXTYFOUR_BIT_CONSTANT(0x0000000000000020)
+#define MCSMODE0_ADDRESS_SELECT_LFSR_VALUE_MASK SIXTYFOUR_BIT_CONSTANT(0x0000000000000018)
+#define MCSMODE0_ENABLE_CENTAUR_SYNC SIXTYFOUR_BIT_CONSTANT(0x0000000000000004)
+#define MCSMODE0_WRITE_DATA_BUFFER_ECC_CHECK_DISABLE SIXTYFOUR_BIT_CONSTANT(0x0000000000000002)
+#define MCSMODE0_WRITE_DATA_BUFFER_ECC_CORRECT_DISABLE SIXTYFOUR_BIT_CONSTANT(0x0000000000000001)
+#ifndef __ASSEMBLER__
+
+#endif // __ASSEMBLER__
+#endif // __MCS_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/mcs_register_addresses.h b/src/ssx/pgp/registers/mcs_register_addresses.h
new file mode 100755
index 0000000..bc7f95c
--- /dev/null
+++ b/src/ssx/pgp/registers/mcs_register_addresses.h
@@ -0,0 +1,46 @@
+#ifndef __MCS_REGISTER_ADDRESSES_H__
+#define __MCS_REGISTER_ADDRESSES_H__
+
+// $Id: mcs_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/mcs_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file mcs_register_addresses.h
+/// \brief Symbolic addresses for the MCS unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define MCS0_PIB_BASE 0x02011800
+#define MCS1_PIB_BASE 0x02011880
+#define MCS2_PIB_BASE 0x02011900
+#define MCS3_PIB_BASE 0x02011980
+#define MCS4_PIB_BASE 0x02011C00
+#define MCS5_PIB_BASE 0x02011C80
+#define MCS6_PIB_BASE 0x02011D00
+#define MCS7_PIB_BASE 0x02011D80
+#define MCFGPR_OFFSET 0x00000002
+#define MCS0_MCFGPR 0x02011802
+#define MCS1_MCFGPR 0x02011882
+#define MCS2_MCFGPR 0x02011902
+#define MCS3_MCFGPR 0x02011982
+#define MCS4_MCFGPR 0x02011c02
+#define MCS5_MCFGPR 0x02011c82
+#define MCS6_MCFGPR 0x02011d02
+#define MCS7_MCFGPR 0x02011d82
+#define MCSMODE0_OFFSET 0x00000007
+#define MCS0_MCSMODE0 0x02011807
+#define MCS1_MCSMODE0 0x02011887
+#define MCS2_MCSMODE0 0x02011907
+#define MCS3_MCSMODE0 0x02011987
+#define MCS4_MCSMODE0 0x02011c07
+#define MCS5_MCSMODE0 0x02011c87
+#define MCS6_MCSMODE0 0x02011d07
+#define MCS7_MCSMODE0 0x02011d87
+
+#endif // __MCS_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/ocb_firmware_registers.h b/src/ssx/pgp/registers/ocb_firmware_registers.h
new file mode 100755
index 0000000..4a4ddb2
--- /dev/null
+++ b/src/ssx/pgp/registers/ocb_firmware_registers.h
@@ -0,0 +1,2668 @@
+#ifndef __OCB_FIRMWARE_REGISTERS_H__
+#define __OCB_FIRMWARE_REGISTERS_H__
+
+// $Id: ocb_firmware_registers.h,v 1.2 2014/03/14 15:33:03 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/ocb_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2014
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ocb_firmware_registers.h
+/// \brief C register structs for the OCB unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union ocb_oitr0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oitr0_t;
+
+
+
+typedef union ocb_oiepr0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oiepr0_t;
+
+
+
+typedef union ocb_ocir0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocir0_t;
+
+
+
+typedef union ocb_onisr0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_onisr0_t;
+
+
+
+typedef union ocb_ouder0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ouder0_t;
+
+
+
+typedef union ocb_ocisr0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocisr0_t;
+
+
+
+typedef union ocb_odher0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t dbg_halt_en : 32;
+#else
+ uint32_t dbg_halt_en : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_odher0_t;
+
+
+
+typedef union ocb_oisr0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t debugger : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t pba_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t spipss_error : 1;
+ uint32_t check_stop : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t external_trap : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t reserved_31 : 1;
+#else
+ uint32_t reserved_31 : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t external_trap : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t check_stop : 1;
+ uint32_t spipss_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pba_error : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t debugger : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oisr0_t;
+
+
+
+typedef union ocb_oisr0_and {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t debugger : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t pba_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t spipss_error : 1;
+ uint32_t check_stop : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t external_trap : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t reserved_31 : 1;
+#else
+ uint32_t reserved_31 : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t external_trap : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t check_stop : 1;
+ uint32_t spipss_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pba_error : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t debugger : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oisr0_and_t;
+
+
+
+typedef union ocb_oisr0_or {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t debugger : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t pba_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t spipss_error : 1;
+ uint32_t check_stop : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t external_trap : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t reserved_31 : 1;
+#else
+ uint32_t reserved_31 : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t external_trap : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t check_stop : 1;
+ uint32_t spipss_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pba_error : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t debugger : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oisr0_or_t;
+
+
+
+typedef union ocb_oimr0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t debugger : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t pba_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t spipss_error : 1;
+ uint32_t check_stop : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t external_trap : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t reserved_31 : 1;
+#else
+ uint32_t reserved_31 : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t external_trap : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t check_stop : 1;
+ uint32_t spipss_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pba_error : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t debugger : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oimr0_t;
+
+
+
+typedef union ocb_oimr0_and {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t debugger : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t pba_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t spipss_error : 1;
+ uint32_t check_stop : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t external_trap : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t reserved_31 : 1;
+#else
+ uint32_t reserved_31 : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t external_trap : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t check_stop : 1;
+ uint32_t spipss_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pba_error : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t debugger : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oimr0_and_t;
+
+
+
+typedef union ocb_oimr0_or {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t debugger : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t pba_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t spipss_error : 1;
+ uint32_t check_stop : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t external_trap : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t reserved_31 : 1;
+#else
+ uint32_t reserved_31 : 1;
+ uint32_t pba_bcue_attn : 1;
+ uint32_t pba_bcde_attn : 1;
+ uint32_t pba_occ_push1 : 1;
+ uint32_t pba_occ_push0 : 1;
+ uint32_t reserved_26 : 1;
+ uint32_t adcfsm_ongoing : 1;
+ uint32_t pore_gpe1_complete : 1;
+ uint32_t pore_gpe0_complete : 1;
+ uint32_t reserved_22 : 1;
+ uint32_t pmc_interchip_msg_recv : 1;
+ uint32_t pore_sbe_error : 1;
+ uint32_t pore_gpe1_error : 1;
+ uint32_t pore_gpe0_error : 1;
+ uint32_t occ_timer1 : 1;
+ uint32_t occ_timer0 : 1;
+ uint32_t external_trap : 1;
+ uint32_t adu_malf_alert : 1;
+ uint32_t pmc_malf_alert : 1;
+ uint32_t check_stop : 1;
+ uint32_t spipss_error : 1;
+ uint32_t ocb_error : 1;
+ uint32_t pmc_error : 1;
+ uint32_t pore_sbe_fatal_error : 1;
+ uint32_t pore_gpe1_fatal_error : 1;
+ uint32_t pore_gpe0_fatal_error : 1;
+ uint32_t pore_sw_error : 1;
+ uint32_t srt_error : 1;
+ uint32_t pba_error : 1;
+ uint32_t reserved_2 : 1;
+ uint32_t trace_trigger : 1;
+ uint32_t debugger : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oimr0_or_t;
+
+
+
+typedef union ocb_oitr1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oitr1_t;
+
+
+
+typedef union ocb_oiepr1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oiepr1_t;
+
+
+
+typedef union ocb_ocir1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocir1_t;
+
+
+
+typedef union ocb_onisr1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_onisr1_t;
+
+
+
+typedef union ocb_ouder1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ouder1_t;
+
+
+
+typedef union ocb_ocisr1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocisr1_t;
+
+
+
+typedef union ocb_odher1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t dbg_halt_en : 32;
+#else
+ uint32_t dbg_halt_en : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_odher1_t;
+
+
+
+typedef union ocb_oisr1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved_32 : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t ipi0 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t reserved_63 : 1;
+#else
+ uint32_t reserved_63 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi0 : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t reserved_32 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oisr1_t;
+
+
+
+typedef union ocb_oisr1_and {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved_32 : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t ipi0 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t reserved_63 : 1;
+#else
+ uint32_t reserved_63 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi0 : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t reserved_32 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oisr1_and_t;
+
+
+
+typedef union ocb_oisr1_or {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved_32 : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t ipi0 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t reserved_63 : 1;
+#else
+ uint32_t reserved_63 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi0 : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t reserved_32 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oisr1_or_t;
+
+
+
+typedef union ocb_oimr1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved_32 : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t ipi0 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t reserved_63 : 1;
+#else
+ uint32_t reserved_63 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi0 : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t reserved_32 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oimr1_t;
+
+
+
+typedef union ocb_oimr1_and {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved_32 : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t ipi0 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t reserved_63 : 1;
+#else
+ uint32_t reserved_63 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi0 : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t reserved_32 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oimr1_and_t;
+
+
+
+typedef union ocb_oimr1_or {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved_32 : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t ipi0 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t reserved_63 : 1;
+#else
+ uint32_t reserved_63 : 1;
+ uint32_t ipi3 : 1;
+ uint32_t ipi2 : 1;
+ uint32_t ipi1 : 1;
+ uint32_t ipi0 : 1;
+ uint32_t pore_sbe_complete : 1;
+ uint32_t pssbridge_ongoing : 1;
+ uint32_t pmc_ocb_o2p_ongoing : 1;
+ uint32_t oci2spivid_ongoing : 1;
+ uint32_t pmc_interchip_msg_send_ongoing : 1;
+ uint32_t reserved_53 : 1;
+ uint32_t pmc_idle_enter : 1;
+ uint32_t pore_sw_complete : 1;
+ uint32_t pmc_idle_exit : 1;
+ uint32_t reserved_49 : 1;
+ uint32_t reserved_48 : 1;
+ uint32_t pmc_pstate_change : 1;
+ uint32_t pmc_sync : 1;
+ uint32_t pmc_protocol_ongoing : 1;
+ uint32_t pmc_voltage_change_ongoing : 1;
+ uint32_t reserved_43 : 1;
+ uint32_t reserved_42 : 1;
+ uint32_t occ_strm3_push : 1;
+ uint32_t occ_strm3_pull : 1;
+ uint32_t occ_strm2_push : 1;
+ uint32_t occ_strm2_pull : 1;
+ uint32_t occ_strm1_push : 1;
+ uint32_t occ_strm1_pull : 1;
+ uint32_t occ_strm0_push : 1;
+ uint32_t occ_strm0_pull : 1;
+ uint32_t reserved_33 : 1;
+ uint32_t reserved_32 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oimr1_or_t;
+
+
+
+typedef union ocb_occmisc {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t core_ext_intr : 1;
+ uint32_t _reserved0 : 31;
+#else
+ uint32_t _reserved0 : 31;
+ uint32_t core_ext_intr : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occmisc_t;
+
+
+
+typedef union ocb_occmisc_and {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t core_ext_intr : 1;
+ uint32_t _reserved0 : 31;
+#else
+ uint32_t _reserved0 : 31;
+ uint32_t core_ext_intr : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occmisc_and_t;
+
+
+
+typedef union ocb_occmisc_or {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t core_ext_intr : 1;
+ uint32_t _reserved0 : 31;
+#else
+ uint32_t _reserved0 : 31;
+ uint32_t core_ext_intr : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occmisc_or_t;
+
+
+
+typedef union ocb_otrn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t timeout : 1;
+ uint32_t control : 1;
+ uint32_t auto_reload : 1;
+ uint32_t reserved : 13;
+ uint32_t timer : 16;
+#else
+ uint32_t timer : 16;
+ uint32_t reserved : 13;
+ uint32_t auto_reload : 1;
+ uint32_t control : 1;
+ uint32_t timeout : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_otrn_t;
+
+#endif // __ASSEMBLER__
+#define OCB_OTRN_TIMEOUT 0x80000000
+#define OCB_OTRN_CONTROL 0x40000000
+#define OCB_OTRN_AUTO_RELOAD 0x20000000
+#define OCB_OTRN_TIMER_MASK 0x0000ffff
+#ifndef __ASSEMBLER__
+
+
+typedef union ocb_ohtmcr {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t htm_src_sel : 2;
+ uint32_t htm_stop : 1;
+ uint32_t htm_marker_slave_adrs : 3;
+ uint32_t event2halt_mode : 2;
+ uint32_t event2halt_en : 11;
+ uint32_t reserved : 1;
+ uint32_t event2halt_halt : 1;
+ uint32_t _reserved0 : 11;
+#else
+ uint32_t _reserved0 : 11;
+ uint32_t event2halt_halt : 1;
+ uint32_t reserved : 1;
+ uint32_t event2halt_en : 11;
+ uint32_t event2halt_mode : 2;
+ uint32_t htm_marker_slave_adrs : 3;
+ uint32_t htm_stop : 1;
+ uint32_t htm_src_sel : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ohtmcr_t;
+
+
+
+typedef union ocb_oehdr {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t event2halt_delay : 20;
+ uint32_t _reserved0 : 12;
+#else
+ uint32_t _reserved0 : 12;
+ uint32_t event2halt_delay : 20;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oehdr_t;
+
+
+
+typedef union ocb_ocbslbrn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pull_oci_region : 2;
+ uint32_t pull_start : 27;
+ uint32_t _reserved0 : 3;
+#else
+ uint32_t _reserved0 : 3;
+ uint32_t pull_start : 27;
+ uint32_t pull_oci_region : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbslbrn_t;
+
+
+
+typedef union ocb_ocbshbrn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t push_oci_region : 2;
+ uint32_t push_start : 27;
+ uint32_t _reserved0 : 3;
+#else
+ uint32_t _reserved0 : 3;
+ uint32_t push_start : 27;
+ uint32_t push_oci_region : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbshbrn_t;
+
+
+
+typedef union ocb_ocbslcsn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pull_full : 1;
+ uint32_t pull_empty : 1;
+ uint32_t reserved0 : 2;
+ uint32_t pull_intr_action : 2;
+ uint32_t pull_length : 5;
+ uint32_t reserved1 : 2;
+ uint32_t pull_write_ptr : 5;
+ uint32_t reserved2 : 3;
+ uint32_t pull_read_ptr : 5;
+ uint32_t reserved3 : 5;
+ uint32_t pull_enable : 1;
+#else
+ uint32_t pull_enable : 1;
+ uint32_t reserved3 : 5;
+ uint32_t pull_read_ptr : 5;
+ uint32_t reserved2 : 3;
+ uint32_t pull_write_ptr : 5;
+ uint32_t reserved1 : 2;
+ uint32_t pull_length : 5;
+ uint32_t pull_intr_action : 2;
+ uint32_t reserved0 : 2;
+ uint32_t pull_empty : 1;
+ uint32_t pull_full : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbslcsn_t;
+
+#endif // __ASSEMBLER__
+#define OCB_OCBSLCSN_PULL_FULL 0x80000000
+#define OCB_OCBSLCSN_PULL_EMPTY 0x40000000
+#define OCB_OCBSLCSN_PULL_INTR_ACTION_MASK 0x0c000000
+#define OCB_OCBSLCSN_PULL_LENGTH_MASK 0x03e00000
+#define OCB_OCBSLCSN_PULL_WRITE_PTR_MASK 0x0007c000
+#define OCB_OCBSLCSN_PULL_READ_PTR_MASK 0x000007c0
+#define OCB_OCBSLCSN_PULL_ENABLE 0x00000001
+#ifndef __ASSEMBLER__
+
+
+typedef union ocb_ocbshcsn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t push_full : 1;
+ uint32_t push_empty : 1;
+ uint32_t reserved0 : 2;
+ uint32_t push_intr_action : 2;
+ uint32_t push_length : 5;
+ uint32_t reserved1 : 2;
+ uint32_t push_write_ptr : 5;
+ uint32_t reserved2 : 3;
+ uint32_t push_read_ptr : 5;
+ uint32_t reserved3 : 5;
+ uint32_t push_enable : 1;
+#else
+ uint32_t push_enable : 1;
+ uint32_t reserved3 : 5;
+ uint32_t push_read_ptr : 5;
+ uint32_t reserved2 : 3;
+ uint32_t push_write_ptr : 5;
+ uint32_t reserved1 : 2;
+ uint32_t push_length : 5;
+ uint32_t push_intr_action : 2;
+ uint32_t reserved0 : 2;
+ uint32_t push_empty : 1;
+ uint32_t push_full : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbshcsn_t;
+
+#endif // __ASSEMBLER__
+#define OCB_OCBSHCSN_PUSH_FULL 0x80000000
+#define OCB_OCBSHCSN_PUSH_EMPTY 0x40000000
+#define OCB_OCBSHCSN_PUSH_INTR_ACTION_MASK 0x0c000000
+#define OCB_OCBSHCSN_PUSH_LENGTH_MASK 0x03e00000
+#define OCB_OCBSHCSN_PUSH_WRITE_PTR_MASK 0x0007c000
+#define OCB_OCBSHCSN_PUSH_READ_PTR_MASK 0x000007c0
+#define OCB_OCBSHCSN_PUSH_ENABLE 0x00000001
+#ifndef __ASSEMBLER__
+
+
+typedef union ocb_ocbslin {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved : 32;
+#else
+ uint32_t reserved : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbslin_t;
+
+
+
+typedef union ocb_ocbshin {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved : 32;
+#else
+ uint32_t reserved : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbshin_t;
+
+
+
+typedef union ocb_ocbsesn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t push_read_underflow : 1;
+ uint32_t pull_write_overflow : 1;
+ uint32_t _reserved0 : 30;
+#else
+ uint32_t _reserved0 : 30;
+ uint32_t pull_write_overflow : 1;
+ uint32_t push_read_underflow : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbsesn_t;
+
+
+
+typedef union ocb_ocbicrn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t allow_unsecure_pib_masters : 1;
+ uint32_t _reserved0 : 31;
+#else
+ uint32_t _reserved0 : 31;
+ uint32_t allow_unsecure_pib_masters : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbicrn_t;
+
+
+
+typedef union ocb_ocblwcrn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t linear_window_enable : 1;
+ uint32_t spare_0 : 3;
+ uint32_t linear_window_bar : 16;
+ uint32_t linear_window_mask : 12;
+#else
+ uint32_t linear_window_mask : 12;
+ uint32_t linear_window_bar : 16;
+ uint32_t spare_0 : 3;
+ uint32_t linear_window_enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocblwcrn_t;
+
+
+
+typedef union ocb_ocblwsrn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t linear_window_scresp : 3;
+ uint32_t spare_0 : 5;
+ uint32_t _reserved0 : 24;
+#else
+ uint32_t _reserved0 : 24;
+ uint32_t spare_0 : 5;
+ uint32_t linear_window_scresp : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocblwsrn_t;
+
+
+
+typedef union ocb_ocblwsbrn {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t linear_window_region : 2;
+ uint32_t linear_window_base : 8;
+ uint32_t _reserved0 : 22;
+#else
+ uint32_t _reserved0 : 22;
+ uint32_t linear_window_base : 8;
+ uint32_t linear_window_region : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocblwsbrn_t;
+
+
+
+typedef union ocb_ocichsw {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t m0_priority : 2;
+ uint32_t m1_priority : 2;
+ uint32_t m2_priority : 2;
+ uint32_t m3_priority : 2;
+ uint32_t m4_priority : 2;
+ uint32_t m5_priority : 2;
+ uint32_t m6_priority : 2;
+ uint32_t m7_priority : 2;
+ uint32_t dcu_priority_sel : 1;
+ uint32_t icu_priority_sel : 1;
+ uint32_t plbarb_lockerr : 1;
+ uint32_t _reserved0 : 13;
+#else
+ uint32_t _reserved0 : 13;
+ uint32_t plbarb_lockerr : 1;
+ uint32_t icu_priority_sel : 1;
+ uint32_t dcu_priority_sel : 1;
+ uint32_t m7_priority : 2;
+ uint32_t m6_priority : 2;
+ uint32_t m5_priority : 2;
+ uint32_t m4_priority : 2;
+ uint32_t m3_priority : 2;
+ uint32_t m2_priority : 2;
+ uint32_t m1_priority : 2;
+ uint32_t m0_priority : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocichsw_t;
+
+
+
+typedef union ocb_ocr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_reset : 1;
+ uint64_t chip_reset : 1;
+ uint64_t system_reset : 1;
+ uint64_t oci_arb_reset : 1;
+ uint64_t trace_disable : 1;
+ uint64_t trace_event : 1;
+ uint64_t dbg_unconditional_event : 1;
+ uint64_t ext_interrupt : 1;
+ uint64_t critical_interrupt : 1;
+ uint64_t spare : 7;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ uint64_t spare : 7;
+ uint64_t critical_interrupt : 1;
+ uint64_t ext_interrupt : 1;
+ uint64_t dbg_unconditional_event : 1;
+ uint64_t trace_event : 1;
+ uint64_t trace_disable : 1;
+ uint64_t oci_arb_reset : 1;
+ uint64_t system_reset : 1;
+ uint64_t chip_reset : 1;
+ uint64_t core_reset : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocr_t;
+
+
+
+typedef union ocb_ocr_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_reset : 1;
+ uint64_t chip_reset : 1;
+ uint64_t system_reset : 1;
+ uint64_t oci_arb_reset : 1;
+ uint64_t trace_disable : 1;
+ uint64_t trace_event : 1;
+ uint64_t dbg_unconditional_event : 1;
+ uint64_t ext_interrupt : 1;
+ uint64_t critical_interrupt : 1;
+ uint64_t spare : 7;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ uint64_t spare : 7;
+ uint64_t critical_interrupt : 1;
+ uint64_t ext_interrupt : 1;
+ uint64_t dbg_unconditional_event : 1;
+ uint64_t trace_event : 1;
+ uint64_t trace_disable : 1;
+ uint64_t oci_arb_reset : 1;
+ uint64_t system_reset : 1;
+ uint64_t chip_reset : 1;
+ uint64_t core_reset : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocr_and_t;
+
+
+
+typedef union ocb_ocr_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_reset : 1;
+ uint64_t chip_reset : 1;
+ uint64_t system_reset : 1;
+ uint64_t oci_arb_reset : 1;
+ uint64_t trace_disable : 1;
+ uint64_t trace_event : 1;
+ uint64_t dbg_unconditional_event : 1;
+ uint64_t ext_interrupt : 1;
+ uint64_t critical_interrupt : 1;
+ uint64_t spare : 7;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ uint64_t spare : 7;
+ uint64_t critical_interrupt : 1;
+ uint64_t ext_interrupt : 1;
+ uint64_t dbg_unconditional_event : 1;
+ uint64_t trace_event : 1;
+ uint64_t trace_disable : 1;
+ uint64_t oci_arb_reset : 1;
+ uint64_t system_reset : 1;
+ uint64_t chip_reset : 1;
+ uint64_t core_reset : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocr_or_t;
+
+
+
+typedef union ocb_ocdbg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 12;
+ uint64_t _reserved0 : 52;
+#else
+ uint64_t _reserved0 : 52;
+ uint64_t value : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocdbg_t;
+
+
+
+typedef union ocb_ocbarn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_region : 2;
+ uint64_t ocb_address : 27;
+ uint64_t reserved : 3;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t reserved : 3;
+ uint64_t ocb_address : 27;
+ uint64_t oci_region : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbarn_t;
+
+#endif // __ASSEMBLER__
+#define OCB_OCBARN_OCI_REGION_MASK SIXTYFOUR_BIT_CONSTANT(0xc000000000000000)
+#define OCB_OCBARN_OCB_ADDRESS_MASK SIXTYFOUR_BIT_CONSTANT(0x3ffffff800000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union ocb_ocbcsrn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pull_read_underflow : 1;
+ uint64_t push_write_overflow : 1;
+ uint64_t pull_read_underflow_en : 1;
+ uint64_t push_write_overflow_en : 1;
+ uint64_t ocb_stream_mode : 1;
+ uint64_t ocb_stream_type : 1;
+ uint64_t reserved1 : 2;
+ uint64_t ocb_oci_timeout : 1;
+ uint64_t ocb_oci_read_data_parity : 1;
+ uint64_t ocb_oci_slave_error : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_pib_data_parity_err : 1;
+ uint64_t reserved2 : 1;
+ uint64_t ocb_fsm_err : 1;
+ uint64_t _reserved0 : 49;
+#else
+ uint64_t _reserved0 : 49;
+ uint64_t ocb_fsm_err : 1;
+ uint64_t reserved2 : 1;
+ uint64_t ocb_pib_data_parity_err : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_oci_slave_error : 1;
+ uint64_t ocb_oci_read_data_parity : 1;
+ uint64_t ocb_oci_timeout : 1;
+ uint64_t reserved1 : 2;
+ uint64_t ocb_stream_type : 1;
+ uint64_t ocb_stream_mode : 1;
+ uint64_t push_write_overflow_en : 1;
+ uint64_t pull_read_underflow_en : 1;
+ uint64_t push_write_overflow : 1;
+ uint64_t pull_read_underflow : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbcsrn_t;
+
+#endif // __ASSEMBLER__
+#define OCB_OCBCSRN_PULL_READ_UNDERFLOW SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define OCB_OCBCSRN_PUSH_WRITE_OVERFLOW SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define OCB_OCBCSRN_PULL_READ_UNDERFLOW_EN SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define OCB_OCBCSRN_PUSH_WRITE_OVERFLOW_EN SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define OCB_OCBCSRN_OCB_STREAM_MODE SIXTYFOUR_BIT_CONSTANT(0x0800000000000000)
+#define OCB_OCBCSRN_OCB_STREAM_TYPE SIXTYFOUR_BIT_CONSTANT(0x0400000000000000)
+#define OCB_OCBCSRN_OCB_OCI_TIMEOUT SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define OCB_OCBCSRN_OCB_OCI_READ_DATA_PARITY SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define OCB_OCBCSRN_OCB_OCI_SLAVE_ERROR SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define OCB_OCBCSRN_OCB_PIB_ADDR_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0010000000000000)
+#define OCB_OCBCSRN_OCB_PIB_DATA_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0008000000000000)
+#define OCB_OCBCSRN_OCB_FSM_ERR SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union ocb_ocbcsrn_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pull_read_underflow : 1;
+ uint64_t push_write_overflow : 1;
+ uint64_t pull_read_underflow_en : 1;
+ uint64_t push_write_overflow_en : 1;
+ uint64_t ocb_stream_mode : 1;
+ uint64_t ocb_stream_type : 1;
+ uint64_t reserved1 : 2;
+ uint64_t ocb_oci_timeout : 1;
+ uint64_t ocb_oci_read_data_parity : 1;
+ uint64_t ocb_oci_slave_error : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_pib_data_parity_err : 1;
+ uint64_t reserved2 : 1;
+ uint64_t ocb_fsm_err : 1;
+ uint64_t _reserved0 : 49;
+#else
+ uint64_t _reserved0 : 49;
+ uint64_t ocb_fsm_err : 1;
+ uint64_t reserved2 : 1;
+ uint64_t ocb_pib_data_parity_err : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_oci_slave_error : 1;
+ uint64_t ocb_oci_read_data_parity : 1;
+ uint64_t ocb_oci_timeout : 1;
+ uint64_t reserved1 : 2;
+ uint64_t ocb_stream_type : 1;
+ uint64_t ocb_stream_mode : 1;
+ uint64_t push_write_overflow_en : 1;
+ uint64_t pull_read_underflow_en : 1;
+ uint64_t push_write_overflow : 1;
+ uint64_t pull_read_underflow : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbcsrn_and_t;
+
+
+
+typedef union ocb_ocbcsrn_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pull_read_underflow : 1;
+ uint64_t push_write_overflow : 1;
+ uint64_t pull_read_underflow_en : 1;
+ uint64_t push_write_overflow_en : 1;
+ uint64_t ocb_stream_mode : 1;
+ uint64_t ocb_stream_type : 1;
+ uint64_t reserved1 : 2;
+ uint64_t ocb_oci_timeout : 1;
+ uint64_t ocb_oci_read_data_parity : 1;
+ uint64_t ocb_oci_slave_error : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_pib_data_parity_err : 1;
+ uint64_t reserved2 : 1;
+ uint64_t ocb_fsm_err : 1;
+ uint64_t _reserved0 : 49;
+#else
+ uint64_t _reserved0 : 49;
+ uint64_t ocb_fsm_err : 1;
+ uint64_t reserved2 : 1;
+ uint64_t ocb_pib_data_parity_err : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_oci_slave_error : 1;
+ uint64_t ocb_oci_read_data_parity : 1;
+ uint64_t ocb_oci_timeout : 1;
+ uint64_t reserved1 : 2;
+ uint64_t ocb_stream_type : 1;
+ uint64_t ocb_stream_mode : 1;
+ uint64_t push_write_overflow_en : 1;
+ uint64_t pull_read_underflow_en : 1;
+ uint64_t push_write_overflow : 1;
+ uint64_t pull_read_underflow : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbcsrn_or_t;
+
+
+
+typedef union ocb_ocbesrn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ocb_error_addr : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t ocb_error_addr : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbesrn_t;
+
+
+
+typedef union ocb_ocbdrn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ocb_data : 64;
+#else
+ uint64_t ocb_data : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_ocbdrn_t;
+
+
+
+typedef union ocb_osbcr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_block_unsecure_masters : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t occ_block_unsecure_masters : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_osbcr_t;
+
+
+
+typedef union ocb_otdcr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t trace_bus_en : 1;
+ uint64_t ocb_trace_mux_sel : 1;
+ uint64_t occ_trace_mux_sel : 2;
+ uint64_t oci_trace_mux_sel : 4;
+ uint64_t _reserved0 : 56;
+#else
+ uint64_t _reserved0 : 56;
+ uint64_t oci_trace_mux_sel : 4;
+ uint64_t occ_trace_mux_sel : 2;
+ uint64_t ocb_trace_mux_sel : 1;
+ uint64_t trace_bus_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_otdcr_t;
+
+
+
+typedef union ocb_oppcinj {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_err_inj_dcu : 1;
+ uint64_t oci_err_inj_icu : 1;
+ uint64_t oci_err_inj_ce_ue : 1;
+ uint64_t oci_err_inj_singl_cont : 1;
+ uint64_t _reserved0 : 60;
+#else
+ uint64_t _reserved0 : 60;
+ uint64_t oci_err_inj_singl_cont : 1;
+ uint64_t oci_err_inj_ce_ue : 1;
+ uint64_t oci_err_inj_icu : 1;
+ uint64_t oci_err_inj_dcu : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_oppcinj_t;
+
+
+
+typedef union ocb_occlfir {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_fw0 : 1;
+ uint64_t occ_fw1 : 1;
+ uint64_t occ_fw2 : 1;
+ uint64_t occ_fw3 : 1;
+ uint64_t pmc_pore_sw_malf : 1;
+ uint64_t pmc_occ_hb_malf : 1;
+ uint64_t pore_gpe0_fatal_err : 1;
+ uint64_t pore_gpe1_fatal_err : 1;
+ uint64_t ocb_error : 1;
+ uint64_t pmc_error : 1;
+ uint64_t srt_ue : 1;
+ uint64_t srt_ce : 1;
+ uint64_t srt_read_error : 1;
+ uint64_t srt_write_error : 1;
+ uint64_t srt_oci_write_data_parity : 1;
+ uint64_t srt_oci_be_parity_err : 1;
+ uint64_t srt_oci_addr_parity_err : 1;
+ uint64_t pore_sw_error_err : 1;
+ uint64_t pore_gpe0_error_err : 1;
+ uint64_t pore_gpe1_error_err : 1;
+ uint64_t external_trap : 1;
+ uint64_t ppc405_core_reset : 1;
+ uint64_t ppc405_chip_reset : 1;
+ uint64_t ppc405_system_reset : 1;
+ uint64_t ppc405_dbgmsrwe : 1;
+ uint64_t ppc405_dbgstopack : 1;
+ uint64_t ocb_db_oci_timeout : 1;
+ uint64_t ocb_db_oci_read_data_parity : 1;
+ uint64_t ocb_db_oci_slave_error : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_db_pib_data_parity_err : 1;
+ uint64_t ocb_idc0_error : 1;
+ uint64_t ocb_idc1_error : 1;
+ uint64_t ocb_idc2_error : 1;
+ uint64_t ocb_idc3_error : 1;
+ uint64_t srt_fsm_err : 1;
+ uint64_t jtagacc_err : 1;
+ uint64_t ocb_dw_err : 1;
+ uint64_t c405_ecc_ue : 1;
+ uint64_t c405_ecc_ce : 1;
+ uint64_t c405_oci_machinecheck : 1;
+ uint64_t sram_spare_direct_error0 : 1;
+ uint64_t sram_spare_direct_error1 : 1;
+ uint64_t sram_spare_direct_error2 : 1;
+ uint64_t sram_spare_direct_error3 : 1;
+ uint64_t slw_ocislv_err : 1;
+ uint64_t gpe_ocislv_err : 1;
+ uint64_t ocb_ocislv_err : 1;
+ uint64_t c405icu_m_timeout : 1;
+ uint64_t c405dcu_m_timeout : 1;
+ uint64_t spare_fir : 12;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t fir_parity_err : 1;
+#else
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t spare_fir : 12;
+ uint64_t c405dcu_m_timeout : 1;
+ uint64_t c405icu_m_timeout : 1;
+ uint64_t ocb_ocislv_err : 1;
+ uint64_t gpe_ocislv_err : 1;
+ uint64_t slw_ocislv_err : 1;
+ uint64_t sram_spare_direct_error3 : 1;
+ uint64_t sram_spare_direct_error2 : 1;
+ uint64_t sram_spare_direct_error1 : 1;
+ uint64_t sram_spare_direct_error0 : 1;
+ uint64_t c405_oci_machinecheck : 1;
+ uint64_t c405_ecc_ce : 1;
+ uint64_t c405_ecc_ue : 1;
+ uint64_t ocb_dw_err : 1;
+ uint64_t jtagacc_err : 1;
+ uint64_t srt_fsm_err : 1;
+ uint64_t ocb_idc3_error : 1;
+ uint64_t ocb_idc2_error : 1;
+ uint64_t ocb_idc1_error : 1;
+ uint64_t ocb_idc0_error : 1;
+ uint64_t ocb_db_pib_data_parity_err : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_db_oci_slave_error : 1;
+ uint64_t ocb_db_oci_read_data_parity : 1;
+ uint64_t ocb_db_oci_timeout : 1;
+ uint64_t ppc405_dbgstopack : 1;
+ uint64_t ppc405_dbgmsrwe : 1;
+ uint64_t ppc405_system_reset : 1;
+ uint64_t ppc405_chip_reset : 1;
+ uint64_t ppc405_core_reset : 1;
+ uint64_t external_trap : 1;
+ uint64_t pore_gpe1_error_err : 1;
+ uint64_t pore_gpe0_error_err : 1;
+ uint64_t pore_sw_error_err : 1;
+ uint64_t srt_oci_addr_parity_err : 1;
+ uint64_t srt_oci_be_parity_err : 1;
+ uint64_t srt_oci_write_data_parity : 1;
+ uint64_t srt_write_error : 1;
+ uint64_t srt_read_error : 1;
+ uint64_t srt_ce : 1;
+ uint64_t srt_ue : 1;
+ uint64_t pmc_error : 1;
+ uint64_t ocb_error : 1;
+ uint64_t pore_gpe1_fatal_err : 1;
+ uint64_t pore_gpe0_fatal_err : 1;
+ uint64_t pmc_occ_hb_malf : 1;
+ uint64_t pmc_pore_sw_malf : 1;
+ uint64_t occ_fw3 : 1;
+ uint64_t occ_fw2 : 1;
+ uint64_t occ_fw1 : 1;
+ uint64_t occ_fw0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfir_t;
+
+#endif // __ASSEMBLER__
+#define OCB_OCCLFIR_OCC_FW0 SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define OCB_OCCLFIR_OCC_FW1 SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define OCB_OCCLFIR_OCC_FW2 SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define OCB_OCCLFIR_OCC_FW3 SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define OCB_OCCLFIR_PMC_PORE_SW_MALF SIXTYFOUR_BIT_CONSTANT(0x0800000000000000)
+#define OCB_OCCLFIR_PMC_OCC_HB_MALF SIXTYFOUR_BIT_CONSTANT(0x0400000000000000)
+#define OCB_OCCLFIR_PORE_GPE0_FATAL_ERR SIXTYFOUR_BIT_CONSTANT(0x0200000000000000)
+#define OCB_OCCLFIR_PORE_GPE1_FATAL_ERR SIXTYFOUR_BIT_CONSTANT(0x0100000000000000)
+#define OCB_OCCLFIR_OCB_ERROR SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define OCB_OCCLFIR_PMC_ERROR SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define OCB_OCCLFIR_SRT_UE SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define OCB_OCCLFIR_SRT_CE SIXTYFOUR_BIT_CONSTANT(0x0010000000000000)
+#define OCB_OCCLFIR_SRT_READ_ERROR SIXTYFOUR_BIT_CONSTANT(0x0008000000000000)
+#define OCB_OCCLFIR_SRT_WRITE_ERROR SIXTYFOUR_BIT_CONSTANT(0x0004000000000000)
+#define OCB_OCCLFIR_SRT_OCI_WRITE_DATA_PARITY SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#define OCB_OCCLFIR_SRT_OCI_BE_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0001000000000000)
+#define OCB_OCCLFIR_SRT_OCI_ADDR_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0000800000000000)
+#define OCB_OCCLFIR_PORE_SW_ERROR_ERR SIXTYFOUR_BIT_CONSTANT(0x0000400000000000)
+#define OCB_OCCLFIR_PORE_GPE0_ERROR_ERR SIXTYFOUR_BIT_CONSTANT(0x0000200000000000)
+#define OCB_OCCLFIR_PORE_GPE1_ERROR_ERR SIXTYFOUR_BIT_CONSTANT(0x0000100000000000)
+#define OCB_OCCLFIR_EXTERNAL_TRAP SIXTYFOUR_BIT_CONSTANT(0x0000080000000000)
+#define OCB_OCCLFIR_PPC405_CORE_RESET SIXTYFOUR_BIT_CONSTANT(0x0000040000000000)
+#define OCB_OCCLFIR_PPC405_CHIP_RESET SIXTYFOUR_BIT_CONSTANT(0x0000020000000000)
+#define OCB_OCCLFIR_PPC405_SYSTEM_RESET SIXTYFOUR_BIT_CONSTANT(0x0000010000000000)
+#define OCB_OCCLFIR_PPC405_DBGMSRWE SIXTYFOUR_BIT_CONSTANT(0x0000008000000000)
+#define OCB_OCCLFIR_PPC405_DBGSTOPACK SIXTYFOUR_BIT_CONSTANT(0x0000004000000000)
+#define OCB_OCCLFIR_OCB_DB_OCI_TIMEOUT SIXTYFOUR_BIT_CONSTANT(0x0000002000000000)
+#define OCB_OCCLFIR_OCB_DB_OCI_READ_DATA_PARITY SIXTYFOUR_BIT_CONSTANT(0x0000001000000000)
+#define OCB_OCCLFIR_OCB_DB_OCI_SLAVE_ERROR SIXTYFOUR_BIT_CONSTANT(0x0000000800000000)
+#define OCB_OCCLFIR_OCB_PIB_ADDR_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000400000000)
+#define OCB_OCCLFIR_OCB_DB_PIB_DATA_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000200000000)
+#define OCB_OCCLFIR_OCB_IDC0_ERROR SIXTYFOUR_BIT_CONSTANT(0x0000000100000000)
+#define OCB_OCCLFIR_OCB_IDC1_ERROR SIXTYFOUR_BIT_CONSTANT(0x0000000080000000)
+#define OCB_OCCLFIR_OCB_IDC2_ERROR SIXTYFOUR_BIT_CONSTANT(0x0000000040000000)
+#define OCB_OCCLFIR_OCB_IDC3_ERROR SIXTYFOUR_BIT_CONSTANT(0x0000000020000000)
+#define OCB_OCCLFIR_SRT_FSM_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000010000000)
+#define OCB_OCCLFIR_JTAGACC_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000008000000)
+#define OCB_OCCLFIR_OCB_DW_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000004000000)
+#define OCB_OCCLFIR_C405_ECC_UE SIXTYFOUR_BIT_CONSTANT(0x0000000002000000)
+#define OCB_OCCLFIR_C405_ECC_CE SIXTYFOUR_BIT_CONSTANT(0x0000000001000000)
+#define OCB_OCCLFIR_C405_OCI_MACHINECHECK SIXTYFOUR_BIT_CONSTANT(0x0000000000800000)
+#define OCB_OCCLFIR_SRAM_SPARE_DIRECT_ERROR0 SIXTYFOUR_BIT_CONSTANT(0x0000000000400000)
+#define OCB_OCCLFIR_SRAM_SPARE_DIRECT_ERROR1 SIXTYFOUR_BIT_CONSTANT(0x0000000000200000)
+#define OCB_OCCLFIR_SRAM_SPARE_DIRECT_ERROR2 SIXTYFOUR_BIT_CONSTANT(0x0000000000100000)
+#define OCB_OCCLFIR_SRAM_SPARE_DIRECT_ERROR3 SIXTYFOUR_BIT_CONSTANT(0x0000000000080000)
+#define OCB_OCCLFIR_SLW_OCISLV_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000000040000)
+#define OCB_OCCLFIR_GPE_OCISLV_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000000020000)
+#define OCB_OCCLFIR_OCB_OCISLV_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000000010000)
+#define OCB_OCCLFIR_C405ICU_M_TIMEOUT SIXTYFOUR_BIT_CONSTANT(0x0000000000008000)
+#define OCB_OCCLFIR_C405DCU_M_TIMEOUT SIXTYFOUR_BIT_CONSTANT(0x0000000000004000)
+#define OCB_OCCLFIR_SPARE_FIR_MASK SIXTYFOUR_BIT_CONSTANT(0x0000000000003ffc)
+#define OCB_OCCLFIR_FIR_PARITY_ERR_DUP SIXTYFOUR_BIT_CONSTANT(0x0000000000000002)
+#define OCB_OCCLFIR_FIR_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000000000001)
+#ifndef __ASSEMBLER__
+
+
+typedef union ocb_occlfir_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_fw0 : 1;
+ uint64_t occ_fw1 : 1;
+ uint64_t occ_fw2 : 1;
+ uint64_t occ_fw3 : 1;
+ uint64_t pmc_pore_sw_malf : 1;
+ uint64_t pmc_occ_hb_malf : 1;
+ uint64_t pore_gpe0_fatal_err : 1;
+ uint64_t pore_gpe1_fatal_err : 1;
+ uint64_t ocb_error : 1;
+ uint64_t pmc_error : 1;
+ uint64_t srt_ue : 1;
+ uint64_t srt_ce : 1;
+ uint64_t srt_read_error : 1;
+ uint64_t srt_write_error : 1;
+ uint64_t srt_oci_write_data_parity : 1;
+ uint64_t srt_oci_be_parity_err : 1;
+ uint64_t srt_oci_addr_parity_err : 1;
+ uint64_t pore_sw_error_err : 1;
+ uint64_t pore_gpe0_error_err : 1;
+ uint64_t pore_gpe1_error_err : 1;
+ uint64_t external_trap : 1;
+ uint64_t ppc405_core_reset : 1;
+ uint64_t ppc405_chip_reset : 1;
+ uint64_t ppc405_system_reset : 1;
+ uint64_t ppc405_dbgmsrwe : 1;
+ uint64_t ppc405_dbgstopack : 1;
+ uint64_t ocb_db_oci_timeout : 1;
+ uint64_t ocb_db_oci_read_data_parity : 1;
+ uint64_t ocb_db_oci_slave_error : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_db_pib_data_parity_err : 1;
+ uint64_t ocb_idc0_error : 1;
+ uint64_t ocb_idc1_error : 1;
+ uint64_t ocb_idc2_error : 1;
+ uint64_t ocb_idc3_error : 1;
+ uint64_t srt_fsm_err : 1;
+ uint64_t jtagacc_err : 1;
+ uint64_t ocb_dw_err : 1;
+ uint64_t c405_ecc_ue : 1;
+ uint64_t c405_ecc_ce : 1;
+ uint64_t c405_oci_machinecheck : 1;
+ uint64_t sram_spare_direct_error0 : 1;
+ uint64_t sram_spare_direct_error1 : 1;
+ uint64_t sram_spare_direct_error2 : 1;
+ uint64_t sram_spare_direct_error3 : 1;
+ uint64_t slw_ocislv_err : 1;
+ uint64_t gpe_ocislv_err : 1;
+ uint64_t ocb_ocislv_err : 1;
+ uint64_t c405icu_m_timeout : 1;
+ uint64_t c405dcu_m_timeout : 1;
+ uint64_t spare_fir : 12;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t fir_parity_err : 1;
+#else
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t spare_fir : 12;
+ uint64_t c405dcu_m_timeout : 1;
+ uint64_t c405icu_m_timeout : 1;
+ uint64_t ocb_ocislv_err : 1;
+ uint64_t gpe_ocislv_err : 1;
+ uint64_t slw_ocislv_err : 1;
+ uint64_t sram_spare_direct_error3 : 1;
+ uint64_t sram_spare_direct_error2 : 1;
+ uint64_t sram_spare_direct_error1 : 1;
+ uint64_t sram_spare_direct_error0 : 1;
+ uint64_t c405_oci_machinecheck : 1;
+ uint64_t c405_ecc_ce : 1;
+ uint64_t c405_ecc_ue : 1;
+ uint64_t ocb_dw_err : 1;
+ uint64_t jtagacc_err : 1;
+ uint64_t srt_fsm_err : 1;
+ uint64_t ocb_idc3_error : 1;
+ uint64_t ocb_idc2_error : 1;
+ uint64_t ocb_idc1_error : 1;
+ uint64_t ocb_idc0_error : 1;
+ uint64_t ocb_db_pib_data_parity_err : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_db_oci_slave_error : 1;
+ uint64_t ocb_db_oci_read_data_parity : 1;
+ uint64_t ocb_db_oci_timeout : 1;
+ uint64_t ppc405_dbgstopack : 1;
+ uint64_t ppc405_dbgmsrwe : 1;
+ uint64_t ppc405_system_reset : 1;
+ uint64_t ppc405_chip_reset : 1;
+ uint64_t ppc405_core_reset : 1;
+ uint64_t external_trap : 1;
+ uint64_t pore_gpe1_error_err : 1;
+ uint64_t pore_gpe0_error_err : 1;
+ uint64_t pore_sw_error_err : 1;
+ uint64_t srt_oci_addr_parity_err : 1;
+ uint64_t srt_oci_be_parity_err : 1;
+ uint64_t srt_oci_write_data_parity : 1;
+ uint64_t srt_write_error : 1;
+ uint64_t srt_read_error : 1;
+ uint64_t srt_ce : 1;
+ uint64_t srt_ue : 1;
+ uint64_t pmc_error : 1;
+ uint64_t ocb_error : 1;
+ uint64_t pore_gpe1_fatal_err : 1;
+ uint64_t pore_gpe0_fatal_err : 1;
+ uint64_t pmc_occ_hb_malf : 1;
+ uint64_t pmc_pore_sw_malf : 1;
+ uint64_t occ_fw3 : 1;
+ uint64_t occ_fw2 : 1;
+ uint64_t occ_fw1 : 1;
+ uint64_t occ_fw0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfir_and_t;
+
+
+
+typedef union ocb_occlfir_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_fw0 : 1;
+ uint64_t occ_fw1 : 1;
+ uint64_t occ_fw2 : 1;
+ uint64_t occ_fw3 : 1;
+ uint64_t pmc_pore_sw_malf : 1;
+ uint64_t pmc_occ_hb_malf : 1;
+ uint64_t pore_gpe0_fatal_err : 1;
+ uint64_t pore_gpe1_fatal_err : 1;
+ uint64_t ocb_error : 1;
+ uint64_t pmc_error : 1;
+ uint64_t srt_ue : 1;
+ uint64_t srt_ce : 1;
+ uint64_t srt_read_error : 1;
+ uint64_t srt_write_error : 1;
+ uint64_t srt_oci_write_data_parity : 1;
+ uint64_t srt_oci_be_parity_err : 1;
+ uint64_t srt_oci_addr_parity_err : 1;
+ uint64_t pore_sw_error_err : 1;
+ uint64_t pore_gpe0_error_err : 1;
+ uint64_t pore_gpe1_error_err : 1;
+ uint64_t external_trap : 1;
+ uint64_t ppc405_core_reset : 1;
+ uint64_t ppc405_chip_reset : 1;
+ uint64_t ppc405_system_reset : 1;
+ uint64_t ppc405_dbgmsrwe : 1;
+ uint64_t ppc405_dbgstopack : 1;
+ uint64_t ocb_db_oci_timeout : 1;
+ uint64_t ocb_db_oci_read_data_parity : 1;
+ uint64_t ocb_db_oci_slave_error : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_db_pib_data_parity_err : 1;
+ uint64_t ocb_idc0_error : 1;
+ uint64_t ocb_idc1_error : 1;
+ uint64_t ocb_idc2_error : 1;
+ uint64_t ocb_idc3_error : 1;
+ uint64_t srt_fsm_err : 1;
+ uint64_t jtagacc_err : 1;
+ uint64_t ocb_dw_err : 1;
+ uint64_t c405_ecc_ue : 1;
+ uint64_t c405_ecc_ce : 1;
+ uint64_t c405_oci_machinecheck : 1;
+ uint64_t sram_spare_direct_error0 : 1;
+ uint64_t sram_spare_direct_error1 : 1;
+ uint64_t sram_spare_direct_error2 : 1;
+ uint64_t sram_spare_direct_error3 : 1;
+ uint64_t slw_ocislv_err : 1;
+ uint64_t gpe_ocislv_err : 1;
+ uint64_t ocb_ocislv_err : 1;
+ uint64_t c405icu_m_timeout : 1;
+ uint64_t c405dcu_m_timeout : 1;
+ uint64_t spare_fir : 12;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t fir_parity_err : 1;
+#else
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t spare_fir : 12;
+ uint64_t c405dcu_m_timeout : 1;
+ uint64_t c405icu_m_timeout : 1;
+ uint64_t ocb_ocislv_err : 1;
+ uint64_t gpe_ocislv_err : 1;
+ uint64_t slw_ocislv_err : 1;
+ uint64_t sram_spare_direct_error3 : 1;
+ uint64_t sram_spare_direct_error2 : 1;
+ uint64_t sram_spare_direct_error1 : 1;
+ uint64_t sram_spare_direct_error0 : 1;
+ uint64_t c405_oci_machinecheck : 1;
+ uint64_t c405_ecc_ce : 1;
+ uint64_t c405_ecc_ue : 1;
+ uint64_t ocb_dw_err : 1;
+ uint64_t jtagacc_err : 1;
+ uint64_t srt_fsm_err : 1;
+ uint64_t ocb_idc3_error : 1;
+ uint64_t ocb_idc2_error : 1;
+ uint64_t ocb_idc1_error : 1;
+ uint64_t ocb_idc0_error : 1;
+ uint64_t ocb_db_pib_data_parity_err : 1;
+ uint64_t ocb_pib_addr_parity_err : 1;
+ uint64_t ocb_db_oci_slave_error : 1;
+ uint64_t ocb_db_oci_read_data_parity : 1;
+ uint64_t ocb_db_oci_timeout : 1;
+ uint64_t ppc405_dbgstopack : 1;
+ uint64_t ppc405_dbgmsrwe : 1;
+ uint64_t ppc405_system_reset : 1;
+ uint64_t ppc405_chip_reset : 1;
+ uint64_t ppc405_core_reset : 1;
+ uint64_t external_trap : 1;
+ uint64_t pore_gpe1_error_err : 1;
+ uint64_t pore_gpe0_error_err : 1;
+ uint64_t pore_sw_error_err : 1;
+ uint64_t srt_oci_addr_parity_err : 1;
+ uint64_t srt_oci_be_parity_err : 1;
+ uint64_t srt_oci_write_data_parity : 1;
+ uint64_t srt_write_error : 1;
+ uint64_t srt_read_error : 1;
+ uint64_t srt_ce : 1;
+ uint64_t srt_ue : 1;
+ uint64_t pmc_error : 1;
+ uint64_t ocb_error : 1;
+ uint64_t pore_gpe1_fatal_err : 1;
+ uint64_t pore_gpe0_fatal_err : 1;
+ uint64_t pmc_occ_hb_malf : 1;
+ uint64_t pmc_pore_sw_malf : 1;
+ uint64_t occ_fw3 : 1;
+ uint64_t occ_fw2 : 1;
+ uint64_t occ_fw1 : 1;
+ uint64_t occ_fw0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfir_or_t;
+
+
+
+typedef union ocb_occlfirmask {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfirmask_t;
+
+
+
+typedef union ocb_occlfirmask_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfirmask_and_t;
+
+
+
+typedef union ocb_occlfirmask_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfirmask_or_t;
+
+
+
+typedef union ocb_occlfiract0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfiract0_t;
+
+
+
+typedef union ocb_occlfiract1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occlfiract1_t;
+
+
+
+typedef union ocb_occerrrpt {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t sram_cerrrpt : 10;
+ uint64_t jtagacc_cerrrpt : 6;
+ uint64_t c405_dcu_ecc_ue_cerrrpt : 1;
+ uint64_t c405_dcu_ecc_ce_cerrrpt : 1;
+ uint64_t c405_icu_ecc_ue_cerrrpt : 1;
+ uint64_t c405_icu_ecc_ce_cerrrpt : 1;
+ uint64_t slw_ocislv_err : 7;
+ uint64_t gpe_ocislv_err : 7;
+ uint64_t ocb_ocislv_err : 6;
+ uint64_t _reserved0 : 24;
+#else
+ uint64_t _reserved0 : 24;
+ uint64_t ocb_ocislv_err : 6;
+ uint64_t gpe_ocislv_err : 7;
+ uint64_t slw_ocislv_err : 7;
+ uint64_t c405_icu_ecc_ce_cerrrpt : 1;
+ uint64_t c405_icu_ecc_ue_cerrrpt : 1;
+ uint64_t c405_dcu_ecc_ce_cerrrpt : 1;
+ uint64_t c405_dcu_ecc_ue_cerrrpt : 1;
+ uint64_t jtagacc_cerrrpt : 6;
+ uint64_t sram_cerrrpt : 10;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_occerrrpt_t;
+
+
+
+typedef union ocb_scan_dummy_1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 48;
+ uint64_t value : 16;
+#else
+ uint64_t value : 16;
+ uint64_t _reserved0 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_scan_dummy_1_t;
+
+
+
+typedef union ocb_scan_dummy_2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 63;
+ uint64_t value : 1;
+#else
+ uint64_t value : 1;
+ uint64_t _reserved0 : 63;
+#endif // _BIG_ENDIAN
+ } fields;
+} ocb_scan_dummy_2_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __OCB_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/ocb_register_addresses.h b/src/ssx/pgp/registers/ocb_register_addresses.h
new file mode 100755
index 0000000..3290e59
--- /dev/null
+++ b/src/ssx/pgp/registers/ocb_register_addresses.h
@@ -0,0 +1,148 @@
+#ifndef __OCB_REGISTER_ADDRESSES_H__
+#define __OCB_REGISTER_ADDRESSES_H__
+
+// $Id: ocb_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/ocb_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ocb_register_addresses.h
+/// \brief Symbolic addresses for the OCB unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define OCB_OCI_BASE 0x40050000
+#define OCB_OITR0 0x40050040
+#define OCB_OIEPR0 0x40050048
+#define OCB_OCIR0 0x40050050
+#define OCB_ONISR0 0x40050058
+#define OCB_OUDER0 0x40050060
+#define OCB_OCISR0 0x40050068
+#define OCB_ODHER0 0x40050070
+#define OCB_OISR0 0x40050000
+#define OCB_OISR0_AND 0x40050008
+#define OCB_OISR0_OR 0x40050010
+#define OCB_OIMR0 0x40050020
+#define OCB_OIMR0_AND 0x40050028
+#define OCB_OIMR0_OR 0x40050030
+#define OCB_OITR1 0x400500c0
+#define OCB_OIEPR1 0x400500c8
+#define OCB_OCIR1 0x400500d0
+#define OCB_ONISR1 0x400500d8
+#define OCB_OUDER1 0x400500e0
+#define OCB_OCISR1 0x400500e8
+#define OCB_ODHER1 0x400500f0
+#define OCB_OISR1 0x40050080
+#define OCB_OISR1_AND 0x40050088
+#define OCB_OISR1_OR 0x40050090
+#define OCB_OIMR1 0x400500a0
+#define OCB_OIMR1_AND 0x400500a8
+#define OCB_OIMR1_OR 0x400500b0
+#define OCB_OCCMISC 0x40050100
+#define OCB_OCCMISC_AND 0x40050108
+#define OCB_OCCMISC_OR 0x40050110
+#define OCB_OTRN(n) (OCB_OTR0 + ((OCB_OTR1 - OCB_OTR0) * (n)))
+#define OCB_OTR0 0x40050800
+#define OCB_OTR1 0x40050808
+#define OCB_OHTMCR 0x40050118
+#define OCB_OEHDR 0x40050120
+#define OCB_OCBSLBRN(n) (OCB_OCBSLBR0 + ((OCB_OCBSLBR1 - OCB_OCBSLBR0) * (n)))
+#define OCB_OCBSLBR0 0x40051000
+#define OCB_OCBSLBR1 0x40051080
+#define OCB_OCBSLBR2 0x40051100
+#define OCB_OCBSHBRN(n) (OCB_OCBSHBR0 + ((OCB_OCBSHBR1 - OCB_OCBSHBR0) * (n)))
+#define OCB_OCBSHBR0 0x40051018
+#define OCB_OCBSHBR1 0x40051098
+#define OCB_OCBSHBR2 0x40051118
+#define OCB_OCBSLCSN(n) (OCB_OCBSLCS0 + ((OCB_OCBSLCS1 - OCB_OCBSLCS0) * (n)))
+#define OCB_OCBSLCS0 0x40051008
+#define OCB_OCBSLCS1 0x40051088
+#define OCB_OCBSLCS2 0x40051108
+#define OCB_OCBSHCSN(n) (OCB_OCBSHCS0 + ((OCB_OCBSHCS1 - OCB_OCBSHCS0) * (n)))
+#define OCB_OCBSHCS0 0x40051020
+#define OCB_OCBSHCS1 0x400510a0
+#define OCB_OCBSHCS2 0x40051120
+#define OCB_OCBSLIN(n) (OCB_OCBSLI0 + ((OCB_OCBSLI1 - OCB_OCBSLI0) * (n)))
+#define OCB_OCBSLI0 0x40051010
+#define OCB_OCBSLI1 0x40051090
+#define OCB_OCBSLI2 0x40051110
+#define OCB_OCBSHIN(n) (OCB_OCBSHI0 + ((OCB_OCBSHI1 - OCB_OCBSHI0) * (n)))
+#define OCB_OCBSHI0 0x40051028
+#define OCB_OCBSHI1 0x400510a8
+#define OCB_OCBSHI2 0x40051128
+#define OCB_OCBSESN(n) (OCB_OCBSES0 + ((OCB_OCBSES1 - OCB_OCBSES0) * (n)))
+#define OCB_OCBSES0 0x40051030
+#define OCB_OCBSES1 0x400510b0
+#define OCB_OCBSES2 0x40051130
+#define OCB_OCBICRN(n) (OCB_OCBICR0 + ((OCB_OCBICR1 - OCB_OCBICR0) * (n)))
+#define OCB_OCBICR0 0x40051038
+#define OCB_OCBICR1 0x400510b8
+#define OCB_OCBICR2 0x40051138
+#define OCB_OCBLWCRN(n) (OCB_OCBLWCR0 + ((OCB_OCBLWCR1 - OCB_OCBLWCR0) * (n)))
+#define OCB_OCBLWCR0 0x40051040
+#define OCB_OCBLWCR1 0x400510c0
+#define OCB_OCBLWCR2 0x40051140
+#define OCB_OCBLWSRN(n) (OCB_OCBLWSR0 + ((OCB_OCBLWSR1 - OCB_OCBLWSR0) * (n)))
+#define OCB_OCBLWSR0 0x40051050
+#define OCB_OCBLWSR1 0x400510d0
+#define OCB_OCBLWSR2 0x40051150
+#define OCB_OCBLWSBRN(n) (OCB_OCBLWSBR0 + ((OCB_OCBLWSBR1 - OCB_OCBLWSBR0) * (n)))
+#define OCB_OCBLWSBR0 0x40051060
+#define OCB_OCBLWSBR1 0x400510e0
+#define OCB_OCBLWSBR2 0x40051160
+#define OCB_OCICHSW 0x40050128
+#define OCB_PIB_BASE 0x0006a000
+#define OCB_OCR 0x0006b000
+#define OCB_OCR_AND 0x0006b001
+#define OCB_OCR_OR 0x0006b002
+#define OCB_OCDBG 0x0006b003
+#define OCB_OCBARN(n) (OCB_OCBAR0 + ((OCB_OCBAR1 - OCB_OCBAR0) * (n)))
+#define OCB_OCBAR0 0x0006b010
+#define OCB_OCBAR1 0x0006b030
+#define OCB_OCBAR2 0x0006b050
+#define OCB_OCBAR3 0x0006b070
+#define OCB_OCBCSRN(n) (OCB_OCBCSR0 + ((OCB_OCBCSR1 - OCB_OCBCSR0) * (n)))
+#define OCB_OCBCSR0 0x0006b011
+#define OCB_OCBCSR1 0x0006b031
+#define OCB_OCBCSR2 0x0006b051
+#define OCB_OCBCSR3 0x0006b071
+#define OCB_OCBCSRN_AND(n) (OCB_OCBCSR0_AND + ((OCB_OCBCSR1_AND - OCB_OCBCSR0_AND) * (n)))
+#define OCB_OCBCSR0_AND 0x0006b012
+#define OCB_OCBCSR1_AND 0x0006b032
+#define OCB_OCBCSR2_AND 0x0006b052
+#define OCB_OCBCSR3_AND 0x0006b072
+#define OCB_OCBCSRN_OR(n) (OCB_OCBCSR0_OR + ((OCB_OCBCSR1_OR - OCB_OCBCSR0_OR) * (n)))
+#define OCB_OCBCSR0_OR 0x0006b013
+#define OCB_OCBCSR1_OR 0x0006b033
+#define OCB_OCBCSR2_OR 0x0006b053
+#define OCB_OCBCSR3_OR 0x0006b073
+#define OCB_OCBESRN(n) (OCB_OCBESR0 + ((OCB_OCBESR1 - OCB_OCBESR0) * (n)))
+#define OCB_OCBESR0 0x0006b014
+#define OCB_OCBESR1 0x0006b034
+#define OCB_OCBESR2 0x0006b054
+#define OCB_OCBESR3 0x0006b074
+#define OCB_OCBDRN(n) (OCB_OCBDR0 + ((OCB_OCBDR1 - OCB_OCBDR0) * (n)))
+#define OCB_OCBDR0 0x0006b015
+#define OCB_OCBDR1 0x0006b035
+#define OCB_OCBDR2 0x0006b055
+#define OCB_OCBDR3 0x0006b075
+#define OCB_OSBCR 0x0006b100
+#define OCB_OTDCR 0x0006b110
+#define OCB_OPPCINJ 0x0006b111
+#define OCB_FIRPIB_BASE 0x01010800
+#define OCB_OCCLFIR 0x01010800
+#define OCB_OCCLFIR_AND 0x01010801
+#define OCB_OCCLFIR_OR 0x01010802
+#define OCB_OCCLFIRMASK 0x01010803
+#define OCB_OCCLFIRMASK_AND 0x01010804
+#define OCB_OCCLFIRMASK_OR 0x01010805
+#define OCB_OCCLFIRACT0 0x01010806
+#define OCB_OCCLFIRACT1 0x01010807
+#define OCB_OCCERRRPT 0x0101080a
+
+#endif // __OCB_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/oha_firmware_registers.h b/src/ssx/pgp/registers/oha_firmware_registers.h
new file mode 100755
index 0000000..cba1500
--- /dev/null
+++ b/src/ssx/pgp/registers/oha_firmware_registers.h
@@ -0,0 +1,1248 @@
+#ifndef __OHA_FIRMWARE_REGISTERS_H__
+#define __OHA_FIRMWARE_REGISTERS_H__
+
+// $Id: oha_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/oha_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file oha_firmware_registers.h
+/// \brief C register structs for the OHA unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union oha_activity_sample_mode_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t enable_activity_sampling : 1;
+ uint64_t enable_ppt_trace : 1;
+ uint64_t l2_act_count_is_free_running : 1;
+ uint64_t l3_act_count_is_free_running : 1;
+ uint64_t activity_sample_l2l3_enable : 1;
+ uint64_t core_activity_sample_enable : 1;
+ uint64_t disable_activity_proxy_reset : 1;
+ uint64_t power_proxy_activity_range_select_vcs : 5;
+ uint64_t power_proxy_activity_range_select_vdd : 5;
+ uint64_t memory_activity_range_select : 4;
+ uint64_t avg_freq_counter_scaler : 3;
+ uint64_t ppt_trace_timer_match_val : 11;
+ uint64_t disable_ppt_int_timer_reset : 1;
+ uint64_t ppt_int_timer_select : 2;
+ uint64_t disable_ppt_cycle_counter_reset : 1;
+ uint64_t ppt_cycle_counter_scaler : 3;
+ uint64_t ppt_squash_timer_match_val : 6;
+ uint64_t ppt_timer_timeout_enable : 1;
+ uint64_t ppt_lpar_change_enable : 1;
+ uint64_t ppt_global_actual_change_enable : 1;
+ uint64_t ppt_local_voltage_change_enable : 1;
+ uint64_t ppt_ivrm_bypass_change_enable : 1;
+ uint64_t ppt_idle_entry_enable : 1;
+ uint64_t ppt_idle_exit_enable : 1;
+ uint64_t ppt_timer_timeout_priority : 1;
+ uint64_t ppt_lpar_change_priority : 1;
+ uint64_t ppt_global_actual_change_priority : 1;
+ uint64_t ppt_local_voltage_change_priority : 1;
+ uint64_t ppt_ivrm_bypass_change_priority : 1;
+ uint64_t ppt_idle_entry_priority : 1;
+ uint64_t ppt_idle_exit_priority : 1;
+ uint64_t ppt_legacy_mode : 1;
+ uint64_t _reserved0 : 1;
+#else
+ uint64_t _reserved0 : 1;
+ uint64_t ppt_legacy_mode : 1;
+ uint64_t ppt_idle_exit_priority : 1;
+ uint64_t ppt_idle_entry_priority : 1;
+ uint64_t ppt_ivrm_bypass_change_priority : 1;
+ uint64_t ppt_local_voltage_change_priority : 1;
+ uint64_t ppt_global_actual_change_priority : 1;
+ uint64_t ppt_lpar_change_priority : 1;
+ uint64_t ppt_timer_timeout_priority : 1;
+ uint64_t ppt_idle_exit_enable : 1;
+ uint64_t ppt_idle_entry_enable : 1;
+ uint64_t ppt_ivrm_bypass_change_enable : 1;
+ uint64_t ppt_local_voltage_change_enable : 1;
+ uint64_t ppt_global_actual_change_enable : 1;
+ uint64_t ppt_lpar_change_enable : 1;
+ uint64_t ppt_timer_timeout_enable : 1;
+ uint64_t ppt_squash_timer_match_val : 6;
+ uint64_t ppt_cycle_counter_scaler : 3;
+ uint64_t disable_ppt_cycle_counter_reset : 1;
+ uint64_t ppt_int_timer_select : 2;
+ uint64_t disable_ppt_int_timer_reset : 1;
+ uint64_t ppt_trace_timer_match_val : 11;
+ uint64_t avg_freq_counter_scaler : 3;
+ uint64_t memory_activity_range_select : 4;
+ uint64_t power_proxy_activity_range_select_vdd : 5;
+ uint64_t power_proxy_activity_range_select_vcs : 5;
+ uint64_t disable_activity_proxy_reset : 1;
+ uint64_t core_activity_sample_enable : 1;
+ uint64_t activity_sample_l2l3_enable : 1;
+ uint64_t l3_act_count_is_free_running : 1;
+ uint64_t l2_act_count_is_free_running : 1;
+ uint64_t enable_ppt_trace : 1;
+ uint64_t enable_activity_sampling : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_activity_sample_mode_reg_t;
+
+
+
+typedef union oha_vcs_activity_cnt_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t l2_activity_count_24bit_vcs : 24;
+ uint64_t l3_activity_count_24bit_vcs : 24;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t l3_activity_count_24bit_vcs : 24;
+ uint64_t l2_activity_count_24bit_vcs : 24;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_vcs_activity_cnt_reg_t;
+
+
+
+typedef union oha_vdd_activity_cnt_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t l2_activity_count_24bit_vdd : 24;
+ uint64_t l3_activity_count_24bit_vdd : 24;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t l3_activity_count_24bit_vdd : 24;
+ uint64_t l2_activity_count_24bit_vdd : 24;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_vdd_activity_cnt_reg_t;
+
+
+
+typedef union oha_low_activity_detect_mode_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t low_activity_detect_sample_enable : 1;
+ uint64_t low_activity_detect_timer_select_for_entry : 8;
+ uint64_t low_activity_detect_timer_select_for_exit : 8;
+ uint64_t low_activity_detect_threshold_range : 4;
+ uint64_t low_activity_detect_threshold_entry : 16;
+ uint64_t low_activity_detect_threshold_exit : 16;
+ uint64_t _reserved0 : 11;
+#else
+ uint64_t _reserved0 : 11;
+ uint64_t low_activity_detect_threshold_exit : 16;
+ uint64_t low_activity_detect_threshold_entry : 16;
+ uint64_t low_activity_detect_threshold_range : 4;
+ uint64_t low_activity_detect_timer_select_for_exit : 8;
+ uint64_t low_activity_detect_timer_select_for_entry : 8;
+ uint64_t low_activity_detect_sample_enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_low_activity_detect_mode_reg_t;
+
+
+
+typedef union oha_activity_and_frequ_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t low_activity_detect_engaged : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t low_activity_detect_engaged : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_activity_and_frequ_reg_t;
+
+
+
+typedef union oha_counter_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t base_counter : 16;
+ uint64_t idle_detec_timer : 16;
+ uint64_t tod_count_msbs : 16;
+ uint64_t ppt_cycle_count_ovfl : 1;
+ uint64_t ppt_parity_error : 1;
+ uint64_t _reserved0 : 14;
+#else
+ uint64_t _reserved0 : 14;
+ uint64_t ppt_parity_error : 1;
+ uint64_t ppt_cycle_count_ovfl : 1;
+ uint64_t tod_count_msbs : 16;
+ uint64_t idle_detec_timer : 16;
+ uint64_t base_counter : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_counter_reg_t;
+
+
+
+typedef union oha_proxy_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t average_frequency : 32;
+ uint64_t special_memory_activity_cnt : 24;
+ uint64_t _reserved0 : 8;
+#else
+ uint64_t _reserved0 : 8;
+ uint64_t special_memory_activity_cnt : 24;
+ uint64_t average_frequency : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_proxy_reg_t;
+
+
+
+typedef union oha_proxy_legacy_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t aproxy_vdd : 16;
+ uint64_t aproxy_vcs : 16;
+ uint64_t memory_activity_cnt : 16;
+ uint64_t scaled_average_frequency : 16;
+#else
+ uint64_t scaled_average_frequency : 16;
+ uint64_t memory_activity_cnt : 16;
+ uint64_t aproxy_vcs : 16;
+ uint64_t aproxy_vdd : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_proxy_legacy_reg_t;
+
+
+
+typedef union oha_skitter_ctrl_mode_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t start_skitter_mux_sel : 3;
+ uint64_t stop_skitter_mux_sel : 3;
+ uint64_t skitter_timer_start_mux_sel : 3;
+ uint64_t disable_skitter_qualification_mode : 1;
+ uint64_t skitter_timer_enable_freerun_mode : 1;
+ uint64_t skitter_timer_range_select : 4;
+ uint64_t _reserved0 : 49;
+#else
+ uint64_t _reserved0 : 49;
+ uint64_t skitter_timer_range_select : 4;
+ uint64_t skitter_timer_enable_freerun_mode : 1;
+ uint64_t disable_skitter_qualification_mode : 1;
+ uint64_t skitter_timer_start_mux_sel : 3;
+ uint64_t stop_skitter_mux_sel : 3;
+ uint64_t start_skitter_mux_sel : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_skitter_ctrl_mode_reg_t;
+
+
+
+typedef union oha_cpm_ctrl_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cpm_bit_sel : 2;
+ uint64_t cpm_bit_sel_trig_0 : 3;
+ uint64_t cpm_bit_sel_trig_1 : 3;
+ uint64_t scom_marker : 8;
+ uint64_t cpm_mark_select : 2;
+ uint64_t cpm_htm_mode : 1;
+ uint64_t cpm_scom_mask : 8;
+ uint64_t cpm_scom_mode : 2;
+ uint64_t cpm_data_mode : 1;
+ uint64_t _reserved0 : 34;
+#else
+ uint64_t _reserved0 : 34;
+ uint64_t cpm_data_mode : 1;
+ uint64_t cpm_scom_mode : 2;
+ uint64_t cpm_scom_mask : 8;
+ uint64_t cpm_htm_mode : 1;
+ uint64_t cpm_mark_select : 2;
+ uint64_t scom_marker : 8;
+ uint64_t cpm_bit_sel_trig_1 : 3;
+ uint64_t cpm_bit_sel_trig_0 : 3;
+ uint64_t cpm_bit_sel : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_cpm_ctrl_reg_t;
+
+
+
+typedef union oha_cpm_hist_reset_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t hist_reset : 1;
+ uint64_t pconly_special_wakeup : 1;
+ uint64_t _reserved0 : 62;
+#else
+ uint64_t _reserved0 : 62;
+ uint64_t pconly_special_wakeup : 1;
+ uint64_t hist_reset : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_cpm_hist_reset_reg_t;
+
+#endif // __ASSEMBLER__
+#define OHA_CPM_HIST_RESET_REG_HIST_RESET SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define OHA_CPM_HIST_RESET_REG_PCONLY_SPECIAL_WAKEUP SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union oha_ro_status_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t low_activity_detect_bit : 1;
+ uint64_t special_wakeup_completed : 1;
+ uint64_t architected_idle_state_from_core : 3;
+ uint64_t core_access_impossible : 1;
+ uint64_t eco_access_impossible : 1;
+ uint64_t spare_6bit : 6;
+ uint64_t current_aiss_fsm_state_vector : 7;
+ uint64_t eff_idle_state : 3;
+ uint64_t spare_1bit : 1;
+ uint64_t pc_tc_deep_idle_thread_state : 8;
+ uint64_t lpar_id : 12;
+ uint64_t ppt_fsm_l : 4;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t ppt_fsm_l : 4;
+ uint64_t lpar_id : 12;
+ uint64_t pc_tc_deep_idle_thread_state : 8;
+ uint64_t spare_1bit : 1;
+ uint64_t eff_idle_state : 3;
+ uint64_t current_aiss_fsm_state_vector : 7;
+ uint64_t spare_6bit : 6;
+ uint64_t eco_access_impossible : 1;
+ uint64_t core_access_impossible : 1;
+ uint64_t architected_idle_state_from_core : 3;
+ uint64_t special_wakeup_completed : 1;
+ uint64_t low_activity_detect_bit : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_ro_status_reg_t;
+
+#endif // __ASSEMBLER__
+#define OHA_RO_STATUS_REG_LOW_ACTIVITY_DETECT_BIT SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define OHA_RO_STATUS_REG_SPECIAL_WAKEUP_COMPLETED SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define OHA_RO_STATUS_REG_ARCHITECTED_IDLE_STATE_FROM_CORE_MASK SIXTYFOUR_BIT_CONSTANT(0x3800000000000000)
+#define OHA_RO_STATUS_REG_CORE_ACCESS_IMPOSSIBLE SIXTYFOUR_BIT_CONSTANT(0x0400000000000000)
+#define OHA_RO_STATUS_REG_ECO_ACCESS_IMPOSSIBLE SIXTYFOUR_BIT_CONSTANT(0x0200000000000000)
+#define OHA_RO_STATUS_REG_SPARE_6BIT_MASK SIXTYFOUR_BIT_CONSTANT(0x01f8000000000000)
+#define OHA_RO_STATUS_REG_CURRENT_AISS_FSM_STATE_VECTOR_MASK SIXTYFOUR_BIT_CONSTANT(0x0007f00000000000)
+#define OHA_RO_STATUS_REG_EFF_IDLE_STATE_MASK SIXTYFOUR_BIT_CONSTANT(0x00000e0000000000)
+#define OHA_RO_STATUS_REG_SPARE_1BIT SIXTYFOUR_BIT_CONSTANT(0x0000010000000000)
+#define OHA_RO_STATUS_REG_PC_TC_DEEP_IDLE_THREAD_STATE_MASK SIXTYFOUR_BIT_CONSTANT(0x000000ff00000000)
+#define OHA_RO_STATUS_REG_LPAR_ID_MASK SIXTYFOUR_BIT_CONSTANT(0x00000000fff00000)
+#define OHA_RO_STATUS_REG_PPT_FSM_L_MASK SIXTYFOUR_BIT_CONSTANT(0x00000000000f0000)
+#ifndef __ASSEMBLER__
+
+
+typedef union oha_mode_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t enable_ignore_recov_errors : 1;
+ uint64_t enable_arch_idle_mode_sequencer : 1;
+ uint64_t treat_sleep_as_nap : 1;
+ uint64_t treat_winkle_as_sleep : 1;
+ uint64_t enable_pstate_tracing : 1;
+ uint64_t enable_suppress_purges_and_pcb_fence : 1;
+ uint64_t idle_state_override_en : 1;
+ uint64_t idle_state_override_value : 3;
+ uint64_t disable_aiss_core_handshake : 1;
+ uint64_t aiss_hang_detect_timer_sel : 4;
+ uint64_t enable_l2_purge_abort : 1;
+ uint64_t enable_l3_purge_abort : 1;
+ uint64_t tod_pulse_count_match_val : 14;
+ uint64_t trace_debug_mode_select : 2;
+ uint64_t lpft_mode : 1;
+ uint64_t _reserved0 : 30;
+#else
+ uint64_t _reserved0 : 30;
+ uint64_t lpft_mode : 1;
+ uint64_t trace_debug_mode_select : 2;
+ uint64_t tod_pulse_count_match_val : 14;
+ uint64_t enable_l3_purge_abort : 1;
+ uint64_t enable_l2_purge_abort : 1;
+ uint64_t aiss_hang_detect_timer_sel : 4;
+ uint64_t disable_aiss_core_handshake : 1;
+ uint64_t idle_state_override_value : 3;
+ uint64_t idle_state_override_en : 1;
+ uint64_t enable_suppress_purges_and_pcb_fence : 1;
+ uint64_t enable_pstate_tracing : 1;
+ uint64_t treat_winkle_as_sleep : 1;
+ uint64_t treat_sleep_as_nap : 1;
+ uint64_t enable_arch_idle_mode_sequencer : 1;
+ uint64_t enable_ignore_recov_errors : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_mode_reg_t;
+
+
+
+typedef union oha_error_and_error_mask_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oha_error_mask : 8;
+ uint64_t oha_chiplet_errors : 8;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ uint64_t oha_chiplet_errors : 8;
+ uint64_t oha_error_mask : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_error_and_error_mask_reg_t;
+
+
+
+typedef union oha_arch_idle_state_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t aiss_thold_sequence_select : 1;
+ uint64_t disable_waiting_on_l3 : 1;
+ uint64_t idle_seq_timer_select : 2;
+ uint64_t allow_aiss_interrupts : 1;
+ uint64_t enable_reset_of_counters_while_sleepwinkle : 1;
+ uint64_t select_p7p_seq_wait_time : 1;
+ uint64_t disable_auto_sleep_entry : 1;
+ uint64_t disable_auto_winkle_entry : 1;
+ uint64_t reset_idle_state_sequencer : 1;
+ uint64_t _reserved0 : 54;
+#else
+ uint64_t _reserved0 : 54;
+ uint64_t reset_idle_state_sequencer : 1;
+ uint64_t disable_auto_winkle_entry : 1;
+ uint64_t disable_auto_sleep_entry : 1;
+ uint64_t select_p7p_seq_wait_time : 1;
+ uint64_t enable_reset_of_counters_while_sleepwinkle : 1;
+ uint64_t allow_aiss_interrupts : 1;
+ uint64_t idle_seq_timer_select : 2;
+ uint64_t disable_waiting_on_l3 : 1;
+ uint64_t aiss_thold_sequence_select : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_arch_idle_state_reg_t;
+
+
+
+typedef union oha_pmu_config_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pmu_pstate_threshold_a : 8;
+ uint64_t pmu_pstate_threshold_b : 8;
+ uint64_t pmu_configuration : 3;
+ uint64_t _reserved0 : 45;
+#else
+ uint64_t _reserved0 : 45;
+ uint64_t pmu_configuration : 3;
+ uint64_t pmu_pstate_threshold_b : 8;
+ uint64_t pmu_pstate_threshold_a : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_pmu_config_reg_t;
+
+
+
+typedef union oha_aiss_io_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare_2bits_b : 2;
+ uint64_t tc_tp_chiplet_pm_state : 4;
+ uint64_t tc_pb_sleep : 1;
+ uint64_t tc_tc_pm_thold_ctrl : 3;
+ uint64_t tc_l3_fence_lco : 1;
+ uint64_t tc_ncu_fence : 1;
+ uint64_t chksw_hw237039dis : 1;
+ uint64_t tc_l3_init_dram : 1;
+ uint64_t tc_pb_purge : 1;
+ uint64_t tc_pc_pm_wake_up : 1;
+ uint64_t spare_entry_for_config_bit : 1;
+ uint64_t reset_of_counters_while_sleepwinkle : 1;
+ uint64_t tc_chtm_purge : 1;
+ uint64_t tc_tp_terminate_pcb : 1;
+ uint64_t tc_oha_therm_purge_lvl : 1;
+ uint64_t pscom_core_fence_lvl : 1;
+ uint64_t pb_eco_fence_lvl : 1;
+ uint64_t core2cache_fence_req : 1;
+ uint64_t cache2core_fence_req : 1;
+ uint64_t pervasive_eco_fence_req : 1;
+ uint64_t tc_oha_pmx_fence_req_lvl_l : 1;
+ uint64_t updateohafreq : 1;
+ uint64_t req_idle_state_change : 1;
+ uint64_t tc_l2_purge : 1;
+ uint64_t tc_l3_purge : 1;
+ uint64_t tc_ncu_purge : 1;
+ uint64_t tc_l2_purge_abort : 1;
+ uint64_t tc_l3_purge_abort : 1;
+ uint64_t pc_tc_pm_state : 3;
+ uint64_t l2_purge_is_done : 1;
+ uint64_t l3_ncu_chtm_purge_done : 3;
+ uint64_t tc_tc_xstop_err : 1;
+ uint64_t tc_tc_recov_err : 1;
+ uint64_t pb_tc_purge_active_lvl : 1;
+ uint64_t l3_tc_dram_ready_lvl : 1;
+ uint64_t core_fsm_non_idle : 1;
+ uint64_t tc_pscom_core_fence_done : 1;
+ uint64_t tc_pmx_oha_fence_done : 1;
+ uint64_t l2_purge_abort_sticky : 1;
+ uint64_t l3_purge_abort_sticky : 1;
+ uint64_t _reserved0 : 14;
+#else
+ uint64_t _reserved0 : 14;
+ uint64_t l3_purge_abort_sticky : 1;
+ uint64_t l2_purge_abort_sticky : 1;
+ uint64_t tc_pmx_oha_fence_done : 1;
+ uint64_t tc_pscom_core_fence_done : 1;
+ uint64_t core_fsm_non_idle : 1;
+ uint64_t l3_tc_dram_ready_lvl : 1;
+ uint64_t pb_tc_purge_active_lvl : 1;
+ uint64_t tc_tc_recov_err : 1;
+ uint64_t tc_tc_xstop_err : 1;
+ uint64_t l3_ncu_chtm_purge_done : 3;
+ uint64_t l2_purge_is_done : 1;
+ uint64_t pc_tc_pm_state : 3;
+ uint64_t tc_l3_purge_abort : 1;
+ uint64_t tc_l2_purge_abort : 1;
+ uint64_t tc_ncu_purge : 1;
+ uint64_t tc_l3_purge : 1;
+ uint64_t tc_l2_purge : 1;
+ uint64_t req_idle_state_change : 1;
+ uint64_t updateohafreq : 1;
+ uint64_t tc_oha_pmx_fence_req_lvl_l : 1;
+ uint64_t pervasive_eco_fence_req : 1;
+ uint64_t cache2core_fence_req : 1;
+ uint64_t core2cache_fence_req : 1;
+ uint64_t pb_eco_fence_lvl : 1;
+ uint64_t pscom_core_fence_lvl : 1;
+ uint64_t tc_oha_therm_purge_lvl : 1;
+ uint64_t tc_tp_terminate_pcb : 1;
+ uint64_t tc_chtm_purge : 1;
+ uint64_t reset_of_counters_while_sleepwinkle : 1;
+ uint64_t spare_entry_for_config_bit : 1;
+ uint64_t tc_pc_pm_wake_up : 1;
+ uint64_t tc_pb_purge : 1;
+ uint64_t tc_l3_init_dram : 1;
+ uint64_t chksw_hw237039dis : 1;
+ uint64_t tc_ncu_fence : 1;
+ uint64_t tc_l3_fence_lco : 1;
+ uint64_t tc_tc_pm_thold_ctrl : 3;
+ uint64_t tc_pb_sleep : 1;
+ uint64_t tc_tp_chiplet_pm_state : 4;
+ uint64_t spare_2bits_b : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_aiss_io_reg_t;
+
+
+
+typedef union oha_ppt_bar_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ppt_bar : 46;
+ uint64_t ppt_size_mask : 7;
+ uint64_t ppt_address_scope : 3;
+ uint64_t _reserved0 : 8;
+#else
+ uint64_t _reserved0 : 8;
+ uint64_t ppt_address_scope : 3;
+ uint64_t ppt_size_mask : 7;
+ uint64_t ppt_bar : 46;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_ppt_bar_reg_t;
+
+
+
+typedef union oha_l2_vcs_directory_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vcs_directory_read_weight_t;
+
+
+
+typedef union oha_l2_vcs_directory_write_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vcs_directory_write_weight_t;
+
+
+
+typedef union oha_l2_vcs_cache_full_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vcs_cache_full_read_weight_t;
+
+
+
+typedef union oha_l2_vcs_cache_targeted_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vcs_cache_targeted_read_weight_t;
+
+
+
+typedef union oha_l2_vcs_cache_write_cnt_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vcs_cache_write_cnt_weight_t;
+
+
+
+typedef union oha_l3_vcs_directory_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l3_vcs_directory_read_weight_t;
+
+
+
+typedef union oha_l3_vcs_directory_write_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l3_vcs_directory_write_weight_t;
+
+
+
+typedef union oha_l3_vcs_cache_access_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l3_vcs_cache_access_weight_t;
+
+
+
+typedef union oha_l2_vdd_directory_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vdd_directory_read_weight_t;
+
+
+
+typedef union oha_l2_vdd_directory_write_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vdd_directory_write_weight_t;
+
+
+
+typedef union oha_l2_vdd_cache_full_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vdd_cache_full_read_weight_t;
+
+
+
+typedef union oha_l2_vdd_cache_targeted_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vdd_cache_targeted_read_weight_t;
+
+
+
+typedef union oha_l2_vdd_cache_write_cnt_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l2_vdd_cache_write_cnt_weight_t;
+
+
+
+typedef union oha_l3_vdd_directory_read_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l3_vdd_directory_read_weight_t;
+
+
+
+typedef union oha_l3_vdd_directory_write_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l3_vdd_directory_write_weight_t;
+
+
+
+typedef union oha_l3_vdd_cache_access_weight {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 6;
+ uint64_t _reserved0 : 58;
+#else
+ uint64_t _reserved0 : 58;
+ uint64_t value : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_l3_vdd_cache_access_weight_t;
+
+
+
+typedef union oha_chksw_hw132623dis {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t value : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_chksw_hw132623dis_t;
+
+
+
+typedef union oha_activity_scale_factor_array {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 56;
+ uint64_t _reserved0 : 8;
+#else
+ uint64_t _reserved0 : 8;
+ uint64_t value : 56;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_activity_scale_factor_array_t;
+
+
+
+typedef union oha_activity_scale_shift_factor_array {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 42;
+ uint64_t _reserved0 : 22;
+#else
+ uint64_t _reserved0 : 22;
+ uint64_t value : 42;
+#endif // _BIG_ENDIAN
+ } fields;
+} oha_activity_scale_shift_factor_array_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __OHA_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/oha_register_addresses.h b/src/ssx/pgp/registers/oha_register_addresses.h
new file mode 100755
index 0000000..1f07b37
--- /dev/null
+++ b/src/ssx/pgp/registers/oha_register_addresses.h
@@ -0,0 +1,39 @@
+#ifndef __OHA_REGISTER_ADDRESSES_H__
+#define __OHA_REGISTER_ADDRESSES_H__
+
+// $Id: oha_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/oha_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file oha_register_addresses.h
+/// \brief Symbolic addresses for the OHA unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define OHA_PCB_BASE 0x10020000
+#define OHA_ACTIVITY_SAMPLE_MODE_REG 0x10020000
+#define OHA_VCS_ACTIVITY_CNT_REG 0x10020001
+#define OHA_VDD_ACTIVITY_CNT_REG 0x10020002
+#define OHA_LOW_ACTIVITY_DETECT_MODE_REG 0x10020003
+#define OHA_ACTIVITY_AND_FREQU_REG 0x10020004
+#define OHA_COUNTER_REG 0x10020005
+#define OHA_PROXY_REG 0x10020006
+#define OHA_PROXY_LEGACY_REG 0x10020007
+#define OHA_SKITTER_CTRL_MODE_REG 0x10020008
+#define OHA_CPM_CTRL_REG 0x1002000a
+#define OHA_CPM_HIST_RESET_REG 0x10020013
+#define OHA_RO_STATUS_REG 0x1002000b
+#define OHA_MODE_REG 0x1002000d
+#define OHA_ERROR_AND_ERROR_MASK_REG 0x1002000e
+#define OHA_ARCH_IDLE_STATE_REG 0x10020011
+#define OHA_PMU_CONFIG_REG 0x10020012
+#define OHA_AISS_IO_REG 0x10020014
+#define OHA_PPT_BAR_REG 0x10020015
+
+#endif // __OHA_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/pba_firmware_registers.h b/src/ssx/pgp/registers/pba_firmware_registers.h
new file mode 100755
index 0000000..502ef51
--- /dev/null
+++ b/src/ssx/pgp/registers/pba_firmware_registers.h
@@ -0,0 +1,2184 @@
+#ifndef __PBA_FIRMWARE_REGISTERS_H__
+#define __PBA_FIRMWARE_REGISTERS_H__
+
+// $Id: pba_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pba_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pba_firmware_registers.h
+/// \brief C register structs for the PBA unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union pba_barn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cmd_scope : 3;
+ uint64_t reserved0 : 1;
+ uint64_t reserved1 : 10;
+ uint64_t addr : 30;
+ uint64_t _reserved0 : 20;
+#else
+ uint64_t _reserved0 : 20;
+ uint64_t addr : 30;
+ uint64_t reserved1 : 10;
+ uint64_t reserved0 : 1;
+ uint64_t cmd_scope : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_barn_t;
+
+#endif // __ASSEMBLER__
+#define PBA_BARN_CMD_SCOPE_MASK SIXTYFOUR_BIT_CONSTANT(0xe000000000000000)
+#define PBA_BARN_ADDR_MASK SIXTYFOUR_BIT_CONSTANT(0x0003fffffff00000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pba_barmskn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 23;
+ uint64_t mask : 21;
+ uint64_t _reserved0 : 20;
+#else
+ uint64_t _reserved0 : 20;
+ uint64_t mask : 21;
+ uint64_t reserved0 : 23;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_barmskn_t;
+
+#endif // __ASSEMBLER__
+#define PBA_BARMSKN_MASK_MASK SIXTYFOUR_BIT_CONSTANT(0x000001fffff00000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pba_fir {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_fir_t;
+
+#endif // __ASSEMBLER__
+#define PBA_FIR_OCI_APAR_ERR SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PBA_FIR_PB_RDADRERR_FW SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define PBA_FIR_PB_RDDATATO_FW SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define PBA_FIR_PB_SUE_FW SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define PBA_FIR_PB_UE_FW SIXTYFOUR_BIT_CONSTANT(0x0800000000000000)
+#define PBA_FIR_PB_CE_FW SIXTYFOUR_BIT_CONSTANT(0x0400000000000000)
+#define PBA_FIR_OCI_SLAVE_INIT SIXTYFOUR_BIT_CONSTANT(0x0200000000000000)
+#define PBA_FIR_OCI_WRPAR_ERR SIXTYFOUR_BIT_CONSTANT(0x0100000000000000)
+#define PBA_FIR_OCI_REREQTO SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PBA_FIR_PB_UNEXPCRESP SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PBA_FIR_PB_UNEXPDATA SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define PBA_FIR_PB_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0010000000000000)
+#define PBA_FIR_PB_WRADRERR_FW SIXTYFOUR_BIT_CONSTANT(0x0008000000000000)
+#define PBA_FIR_PB_BADCRESP SIXTYFOUR_BIT_CONSTANT(0x0004000000000000)
+#define PBA_FIR_PB_ACKDEAD_FW SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#define PBA_FIR_PB_CRESPTO SIXTYFOUR_BIT_CONSTANT(0x0001000000000000)
+#define PBA_FIR_BCUE_SETUP_ERR SIXTYFOUR_BIT_CONSTANT(0x0000800000000000)
+#define PBA_FIR_BCUE_PB_ACK_DEAD SIXTYFOUR_BIT_CONSTANT(0x0000400000000000)
+#define PBA_FIR_BCUE_PB_ADRERR SIXTYFOUR_BIT_CONSTANT(0x0000200000000000)
+#define PBA_FIR_BCUE_OCI_DATAERR SIXTYFOUR_BIT_CONSTANT(0x0000100000000000)
+#define PBA_FIR_BCDE_SETUP_ERR SIXTYFOUR_BIT_CONSTANT(0x0000080000000000)
+#define PBA_FIR_BCDE_PB_ACK_DEAD SIXTYFOUR_BIT_CONSTANT(0x0000040000000000)
+#define PBA_FIR_BCDE_PB_ADRERR SIXTYFOUR_BIT_CONSTANT(0x0000020000000000)
+#define PBA_FIR_BCDE_RDDATATO_ERR SIXTYFOUR_BIT_CONSTANT(0x0000010000000000)
+#define PBA_FIR_BCDE_SUE_ERR SIXTYFOUR_BIT_CONSTANT(0x0000008000000000)
+#define PBA_FIR_BCDE_UE_ERR SIXTYFOUR_BIT_CONSTANT(0x0000004000000000)
+#define PBA_FIR_BCDE_CE SIXTYFOUR_BIT_CONSTANT(0x0000002000000000)
+#define PBA_FIR_BCDE_OCI_DATAERR SIXTYFOUR_BIT_CONSTANT(0x0000001000000000)
+#define PBA_FIR_INTERNAL_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000800000000)
+#define PBA_FIR_ILLEGAL_CACHE_OP SIXTYFOUR_BIT_CONSTANT(0x0000000400000000)
+#define PBA_FIR_OCI_BAD_REG_ADDR SIXTYFOUR_BIT_CONSTANT(0x0000000200000000)
+#define PBA_FIR_AXPUSH_WRERR SIXTYFOUR_BIT_CONSTANT(0x0000000100000000)
+#define PBA_FIR_AXRCV_DLO_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000080000000)
+#define PBA_FIR_AXRCV_DLO_TO SIXTYFOUR_BIT_CONSTANT(0x0000000040000000)
+#define PBA_FIR_AXRCV_RSVDATA_TO SIXTYFOUR_BIT_CONSTANT(0x0000000020000000)
+#define PBA_FIR_AXFLOW_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000010000000)
+#define PBA_FIR_AXSND_DHI_RTYTO SIXTYFOUR_BIT_CONSTANT(0x0000000008000000)
+#define PBA_FIR_AXSND_DLO_RTYTO SIXTYFOUR_BIT_CONSTANT(0x0000000004000000)
+#define PBA_FIR_AXSND_RSVTO SIXTYFOUR_BIT_CONSTANT(0x0000000002000000)
+#define PBA_FIR_AXSND_RSVERR SIXTYFOUR_BIT_CONSTANT(0x0000000001000000)
+#define PBA_FIR_PB_ACKDEAD_FW_WR SIXTYFOUR_BIT_CONSTANT(0x0000000000800000)
+#define PBA_FIR_FIR_PARITY_ERR2 SIXTYFOUR_BIT_CONSTANT(0x0000000000080000)
+#define PBA_FIR_FIR_PARITY_ERR SIXTYFOUR_BIT_CONSTANT(0x0000000000040000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pba_fir_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_fir_and_t;
+
+
+
+typedef union pba_fir_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_fir_or_t;
+
+
+
+typedef union pba_firmask {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_firmask_t;
+
+
+
+typedef union pba_firmask_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_firmask_and_t;
+
+
+
+typedef union pba_firmask_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_firmask_or_t;
+
+
+
+typedef union pba_firact0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_firact0_t;
+
+
+
+typedef union pba_firact1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_firact1_t;
+
+
+
+typedef union pba_occact {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t oci_apar_err : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t internal_err : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t reserved41 : 3;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err2 : 1;
+ uint64_t reserved41 : 3;
+ uint64_t pb_ackdead_fw_wr : 1;
+ uint64_t axsnd_rsverr : 1;
+ uint64_t axsnd_rsvto : 1;
+ uint64_t axsnd_dlo_rtyto : 1;
+ uint64_t axsnd_dhi_rtyto : 1;
+ uint64_t axflow_err : 1;
+ uint64_t axrcv_rsvdata_to : 1;
+ uint64_t axrcv_dlo_to : 1;
+ uint64_t axrcv_dlo_err : 1;
+ uint64_t axpush_wrerr : 1;
+ uint64_t oci_bad_reg_addr : 1;
+ uint64_t illegal_cache_op : 1;
+ uint64_t internal_err : 1;
+ uint64_t bcde_oci_dataerr : 1;
+ uint64_t bcde_ce : 1;
+ uint64_t bcde_ue_err : 1;
+ uint64_t bcde_sue_err : 1;
+ uint64_t bcde_rddatato_err : 1;
+ uint64_t bcde_pb_adrerr : 1;
+ uint64_t bcde_pb_ack_dead : 1;
+ uint64_t bcde_setup_err : 1;
+ uint64_t bcue_oci_dataerr : 1;
+ uint64_t bcue_pb_adrerr : 1;
+ uint64_t bcue_pb_ack_dead : 1;
+ uint64_t bcue_setup_err : 1;
+ uint64_t pb_crespto : 1;
+ uint64_t pb_ackdead_fw : 1;
+ uint64_t pb_badcresp : 1;
+ uint64_t pb_wradrerr_fw : 1;
+ uint64_t pb_parity_err : 1;
+ uint64_t pb_unexpdata : 1;
+ uint64_t pb_unexpcresp : 1;
+ uint64_t oci_rereqto : 1;
+ uint64_t oci_wrpar_err : 1;
+ uint64_t oci_slave_init : 1;
+ uint64_t pb_ce_fw : 1;
+ uint64_t pb_ue_fw : 1;
+ uint64_t pb_sue_fw : 1;
+ uint64_t pb_rddatato_fw : 1;
+ uint64_t pb_rdadrerr_fw : 1;
+ uint64_t oci_apar_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_occact_t;
+
+
+
+typedef union pba_cfg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pbreq_slvfw_max_priority : 2;
+ uint64_t pbreq_bce_max_priority : 2;
+ uint64_t pbreq_data_hang_div : 5;
+ uint64_t pbreq_oper_hang_div : 5;
+ uint64_t pbreq_drop_priority_mask : 6;
+ uint64_t reserved20 : 4;
+ uint64_t chsw_hang_on_adrerror : 1;
+ uint64_t chsw_dis_ociabuspar_check : 1;
+ uint64_t chsw_dis_ocibepar_check : 1;
+ uint64_t chsw_hang_on_derror : 1;
+ uint64_t chsw_hang_on_rereq_timeout : 1;
+ uint64_t chsw_dis_write_match_rearb : 1;
+ uint64_t chsw_dis_ocidatapar_gen : 1;
+ uint64_t chsw_dis_ocidatapar_check : 1;
+ uint64_t chsw_dis_oper_hang : 1;
+ uint64_t chsw_dis_data_hang : 1;
+ uint64_t chsw_dis_ecc_check : 1;
+ uint64_t chsw_dis_retry_backoff : 1;
+ uint64_t chsw_hang_on_invalid_cresp : 1;
+ uint64_t chsw_en_scopeinc_on_bkill_inc : 1;
+ uint64_t chsw_dis_group_scope : 1;
+ uint64_t chsw_dis_rtag_parity_chk : 1;
+ uint64_t chsw_dis_pb_parity_chk : 1;
+ uint64_t _reserved0 : 23;
+#else
+ uint64_t _reserved0 : 23;
+ uint64_t chsw_dis_pb_parity_chk : 1;
+ uint64_t chsw_dis_rtag_parity_chk : 1;
+ uint64_t chsw_dis_group_scope : 1;
+ uint64_t chsw_en_scopeinc_on_bkill_inc : 1;
+ uint64_t chsw_hang_on_invalid_cresp : 1;
+ uint64_t chsw_dis_retry_backoff : 1;
+ uint64_t chsw_dis_ecc_check : 1;
+ uint64_t chsw_dis_data_hang : 1;
+ uint64_t chsw_dis_oper_hang : 1;
+ uint64_t chsw_dis_ocidatapar_check : 1;
+ uint64_t chsw_dis_ocidatapar_gen : 1;
+ uint64_t chsw_dis_write_match_rearb : 1;
+ uint64_t chsw_hang_on_rereq_timeout : 1;
+ uint64_t chsw_hang_on_derror : 1;
+ uint64_t chsw_dis_ocibepar_check : 1;
+ uint64_t chsw_dis_ociabuspar_check : 1;
+ uint64_t chsw_hang_on_adrerror : 1;
+ uint64_t reserved20 : 4;
+ uint64_t pbreq_drop_priority_mask : 6;
+ uint64_t pbreq_oper_hang_div : 5;
+ uint64_t pbreq_data_hang_div : 5;
+ uint64_t pbreq_bce_max_priority : 2;
+ uint64_t pbreq_slvfw_max_priority : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_cfg_t;
+
+
+
+typedef union pba_errpt0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cerr_pb_rddatato_fw : 6;
+ uint64_t cerr_pb_rdadrerr_fw : 6;
+ uint64_t cerr_pb_wradrerr_fw : 4;
+ uint64_t cerr_pb_ackdead_fw_rd : 6;
+ uint64_t cerr_pb_ackdead_fw_wr : 2;
+ uint64_t cerr_pb_unexpcresp : 11;
+ uint64_t cerr_pb_unexpdata : 6;
+ uint64_t _reserved0 : 23;
+#else
+ uint64_t _reserved0 : 23;
+ uint64_t cerr_pb_unexpdata : 6;
+ uint64_t cerr_pb_unexpcresp : 11;
+ uint64_t cerr_pb_ackdead_fw_wr : 2;
+ uint64_t cerr_pb_ackdead_fw_rd : 6;
+ uint64_t cerr_pb_wradrerr_fw : 4;
+ uint64_t cerr_pb_rdadrerr_fw : 6;
+ uint64_t cerr_pb_rddatato_fw : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_errpt0_t;
+
+
+
+typedef union pba_errpt1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cerr_pb_badcresp : 12;
+ uint64_t cerr_pb_crespto : 12;
+ uint64_t cerr_oci_rereqto : 6;
+ uint64_t cerr_bcde_setup_err : 2;
+ uint64_t cerr_bcue_setup_err : 2;
+ uint64_t cerr_bcue_oci_dataerr : 2;
+ uint64_t _reserved0 : 28;
+#else
+ uint64_t _reserved0 : 28;
+ uint64_t cerr_bcue_oci_dataerr : 2;
+ uint64_t cerr_bcue_setup_err : 2;
+ uint64_t cerr_bcde_setup_err : 2;
+ uint64_t cerr_oci_rereqto : 6;
+ uint64_t cerr_pb_crespto : 12;
+ uint64_t cerr_pb_badcresp : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_errpt1_t;
+
+
+
+typedef union pba_errpt2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cerr_slv_internal_err : 8;
+ uint64_t cerr_bcde_internal_err : 4;
+ uint64_t cerr_bcue_internal_err : 4;
+ uint64_t cerr_bar_parity_err : 1;
+ uint64_t cerr_scomtb_err : 1;
+ uint64_t reserved18 : 2;
+ uint64_t cerr_pbdout_parity_err : 1;
+ uint64_t cerr_pb_parity_err : 3;
+ uint64_t cerr_axflow_err : 5;
+ uint64_t cerr_axpush_wrerr : 2;
+ uint64_t _reserved0 : 33;
+#else
+ uint64_t _reserved0 : 33;
+ uint64_t cerr_axpush_wrerr : 2;
+ uint64_t cerr_axflow_err : 5;
+ uint64_t cerr_pb_parity_err : 3;
+ uint64_t cerr_pbdout_parity_err : 1;
+ uint64_t reserved18 : 2;
+ uint64_t cerr_scomtb_err : 1;
+ uint64_t cerr_bar_parity_err : 1;
+ uint64_t cerr_bcue_internal_err : 4;
+ uint64_t cerr_bcde_internal_err : 4;
+ uint64_t cerr_slv_internal_err : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_errpt2_t;
+
+
+
+typedef union pba_rbufvaln {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t rd_slvnum : 2;
+ uint64_t cur_rd_addr : 23;
+ uint64_t spare1 : 3;
+ uint64_t prefetch : 1;
+ uint64_t spare2 : 2;
+ uint64_t abort : 1;
+ uint64_t spare3 : 1;
+ uint64_t buffer_status : 7;
+ uint64_t spare4 : 1;
+ uint64_t masterid : 3;
+ uint64_t _reserved0 : 20;
+#else
+ uint64_t _reserved0 : 20;
+ uint64_t masterid : 3;
+ uint64_t spare4 : 1;
+ uint64_t buffer_status : 7;
+ uint64_t spare3 : 1;
+ uint64_t abort : 1;
+ uint64_t spare2 : 2;
+ uint64_t prefetch : 1;
+ uint64_t spare1 : 3;
+ uint64_t cur_rd_addr : 23;
+ uint64_t rd_slvnum : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_rbufvaln_t;
+
+
+
+typedef union pba_wbufvaln {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t wr_slvnum : 2;
+ uint64_t start_wr_addr : 30;
+ uint64_t spare1 : 3;
+ uint64_t wr_buffer_status : 5;
+ uint64_t spare2 : 1;
+ uint64_t wr_byte_count : 7;
+ uint64_t spare3 : 16;
+#else
+ uint64_t spare3 : 16;
+ uint64_t wr_byte_count : 7;
+ uint64_t spare2 : 1;
+ uint64_t wr_buffer_status : 5;
+ uint64_t spare1 : 3;
+ uint64_t start_wr_addr : 30;
+ uint64_t wr_slvnum : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_wbufvaln_t;
+
+
+
+typedef union pba_mode {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 4;
+ uint64_t dis_rearb : 1;
+ uint64_t dis_mstid_match_pref_inv : 1;
+ uint64_t dis_slave_rdpipe : 1;
+ uint64_t dis_slave_wrpipe : 1;
+ uint64_t en_marker_ack : 1;
+ uint64_t dis_slvmatch_order : 1;
+ uint64_t en_second_wrbuf : 1;
+ uint64_t dis_rerequest_to : 1;
+ uint64_t inject_type : 2;
+ uint64_t inject_mode : 2;
+ uint64_t pba_region : 2;
+ uint64_t oci_marker_space : 3;
+ uint64_t bcde_ocitrans : 2;
+ uint64_t bcue_ocitrans : 2;
+ uint64_t dis_master_rd_pipe : 1;
+ uint64_t dis_master_wr_pipe : 1;
+ uint64_t en_slave_fairness : 1;
+ uint64_t en_event_count : 1;
+ uint64_t pb_noci_event_sel : 1;
+ uint64_t slv_event_mux : 2;
+ uint64_t enable_debug_bus : 1;
+ uint64_t debug_pb_not_oci : 1;
+ uint64_t debug_oci_mode : 5;
+ uint64_t reserved2 : 1;
+ uint64_t ocislv_fairness_mask : 5;
+ uint64_t ocislv_rereq_hang_div : 5;
+ uint64_t dis_chgrate_count : 1;
+ uint64_t pbreq_event_mux : 2;
+ uint64_t _reserved0 : 11;
+#else
+ uint64_t _reserved0 : 11;
+ uint64_t pbreq_event_mux : 2;
+ uint64_t dis_chgrate_count : 1;
+ uint64_t ocislv_rereq_hang_div : 5;
+ uint64_t ocislv_fairness_mask : 5;
+ uint64_t reserved2 : 1;
+ uint64_t debug_oci_mode : 5;
+ uint64_t debug_pb_not_oci : 1;
+ uint64_t enable_debug_bus : 1;
+ uint64_t slv_event_mux : 2;
+ uint64_t pb_noci_event_sel : 1;
+ uint64_t en_event_count : 1;
+ uint64_t en_slave_fairness : 1;
+ uint64_t dis_master_wr_pipe : 1;
+ uint64_t dis_master_rd_pipe : 1;
+ uint64_t bcue_ocitrans : 2;
+ uint64_t bcde_ocitrans : 2;
+ uint64_t oci_marker_space : 3;
+ uint64_t pba_region : 2;
+ uint64_t inject_mode : 2;
+ uint64_t inject_type : 2;
+ uint64_t dis_rerequest_to : 1;
+ uint64_t en_second_wrbuf : 1;
+ uint64_t dis_slvmatch_order : 1;
+ uint64_t en_marker_ack : 1;
+ uint64_t dis_slave_wrpipe : 1;
+ uint64_t dis_slave_rdpipe : 1;
+ uint64_t dis_mstid_match_pref_inv : 1;
+ uint64_t dis_rearb : 1;
+ uint64_t reserved0 : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_mode_t;
+
+
+
+typedef union pba_slvrst {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t set : 3;
+ uint64_t notimp1 : 1;
+ uint64_t in_prog : 4;
+ uint64_t busy_status : 4;
+ uint64_t _reserved0 : 52;
+#else
+ uint64_t _reserved0 : 52;
+ uint64_t busy_status : 4;
+ uint64_t in_prog : 4;
+ uint64_t notimp1 : 1;
+ uint64_t set : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_slvrst_t;
+
+
+
+typedef union pba_slvctln {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t enable : 1;
+ uint64_t mid_match_value : 3;
+ uint64_t _reserved0 : 1;
+ uint64_t mid_care_mask : 3;
+ uint64_t write_ttype : 3;
+ uint64_t _reserved1 : 4;
+ uint64_t read_ttype : 1;
+ uint64_t read_prefetch_ctl : 2;
+ uint64_t buf_invalidate_ctl : 1;
+ uint64_t buf_alloc_w : 1;
+ uint64_t buf_alloc_a : 1;
+ uint64_t buf_alloc_b : 1;
+ uint64_t buf_alloc_c : 1;
+ uint64_t _reserved2 : 1;
+ uint64_t dis_write_gather : 1;
+ uint64_t wr_gather_timeout : 3;
+ uint64_t write_tsize : 7;
+ uint64_t extaddr : 14;
+ uint64_t _reserved3 : 15;
+#else
+ uint64_t _reserved3 : 15;
+ uint64_t extaddr : 14;
+ uint64_t write_tsize : 7;
+ uint64_t wr_gather_timeout : 3;
+ uint64_t dis_write_gather : 1;
+ uint64_t _reserved2 : 1;
+ uint64_t buf_alloc_c : 1;
+ uint64_t buf_alloc_b : 1;
+ uint64_t buf_alloc_a : 1;
+ uint64_t buf_alloc_w : 1;
+ uint64_t buf_invalidate_ctl : 1;
+ uint64_t read_prefetch_ctl : 2;
+ uint64_t read_ttype : 1;
+ uint64_t _reserved1 : 4;
+ uint64_t write_ttype : 3;
+ uint64_t mid_care_mask : 3;
+ uint64_t _reserved0 : 1;
+ uint64_t mid_match_value : 3;
+ uint64_t enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_slvctln_t;
+
+
+
+typedef union pba_bcde_ctl {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t stop : 1;
+ uint64_t start : 1;
+ uint64_t _reserved0 : 62;
+#else
+ uint64_t _reserved0 : 62;
+ uint64_t start : 1;
+ uint64_t stop : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcde_ctl_t;
+
+#endif // __ASSEMBLER__
+#define PBA_BCDE_CTL_STOP SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PBA_BCDE_CTL_START SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pba_bcde_set {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 2;
+ uint64_t copy_length : 6;
+ uint64_t _reserved1 : 56;
+#else
+ uint64_t _reserved1 : 56;
+ uint64_t copy_length : 6;
+ uint64_t _reserved0 : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcde_set_t;
+
+
+
+typedef union pba_bcde_stat {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t running : 1;
+ uint64_t waiting : 1;
+ uint64_t wrcmp : 6;
+ uint64_t _reserved0 : 6;
+ uint64_t rdcmp : 6;
+ uint64_t debug : 9;
+ uint64_t stopped : 1;
+ uint64_t error : 1;
+ uint64_t done : 1;
+ uint64_t _reserved1 : 32;
+#else
+ uint64_t _reserved1 : 32;
+ uint64_t done : 1;
+ uint64_t error : 1;
+ uint64_t stopped : 1;
+ uint64_t debug : 9;
+ uint64_t rdcmp : 6;
+ uint64_t _reserved0 : 6;
+ uint64_t wrcmp : 6;
+ uint64_t waiting : 1;
+ uint64_t running : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcde_stat_t;
+
+
+
+typedef union pba_bcde_pbadr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 2;
+ uint64_t pb_offset : 23;
+ uint64_t _reserved1 : 2;
+ uint64_t extaddr : 14;
+ uint64_t _reserved2 : 23;
+#else
+ uint64_t _reserved2 : 23;
+ uint64_t extaddr : 14;
+ uint64_t _reserved1 : 2;
+ uint64_t pb_offset : 23;
+ uint64_t _reserved0 : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcde_pbadr_t;
+
+
+
+typedef union pba_bcde_ocibar {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t addr : 25;
+ uint64_t _reserved0 : 39;
+#else
+ uint64_t _reserved0 : 39;
+ uint64_t addr : 25;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcde_ocibar_t;
+
+
+
+typedef union pba_bcue_ctl {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t stop : 1;
+ uint64_t start : 1;
+ uint64_t _reserved0 : 62;
+#else
+ uint64_t _reserved0 : 62;
+ uint64_t start : 1;
+ uint64_t stop : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcue_ctl_t;
+
+#endif // __ASSEMBLER__
+#define PBA_BCUE_CTL_STOP SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PBA_BCUE_CTL_START SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pba_bcue_set {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 2;
+ uint64_t copy_length : 6;
+ uint64_t _reserved1 : 56;
+#else
+ uint64_t _reserved1 : 56;
+ uint64_t copy_length : 6;
+ uint64_t _reserved0 : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcue_set_t;
+
+
+
+typedef union pba_bcue_stat {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t running : 1;
+ uint64_t waiting : 1;
+ uint64_t wrcmp : 6;
+ uint64_t _reserved0 : 6;
+ uint64_t rdcmp : 6;
+ uint64_t debug : 9;
+ uint64_t stopped : 1;
+ uint64_t error : 1;
+ uint64_t done : 1;
+ uint64_t _reserved1 : 32;
+#else
+ uint64_t _reserved1 : 32;
+ uint64_t done : 1;
+ uint64_t error : 1;
+ uint64_t stopped : 1;
+ uint64_t debug : 9;
+ uint64_t rdcmp : 6;
+ uint64_t _reserved0 : 6;
+ uint64_t wrcmp : 6;
+ uint64_t waiting : 1;
+ uint64_t running : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcue_stat_t;
+
+
+
+typedef union pba_bcue_pbadr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 2;
+ uint64_t pb_offset : 23;
+ uint64_t _reserved1 : 2;
+ uint64_t extaddr : 14;
+ uint64_t _reserved2 : 23;
+#else
+ uint64_t _reserved2 : 23;
+ uint64_t extaddr : 14;
+ uint64_t _reserved1 : 2;
+ uint64_t pb_offset : 23;
+ uint64_t _reserved0 : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcue_pbadr_t;
+
+
+
+typedef union pba_bcue_ocibar {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t addr : 25;
+ uint64_t _reserved0 : 39;
+#else
+ uint64_t _reserved0 : 39;
+ uint64_t addr : 25;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_bcue_ocibar_t;
+
+
+
+typedef union pba_pbocrn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 16;
+ uint64_t event : 16;
+ uint64_t _reserved1 : 12;
+ uint64_t accum : 20;
+#else
+ uint64_t accum : 20;
+ uint64_t _reserved1 : 12;
+ uint64_t event : 16;
+ uint64_t _reserved0 : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_pbocrn_t;
+
+
+
+typedef union pba_xsndtx {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t snd_scope : 3;
+ uint64_t snd_qid : 1;
+ uint64_t snd_type : 1;
+ uint64_t snd_reservation : 1;
+ uint64_t spare6 : 2;
+ uint64_t snd_nodeid : 3;
+ uint64_t snd_chipid : 3;
+ uint64_t spare14 : 2;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ uint64_t spare14 : 2;
+ uint64_t snd_chipid : 3;
+ uint64_t snd_nodeid : 3;
+ uint64_t spare6 : 2;
+ uint64_t snd_reservation : 1;
+ uint64_t snd_type : 1;
+ uint64_t snd_qid : 1;
+ uint64_t snd_scope : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xsndtx_t;
+
+
+
+typedef union pba_xcfg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pbax_en : 1;
+ uint64_t reservation_en : 1;
+ uint64_t snd_reset : 1;
+ uint64_t rcv_reset : 1;
+ uint64_t rcv_nodeid : 3;
+ uint64_t rcv_chipid : 3;
+ uint64_t spare10 : 2;
+ uint64_t rcv_brdcst_group : 8;
+ uint64_t rcv_datato_div : 5;
+ uint64_t spare25 : 2;
+ uint64_t snd_retry_count_overcom : 1;
+ uint64_t snd_retry_thresh : 8;
+ uint64_t snd_rsvto_div : 5;
+ uint64_t _reserved0 : 23;
+#else
+ uint64_t _reserved0 : 23;
+ uint64_t snd_rsvto_div : 5;
+ uint64_t snd_retry_thresh : 8;
+ uint64_t snd_retry_count_overcom : 1;
+ uint64_t spare25 : 2;
+ uint64_t rcv_datato_div : 5;
+ uint64_t rcv_brdcst_group : 8;
+ uint64_t spare10 : 2;
+ uint64_t rcv_chipid : 3;
+ uint64_t rcv_nodeid : 3;
+ uint64_t rcv_reset : 1;
+ uint64_t snd_reset : 1;
+ uint64_t reservation_en : 1;
+ uint64_t pbax_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xcfg_t;
+
+
+
+typedef union pba_xsndstat {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t snd_in_progress : 1;
+ uint64_t snd_error : 1;
+ uint64_t snd_status : 6;
+ uint64_t snd_retry_count : 8;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ uint64_t snd_retry_count : 8;
+ uint64_t snd_status : 6;
+ uint64_t snd_error : 1;
+ uint64_t snd_in_progress : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xsndstat_t;
+
+
+
+typedef union pba_xsnddat {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pbax_datahi : 32;
+ uint64_t pbax_datalo : 32;
+#else
+ uint64_t pbax_datalo : 32;
+ uint64_t pbax_datahi : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xsnddat_t;
+
+
+
+typedef union pba_xrcvstat {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t rcv_in_progress : 1;
+ uint64_t rcv_error : 1;
+ uint64_t rcv_write_in_progress : 1;
+ uint64_t rcv_reservation_set : 1;
+ uint64_t rcv_capture : 14;
+ uint64_t _reserved0 : 46;
+#else
+ uint64_t _reserved0 : 46;
+ uint64_t rcv_capture : 14;
+ uint64_t rcv_reservation_set : 1;
+ uint64_t rcv_write_in_progress : 1;
+ uint64_t rcv_error : 1;
+ uint64_t rcv_in_progress : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xrcvstat_t;
+
+
+
+typedef union pba_xshbrn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t push_start : 29;
+ uint64_t _reserved0 : 35;
+#else
+ uint64_t _reserved0 : 35;
+ uint64_t push_start : 29;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xshbrn_t;
+
+
+
+typedef union pba_xshcsn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t push_full : 1;
+ uint64_t push_empty : 1;
+ uint64_t spare1 : 2;
+ uint64_t push_intr_action : 2;
+ uint64_t push_length : 5;
+ uint64_t notimp1 : 2;
+ uint64_t push_write_ptr : 5;
+ uint64_t notimp2 : 3;
+ uint64_t push_read_ptr : 5;
+ uint64_t notimp3 : 5;
+ uint64_t push_enable : 1;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t push_enable : 1;
+ uint64_t notimp3 : 5;
+ uint64_t push_read_ptr : 5;
+ uint64_t notimp2 : 3;
+ uint64_t push_write_ptr : 5;
+ uint64_t notimp1 : 2;
+ uint64_t push_length : 5;
+ uint64_t push_intr_action : 2;
+ uint64_t spare1 : 2;
+ uint64_t push_empty : 1;
+ uint64_t push_full : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xshcsn_t;
+
+
+
+typedef union pba_xshincn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 64;
+#else
+ uint64_t reserved : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pba_xshincn_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __PBA_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/pba_register_addresses.h b/src/ssx/pgp/registers/pba_register_addresses.h
new file mode 100755
index 0000000..1703629
--- /dev/null
+++ b/src/ssx/pgp/registers/pba_register_addresses.h
@@ -0,0 +1,94 @@
+#ifndef __PBA_REGISTER_ADDRESSES_H__
+#define __PBA_REGISTER_ADDRESSES_H__
+
+// $Id: pba_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pba_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pba_register_addresses.h
+/// \brief Symbolic addresses for the PBA unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define TRUSTEDPIB_BASE 0x02013f00
+#define PBA_BARN(n) (PBA_BAR0 + ((PBA_BAR1 - PBA_BAR0) * (n)))
+#define PBA_BAR0 0x02013f00
+#define PBA_BAR1 0x02013f01
+#define PBA_BAR2 0x02013f02
+#define PBA_BAR3 0x02013f03
+#define PBA_BARMSKN(n) (PBA_BARMSK0 + ((PBA_BARMSK1 - PBA_BARMSK0) * (n)))
+#define PBA_BARMSK0 0x02013f04
+#define PBA_BARMSK1 0x02013f05
+#define PBA_BARMSK2 0x02013f06
+#define PBA_BARMSK3 0x02013f07
+#define PIB_BASE 0x02010840
+#define PBA_FIR 0x02010840
+#define PBA_FIR_AND 0x02010841
+#define PBA_FIR_OR 0x02010842
+#define PBA_FIRMASK 0x02010843
+#define PBA_FIRMASK_AND 0x02010844
+#define PBA_FIRMASK_OR 0x02010845
+#define PBA_FIRACT0 0x02010846
+#define PBA_FIRACT1 0x02010847
+#define PBA_OCCACT 0x0201084a
+#define PBA_CFG 0x0201084b
+#define PBA_ERRPT0 0x0201084c
+#define PBA_ERRPT1 0x0201084d
+#define PBA_ERRPT2 0x0201084e
+#define PBA_RBUFVALN(n) (PBA_RBUFVAL0 + ((PBA_RBUFVAL1 - PBA_RBUFVAL0) * (n)))
+#define PBA_RBUFVAL0 0x02010850
+#define PBA_RBUFVAL1 0x02010851
+#define PBA_RBUFVAL2 0x02010852
+#define PBA_RBUFVAL3 0x02010853
+#define PBA_RBUFVAL4 0x02010854
+#define PBA_RBUFVAL5 0x02010855
+#define PBA_WBUFVALN(n) (PBA_WBUFVAL0 + ((PBA_WBUFVAL1 - PBA_WBUFVAL0) * (n)))
+#define PBA_WBUFVAL0 0x02010858
+#define PBA_WBUFVAL1 0x02010859
+#define OCI_BASE 0x40020000
+#define PBA_MODE 0x40020000
+#define PBA_SLVRST 0x40020008
+#define PBA_SLVCTLN(n) (PBA_SLVCTL0 + ((PBA_SLVCTL1 - PBA_SLVCTL0) * (n)))
+#define PBA_SLVCTL0 0x40020020
+#define PBA_SLVCTL1 0x40020028
+#define PBA_SLVCTL2 0x40020030
+#define PBA_SLVCTL3 0x40020038
+#define PBA_BCDE_CTL 0x40020080
+#define PBA_BCDE_SET 0x40020088
+#define PBA_BCDE_STAT 0x40020090
+#define PBA_BCDE_PBADR 0x40020098
+#define PBA_BCDE_OCIBAR 0x400200a0
+#define PBA_BCUE_CTL 0x400200a8
+#define PBA_BCUE_SET 0x400200b0
+#define PBA_BCUE_STAT 0x400200b8
+#define PBA_BCUE_PBADR 0x400200c0
+#define PBA_BCUE_OCIBAR 0x400200c8
+#define PBA_PBOCRN(n) (PBA_PBOCR0 + ((PBA_PBOCR1 - PBA_PBOCR0) * (n)))
+#define PBA_PBOCR0 0x400200d0
+#define PBA_PBOCR1 0x400200d8
+#define PBA_PBOCR2 0x400200e0
+#define PBA_PBOCR3 0x400200e8
+#define PBA_PBOCR4 0x400200f0
+#define PBA_PBOCR5 0x400200f8
+#define PBA_XSNDTX 0x40020100
+#define PBA_XCFG 0x40020108
+#define PBA_XSNDSTAT 0x40020110
+#define PBA_XSNDDAT 0x40020118
+#define PBA_XRCVSTAT 0x40020120
+#define PBA_XSHBRN(n) (PBA_XSHBR0 + ((PBA_XSHBR1 - PBA_XSHBR0) * (n)))
+#define PBA_XSHBR0 0x40020130
+#define PBA_XSHBR1 0x40020150
+#define PBA_XSHCSN(n) (PBA_XSHCS0 + ((PBA_XSHCS1 - PBA_XSHCS0) * (n)))
+#define PBA_XSHCS0 0x40020138
+#define PBA_XSHCS1 0x40020158
+#define PBA_XSHINCN(n) (PBA_XSHINC0 + ((PBA_XSHINC1 - PBA_XSHINC0) * (n)))
+#define PBA_XSHINC0 0x40020140
+#define PBA_XSHINC1 0x40020160
+
+#endif // __PBA_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/pc_firmware_registers.h b/src/ssx/pgp/registers/pc_firmware_registers.h
new file mode 100755
index 0000000..2c86308
--- /dev/null
+++ b/src/ssx/pgp/registers/pc_firmware_registers.h
@@ -0,0 +1,442 @@
+#ifndef __PC_FIRMWARE_REGISTERS_H__
+#define __PC_FIRMWARE_REGISTERS_H__
+
+// $Id: pc_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pc_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pc_firmware_registers.h
+/// \brief C register structs for the PC unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union pc_pfth_modereg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pfth_cntr_dis : 1;
+ uint64_t pfth_charac_mode : 1;
+ uint64_t pfth_cntr_run_latch_gate_dis : 1;
+ uint64_t sprd_pfth_tx_run_latches : 8;
+ uint64_t tx_threads_stopped : 8;
+ uint64_t _reserved0 : 45;
+#else
+ uint64_t _reserved0 : 45;
+ uint64_t tx_threads_stopped : 8;
+ uint64_t sprd_pfth_tx_run_latches : 8;
+ uint64_t pfth_cntr_run_latch_gate_dis : 1;
+ uint64_t pfth_charac_mode : 1;
+ uint64_t pfth_cntr_dis : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_pfth_modereg_t;
+
+
+
+typedef union pc_occ_sprc {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 53;
+ uint64_t autoinc : 1;
+ uint64_t sprn : 7;
+ uint64_t reserved1 : 3;
+#else
+ uint64_t reserved1 : 3;
+ uint64_t sprn : 7;
+ uint64_t autoinc : 1;
+ uint64_t reserved0 : 53;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_occ_sprc_t;
+
+
+
+typedef union pc_occ_sprd {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_occ_sprd_t;
+
+
+
+typedef union pc_pfth_oha_instr_cnt_sel {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 62;
+ uint64_t value : 2;
+#else
+ uint64_t value : 2;
+ uint64_t _reserved0 : 62;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_pfth_oha_instr_cnt_sel_t;
+
+
+
+typedef union pc_pfth_throt_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t didt_trigger_enable : 1;
+ uint64_t isu_trigger_enable : 1;
+ uint64_t didt_throttle : 2;
+ uint64_t uthrottle : 2;
+ uint64_t force_suppress_speedup : 1;
+ uint64_t suppress_speedup_on_throttle : 1;
+ uint64_t core_slowdown : 1;
+ uint64_t suppress_on_slowdown : 1;
+ uint64_t isu_only_count_mode : 1;
+ uint64_t spare : 5;
+ uint64_t reserved : 48;
+#else
+ uint64_t reserved : 48;
+ uint64_t spare : 5;
+ uint64_t isu_only_count_mode : 1;
+ uint64_t suppress_on_slowdown : 1;
+ uint64_t core_slowdown : 1;
+ uint64_t suppress_speedup_on_throttle : 1;
+ uint64_t force_suppress_speedup : 1;
+ uint64_t uthrottle : 2;
+ uint64_t didt_throttle : 2;
+ uint64_t isu_trigger_enable : 1;
+ uint64_t didt_trigger_enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_pfth_throt_reg_t;
+
+
+
+typedef union pc_direct_controln {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 42;
+ uint64_t dc_prestart_sleep : 1;
+ uint64_t dc_prestart_winkle : 1;
+ uint64_t dc_clear_maint : 1;
+ uint64_t dc_ntc_flush : 1;
+ uint64_t reserved46 : 1;
+ uint64_t dc_prestart_nap : 1;
+ uint64_t dc_cancel_lost : 1;
+ uint64_t dc_reset_maint : 1;
+ uint64_t reserved50 : 1;
+ uint64_t dc_set_maint : 1;
+ uint64_t dc_goto_quiesce_state : 1;
+ uint64_t reserved53 : 1;
+ uint64_t dc_inj_test_hang : 2;
+ uint64_t dc_core_running : 1;
+ uint64_t dc_hang_inject : 1;
+ uint64_t dc_smt_start_suppress : 1;
+ uint64_t reserved59 : 1;
+ uint64_t dc_sreset_request : 1;
+ uint64_t dc_core_step : 1;
+ uint64_t dc_core_start : 1;
+ uint64_t dc_core_stop : 1;
+#else
+ uint64_t dc_core_stop : 1;
+ uint64_t dc_core_start : 1;
+ uint64_t dc_core_step : 1;
+ uint64_t dc_sreset_request : 1;
+ uint64_t reserved59 : 1;
+ uint64_t dc_smt_start_suppress : 1;
+ uint64_t dc_hang_inject : 1;
+ uint64_t dc_core_running : 1;
+ uint64_t dc_inj_test_hang : 2;
+ uint64_t reserved53 : 1;
+ uint64_t dc_goto_quiesce_state : 1;
+ uint64_t dc_set_maint : 1;
+ uint64_t reserved50 : 1;
+ uint64_t dc_reset_maint : 1;
+ uint64_t dc_cancel_lost : 1;
+ uint64_t dc_prestart_nap : 1;
+ uint64_t reserved46 : 1;
+ uint64_t dc_ntc_flush : 1;
+ uint64_t dc_clear_maint : 1;
+ uint64_t dc_prestart_winkle : 1;
+ uint64_t dc_prestart_sleep : 1;
+ uint64_t reserved0 : 42;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_direct_controln_t;
+
+
+
+typedef union pc_ras_moderegn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 43;
+ uint64_t mr_thread_in_debug_mode : 1;
+ uint64_t mr_pmon_inhibit : 1;
+ uint64_t mr_fence_interrupts : 1;
+ uint64_t mr_stop_fetch : 1;
+ uint64_t mr_stop_prefetch : 1;
+ uint64_t mr_stop_dispatch : 1;
+ uint64_t mr_single_decode : 1;
+ uint64_t mr_do_single_mode : 1;
+ uint64_t mr_one_ppc_mode : 1;
+ uint64_t mr_hang_test_ctrl : 2;
+ uint64_t mr_attempt_gps_hr : 3;
+ uint64_t mr_hang_dis : 1;
+ uint64_t mr_on_corehng : 1;
+ uint64_t mr_on_ambihng : 1;
+ uint64_t mr_on_nesthng : 1;
+ uint64_t mr_recov_enable : 1;
+ uint64_t mr_block_hmi_on_maint : 1;
+ uint64_t mr_fence_intr_on_checkstop : 1;
+#else
+ uint64_t mr_fence_intr_on_checkstop : 1;
+ uint64_t mr_block_hmi_on_maint : 1;
+ uint64_t mr_recov_enable : 1;
+ uint64_t mr_on_nesthng : 1;
+ uint64_t mr_on_ambihng : 1;
+ uint64_t mr_on_corehng : 1;
+ uint64_t mr_hang_dis : 1;
+ uint64_t mr_attempt_gps_hr : 3;
+ uint64_t mr_hang_test_ctrl : 2;
+ uint64_t mr_one_ppc_mode : 1;
+ uint64_t mr_do_single_mode : 1;
+ uint64_t mr_single_decode : 1;
+ uint64_t mr_stop_dispatch : 1;
+ uint64_t mr_stop_prefetch : 1;
+ uint64_t mr_stop_fetch : 1;
+ uint64_t mr_fence_interrupts : 1;
+ uint64_t mr_pmon_inhibit : 1;
+ uint64_t mr_thread_in_debug_mode : 1;
+ uint64_t reserved0 : 43;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_ras_moderegn_t;
+
+
+
+typedef union pc_ras_statusn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t quiesce_status : 20;
+ uint64_t reserved20 : 1;
+ uint64_t reserved21 : 1;
+ uint64_t reserved22 : 1;
+ uint64_t other_thread_active : 1;
+ uint64_t hang_fsm : 3;
+ uint64_t reserved27 : 1;
+ uint64_t hang_hist0 : 1;
+ uint64_t hang_hist1 : 1;
+ uint64_t hang_hist2 : 1;
+ uint64_t hang_hist3 : 1;
+ uint64_t reserved32 : 1;
+ uint64_t hr_comp_cnt : 8;
+ uint64_t smt_dead_stop : 1;
+ uint64_t stop_fetch : 1;
+ uint64_t stop_dispatch : 1;
+ uint64_t stop_completion : 1;
+ uint64_t hold_decode : 1;
+ uint64_t reserved46 : 1;
+ uint64_t reserved47 : 1;
+ uint64_t thread_enabled : 1;
+ uint64_t pow_status_thread_state : 4;
+ uint64_t reserved53 : 1;
+ uint64_t maint_single_mode : 1;
+ uint64_t reserved55 : 1;
+ uint64_t reserved56 : 1;
+ uint64_t reserved57 : 7;
+#else
+ uint64_t reserved57 : 7;
+ uint64_t reserved56 : 1;
+ uint64_t reserved55 : 1;
+ uint64_t maint_single_mode : 1;
+ uint64_t reserved53 : 1;
+ uint64_t pow_status_thread_state : 4;
+ uint64_t thread_enabled : 1;
+ uint64_t reserved47 : 1;
+ uint64_t reserved46 : 1;
+ uint64_t hold_decode : 1;
+ uint64_t stop_completion : 1;
+ uint64_t stop_dispatch : 1;
+ uint64_t stop_fetch : 1;
+ uint64_t smt_dead_stop : 1;
+ uint64_t hr_comp_cnt : 8;
+ uint64_t reserved32 : 1;
+ uint64_t hang_hist3 : 1;
+ uint64_t hang_hist2 : 1;
+ uint64_t hang_hist1 : 1;
+ uint64_t hang_hist0 : 1;
+ uint64_t reserved27 : 1;
+ uint64_t hang_fsm : 3;
+ uint64_t other_thread_active : 1;
+ uint64_t reserved22 : 1;
+ uint64_t reserved21 : 1;
+ uint64_t reserved20 : 1;
+ uint64_t quiesce_status : 20;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_ras_statusn_t;
+
+
+
+typedef union pc_pow_statusn {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t thread_state : 4;
+ uint64_t thread_pow_state : 2;
+ uint64_t smt_mode : 3;
+ uint64_t hmi_intr : 1;
+ uint64_t maybe_ext_intr : 1;
+ uint64_t decr_intr : 1;
+ uint64_t maybe_debug_intr : 1;
+ uint64_t hdec_intr : 1;
+ uint64_t maybe_pmu_intr : 1;
+ uint64_t sp_attn_intr : 1;
+ uint64_t sreset_type : 3;
+ uint64_t reserved19 : 1;
+ uint64_t sreset_pending : 1;
+ uint64_t debug_fetch_stop : 1;
+ uint64_t async_pending : 1;
+ uint64_t core_pow_state : 3;
+ uint64_t reserved26 : 3;
+ uint64_t _reserved0 : 35;
+#else
+ uint64_t _reserved0 : 35;
+ uint64_t reserved26 : 3;
+ uint64_t core_pow_state : 3;
+ uint64_t async_pending : 1;
+ uint64_t debug_fetch_stop : 1;
+ uint64_t sreset_pending : 1;
+ uint64_t reserved19 : 1;
+ uint64_t sreset_type : 3;
+ uint64_t sp_attn_intr : 1;
+ uint64_t maybe_pmu_intr : 1;
+ uint64_t hdec_intr : 1;
+ uint64_t maybe_debug_intr : 1;
+ uint64_t decr_intr : 1;
+ uint64_t maybe_ext_intr : 1;
+ uint64_t hmi_intr : 1;
+ uint64_t smt_mode : 3;
+ uint64_t thread_pow_state : 2;
+ uint64_t thread_state : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pc_pow_statusn_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __PC_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/pc_register_addresses.h b/src/ssx/pgp/registers/pc_register_addresses.h
new file mode 100755
index 0000000..8b9baf2
--- /dev/null
+++ b/src/ssx/pgp/registers/pc_register_addresses.h
@@ -0,0 +1,61 @@
+#ifndef __PC_REGISTER_ADDRESSES_H__
+#define __PC_REGISTER_ADDRESSES_H__
+
+// $Id: pc_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pc_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pc_register_addresses.h
+/// \brief Symbolic addresses for the PC unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define PC_PCB_BASE 0x10010000
+#define PC_PFTH_MODEREG 0x100132a7
+#define PC_OCC_SPRC 0x100132ab
+#define PC_OCC_SPRD 0x100132ac
+#define PC_PFTH_THROT_REG 0x100132ad
+#define PC_DIRECT_CONTROLN(n) (PC_DIRECT_CONTROL0 + ((PC_DIRECT_CONTROL1 - PC_DIRECT_CONTROL0) * (n)))
+#define PC_DIRECT_CONTROL0 0x10013000
+#define PC_DIRECT_CONTROL1 0x10013010
+#define PC_DIRECT_CONTROL2 0x10013020
+#define PC_DIRECT_CONTROL3 0x10013030
+#define PC_DIRECT_CONTROL4 0x10013040
+#define PC_DIRECT_CONTROL5 0x10013050
+#define PC_DIRECT_CONTROL6 0x10013060
+#define PC_DIRECT_CONTROL7 0x10013070
+#define PC_RAS_MODEREGN(n) (PC_RAS_MODEREG0 + ((PC_RAS_MODEREG1 - PC_RAS_MODEREG0) * (n)))
+#define PC_RAS_MODEREG0 0x10013001
+#define PC_RAS_MODEREG1 0x10013011
+#define PC_RAS_MODEREG2 0x10013021
+#define PC_RAS_MODEREG3 0x10013031
+#define PC_RAS_MODEREG4 0x10013041
+#define PC_RAS_MODEREG5 0x10013051
+#define PC_RAS_MODEREG6 0x10013061
+#define PC_RAS_MODEREG7 0x10013071
+#define PC_RAS_STATUSN(n) (PC_RAS_STATUS0 + ((PC_RAS_STATUS1 - PC_RAS_STATUS0) * (n)))
+#define PC_RAS_STATUS0 0x10013002
+#define PC_RAS_STATUS1 0x10013012
+#define PC_RAS_STATUS2 0x10013022
+#define PC_RAS_STATUS3 0x10013032
+#define PC_RAS_STATUS4 0x10013042
+#define PC_RAS_STATUS5 0x10013052
+#define PC_RAS_STATUS6 0x10013062
+#define PC_RAS_STATUS7 0x10013072
+#define PC_POW_STATUSN(n) (PC_POW_STATUS0 + ((PC_POW_STATUS1 - PC_POW_STATUS0) * (n)))
+#define PC_POW_STATUS0 0x10013004
+#define PC_POW_STATUS1 0x10013014
+#define PC_POW_STATUS2 0x10013024
+#define PC_POW_STATUS3 0x10013034
+#define PC_POW_STATUS4 0x10013044
+#define PC_POW_STATUS5 0x10013054
+#define PC_POW_STATUS6 0x10013064
+#define PC_POW_STATUS7 0x10013074
+
+#endif // __PC_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/pcbs_firmware_registers.h b/src/ssx/pgp/registers/pcbs_firmware_registers.h
new file mode 100755
index 0000000..1d268a2
--- /dev/null
+++ b/src/ssx/pgp/registers/pcbs_firmware_registers.h
@@ -0,0 +1,2477 @@
+#ifndef __PCBS_FIRMWARE_REGISTERS_H__
+#define __PCBS_FIRMWARE_REGISTERS_H__
+
+// $Id: pcbs_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pcbs_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pcbs_firmware_registers.h
+/// \brief C register structs for the PCBS unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union pcbs_pmgp0_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pm_disable : 1;
+ uint64_t pmgp0_spare_bit1 : 1;
+ uint64_t tp_tc_restart_core_domain : 1;
+ uint64_t dpll_thold : 1;
+ uint64_t perv_thold : 1;
+ uint64_t cpm_cal_set_override_en : 1;
+ uint64_t cpm_cal_set_val : 1;
+ uint64_t pm_dpll_timer_ena : 1;
+ uint64_t dpll_lock_sense : 1;
+ uint64_t pmgp0_spare2 : 1;
+ uint64_t dpll_reset : 1;
+ uint64_t pmgp0_spare_bit11 : 1;
+ uint64_t dpll_testout_ctl : 8;
+ uint64_t tp_tc_cache2core_fence : 1;
+ uint64_t tp_tc_core2cache_fence : 1;
+ uint64_t tp_tc_pervasive_eco_fence : 1;
+ uint64_t chksw_hw257424_disable : 1;
+ uint64_t tp_clk_async_reset_dc : 3;
+ uint64_t tp_clkglm_sel_dc : 3;
+ uint64_t tp_clkglm_eco_sel_dc : 1;
+ uint64_t special_wkup_done : 1;
+ uint64_t tp_clkglm_core_sel_dc : 2;
+ uint64_t tp_clkglm_const_dc : 1;
+ uint64_t thold_timer_sel : 2;
+ uint64_t block_all_wakeup_sources : 1;
+ uint64_t tp_tc_dpll_testmode_dc : 1;
+ uint64_t pm_slv_winkle_fence : 1;
+ uint64_t l3_enable_switch : 1;
+ uint64_t tp_cplt_ivrm_refbypass_dc : 1;
+ uint64_t chksw_hw241939_disable : 1;
+ uint64_t chksw_hw273115_disable : 1;
+ uint64_t chksw_hw245103_disable : 1;
+ uint64_t chksw_hw257534_disable : 1;
+ uint64_t chksw_hw259509_enable : 1;
+ uint64_t pmgp0_spare3 : 1;
+ uint64_t wakeup_int_type : 2;
+ uint64_t dpll_lock : 1;
+ uint64_t special_wkup_all_sources_ored : 1;
+ uint64_t regular_wkup_available : 1;
+ uint64_t block_reg_wkup_sources : 1;
+ uint64_t _reserved0 : 10;
+#else
+ uint64_t _reserved0 : 10;
+ uint64_t block_reg_wkup_sources : 1;
+ uint64_t regular_wkup_available : 1;
+ uint64_t special_wkup_all_sources_ored : 1;
+ uint64_t dpll_lock : 1;
+ uint64_t wakeup_int_type : 2;
+ uint64_t pmgp0_spare3 : 1;
+ uint64_t chksw_hw259509_enable : 1;
+ uint64_t chksw_hw257534_disable : 1;
+ uint64_t chksw_hw245103_disable : 1;
+ uint64_t chksw_hw273115_disable : 1;
+ uint64_t chksw_hw241939_disable : 1;
+ uint64_t tp_cplt_ivrm_refbypass_dc : 1;
+ uint64_t l3_enable_switch : 1;
+ uint64_t pm_slv_winkle_fence : 1;
+ uint64_t tp_tc_dpll_testmode_dc : 1;
+ uint64_t block_all_wakeup_sources : 1;
+ uint64_t thold_timer_sel : 2;
+ uint64_t tp_clkglm_const_dc : 1;
+ uint64_t tp_clkglm_core_sel_dc : 2;
+ uint64_t special_wkup_done : 1;
+ uint64_t tp_clkglm_eco_sel_dc : 1;
+ uint64_t tp_clkglm_sel_dc : 3;
+ uint64_t tp_clk_async_reset_dc : 3;
+ uint64_t chksw_hw257424_disable : 1;
+ uint64_t tp_tc_pervasive_eco_fence : 1;
+ uint64_t tp_tc_core2cache_fence : 1;
+ uint64_t tp_tc_cache2core_fence : 1;
+ uint64_t dpll_testout_ctl : 8;
+ uint64_t pmgp0_spare_bit11 : 1;
+ uint64_t dpll_reset : 1;
+ uint64_t pmgp0_spare2 : 1;
+ uint64_t dpll_lock_sense : 1;
+ uint64_t pm_dpll_timer_ena : 1;
+ uint64_t cpm_cal_set_val : 1;
+ uint64_t cpm_cal_set_override_en : 1;
+ uint64_t perv_thold : 1;
+ uint64_t dpll_thold : 1;
+ uint64_t tp_tc_restart_core_domain : 1;
+ uint64_t pmgp0_spare_bit1 : 1;
+ uint64_t pm_disable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmgp0_reg_t;
+
+
+
+typedef union pcbs_pmgp0_reg_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pm_disable : 1;
+ uint64_t pmgp0_spare_bit1 : 1;
+ uint64_t tp_tc_restart_core_domain : 1;
+ uint64_t dpll_thold : 1;
+ uint64_t perv_thold : 1;
+ uint64_t cpm_cal_set_override_en : 1;
+ uint64_t cpm_cal_set_val : 1;
+ uint64_t pm_dpll_timer_ena : 1;
+ uint64_t dpll_lock_sense : 1;
+ uint64_t pmgp0_spare2 : 1;
+ uint64_t dpll_reset : 1;
+ uint64_t pmgp0_spare_bit11 : 1;
+ uint64_t dpll_testout_ctl : 8;
+ uint64_t tp_tc_cache2core_fence : 1;
+ uint64_t tp_tc_core2cache_fence : 1;
+ uint64_t tp_tc_pervasive_eco_fence : 1;
+ uint64_t chksw_hw257424_disable : 1;
+ uint64_t tp_clk_async_reset_dc : 3;
+ uint64_t tp_clkglm_sel_dc : 3;
+ uint64_t tp_clkglm_eco_sel_dc : 1;
+ uint64_t special_wkup_done : 1;
+ uint64_t tp_clkglm_core_sel_dc : 2;
+ uint64_t tp_clkglm_const_dc : 1;
+ uint64_t thold_timer_sel : 2;
+ uint64_t block_all_wakeup_sources : 1;
+ uint64_t tp_tc_dpll_testmode_dc : 1;
+ uint64_t pm_slv_winkle_fence : 1;
+ uint64_t l3_enable_switch : 1;
+ uint64_t tp_cplt_ivrm_refbypass_dc : 1;
+ uint64_t chksw_hw241939_disable : 1;
+ uint64_t chksw_hw273115_disable : 1;
+ uint64_t chksw_hw245103_disable : 1;
+ uint64_t chksw_hw257534_disable : 1;
+ uint64_t chksw_hw259509_enable : 1;
+ uint64_t pmgp0_spare3 : 1;
+ uint64_t wakeup_int_type : 2;
+ uint64_t dpll_lock : 1;
+ uint64_t special_wkup_all_sources_ored : 1;
+ uint64_t regular_wkup_available : 1;
+ uint64_t block_reg_wkup_sources : 1;
+ uint64_t _reserved0 : 10;
+#else
+ uint64_t _reserved0 : 10;
+ uint64_t block_reg_wkup_sources : 1;
+ uint64_t regular_wkup_available : 1;
+ uint64_t special_wkup_all_sources_ored : 1;
+ uint64_t dpll_lock : 1;
+ uint64_t wakeup_int_type : 2;
+ uint64_t pmgp0_spare3 : 1;
+ uint64_t chksw_hw259509_enable : 1;
+ uint64_t chksw_hw257534_disable : 1;
+ uint64_t chksw_hw245103_disable : 1;
+ uint64_t chksw_hw273115_disable : 1;
+ uint64_t chksw_hw241939_disable : 1;
+ uint64_t tp_cplt_ivrm_refbypass_dc : 1;
+ uint64_t l3_enable_switch : 1;
+ uint64_t pm_slv_winkle_fence : 1;
+ uint64_t tp_tc_dpll_testmode_dc : 1;
+ uint64_t block_all_wakeup_sources : 1;
+ uint64_t thold_timer_sel : 2;
+ uint64_t tp_clkglm_const_dc : 1;
+ uint64_t tp_clkglm_core_sel_dc : 2;
+ uint64_t special_wkup_done : 1;
+ uint64_t tp_clkglm_eco_sel_dc : 1;
+ uint64_t tp_clkglm_sel_dc : 3;
+ uint64_t tp_clk_async_reset_dc : 3;
+ uint64_t chksw_hw257424_disable : 1;
+ uint64_t tp_tc_pervasive_eco_fence : 1;
+ uint64_t tp_tc_core2cache_fence : 1;
+ uint64_t tp_tc_cache2core_fence : 1;
+ uint64_t dpll_testout_ctl : 8;
+ uint64_t pmgp0_spare_bit11 : 1;
+ uint64_t dpll_reset : 1;
+ uint64_t pmgp0_spare2 : 1;
+ uint64_t dpll_lock_sense : 1;
+ uint64_t pm_dpll_timer_ena : 1;
+ uint64_t cpm_cal_set_val : 1;
+ uint64_t cpm_cal_set_override_en : 1;
+ uint64_t perv_thold : 1;
+ uint64_t dpll_thold : 1;
+ uint64_t tp_tc_restart_core_domain : 1;
+ uint64_t pmgp0_spare_bit1 : 1;
+ uint64_t pm_disable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmgp0_reg_and_t;
+
+
+
+typedef union pcbs_pmgp0_reg_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pm_disable : 1;
+ uint64_t pmgp0_spare_bit1 : 1;
+ uint64_t tp_tc_restart_core_domain : 1;
+ uint64_t dpll_thold : 1;
+ uint64_t perv_thold : 1;
+ uint64_t cpm_cal_set_override_en : 1;
+ uint64_t cpm_cal_set_val : 1;
+ uint64_t pm_dpll_timer_ena : 1;
+ uint64_t dpll_lock_sense : 1;
+ uint64_t pmgp0_spare2 : 1;
+ uint64_t dpll_reset : 1;
+ uint64_t pmgp0_spare_bit11 : 1;
+ uint64_t dpll_testout_ctl : 8;
+ uint64_t tp_tc_cache2core_fence : 1;
+ uint64_t tp_tc_core2cache_fence : 1;
+ uint64_t tp_tc_pervasive_eco_fence : 1;
+ uint64_t chksw_hw257424_disable : 1;
+ uint64_t tp_clk_async_reset_dc : 3;
+ uint64_t tp_clkglm_sel_dc : 3;
+ uint64_t tp_clkglm_eco_sel_dc : 1;
+ uint64_t special_wkup_done : 1;
+ uint64_t tp_clkglm_core_sel_dc : 2;
+ uint64_t tp_clkglm_const_dc : 1;
+ uint64_t thold_timer_sel : 2;
+ uint64_t block_all_wakeup_sources : 1;
+ uint64_t tp_tc_dpll_testmode_dc : 1;
+ uint64_t pm_slv_winkle_fence : 1;
+ uint64_t l3_enable_switch : 1;
+ uint64_t tp_cplt_ivrm_refbypass_dc : 1;
+ uint64_t chksw_hw241939_disable : 1;
+ uint64_t chksw_hw273115_disable : 1;
+ uint64_t chksw_hw245103_disable : 1;
+ uint64_t chksw_hw257534_disable : 1;
+ uint64_t chksw_hw259509_enable : 1;
+ uint64_t pmgp0_spare3 : 1;
+ uint64_t wakeup_int_type : 2;
+ uint64_t dpll_lock : 1;
+ uint64_t special_wkup_all_sources_ored : 1;
+ uint64_t regular_wkup_available : 1;
+ uint64_t block_reg_wkup_sources : 1;
+ uint64_t _reserved0 : 10;
+#else
+ uint64_t _reserved0 : 10;
+ uint64_t block_reg_wkup_sources : 1;
+ uint64_t regular_wkup_available : 1;
+ uint64_t special_wkup_all_sources_ored : 1;
+ uint64_t dpll_lock : 1;
+ uint64_t wakeup_int_type : 2;
+ uint64_t pmgp0_spare3 : 1;
+ uint64_t chksw_hw259509_enable : 1;
+ uint64_t chksw_hw257534_disable : 1;
+ uint64_t chksw_hw245103_disable : 1;
+ uint64_t chksw_hw273115_disable : 1;
+ uint64_t chksw_hw241939_disable : 1;
+ uint64_t tp_cplt_ivrm_refbypass_dc : 1;
+ uint64_t l3_enable_switch : 1;
+ uint64_t pm_slv_winkle_fence : 1;
+ uint64_t tp_tc_dpll_testmode_dc : 1;
+ uint64_t block_all_wakeup_sources : 1;
+ uint64_t thold_timer_sel : 2;
+ uint64_t tp_clkglm_const_dc : 1;
+ uint64_t tp_clkglm_core_sel_dc : 2;
+ uint64_t special_wkup_done : 1;
+ uint64_t tp_clkglm_eco_sel_dc : 1;
+ uint64_t tp_clkglm_sel_dc : 3;
+ uint64_t tp_clk_async_reset_dc : 3;
+ uint64_t chksw_hw257424_disable : 1;
+ uint64_t tp_tc_pervasive_eco_fence : 1;
+ uint64_t tp_tc_core2cache_fence : 1;
+ uint64_t tp_tc_cache2core_fence : 1;
+ uint64_t dpll_testout_ctl : 8;
+ uint64_t pmgp0_spare_bit11 : 1;
+ uint64_t dpll_reset : 1;
+ uint64_t pmgp0_spare2 : 1;
+ uint64_t dpll_lock_sense : 1;
+ uint64_t pm_dpll_timer_ena : 1;
+ uint64_t cpm_cal_set_val : 1;
+ uint64_t cpm_cal_set_override_en : 1;
+ uint64_t perv_thold : 1;
+ uint64_t dpll_thold : 1;
+ uint64_t tp_tc_restart_core_domain : 1;
+ uint64_t pmgp0_spare_bit1 : 1;
+ uint64_t pm_disable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmgp0_reg_or_t;
+
+
+
+typedef union pcbs_pmgp1_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t sleep_power_down_en : 1;
+ uint64_t sleep_power_up_en : 1;
+ uint64_t sleep_power_off_sel : 1;
+ uint64_t winkle_power_down_en : 1;
+ uint64_t winkle_power_up_en : 1;
+ uint64_t winkle_power_off_sel : 1;
+ uint64_t oha_wkup_override_en : 1;
+ uint64_t oha_pm_wkup_override : 1;
+ uint64_t oha_spc_wkup_override : 1;
+ uint64_t endp_reset_pm_only : 1;
+ uint64_t dpll_freq_override_enable : 1;
+ uint64_t pm_spr_override_en : 1;
+ uint64_t force_safe_mode : 1;
+ uint64_t ivrm_safe_mode_en : 1;
+ uint64_t ivrm_safe_mode_force_active : 1;
+ uint64_t pmicr_latency_en : 1;
+ uint64_t enable_occ_ctrl_for_local_pstate_eff_req : 1;
+ uint64_t serialize_pfet_powerdown : 1;
+ uint64_t serialize_pfet_powerup : 1;
+ uint64_t disable_force_deep_to_fast_sleep : 1;
+ uint64_t disable_force_deep_to_fast_winkle : 1;
+ uint64_t _reserved0 : 43;
+#else
+ uint64_t _reserved0 : 43;
+ uint64_t disable_force_deep_to_fast_winkle : 1;
+ uint64_t disable_force_deep_to_fast_sleep : 1;
+ uint64_t serialize_pfet_powerup : 1;
+ uint64_t serialize_pfet_powerdown : 1;
+ uint64_t enable_occ_ctrl_for_local_pstate_eff_req : 1;
+ uint64_t pmicr_latency_en : 1;
+ uint64_t ivrm_safe_mode_force_active : 1;
+ uint64_t ivrm_safe_mode_en : 1;
+ uint64_t force_safe_mode : 1;
+ uint64_t pm_spr_override_en : 1;
+ uint64_t dpll_freq_override_enable : 1;
+ uint64_t endp_reset_pm_only : 1;
+ uint64_t oha_spc_wkup_override : 1;
+ uint64_t oha_pm_wkup_override : 1;
+ uint64_t oha_wkup_override_en : 1;
+ uint64_t winkle_power_off_sel : 1;
+ uint64_t winkle_power_up_en : 1;
+ uint64_t winkle_power_down_en : 1;
+ uint64_t sleep_power_off_sel : 1;
+ uint64_t sleep_power_up_en : 1;
+ uint64_t sleep_power_down_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmgp1_reg_t;
+
+
+
+typedef union pcbs_pmgp1_reg_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t sleep_power_down_en : 1;
+ uint64_t sleep_power_up_en : 1;
+ uint64_t sleep_power_off_sel : 1;
+ uint64_t winkle_power_down_en : 1;
+ uint64_t winkle_power_up_en : 1;
+ uint64_t winkle_power_off_sel : 1;
+ uint64_t oha_wkup_override_en : 1;
+ uint64_t oha_pm_wkup_override : 1;
+ uint64_t oha_spc_wkup_override : 1;
+ uint64_t endp_reset_pm_only : 1;
+ uint64_t dpll_freq_override_enable : 1;
+ uint64_t pm_spr_override_en : 1;
+ uint64_t force_safe_mode : 1;
+ uint64_t ivrm_safe_mode_en : 1;
+ uint64_t ivrm_safe_mode_force_active : 1;
+ uint64_t pmicr_latency_en : 1;
+ uint64_t enable_occ_ctrl_for_local_pstate_eff_req : 1;
+ uint64_t serialize_pfet_powerdown : 1;
+ uint64_t serialize_pfet_powerup : 1;
+ uint64_t disable_force_deep_to_fast_sleep : 1;
+ uint64_t disable_force_deep_to_fast_winkle : 1;
+ uint64_t _reserved0 : 43;
+#else
+ uint64_t _reserved0 : 43;
+ uint64_t disable_force_deep_to_fast_winkle : 1;
+ uint64_t disable_force_deep_to_fast_sleep : 1;
+ uint64_t serialize_pfet_powerup : 1;
+ uint64_t serialize_pfet_powerdown : 1;
+ uint64_t enable_occ_ctrl_for_local_pstate_eff_req : 1;
+ uint64_t pmicr_latency_en : 1;
+ uint64_t ivrm_safe_mode_force_active : 1;
+ uint64_t ivrm_safe_mode_en : 1;
+ uint64_t force_safe_mode : 1;
+ uint64_t pm_spr_override_en : 1;
+ uint64_t dpll_freq_override_enable : 1;
+ uint64_t endp_reset_pm_only : 1;
+ uint64_t oha_spc_wkup_override : 1;
+ uint64_t oha_pm_wkup_override : 1;
+ uint64_t oha_wkup_override_en : 1;
+ uint64_t winkle_power_off_sel : 1;
+ uint64_t winkle_power_up_en : 1;
+ uint64_t winkle_power_down_en : 1;
+ uint64_t sleep_power_off_sel : 1;
+ uint64_t sleep_power_up_en : 1;
+ uint64_t sleep_power_down_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmgp1_reg_and_t;
+
+
+
+typedef union pcbs_pmgp1_reg_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t sleep_power_down_en : 1;
+ uint64_t sleep_power_up_en : 1;
+ uint64_t sleep_power_off_sel : 1;
+ uint64_t winkle_power_down_en : 1;
+ uint64_t winkle_power_up_en : 1;
+ uint64_t winkle_power_off_sel : 1;
+ uint64_t oha_wkup_override_en : 1;
+ uint64_t oha_pm_wkup_override : 1;
+ uint64_t oha_spc_wkup_override : 1;
+ uint64_t endp_reset_pm_only : 1;
+ uint64_t dpll_freq_override_enable : 1;
+ uint64_t pm_spr_override_en : 1;
+ uint64_t force_safe_mode : 1;
+ uint64_t ivrm_safe_mode_en : 1;
+ uint64_t ivrm_safe_mode_force_active : 1;
+ uint64_t pmicr_latency_en : 1;
+ uint64_t enable_occ_ctrl_for_local_pstate_eff_req : 1;
+ uint64_t serialize_pfet_powerdown : 1;
+ uint64_t serialize_pfet_powerup : 1;
+ uint64_t disable_force_deep_to_fast_sleep : 1;
+ uint64_t disable_force_deep_to_fast_winkle : 1;
+ uint64_t _reserved0 : 43;
+#else
+ uint64_t _reserved0 : 43;
+ uint64_t disable_force_deep_to_fast_winkle : 1;
+ uint64_t disable_force_deep_to_fast_sleep : 1;
+ uint64_t serialize_pfet_powerup : 1;
+ uint64_t serialize_pfet_powerdown : 1;
+ uint64_t enable_occ_ctrl_for_local_pstate_eff_req : 1;
+ uint64_t pmicr_latency_en : 1;
+ uint64_t ivrm_safe_mode_force_active : 1;
+ uint64_t ivrm_safe_mode_en : 1;
+ uint64_t force_safe_mode : 1;
+ uint64_t pm_spr_override_en : 1;
+ uint64_t dpll_freq_override_enable : 1;
+ uint64_t endp_reset_pm_only : 1;
+ uint64_t oha_spc_wkup_override : 1;
+ uint64_t oha_pm_wkup_override : 1;
+ uint64_t oha_wkup_override_en : 1;
+ uint64_t winkle_power_off_sel : 1;
+ uint64_t winkle_power_up_en : 1;
+ uint64_t winkle_power_down_en : 1;
+ uint64_t sleep_power_off_sel : 1;
+ uint64_t sleep_power_up_en : 1;
+ uint64_t sleep_power_down_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmgp1_reg_or_t;
+
+
+
+typedef union pcbs_pfvddcntlstat_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_vdd_pfet_force_state : 2;
+ uint64_t eco_vdd_pfet_force_state : 2;
+ uint64_t core_vdd_pfet_val_override : 1;
+ uint64_t core_vdd_pfet_sel_override : 1;
+ uint64_t eco_vdd_pfet_val_override : 1;
+ uint64_t eco_vdd_pfet_sel_override : 1;
+ uint64_t core_vdd_pfet_enable_regulation_finger : 1;
+ uint64_t eco_vdd_pfet_enable_regulation_finger : 1;
+ uint64_t core_vdd_pfet_enable_value : 12;
+ uint64_t core_vdd_pfet_sel_value : 4;
+ uint64_t eco_vdd_pfet_enable_value : 12;
+ uint64_t eco_vdd_pfet_sel_value : 4;
+ uint64_t core_vdd_pg_state : 4;
+ uint64_t core_vdd_pg_sel : 4;
+ uint64_t eco_vdd_pg_state : 4;
+ uint64_t eco_vdd_pg_sel : 4;
+ uint64_t _reserved0 : 6;
+#else
+ uint64_t _reserved0 : 6;
+ uint64_t eco_vdd_pg_sel : 4;
+ uint64_t eco_vdd_pg_state : 4;
+ uint64_t core_vdd_pg_sel : 4;
+ uint64_t core_vdd_pg_state : 4;
+ uint64_t eco_vdd_pfet_sel_value : 4;
+ uint64_t eco_vdd_pfet_enable_value : 12;
+ uint64_t core_vdd_pfet_sel_value : 4;
+ uint64_t core_vdd_pfet_enable_value : 12;
+ uint64_t eco_vdd_pfet_enable_regulation_finger : 1;
+ uint64_t core_vdd_pfet_enable_regulation_finger : 1;
+ uint64_t eco_vdd_pfet_sel_override : 1;
+ uint64_t eco_vdd_pfet_val_override : 1;
+ uint64_t core_vdd_pfet_sel_override : 1;
+ uint64_t core_vdd_pfet_val_override : 1;
+ uint64_t eco_vdd_pfet_force_state : 2;
+ uint64_t core_vdd_pfet_force_state : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pfvddcntlstat_reg_t;
+
+
+
+typedef union pcbs_pfvcscntlstat_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_vcs_pfet_force_state : 2;
+ uint64_t eco_vcs_pfet_force_state : 2;
+ uint64_t core_vcs_pfet_val_override : 1;
+ uint64_t core_vcs_pfet_sel_override : 1;
+ uint64_t eco_vcs_pfet_val_override : 1;
+ uint64_t eco_vcs_pfet_sel_override : 1;
+ uint64_t core_vcs_pfet_enable_regulation_finger : 1;
+ uint64_t eco_vcs_pfet_enable_regulation_finger : 1;
+ uint64_t core_vcs_pfet_enable_value : 12;
+ uint64_t core_vcs_pfet_sel_value : 4;
+ uint64_t eco_vcs_pfet_enable_value : 12;
+ uint64_t eco_vcs_pfet_sel_value : 4;
+ uint64_t core_vcs_pg_state : 4;
+ uint64_t core_vcs_pg_sel : 4;
+ uint64_t eco_vcs_pg_state : 4;
+ uint64_t eco_vcs_pg_sel : 4;
+ uint64_t _reserved0 : 6;
+#else
+ uint64_t _reserved0 : 6;
+ uint64_t eco_vcs_pg_sel : 4;
+ uint64_t eco_vcs_pg_state : 4;
+ uint64_t core_vcs_pg_sel : 4;
+ uint64_t core_vcs_pg_state : 4;
+ uint64_t eco_vcs_pfet_sel_value : 4;
+ uint64_t eco_vcs_pfet_enable_value : 12;
+ uint64_t core_vcs_pfet_sel_value : 4;
+ uint64_t core_vcs_pfet_enable_value : 12;
+ uint64_t eco_vcs_pfet_enable_regulation_finger : 1;
+ uint64_t core_vcs_pfet_enable_regulation_finger : 1;
+ uint64_t eco_vcs_pfet_sel_override : 1;
+ uint64_t eco_vcs_pfet_val_override : 1;
+ uint64_t core_vcs_pfet_sel_override : 1;
+ uint64_t core_vcs_pfet_val_override : 1;
+ uint64_t eco_vcs_pfet_force_state : 2;
+ uint64_t core_vcs_pfet_force_state : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pfvcscntlstat_reg_t;
+
+
+
+typedef union pcbs_pfsense_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t tp_core_vdd_pfet_enable_sense : 12;
+ uint64_t tp_eco_vdd_pfet_enable_sense : 12;
+ uint64_t tp_core_vcs_pfet_enable_sense : 12;
+ uint64_t tp_eco_vcs_pfet_enable_sense : 12;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t tp_eco_vcs_pfet_enable_sense : 12;
+ uint64_t tp_core_vcs_pfet_enable_sense : 12;
+ uint64_t tp_eco_vdd_pfet_enable_sense : 12;
+ uint64_t tp_core_vdd_pfet_enable_sense : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pfsense_reg_t;
+
+
+
+typedef union pcbs_pmerrsum_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pm_error : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t pm_error : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmerrsum_reg_t;
+
+
+
+typedef union pcbs_pmerr_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pcbs_sleep_entry_notify_pmc_hang_err : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_assist_hang_err : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_err : 1;
+ uint64_t pcbs_sleep_exit_invoke_pore_err : 1;
+ uint64_t pcbs_winkle_entry_notify_pmc_err : 1;
+ uint64_t pcbs_winkle_entry_send_int_assist_err : 1;
+ uint64_t pcbs_winkle_exit_notify_pmc_err : 1;
+ uint64_t pcbs_wait_dpll_lock_err : 1;
+ uint64_t pcbs_spare8_err : 1;
+ uint64_t pcbs_winkle_exit_send_int_assist_err : 1;
+ uint64_t pcbs_winkle_exit_send_int_powup_assist_err : 1;
+ uint64_t pcbs_write_fsm_goto_reg_in_invalid_state_err : 1;
+ uint64_t pcbs_write_pmgp0_in_invalid_state_err : 1;
+ uint64_t pcbs_freq_overflow_in_pstate_mode_err : 1;
+ uint64_t pcbs_eco_rs_bypass_confusion_err : 1;
+ uint64_t pcbs_core_rs_bypass_confusion_err : 1;
+ uint64_t pcbs_read_lpst_in_pstate_mode_err : 1;
+ uint64_t pcbs_lpst_read_corr_err : 1;
+ uint64_t pcbs_lpst_read_uncorr_err : 1;
+ uint64_t pcbs_pfet_strength_overflow_err : 1;
+ uint64_t pcbs_vds_lookup_err : 1;
+ uint64_t pcbs_idle_interrupt_timeout_err : 1;
+ uint64_t pcbs_pstate_interrupt_timeout_err : 1;
+ uint64_t pcbs_global_actual_sync_interrupt_timeout_err : 1;
+ uint64_t pcbs_pmax_sync_interrupt_timeout_err : 1;
+ uint64_t pcbs_global_actual_pstate_protocol_err : 1;
+ uint64_t pcbs_pmax_protocol_err : 1;
+ uint64_t pcbs_ivrm_gross_or_fine_err : 1;
+ uint64_t pcbs_ivrm_range_err : 1;
+ uint64_t pcbs_dpll_cpm_fmin_err : 1;
+ uint64_t pcbs_dpll_dco_full_err : 1;
+ uint64_t pcbs_dpll_dco_empty_err : 1;
+ uint64_t pcbs_dpll_int_err : 1;
+ uint64_t pcbs_fmin_and_not_cpmbit_err : 1;
+ uint64_t pcbs_dpll_faster_than_fmax_plus_delta1_err : 1;
+ uint64_t pcbs_dpll_slower_than_fmin_minus_delta2_err : 1;
+ uint64_t pcbs_resclk_csb_instr_vector_chg_in_invalid_state_err : 1;
+ uint64_t pcbs_reslkc_band_boundary_chg_in_invalid_state_err : 1;
+ uint64_t pcbs_occ_heartbeat_loss_err : 1;
+ uint64_t pcbs_spare39_err : 1;
+ uint64_t pcbs_spare40_err : 1;
+ uint64_t pcbs_spare41_err : 1;
+ uint64_t pcbs_spare42_err : 1;
+ uint64_t _reserved0 : 21;
+#else
+ uint64_t _reserved0 : 21;
+ uint64_t pcbs_spare42_err : 1;
+ uint64_t pcbs_spare41_err : 1;
+ uint64_t pcbs_spare40_err : 1;
+ uint64_t pcbs_spare39_err : 1;
+ uint64_t pcbs_occ_heartbeat_loss_err : 1;
+ uint64_t pcbs_reslkc_band_boundary_chg_in_invalid_state_err : 1;
+ uint64_t pcbs_resclk_csb_instr_vector_chg_in_invalid_state_err : 1;
+ uint64_t pcbs_dpll_slower_than_fmin_minus_delta2_err : 1;
+ uint64_t pcbs_dpll_faster_than_fmax_plus_delta1_err : 1;
+ uint64_t pcbs_fmin_and_not_cpmbit_err : 1;
+ uint64_t pcbs_dpll_int_err : 1;
+ uint64_t pcbs_dpll_dco_empty_err : 1;
+ uint64_t pcbs_dpll_dco_full_err : 1;
+ uint64_t pcbs_dpll_cpm_fmin_err : 1;
+ uint64_t pcbs_ivrm_range_err : 1;
+ uint64_t pcbs_ivrm_gross_or_fine_err : 1;
+ uint64_t pcbs_pmax_protocol_err : 1;
+ uint64_t pcbs_global_actual_pstate_protocol_err : 1;
+ uint64_t pcbs_pmax_sync_interrupt_timeout_err : 1;
+ uint64_t pcbs_global_actual_sync_interrupt_timeout_err : 1;
+ uint64_t pcbs_pstate_interrupt_timeout_err : 1;
+ uint64_t pcbs_idle_interrupt_timeout_err : 1;
+ uint64_t pcbs_vds_lookup_err : 1;
+ uint64_t pcbs_pfet_strength_overflow_err : 1;
+ uint64_t pcbs_lpst_read_uncorr_err : 1;
+ uint64_t pcbs_lpst_read_corr_err : 1;
+ uint64_t pcbs_read_lpst_in_pstate_mode_err : 1;
+ uint64_t pcbs_core_rs_bypass_confusion_err : 1;
+ uint64_t pcbs_eco_rs_bypass_confusion_err : 1;
+ uint64_t pcbs_freq_overflow_in_pstate_mode_err : 1;
+ uint64_t pcbs_write_pmgp0_in_invalid_state_err : 1;
+ uint64_t pcbs_write_fsm_goto_reg_in_invalid_state_err : 1;
+ uint64_t pcbs_winkle_exit_send_int_powup_assist_err : 1;
+ uint64_t pcbs_winkle_exit_send_int_assist_err : 1;
+ uint64_t pcbs_spare8_err : 1;
+ uint64_t pcbs_wait_dpll_lock_err : 1;
+ uint64_t pcbs_winkle_exit_notify_pmc_err : 1;
+ uint64_t pcbs_winkle_entry_send_int_assist_err : 1;
+ uint64_t pcbs_winkle_entry_notify_pmc_err : 1;
+ uint64_t pcbs_sleep_exit_invoke_pore_err : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_err : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_assist_hang_err : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_hang_err : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmerr_reg_t;
+
+
+
+typedef union pcbs_pmerrmask_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pcbs_sleep_entry_notify_pmc_hang_err_mask : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_assist_hang_err_mask : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_err_mask : 1;
+ uint64_t pcbs_sleep_exit_invoke_pore_err_mask : 1;
+ uint64_t pcbs_winkle_entry_notify_pmc_err_mask : 1;
+ uint64_t pcbs_winkle_entry_send_int_assist_err_mask : 1;
+ uint64_t pcbs_winkle_exit_notify_pmc_err_mask : 1;
+ uint64_t pcbs_wait_dpll_lock_err_mask : 1;
+ uint64_t pcbs_spare8_err_mask : 1;
+ uint64_t pcbs_winkle_exit_send_int_assist_err_mask : 1;
+ uint64_t pcbs_winkle_exit_send_int_powup_assist_err_mask : 1;
+ uint64_t pcbs_write_fsm_goto_reg_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_write_pmgp0_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_freq_overflow_in_pstate_mode_err_mask : 1;
+ uint64_t pcbs_eco_rs_bypass_confusion_err_mask : 1;
+ uint64_t pcbs_core_rs_bypass_confusion_err_mask : 1;
+ uint64_t pcbs_read_lpst_in_pstate_mode_err_mask : 1;
+ uint64_t pcbs_lpst_read_corr_err_mask : 1;
+ uint64_t pcbs_lpst_read_uncorr_err_mask : 1;
+ uint64_t pcbs_pfet_strength_overflow_err_mask : 1;
+ uint64_t pcbs_vds_lookup_err_mask : 1;
+ uint64_t pcbs_idle_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_pstate_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_global_actual_sync_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_pmax_sync_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_global_actual_pstate_protocol_err_mask : 1;
+ uint64_t pcbs_pmax_protocol_err_mask : 1;
+ uint64_t pcbs_ivrm_gross_or_fine_err_mask : 1;
+ uint64_t pcbs_ivrm_range_err_mask : 1;
+ uint64_t pcbs_dpll_cpm_fmin_err_mask : 1;
+ uint64_t pcbs_dpll_dco_full_err_mask : 1;
+ uint64_t pcbs_dpll_dco_empty_err_mask : 1;
+ uint64_t pcbs_dpll_int_err_mask : 1;
+ uint64_t pcbs_fmin_and_not_cpmbit_err_mask : 1;
+ uint64_t pcbs_dpll_faster_than_fmax_plus_delta1_err_mask : 1;
+ uint64_t pcbs_dpll_slower_than_fmin_minus_delta2_err_mask : 1;
+ uint64_t pcbs_resclk_csb_instr_vector_chg_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_reslkc_band_boundary_chg_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_occ_heartbeat_loss_err_mask : 1;
+ uint64_t pcbs_spare39_err_mask : 1;
+ uint64_t pcbs_spare40_err_mask : 1;
+ uint64_t pcbs_spare41_err_mask : 1;
+ uint64_t pcbs_spare42_err_mask : 1;
+ uint64_t _reserved0 : 21;
+#else
+ uint64_t _reserved0 : 21;
+ uint64_t pcbs_spare42_err_mask : 1;
+ uint64_t pcbs_spare41_err_mask : 1;
+ uint64_t pcbs_spare40_err_mask : 1;
+ uint64_t pcbs_spare39_err_mask : 1;
+ uint64_t pcbs_occ_heartbeat_loss_err_mask : 1;
+ uint64_t pcbs_reslkc_band_boundary_chg_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_resclk_csb_instr_vector_chg_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_dpll_slower_than_fmin_minus_delta2_err_mask : 1;
+ uint64_t pcbs_dpll_faster_than_fmax_plus_delta1_err_mask : 1;
+ uint64_t pcbs_fmin_and_not_cpmbit_err_mask : 1;
+ uint64_t pcbs_dpll_int_err_mask : 1;
+ uint64_t pcbs_dpll_dco_empty_err_mask : 1;
+ uint64_t pcbs_dpll_dco_full_err_mask : 1;
+ uint64_t pcbs_dpll_cpm_fmin_err_mask : 1;
+ uint64_t pcbs_ivrm_range_err_mask : 1;
+ uint64_t pcbs_ivrm_gross_or_fine_err_mask : 1;
+ uint64_t pcbs_pmax_protocol_err_mask : 1;
+ uint64_t pcbs_global_actual_pstate_protocol_err_mask : 1;
+ uint64_t pcbs_pmax_sync_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_global_actual_sync_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_pstate_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_idle_interrupt_timeout_err_mask : 1;
+ uint64_t pcbs_vds_lookup_err_mask : 1;
+ uint64_t pcbs_pfet_strength_overflow_err_mask : 1;
+ uint64_t pcbs_lpst_read_uncorr_err_mask : 1;
+ uint64_t pcbs_lpst_read_corr_err_mask : 1;
+ uint64_t pcbs_read_lpst_in_pstate_mode_err_mask : 1;
+ uint64_t pcbs_core_rs_bypass_confusion_err_mask : 1;
+ uint64_t pcbs_eco_rs_bypass_confusion_err_mask : 1;
+ uint64_t pcbs_freq_overflow_in_pstate_mode_err_mask : 1;
+ uint64_t pcbs_write_pmgp0_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_write_fsm_goto_reg_in_invalid_state_err_mask : 1;
+ uint64_t pcbs_winkle_exit_send_int_powup_assist_err_mask : 1;
+ uint64_t pcbs_winkle_exit_send_int_assist_err_mask : 1;
+ uint64_t pcbs_spare8_err_mask : 1;
+ uint64_t pcbs_wait_dpll_lock_err_mask : 1;
+ uint64_t pcbs_winkle_exit_notify_pmc_err_mask : 1;
+ uint64_t pcbs_winkle_entry_send_int_assist_err_mask : 1;
+ uint64_t pcbs_winkle_entry_notify_pmc_err_mask : 1;
+ uint64_t pcbs_sleep_exit_invoke_pore_err_mask : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_err_mask : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_assist_hang_err_mask : 1;
+ uint64_t pcbs_sleep_entry_notify_pmc_hang_err_mask : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmerrmask_reg_t;
+
+
+
+typedef union pcbs_pmspcwkupfsp_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t fsp_special_wakeup : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t fsp_special_wakeup : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmspcwkupfsp_reg_t;
+
+
+
+typedef union pcbs_pmspcwkupocc_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_special_wakeup : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t occ_special_wakeup : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmspcwkupocc_reg_t;
+
+
+
+typedef union pcbs_pmspcwkupphyp_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t phyp_special_wakeup : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t phyp_special_wakeup : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmspcwkupphyp_reg_t;
+
+
+
+typedef union pcbs_pmstatehistphyp_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t phyp_pm_state : 3;
+ uint64_t phyp_past_core_instruct_stop : 1;
+ uint64_t phyp_past_core_clk_stop : 1;
+ uint64_t phyp_past_core_pwr_off : 1;
+ uint64_t phyp_past_eco_clk_stop : 1;
+ uint64_t phyp_past_eco_pwr_off : 1;
+ uint64_t _reserved0 : 56;
+#else
+ uint64_t _reserved0 : 56;
+ uint64_t phyp_past_eco_pwr_off : 1;
+ uint64_t phyp_past_eco_clk_stop : 1;
+ uint64_t phyp_past_core_pwr_off : 1;
+ uint64_t phyp_past_core_clk_stop : 1;
+ uint64_t phyp_past_core_instruct_stop : 1;
+ uint64_t phyp_pm_state : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmstatehistphyp_reg_t;
+
+
+
+typedef union pcbs_pmstatehistfsp_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t fsp_pm_state : 3;
+ uint64_t fsp_past_core_instruct_stop : 1;
+ uint64_t fsp_past_core_clk_stop : 1;
+ uint64_t fsp_past_core_pwr_off : 1;
+ uint64_t fsp_past_eco_clk_stop : 1;
+ uint64_t fsp_past_eco_pwr_off : 1;
+ uint64_t _reserved0 : 56;
+#else
+ uint64_t _reserved0 : 56;
+ uint64_t fsp_past_eco_pwr_off : 1;
+ uint64_t fsp_past_eco_clk_stop : 1;
+ uint64_t fsp_past_core_pwr_off : 1;
+ uint64_t fsp_past_core_clk_stop : 1;
+ uint64_t fsp_past_core_instruct_stop : 1;
+ uint64_t fsp_pm_state : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmstatehistfsp_reg_t;
+
+
+
+typedef union pcbs_pmstatehistocc_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_pm_state : 3;
+ uint64_t occ_past_core_instruct_stop : 1;
+ uint64_t occ_past_core_clk_stop : 1;
+ uint64_t occ_past_core_pwr_off : 1;
+ uint64_t occ_past_eco_clk_stop : 1;
+ uint64_t occ_past_eco_pwr_off : 1;
+ uint64_t _reserved0 : 56;
+#else
+ uint64_t _reserved0 : 56;
+ uint64_t occ_past_eco_pwr_off : 1;
+ uint64_t occ_past_eco_clk_stop : 1;
+ uint64_t occ_past_core_pwr_off : 1;
+ uint64_t occ_past_core_clk_stop : 1;
+ uint64_t occ_past_core_instruct_stop : 1;
+ uint64_t occ_pm_state : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmstatehistocc_reg_t;
+
+
+
+typedef union pcbs_pmstatehistperf_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t perf_pm_state : 3;
+ uint64_t perf_past_core_instruct_stop : 1;
+ uint64_t perf_past_core_clk_stop : 1;
+ uint64_t perf_past_core_pwr_off : 1;
+ uint64_t perf_past_eco_clk_stop : 1;
+ uint64_t perf_past_eco_pwr_off : 1;
+ uint64_t _reserved0 : 56;
+#else
+ uint64_t _reserved0 : 56;
+ uint64_t perf_past_eco_pwr_off : 1;
+ uint64_t perf_past_eco_clk_stop : 1;
+ uint64_t perf_past_core_pwr_off : 1;
+ uint64_t perf_past_core_clk_stop : 1;
+ uint64_t perf_past_core_instruct_stop : 1;
+ uint64_t perf_pm_state : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmstatehistperf_reg_t;
+
+
+
+typedef union pcbs_idlefsmgotocmd_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t idle_fsm_goto_cmd : 2;
+ uint64_t babystp_trigger_sleep_entry : 1;
+ uint64_t babystp_trigger_winkle_entry : 1;
+ uint64_t babystp_trigger_wakeup : 1;
+ uint64_t _reserved0 : 59;
+#else
+ uint64_t _reserved0 : 59;
+ uint64_t babystp_trigger_wakeup : 1;
+ uint64_t babystp_trigger_winkle_entry : 1;
+ uint64_t babystp_trigger_sleep_entry : 1;
+ uint64_t idle_fsm_goto_cmd : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_idlefsmgotocmd_reg_t;
+
+
+
+typedef union pcbs_corepfpudly_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_powup_dly0 : 4;
+ uint64_t core_powup_dly1 : 4;
+ uint64_t core_power_up_delay_sel : 12;
+ uint64_t _reserved0 : 44;
+#else
+ uint64_t _reserved0 : 44;
+ uint64_t core_power_up_delay_sel : 12;
+ uint64_t core_powup_dly1 : 4;
+ uint64_t core_powup_dly0 : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_corepfpudly_reg_t;
+
+
+
+typedef union pcbs_corepfpddly_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_powdn_dly0 : 4;
+ uint64_t core_powdn_dly1 : 4;
+ uint64_t core_power_dn_delay_sel : 12;
+ uint64_t _reserved0 : 44;
+#else
+ uint64_t _reserved0 : 44;
+ uint64_t core_power_dn_delay_sel : 12;
+ uint64_t core_powdn_dly1 : 4;
+ uint64_t core_powdn_dly0 : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_corepfpddly_reg_t;
+
+
+
+typedef union pcbs_corepfvret_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t core_vret_sel : 4;
+ uint64_t core_voff_sel : 4;
+ uint64_t _reserved0 : 56;
+#else
+ uint64_t _reserved0 : 56;
+ uint64_t core_voff_sel : 4;
+ uint64_t core_vret_sel : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_corepfvret_reg_t;
+
+
+
+typedef union pcbs_ecopfpudly_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t eco_powup_dly0 : 4;
+ uint64_t eco_powup_dly1 : 4;
+ uint64_t eco_power_up_delay_sel : 12;
+ uint64_t _reserved0 : 44;
+#else
+ uint64_t _reserved0 : 44;
+ uint64_t eco_power_up_delay_sel : 12;
+ uint64_t eco_powup_dly1 : 4;
+ uint64_t eco_powup_dly0 : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ecopfpudly_reg_t;
+
+
+
+typedef union pcbs_ecopfpddly_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t eco_powdn_dly0 : 4;
+ uint64_t eco_powdn_dly1 : 4;
+ uint64_t eco_power_dn_delay_sel : 12;
+ uint64_t _reserved0 : 44;
+#else
+ uint64_t _reserved0 : 44;
+ uint64_t eco_power_dn_delay_sel : 12;
+ uint64_t eco_powdn_dly1 : 4;
+ uint64_t eco_powdn_dly0 : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ecopfpddly_reg_t;
+
+
+
+typedef union pcbs_ecopfvret_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t eco_vret_sel : 4;
+ uint64_t eco_voff_sel : 4;
+ uint64_t _reserved0 : 56;
+#else
+ uint64_t _reserved0 : 56;
+ uint64_t eco_voff_sel : 4;
+ uint64_t eco_vret_sel : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ecopfvret_reg_t;
+
+
+
+typedef union pcbs_freq_ctrl_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dpll_fmin : 9;
+ uint64_t dpll_fmax : 9;
+ uint64_t dpll_fmax_bias : 4;
+ uint64_t frequ_at_pstate0 : 9;
+ uint64_t _reserved0 : 33;
+#else
+ uint64_t _reserved0 : 33;
+ uint64_t frequ_at_pstate0 : 9;
+ uint64_t dpll_fmax_bias : 4;
+ uint64_t dpll_fmax : 9;
+ uint64_t dpll_fmin : 9;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_freq_ctrl_reg_t;
+
+
+
+typedef union pcbs_dpll_cpm_parm_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t lf_slewratexpi : 8;
+ uint64_t lf_use_cpmxpi : 1;
+ uint64_t ff_use_cpmxpi : 1;
+ uint64_t cpm_filter_enable : 1;
+ uint64_t ff_bypassxpi : 1;
+ uint64_t dco_override : 1;
+ uint64_t dco_incr : 1;
+ uint64_t dco_decr : 1;
+ uint64_t dpll_lock_timer_replacement_value : 9;
+ uint64_t pre_vret_pstate : 8;
+ uint64_t override_pcbs_dpll_synchronizer : 1;
+ uint64_t dpll_char_delta1 : 4;
+ uint64_t dpll_char_delta2 : 4;
+ uint64_t _reserved0 : 23;
+#else
+ uint64_t _reserved0 : 23;
+ uint64_t dpll_char_delta2 : 4;
+ uint64_t dpll_char_delta1 : 4;
+ uint64_t override_pcbs_dpll_synchronizer : 1;
+ uint64_t pre_vret_pstate : 8;
+ uint64_t dpll_lock_timer_replacement_value : 9;
+ uint64_t dco_decr : 1;
+ uint64_t dco_incr : 1;
+ uint64_t dco_override : 1;
+ uint64_t ff_bypassxpi : 1;
+ uint64_t cpm_filter_enable : 1;
+ uint64_t ff_use_cpmxpi : 1;
+ uint64_t lf_use_cpmxpi : 1;
+ uint64_t lf_slewratexpi : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_dpll_cpm_parm_reg_t;
+
+
+
+typedef union pcbs_power_management_status_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t global_pstate_actual : 8;
+ int64_t local_pstate_actual : 8;
+ int64_t pv_min : 8;
+ int64_t pvf_max : 8;
+ uint64_t spr_em_disabled : 1;
+ uint64_t psafe_mode_active : 1;
+ uint64_t ivrm_safe_mode_active : 1;
+ uint64_t ivrm_enable : 1;
+ uint64_t all_fsms_in_safe_state : 1;
+ uint64_t pmsr_spares : 4;
+ uint64_t _reserved0 : 23;
+#else
+ uint64_t _reserved0 : 23;
+ uint64_t pmsr_spares : 4;
+ uint64_t all_fsms_in_safe_state : 1;
+ uint64_t ivrm_enable : 1;
+ uint64_t ivrm_safe_mode_active : 1;
+ uint64_t psafe_mode_active : 1;
+ uint64_t spr_em_disabled : 1;
+ int64_t pvf_max : 8;
+ int64_t pv_min : 8;
+ int64_t local_pstate_actual : 8;
+ int64_t global_pstate_actual : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_power_management_status_reg_t;
+
+
+
+typedef union pcbs_ivrm_control_status_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ivrm_fsm_enable : 1;
+ uint64_t use_ivrm_for_vret : 1;
+ uint64_t binsearch_cal_ena : 1;
+ uint64_t pvref_en : 1;
+ uint64_t ivrm_core_vdd_bypass_b : 1;
+ uint64_t ivrm_core_vdd_poweron : 1;
+ uint64_t ivrm_core_vcs_bypass_b : 1;
+ uint64_t ivrm_core_vcs_poweron : 1;
+ uint64_t ivrm_eco_vdd_bypass_b : 1;
+ uint64_t ivrm_eco_vdd_poweron : 1;
+ uint64_t ivrm_eco_vcs_bypass_b : 1;
+ uint64_t ivrm_eco_vcs_poweron : 1;
+ uint64_t ivrm_vret_vdd : 7;
+ uint64_t ivrm_vret_vcs : 7;
+ uint64_t ivrm_vret_core_vdd_pfet_strength : 5;
+ uint64_t ivrm_vret_core_vcs_pfet_strength : 5;
+ uint64_t ivrm_vret_eco_vdd_pfet_strength : 5;
+ uint64_t ivrm_vret_eco_vcs_pfet_strength : 5;
+ uint64_t pvref_fail : 1;
+ uint64_t ivrm_pref_error_gross : 1;
+ uint64_t ivrm_pref_error_fine : 1;
+ uint64_t ivrm_core_vdd_range_hi : 1;
+ uint64_t ivrm_core_vdd_range_lo : 1;
+ uint64_t ivrm_eco_vdd_range_hi : 1;
+ uint64_t ivrm_eco_vdd_range_lo : 1;
+ uint64_t ivrm_core_vcs_range_hi : 1;
+ uint64_t ivrm_core_vcs_range_lo : 1;
+ uint64_t ivrm_eco_vcs_range_hi : 1;
+ uint64_t ivrm_eco_vcs_range_lo : 1;
+ uint64_t binsearch_cal_done : 1;
+ uint64_t ivrm_core_vdd_pfet_low_vout : 1;
+ uint64_t ivrm_core_vcs_pfet_low_vout : 1;
+ uint64_t ivrm_eco_vdd_pfet_low_vout : 1;
+ uint64_t ivrm_eco_vcs_pfet_low_vout : 1;
+ uint64_t ivrm_power_down_disable : 1;
+ uint64_t _reserved0 : 1;
+#else
+ uint64_t _reserved0 : 1;
+ uint64_t ivrm_power_down_disable : 1;
+ uint64_t ivrm_eco_vcs_pfet_low_vout : 1;
+ uint64_t ivrm_eco_vdd_pfet_low_vout : 1;
+ uint64_t ivrm_core_vcs_pfet_low_vout : 1;
+ uint64_t ivrm_core_vdd_pfet_low_vout : 1;
+ uint64_t binsearch_cal_done : 1;
+ uint64_t ivrm_eco_vcs_range_lo : 1;
+ uint64_t ivrm_eco_vcs_range_hi : 1;
+ uint64_t ivrm_core_vcs_range_lo : 1;
+ uint64_t ivrm_core_vcs_range_hi : 1;
+ uint64_t ivrm_eco_vdd_range_lo : 1;
+ uint64_t ivrm_eco_vdd_range_hi : 1;
+ uint64_t ivrm_core_vdd_range_lo : 1;
+ uint64_t ivrm_core_vdd_range_hi : 1;
+ uint64_t ivrm_pref_error_fine : 1;
+ uint64_t ivrm_pref_error_gross : 1;
+ uint64_t pvref_fail : 1;
+ uint64_t ivrm_vret_eco_vcs_pfet_strength : 5;
+ uint64_t ivrm_vret_eco_vdd_pfet_strength : 5;
+ uint64_t ivrm_vret_core_vcs_pfet_strength : 5;
+ uint64_t ivrm_vret_core_vdd_pfet_strength : 5;
+ uint64_t ivrm_vret_vcs : 7;
+ uint64_t ivrm_vret_vdd : 7;
+ uint64_t ivrm_eco_vcs_poweron : 1;
+ uint64_t ivrm_eco_vcs_bypass_b : 1;
+ uint64_t ivrm_eco_vdd_poweron : 1;
+ uint64_t ivrm_eco_vdd_bypass_b : 1;
+ uint64_t ivrm_core_vcs_poweron : 1;
+ uint64_t ivrm_core_vcs_bypass_b : 1;
+ uint64_t ivrm_core_vdd_poweron : 1;
+ uint64_t ivrm_core_vdd_bypass_b : 1;
+ uint64_t pvref_en : 1;
+ uint64_t binsearch_cal_ena : 1;
+ uint64_t use_ivrm_for_vret : 1;
+ uint64_t ivrm_fsm_enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ivrm_control_status_reg_t;
+
+
+
+typedef union pcbs_ivrm_value_setting_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ivrm_core_vdd_ivid : 8;
+ uint64_t ivrm_core_vcs_ivid : 8;
+ uint64_t ivrm_eco_vdd_ivid : 8;
+ uint64_t ivrm_eco_vcs_ivid : 8;
+ uint64_t ivrm_core_vdd_pfet_strength : 5;
+ uint64_t ivrm_core_vcs_pfet_strength : 5;
+ uint64_t ivrm_eco_vdd_pfet_strength : 5;
+ uint64_t ivrm_eco_vcs_pfet_strength : 5;
+ uint64_t ivrm_vdd_core_pfetstr_valid : 1;
+ uint64_t ivrm_vcs_core_pfetstr_valid : 1;
+ uint64_t ivrm_vdd_eco_pfetstr_valid : 1;
+ uint64_t ivrm_vcs_eco_pfetstr_valid : 1;
+ uint64_t core_vdd_vpump_en : 1;
+ uint64_t core_vcs_vpump_en : 1;
+ uint64_t eco_vdd_vpump_en : 1;
+ uint64_t eco_vcs_vpump_en : 1;
+ uint64_t _reserved0 : 4;
+#else
+ uint64_t _reserved0 : 4;
+ uint64_t eco_vcs_vpump_en : 1;
+ uint64_t eco_vdd_vpump_en : 1;
+ uint64_t core_vcs_vpump_en : 1;
+ uint64_t core_vdd_vpump_en : 1;
+ uint64_t ivrm_vcs_eco_pfetstr_valid : 1;
+ uint64_t ivrm_vdd_eco_pfetstr_valid : 1;
+ uint64_t ivrm_vcs_core_pfetstr_valid : 1;
+ uint64_t ivrm_vdd_core_pfetstr_valid : 1;
+ uint64_t ivrm_eco_vcs_pfet_strength : 5;
+ uint64_t ivrm_eco_vdd_pfet_strength : 5;
+ uint64_t ivrm_core_vcs_pfet_strength : 5;
+ uint64_t ivrm_core_vdd_pfet_strength : 5;
+ uint64_t ivrm_eco_vcs_ivid : 8;
+ uint64_t ivrm_eco_vdd_ivid : 8;
+ uint64_t ivrm_core_vcs_ivid : 8;
+ uint64_t ivrm_core_vdd_ivid : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ivrm_value_setting_reg_t;
+
+
+
+typedef union pcbs_pcbspm_mode_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t enable_pstate_mode : 1;
+ uint64_t global_pstate_change_for_idle_state_enabled : 1;
+ uint64_t enable_global_pstate_req : 1;
+ uint64_t enable_winkle_with_cpm_mode : 1;
+ uint64_t enable_clipping_of_global_pstate_req : 1;
+ uint64_t chksw_hw214553 : 1;
+ uint64_t enable_pmc_pmax_sync_notification : 1;
+ uint64_t dpll_lock_replacement_timer_mode_en : 1;
+ uint64_t dpll_freqout_mode_en : 1;
+ uint64_t dpll_flock_mode_en : 1;
+ uint64_t enable_sense_delay_characterization : 1;
+ uint64_t sense_delay_timer_val : 7;
+ uint64_t cpm_fmin_clip_error_sel : 2;
+ uint64_t dbg_trace_sel : 4;
+ uint64_t trace_data_sel : 2;
+ uint64_t tp_cplt_ivrm_vpp_tune : 4;
+ uint64_t _reserved0 : 34;
+#else
+ uint64_t _reserved0 : 34;
+ uint64_t tp_cplt_ivrm_vpp_tune : 4;
+ uint64_t trace_data_sel : 2;
+ uint64_t dbg_trace_sel : 4;
+ uint64_t cpm_fmin_clip_error_sel : 2;
+ uint64_t sense_delay_timer_val : 7;
+ uint64_t enable_sense_delay_characterization : 1;
+ uint64_t dpll_flock_mode_en : 1;
+ uint64_t dpll_freqout_mode_en : 1;
+ uint64_t dpll_lock_replacement_timer_mode_en : 1;
+ uint64_t enable_pmc_pmax_sync_notification : 1;
+ uint64_t chksw_hw214553 : 1;
+ uint64_t enable_clipping_of_global_pstate_req : 1;
+ uint64_t enable_winkle_with_cpm_mode : 1;
+ uint64_t enable_global_pstate_req : 1;
+ uint64_t global_pstate_change_for_idle_state_enabled : 1;
+ uint64_t enable_pstate_mode : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pcbspm_mode_reg_t;
+
+#endif // __ASSEMBLER__
+#define PCBS_PCBSPM_MODE_REG_ENABLE_PSTATE_MODE SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PCBS_PCBSPM_MODE_REG_GLOBAL_PSTATE_CHANGE_FOR_IDLE_STATE_ENABLED SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define PCBS_PCBSPM_MODE_REG_ENABLE_GLOBAL_PSTATE_REQ SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define PCBS_PCBSPM_MODE_REG_ENABLE_WINKLE_WITH_CPM_MODE SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define PCBS_PCBSPM_MODE_REG_ENABLE_CLIPPING_OF_GLOBAL_PSTATE_REQ SIXTYFOUR_BIT_CONSTANT(0x0800000000000000)
+#define PCBS_PCBSPM_MODE_REG_CHKSW_HW214553 SIXTYFOUR_BIT_CONSTANT(0x0400000000000000)
+#define PCBS_PCBSPM_MODE_REG_ENABLE_PMC_PMAX_SYNC_NOTIFICATION SIXTYFOUR_BIT_CONSTANT(0x0200000000000000)
+#define PCBS_PCBSPM_MODE_REG_DPLL_LOCK_REPLACEMENT_TIMER_MODE_EN SIXTYFOUR_BIT_CONSTANT(0x0100000000000000)
+#define PCBS_PCBSPM_MODE_REG_DPLL_FREQOUT_MODE_EN SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PCBS_PCBSPM_MODE_REG_DPLL_FLOCK_MODE_EN SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PCBS_PCBSPM_MODE_REG_ENABLE_SENSE_DELAY_CHARACTERIZATION SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define PCBS_PCBSPM_MODE_REG_SENSE_DELAY_TIMER_VAL_MASK SIXTYFOUR_BIT_CONSTANT(0x001fc00000000000)
+#define PCBS_PCBSPM_MODE_REG_CPM_FMIN_CLIP_ERROR_SEL_MASK SIXTYFOUR_BIT_CONSTANT(0x0000300000000000)
+#define PCBS_PCBSPM_MODE_REG_DBG_TRACE_SEL_MASK SIXTYFOUR_BIT_CONSTANT(0x00000f0000000000)
+#define PCBS_PCBSPM_MODE_REG_TRACE_DATA_SEL_MASK SIXTYFOUR_BIT_CONSTANT(0x000000c000000000)
+#define PCBS_PCBSPM_MODE_REG_TP_CPLT_IVRM_VPP_TUNE_MASK SIXTYFOUR_BIT_CONSTANT(0x0000003c00000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pcbs_ivrm_pfetstr_sense_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ivrm_core_vdd_pfetstr_sns : 5;
+ uint64_t ivrm_core_vcs_pfetstr_sns : 5;
+ uint64_t ivrm_eco_vdd_pfetstr_sns : 5;
+ uint64_t ivrm_eco_vcs_pfetstr_sns : 5;
+ uint64_t ivrm_vdd_core_pfetstr_valid_sns : 1;
+ uint64_t ivrm_vcs_core_pfetstr_valid_sns : 1;
+ uint64_t ivrm_vdd_eco_pfetstr_valid_sns : 1;
+ uint64_t ivrm_vcs_eco_pfetstr_valid_sns : 1;
+ uint64_t core_vdd_bypass_b_sense : 1;
+ uint64_t core_vcs_bypass_b_sense : 1;
+ uint64_t eco_vdd_bypass_b_sense : 1;
+ uint64_t eco_vcs_bypass_b_sense : 1;
+ uint64_t core_vdd_poweron_sense : 1;
+ uint64_t core_vcs_poweron_sense : 1;
+ uint64_t eco_vdd_poweron_sense : 1;
+ uint64_t eco_vcs_poweron_sense : 1;
+ uint64_t core_vdd_vpump_en_sense : 1;
+ uint64_t core_vcs_vpump_en_sense : 1;
+ uint64_t eco_vdd_vpump_en_sense : 1;
+ uint64_t eco_vcs_vpump_en_sense : 1;
+ uint64_t core_vdd_pfet_low_vout_sns : 1;
+ uint64_t core_vcs_pfet_low_vout_sns : 1;
+ uint64_t eco_vdd_pfet_low_vout_sns : 1;
+ uint64_t eco_vcs_pfet_low_vout_sns : 1;
+ uint64_t _reserved0 : 24;
+#else
+ uint64_t _reserved0 : 24;
+ uint64_t eco_vcs_pfet_low_vout_sns : 1;
+ uint64_t eco_vdd_pfet_low_vout_sns : 1;
+ uint64_t core_vcs_pfet_low_vout_sns : 1;
+ uint64_t core_vdd_pfet_low_vout_sns : 1;
+ uint64_t eco_vcs_vpump_en_sense : 1;
+ uint64_t eco_vdd_vpump_en_sense : 1;
+ uint64_t core_vcs_vpump_en_sense : 1;
+ uint64_t core_vdd_vpump_en_sense : 1;
+ uint64_t eco_vcs_poweron_sense : 1;
+ uint64_t eco_vdd_poweron_sense : 1;
+ uint64_t core_vcs_poweron_sense : 1;
+ uint64_t core_vdd_poweron_sense : 1;
+ uint64_t eco_vcs_bypass_b_sense : 1;
+ uint64_t eco_vdd_bypass_b_sense : 1;
+ uint64_t core_vcs_bypass_b_sense : 1;
+ uint64_t core_vdd_bypass_b_sense : 1;
+ uint64_t ivrm_vcs_eco_pfetstr_valid_sns : 1;
+ uint64_t ivrm_vdd_eco_pfetstr_valid_sns : 1;
+ uint64_t ivrm_vcs_core_pfetstr_valid_sns : 1;
+ uint64_t ivrm_vdd_core_pfetstr_valid_sns : 1;
+ uint64_t ivrm_eco_vcs_pfetstr_sns : 5;
+ uint64_t ivrm_eco_vdd_pfetstr_sns : 5;
+ uint64_t ivrm_core_vcs_pfetstr_sns : 5;
+ uint64_t ivrm_core_vdd_pfetstr_sns : 5;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ivrm_pfetstr_sense_reg_t;
+
+
+
+typedef union pcbs_power_management_idle_control_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t nap_pstate_req : 8;
+ uint64_t nap_pstate_en : 1;
+ uint64_t nap_global_en : 1;
+ uint64_t nap_latency : 2;
+ uint64_t reserved_ppmicr_0 : 4;
+ int64_t sleep_pstate_req : 8;
+ uint64_t sleep_pstate_en : 1;
+ uint64_t sleep_global_en : 1;
+ uint64_t sleep_latency : 2;
+ uint64_t reserved_ppmicr_1 : 4;
+ int64_t winkle_pstate_req : 8;
+ uint64_t winkle_pstate_en : 1;
+ uint64_t winkle_global_en : 1;
+ uint64_t winkle_latency : 2;
+ uint64_t reserved_ppmicr_2 : 4;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t reserved_ppmicr_2 : 4;
+ uint64_t winkle_latency : 2;
+ uint64_t winkle_global_en : 1;
+ uint64_t winkle_pstate_en : 1;
+ int64_t winkle_pstate_req : 8;
+ uint64_t reserved_ppmicr_1 : 4;
+ uint64_t sleep_latency : 2;
+ uint64_t sleep_global_en : 1;
+ uint64_t sleep_pstate_en : 1;
+ int64_t sleep_pstate_req : 8;
+ uint64_t reserved_ppmicr_0 : 4;
+ uint64_t nap_latency : 2;
+ uint64_t nap_global_en : 1;
+ uint64_t nap_pstate_en : 1;
+ int64_t nap_pstate_req : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_power_management_idle_control_reg_t;
+
+
+
+typedef union pcbs_power_management_control_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t global_pstate_req : 8;
+ int64_t local_pstate_req : 8;
+ uint64_t auto_override0_pstate_limit_en : 1;
+ uint64_t auto_override1_pstate_limit_en : 1;
+ uint64_t reserved_ppmcr : 6;
+ int64_t auto_override_pstate0 : 8;
+ int64_t auto_override_pstate1 : 8;
+ uint64_t _reserved0 : 24;
+#else
+ uint64_t _reserved0 : 24;
+ int64_t auto_override_pstate1 : 8;
+ int64_t auto_override_pstate0 : 8;
+ uint64_t reserved_ppmcr : 6;
+ uint64_t auto_override1_pstate_limit_en : 1;
+ uint64_t auto_override0_pstate_limit_en : 1;
+ int64_t local_pstate_req : 8;
+ int64_t global_pstate_req : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_power_management_control_reg_t;
+
+
+
+typedef union pcbs_pmc_vf_ctrl_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t pglobal_actual : 8;
+ uint64_t maxregvcs : 8;
+ uint64_t maxregvdd : 8;
+ uint64_t evidvcs_eff : 8;
+ uint64_t evidvdd_eff : 8;
+ uint64_t _reserved0 : 24;
+#else
+ uint64_t _reserved0 : 24;
+ uint64_t evidvdd_eff : 8;
+ uint64_t evidvcs_eff : 8;
+ uint64_t maxregvdd : 8;
+ uint64_t maxregvcs : 8;
+ int64_t pglobal_actual : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pmc_vf_ctrl_reg_t;
+
+
+
+typedef union pcbs_undervolting_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t puv_min : 8;
+ int64_t puv_max : 8;
+ uint64_t kuv : 6;
+ uint64_t _reserved0 : 42;
+#else
+ uint64_t _reserved0 : 42;
+ uint64_t kuv : 6;
+ int64_t puv_max : 8;
+ int64_t puv_min : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_undervolting_reg_t;
+
+
+
+typedef union pcbs_pstate_index_bound_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t lpsi_min : 8;
+ uint64_t lpsi_entries_minus_1 : 7;
+ uint64_t _reserved0 : 49;
+#else
+ uint64_t _reserved0 : 49;
+ uint64_t lpsi_entries_minus_1 : 7;
+ uint64_t lpsi_min : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pstate_index_bound_reg_t;
+
+
+
+typedef union pcbs_power_management_bounds_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t pmin_clip : 8;
+ int64_t pmax_clip : 8;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ int64_t pmax_clip : 8;
+ int64_t pmin_clip : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_power_management_bounds_reg_t;
+
+
+
+typedef union pcbs_pstate_table_ctrl_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pstate_table_address : 7;
+ uint64_t _reserved0 : 57;
+#else
+ uint64_t _reserved0 : 57;
+ uint64_t pstate_table_address : 7;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pstate_table_ctrl_reg_t;
+
+
+
+typedef union pcbs_pstate_table_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pstate_data : 64;
+#else
+ uint64_t pstate_data : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pstate_table_reg_t;
+
+
+
+typedef union pcbs_pstate_step_target_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t local_pstate_eff_req : 8;
+ int64_t local_pstate_target : 8;
+ int64_t local_core_pstate_step_target : 8;
+ int64_t local_eco_pstate_step_target : 8;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ int64_t local_eco_pstate_step_target : 8;
+ int64_t local_core_pstate_step_target : 8;
+ int64_t local_pstate_target : 8;
+ int64_t local_pstate_eff_req : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_pstate_step_target_reg_t;
+
+
+
+typedef union pcbs_dpll_status_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dpll_ff_freqout : 15;
+ uint64_t dpll_frequ_change : 1;
+ uint64_t dpll_status_spare_bit1 : 1;
+ uint64_t pmax_sync_pending : 1;
+ uint64_t ga_ack_pending : 1;
+ int64_t capped_global_pstate_req : 8;
+ uint64_t dpll_fmax_and_cpmbit2 : 1;
+ uint64_t dpll_fmax_and_cpmbit3 : 1;
+ uint64_t dpll_fmax_and_cpmbit4 : 1;
+ uint64_t dpll_fmin_and_not_cpmbit2 : 1;
+ uint64_t dpll_fmin_and_not_cpmbit1 : 1;
+ uint64_t dpll_fmin_and_not_cpmbit0 : 1;
+ uint64_t dpll_faster_than_fmax_plus_delta1 : 1;
+ uint64_t dpll_slower_than_fmin_minus_delta2 : 1;
+ uint64_t dpll_max_freqout_after_last_read : 14;
+ uint64_t dpll_min_freqout_after_last_read : 14;
+ uint64_t _reserved0 : 1;
+#else
+ uint64_t _reserved0 : 1;
+ uint64_t dpll_min_freqout_after_last_read : 14;
+ uint64_t dpll_max_freqout_after_last_read : 14;
+ uint64_t dpll_slower_than_fmin_minus_delta2 : 1;
+ uint64_t dpll_faster_than_fmax_plus_delta1 : 1;
+ uint64_t dpll_fmin_and_not_cpmbit0 : 1;
+ uint64_t dpll_fmin_and_not_cpmbit1 : 1;
+ uint64_t dpll_fmin_and_not_cpmbit2 : 1;
+ uint64_t dpll_fmax_and_cpmbit4 : 1;
+ uint64_t dpll_fmax_and_cpmbit3 : 1;
+ uint64_t dpll_fmax_and_cpmbit2 : 1;
+ int64_t capped_global_pstate_req : 8;
+ uint64_t ga_ack_pending : 1;
+ uint64_t pmax_sync_pending : 1;
+ uint64_t dpll_status_spare_bit1 : 1;
+ uint64_t dpll_frequ_change : 1;
+ uint64_t dpll_ff_freqout : 15;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_dpll_status_reg_t;
+
+
+
+typedef union pcbs_ivrm_vid_control_reg0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ivrm_req_pstate_stepdelay_rising : 8;
+ uint64_t ivrm_req_pstate_stepdelay_lowering : 8;
+ uint64_t _reserved0 : 48;
+#else
+ uint64_t _reserved0 : 48;
+ uint64_t ivrm_req_pstate_stepdelay_lowering : 8;
+ uint64_t ivrm_req_pstate_stepdelay_rising : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ivrm_vid_control_reg0_t;
+
+
+
+typedef union pcbs_ivrm_vid_control_reg1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ivrm_stabilize_delay_run : 8;
+ uint64_t ivrm_stabilize_delay_idle : 8;
+ uint64_t ivrm_pfstr_prop_delay : 8;
+ uint64_t ivrm_pfstrvalid_prop_delay : 8;
+ uint64_t ivrm_vpump_poweron_time : 8;
+ uint64_t ivrm_bypass_delay : 8;
+ uint64_t pfet_vpump_enable_delay : 8;
+ uint64_t ivrm_vid_vout_threshold : 7;
+ uint64_t _reserved0 : 1;
+#else
+ uint64_t _reserved0 : 1;
+ uint64_t ivrm_vid_vout_threshold : 7;
+ uint64_t pfet_vpump_enable_delay : 8;
+ uint64_t ivrm_bypass_delay : 8;
+ uint64_t ivrm_vpump_poweron_time : 8;
+ uint64_t ivrm_pfstrvalid_prop_delay : 8;
+ uint64_t ivrm_pfstr_prop_delay : 8;
+ uint64_t ivrm_stabilize_delay_idle : 8;
+ uint64_t ivrm_stabilize_delay_run : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_ivrm_vid_control_reg1_t;
+
+
+
+typedef union pcbs_occ_heartbeat_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t occ_heartbeat_time : 8;
+ uint64_t occ_heartbeat_enable : 1;
+ uint64_t occ_heartbeat_reg_addr_offset : 8;
+ int64_t psafe : 8;
+ uint64_t _reserved0 : 39;
+#else
+ uint64_t _reserved0 : 39;
+ int64_t psafe : 8;
+ uint64_t occ_heartbeat_reg_addr_offset : 8;
+ uint64_t occ_heartbeat_enable : 1;
+ uint64_t occ_heartbeat_time : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_occ_heartbeat_reg_t;
+
+
+
+typedef union pcbs_resonant_clock_control_reg0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t resclk_dis : 1;
+ uint64_t resclk_control_mode : 1;
+ uint64_t resclk_sync_pw : 3;
+ uint64_t res_sync_delay_cnt : 7;
+ uint64_t res_csb_str_instr_lo : 15;
+ uint64_t res_csb_str_instr_hi : 15;
+ uint64_t _reserved0 : 22;
+#else
+ uint64_t _reserved0 : 22;
+ uint64_t res_csb_str_instr_hi : 15;
+ uint64_t res_csb_str_instr_lo : 15;
+ uint64_t res_sync_delay_cnt : 7;
+ uint64_t resclk_sync_pw : 3;
+ uint64_t resclk_control_mode : 1;
+ uint64_t resclk_dis : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_resonant_clock_control_reg0_t;
+
+
+
+typedef union pcbs_resonant_clock_control_reg1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ int64_t full_csb_ps : 8;
+ int64_t res_low_lower_ps : 8;
+ int64_t res_low_upper_ps : 8;
+ int64_t res_high_lower_ps : 8;
+ int64_t res_high_upper_ps : 8;
+ uint64_t nonres_csb_value_ti : 4;
+ uint64_t full_csb_value_ti : 4;
+ uint64_t resclk_value : 9;
+ uint64_t resclk_core_sync_value : 1;
+ uint64_t csb_eco_sync_value : 1;
+ uint64_t _reserved0 : 5;
+#else
+ uint64_t _reserved0 : 5;
+ uint64_t csb_eco_sync_value : 1;
+ uint64_t resclk_core_sync_value : 1;
+ uint64_t resclk_value : 9;
+ uint64_t full_csb_value_ti : 4;
+ uint64_t nonres_csb_value_ti : 4;
+ int64_t res_high_upper_ps : 8;
+ int64_t res_high_lower_ps : 8;
+ int64_t res_low_upper_ps : 8;
+ int64_t res_low_lower_ps : 8;
+ int64_t full_csb_ps : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_resonant_clock_control_reg1_t;
+
+
+
+typedef union pcbs_resonant_clock_status_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t resclk_state : 1;
+ uint64_t res_hi_induct_en : 1;
+ uint64_t resclk_inprogress : 1;
+ uint64_t resclk_full_csb : 1;
+ uint64_t _reserved0 : 60;
+#else
+ uint64_t _reserved0 : 60;
+ uint64_t resclk_full_csb : 1;
+ uint64_t resclk_inprogress : 1;
+ uint64_t res_hi_induct_en : 1;
+ uint64_t resclk_state : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_resonant_clock_status_reg_t;
+
+
+
+typedef union pcbs_local_pstate_frequency_target_control_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t delay_time : 3;
+ uint64_t record_transitions : 1;
+ uint64_t multiplier : 15;
+ uint64_t enable_lpft_function : 1;
+ uint64_t _reserved0 : 44;
+#else
+ uint64_t _reserved0 : 44;
+ uint64_t enable_lpft_function : 1;
+ uint64_t multiplier : 15;
+ uint64_t record_transitions : 1;
+ uint64_t delay_time : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_local_pstate_frequency_target_control_reg_t;
+
+
+
+typedef union pcbs_local_pstate_frequency_target_status_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t valid : 1;
+ uint64_t cpm_dpll : 1;
+ uint64_t ivrm : 1;
+ uint64_t transition : 1;
+ uint64_t stable : 1;
+ uint64_t delta : 24;
+ uint64_t cumulative : 24;
+ uint64_t pstate : 8;
+ uint64_t _reserved0 : 3;
+#else
+ uint64_t _reserved0 : 3;
+ uint64_t pstate : 8;
+ uint64_t cumulative : 24;
+ uint64_t delta : 24;
+ uint64_t stable : 1;
+ uint64_t transition : 1;
+ uint64_t ivrm : 1;
+ uint64_t cpm_dpll : 1;
+ uint64_t valid : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_local_pstate_frequency_target_status_reg_t;
+
+
+
+typedef union pcbs_fsm_monitor1_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t babystep_main_fsm : 7;
+ uint64_t babystep_slave_fsm : 5;
+ uint64_t core_railstepper_main_fsm : 5;
+ uint64_t eco_railstepper_main_fsm : 5;
+ uint64_t core_railstepper_sub_fsm : 4;
+ uint64_t eco_railstepper_sub_fsm : 4;
+ uint64_t core_railstepper_byp_fsm : 5;
+ uint64_t eco_railstepper_byp_fsm : 5;
+ uint64_t ivrm_core_vdd_sequencer_fsm : 6;
+ uint64_t ivrm_core_vcs_sequencer_fsm : 6;
+ uint64_t ivrm_eco_vdd_sequencer_fsm : 6;
+ uint64_t ivrm_eco_vcs_sequencer_fsm : 6;
+#else
+ uint64_t ivrm_eco_vcs_sequencer_fsm : 6;
+ uint64_t ivrm_eco_vdd_sequencer_fsm : 6;
+ uint64_t ivrm_core_vcs_sequencer_fsm : 6;
+ uint64_t ivrm_core_vdd_sequencer_fsm : 6;
+ uint64_t eco_railstepper_byp_fsm : 5;
+ uint64_t core_railstepper_byp_fsm : 5;
+ uint64_t eco_railstepper_sub_fsm : 4;
+ uint64_t core_railstepper_sub_fsm : 4;
+ uint64_t eco_railstepper_main_fsm : 5;
+ uint64_t core_railstepper_main_fsm : 5;
+ uint64_t babystep_slave_fsm : 5;
+ uint64_t babystep_main_fsm : 7;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_fsm_monitor1_reg_t;
+
+
+
+typedef union pcbs_fsm_monitor2_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t resclk_band_fsm : 7;
+ uint64_t resclk_lowres_fsm : 4;
+ uint64_t resclk_highres_fsm : 4;
+ uint64_t resclk_fullcsb_fsm : 4;
+ uint64_t resclk_update_fsm : 4;
+ uint64_t idle_transition_fsm : 7;
+ uint64_t peco_step_target_uv : 8;
+ uint64_t pcore_step_target_uv : 8;
+ uint64_t _reserved0 : 18;
+#else
+ uint64_t _reserved0 : 18;
+ uint64_t pcore_step_target_uv : 8;
+ uint64_t peco_step_target_uv : 8;
+ uint64_t idle_transition_fsm : 7;
+ uint64_t resclk_update_fsm : 4;
+ uint64_t resclk_fullcsb_fsm : 4;
+ uint64_t resclk_highres_fsm : 4;
+ uint64_t resclk_lowres_fsm : 4;
+ uint64_t resclk_band_fsm : 7;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_fsm_monitor2_reg_t;
+
+
+
+typedef union pcbs_chksw_unassisted_interrupts {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 1;
+ uint64_t _reserved0 : 63;
+#else
+ uint64_t _reserved0 : 63;
+ uint64_t value : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pcbs_chksw_unassisted_interrupts_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __PCBS_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/pcbs_register_addresses.h b/src/ssx/pgp/registers/pcbs_register_addresses.h
new file mode 100755
index 0000000..8c465d1
--- /dev/null
+++ b/src/ssx/pgp/registers/pcbs_register_addresses.h
@@ -0,0 +1,74 @@
+#ifndef __PCBS_REGISTER_ADDRESSES_H__
+#define __PCBS_REGISTER_ADDRESSES_H__
+
+// $Id: pcbs_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:24 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pcbs_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pcbs_register_addresses.h
+/// \brief Symbolic addresses for the PCBS unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define PCBS_PIB_BASE 0x100f0100
+#define PCBS_PMGP0_REG 0x100f0100
+#define PCBS_PMGP0_REG_AND 0x100f0101
+#define PCBS_PMGP0_REG_OR 0x100f0102
+#define PCBS_PMGP1_REG 0x100f0103
+#define PCBS_PMGP1_REG_AND 0x100f0104
+#define PCBS_PMGP1_REG_OR 0x100f0105
+#define PCBS_PFVDDCNTLSTAT_REG 0x100f0106
+#define PCBS_PFVCSCNTLSTAT_REG 0x100f010e
+#define PCBS_PFSENSE_REG 0x100f0107
+#define PCBS_PMERRSUM_REG 0x100f0108
+#define PCBS_PMERR_REG 0x100f0109
+#define PCBS_PMERRMASK_REG 0x100f010a
+#define PCBS_PMSPCWKUPFSP_REG 0x100f010b
+#define PCBS_PMSPCWKUPOCC_REG 0x100f010c
+#define PCBS_PMSPCWKUPPHYP_REG 0x100f010d
+#define PCBS_PMSTATEHISTPHYP_REG 0x100f0110
+#define PCBS_PMSTATEHISTFSP_REG 0x100f0111
+#define PCBS_PMSTATEHISTOCC_REG 0x100f0112
+#define PCBS_PMSTATEHISTPERF_REG 0x100f0113
+#define PCBS_IDLEFSMGOTOCMD_REG 0x100f0114
+#define PCBS_COREPFPUDLY_REG 0x100f012c
+#define PCBS_COREPFPDDLY_REG 0x100f012d
+#define PCBS_COREPFVRET_REG 0x100f0130
+#define PCBS_ECOPFPUDLY_REG 0x100f014c
+#define PCBS_ECOPFPDDLY_REG 0x100f014d
+#define PCBS_ECOPFVRET_REG 0x100f0150
+#define PCBS_FREQ_CTRL_REG 0x100f0151
+#define PCBS_DPLL_CPM_PARM_REG 0x100f0152
+#define PCBS_POWER_MANAGEMENT_STATUS_REG 0x100f0153
+#define PCBS_IVRM_CONTROL_STATUS_REG 0x100f0154
+#define PCBS_IVRM_VALUE_SETTING_REG 0x100f0155
+#define PCBS_PCBSPM_MODE_REG 0x100f0156
+#define PCBS_IVRM_PFETSTR_SENSE_REG 0x100f0157
+#define PCBS_POWER_MANAGEMENT_IDLE_CONTROL_REG 0x100f0158
+#define PCBS_POWER_MANAGEMENT_CONTROL_REG 0x100f0159
+#define PCBS_PMC_VF_CTRL_REG 0x100f015a
+#define PCBS_UNDERVOLTING_REG 0x100f015b
+#define PCBS_PSTATE_INDEX_BOUND_REG 0x100f015c
+#define PCBS_POWER_MANAGEMENT_BOUNDS_REG 0x100f015d
+#define PCBS_PSTATE_TABLE_CTRL_REG 0x100f015e
+#define PCBS_PSTATE_TABLE_REG 0x100f015f
+#define PCBS_PSTATE_STEP_TARGET_REG 0x100f0160
+#define PCBS_DPLL_STATUS_REG 0x100f0161
+#define PCBS_IVRM_VID_CONTROL_REG0 0x100f0162
+#define PCBS_IVRM_VID_CONTROL_REG1 0x100f0163
+#define PCBS_OCC_HEARTBEAT_REG 0x100f0164
+#define PCBS_RESONANT_CLOCK_CONTROL_REG0 0x100f0165
+#define PCBS_RESONANT_CLOCK_CONTROL_REG1 0x100f0166
+#define PCBS_RESONANT_CLOCK_STATUS_REG 0x100f0167
+#define PCBS_LOCAL_PSTATE_FREQUENCY_TARGET_CONTROL_REG 0x100f0168
+#define PCBS_LOCAL_PSTATE_FREQUENCY_TARGET_STATUS_REG 0x100f0169
+#define PCBS_FSM_MONITOR1_REG 0x100f0170
+#define PCBS_FSM_MONITOR2_REG 0x100f0171
+
+#endif // __PCBS_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/pibmem_firmware_registers.h b/src/ssx/pgp/registers/pibmem_firmware_registers.h
new file mode 100644
index 0000000..3b36fc1
--- /dev/null
+++ b/src/ssx/pgp/registers/pibmem_firmware_registers.h
@@ -0,0 +1,264 @@
+#ifndef __PIBMEM_FIRMWARE_REGISTERS_H__
+#define __PIBMEM_FIRMWARE_REGISTERS_H__
+
+// $Id: pibmem_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pibmem_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pibmem_firmware_registers.h
+/// \brief C register structs for the PIBMEM unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union pibmem_data0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_data0_t;
+
+
+
+typedef union pibmem_control {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t auto_pre_increment : 1;
+ uint64_t auto_post_decrement : 1;
+ uint64_t _reserved0 : 62;
+#else
+ uint64_t _reserved0 : 62;
+ uint64_t auto_post_decrement : 1;
+ uint64_t auto_pre_increment : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_control_t;
+
+
+
+typedef union pibmem_address {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 48;
+ uint64_t address : 16;
+#else
+ uint64_t address : 16;
+ uint64_t reserved0 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_address_t;
+
+
+
+typedef union pibmem_data {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_data_t;
+
+
+
+typedef union pibmem_data_inc {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_data_inc_t;
+
+
+
+typedef union pibmem_data_dec {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_data_dec_t;
+
+
+
+typedef union pibmem_status {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t addr_invalid : 1;
+ uint64_t write_invalid : 1;
+ uint64_t read_invalid : 1;
+ uint64_t ecc_uncorrected_error : 1;
+ uint64_t ecc_corrected_error : 1;
+ uint64_t bad_array_address : 1;
+ uint64_t reserved6 : 5;
+ uint64_t fsm_present_state : 7;
+ uint64_t _reserved0 : 46;
+#else
+ uint64_t _reserved0 : 46;
+ uint64_t fsm_present_state : 7;
+ uint64_t reserved6 : 5;
+ uint64_t bad_array_address : 1;
+ uint64_t ecc_corrected_error : 1;
+ uint64_t ecc_uncorrected_error : 1;
+ uint64_t read_invalid : 1;
+ uint64_t write_invalid : 1;
+ uint64_t addr_invalid : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_status_t;
+
+
+
+typedef union pibmem_reset {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reset_code : 2;
+ uint64_t _reserved0 : 62;
+#else
+ uint64_t _reserved0 : 62;
+ uint64_t reset_code : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_reset_t;
+
+
+
+typedef union pibmem_repair {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 64;
+#else
+ uint64_t value : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pibmem_repair_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __PIBMEM_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/pibmem_register_addresses.h b/src/ssx/pgp/registers/pibmem_register_addresses.h
new file mode 100644
index 0000000..0cffaa2
--- /dev/null
+++ b/src/ssx/pgp/registers/pibmem_register_addresses.h
@@ -0,0 +1,30 @@
+#ifndef __PIBMEM_REGISTER_ADDRESSES_H__
+#define __PIBMEM_REGISTER_ADDRESSES_H__
+
+// $Id: pibmem_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pibmem_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pibmem_register_addresses.h
+/// \brief Symbolic addresses for the PIBMEM unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define PIBMEM_PIB_BASE 0x00080000
+#define PIBMEM_DATA0 0x00080000
+#define PIBMEM_CONTROL 0x00088000
+#define PIBMEM_ADDRESS 0x00088001
+#define PIBMEM_DATA 0x00088002
+#define PIBMEM_DATA_INC 0x00088003
+#define PIBMEM_DATA_DEC 0x00088004
+#define PIBMEM_STATUS 0x00088005
+#define PIBMEM_RESET 0x00088006
+#define PIBMEM_REPAIR 0x00088007
+
+#endif // __PIBMEM_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/plb_arbiter_firmware_registers.h b/src/ssx/pgp/registers/plb_arbiter_firmware_registers.h
new file mode 100755
index 0000000..583e95d
--- /dev/null
+++ b/src/ssx/pgp/registers/plb_arbiter_firmware_registers.h
@@ -0,0 +1,215 @@
+#ifndef __PLB_ARBITER_FIRMWARE_REGISTERS_H__
+#define __PLB_ARBITER_FIRMWARE_REGISTERS_H__
+
+// $Id: plb_arbiter_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/plb_arbiter_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file plb_arbiter_firmware_registers.h
+/// \brief C register structs for the PLB_ARBITER unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union plb_prev {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} plb_prev_t;
+
+
+
+typedef union plb_pacr {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t ppm : 1;
+ uint32_t ppo : 3;
+ uint32_t hbu : 1;
+ uint32_t rdp : 2;
+ uint32_t wrp : 1;
+ uint32_t _reserved0 : 24;
+#else
+ uint32_t _reserved0 : 24;
+ uint32_t wrp : 1;
+ uint32_t rdp : 2;
+ uint32_t hbu : 1;
+ uint32_t ppo : 3;
+ uint32_t ppm : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} plb_pacr_t;
+
+
+
+typedef union plb_pesr {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pte0 : 1;
+ uint32_t rw0 : 1;
+ uint32_t flk0 : 1;
+ uint32_t alk0 : 1;
+ uint32_t pte1 : 1;
+ uint32_t rw1 : 1;
+ uint32_t flk1 : 1;
+ uint32_t alk1 : 1;
+ uint32_t pte2 : 1;
+ uint32_t rw2 : 1;
+ uint32_t flk2 : 1;
+ uint32_t alk2 : 1;
+ uint32_t pte3 : 1;
+ uint32_t rw3 : 1;
+ uint32_t flk3 : 1;
+ uint32_t alk3 : 1;
+ uint32_t pte4 : 1;
+ uint32_t rw4 : 1;
+ uint32_t flk4 : 1;
+ uint32_t alk4 : 1;
+ uint32_t pte5 : 1;
+ uint32_t rw5 : 1;
+ uint32_t flk5 : 1;
+ uint32_t alk5 : 1;
+ uint32_t pte6 : 1;
+ uint32_t rw6 : 1;
+ uint32_t flk6 : 1;
+ uint32_t alk6 : 1;
+ uint32_t pte7 : 1;
+ uint32_t rw7 : 1;
+ uint32_t flk7 : 1;
+ uint32_t alk7 : 1;
+#else
+ uint32_t alk7 : 1;
+ uint32_t flk7 : 1;
+ uint32_t rw7 : 1;
+ uint32_t pte7 : 1;
+ uint32_t alk6 : 1;
+ uint32_t flk6 : 1;
+ uint32_t rw6 : 1;
+ uint32_t pte6 : 1;
+ uint32_t alk5 : 1;
+ uint32_t flk5 : 1;
+ uint32_t rw5 : 1;
+ uint32_t pte5 : 1;
+ uint32_t alk4 : 1;
+ uint32_t flk4 : 1;
+ uint32_t rw4 : 1;
+ uint32_t pte4 : 1;
+ uint32_t alk3 : 1;
+ uint32_t flk3 : 1;
+ uint32_t rw3 : 1;
+ uint32_t pte3 : 1;
+ uint32_t alk2 : 1;
+ uint32_t flk2 : 1;
+ uint32_t rw2 : 1;
+ uint32_t pte2 : 1;
+ uint32_t alk1 : 1;
+ uint32_t flk1 : 1;
+ uint32_t rw1 : 1;
+ uint32_t pte1 : 1;
+ uint32_t alk0 : 1;
+ uint32_t flk0 : 1;
+ uint32_t rw0 : 1;
+ uint32_t pte0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} plb_pesr_t;
+
+
+
+typedef union plb_pearl {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} plb_pearl_t;
+
+
+
+typedef union plb_pearh {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} plb_pearh_t;
+
+
+
+typedef union plb_sto_pesr {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t icu_te : 1;
+ uint32_t icu_rw : 1;
+ uint32_t reserved2 : 2;
+ uint32_t dcu_te : 1;
+ uint32_t dcu_rw : 1;
+ uint32_t reserved6 : 2;
+ uint32_t _reserved0 : 24;
+#else
+ uint32_t _reserved0 : 24;
+ uint32_t reserved6 : 2;
+ uint32_t dcu_rw : 1;
+ uint32_t dcu_te : 1;
+ uint32_t reserved2 : 2;
+ uint32_t icu_rw : 1;
+ uint32_t icu_te : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} plb_sto_pesr_t;
+
+
+
+typedef union plb_sto_pear {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t value : 32;
+#else
+ uint32_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} plb_sto_pear_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __PLB_ARBITER_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/plb_arbiter_register_addresses.h b/src/ssx/pgp/registers/plb_arbiter_register_addresses.h
new file mode 100755
index 0000000..2bc2f41
--- /dev/null
+++ b/src/ssx/pgp/registers/plb_arbiter_register_addresses.h
@@ -0,0 +1,28 @@
+#ifndef __PLB_ARBITER_REGISTER_ADDRESSES_H__
+#define __PLB_ARBITER_REGISTER_ADDRESSES_H__
+
+// $Id: plb_arbiter_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:24 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/plb_arbiter_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file plb_arbiter_register_addresses.h
+/// \brief Symbolic addresses for the PLB_ARBITER unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define PLB_DCR_BASE 0x90
+#define PLB_PREV 0x00000092
+#define PLB_PACR 0x00000093
+#define PLB_PESR 0x00000094
+#define PLB_PEARL 0x00000096
+#define PLB_PEARH 0x00000097
+#define PLB_STO_PESR 0x00000099
+#define PLB_STO_PEAR 0x00000098
+
+#endif // __PLB_ARBITER_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/pmc_firmware_registers.h b/src/ssx/pgp/registers/pmc_firmware_registers.h
new file mode 100755
index 0000000..76642a4
--- /dev/null
+++ b/src/ssx/pgp/registers/pmc_firmware_registers.h
@@ -0,0 +1,3140 @@
+#ifndef __PMC_FIRMWARE_REGISTERS_H__
+#define __PMC_FIRMWARE_REGISTERS_H__
+
+// $Id: pmc_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pmc_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pmc_firmware_registers.h
+/// \brief C register structs for the PMC unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union pmc_mode_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t enable_hw_pstate_mode : 1;
+ uint32_t enable_fw_auction_pstate_mode : 1;
+ uint32_t enable_fw_pstate_mode : 1;
+ uint32_t enable_pstate_voltage_changes : 1;
+ uint32_t enable_global_actual_pstate_forwarding : 1;
+ uint32_t halt_pstate_master_fsm : 1;
+ uint32_t enable_interchip_interface : 1;
+ uint32_t interchip_mode : 1;
+ uint32_t enable_interchip_pstate_in_haps : 1;
+ uint32_t enable_pstate_stepping : 1;
+ uint32_t honor_oha_idle_state_requests : 1;
+ uint32_t vid_endianess : 1;
+ uint32_t reset_all_pmc_registers : 1;
+ uint32_t safe_mode_without_spivid : 1;
+ uint32_t halt_idle_state_master_fsm : 1;
+ uint32_t interchip_halt_if : 1;
+ uint32_t unfreeze_pstate_processing : 1;
+ uint32_t spivid_reset_if : 1;
+ uint32_t unfreeze_istate_processing : 1;
+ uint32_t _reserved0 : 13;
+#else
+ uint32_t _reserved0 : 13;
+ uint32_t unfreeze_istate_processing : 1;
+ uint32_t spivid_reset_if : 1;
+ uint32_t unfreeze_pstate_processing : 1;
+ uint32_t interchip_halt_if : 1;
+ uint32_t halt_idle_state_master_fsm : 1;
+ uint32_t safe_mode_without_spivid : 1;
+ uint32_t reset_all_pmc_registers : 1;
+ uint32_t vid_endianess : 1;
+ uint32_t honor_oha_idle_state_requests : 1;
+ uint32_t enable_pstate_stepping : 1;
+ uint32_t enable_interchip_pstate_in_haps : 1;
+ uint32_t interchip_mode : 1;
+ uint32_t enable_interchip_interface : 1;
+ uint32_t halt_pstate_master_fsm : 1;
+ uint32_t enable_global_actual_pstate_forwarding : 1;
+ uint32_t enable_pstate_voltage_changes : 1;
+ uint32_t enable_fw_pstate_mode : 1;
+ uint32_t enable_fw_auction_pstate_mode : 1;
+ uint32_t enable_hw_pstate_mode : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_mode_reg_t;
+
+
+
+typedef union pmc_hardware_auction_pstate_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t haps : 8;
+ uint32_t kuv_actual : 8;
+ uint32_t kuv_received : 8;
+ uint32_t _reserved0 : 8;
+#else
+ uint32_t _reserved0 : 8;
+ uint32_t kuv_received : 8;
+ uint32_t kuv_actual : 8;
+ int32_t haps : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_hardware_auction_pstate_reg_t;
+
+
+
+typedef union pmc_pstate_monitor_and_ctrl_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t gpst_val : 8;
+ int32_t gpsst : 8;
+ int32_t gpsa : 8;
+ int32_t gapr : 8;
+#else
+ int32_t gapr : 8;
+ int32_t gpsa : 8;
+ int32_t gpsst : 8;
+ int32_t gpst_val : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pstate_monitor_and_ctrl_reg_t;
+
+
+
+typedef union pmc_rail_bounds_register {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t pmin_rail : 8;
+ int32_t pmax_rail : 8;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ int32_t pmax_rail : 8;
+ int32_t pmin_rail : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_rail_bounds_register_t;
+
+
+
+typedef union pmc_global_pstate_bounds_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t gpsi_min : 8;
+ uint32_t gpst_number_of_entries_minus_one : 7;
+ uint32_t _reserved0 : 17;
+#else
+ uint32_t _reserved0 : 17;
+ uint32_t gpst_number_of_entries_minus_one : 7;
+ uint32_t gpsi_min : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_global_pstate_bounds_reg_t;
+
+
+
+typedef union pmc_parameter_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pstate_stepsize : 7;
+ uint32_t vrm_stepdelay_range : 4;
+ uint32_t vrm_stepdelay_value : 4;
+ uint32_t hangpulse_predivider : 6;
+ uint32_t gpsa_timeout_value : 8;
+ uint32_t gpsa_timeout_value_sel : 1;
+ uint32_t _reserved0 : 2;
+#else
+ uint32_t _reserved0 : 2;
+ uint32_t gpsa_timeout_value_sel : 1;
+ uint32_t gpsa_timeout_value : 8;
+ uint32_t hangpulse_predivider : 6;
+ uint32_t vrm_stepdelay_value : 4;
+ uint32_t vrm_stepdelay_range : 4;
+ uint32_t pstate_stepsize : 7;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_parameter_reg0_t;
+
+
+
+typedef union pmc_parameter_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t ba_sram_pstate_table : 22;
+ int32_t pvsafe : 8;
+ uint32_t _reserved0 : 2;
+#else
+ uint32_t _reserved0 : 2;
+ int32_t pvsafe : 8;
+ uint32_t ba_sram_pstate_table : 22;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_parameter_reg1_t;
+
+
+
+typedef union pmc_eff_global_actual_voltage_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t maxreg_vdd : 8;
+ uint32_t maxreg_vcs : 8;
+ uint32_t eff_evid_vdd : 8;
+ uint32_t eff_evid_vcs : 8;
+#else
+ uint32_t eff_evid_vcs : 8;
+ uint32_t eff_evid_vdd : 8;
+ uint32_t maxreg_vcs : 8;
+ uint32_t maxreg_vdd : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_eff_global_actual_voltage_reg_t;
+
+
+
+typedef union pmc_global_actual_voltage_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t evid_vdd : 8;
+ uint32_t evid_vcs : 8;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t evid_vcs : 8;
+ uint32_t evid_vdd : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_global_actual_voltage_reg_t;
+
+
+
+typedef union pmc_status_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pstate_processing_is_suspended : 1;
+ uint32_t gpsa_bdcst_error : 1;
+ uint32_t gpsa_bdcst_resp_info : 3;
+ uint32_t gpsa_vchg_error : 1;
+ uint32_t gpsa_timeout_error : 1;
+ uint32_t gpsa_chg_ongoing : 1;
+ uint32_t volt_chg_ongoing : 1;
+ uint32_t brd_cst_ongoing : 1;
+ uint32_t gps_table_error : 1;
+ uint32_t pstate_interchip_error : 1;
+ uint32_t istate_processing_is_suspended : 1;
+ uint32_t safe_mode_engaged : 1;
+ uint32_t _reserved0 : 18;
+#else
+ uint32_t _reserved0 : 18;
+ uint32_t safe_mode_engaged : 1;
+ uint32_t istate_processing_is_suspended : 1;
+ uint32_t pstate_interchip_error : 1;
+ uint32_t gps_table_error : 1;
+ uint32_t brd_cst_ongoing : 1;
+ uint32_t volt_chg_ongoing : 1;
+ uint32_t gpsa_chg_ongoing : 1;
+ uint32_t gpsa_timeout_error : 1;
+ uint32_t gpsa_vchg_error : 1;
+ uint32_t gpsa_bdcst_resp_info : 3;
+ uint32_t gpsa_bdcst_error : 1;
+ uint32_t pstate_processing_is_suspended : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_status_reg_t;
+
+
+
+typedef union pmc_phase_enable_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t phase_enable : 4;
+ uint32_t _reserved0 : 28;
+#else
+ uint32_t _reserved0 : 28;
+ uint32_t phase_enable : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_phase_enable_reg_t;
+
+
+
+typedef union pmc_undervolting_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t puv_min : 8;
+ int32_t puv_max : 8;
+ uint32_t kuv_request : 8;
+ uint32_t _reserved0 : 8;
+#else
+ uint32_t _reserved0 : 8;
+ uint32_t kuv_request : 8;
+ int32_t puv_max : 8;
+ int32_t puv_min : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_undervolting_reg_t;
+
+
+
+typedef union pmc_core_deconfiguration_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t core_chiplet_deconf_vector : 16;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t core_chiplet_deconf_vector : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_core_deconfiguration_reg_t;
+
+
+
+typedef union pmc_intchp_ctrl_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t interchip_ga_fsm_enable : 1;
+ uint32_t interchip_recv_done_valid_without_if_en : 1;
+ uint32_t pmcic1_reserved_2 : 1;
+ uint32_t interchip_cpha : 1;
+ uint32_t interchip_clock_divider : 10;
+ uint32_t pmcicr1_reserved_14_17 : 4;
+ uint32_t pmcicr1_reserved_18_20 : 3;
+ uint32_t _reserved0 : 11;
+#else
+ uint32_t _reserved0 : 11;
+ uint32_t pmcicr1_reserved_18_20 : 3;
+ uint32_t pmcicr1_reserved_14_17 : 4;
+ uint32_t interchip_clock_divider : 10;
+ uint32_t interchip_cpha : 1;
+ uint32_t pmcic1_reserved_2 : 1;
+ uint32_t interchip_recv_done_valid_without_if_en : 1;
+ uint32_t interchip_ga_fsm_enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_ctrl_reg1_t;
+
+
+
+typedef union pmc_intchp_ctrl_reg2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t interchip_ping_send : 1;
+ uint32_t interchip_ping_detect_clear : 1;
+ uint32_t interchip_ping_mode : 1;
+ uint32_t pmcic2_reserved3 : 1;
+ uint32_t pmcic2_reserved4 : 1;
+ uint32_t pmcic2_reserved5_7 : 3;
+ uint32_t _reserved0 : 24;
+#else
+ uint32_t _reserved0 : 24;
+ uint32_t pmcic2_reserved5_7 : 3;
+ uint32_t pmcic2_reserved4 : 1;
+ uint32_t pmcic2_reserved3 : 1;
+ uint32_t interchip_ping_mode : 1;
+ uint32_t interchip_ping_detect_clear : 1;
+ uint32_t interchip_ping_send : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_ctrl_reg2_t;
+
+
+
+typedef union pmc_intchp_ctrl_reg4 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t interchip_ecc_gen_en : 1;
+ uint32_t interchip_ecc_check_en : 1;
+ uint32_t interchip_msg_rcv_overflow_check_en : 1;
+ uint32_t interchip_ecc_ue_block_en : 1;
+ uint32_t chksw_hw221732 : 1;
+ uint32_t slave_occ_timeout_forces_safe_mode_disable : 1;
+ uint32_t pmcic4_reserved6_7 : 2;
+ uint32_t _reserved0 : 24;
+#else
+ uint32_t _reserved0 : 24;
+ uint32_t pmcic4_reserved6_7 : 2;
+ uint32_t slave_occ_timeout_forces_safe_mode_disable : 1;
+ uint32_t chksw_hw221732 : 1;
+ uint32_t interchip_ecc_ue_block_en : 1;
+ uint32_t interchip_msg_rcv_overflow_check_en : 1;
+ uint32_t interchip_ecc_check_en : 1;
+ uint32_t interchip_ecc_gen_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_ctrl_reg4_t;
+
+
+
+typedef union pmc_intchp_status_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t interchip_ga_ongoing : 1;
+ uint32_t interchip_ecc_ue : 1;
+ uint32_t interchip_ecc_ce : 1;
+ uint32_t interchip_ping_detected : 1;
+ uint32_t interchip_ping_ack_detected : 1;
+ uint32_t interchip_msg_send_ongoing : 1;
+ uint32_t interchip_msg_recv_detected : 1;
+ uint32_t interchip_fsm_err : 1;
+ uint32_t interchip_ping_detect_count : 8;
+ uint32_t interchip_slave_error_code : 4;
+ uint32_t interchip_msg_snd_overflow_detected : 1;
+ uint32_t interchip_msg_rcv_overflow_detected : 1;
+ uint32_t interchip_ecc_ue_err : 1;
+ uint32_t _reserved0 : 9;
+#else
+ uint32_t _reserved0 : 9;
+ uint32_t interchip_ecc_ue_err : 1;
+ uint32_t interchip_msg_rcv_overflow_detected : 1;
+ uint32_t interchip_msg_snd_overflow_detected : 1;
+ uint32_t interchip_slave_error_code : 4;
+ uint32_t interchip_ping_detect_count : 8;
+ uint32_t interchip_fsm_err : 1;
+ uint32_t interchip_msg_recv_detected : 1;
+ uint32_t interchip_msg_send_ongoing : 1;
+ uint32_t interchip_ping_ack_detected : 1;
+ uint32_t interchip_ping_detected : 1;
+ uint32_t interchip_ecc_ce : 1;
+ uint32_t interchip_ecc_ue : 1;
+ uint32_t interchip_ga_ongoing : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_status_reg_t;
+
+
+
+typedef union pmc_intchp_command_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t interchip_reset_if : 1;
+ uint32_t interchip_halt_msg_fsm : 1;
+ uint32_t interchip_clear_sticky_bits : 1;
+ uint32_t _reserved0 : 29;
+#else
+ uint32_t _reserved0 : 29;
+ uint32_t interchip_clear_sticky_bits : 1;
+ uint32_t interchip_halt_msg_fsm : 1;
+ uint32_t interchip_reset_if : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_command_reg_t;
+
+
+
+typedef union pmc_intchp_msg_wdata {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t interchip_msg_wdata : 32;
+#else
+ uint32_t interchip_msg_wdata : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_msg_wdata_t;
+
+
+
+typedef union pmc_intchp_msg_rdata {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t interchip_msg_rdata : 32;
+#else
+ uint32_t interchip_msg_rdata : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_msg_rdata_t;
+
+
+
+typedef union pmc_intchp_pstate_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t pstate_interchip : 8;
+ uint32_t _reserved0 : 24;
+#else
+ uint32_t _reserved0 : 24;
+ int32_t pstate_interchip : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_pstate_reg_t;
+
+
+
+typedef union pmc_intchp_globack_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t gaack_interchip : 1;
+ int32_t gaack_interchip_pstate : 8;
+ uint32_t _reserved0 : 23;
+#else
+ uint32_t _reserved0 : 23;
+ int32_t gaack_interchip_pstate : 8;
+ uint32_t gaack_interchip : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_intchp_globack_reg_t;
+
+
+
+typedef union pmc_fsmstate_status_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t mis_fsm_state : 3;
+ uint32_t mps_fsm_state : 5;
+ uint32_t svs_fsm_state : 4;
+ uint32_t o2s_fsm_state : 4;
+ uint32_t m2p_fsm_state : 4;
+ uint32_t o2p_fsm_state : 4;
+ uint32_t icp_msg_fsm_state : 5;
+ uint32_t _reserved0 : 3;
+#else
+ uint32_t _reserved0 : 3;
+ uint32_t icp_msg_fsm_state : 5;
+ uint32_t o2p_fsm_state : 4;
+ uint32_t m2p_fsm_state : 4;
+ uint32_t o2s_fsm_state : 4;
+ uint32_t svs_fsm_state : 4;
+ uint32_t mps_fsm_state : 5;
+ uint32_t mis_fsm_state : 3;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_fsmstate_status_reg_t;
+
+
+
+typedef union pmc_trace_mode_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pmc_trace_mode : 4;
+ uint32_t trace_sel_data : 2;
+ uint32_t _reserved0 : 26;
+#else
+ uint32_t _reserved0 : 26;
+ uint32_t trace_sel_data : 2;
+ uint32_t pmc_trace_mode : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_trace_mode_reg_t;
+
+
+
+typedef union pmc_spiv_ctrl_reg0a {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_frame_size : 6;
+ uint32_t spivid_out_count1 : 6;
+ uint32_t spivid_in_delay1 : 6;
+ uint32_t spivid_in_count1 : 6;
+ uint32_t _reserved0 : 8;
+#else
+ uint32_t _reserved0 : 8;
+ uint32_t spivid_in_count1 : 6;
+ uint32_t spivid_in_delay1 : 6;
+ uint32_t spivid_out_count1 : 6;
+ uint32_t spivid_frame_size : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_ctrl_reg0a_t;
+
+
+
+typedef union pmc_spiv_ctrl_reg0b {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_out_count2 : 6;
+ uint32_t spivid_in_delay2 : 6;
+ uint32_t spivid_in_count2 : 6;
+ uint32_t _reserved0 : 14;
+#else
+ uint32_t _reserved0 : 14;
+ uint32_t spivid_in_count2 : 6;
+ uint32_t spivid_in_delay2 : 6;
+ uint32_t spivid_out_count2 : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_ctrl_reg0b_t;
+
+
+
+typedef union pmc_spiv_ctrl_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_fsm_enable : 1;
+ uint32_t pmcscr1_reserved_1 : 1;
+ uint32_t spivid_cpol : 1;
+ uint32_t spivid_cpha : 1;
+ uint32_t spivid_clock_divider : 10;
+ uint32_t pmcscr1_reserved_2 : 4;
+ uint32_t spivid_port_enable : 3;
+ uint32_t _reserved0 : 11;
+#else
+ uint32_t _reserved0 : 11;
+ uint32_t spivid_port_enable : 3;
+ uint32_t pmcscr1_reserved_2 : 4;
+ uint32_t spivid_clock_divider : 10;
+ uint32_t spivid_cpha : 1;
+ uint32_t spivid_cpol : 1;
+ uint32_t pmcscr1_reserved_1 : 1;
+ uint32_t spivid_fsm_enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_ctrl_reg1_t;
+
+
+
+typedef union pmc_spiv_ctrl_reg2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_inter_frame_delay_write_status : 17;
+ uint32_t _reserved0 : 15;
+#else
+ uint32_t _reserved0 : 15;
+ uint32_t spivid_inter_frame_delay_write_status : 17;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_ctrl_reg2_t;
+
+
+
+typedef union pmc_spiv_ctrl_reg3 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_inter_retry_delay : 17;
+ uint32_t pmc_100ns_pls_range : 6;
+ uint32_t _reserved0 : 9;
+#else
+ uint32_t _reserved0 : 9;
+ uint32_t pmc_100ns_pls_range : 6;
+ uint32_t spivid_inter_retry_delay : 17;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_ctrl_reg3_t;
+
+
+
+typedef union pmc_spiv_ctrl_reg4 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_crc_gen_en : 1;
+ uint32_t spivid_crc_check_en : 1;
+ uint32_t spivid_majority_vote_en : 1;
+ uint32_t spivid_max_retries : 5;
+ uint32_t spivid_crc_polynomial_enables : 8;
+ uint32_t spivid_crc_const_gen_enable : 1;
+ uint32_t spivid_crc_const_check_enable : 1;
+ uint32_t spivid_frame_sync_wrong_enable : 1;
+ uint32_t _reserved0 : 13;
+#else
+ uint32_t _reserved0 : 13;
+ uint32_t spivid_frame_sync_wrong_enable : 1;
+ uint32_t spivid_crc_const_check_enable : 1;
+ uint32_t spivid_crc_const_gen_enable : 1;
+ uint32_t spivid_crc_polynomial_enables : 8;
+ uint32_t spivid_max_retries : 5;
+ uint32_t spivid_majority_vote_en : 1;
+ uint32_t spivid_crc_check_en : 1;
+ uint32_t spivid_crc_gen_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_ctrl_reg4_t;
+
+
+
+typedef union pmc_spiv_status_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_ongoing : 1;
+ uint32_t spivid_crc_error0 : 1;
+ uint32_t spivid_crc_error1 : 1;
+ uint32_t spivid_crc_error2 : 1;
+ uint32_t spivid_retry_timeout : 1;
+ uint32_t pmcssr_reserved_1 : 2;
+ uint32_t spivid_fsm_err : 1;
+ uint32_t spivid_majority_detected_a_minority0 : 1;
+ uint32_t spivid_majority_detected_a_minority1 : 1;
+ uint32_t spivid_majority_detected_a_minority2 : 1;
+ uint32_t spivid_majority_nr_of_minorities0 : 4;
+ uint32_t spivid_majority_nr_of_minorities1 : 4;
+ uint32_t spivid_majority_nr_of_minorities2 : 4;
+ uint32_t _reserved0 : 9;
+#else
+ uint32_t _reserved0 : 9;
+ uint32_t spivid_majority_nr_of_minorities2 : 4;
+ uint32_t spivid_majority_nr_of_minorities1 : 4;
+ uint32_t spivid_majority_nr_of_minorities0 : 4;
+ uint32_t spivid_majority_detected_a_minority2 : 1;
+ uint32_t spivid_majority_detected_a_minority1 : 1;
+ uint32_t spivid_majority_detected_a_minority0 : 1;
+ uint32_t spivid_fsm_err : 1;
+ uint32_t pmcssr_reserved_1 : 2;
+ uint32_t spivid_retry_timeout : 1;
+ uint32_t spivid_crc_error2 : 1;
+ uint32_t spivid_crc_error1 : 1;
+ uint32_t spivid_crc_error0 : 1;
+ uint32_t spivid_ongoing : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_status_reg_t;
+
+
+
+typedef union pmc_spiv_command_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t spivid_halt_fsm : 1;
+ uint32_t _reserved0 : 31;
+#else
+ uint32_t _reserved0 : 31;
+ uint32_t spivid_halt_fsm : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_spiv_command_reg_t;
+
+
+
+typedef union pmc_o2s_ctrl_reg0a {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_frame_size : 6;
+ uint32_t o2s_out_count1 : 6;
+ uint32_t o2s_in_delay1 : 6;
+ uint32_t o2s_in_count1 : 6;
+ uint32_t _reserved0 : 8;
+#else
+ uint32_t _reserved0 : 8;
+ uint32_t o2s_in_count1 : 6;
+ uint32_t o2s_in_delay1 : 6;
+ uint32_t o2s_out_count1 : 6;
+ uint32_t o2s_frame_size : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_ctrl_reg0a_t;
+
+
+
+typedef union pmc_o2s_ctrl_reg0b {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_out_count2 : 6;
+ uint32_t o2s_in_delay2 : 6;
+ uint32_t o2s_in_count2 : 6;
+ uint32_t _reserved0 : 14;
+#else
+ uint32_t _reserved0 : 14;
+ uint32_t o2s_in_count2 : 6;
+ uint32_t o2s_in_delay2 : 6;
+ uint32_t o2s_out_count2 : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_ctrl_reg0b_t;
+
+
+
+typedef union pmc_o2s_ctrl_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_bridge_enable : 1;
+ uint32_t pmcocr1_reserved_1 : 1;
+ uint32_t o2s_cpol : 1;
+ uint32_t o2s_cpha : 1;
+ uint32_t o2s_clock_divider : 10;
+ uint32_t pmcocr1_reserved_2 : 3;
+ uint32_t o2s_nr_of_frames : 1;
+ uint32_t o2s_port_enable : 3;
+ uint32_t _reserved0 : 11;
+#else
+ uint32_t _reserved0 : 11;
+ uint32_t o2s_port_enable : 3;
+ uint32_t o2s_nr_of_frames : 1;
+ uint32_t pmcocr1_reserved_2 : 3;
+ uint32_t o2s_clock_divider : 10;
+ uint32_t o2s_cpha : 1;
+ uint32_t o2s_cpol : 1;
+ uint32_t pmcocr1_reserved_1 : 1;
+ uint32_t o2s_bridge_enable : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_ctrl_reg1_t;
+
+
+
+typedef union pmc_o2s_ctrl_reg2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_inter_frame_delay : 17;
+ uint32_t _reserved0 : 15;
+#else
+ uint32_t _reserved0 : 15;
+ uint32_t o2s_inter_frame_delay : 17;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_ctrl_reg2_t;
+
+
+
+typedef union pmc_o2s_ctrl_reg4 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_crc_gen_en : 1;
+ uint32_t o2s_crc_check_en : 1;
+ uint32_t o2s_majority_vote_en : 1;
+ uint32_t o2s_max_retries : 5;
+ uint32_t pmcocr4_reserved8_15 : 8;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t pmcocr4_reserved8_15 : 8;
+ uint32_t o2s_max_retries : 5;
+ uint32_t o2s_majority_vote_en : 1;
+ uint32_t o2s_crc_check_en : 1;
+ uint32_t o2s_crc_gen_en : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_ctrl_reg4_t;
+
+
+
+typedef union pmc_o2s_status_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_ongoing : 1;
+ uint32_t o2s_crc_error0 : 1;
+ uint32_t o2s_crc_error1 : 1;
+ uint32_t o2s_crc_error2 : 1;
+ uint32_t o2s_retry_timeout : 1;
+ uint32_t o2s_write_while_bridge_busy_err : 1;
+ uint32_t pmcosr_reserved_6 : 1;
+ uint32_t o2s_fsm_err : 1;
+ uint32_t o2s_majority_detected_a_minority0 : 1;
+ uint32_t o2s_majority_detected_a_minority1 : 1;
+ uint32_t o2s_majority_detected_a_minority2 : 1;
+ uint32_t o2s_majority_nr_of_minorities0 : 4;
+ uint32_t o2s_majority_nr_of_minorities1 : 4;
+ uint32_t o2s_majority_nr_of_minorities2 : 4;
+ uint32_t _reserved0 : 9;
+#else
+ uint32_t _reserved0 : 9;
+ uint32_t o2s_majority_nr_of_minorities2 : 4;
+ uint32_t o2s_majority_nr_of_minorities1 : 4;
+ uint32_t o2s_majority_nr_of_minorities0 : 4;
+ uint32_t o2s_majority_detected_a_minority2 : 1;
+ uint32_t o2s_majority_detected_a_minority1 : 1;
+ uint32_t o2s_majority_detected_a_minority0 : 1;
+ uint32_t o2s_fsm_err : 1;
+ uint32_t pmcosr_reserved_6 : 1;
+ uint32_t o2s_write_while_bridge_busy_err : 1;
+ uint32_t o2s_retry_timeout : 1;
+ uint32_t o2s_crc_error2 : 1;
+ uint32_t o2s_crc_error1 : 1;
+ uint32_t o2s_crc_error0 : 1;
+ uint32_t o2s_ongoing : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_status_reg_t;
+
+
+
+typedef union pmc_o2s_command_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_halt_retries : 1;
+ uint32_t o2s_clear_sticky_bits : 1;
+ uint32_t _reserved0 : 30;
+#else
+ uint32_t _reserved0 : 30;
+ uint32_t o2s_clear_sticky_bits : 1;
+ uint32_t o2s_halt_retries : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_command_reg_t;
+
+
+
+typedef union pmc_o2s_wdata_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_wdata : 32;
+#else
+ uint32_t o2s_wdata : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_wdata_reg_t;
+
+
+
+typedef union pmc_o2s_rdata_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2s_rdata : 32;
+#else
+ uint32_t o2s_rdata : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2s_rdata_reg_t;
+
+
+
+typedef union pmc_o2p_addr_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2p_write_plus_read : 1;
+ uint32_t o2p_mc : 1;
+ uint32_t o2p_slave_addr : 6;
+ uint32_t o2p_read_not_write : 1;
+ uint32_t reserved_bit_pmco2par2 : 3;
+ uint32_t o2p_pcb_port : 4;
+ uint32_t o2p_pcb_reg_addr : 16;
+#else
+ uint32_t o2p_pcb_reg_addr : 16;
+ uint32_t o2p_pcb_port : 4;
+ uint32_t reserved_bit_pmco2par2 : 3;
+ uint32_t o2p_read_not_write : 1;
+ uint32_t o2p_slave_addr : 6;
+ uint32_t o2p_mc : 1;
+ uint32_t o2p_write_plus_read : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2p_addr_reg_t;
+
+
+
+typedef union pmc_o2p_ctrl_status_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2p_ongoing : 1;
+ uint32_t o2p_scresp : 3;
+ uint32_t o2p_write_while_bridge_busy_err : 1;
+ uint32_t o2p_fsm_err : 1;
+ uint32_t o2p_abort : 1;
+ uint32_t o2p_parity_error : 1;
+ uint32_t o2p_clear_sticky_bits : 1;
+ uint32_t _reserved0 : 23;
+#else
+ uint32_t _reserved0 : 23;
+ uint32_t o2p_clear_sticky_bits : 1;
+ uint32_t o2p_parity_error : 1;
+ uint32_t o2p_abort : 1;
+ uint32_t o2p_fsm_err : 1;
+ uint32_t o2p_write_while_bridge_busy_err : 1;
+ uint32_t o2p_scresp : 3;
+ uint32_t o2p_ongoing : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2p_ctrl_status_reg_t;
+
+
+
+typedef union pmc_o2p_send_data_hi_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2p_send_data_hi : 32;
+#else
+ uint32_t o2p_send_data_hi : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2p_send_data_hi_reg_t;
+
+
+
+typedef union pmc_o2p_send_data_lo_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2p_send_data_lo : 32;
+#else
+ uint32_t o2p_send_data_lo : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2p_send_data_lo_reg_t;
+
+
+
+typedef union pmc_o2p_recv_data_hi_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2p_receive_data_hi : 32;
+#else
+ uint32_t o2p_receive_data_hi : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2p_recv_data_hi_reg_t;
+
+
+
+typedef union pmc_o2p_recv_data_lo_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t o2p_receive_data_lo : 32;
+#else
+ uint32_t o2p_receive_data_lo : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_o2p_recv_data_lo_reg_t;
+
+
+
+typedef union pmc_occ_heartbeat_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pmc_occ_heartbeat_time : 16;
+ uint32_t pmc_occ_heartbeat_en : 1;
+ uint32_t _reserved0 : 15;
+#else
+ uint32_t _reserved0 : 15;
+ uint32_t pmc_occ_heartbeat_en : 1;
+ uint32_t pmc_occ_heartbeat_time : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_occ_heartbeat_reg_t;
+
+
+
+typedef union pmc_error_int_mask_hi_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pmc_error_int_mask_hi : 32;
+#else
+ uint32_t pmc_error_int_mask_hi : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_error_int_mask_hi_reg_t;
+
+
+
+typedef union pmc_error_int_mask_lo_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pmc_error_int_mask_lo : 32;
+#else
+ uint32_t pmc_error_int_mask_lo : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_error_int_mask_lo_reg_t;
+
+
+
+typedef union pmc_idle_suspend_mask_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pmc_idle_suspend_mask : 16;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t pmc_idle_suspend_mask : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_idle_suspend_mask_reg_t;
+
+
+
+typedef union pmc_pend_idle_req_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t idle_pending_0 : 1;
+ uint32_t idle_op_0 : 2;
+ uint32_t idle_type_0 : 1;
+ uint32_t idle_scope_0 : 1;
+ uint32_t assist_mode_0 : 1;
+ uint32_t reserved_pirr_0 : 2;
+ uint32_t idle_pending_1 : 1;
+ uint32_t idle_op_1 : 2;
+ uint32_t idle_type_1 : 1;
+ uint32_t idle_scope_1 : 1;
+ uint32_t assist_mode_1 : 1;
+ uint32_t reserved_pirr_1 : 2;
+ uint32_t idle_pending_2 : 1;
+ uint32_t idle_op_2 : 2;
+ uint32_t idle_type_2 : 1;
+ uint32_t idle_scope_2 : 1;
+ uint32_t assist_mode_2 : 1;
+ uint32_t reserved_pirr_2 : 2;
+ uint32_t idle_pending_3 : 1;
+ uint32_t idle_op_3 : 2;
+ uint32_t idle_type_3 : 1;
+ uint32_t idle_scope_3 : 1;
+ uint32_t assist_mode_3 : 1;
+ uint32_t reserved_pirr_3 : 2;
+#else
+ uint32_t reserved_pirr_3 : 2;
+ uint32_t assist_mode_3 : 1;
+ uint32_t idle_scope_3 : 1;
+ uint32_t idle_type_3 : 1;
+ uint32_t idle_op_3 : 2;
+ uint32_t idle_pending_3 : 1;
+ uint32_t reserved_pirr_2 : 2;
+ uint32_t assist_mode_2 : 1;
+ uint32_t idle_scope_2 : 1;
+ uint32_t idle_type_2 : 1;
+ uint32_t idle_op_2 : 2;
+ uint32_t idle_pending_2 : 1;
+ uint32_t reserved_pirr_1 : 2;
+ uint32_t assist_mode_1 : 1;
+ uint32_t idle_scope_1 : 1;
+ uint32_t idle_type_1 : 1;
+ uint32_t idle_op_1 : 2;
+ uint32_t idle_pending_1 : 1;
+ uint32_t reserved_pirr_0 : 2;
+ uint32_t assist_mode_0 : 1;
+ uint32_t idle_scope_0 : 1;
+ uint32_t idle_type_0 : 1;
+ uint32_t idle_op_0 : 2;
+ uint32_t idle_pending_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pend_idle_req_reg0_t;
+
+
+
+typedef union pmc_pend_idle_req_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t idle_pending_4 : 1;
+ uint32_t idle_op_4 : 2;
+ uint32_t idle_type_4 : 1;
+ uint32_t idle_scope_4 : 1;
+ uint32_t assist_mode_4 : 1;
+ uint32_t reserved_pirr_4 : 2;
+ uint32_t idle_pending_5 : 1;
+ uint32_t idle_op_5 : 2;
+ uint32_t idle_type_5 : 1;
+ uint32_t idle_scope_5 : 1;
+ uint32_t assist_mode_5 : 1;
+ uint32_t reserved_pirr_5 : 2;
+ uint32_t idle_pending_6 : 1;
+ uint32_t idle_op_6 : 2;
+ uint32_t idle_type_6 : 1;
+ uint32_t idle_scope_6 : 1;
+ uint32_t assist_mode_6 : 1;
+ uint32_t reserved_pirr_6 : 2;
+ uint32_t idle_pending_7 : 1;
+ uint32_t idle_op_7 : 2;
+ uint32_t idle_type_7 : 1;
+ uint32_t idle_scope_7 : 1;
+ uint32_t assist_mode_7 : 1;
+ uint32_t reserved_pirr_7 : 2;
+#else
+ uint32_t reserved_pirr_7 : 2;
+ uint32_t assist_mode_7 : 1;
+ uint32_t idle_scope_7 : 1;
+ uint32_t idle_type_7 : 1;
+ uint32_t idle_op_7 : 2;
+ uint32_t idle_pending_7 : 1;
+ uint32_t reserved_pirr_6 : 2;
+ uint32_t assist_mode_6 : 1;
+ uint32_t idle_scope_6 : 1;
+ uint32_t idle_type_6 : 1;
+ uint32_t idle_op_6 : 2;
+ uint32_t idle_pending_6 : 1;
+ uint32_t reserved_pirr_5 : 2;
+ uint32_t assist_mode_5 : 1;
+ uint32_t idle_scope_5 : 1;
+ uint32_t idle_type_5 : 1;
+ uint32_t idle_op_5 : 2;
+ uint32_t idle_pending_5 : 1;
+ uint32_t reserved_pirr_4 : 2;
+ uint32_t assist_mode_4 : 1;
+ uint32_t idle_scope_4 : 1;
+ uint32_t idle_type_4 : 1;
+ uint32_t idle_op_4 : 2;
+ uint32_t idle_pending_4 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pend_idle_req_reg1_t;
+
+
+
+typedef union pmc_pend_idle_req_reg2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t idle_pending_8 : 1;
+ uint32_t idle_op_8 : 2;
+ uint32_t idle_type_8 : 1;
+ uint32_t idle_scope_8 : 1;
+ uint32_t assist_mode_8 : 1;
+ uint32_t reserved_pirr_8 : 2;
+ uint32_t idle_pending_9 : 1;
+ uint32_t idle_op_9 : 2;
+ uint32_t idle_type_9 : 1;
+ uint32_t idle_scope_9 : 1;
+ uint32_t assist_mode_9 : 1;
+ uint32_t reserved_pirr_9 : 2;
+ uint32_t idle_pending_10 : 1;
+ uint32_t idle_op_10 : 2;
+ uint32_t idle_type_10 : 1;
+ uint32_t idle_scope_10 : 1;
+ uint32_t assist_mode_10 : 1;
+ uint32_t reserved_pirr_10 : 2;
+ uint32_t idle_pending_11 : 1;
+ uint32_t idle_op_11 : 2;
+ uint32_t idle_type_11 : 1;
+ uint32_t idle_scope_11 : 1;
+ uint32_t assist_mode_11 : 1;
+ uint32_t reserved_pirr_11 : 2;
+#else
+ uint32_t reserved_pirr_11 : 2;
+ uint32_t assist_mode_11 : 1;
+ uint32_t idle_scope_11 : 1;
+ uint32_t idle_type_11 : 1;
+ uint32_t idle_op_11 : 2;
+ uint32_t idle_pending_11 : 1;
+ uint32_t reserved_pirr_10 : 2;
+ uint32_t assist_mode_10 : 1;
+ uint32_t idle_scope_10 : 1;
+ uint32_t idle_type_10 : 1;
+ uint32_t idle_op_10 : 2;
+ uint32_t idle_pending_10 : 1;
+ uint32_t reserved_pirr_9 : 2;
+ uint32_t assist_mode_9 : 1;
+ uint32_t idle_scope_9 : 1;
+ uint32_t idle_type_9 : 1;
+ uint32_t idle_op_9 : 2;
+ uint32_t idle_pending_9 : 1;
+ uint32_t reserved_pirr_8 : 2;
+ uint32_t assist_mode_8 : 1;
+ uint32_t idle_scope_8 : 1;
+ uint32_t idle_type_8 : 1;
+ uint32_t idle_op_8 : 2;
+ uint32_t idle_pending_8 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pend_idle_req_reg2_t;
+
+
+
+typedef union pmc_pend_idle_req_reg3 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t idle_pending_12 : 1;
+ uint32_t idle_op_12 : 2;
+ uint32_t idle_type_12 : 1;
+ uint32_t idle_scope_12 : 1;
+ uint32_t assist_mode_12 : 1;
+ uint32_t reserved_pirr_12 : 2;
+ uint32_t idle_pending_13 : 1;
+ uint32_t idle_op_13 : 2;
+ uint32_t idle_type_13 : 1;
+ uint32_t idle_scope_13 : 1;
+ uint32_t assist_mode_13 : 1;
+ uint32_t reserved_pirr_13 : 2;
+ uint32_t idle_pending_14 : 1;
+ uint32_t idle_op_14 : 2;
+ uint32_t idle_type_14 : 1;
+ uint32_t idle_scope_14 : 1;
+ uint32_t assist_mode_14 : 1;
+ uint32_t reserved_pirr_14 : 2;
+ uint32_t idle_pending_15 : 1;
+ uint32_t idle_op_15 : 2;
+ uint32_t idle_type_15 : 1;
+ uint32_t idle_scope_15 : 1;
+ uint32_t assist_mode_15 : 1;
+ uint32_t reserved_pirr_15 : 2;
+#else
+ uint32_t reserved_pirr_15 : 2;
+ uint32_t assist_mode_15 : 1;
+ uint32_t idle_scope_15 : 1;
+ uint32_t idle_type_15 : 1;
+ uint32_t idle_op_15 : 2;
+ uint32_t idle_pending_15 : 1;
+ uint32_t reserved_pirr_14 : 2;
+ uint32_t assist_mode_14 : 1;
+ uint32_t idle_scope_14 : 1;
+ uint32_t idle_type_14 : 1;
+ uint32_t idle_op_14 : 2;
+ uint32_t idle_pending_14 : 1;
+ uint32_t reserved_pirr_13 : 2;
+ uint32_t assist_mode_13 : 1;
+ uint32_t idle_scope_13 : 1;
+ uint32_t idle_type_13 : 1;
+ uint32_t idle_op_13 : 2;
+ uint32_t idle_pending_13 : 1;
+ uint32_t reserved_pirr_12 : 2;
+ uint32_t assist_mode_12 : 1;
+ uint32_t idle_scope_12 : 1;
+ uint32_t idle_type_12 : 1;
+ uint32_t idle_op_12 : 2;
+ uint32_t idle_pending_12 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pend_idle_req_reg3_t;
+
+
+
+typedef union pmc_sleep_int_req_vec_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t fastsleepentry_int_req_vec : 32;
+#else
+ uint32_t fastsleepentry_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_sleep_int_req_vec_reg0_t;
+
+
+
+typedef union pmc_sleep_int_req_vec_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t deepsleepentry_int_req_vec : 32;
+#else
+ uint32_t deepsleepentry_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_sleep_int_req_vec_reg1_t;
+
+
+
+typedef union pmc_sleep_int_req_vec_reg2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t fastsleepexit_int_req_vec : 32;
+#else
+ uint32_t fastsleepexit_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_sleep_int_req_vec_reg2_t;
+
+
+
+typedef union pmc_sleep_int_req_vec_reg3 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t deepsleepexit_int_req_vec : 32;
+#else
+ uint32_t deepsleepexit_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_sleep_int_req_vec_reg3_t;
+
+
+
+typedef union pmc_winkle_int_req_vec_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t fastwinkleentry_int_req_vec : 32;
+#else
+ uint32_t fastwinkleentry_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_winkle_int_req_vec_reg0_t;
+
+
+
+typedef union pmc_winkle_int_req_vec_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t deepwinkleentry_int_req_vec : 32;
+#else
+ uint32_t deepwinkleentry_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_winkle_int_req_vec_reg1_t;
+
+
+
+typedef union pmc_winkle_int_req_vec_reg2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t fastwinkleexit_int_req_vec : 32;
+#else
+ uint32_t fastwinkleexit_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_winkle_int_req_vec_reg2_t;
+
+
+
+typedef union pmc_winkle_int_req_vec_reg3 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t deepwinkleexit_int_req_vec : 32;
+#else
+ uint32_t deepwinkleexit_int_req_vec : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_winkle_int_req_vec_reg3_t;
+
+
+
+typedef union pmc_nap_int_req_vec_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t napentry_int_req_vec : 16;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t napentry_int_req_vec : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_nap_int_req_vec_reg0_t;
+
+
+
+typedef union pmc_nap_int_req_vec_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t napexit_int_req_vec : 25;
+ uint32_t _reserved0 : 7;
+#else
+ uint32_t _reserved0 : 7;
+ uint32_t napexit_int_req_vec : 25;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_nap_int_req_vec_reg1_t;
+
+
+
+typedef union pmc_pore_req_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t porrr_reserved0 : 8;
+ uint32_t porrr_start_vector : 4;
+ uint32_t porrr_reserved1 : 8;
+ uint32_t porrr_pore_busy : 1;
+ uint32_t porrr_pore_suspended : 1;
+ uint32_t porrr_porrtc_busy : 1;
+ uint32_t _reserved0 : 9;
+#else
+ uint32_t _reserved0 : 9;
+ uint32_t porrr_porrtc_busy : 1;
+ uint32_t porrr_pore_suspended : 1;
+ uint32_t porrr_pore_busy : 1;
+ uint32_t porrr_reserved1 : 8;
+ uint32_t porrr_start_vector : 4;
+ uint32_t porrr_reserved0 : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pore_req_reg0_t;
+
+
+
+typedef union pmc_pore_req_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t porrr_chiplet_enable_0 : 1;
+ uint32_t porrr_chiplet_enable_1 : 1;
+ uint32_t porrr_chiplet_enable_2 : 1;
+ uint32_t porrr_chiplet_enable_3 : 1;
+ uint32_t porrr_chiplet_enable_4 : 1;
+ uint32_t porrr_chiplet_enable_5 : 1;
+ uint32_t porrr_chiplet_enable_6 : 1;
+ uint32_t porrr_chiplet_enable_7 : 1;
+ uint32_t porrr_chiplet_enable_8 : 1;
+ uint32_t porrr_chiplet_enable_9 : 1;
+ uint32_t porrr_chiplet_enable_10 : 1;
+ uint32_t porrr_chiplet_enable_11 : 1;
+ uint32_t porrr_chiplet_enable_12 : 1;
+ uint32_t porrr_chiplet_enable_13 : 1;
+ uint32_t porrr_chiplet_enable_14 : 1;
+ uint32_t porrr_chiplet_enable_15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t porrr_chiplet_enable_15 : 1;
+ uint32_t porrr_chiplet_enable_14 : 1;
+ uint32_t porrr_chiplet_enable_13 : 1;
+ uint32_t porrr_chiplet_enable_12 : 1;
+ uint32_t porrr_chiplet_enable_11 : 1;
+ uint32_t porrr_chiplet_enable_10 : 1;
+ uint32_t porrr_chiplet_enable_9 : 1;
+ uint32_t porrr_chiplet_enable_8 : 1;
+ uint32_t porrr_chiplet_enable_7 : 1;
+ uint32_t porrr_chiplet_enable_6 : 1;
+ uint32_t porrr_chiplet_enable_5 : 1;
+ uint32_t porrr_chiplet_enable_4 : 1;
+ uint32_t porrr_chiplet_enable_3 : 1;
+ uint32_t porrr_chiplet_enable_2 : 1;
+ uint32_t porrr_chiplet_enable_1 : 1;
+ uint32_t porrr_chiplet_enable_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pore_req_reg1_t;
+
+
+
+typedef union pmc_pore_req_stat_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t porrs_reserved0 : 8;
+ uint32_t porrs_start_vector : 4;
+ uint32_t pore_rc : 8;
+ uint32_t porrs_reserved1 : 1;
+ uint32_t porrs_recovery_write : 1;
+ uint32_t _reserved0 : 10;
+#else
+ uint32_t _reserved0 : 10;
+ uint32_t porrs_recovery_write : 1;
+ uint32_t porrs_reserved1 : 1;
+ uint32_t pore_rc : 8;
+ uint32_t porrs_start_vector : 4;
+ uint32_t porrs_reserved0 : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pore_req_stat_reg_t;
+
+
+
+typedef union pmc_pore_req_tout_th_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t porrtt_timeout_threshold : 8;
+ uint32_t porrtc_no_predivide : 1;
+ uint32_t _reserved0 : 23;
+#else
+ uint32_t _reserved0 : 23;
+ uint32_t porrtc_no_predivide : 1;
+ uint32_t porrtt_timeout_threshold : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pore_req_tout_th_reg_t;
+
+
+
+typedef union pmc_deep_exit_mask_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t chiplet_deep_exit_mask0 : 1;
+ uint32_t chiplet_deep_exit_mask1 : 1;
+ uint32_t chiplet_deep_exit_mask2 : 1;
+ uint32_t chiplet_deep_exit_mask3 : 1;
+ uint32_t chiplet_deep_exit_mask4 : 1;
+ uint32_t chiplet_deep_exit_mask5 : 1;
+ uint32_t chiplet_deep_exit_mask6 : 1;
+ uint32_t chiplet_deep_exit_mask7 : 1;
+ uint32_t chiplet_deep_exit_mask8 : 1;
+ uint32_t chiplet_deep_exit_mask9 : 1;
+ uint32_t chiplet_deep_exit_mask10 : 1;
+ uint32_t chiplet_deep_exit_mask11 : 1;
+ uint32_t chiplet_deep_exit_mask12 : 1;
+ uint32_t chiplet_deep_exit_mask13 : 1;
+ uint32_t chiplet_deep_exit_mask14 : 1;
+ uint32_t chiplet_deep_exit_mask15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t chiplet_deep_exit_mask15 : 1;
+ uint32_t chiplet_deep_exit_mask14 : 1;
+ uint32_t chiplet_deep_exit_mask13 : 1;
+ uint32_t chiplet_deep_exit_mask12 : 1;
+ uint32_t chiplet_deep_exit_mask11 : 1;
+ uint32_t chiplet_deep_exit_mask10 : 1;
+ uint32_t chiplet_deep_exit_mask9 : 1;
+ uint32_t chiplet_deep_exit_mask8 : 1;
+ uint32_t chiplet_deep_exit_mask7 : 1;
+ uint32_t chiplet_deep_exit_mask6 : 1;
+ uint32_t chiplet_deep_exit_mask5 : 1;
+ uint32_t chiplet_deep_exit_mask4 : 1;
+ uint32_t chiplet_deep_exit_mask3 : 1;
+ uint32_t chiplet_deep_exit_mask2 : 1;
+ uint32_t chiplet_deep_exit_mask1 : 1;
+ uint32_t chiplet_deep_exit_mask0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_deep_exit_mask_reg_t;
+
+
+
+typedef union pmc_deep_exit_mask_reg_and {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t chiplet_deep_exit_mask0 : 1;
+ uint32_t chiplet_deep_exit_mask1 : 1;
+ uint32_t chiplet_deep_exit_mask2 : 1;
+ uint32_t chiplet_deep_exit_mask3 : 1;
+ uint32_t chiplet_deep_exit_mask4 : 1;
+ uint32_t chiplet_deep_exit_mask5 : 1;
+ uint32_t chiplet_deep_exit_mask6 : 1;
+ uint32_t chiplet_deep_exit_mask7 : 1;
+ uint32_t chiplet_deep_exit_mask8 : 1;
+ uint32_t chiplet_deep_exit_mask9 : 1;
+ uint32_t chiplet_deep_exit_mask10 : 1;
+ uint32_t chiplet_deep_exit_mask11 : 1;
+ uint32_t chiplet_deep_exit_mask12 : 1;
+ uint32_t chiplet_deep_exit_mask13 : 1;
+ uint32_t chiplet_deep_exit_mask14 : 1;
+ uint32_t chiplet_deep_exit_mask15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t chiplet_deep_exit_mask15 : 1;
+ uint32_t chiplet_deep_exit_mask14 : 1;
+ uint32_t chiplet_deep_exit_mask13 : 1;
+ uint32_t chiplet_deep_exit_mask12 : 1;
+ uint32_t chiplet_deep_exit_mask11 : 1;
+ uint32_t chiplet_deep_exit_mask10 : 1;
+ uint32_t chiplet_deep_exit_mask9 : 1;
+ uint32_t chiplet_deep_exit_mask8 : 1;
+ uint32_t chiplet_deep_exit_mask7 : 1;
+ uint32_t chiplet_deep_exit_mask6 : 1;
+ uint32_t chiplet_deep_exit_mask5 : 1;
+ uint32_t chiplet_deep_exit_mask4 : 1;
+ uint32_t chiplet_deep_exit_mask3 : 1;
+ uint32_t chiplet_deep_exit_mask2 : 1;
+ uint32_t chiplet_deep_exit_mask1 : 1;
+ uint32_t chiplet_deep_exit_mask0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_deep_exit_mask_reg_and_t;
+
+
+
+typedef union pmc_deep_exit_mask_reg_or {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t chiplet_deep_exit_mask0 : 1;
+ uint32_t chiplet_deep_exit_mask1 : 1;
+ uint32_t chiplet_deep_exit_mask2 : 1;
+ uint32_t chiplet_deep_exit_mask3 : 1;
+ uint32_t chiplet_deep_exit_mask4 : 1;
+ uint32_t chiplet_deep_exit_mask5 : 1;
+ uint32_t chiplet_deep_exit_mask6 : 1;
+ uint32_t chiplet_deep_exit_mask7 : 1;
+ uint32_t chiplet_deep_exit_mask8 : 1;
+ uint32_t chiplet_deep_exit_mask9 : 1;
+ uint32_t chiplet_deep_exit_mask10 : 1;
+ uint32_t chiplet_deep_exit_mask11 : 1;
+ uint32_t chiplet_deep_exit_mask12 : 1;
+ uint32_t chiplet_deep_exit_mask13 : 1;
+ uint32_t chiplet_deep_exit_mask14 : 1;
+ uint32_t chiplet_deep_exit_mask15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t chiplet_deep_exit_mask15 : 1;
+ uint32_t chiplet_deep_exit_mask14 : 1;
+ uint32_t chiplet_deep_exit_mask13 : 1;
+ uint32_t chiplet_deep_exit_mask12 : 1;
+ uint32_t chiplet_deep_exit_mask11 : 1;
+ uint32_t chiplet_deep_exit_mask10 : 1;
+ uint32_t chiplet_deep_exit_mask9 : 1;
+ uint32_t chiplet_deep_exit_mask8 : 1;
+ uint32_t chiplet_deep_exit_mask7 : 1;
+ uint32_t chiplet_deep_exit_mask6 : 1;
+ uint32_t chiplet_deep_exit_mask5 : 1;
+ uint32_t chiplet_deep_exit_mask4 : 1;
+ uint32_t chiplet_deep_exit_mask3 : 1;
+ uint32_t chiplet_deep_exit_mask2 : 1;
+ uint32_t chiplet_deep_exit_mask1 : 1;
+ uint32_t chiplet_deep_exit_mask0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_deep_exit_mask_reg_or_t;
+
+
+
+typedef union pmc_core_pstate_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t pstate_core0 : 8;
+ int32_t pstate_core1 : 8;
+ int32_t pstate_core2 : 8;
+ int32_t pstate_core3 : 8;
+#else
+ int32_t pstate_core3 : 8;
+ int32_t pstate_core2 : 8;
+ int32_t pstate_core1 : 8;
+ int32_t pstate_core0 : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_core_pstate_reg0_t;
+
+
+
+typedef union pmc_core_pstate_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t pstate_core4 : 8;
+ int32_t pstate_core5 : 8;
+ int32_t pstate_core6 : 8;
+ int32_t pstate_core7 : 8;
+#else
+ int32_t pstate_core7 : 8;
+ int32_t pstate_core6 : 8;
+ int32_t pstate_core5 : 8;
+ int32_t pstate_core4 : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_core_pstate_reg1_t;
+
+
+
+typedef union pmc_core_pstate_reg2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t pstate_core8 : 8;
+ int32_t pstate_core9 : 8;
+ int32_t pstate_core10 : 8;
+ int32_t pstate_core11 : 8;
+#else
+ int32_t pstate_core11 : 8;
+ int32_t pstate_core10 : 8;
+ int32_t pstate_core9 : 8;
+ int32_t pstate_core8 : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_core_pstate_reg2_t;
+
+
+
+typedef union pmc_core_pstate_reg3 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ int32_t pstate_core12 : 8;
+ int32_t pstate_core13 : 8;
+ int32_t pstate_core14 : 8;
+ int32_t pstate_core15 : 8;
+#else
+ int32_t pstate_core15 : 8;
+ int32_t pstate_core14 : 8;
+ int32_t pstate_core13 : 8;
+ int32_t pstate_core12 : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_core_pstate_reg3_t;
+
+
+
+typedef union pmc_core_power_donation_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t power_donation_core0 : 1;
+ uint32_t power_donation_core1 : 1;
+ uint32_t power_donation_core2 : 1;
+ uint32_t power_donation_core3 : 1;
+ uint32_t power_donation_core4 : 1;
+ uint32_t power_donation_core5 : 1;
+ uint32_t power_donation_core6 : 1;
+ uint32_t power_donation_core7 : 1;
+ uint32_t power_donation_core8 : 1;
+ uint32_t power_donation_core9 : 1;
+ uint32_t power_donation_core10 : 1;
+ uint32_t power_donation_core11 : 1;
+ uint32_t power_donation_core12 : 1;
+ uint32_t power_donation_core13 : 1;
+ uint32_t power_donation_core14 : 1;
+ uint32_t power_donation_core15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t power_donation_core15 : 1;
+ uint32_t power_donation_core14 : 1;
+ uint32_t power_donation_core13 : 1;
+ uint32_t power_donation_core12 : 1;
+ uint32_t power_donation_core11 : 1;
+ uint32_t power_donation_core10 : 1;
+ uint32_t power_donation_core9 : 1;
+ uint32_t power_donation_core8 : 1;
+ uint32_t power_donation_core7 : 1;
+ uint32_t power_donation_core6 : 1;
+ uint32_t power_donation_core5 : 1;
+ uint32_t power_donation_core4 : 1;
+ uint32_t power_donation_core3 : 1;
+ uint32_t power_donation_core2 : 1;
+ uint32_t power_donation_core1 : 1;
+ uint32_t power_donation_core0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_core_power_donation_reg_t;
+
+
+
+typedef union pmc_pmax_sync_collection_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pmax_sync0 : 1;
+ uint32_t pmax_sync1 : 1;
+ uint32_t pmax_sync2 : 1;
+ uint32_t pmax_sync3 : 1;
+ uint32_t pmax_sync4 : 1;
+ uint32_t pmax_sync5 : 1;
+ uint32_t pmax_sync6 : 1;
+ uint32_t pmax_sync7 : 1;
+ uint32_t pmax_sync8 : 1;
+ uint32_t pmax_sync9 : 1;
+ uint32_t pmax_sync10 : 1;
+ uint32_t pmax_sync11 : 1;
+ uint32_t pmax_sync12 : 1;
+ uint32_t pmax_sync13 : 1;
+ uint32_t pmax_sync14 : 1;
+ uint32_t pmax_sync15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t pmax_sync15 : 1;
+ uint32_t pmax_sync14 : 1;
+ uint32_t pmax_sync13 : 1;
+ uint32_t pmax_sync12 : 1;
+ uint32_t pmax_sync11 : 1;
+ uint32_t pmax_sync10 : 1;
+ uint32_t pmax_sync9 : 1;
+ uint32_t pmax_sync8 : 1;
+ uint32_t pmax_sync7 : 1;
+ uint32_t pmax_sync6 : 1;
+ uint32_t pmax_sync5 : 1;
+ uint32_t pmax_sync4 : 1;
+ uint32_t pmax_sync3 : 1;
+ uint32_t pmax_sync2 : 1;
+ uint32_t pmax_sync1 : 1;
+ uint32_t pmax_sync0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pmax_sync_collection_reg_t;
+
+
+
+typedef union pmc_pmax_sync_collection_mask_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t pmax_sync_mask0 : 1;
+ uint32_t pmax_sync_mask1 : 1;
+ uint32_t pmax_sync_mask2 : 1;
+ uint32_t pmax_sync_mask3 : 1;
+ uint32_t pmax_sync_mask4 : 1;
+ uint32_t pmax_sync_mask5 : 1;
+ uint32_t pmax_sync_mask6 : 1;
+ uint32_t pmax_sync_mask7 : 1;
+ uint32_t pmax_sync_mask8 : 1;
+ uint32_t pmax_sync_mask9 : 1;
+ uint32_t pmax_sync_mask10 : 1;
+ uint32_t pmax_sync_mask11 : 1;
+ uint32_t pmax_sync_mask12 : 1;
+ uint32_t pmax_sync_mask13 : 1;
+ uint32_t pmax_sync_mask14 : 1;
+ uint32_t pmax_sync_mask15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t pmax_sync_mask15 : 1;
+ uint32_t pmax_sync_mask14 : 1;
+ uint32_t pmax_sync_mask13 : 1;
+ uint32_t pmax_sync_mask12 : 1;
+ uint32_t pmax_sync_mask11 : 1;
+ uint32_t pmax_sync_mask10 : 1;
+ uint32_t pmax_sync_mask9 : 1;
+ uint32_t pmax_sync_mask8 : 1;
+ uint32_t pmax_sync_mask7 : 1;
+ uint32_t pmax_sync_mask6 : 1;
+ uint32_t pmax_sync_mask5 : 1;
+ uint32_t pmax_sync_mask4 : 1;
+ uint32_t pmax_sync_mask3 : 1;
+ uint32_t pmax_sync_mask2 : 1;
+ uint32_t pmax_sync_mask1 : 1;
+ uint32_t pmax_sync_mask0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pmax_sync_collection_mask_reg_t;
+
+
+
+typedef union pmc_gpsa_ack_collection_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t gpsa_ack0 : 1;
+ uint32_t gpsa_ack1 : 1;
+ uint32_t gpsa_ack2 : 1;
+ uint32_t gpsa_ack3 : 1;
+ uint32_t gpsa_ack4 : 1;
+ uint32_t gpsa_ack5 : 1;
+ uint32_t gpsa_ack6 : 1;
+ uint32_t gpsa_ack7 : 1;
+ uint32_t gpsa_ack8 : 1;
+ uint32_t gpsa_ack9 : 1;
+ uint32_t gpsa_ack10 : 1;
+ uint32_t gpsa_ack11 : 1;
+ uint32_t gpsa_ack12 : 1;
+ uint32_t gpsa_ack13 : 1;
+ uint32_t gpsa_ack14 : 1;
+ uint32_t gpsa_ack15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t gpsa_ack15 : 1;
+ uint32_t gpsa_ack14 : 1;
+ uint32_t gpsa_ack13 : 1;
+ uint32_t gpsa_ack12 : 1;
+ uint32_t gpsa_ack11 : 1;
+ uint32_t gpsa_ack10 : 1;
+ uint32_t gpsa_ack9 : 1;
+ uint32_t gpsa_ack8 : 1;
+ uint32_t gpsa_ack7 : 1;
+ uint32_t gpsa_ack6 : 1;
+ uint32_t gpsa_ack5 : 1;
+ uint32_t gpsa_ack4 : 1;
+ uint32_t gpsa_ack3 : 1;
+ uint32_t gpsa_ack2 : 1;
+ uint32_t gpsa_ack1 : 1;
+ uint32_t gpsa_ack0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_gpsa_ack_collection_reg_t;
+
+
+
+typedef union pmc_gpsa_ack_collection_mask_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t gpsa_ack_mask0 : 1;
+ uint32_t gpsa_ack_mask1 : 1;
+ uint32_t gpsa_ack_mask2 : 1;
+ uint32_t gpsa_ack_mask3 : 1;
+ uint32_t gpsa_ack_mask4 : 1;
+ uint32_t gpsa_ack_mask5 : 1;
+ uint32_t gpsa_ack_mask6 : 1;
+ uint32_t gpsa_ack_mask7 : 1;
+ uint32_t gpsa_ack_mask8 : 1;
+ uint32_t gpsa_ack_mask9 : 1;
+ uint32_t gpsa_ack_mask10 : 1;
+ uint32_t gpsa_ack_mask11 : 1;
+ uint32_t gpsa_ack_mask12 : 1;
+ uint32_t gpsa_ack_mask13 : 1;
+ uint32_t gpsa_ack_mask14 : 1;
+ uint32_t gpsa_ack_mask15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t gpsa_ack_mask15 : 1;
+ uint32_t gpsa_ack_mask14 : 1;
+ uint32_t gpsa_ack_mask13 : 1;
+ uint32_t gpsa_ack_mask12 : 1;
+ uint32_t gpsa_ack_mask11 : 1;
+ uint32_t gpsa_ack_mask10 : 1;
+ uint32_t gpsa_ack_mask9 : 1;
+ uint32_t gpsa_ack_mask8 : 1;
+ uint32_t gpsa_ack_mask7 : 1;
+ uint32_t gpsa_ack_mask6 : 1;
+ uint32_t gpsa_ack_mask5 : 1;
+ uint32_t gpsa_ack_mask4 : 1;
+ uint32_t gpsa_ack_mask3 : 1;
+ uint32_t gpsa_ack_mask2 : 1;
+ uint32_t gpsa_ack_mask1 : 1;
+ uint32_t gpsa_ack_mask0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_gpsa_ack_collection_mask_reg_t;
+
+
+
+typedef union pmc_pore_scratch_reg0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t porscr_scratch0 : 32;
+#else
+ uint32_t porscr_scratch0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pore_scratch_reg0_t;
+
+
+
+typedef union pmc_pore_scratch_reg1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t porscr_scratch1 : 32;
+#else
+ uint32_t porscr_scratch1 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pore_scratch_reg1_t;
+
+
+
+typedef union pmc_deep_idle_exit_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t deep_exit_pending_and_masked_0 : 1;
+ uint32_t deep_exit_pending_and_masked_1 : 1;
+ uint32_t deep_exit_pending_and_masked_2 : 1;
+ uint32_t deep_exit_pending_and_masked_3 : 1;
+ uint32_t deep_exit_pending_and_masked_4 : 1;
+ uint32_t deep_exit_pending_and_masked_5 : 1;
+ uint32_t deep_exit_pending_and_masked_6 : 1;
+ uint32_t deep_exit_pending_and_masked_7 : 1;
+ uint32_t deep_exit_pending_and_masked_8 : 1;
+ uint32_t deep_exit_pending_and_masked_9 : 1;
+ uint32_t deep_exit_pending_and_masked_10 : 1;
+ uint32_t deep_exit_pending_and_masked_11 : 1;
+ uint32_t deep_exit_pending_and_masked_12 : 1;
+ uint32_t deep_exit_pending_and_masked_13 : 1;
+ uint32_t deep_exit_pending_and_masked_14 : 1;
+ uint32_t deep_exit_pending_and_masked_15 : 1;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t deep_exit_pending_and_masked_15 : 1;
+ uint32_t deep_exit_pending_and_masked_14 : 1;
+ uint32_t deep_exit_pending_and_masked_13 : 1;
+ uint32_t deep_exit_pending_and_masked_12 : 1;
+ uint32_t deep_exit_pending_and_masked_11 : 1;
+ uint32_t deep_exit_pending_and_masked_10 : 1;
+ uint32_t deep_exit_pending_and_masked_9 : 1;
+ uint32_t deep_exit_pending_and_masked_8 : 1;
+ uint32_t deep_exit_pending_and_masked_7 : 1;
+ uint32_t deep_exit_pending_and_masked_6 : 1;
+ uint32_t deep_exit_pending_and_masked_5 : 1;
+ uint32_t deep_exit_pending_and_masked_4 : 1;
+ uint32_t deep_exit_pending_and_masked_3 : 1;
+ uint32_t deep_exit_pending_and_masked_2 : 1;
+ uint32_t deep_exit_pending_and_masked_1 : 1;
+ uint32_t deep_exit_pending_and_masked_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_deep_idle_exit_reg_t;
+
+
+
+typedef union pmc_deep_status_reg {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t deep_idle_state_core0 : 1;
+ uint32_t deep_idle_state_core1 : 1;
+ uint32_t deep_idle_state_core2 : 1;
+ uint32_t deep_idle_state_core3 : 1;
+ uint32_t deep_idle_state_core4 : 1;
+ uint32_t deep_idle_state_core5 : 1;
+ uint32_t deep_idle_state_core6 : 1;
+ uint32_t deep_idle_state_core7 : 1;
+ uint32_t deep_idle_state_core8 : 1;
+ uint32_t deep_idle_state_core9 : 1;
+ uint32_t deep_idle_state_core10 : 1;
+ uint32_t deep_idle_state_core11 : 1;
+ uint32_t deep_idle_state_core12 : 1;
+ uint32_t deep_idle_state_core13 : 1;
+ uint32_t deep_idle_state_core14 : 1;
+ uint32_t deep_idle_state_core15 : 1;
+ uint32_t winkle_state_core0 : 1;
+ uint32_t winkle_state_core1 : 1;
+ uint32_t winkle_state_core2 : 1;
+ uint32_t winkle_state_core3 : 1;
+ uint32_t winkle_state_core4 : 1;
+ uint32_t winkle_state_core5 : 1;
+ uint32_t winkle_state_core6 : 1;
+ uint32_t winkle_state_core7 : 1;
+ uint32_t winkle_state_core8 : 1;
+ uint32_t winkle_state_core9 : 1;
+ uint32_t winkle_state_core10 : 1;
+ uint32_t winkle_state_core11 : 1;
+ uint32_t winkle_state_core12 : 1;
+ uint32_t winkle_state_core13 : 1;
+ uint32_t winkle_state_core14 : 1;
+ uint32_t winkle_state_core15 : 1;
+#else
+ uint32_t winkle_state_core15 : 1;
+ uint32_t winkle_state_core14 : 1;
+ uint32_t winkle_state_core13 : 1;
+ uint32_t winkle_state_core12 : 1;
+ uint32_t winkle_state_core11 : 1;
+ uint32_t winkle_state_core10 : 1;
+ uint32_t winkle_state_core9 : 1;
+ uint32_t winkle_state_core8 : 1;
+ uint32_t winkle_state_core7 : 1;
+ uint32_t winkle_state_core6 : 1;
+ uint32_t winkle_state_core5 : 1;
+ uint32_t winkle_state_core4 : 1;
+ uint32_t winkle_state_core3 : 1;
+ uint32_t winkle_state_core2 : 1;
+ uint32_t winkle_state_core1 : 1;
+ uint32_t winkle_state_core0 : 1;
+ uint32_t deep_idle_state_core15 : 1;
+ uint32_t deep_idle_state_core14 : 1;
+ uint32_t deep_idle_state_core13 : 1;
+ uint32_t deep_idle_state_core12 : 1;
+ uint32_t deep_idle_state_core11 : 1;
+ uint32_t deep_idle_state_core10 : 1;
+ uint32_t deep_idle_state_core9 : 1;
+ uint32_t deep_idle_state_core8 : 1;
+ uint32_t deep_idle_state_core7 : 1;
+ uint32_t deep_idle_state_core6 : 1;
+ uint32_t deep_idle_state_core5 : 1;
+ uint32_t deep_idle_state_core4 : 1;
+ uint32_t deep_idle_state_core3 : 1;
+ uint32_t deep_idle_state_core2 : 1;
+ uint32_t deep_idle_state_core1 : 1;
+ uint32_t deep_idle_state_core0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_deep_status_reg_t;
+
+
+
+typedef union pmc_ba_pore_exe_trigger_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_ba_pore_exe_trigger_reg_t;
+
+
+
+typedef union pmc_pcbs_gaps_brdcast_addr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t value : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t value : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_pcbs_gaps_brdcast_addr_t;
+
+
+
+typedef union pmc_lfir_err_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t lfir_pstate_oci_master_rderr : 1;
+ uint64_t lfir_pstate_oci_master_rddata_parity_err : 1;
+ uint64_t lfir_pstate_gpst_checkbyte_err : 1;
+ uint64_t lfir_pstate_gack_to_err : 1;
+ uint64_t lfir_pstate_pib_master_nonoffline_err : 1;
+ uint64_t lfir_pstate_pib_master_offline_err : 1;
+ uint64_t lfir_pstate_oci_master_to_err : 1;
+ uint64_t lfir_pstate_interchip_ue_err : 1;
+ uint64_t lfir_pstate_interchip_errorframe_err : 1;
+ uint64_t lfir_pstate_ms_fsm_err : 1;
+ uint64_t lfir_ms_comp_parity_err : 1;
+ uint64_t lfir_idle_poresw_fatal_err : 1;
+ uint64_t lfir_idle_poresw_status_rc_err : 1;
+ uint64_t lfir_idle_poresw_status_value_err : 1;
+ uint64_t lfir_idle_poresw_write_while_inactive_err : 1;
+ uint64_t lfir_idle_poresw_timeout_err : 1;
+ uint64_t lfir_idle_oci_master_write_timeout_err : 1;
+ uint64_t lfir_idle_internal_err : 1;
+ uint64_t lfir_int_comp_parity_err : 1;
+ uint64_t lfir_pmc_occ_heartbeat_timeout : 1;
+ uint64_t lfir_spivid_crc_error0 : 1;
+ uint64_t lfir_spivid_crc_error1 : 1;
+ uint64_t lfir_spivid_crc_error2 : 1;
+ uint64_t lfir_spivid_retry_timeout : 1;
+ uint64_t lfir_spivid_fsm_err : 1;
+ uint64_t lfir_spivid_majority_detected_a_minority : 1;
+ uint64_t lfir_o2s_crc_error0 : 1;
+ uint64_t lfir_o2s_crc_error1 : 1;
+ uint64_t lfir_o2s_crc_error2 : 1;
+ uint64_t lfir_o2s_retry_timeout : 1;
+ uint64_t lfir_o2s_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_fsm_err : 1;
+ uint64_t lfir_o2s_majority_detected_a_minority : 1;
+ uint64_t lfir_o2p_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2p_fsm_err : 1;
+ uint64_t lfir_oci_slave_err : 1;
+ uint64_t lfir_if_comp_parity_error : 1;
+ uint64_t spare_fir : 10;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t spare_fir : 10;
+ uint64_t lfir_if_comp_parity_error : 1;
+ uint64_t lfir_oci_slave_err : 1;
+ uint64_t lfir_o2p_fsm_err : 1;
+ uint64_t lfir_o2p_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_majority_detected_a_minority : 1;
+ uint64_t lfir_o2s_fsm_err : 1;
+ uint64_t lfir_o2s_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_retry_timeout : 1;
+ uint64_t lfir_o2s_crc_error2 : 1;
+ uint64_t lfir_o2s_crc_error1 : 1;
+ uint64_t lfir_o2s_crc_error0 : 1;
+ uint64_t lfir_spivid_majority_detected_a_minority : 1;
+ uint64_t lfir_spivid_fsm_err : 1;
+ uint64_t lfir_spivid_retry_timeout : 1;
+ uint64_t lfir_spivid_crc_error2 : 1;
+ uint64_t lfir_spivid_crc_error1 : 1;
+ uint64_t lfir_spivid_crc_error0 : 1;
+ uint64_t lfir_pmc_occ_heartbeat_timeout : 1;
+ uint64_t lfir_int_comp_parity_err : 1;
+ uint64_t lfir_idle_internal_err : 1;
+ uint64_t lfir_idle_oci_master_write_timeout_err : 1;
+ uint64_t lfir_idle_poresw_timeout_err : 1;
+ uint64_t lfir_idle_poresw_write_while_inactive_err : 1;
+ uint64_t lfir_idle_poresw_status_value_err : 1;
+ uint64_t lfir_idle_poresw_status_rc_err : 1;
+ uint64_t lfir_idle_poresw_fatal_err : 1;
+ uint64_t lfir_ms_comp_parity_err : 1;
+ uint64_t lfir_pstate_ms_fsm_err : 1;
+ uint64_t lfir_pstate_interchip_errorframe_err : 1;
+ uint64_t lfir_pstate_interchip_ue_err : 1;
+ uint64_t lfir_pstate_oci_master_to_err : 1;
+ uint64_t lfir_pstate_pib_master_offline_err : 1;
+ uint64_t lfir_pstate_pib_master_nonoffline_err : 1;
+ uint64_t lfir_pstate_gack_to_err : 1;
+ uint64_t lfir_pstate_gpst_checkbyte_err : 1;
+ uint64_t lfir_pstate_oci_master_rddata_parity_err : 1;
+ uint64_t lfir_pstate_oci_master_rderr : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_err_reg_t;
+
+
+
+typedef union pmc_lfir_err_reg_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t lfir_pstate_oci_master_rderr : 1;
+ uint64_t lfir_pstate_oci_master_rddata_parity_err : 1;
+ uint64_t lfir_pstate_gpst_checkbyte_err : 1;
+ uint64_t lfir_pstate_gack_to_err : 1;
+ uint64_t lfir_pstate_pib_master_nonoffline_err : 1;
+ uint64_t lfir_pstate_pib_master_offline_err : 1;
+ uint64_t lfir_pstate_oci_master_to_err : 1;
+ uint64_t lfir_pstate_interchip_ue_err : 1;
+ uint64_t lfir_pstate_interchip_errorframe_err : 1;
+ uint64_t lfir_pstate_ms_fsm_err : 1;
+ uint64_t lfir_ms_comp_parity_err : 1;
+ uint64_t lfir_idle_poresw_fatal_err : 1;
+ uint64_t lfir_idle_poresw_status_rc_err : 1;
+ uint64_t lfir_idle_poresw_status_value_err : 1;
+ uint64_t lfir_idle_poresw_write_while_inactive_err : 1;
+ uint64_t lfir_idle_poresw_timeout_err : 1;
+ uint64_t lfir_idle_oci_master_write_timeout_err : 1;
+ uint64_t lfir_idle_internal_err : 1;
+ uint64_t lfir_int_comp_parity_err : 1;
+ uint64_t lfir_pmc_occ_heartbeat_timeout : 1;
+ uint64_t lfir_spivid_crc_error0 : 1;
+ uint64_t lfir_spivid_crc_error1 : 1;
+ uint64_t lfir_spivid_crc_error2 : 1;
+ uint64_t lfir_spivid_retry_timeout : 1;
+ uint64_t lfir_spivid_fsm_err : 1;
+ uint64_t lfir_spivid_majority_detected_a_minority : 1;
+ uint64_t lfir_o2s_crc_error0 : 1;
+ uint64_t lfir_o2s_crc_error1 : 1;
+ uint64_t lfir_o2s_crc_error2 : 1;
+ uint64_t lfir_o2s_retry_timeout : 1;
+ uint64_t lfir_o2s_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_fsm_err : 1;
+ uint64_t lfir_o2s_majority_detected_a_minority : 1;
+ uint64_t lfir_o2p_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2p_fsm_err : 1;
+ uint64_t lfir_oci_slave_err : 1;
+ uint64_t lfir_if_comp_parity_error : 1;
+ uint64_t spare_fir : 10;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t spare_fir : 10;
+ uint64_t lfir_if_comp_parity_error : 1;
+ uint64_t lfir_oci_slave_err : 1;
+ uint64_t lfir_o2p_fsm_err : 1;
+ uint64_t lfir_o2p_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_majority_detected_a_minority : 1;
+ uint64_t lfir_o2s_fsm_err : 1;
+ uint64_t lfir_o2s_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_retry_timeout : 1;
+ uint64_t lfir_o2s_crc_error2 : 1;
+ uint64_t lfir_o2s_crc_error1 : 1;
+ uint64_t lfir_o2s_crc_error0 : 1;
+ uint64_t lfir_spivid_majority_detected_a_minority : 1;
+ uint64_t lfir_spivid_fsm_err : 1;
+ uint64_t lfir_spivid_retry_timeout : 1;
+ uint64_t lfir_spivid_crc_error2 : 1;
+ uint64_t lfir_spivid_crc_error1 : 1;
+ uint64_t lfir_spivid_crc_error0 : 1;
+ uint64_t lfir_pmc_occ_heartbeat_timeout : 1;
+ uint64_t lfir_int_comp_parity_err : 1;
+ uint64_t lfir_idle_internal_err : 1;
+ uint64_t lfir_idle_oci_master_write_timeout_err : 1;
+ uint64_t lfir_idle_poresw_timeout_err : 1;
+ uint64_t lfir_idle_poresw_write_while_inactive_err : 1;
+ uint64_t lfir_idle_poresw_status_value_err : 1;
+ uint64_t lfir_idle_poresw_status_rc_err : 1;
+ uint64_t lfir_idle_poresw_fatal_err : 1;
+ uint64_t lfir_ms_comp_parity_err : 1;
+ uint64_t lfir_pstate_ms_fsm_err : 1;
+ uint64_t lfir_pstate_interchip_errorframe_err : 1;
+ uint64_t lfir_pstate_interchip_ue_err : 1;
+ uint64_t lfir_pstate_oci_master_to_err : 1;
+ uint64_t lfir_pstate_pib_master_offline_err : 1;
+ uint64_t lfir_pstate_pib_master_nonoffline_err : 1;
+ uint64_t lfir_pstate_gack_to_err : 1;
+ uint64_t lfir_pstate_gpst_checkbyte_err : 1;
+ uint64_t lfir_pstate_oci_master_rddata_parity_err : 1;
+ uint64_t lfir_pstate_oci_master_rderr : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_err_reg_and_t;
+
+
+
+typedef union pmc_lfir_err_reg_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t lfir_pstate_oci_master_rderr : 1;
+ uint64_t lfir_pstate_oci_master_rddata_parity_err : 1;
+ uint64_t lfir_pstate_gpst_checkbyte_err : 1;
+ uint64_t lfir_pstate_gack_to_err : 1;
+ uint64_t lfir_pstate_pib_master_nonoffline_err : 1;
+ uint64_t lfir_pstate_pib_master_offline_err : 1;
+ uint64_t lfir_pstate_oci_master_to_err : 1;
+ uint64_t lfir_pstate_interchip_ue_err : 1;
+ uint64_t lfir_pstate_interchip_errorframe_err : 1;
+ uint64_t lfir_pstate_ms_fsm_err : 1;
+ uint64_t lfir_ms_comp_parity_err : 1;
+ uint64_t lfir_idle_poresw_fatal_err : 1;
+ uint64_t lfir_idle_poresw_status_rc_err : 1;
+ uint64_t lfir_idle_poresw_status_value_err : 1;
+ uint64_t lfir_idle_poresw_write_while_inactive_err : 1;
+ uint64_t lfir_idle_poresw_timeout_err : 1;
+ uint64_t lfir_idle_oci_master_write_timeout_err : 1;
+ uint64_t lfir_idle_internal_err : 1;
+ uint64_t lfir_int_comp_parity_err : 1;
+ uint64_t lfir_pmc_occ_heartbeat_timeout : 1;
+ uint64_t lfir_spivid_crc_error0 : 1;
+ uint64_t lfir_spivid_crc_error1 : 1;
+ uint64_t lfir_spivid_crc_error2 : 1;
+ uint64_t lfir_spivid_retry_timeout : 1;
+ uint64_t lfir_spivid_fsm_err : 1;
+ uint64_t lfir_spivid_majority_detected_a_minority : 1;
+ uint64_t lfir_o2s_crc_error0 : 1;
+ uint64_t lfir_o2s_crc_error1 : 1;
+ uint64_t lfir_o2s_crc_error2 : 1;
+ uint64_t lfir_o2s_retry_timeout : 1;
+ uint64_t lfir_o2s_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_fsm_err : 1;
+ uint64_t lfir_o2s_majority_detected_a_minority : 1;
+ uint64_t lfir_o2p_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2p_fsm_err : 1;
+ uint64_t lfir_oci_slave_err : 1;
+ uint64_t lfir_if_comp_parity_error : 1;
+ uint64_t spare_fir : 10;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t fir_parity_err : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t fir_parity_err : 1;
+ uint64_t fir_parity_err_dup : 1;
+ uint64_t spare_fir : 10;
+ uint64_t lfir_if_comp_parity_error : 1;
+ uint64_t lfir_oci_slave_err : 1;
+ uint64_t lfir_o2p_fsm_err : 1;
+ uint64_t lfir_o2p_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_majority_detected_a_minority : 1;
+ uint64_t lfir_o2s_fsm_err : 1;
+ uint64_t lfir_o2s_write_while_bridge_busy_err : 1;
+ uint64_t lfir_o2s_retry_timeout : 1;
+ uint64_t lfir_o2s_crc_error2 : 1;
+ uint64_t lfir_o2s_crc_error1 : 1;
+ uint64_t lfir_o2s_crc_error0 : 1;
+ uint64_t lfir_spivid_majority_detected_a_minority : 1;
+ uint64_t lfir_spivid_fsm_err : 1;
+ uint64_t lfir_spivid_retry_timeout : 1;
+ uint64_t lfir_spivid_crc_error2 : 1;
+ uint64_t lfir_spivid_crc_error1 : 1;
+ uint64_t lfir_spivid_crc_error0 : 1;
+ uint64_t lfir_pmc_occ_heartbeat_timeout : 1;
+ uint64_t lfir_int_comp_parity_err : 1;
+ uint64_t lfir_idle_internal_err : 1;
+ uint64_t lfir_idle_oci_master_write_timeout_err : 1;
+ uint64_t lfir_idle_poresw_timeout_err : 1;
+ uint64_t lfir_idle_poresw_write_while_inactive_err : 1;
+ uint64_t lfir_idle_poresw_status_value_err : 1;
+ uint64_t lfir_idle_poresw_status_rc_err : 1;
+ uint64_t lfir_idle_poresw_fatal_err : 1;
+ uint64_t lfir_ms_comp_parity_err : 1;
+ uint64_t lfir_pstate_ms_fsm_err : 1;
+ uint64_t lfir_pstate_interchip_errorframe_err : 1;
+ uint64_t lfir_pstate_interchip_ue_err : 1;
+ uint64_t lfir_pstate_oci_master_to_err : 1;
+ uint64_t lfir_pstate_pib_master_offline_err : 1;
+ uint64_t lfir_pstate_pib_master_nonoffline_err : 1;
+ uint64_t lfir_pstate_gack_to_err : 1;
+ uint64_t lfir_pstate_gpst_checkbyte_err : 1;
+ uint64_t lfir_pstate_oci_master_rddata_parity_err : 1;
+ uint64_t lfir_pstate_oci_master_rderr : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_err_reg_or_t;
+
+
+
+typedef union pmc_lfir_err_mask_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pmc_lfir_mask_0 : 1;
+ uint64_t pmc_lfir_mask_1 : 1;
+ uint64_t pmc_lfir_mask_2 : 1;
+ uint64_t pmc_lfir_mask_3 : 1;
+ uint64_t pmc_lfir_mask_4 : 1;
+ uint64_t pmc_lfir_mask_5 : 1;
+ uint64_t pmc_lfir_mask_6 : 1;
+ uint64_t pmc_lfir_mask_7 : 1;
+ uint64_t pmc_lfir_mask_8 : 1;
+ uint64_t pmc_lfir_mask_9 : 1;
+ uint64_t pmc_lfir_mask_10 : 1;
+ uint64_t pmc_lfir_mask_11 : 1;
+ uint64_t pmc_lfir_mask_12 : 1;
+ uint64_t pmc_lfir_mask_13 : 1;
+ uint64_t pmc_lfir_mask_14 : 1;
+ uint64_t pmc_lfir_mask_15 : 1;
+ uint64_t pmc_lfir_mask_16 : 1;
+ uint64_t pmc_lfir_mask_17 : 1;
+ uint64_t pmc_lfir_mask_18 : 1;
+ uint64_t pmc_lfir_mask_19 : 1;
+ uint64_t pmc_lfir_mask_20 : 1;
+ uint64_t pmc_lfir_mask_21 : 1;
+ uint64_t pmc_lfir_mask_22 : 1;
+ uint64_t pmc_lfir_mask_23 : 1;
+ uint64_t pmc_lfir_mask_24 : 1;
+ uint64_t pmc_lfir_mask_25 : 1;
+ uint64_t pmc_lfir_mask_26 : 1;
+ uint64_t pmc_lfir_mask_27 : 1;
+ uint64_t pmc_lfir_mask_28 : 1;
+ uint64_t pmc_lfir_mask_29 : 1;
+ uint64_t pmc_lfir_mask_30 : 1;
+ uint64_t pmc_lfir_mask_31 : 1;
+ uint64_t pmc_lfir_mask_32 : 1;
+ uint64_t pmc_lfir_mask_33 : 1;
+ uint64_t pmc_lfir_mask_34 : 1;
+ uint64_t pmc_lfir_mask_35 : 1;
+ uint64_t pmc_lfir_mask_36 : 1;
+ uint64_t pmc_lfir_mask1_37_46 : 10;
+ uint64_t pmc_lfir_mask1_47 : 1;
+ uint64_t pmc_lfir_mask1_48 : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t pmc_lfir_mask1_48 : 1;
+ uint64_t pmc_lfir_mask1_47 : 1;
+ uint64_t pmc_lfir_mask1_37_46 : 10;
+ uint64_t pmc_lfir_mask_36 : 1;
+ uint64_t pmc_lfir_mask_35 : 1;
+ uint64_t pmc_lfir_mask_34 : 1;
+ uint64_t pmc_lfir_mask_33 : 1;
+ uint64_t pmc_lfir_mask_32 : 1;
+ uint64_t pmc_lfir_mask_31 : 1;
+ uint64_t pmc_lfir_mask_30 : 1;
+ uint64_t pmc_lfir_mask_29 : 1;
+ uint64_t pmc_lfir_mask_28 : 1;
+ uint64_t pmc_lfir_mask_27 : 1;
+ uint64_t pmc_lfir_mask_26 : 1;
+ uint64_t pmc_lfir_mask_25 : 1;
+ uint64_t pmc_lfir_mask_24 : 1;
+ uint64_t pmc_lfir_mask_23 : 1;
+ uint64_t pmc_lfir_mask_22 : 1;
+ uint64_t pmc_lfir_mask_21 : 1;
+ uint64_t pmc_lfir_mask_20 : 1;
+ uint64_t pmc_lfir_mask_19 : 1;
+ uint64_t pmc_lfir_mask_18 : 1;
+ uint64_t pmc_lfir_mask_17 : 1;
+ uint64_t pmc_lfir_mask_16 : 1;
+ uint64_t pmc_lfir_mask_15 : 1;
+ uint64_t pmc_lfir_mask_14 : 1;
+ uint64_t pmc_lfir_mask_13 : 1;
+ uint64_t pmc_lfir_mask_12 : 1;
+ uint64_t pmc_lfir_mask_11 : 1;
+ uint64_t pmc_lfir_mask_10 : 1;
+ uint64_t pmc_lfir_mask_9 : 1;
+ uint64_t pmc_lfir_mask_8 : 1;
+ uint64_t pmc_lfir_mask_7 : 1;
+ uint64_t pmc_lfir_mask_6 : 1;
+ uint64_t pmc_lfir_mask_5 : 1;
+ uint64_t pmc_lfir_mask_4 : 1;
+ uint64_t pmc_lfir_mask_3 : 1;
+ uint64_t pmc_lfir_mask_2 : 1;
+ uint64_t pmc_lfir_mask_1 : 1;
+ uint64_t pmc_lfir_mask_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_err_mask_reg_t;
+
+
+
+typedef union pmc_lfir_err_mask_reg_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pmc_lfir_mask_0 : 1;
+ uint64_t pmc_lfir_mask_1 : 1;
+ uint64_t pmc_lfir_mask_2 : 1;
+ uint64_t pmc_lfir_mask_3 : 1;
+ uint64_t pmc_lfir_mask_4 : 1;
+ uint64_t pmc_lfir_mask_5 : 1;
+ uint64_t pmc_lfir_mask_6 : 1;
+ uint64_t pmc_lfir_mask_7 : 1;
+ uint64_t pmc_lfir_mask_8 : 1;
+ uint64_t pmc_lfir_mask_9 : 1;
+ uint64_t pmc_lfir_mask_10 : 1;
+ uint64_t pmc_lfir_mask_11 : 1;
+ uint64_t pmc_lfir_mask_12 : 1;
+ uint64_t pmc_lfir_mask_13 : 1;
+ uint64_t pmc_lfir_mask_14 : 1;
+ uint64_t pmc_lfir_mask_15 : 1;
+ uint64_t pmc_lfir_mask_16 : 1;
+ uint64_t pmc_lfir_mask_17 : 1;
+ uint64_t pmc_lfir_mask_18 : 1;
+ uint64_t pmc_lfir_mask_19 : 1;
+ uint64_t pmc_lfir_mask_20 : 1;
+ uint64_t pmc_lfir_mask_21 : 1;
+ uint64_t pmc_lfir_mask_22 : 1;
+ uint64_t pmc_lfir_mask_23 : 1;
+ uint64_t pmc_lfir_mask_24 : 1;
+ uint64_t pmc_lfir_mask_25 : 1;
+ uint64_t pmc_lfir_mask_26 : 1;
+ uint64_t pmc_lfir_mask_27 : 1;
+ uint64_t pmc_lfir_mask_28 : 1;
+ uint64_t pmc_lfir_mask_29 : 1;
+ uint64_t pmc_lfir_mask_30 : 1;
+ uint64_t pmc_lfir_mask_31 : 1;
+ uint64_t pmc_lfir_mask_32 : 1;
+ uint64_t pmc_lfir_mask_33 : 1;
+ uint64_t pmc_lfir_mask_34 : 1;
+ uint64_t pmc_lfir_mask_35 : 1;
+ uint64_t pmc_lfir_mask_36 : 1;
+ uint64_t pmc_lfir_mask1_37_46 : 10;
+ uint64_t pmc_lfir_mask1_47 : 1;
+ uint64_t pmc_lfir_mask1_48 : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t pmc_lfir_mask1_48 : 1;
+ uint64_t pmc_lfir_mask1_47 : 1;
+ uint64_t pmc_lfir_mask1_37_46 : 10;
+ uint64_t pmc_lfir_mask_36 : 1;
+ uint64_t pmc_lfir_mask_35 : 1;
+ uint64_t pmc_lfir_mask_34 : 1;
+ uint64_t pmc_lfir_mask_33 : 1;
+ uint64_t pmc_lfir_mask_32 : 1;
+ uint64_t pmc_lfir_mask_31 : 1;
+ uint64_t pmc_lfir_mask_30 : 1;
+ uint64_t pmc_lfir_mask_29 : 1;
+ uint64_t pmc_lfir_mask_28 : 1;
+ uint64_t pmc_lfir_mask_27 : 1;
+ uint64_t pmc_lfir_mask_26 : 1;
+ uint64_t pmc_lfir_mask_25 : 1;
+ uint64_t pmc_lfir_mask_24 : 1;
+ uint64_t pmc_lfir_mask_23 : 1;
+ uint64_t pmc_lfir_mask_22 : 1;
+ uint64_t pmc_lfir_mask_21 : 1;
+ uint64_t pmc_lfir_mask_20 : 1;
+ uint64_t pmc_lfir_mask_19 : 1;
+ uint64_t pmc_lfir_mask_18 : 1;
+ uint64_t pmc_lfir_mask_17 : 1;
+ uint64_t pmc_lfir_mask_16 : 1;
+ uint64_t pmc_lfir_mask_15 : 1;
+ uint64_t pmc_lfir_mask_14 : 1;
+ uint64_t pmc_lfir_mask_13 : 1;
+ uint64_t pmc_lfir_mask_12 : 1;
+ uint64_t pmc_lfir_mask_11 : 1;
+ uint64_t pmc_lfir_mask_10 : 1;
+ uint64_t pmc_lfir_mask_9 : 1;
+ uint64_t pmc_lfir_mask_8 : 1;
+ uint64_t pmc_lfir_mask_7 : 1;
+ uint64_t pmc_lfir_mask_6 : 1;
+ uint64_t pmc_lfir_mask_5 : 1;
+ uint64_t pmc_lfir_mask_4 : 1;
+ uint64_t pmc_lfir_mask_3 : 1;
+ uint64_t pmc_lfir_mask_2 : 1;
+ uint64_t pmc_lfir_mask_1 : 1;
+ uint64_t pmc_lfir_mask_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_err_mask_reg_and_t;
+
+
+
+typedef union pmc_lfir_err_mask_reg_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pmc_lfir_mask_0 : 1;
+ uint64_t pmc_lfir_mask_1 : 1;
+ uint64_t pmc_lfir_mask_2 : 1;
+ uint64_t pmc_lfir_mask_3 : 1;
+ uint64_t pmc_lfir_mask_4 : 1;
+ uint64_t pmc_lfir_mask_5 : 1;
+ uint64_t pmc_lfir_mask_6 : 1;
+ uint64_t pmc_lfir_mask_7 : 1;
+ uint64_t pmc_lfir_mask_8 : 1;
+ uint64_t pmc_lfir_mask_9 : 1;
+ uint64_t pmc_lfir_mask_10 : 1;
+ uint64_t pmc_lfir_mask_11 : 1;
+ uint64_t pmc_lfir_mask_12 : 1;
+ uint64_t pmc_lfir_mask_13 : 1;
+ uint64_t pmc_lfir_mask_14 : 1;
+ uint64_t pmc_lfir_mask_15 : 1;
+ uint64_t pmc_lfir_mask_16 : 1;
+ uint64_t pmc_lfir_mask_17 : 1;
+ uint64_t pmc_lfir_mask_18 : 1;
+ uint64_t pmc_lfir_mask_19 : 1;
+ uint64_t pmc_lfir_mask_20 : 1;
+ uint64_t pmc_lfir_mask_21 : 1;
+ uint64_t pmc_lfir_mask_22 : 1;
+ uint64_t pmc_lfir_mask_23 : 1;
+ uint64_t pmc_lfir_mask_24 : 1;
+ uint64_t pmc_lfir_mask_25 : 1;
+ uint64_t pmc_lfir_mask_26 : 1;
+ uint64_t pmc_lfir_mask_27 : 1;
+ uint64_t pmc_lfir_mask_28 : 1;
+ uint64_t pmc_lfir_mask_29 : 1;
+ uint64_t pmc_lfir_mask_30 : 1;
+ uint64_t pmc_lfir_mask_31 : 1;
+ uint64_t pmc_lfir_mask_32 : 1;
+ uint64_t pmc_lfir_mask_33 : 1;
+ uint64_t pmc_lfir_mask_34 : 1;
+ uint64_t pmc_lfir_mask_35 : 1;
+ uint64_t pmc_lfir_mask_36 : 1;
+ uint64_t pmc_lfir_mask1_37_46 : 10;
+ uint64_t pmc_lfir_mask1_47 : 1;
+ uint64_t pmc_lfir_mask1_48 : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t pmc_lfir_mask1_48 : 1;
+ uint64_t pmc_lfir_mask1_47 : 1;
+ uint64_t pmc_lfir_mask1_37_46 : 10;
+ uint64_t pmc_lfir_mask_36 : 1;
+ uint64_t pmc_lfir_mask_35 : 1;
+ uint64_t pmc_lfir_mask_34 : 1;
+ uint64_t pmc_lfir_mask_33 : 1;
+ uint64_t pmc_lfir_mask_32 : 1;
+ uint64_t pmc_lfir_mask_31 : 1;
+ uint64_t pmc_lfir_mask_30 : 1;
+ uint64_t pmc_lfir_mask_29 : 1;
+ uint64_t pmc_lfir_mask_28 : 1;
+ uint64_t pmc_lfir_mask_27 : 1;
+ uint64_t pmc_lfir_mask_26 : 1;
+ uint64_t pmc_lfir_mask_25 : 1;
+ uint64_t pmc_lfir_mask_24 : 1;
+ uint64_t pmc_lfir_mask_23 : 1;
+ uint64_t pmc_lfir_mask_22 : 1;
+ uint64_t pmc_lfir_mask_21 : 1;
+ uint64_t pmc_lfir_mask_20 : 1;
+ uint64_t pmc_lfir_mask_19 : 1;
+ uint64_t pmc_lfir_mask_18 : 1;
+ uint64_t pmc_lfir_mask_17 : 1;
+ uint64_t pmc_lfir_mask_16 : 1;
+ uint64_t pmc_lfir_mask_15 : 1;
+ uint64_t pmc_lfir_mask_14 : 1;
+ uint64_t pmc_lfir_mask_13 : 1;
+ uint64_t pmc_lfir_mask_12 : 1;
+ uint64_t pmc_lfir_mask_11 : 1;
+ uint64_t pmc_lfir_mask_10 : 1;
+ uint64_t pmc_lfir_mask_9 : 1;
+ uint64_t pmc_lfir_mask_8 : 1;
+ uint64_t pmc_lfir_mask_7 : 1;
+ uint64_t pmc_lfir_mask_6 : 1;
+ uint64_t pmc_lfir_mask_5 : 1;
+ uint64_t pmc_lfir_mask_4 : 1;
+ uint64_t pmc_lfir_mask_3 : 1;
+ uint64_t pmc_lfir_mask_2 : 1;
+ uint64_t pmc_lfir_mask_1 : 1;
+ uint64_t pmc_lfir_mask_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_err_mask_reg_or_t;
+
+
+
+typedef union pmc_lfir_action0_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pmc_lfir_action0_0 : 1;
+ uint64_t pmc_lfir_action0_1 : 1;
+ uint64_t pmc_lfir_action0_2 : 1;
+ uint64_t pmc_lfir_action0_3 : 1;
+ uint64_t pmc_lfir_action0_4 : 1;
+ uint64_t pmc_lfir_action0_5 : 1;
+ uint64_t pmc_lfir_action0_6 : 1;
+ uint64_t pmc_lfir_action0_7 : 1;
+ uint64_t pmc_lfir_action0_8 : 1;
+ uint64_t pmc_lfir_action0_9 : 1;
+ uint64_t pmc_lfir_action0_10 : 1;
+ uint64_t pmc_lfir_action0_11 : 1;
+ uint64_t pmc_lfir_action0_12 : 1;
+ uint64_t pmc_lfir_action0_13 : 1;
+ uint64_t pmc_lfir_action0_14 : 1;
+ uint64_t pmc_lfir_action0_15 : 1;
+ uint64_t pmc_lfir_action0_16 : 1;
+ uint64_t pmc_lfir_action0_17 : 1;
+ uint64_t pmc_lfir_action0_18 : 1;
+ uint64_t pmc_lfir_action0_19 : 1;
+ uint64_t pmc_lfir_action0_20 : 1;
+ uint64_t pmc_lfir_action0_21 : 1;
+ uint64_t pmc_lfir_action0_22 : 1;
+ uint64_t pmc_lfir_action0_23 : 1;
+ uint64_t pmc_lfir_action0_24 : 1;
+ uint64_t pmc_lfir_action0_25 : 1;
+ uint64_t pmc_lfir_action0_26 : 1;
+ uint64_t pmc_lfir_action0_27 : 1;
+ uint64_t pmc_lfir_action0_28 : 1;
+ uint64_t pmc_lfir_action0_29 : 1;
+ uint64_t pmc_lfir_action0_30 : 1;
+ uint64_t pmc_lfir_action0_31 : 1;
+ uint64_t pmc_lfir_action0_32 : 1;
+ uint64_t pmc_lfir_action0_33 : 1;
+ uint64_t pmc_lfir_action0_34 : 1;
+ uint64_t pmc_lfir_action0_35 : 1;
+ uint64_t pmc_lfir_action0_36 : 1;
+ uint64_t pmc_lfir_action0_37_46 : 10;
+ uint64_t pmc_lfir_action0_47 : 1;
+ uint64_t pmc_lfir_action0_48 : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t pmc_lfir_action0_48 : 1;
+ uint64_t pmc_lfir_action0_47 : 1;
+ uint64_t pmc_lfir_action0_37_46 : 10;
+ uint64_t pmc_lfir_action0_36 : 1;
+ uint64_t pmc_lfir_action0_35 : 1;
+ uint64_t pmc_lfir_action0_34 : 1;
+ uint64_t pmc_lfir_action0_33 : 1;
+ uint64_t pmc_lfir_action0_32 : 1;
+ uint64_t pmc_lfir_action0_31 : 1;
+ uint64_t pmc_lfir_action0_30 : 1;
+ uint64_t pmc_lfir_action0_29 : 1;
+ uint64_t pmc_lfir_action0_28 : 1;
+ uint64_t pmc_lfir_action0_27 : 1;
+ uint64_t pmc_lfir_action0_26 : 1;
+ uint64_t pmc_lfir_action0_25 : 1;
+ uint64_t pmc_lfir_action0_24 : 1;
+ uint64_t pmc_lfir_action0_23 : 1;
+ uint64_t pmc_lfir_action0_22 : 1;
+ uint64_t pmc_lfir_action0_21 : 1;
+ uint64_t pmc_lfir_action0_20 : 1;
+ uint64_t pmc_lfir_action0_19 : 1;
+ uint64_t pmc_lfir_action0_18 : 1;
+ uint64_t pmc_lfir_action0_17 : 1;
+ uint64_t pmc_lfir_action0_16 : 1;
+ uint64_t pmc_lfir_action0_15 : 1;
+ uint64_t pmc_lfir_action0_14 : 1;
+ uint64_t pmc_lfir_action0_13 : 1;
+ uint64_t pmc_lfir_action0_12 : 1;
+ uint64_t pmc_lfir_action0_11 : 1;
+ uint64_t pmc_lfir_action0_10 : 1;
+ uint64_t pmc_lfir_action0_9 : 1;
+ uint64_t pmc_lfir_action0_8 : 1;
+ uint64_t pmc_lfir_action0_7 : 1;
+ uint64_t pmc_lfir_action0_6 : 1;
+ uint64_t pmc_lfir_action0_5 : 1;
+ uint64_t pmc_lfir_action0_4 : 1;
+ uint64_t pmc_lfir_action0_3 : 1;
+ uint64_t pmc_lfir_action0_2 : 1;
+ uint64_t pmc_lfir_action0_1 : 1;
+ uint64_t pmc_lfir_action0_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_action0_reg_t;
+
+
+
+typedef union pmc_lfir_action1_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pmc_lfir_action1_0 : 1;
+ uint64_t pmc_lfir_action1_1 : 1;
+ uint64_t pmc_lfir_action1_2 : 1;
+ uint64_t pmc_lfir_action1_3 : 1;
+ uint64_t pmc_lfir_action1_4 : 1;
+ uint64_t pmc_lfir_action1_5 : 1;
+ uint64_t pmc_lfir_action1_6 : 1;
+ uint64_t pmc_lfir_action1_7 : 1;
+ uint64_t pmc_lfir_action1_8 : 1;
+ uint64_t pmc_lfir_action1_9 : 1;
+ uint64_t pmc_lfir_action1_10 : 1;
+ uint64_t pmc_lfir_action1_11 : 1;
+ uint64_t pmc_lfir_action1_12 : 1;
+ uint64_t pmc_lfir_action1_13 : 1;
+ uint64_t pmc_lfir_action1_14 : 1;
+ uint64_t pmc_lfir_action1_15 : 1;
+ uint64_t pmc_lfir_action1_16 : 1;
+ uint64_t pmc_lfir_action1_17 : 1;
+ uint64_t pmc_lfir_action1_18 : 1;
+ uint64_t pmc_lfir_action1_19 : 1;
+ uint64_t pmc_lfir_action1_20 : 1;
+ uint64_t pmc_lfir_action1_21 : 1;
+ uint64_t pmc_lfir_action1_22 : 1;
+ uint64_t pmc_lfir_action1_23 : 1;
+ uint64_t pmc_lfir_action1_24 : 1;
+ uint64_t pmc_lfir_action1_25 : 1;
+ uint64_t pmc_lfir_action1_26 : 1;
+ uint64_t pmc_lfir_action1_27 : 1;
+ uint64_t pmc_lfir_action1_28 : 1;
+ uint64_t pmc_lfir_action1_29 : 1;
+ uint64_t pmc_lfir_action1_30 : 1;
+ uint64_t pmc_lfir_action1_31 : 1;
+ uint64_t pmc_lfir_action1_32 : 1;
+ uint64_t pmc_lfir_action1_33 : 1;
+ uint64_t pmc_lfir_action1_34 : 1;
+ uint64_t pmc_lfir_action1_35 : 1;
+ uint64_t pmc_lfir_action1_36 : 1;
+ uint64_t pmc_lfir_action1_37_46 : 10;
+ uint64_t pmc_lfir_action1_47 : 1;
+ uint64_t pmc_lfir_action1_48 : 1;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t pmc_lfir_action1_48 : 1;
+ uint64_t pmc_lfir_action1_47 : 1;
+ uint64_t pmc_lfir_action1_37_46 : 10;
+ uint64_t pmc_lfir_action1_36 : 1;
+ uint64_t pmc_lfir_action1_35 : 1;
+ uint64_t pmc_lfir_action1_34 : 1;
+ uint64_t pmc_lfir_action1_33 : 1;
+ uint64_t pmc_lfir_action1_32 : 1;
+ uint64_t pmc_lfir_action1_31 : 1;
+ uint64_t pmc_lfir_action1_30 : 1;
+ uint64_t pmc_lfir_action1_29 : 1;
+ uint64_t pmc_lfir_action1_28 : 1;
+ uint64_t pmc_lfir_action1_27 : 1;
+ uint64_t pmc_lfir_action1_26 : 1;
+ uint64_t pmc_lfir_action1_25 : 1;
+ uint64_t pmc_lfir_action1_24 : 1;
+ uint64_t pmc_lfir_action1_23 : 1;
+ uint64_t pmc_lfir_action1_22 : 1;
+ uint64_t pmc_lfir_action1_21 : 1;
+ uint64_t pmc_lfir_action1_20 : 1;
+ uint64_t pmc_lfir_action1_19 : 1;
+ uint64_t pmc_lfir_action1_18 : 1;
+ uint64_t pmc_lfir_action1_17 : 1;
+ uint64_t pmc_lfir_action1_16 : 1;
+ uint64_t pmc_lfir_action1_15 : 1;
+ uint64_t pmc_lfir_action1_14 : 1;
+ uint64_t pmc_lfir_action1_13 : 1;
+ uint64_t pmc_lfir_action1_12 : 1;
+ uint64_t pmc_lfir_action1_11 : 1;
+ uint64_t pmc_lfir_action1_10 : 1;
+ uint64_t pmc_lfir_action1_9 : 1;
+ uint64_t pmc_lfir_action1_8 : 1;
+ uint64_t pmc_lfir_action1_7 : 1;
+ uint64_t pmc_lfir_action1_6 : 1;
+ uint64_t pmc_lfir_action1_5 : 1;
+ uint64_t pmc_lfir_action1_4 : 1;
+ uint64_t pmc_lfir_action1_3 : 1;
+ uint64_t pmc_lfir_action1_2 : 1;
+ uint64_t pmc_lfir_action1_1 : 1;
+ uint64_t pmc_lfir_action1_0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_action1_reg_t;
+
+
+
+typedef union pmc_lfir_wof_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pmc_lfir_wof : 49;
+ uint64_t _reserved0 : 15;
+#else
+ uint64_t _reserved0 : 15;
+ uint64_t pmc_lfir_wof : 49;
+#endif // _BIG_ENDIAN
+ } fields;
+} pmc_lfir_wof_reg_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __PMC_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/pmc_register_addresses.h b/src/ssx/pgp/registers/pmc_register_addresses.h
new file mode 100755
index 0000000..96f8dac
--- /dev/null
+++ b/src/ssx/pgp/registers/pmc_register_addresses.h
@@ -0,0 +1,116 @@
+#ifndef __PMC_REGISTER_ADDRESSES_H__
+#define __PMC_REGISTER_ADDRESSES_H__
+
+// $Id: pmc_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pmc_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pmc_register_addresses.h
+/// \brief Symbolic addresses for the PMC unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define PMC_OCI_BASE 0x40010000
+#define PMC_MODE_REG 0x40010000
+#define PMC_HARDWARE_AUCTION_PSTATE_REG 0x40010008
+#define PMC_PSTATE_MONITOR_AND_CTRL_REG 0x40010010
+#define PMC_RAIL_BOUNDS_REGISTER 0x40010018
+#define PMC_GLOBAL_PSTATE_BOUNDS_REG 0x40010020
+#define PMC_PARAMETER_REG0 0x40010028
+#define PMC_PARAMETER_REG1 0x40010030
+#define PMC_EFF_GLOBAL_ACTUAL_VOLTAGE_REG 0x40010038
+#define PMC_GLOBAL_ACTUAL_VOLTAGE_REG 0x40010040
+#define PMC_STATUS_REG 0x40010048
+#define PMC_PHASE_ENABLE_REG 0x40010050
+#define PMC_UNDERVOLTING_REG 0x40010060
+#define PMC_CORE_DECONFIGURATION_REG 0x40010068
+#define PMC_INTCHP_CTRL_REG1 0x40010080
+#define PMC_INTCHP_CTRL_REG2 0x40010088
+#define PMC_INTCHP_CTRL_REG4 0x40010090
+#define PMC_INTCHP_STATUS_REG 0x40010098
+#define PMC_INTCHP_COMMAND_REG 0x400100a0
+#define PMC_INTCHP_MSG_WDATA 0x400100a8
+#define PMC_INTCHP_MSG_RDATA 0x400100b0
+#define PMC_INTCHP_PSTATE_REG 0x400100b8
+#define PMC_INTCHP_GLOBACK_REG 0x400100c0
+#define PMC_FSMSTATE_STATUS_REG 0x40010100
+#define PMC_TRACE_MODE_REG 0x40010180
+#define PMC_SPIV_CTRL_REG0A 0x40010200
+#define PMC_SPIV_CTRL_REG0B 0x40010208
+#define PMC_SPIV_CTRL_REG1 0x40010210
+#define PMC_SPIV_CTRL_REG2 0x40010218
+#define PMC_SPIV_CTRL_REG3 0x40010220
+#define PMC_SPIV_CTRL_REG4 0x40010228
+#define PMC_SPIV_STATUS_REG 0x40010230
+#define PMC_SPIV_COMMAND_REG 0x40010238
+#define PMC_O2S_CTRL_REG0A 0x40010280
+#define PMC_O2S_CTRL_REG0B 0x40010288
+#define PMC_O2S_CTRL_REG1 0x40010290
+#define PMC_O2S_CTRL_REG2 0x40010298
+#define PMC_O2S_CTRL_REG4 0x400102a8
+#define PMC_O2S_STATUS_REG 0x400102b0
+#define PMC_O2S_COMMAND_REG 0x400102b8
+#define PMC_O2S_WDATA_REG 0x400102c0
+#define PMC_O2S_RDATA_REG 0x400102c8
+#define PMC_O2P_ADDR_REG 0x40010300
+#define PMC_O2P_CTRL_STATUS_REG 0x40010308
+#define PMC_O2P_SEND_DATA_HI_REG 0x40010310
+#define PMC_O2P_SEND_DATA_LO_REG 0x40010318
+#define PMC_O2P_RECV_DATA_HI_REG 0x40010320
+#define PMC_O2P_RECV_DATA_LO_REG 0x40010328
+#define PMC_OCC_HEARTBEAT_REG 0x40010330
+#define PMC_ERROR_INT_MASK_HI_REG 0x40010338
+#define PMC_ERROR_INT_MASK_LO_REG 0x40010340
+#define PMC_IDLE_SUSPEND_MASK_REG 0x40010348
+#define PMC_PEND_IDLE_REQ_REG0 0x40010400
+#define PMC_PEND_IDLE_REQ_REG1 0x40010408
+#define PMC_PEND_IDLE_REQ_REG2 0x40010410
+#define PMC_PEND_IDLE_REQ_REG3 0x40010418
+#define PMC_SLEEP_INT_REQ_VEC_REG0 0x40010420
+#define PMC_SLEEP_INT_REQ_VEC_REG1 0x40010428
+#define PMC_SLEEP_INT_REQ_VEC_REG2 0x40010430
+#define PMC_SLEEP_INT_REQ_VEC_REG3 0x40010438
+#define PMC_WINKLE_INT_REQ_VEC_REG0 0x40010440
+#define PMC_WINKLE_INT_REQ_VEC_REG1 0x40010448
+#define PMC_WINKLE_INT_REQ_VEC_REG2 0x40010450
+#define PMC_WINKLE_INT_REQ_VEC_REG3 0x40010458
+#define PMC_NAP_INT_REQ_VEC_REG0 0x40010460
+#define PMC_NAP_INT_REQ_VEC_REG1 0x40010468
+#define PMC_PORE_REQ_REG0 0x40010470
+#define PMC_PORE_REQ_REG1 0x40010478
+#define PMC_PORE_REQ_STAT_REG 0x40010480
+#define PMC_PORE_REQ_TOUT_TH_REG 0x40010488
+#define PMC_DEEP_EXIT_MASK_REG 0x40010490
+#define PMC_DEEP_EXIT_MASK_REG_AND 0x40010500
+#define PMC_DEEP_EXIT_MASK_REG_OR 0x40010508
+#define PMC_CORE_PSTATE_REG0 0x400104a0
+#define PMC_CORE_PSTATE_REG1 0x400104a8
+#define PMC_CORE_PSTATE_REG2 0x400104b0
+#define PMC_CORE_PSTATE_REG3 0x400104b8
+#define PMC_CORE_POWER_DONATION_REG 0x400104c0
+#define PMC_PMAX_SYNC_COLLECTION_REG 0x400104c8
+#define PMC_PMAX_SYNC_COLLECTION_MASK_REG 0x400104d0
+#define PMC_GPSA_ACK_COLLECTION_REG 0x400104d8
+#define PMC_GPSA_ACK_COLLECTION_MASK_REG 0x400104e0
+#define PMC_PORE_SCRATCH_REG0 0x400104e8
+#define PMC_PORE_SCRATCH_REG1 0x400104f0
+#define PMC_DEEP_IDLE_EXIT_REG 0x400104f8
+#define PMC_DEEP_STATUS_REG 0x40010510
+#define PMC_PIB_BASE 0x01010840
+#define PMC_LFIR_ERR_REG 0x01010840
+#define PMC_LFIR_ERR_REG_AND 0x01010841
+#define PMC_LFIR_ERR_REG_OR 0x01010842
+#define PMC_LFIR_ERR_MASK_REG 0x01010843
+#define PMC_LFIR_ERR_MASK_REG_AND 0x01010844
+#define PMC_LFIR_ERR_MASK_REG_OR 0x01010845
+#define PMC_LFIR_ACTION0_REG 0x01010846
+#define PMC_LFIR_ACTION1_REG 0x01010847
+#define PMC_LFIR_WOF_REG 0x01010848
+
+#endif // __PMC_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/pore_firmware_registers.h b/src/ssx/pgp/registers/pore_firmware_registers.h
new file mode 100755
index 0000000..76127d9
--- /dev/null
+++ b/src/ssx/pgp/registers/pore_firmware_registers.h
@@ -0,0 +1,906 @@
+#ifndef __PORE_FIRMWARE_REGISTERS_H__
+#define __PORE_FIRMWARE_REGISTERS_H__
+
+// $Id: pore_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pore_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pore_firmware_registers.h
+/// \brief C register structs for the PORE unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union pore_status {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cur_state : 8;
+ uint64_t freeze_action : 1;
+ uint64_t interrupt_pending : 1;
+ uint64_t spare : 2;
+ uint64_t stack_pointer : 4;
+ uint64_t pc : 48;
+#else
+ uint64_t pc : 48;
+ uint64_t stack_pointer : 4;
+ uint64_t spare : 2;
+ uint64_t interrupt_pending : 1;
+ uint64_t freeze_action : 1;
+ uint64_t cur_state : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_status_t;
+
+#endif // __ASSEMBLER__
+#define PORE_STATUS_CUR_STATE_MASK SIXTYFOUR_BIT_CONSTANT(0xff00000000000000)
+#define PORE_STATUS_FREEZE_ACTION SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PORE_STATUS_INTERRUPT_PENDING SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PORE_STATUS_SPARE_MASK SIXTYFOUR_BIT_CONSTANT(0x0030000000000000)
+#define PORE_STATUS_STACK_POINTER_MASK SIXTYFOUR_BIT_CONSTANT(0x000f000000000000)
+#define PORE_STATUS_PC_MASK SIXTYFOUR_BIT_CONSTANT(0xffffffffffffffff)
+#ifndef __ASSEMBLER__
+
+
+typedef union pore_control {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t start_stop : 1;
+ uint64_t continue_step : 1;
+ uint64_t skip : 1;
+ uint64_t set_pc : 1;
+ uint64_t set_tp_scan_clk : 3;
+ uint64_t lock_exe_trig : 1;
+ uint64_t freeze_mask : 1;
+ uint64_t check_parity : 1;
+ uint64_t prv_parity : 1;
+ uint64_t trap_enable : 1;
+ uint64_t narrow_mode_trace : 1;
+ uint64_t interruptible : 1;
+ uint64_t pore_done_override : 1;
+ uint64_t interruptible_en : 1;
+ uint64_t pc_brk_pt : 48;
+#else
+ uint64_t pc_brk_pt : 48;
+ uint64_t interruptible_en : 1;
+ uint64_t pore_done_override : 1;
+ uint64_t interruptible : 1;
+ uint64_t narrow_mode_trace : 1;
+ uint64_t trap_enable : 1;
+ uint64_t prv_parity : 1;
+ uint64_t check_parity : 1;
+ uint64_t freeze_mask : 1;
+ uint64_t lock_exe_trig : 1;
+ uint64_t set_tp_scan_clk : 3;
+ uint64_t set_pc : 1;
+ uint64_t skip : 1;
+ uint64_t continue_step : 1;
+ uint64_t start_stop : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_control_t;
+
+#endif // __ASSEMBLER__
+#define PORE_CONTROL_START_STOP SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PORE_CONTROL_CONTINUE_STEP SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define PORE_CONTROL_SKIP SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define PORE_CONTROL_SET_PC SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define PORE_CONTROL_SET_TP_SCAN_CLK_MASK SIXTYFOUR_BIT_CONSTANT(0x0e00000000000000)
+#define PORE_CONTROL_LOCK_EXE_TRIG SIXTYFOUR_BIT_CONSTANT(0x0100000000000000)
+#define PORE_CONTROL_FREEZE_MASK SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PORE_CONTROL_CHECK_PARITY SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PORE_CONTROL_PRV_PARITY SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define PORE_CONTROL_TRAP_ENABLE SIXTYFOUR_BIT_CONSTANT(0x0010000000000000)
+#define PORE_CONTROL_NARROW_MODE_TRACE SIXTYFOUR_BIT_CONSTANT(0x0008000000000000)
+#define PORE_CONTROL_INTERRUPTIBLE SIXTYFOUR_BIT_CONSTANT(0x0004000000000000)
+#define PORE_CONTROL_PORE_DONE_OVERRIDE SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#define PORE_CONTROL_INTERRUPTIBLE_EN SIXTYFOUR_BIT_CONSTANT(0x0001000000000000)
+#define PORE_CONTROL_PC_BRK_PT_MASK SIXTYFOUR_BIT_CONSTANT(0xffffffffffffffff)
+#ifndef __ASSEMBLER__
+
+
+typedef union pore_reset {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t fn_reset : 1;
+ uint64_t oci_reset : 1;
+ uint64_t _reserved0 : 62;
+#else
+ uint64_t _reserved0 : 62;
+ uint64_t oci_reset : 1;
+ uint64_t fn_reset : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_reset_t;
+
+
+
+typedef union pore_error_mask {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t enable_err_handler0 : 1;
+ uint64_t enable_err_handler1 : 1;
+ uint64_t enable_err_handler2 : 1;
+ uint64_t enable_err_handler3 : 1;
+ uint64_t enable_err_handler4 : 1;
+ uint64_t enable_err_output0 : 1;
+ uint64_t enable_err_output1 : 1;
+ uint64_t enable_err_output2 : 1;
+ uint64_t enable_err_output3 : 1;
+ uint64_t enable_err_output4 : 1;
+ uint64_t enable_fatal_err_output0 : 1;
+ uint64_t enable_fatal_err_output1 : 1;
+ uint64_t enable_fatal_err_output2 : 1;
+ uint64_t enable_fatal_err_output3 : 1;
+ uint64_t enable_fatal_err_output4 : 1;
+ uint64_t stop_exe_on_error0 : 1;
+ uint64_t stop_exe_on_error1 : 1;
+ uint64_t stop_exe_on_error2 : 1;
+ uint64_t stop_exe_on_error3 : 1;
+ uint64_t stop_exe_on_error4 : 1;
+ uint64_t gate_chiplet_offline_err : 1;
+ uint64_t i2c_bad_status_0 : 1;
+ uint64_t i2c_bad_status_1 : 1;
+ uint64_t i2c_bad_status_2 : 1;
+ uint64_t i2c_bad_status_3 : 1;
+ uint64_t group_parity_error_0 : 1;
+ uint64_t group_parity_error_1 : 1;
+ uint64_t group_parity_error_2 : 1;
+ uint64_t group_parity_error_3 : 1;
+ uint64_t group_parity_error_4 : 1;
+ uint64_t _reserved0 : 34;
+#else
+ uint64_t _reserved0 : 34;
+ uint64_t group_parity_error_4 : 1;
+ uint64_t group_parity_error_3 : 1;
+ uint64_t group_parity_error_2 : 1;
+ uint64_t group_parity_error_1 : 1;
+ uint64_t group_parity_error_0 : 1;
+ uint64_t i2c_bad_status_3 : 1;
+ uint64_t i2c_bad_status_2 : 1;
+ uint64_t i2c_bad_status_1 : 1;
+ uint64_t i2c_bad_status_0 : 1;
+ uint64_t gate_chiplet_offline_err : 1;
+ uint64_t stop_exe_on_error4 : 1;
+ uint64_t stop_exe_on_error3 : 1;
+ uint64_t stop_exe_on_error2 : 1;
+ uint64_t stop_exe_on_error1 : 1;
+ uint64_t stop_exe_on_error0 : 1;
+ uint64_t enable_fatal_err_output4 : 1;
+ uint64_t enable_fatal_err_output3 : 1;
+ uint64_t enable_fatal_err_output2 : 1;
+ uint64_t enable_fatal_err_output1 : 1;
+ uint64_t enable_fatal_err_output0 : 1;
+ uint64_t enable_err_output4 : 1;
+ uint64_t enable_err_output3 : 1;
+ uint64_t enable_err_output2 : 1;
+ uint64_t enable_err_output1 : 1;
+ uint64_t enable_err_output0 : 1;
+ uint64_t enable_err_handler4 : 1;
+ uint64_t enable_err_handler3 : 1;
+ uint64_t enable_err_handler2 : 1;
+ uint64_t enable_err_handler1 : 1;
+ uint64_t enable_err_handler0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_error_mask_t;
+
+#endif // __ASSEMBLER__
+#define PORE_ERROR_MASK_ENABLE_ERR_HANDLER0 SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_HANDLER1 SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_HANDLER2 SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_HANDLER3 SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_HANDLER4 SIXTYFOUR_BIT_CONSTANT(0x0800000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_OUTPUT0 SIXTYFOUR_BIT_CONSTANT(0x0400000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_OUTPUT1 SIXTYFOUR_BIT_CONSTANT(0x0200000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_OUTPUT2 SIXTYFOUR_BIT_CONSTANT(0x0100000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_OUTPUT3 SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PORE_ERROR_MASK_ENABLE_ERR_OUTPUT4 SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT0 SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT1 SIXTYFOUR_BIT_CONSTANT(0x0010000000000000)
+#define PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT2 SIXTYFOUR_BIT_CONSTANT(0x0008000000000000)
+#define PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT3 SIXTYFOUR_BIT_CONSTANT(0x0004000000000000)
+#define PORE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT4 SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#define PORE_ERROR_MASK_STOP_EXE_ON_ERROR0 SIXTYFOUR_BIT_CONSTANT(0x0001000000000000)
+#define PORE_ERROR_MASK_STOP_EXE_ON_ERROR1 SIXTYFOUR_BIT_CONSTANT(0x0000800000000000)
+#define PORE_ERROR_MASK_STOP_EXE_ON_ERROR2 SIXTYFOUR_BIT_CONSTANT(0x0000400000000000)
+#define PORE_ERROR_MASK_STOP_EXE_ON_ERROR3 SIXTYFOUR_BIT_CONSTANT(0x0000200000000000)
+#define PORE_ERROR_MASK_STOP_EXE_ON_ERROR4 SIXTYFOUR_BIT_CONSTANT(0x0000100000000000)
+#define PORE_ERROR_MASK_GATE_CHIPLET_OFFLINE_ERR SIXTYFOUR_BIT_CONSTANT(0x0000080000000000)
+#define PORE_ERROR_MASK_I2C_BAD_STATUS_0 SIXTYFOUR_BIT_CONSTANT(0x0000040000000000)
+#define PORE_ERROR_MASK_I2C_BAD_STATUS_1 SIXTYFOUR_BIT_CONSTANT(0x0000020000000000)
+#define PORE_ERROR_MASK_I2C_BAD_STATUS_2 SIXTYFOUR_BIT_CONSTANT(0x0000010000000000)
+#define PORE_ERROR_MASK_I2C_BAD_STATUS_3 SIXTYFOUR_BIT_CONSTANT(0x0000008000000000)
+#define PORE_ERROR_MASK_GROUP_PARITY_ERROR_0 SIXTYFOUR_BIT_CONSTANT(0x0000004000000000)
+#define PORE_ERROR_MASK_GROUP_PARITY_ERROR_1 SIXTYFOUR_BIT_CONSTANT(0x0000002000000000)
+#define PORE_ERROR_MASK_GROUP_PARITY_ERROR_2 SIXTYFOUR_BIT_CONSTANT(0x0000001000000000)
+#define PORE_ERROR_MASK_GROUP_PARITY_ERROR_3 SIXTYFOUR_BIT_CONSTANT(0x0000000800000000)
+#define PORE_ERROR_MASK_GROUP_PARITY_ERROR_4 SIXTYFOUR_BIT_CONSTANT(0x0000000400000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pore_prv_base_address0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 25;
+ uint64_t mc : 1;
+ uint64_t chiplet_id : 6;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t chiplet_id : 6;
+ uint64_t mc : 1;
+ uint64_t spare : 25;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_prv_base_address0_t;
+
+
+
+typedef union pore_prv_base_address1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 25;
+ uint64_t mc : 1;
+ uint64_t chiplet_id : 6;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t chiplet_id : 6;
+ uint64_t mc : 1;
+ uint64_t spare : 25;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_prv_base_address1_t;
+
+
+
+typedef union pore_oci_base_address0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 18;
+ uint64_t oci_mem_route : 14;
+ uint64_t oci_base_address : 32;
+#else
+ uint64_t oci_base_address : 32;
+ uint64_t oci_mem_route : 14;
+ uint64_t spare : 18;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_oci_base_address0_t;
+
+
+
+typedef union pore_oci_base_address1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 18;
+ uint64_t oci_mem_route : 14;
+ uint64_t oci_base_address : 32;
+#else
+ uint64_t oci_base_address : 32;
+ uint64_t oci_mem_route : 14;
+ uint64_t spare : 18;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_oci_base_address1_t;
+
+
+
+typedef union pore_table_base_addr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 16;
+ uint64_t memory_space : 16;
+ uint64_t table_base_address : 32;
+#else
+ uint64_t table_base_address : 32;
+ uint64_t memory_space : 16;
+ uint64_t reserved : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_table_base_addr_t;
+
+
+
+typedef union pore_exe_trigger {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 8;
+ uint64_t start_vector : 4;
+ uint64_t zeroes : 8;
+ uint64_t unused : 12;
+ uint64_t mc_chiplet_select_mask : 32;
+#else
+ uint64_t mc_chiplet_select_mask : 32;
+ uint64_t unused : 12;
+ uint64_t zeroes : 8;
+ uint64_t start_vector : 4;
+ uint64_t reserved : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_exe_trigger_t;
+
+
+
+typedef union pore_scratch0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t zeroes : 8;
+ uint64_t scratch0 : 24;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t scratch0 : 24;
+ uint64_t zeroes : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_scratch0_t;
+
+
+
+typedef union pore_scratch1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t scratch1 : 64;
+#else
+ uint64_t scratch1 : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_scratch1_t;
+
+
+
+typedef union pore_scratch2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t scratch2 : 64;
+#else
+ uint64_t scratch2 : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_scratch2_t;
+
+
+
+typedef union pore_ibuf_01 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ibuf0 : 32;
+ uint64_t ibuf1 : 32;
+#else
+ uint64_t ibuf1 : 32;
+ uint64_t ibuf0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_ibuf_01_t;
+
+
+
+typedef union pore_ibuf_2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ibuf2 : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t ibuf2 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_ibuf_2_t;
+
+
+
+typedef union pore_dbg0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t last_completed_address : 32;
+ uint64_t last_pib_parity_fail : 1;
+ uint64_t last_ret_code_prv : 3;
+ uint64_t i2c_bad_status0 : 1;
+ uint64_t i2c_bad_status1 : 1;
+ uint64_t i2c_bad_status2 : 1;
+ uint64_t i2c_bad_status3 : 1;
+ uint64_t group_parity_error0 : 1;
+ uint64_t group_parity_error1 : 1;
+ uint64_t group_parity_error2 : 1;
+ uint64_t group_parity_error3 : 1;
+ uint64_t group_parity_error4 : 1;
+ uint64_t interrupt_counter : 8;
+ uint64_t _reserved0 : 11;
+#else
+ uint64_t _reserved0 : 11;
+ uint64_t interrupt_counter : 8;
+ uint64_t group_parity_error4 : 1;
+ uint64_t group_parity_error3 : 1;
+ uint64_t group_parity_error2 : 1;
+ uint64_t group_parity_error1 : 1;
+ uint64_t group_parity_error0 : 1;
+ uint64_t i2c_bad_status3 : 1;
+ uint64_t i2c_bad_status2 : 1;
+ uint64_t i2c_bad_status1 : 1;
+ uint64_t i2c_bad_status0 : 1;
+ uint64_t last_ret_code_prv : 3;
+ uint64_t last_pib_parity_fail : 1;
+ uint64_t last_completed_address : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_dbg0_t;
+
+
+
+typedef union pore_dbg1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_last_access : 48;
+ uint64_t oci_master_rd_parity_err : 1;
+ uint64_t last_ret_code_oci : 3;
+ uint64_t bad_instr_parity : 1;
+ uint64_t invalid_instr_code : 1;
+ uint64_t pc_overflow_underrun : 1;
+ uint64_t bad_scan_crc : 1;
+ uint64_t pc_stack_ovflw_undrn_err : 1;
+ uint64_t instruction_fetch_error : 1;
+ uint64_t invalid_instruction_operand : 1;
+ uint64_t invalid_instruction_path : 1;
+ uint64_t invalid_start_vector : 1;
+ uint64_t fast_i2c_protocol_hang : 1;
+ uint64_t spare : 1;
+ uint64_t debug_regs_locked : 1;
+#else
+ uint64_t debug_regs_locked : 1;
+ uint64_t spare : 1;
+ uint64_t fast_i2c_protocol_hang : 1;
+ uint64_t invalid_start_vector : 1;
+ uint64_t invalid_instruction_path : 1;
+ uint64_t invalid_instruction_operand : 1;
+ uint64_t instruction_fetch_error : 1;
+ uint64_t pc_stack_ovflw_undrn_err : 1;
+ uint64_t bad_scan_crc : 1;
+ uint64_t pc_overflow_underrun : 1;
+ uint64_t invalid_instr_code : 1;
+ uint64_t bad_instr_parity : 1;
+ uint64_t last_ret_code_oci : 3;
+ uint64_t oci_master_rd_parity_err : 1;
+ uint64_t pc_last_access : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_dbg1_t;
+
+
+
+typedef union pore_pc_stack0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_stack0 : 48;
+ uint64_t _reserved0 : 11;
+ uint64_t set_new_stack_pointer : 1;
+ uint64_t new_stack_pointer : 4;
+#else
+ uint64_t new_stack_pointer : 4;
+ uint64_t set_new_stack_pointer : 1;
+ uint64_t _reserved0 : 11;
+ uint64_t pc_stack0 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_pc_stack0_t;
+
+
+
+typedef union pore_pc_stack1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_stack1 : 48;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t pc_stack1 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_pc_stack1_t;
+
+
+
+typedef union pore_pc_stack2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_stack2 : 48;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t pc_stack2 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_pc_stack2_t;
+
+
+
+typedef union pore_id_flags {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 32;
+ uint64_t pib_parity_fail : 1;
+ uint64_t pib_status : 3;
+ uint64_t oci_parity_fail : 1;
+ uint64_t oci_status : 3;
+ uint64_t reserved1 : 8;
+ uint64_t ugt : 1;
+ uint64_t ult : 1;
+ uint64_t sgt : 1;
+ uint64_t slt : 1;
+ uint64_t c : 1;
+ uint64_t o : 1;
+ uint64_t n : 1;
+ uint64_t z : 1;
+ uint64_t reserved2 : 4;
+ uint64_t ibuf_id : 4;
+#else
+ uint64_t ibuf_id : 4;
+ uint64_t reserved2 : 4;
+ uint64_t z : 1;
+ uint64_t n : 1;
+ uint64_t o : 1;
+ uint64_t c : 1;
+ uint64_t slt : 1;
+ uint64_t sgt : 1;
+ uint64_t ult : 1;
+ uint64_t ugt : 1;
+ uint64_t reserved1 : 8;
+ uint64_t oci_status : 3;
+ uint64_t oci_parity_fail : 1;
+ uint64_t pib_status : 3;
+ uint64_t pib_parity_fail : 1;
+ uint64_t reserved0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_id_flags_t;
+
+
+
+typedef union pore_data0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t data0 : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t data0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_data0_t;
+
+
+
+typedef union pore_memory_reloc {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 30;
+ uint64_t memory_reloc_region : 2;
+ uint64_t memory_reloc_base : 20;
+ uint64_t _reserved1 : 12;
+#else
+ uint64_t _reserved1 : 12;
+ uint64_t memory_reloc_base : 20;
+ uint64_t memory_reloc_region : 2;
+ uint64_t _reserved0 : 30;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_memory_reloc_t;
+
+
+
+typedef union pore_i2c_en_param {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t i2c_engine_identifier : 4;
+ uint64_t reserved0 : 1;
+ uint64_t i2c_engine_address_range : 3;
+ uint64_t reserved1 : 3;
+ uint64_t i2c_engine_port : 5;
+ uint64_t reserved2 : 1;
+ uint64_t i2c_engine_device_id : 7;
+ uint64_t reserved3 : 2;
+ uint64_t i2c_engine_speed : 2;
+ uint64_t i2c_poll_threshold : 4;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t i2c_poll_threshold : 4;
+ uint64_t i2c_engine_speed : 2;
+ uint64_t reserved3 : 2;
+ uint64_t i2c_engine_device_id : 7;
+ uint64_t reserved2 : 1;
+ uint64_t i2c_engine_port : 5;
+ uint64_t reserved1 : 3;
+ uint64_t i2c_engine_address_range : 3;
+ uint64_t reserved0 : 1;
+ uint64_t i2c_engine_identifier : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_i2c_en_param_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __PORE_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/pore_register_addresses.h b/src/ssx/pgp/registers/pore_register_addresses.h
new file mode 100755
index 0000000..0fc769b
--- /dev/null
+++ b/src/ssx/pgp/registers/pore_register_addresses.h
@@ -0,0 +1,130 @@
+#ifndef __PORE_REGISTER_ADDRESSES_H__
+#define __PORE_REGISTER_ADDRESSES_H__
+
+// $Id: pore_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/pore_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file pore_register_addresses.h
+/// \brief Symbolic addresses for the PORE unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define PORE_GPE0_OCI_BASE 0x40000000
+#define PORE_GPE1_OCI_BASE 0x40000100
+#define PORE_SLW_OCI_BASE 0x40040000
+#define PORE_STATUS_OFFSET 0x00000000
+#define PORE_GPE0_STATUS 0x40000000
+#define PORE_GPE1_STATUS 0x40000100
+#define PORE_SLW_STATUS 0x40040000
+#define PORE_CONTROL_OFFSET 0x00000008
+#define PORE_GPE0_CONTROL 0x40000008
+#define PORE_GPE1_CONTROL 0x40000108
+#define PORE_SLW_CONTROL 0x40040008
+#define PORE_RESET_OFFSET 0x00000010
+#define PORE_GPE0_RESET 0x40000010
+#define PORE_GPE1_RESET 0x40000110
+#define PORE_SLW_RESET 0x40040010
+#define PORE_ERROR_MASK_OFFSET 0x00000018
+#define PORE_GPE0_ERROR_MASK 0x40000018
+#define PORE_GPE1_ERROR_MASK 0x40000118
+#define PORE_SLW_ERROR_MASK 0x40040018
+#define PORE_PRV_BASE_ADDRESS0_OFFSET 0x00000020
+#define PORE_GPE0_PRV_BASE_ADDRESS0 0x40000020
+#define PORE_GPE1_PRV_BASE_ADDRESS0 0x40000120
+#define PORE_SLW_PRV_BASE_ADDRESS0 0x40040020
+#define PORE_PRV_BASE_ADDRESS1_OFFSET 0x00000028
+#define PORE_GPE0_PRV_BASE_ADDRESS1 0x40000028
+#define PORE_GPE1_PRV_BASE_ADDRESS1 0x40000128
+#define PORE_SLW_PRV_BASE_ADDRESS1 0x40040028
+#define PORE_OCI_BASE_ADDRESS0_OFFSET 0x00000030
+#define PORE_GPE0_OCI_BASE_ADDRESS0 0x40000030
+#define PORE_GPE1_OCI_BASE_ADDRESS0 0x40000130
+#define PORE_SLW_OCI_BASE_ADDRESS0 0x40040030
+#define PORE_OCI_BASE_ADDRESS1_OFFSET 0x00000038
+#define PORE_GPE0_OCI_BASE_ADDRESS1 0x40000038
+#define PORE_GPE1_OCI_BASE_ADDRESS1 0x40000138
+#define PORE_SLW_OCI_BASE_ADDRESS1 0x40040038
+#define PORE_TABLE_BASE_ADDR_OFFSET 0x00000040
+#define PORE_GPE0_TABLE_BASE_ADDR 0x40000040
+#define PORE_GPE1_TABLE_BASE_ADDR 0x40000140
+#define PORE_SLW_TABLE_BASE_ADDR 0x40040040
+#define PORE_EXE_TRIGGER_OFFSET 0x00000048
+#define PORE_GPE0_EXE_TRIGGER 0x40000048
+#define PORE_GPE1_EXE_TRIGGER 0x40000148
+#define PORE_SLW_EXE_TRIGGER 0x40040048
+#define PORE_SCRATCH0_OFFSET 0x00000050
+#define PORE_GPE0_SCRATCH0 0x40000050
+#define PORE_GPE1_SCRATCH0 0x40000150
+#define PORE_SLW_SCRATCH0 0x40040050
+#define PORE_SCRATCH1_OFFSET 0x00000058
+#define PORE_GPE0_SCRATCH1 0x40000058
+#define PORE_GPE1_SCRATCH1 0x40000158
+#define PORE_SLW_SCRATCH1 0x40040058
+#define PORE_SCRATCH2_OFFSET 0x00000060
+#define PORE_GPE0_SCRATCH2 0x40000060
+#define PORE_GPE1_SCRATCH2 0x40000160
+#define PORE_SLW_SCRATCH2 0x40040060
+#define PORE_IBUF_01_OFFSET 0x00000068
+#define PORE_GPE0_IBUF_01 0x40000068
+#define PORE_GPE1_IBUF_01 0x40000168
+#define PORE_SLW_IBUF_01 0x40040068
+#define PORE_IBUF_2_OFFSET 0x00000070
+#define PORE_GPE0_IBUF_2 0x40000070
+#define PORE_GPE1_IBUF_2 0x40000170
+#define PORE_SLW_IBUF_2 0x40040070
+#define PORE_DBG0_OFFSET 0x00000078
+#define PORE_GPE0_DBG0 0x40000078
+#define PORE_GPE1_DBG0 0x40000178
+#define PORE_SLW_DBG0 0x40040078
+#define PORE_DBG1_OFFSET 0x00000080
+#define PORE_GPE0_DBG1 0x40000080
+#define PORE_GPE1_DBG1 0x40000180
+#define PORE_SLW_DBG1 0x40040080
+#define PORE_PC_STACK0_OFFSET 0x00000088
+#define PORE_GPE0_PC_STACK0 0x40000088
+#define PORE_GPE1_PC_STACK0 0x40000188
+#define PORE_SLW_PC_STACK0 0x40040088
+#define PORE_PC_STACK1_OFFSET 0x00000090
+#define PORE_GPE0_PC_STACK1 0x40000090
+#define PORE_GPE1_PC_STACK1 0x40000190
+#define PORE_SLW_PC_STACK1 0x40040090
+#define PORE_PC_STACK2_OFFSET 0x00000098
+#define PORE_GPE0_PC_STACK2 0x40000098
+#define PORE_GPE1_PC_STACK2 0x40000198
+#define PORE_SLW_PC_STACK2 0x40040098
+#define PORE_ID_FLAGS_OFFSET 0x000000a0
+#define PORE_GPE0_ID_FLAGS 0x400000a0
+#define PORE_GPE1_ID_FLAGS 0x400001a0
+#define PORE_SLW_ID_FLAGS 0x400400a0
+#define PORE_DATA0_OFFSET 0x000000a8
+#define PORE_GPE0_DATA0 0x400000a8
+#define PORE_GPE1_DATA0 0x400001a8
+#define PORE_SLW_DATA0 0x400400a8
+#define PORE_MEMORY_RELOC_OFFSET 0x000000b0
+#define PORE_GPE0_MEMORY_RELOC 0x400000b0
+#define PORE_GPE1_MEMORY_RELOC 0x400001b0
+#define PORE_SLW_MEMORY_RELOC 0x400400b0
+#define PORE_I2C_E0_PARAM_OFFSET 0x000000b8
+#define PORE_I2C_E1_PARAM_OFFSET 0x000000c0
+#define PORE_I2C_E2_PARAM_OFFSET 0x000000c8
+#define PORE_GPE0_I2C_EN_PARAM(n) (PORE_GPE0_I2C_E0_PARAM + ((PORE_GPE0_I2C_E1_PARAM - PORE_GPE0_I2C_E0_PARAM) * (n)))
+#define PORE_GPE1_I2C_EN_PARAM(n) (PORE_GPE1_I2C_E0_PARAM + ((PORE_GPE1_I2C_E1_PARAM - PORE_GPE1_I2C_E0_PARAM) * (n)))
+#define PORE_SLW_I2C_EN_PARAM(n) (PORE_SLW_I2C_E0_PARAM + ((PORE_SLW_I2C_E1_PARAM - PORE_SLW_I2C_E0_PARAM) * (n)))
+#define PORE_GPE0_I2C_E0_PARAM 0x400000b8
+#define PORE_GPE1_I2C_E0_PARAM 0x400001b8
+#define PORE_SLW_I2C_E0_PARAM 0x400400b8
+#define PORE_GPE0_I2C_E1_PARAM 0x400000c0
+#define PORE_GPE1_I2C_E1_PARAM 0x400001c0
+#define PORE_SLW_I2C_E1_PARAM 0x400400c0
+#define PORE_GPE0_I2C_E2_PARAM 0x400000c8
+#define PORE_GPE1_I2C_E2_PARAM 0x400001c8
+#define PORE_SLW_I2C_E2_PARAM 0x400400c8
+
+#endif // __PORE_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/sbe_firmware_registers.h b/src/ssx/pgp/registers/sbe_firmware_registers.h
new file mode 100644
index 0000000..8175c11
--- /dev/null
+++ b/src/ssx/pgp/registers/sbe_firmware_registers.h
@@ -0,0 +1,906 @@
+#ifndef __SBE_FIRMWARE_REGISTERS_H__
+#define __SBE_FIRMWARE_REGISTERS_H__
+
+// $Id: sbe_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/sbe_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sbe_firmware_registers.h
+/// \brief C register structs for the SBE unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union pore_sbe_status {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cur_state : 8;
+ uint64_t freeze_action : 1;
+ uint64_t interrupt_pending : 1;
+ uint64_t spare : 2;
+ uint64_t stack_pointer : 4;
+ uint64_t pc : 48;
+#else
+ uint64_t pc : 48;
+ uint64_t stack_pointer : 4;
+ uint64_t spare : 2;
+ uint64_t interrupt_pending : 1;
+ uint64_t freeze_action : 1;
+ uint64_t cur_state : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_status_t;
+
+#endif // __ASSEMBLER__
+#define PORE_SBE_STATUS_CUR_STATE_MASK SIXTYFOUR_BIT_CONSTANT(0xff00000000000000)
+#define PORE_SBE_STATUS_FREEZE_ACTION SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PORE_SBE_STATUS_INTERRUPT_PENDING SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PORE_SBE_STATUS_SPARE_MASK SIXTYFOUR_BIT_CONSTANT(0x0030000000000000)
+#define PORE_SBE_STATUS_STACK_POINTER_MASK SIXTYFOUR_BIT_CONSTANT(0x000f000000000000)
+#define PORE_SBE_STATUS_PC_MASK SIXTYFOUR_BIT_CONSTANT(0xffffffffffffffff)
+#ifndef __ASSEMBLER__
+
+
+typedef union pore_sbe_control {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t start_stop : 1;
+ uint64_t continue_step : 1;
+ uint64_t skip : 1;
+ uint64_t set_pc : 1;
+ uint64_t set_tp_scan_clk : 3;
+ uint64_t lock_exe_trig : 1;
+ uint64_t freeze_mask : 1;
+ uint64_t check_parity : 1;
+ uint64_t prv_parity : 1;
+ uint64_t trap_enable : 1;
+ uint64_t narrow_mode_trace : 1;
+ uint64_t interruptible : 1;
+ uint64_t pore_done_override : 1;
+ uint64_t interruptible_en : 1;
+ uint64_t pc_brk_pt : 48;
+#else
+ uint64_t pc_brk_pt : 48;
+ uint64_t interruptible_en : 1;
+ uint64_t pore_done_override : 1;
+ uint64_t interruptible : 1;
+ uint64_t narrow_mode_trace : 1;
+ uint64_t trap_enable : 1;
+ uint64_t prv_parity : 1;
+ uint64_t check_parity : 1;
+ uint64_t freeze_mask : 1;
+ uint64_t lock_exe_trig : 1;
+ uint64_t set_tp_scan_clk : 3;
+ uint64_t set_pc : 1;
+ uint64_t skip : 1;
+ uint64_t continue_step : 1;
+ uint64_t start_stop : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_control_t;
+
+#endif // __ASSEMBLER__
+#define PORE_SBE_CONTROL_START_STOP SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PORE_SBE_CONTROL_CONTINUE_STEP SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define PORE_SBE_CONTROL_SKIP SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define PORE_SBE_CONTROL_SET_PC SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define PORE_SBE_CONTROL_SET_TP_SCAN_CLK_MASK SIXTYFOUR_BIT_CONSTANT(0x0e00000000000000)
+#define PORE_SBE_CONTROL_LOCK_EXE_TRIG SIXTYFOUR_BIT_CONSTANT(0x0100000000000000)
+#define PORE_SBE_CONTROL_FREEZE_MASK SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PORE_SBE_CONTROL_CHECK_PARITY SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PORE_SBE_CONTROL_PRV_PARITY SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define PORE_SBE_CONTROL_TRAP_ENABLE SIXTYFOUR_BIT_CONSTANT(0x0010000000000000)
+#define PORE_SBE_CONTROL_NARROW_MODE_TRACE SIXTYFOUR_BIT_CONSTANT(0x0008000000000000)
+#define PORE_SBE_CONTROL_INTERRUPTIBLE SIXTYFOUR_BIT_CONSTANT(0x0004000000000000)
+#define PORE_SBE_CONTROL_PORE_DONE_OVERRIDE SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#define PORE_SBE_CONTROL_INTERRUPTIBLE_EN SIXTYFOUR_BIT_CONSTANT(0x0001000000000000)
+#define PORE_SBE_CONTROL_PC_BRK_PT_MASK SIXTYFOUR_BIT_CONSTANT(0xffffffffffffffff)
+#ifndef __ASSEMBLER__
+
+
+typedef union pore_sbe_reset {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t fn_reset : 1;
+ uint64_t oci_reset : 1;
+ uint64_t _reserved0 : 62;
+#else
+ uint64_t _reserved0 : 62;
+ uint64_t oci_reset : 1;
+ uint64_t fn_reset : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_reset_t;
+
+
+
+typedef union pore_sbe_error_mask {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t enable_err_handler0 : 1;
+ uint64_t enable_err_handler1 : 1;
+ uint64_t enable_err_handler2 : 1;
+ uint64_t enable_err_handler3 : 1;
+ uint64_t enable_err_handler4 : 1;
+ uint64_t enable_err_output0 : 1;
+ uint64_t enable_err_output1 : 1;
+ uint64_t enable_err_output2 : 1;
+ uint64_t enable_err_output3 : 1;
+ uint64_t enable_err_output4 : 1;
+ uint64_t enable_fatal_err_output0 : 1;
+ uint64_t enable_fatal_err_output1 : 1;
+ uint64_t enable_fatal_err_output2 : 1;
+ uint64_t enable_fatal_err_output3 : 1;
+ uint64_t enable_fatal_err_output4 : 1;
+ uint64_t stop_exe_on_error0 : 1;
+ uint64_t stop_exe_on_error1 : 1;
+ uint64_t stop_exe_on_error2 : 1;
+ uint64_t stop_exe_on_error3 : 1;
+ uint64_t stop_exe_on_error4 : 1;
+ uint64_t gate_chiplet_offline_err : 1;
+ uint64_t i2c_bad_status_0 : 1;
+ uint64_t i2c_bad_status_1 : 1;
+ uint64_t i2c_bad_status_2 : 1;
+ uint64_t i2c_bad_status_3 : 1;
+ uint64_t group_parity_error_0 : 1;
+ uint64_t group_parity_error_1 : 1;
+ uint64_t group_parity_error_2 : 1;
+ uint64_t group_parity_error_3 : 1;
+ uint64_t group_parity_error_4 : 1;
+ uint64_t _reserved0 : 34;
+#else
+ uint64_t _reserved0 : 34;
+ uint64_t group_parity_error_4 : 1;
+ uint64_t group_parity_error_3 : 1;
+ uint64_t group_parity_error_2 : 1;
+ uint64_t group_parity_error_1 : 1;
+ uint64_t group_parity_error_0 : 1;
+ uint64_t i2c_bad_status_3 : 1;
+ uint64_t i2c_bad_status_2 : 1;
+ uint64_t i2c_bad_status_1 : 1;
+ uint64_t i2c_bad_status_0 : 1;
+ uint64_t gate_chiplet_offline_err : 1;
+ uint64_t stop_exe_on_error4 : 1;
+ uint64_t stop_exe_on_error3 : 1;
+ uint64_t stop_exe_on_error2 : 1;
+ uint64_t stop_exe_on_error1 : 1;
+ uint64_t stop_exe_on_error0 : 1;
+ uint64_t enable_fatal_err_output4 : 1;
+ uint64_t enable_fatal_err_output3 : 1;
+ uint64_t enable_fatal_err_output2 : 1;
+ uint64_t enable_fatal_err_output1 : 1;
+ uint64_t enable_fatal_err_output0 : 1;
+ uint64_t enable_err_output4 : 1;
+ uint64_t enable_err_output3 : 1;
+ uint64_t enable_err_output2 : 1;
+ uint64_t enable_err_output1 : 1;
+ uint64_t enable_err_output0 : 1;
+ uint64_t enable_err_handler4 : 1;
+ uint64_t enable_err_handler3 : 1;
+ uint64_t enable_err_handler2 : 1;
+ uint64_t enable_err_handler1 : 1;
+ uint64_t enable_err_handler0 : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_error_mask_t;
+
+#endif // __ASSEMBLER__
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_HANDLER0 SIXTYFOUR_BIT_CONSTANT(0x8000000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_HANDLER1 SIXTYFOUR_BIT_CONSTANT(0x4000000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_HANDLER2 SIXTYFOUR_BIT_CONSTANT(0x2000000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_HANDLER3 SIXTYFOUR_BIT_CONSTANT(0x1000000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_HANDLER4 SIXTYFOUR_BIT_CONSTANT(0x0800000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_OUTPUT0 SIXTYFOUR_BIT_CONSTANT(0x0400000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_OUTPUT1 SIXTYFOUR_BIT_CONSTANT(0x0200000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_OUTPUT2 SIXTYFOUR_BIT_CONSTANT(0x0100000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_OUTPUT3 SIXTYFOUR_BIT_CONSTANT(0x0080000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_ERR_OUTPUT4 SIXTYFOUR_BIT_CONSTANT(0x0040000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT0 SIXTYFOUR_BIT_CONSTANT(0x0020000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT1 SIXTYFOUR_BIT_CONSTANT(0x0010000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT2 SIXTYFOUR_BIT_CONSTANT(0x0008000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT3 SIXTYFOUR_BIT_CONSTANT(0x0004000000000000)
+#define PORE_SBE_ERROR_MASK_ENABLE_FATAL_ERR_OUTPUT4 SIXTYFOUR_BIT_CONSTANT(0x0002000000000000)
+#define PORE_SBE_ERROR_MASK_STOP_EXE_ON_ERROR0 SIXTYFOUR_BIT_CONSTANT(0x0001000000000000)
+#define PORE_SBE_ERROR_MASK_STOP_EXE_ON_ERROR1 SIXTYFOUR_BIT_CONSTANT(0x0000800000000000)
+#define PORE_SBE_ERROR_MASK_STOP_EXE_ON_ERROR2 SIXTYFOUR_BIT_CONSTANT(0x0000400000000000)
+#define PORE_SBE_ERROR_MASK_STOP_EXE_ON_ERROR3 SIXTYFOUR_BIT_CONSTANT(0x0000200000000000)
+#define PORE_SBE_ERROR_MASK_STOP_EXE_ON_ERROR4 SIXTYFOUR_BIT_CONSTANT(0x0000100000000000)
+#define PORE_SBE_ERROR_MASK_GATE_CHIPLET_OFFLINE_ERR SIXTYFOUR_BIT_CONSTANT(0x0000080000000000)
+#define PORE_SBE_ERROR_MASK_I2C_BAD_STATUS_0 SIXTYFOUR_BIT_CONSTANT(0x0000040000000000)
+#define PORE_SBE_ERROR_MASK_I2C_BAD_STATUS_1 SIXTYFOUR_BIT_CONSTANT(0x0000020000000000)
+#define PORE_SBE_ERROR_MASK_I2C_BAD_STATUS_2 SIXTYFOUR_BIT_CONSTANT(0x0000010000000000)
+#define PORE_SBE_ERROR_MASK_I2C_BAD_STATUS_3 SIXTYFOUR_BIT_CONSTANT(0x0000008000000000)
+#define PORE_SBE_ERROR_MASK_GROUP_PARITY_ERROR_0 SIXTYFOUR_BIT_CONSTANT(0x0000004000000000)
+#define PORE_SBE_ERROR_MASK_GROUP_PARITY_ERROR_1 SIXTYFOUR_BIT_CONSTANT(0x0000002000000000)
+#define PORE_SBE_ERROR_MASK_GROUP_PARITY_ERROR_2 SIXTYFOUR_BIT_CONSTANT(0x0000001000000000)
+#define PORE_SBE_ERROR_MASK_GROUP_PARITY_ERROR_3 SIXTYFOUR_BIT_CONSTANT(0x0000000800000000)
+#define PORE_SBE_ERROR_MASK_GROUP_PARITY_ERROR_4 SIXTYFOUR_BIT_CONSTANT(0x0000000400000000)
+#ifndef __ASSEMBLER__
+
+
+typedef union pore_sbe_prv_base_address0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 25;
+ uint64_t mc : 1;
+ uint64_t chiplet_id : 6;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t chiplet_id : 6;
+ uint64_t mc : 1;
+ uint64_t spare : 25;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_prv_base_address0_t;
+
+
+
+typedef union pore_sbe_prv_base_address1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 25;
+ uint64_t mc : 1;
+ uint64_t chiplet_id : 6;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t chiplet_id : 6;
+ uint64_t mc : 1;
+ uint64_t spare : 25;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_prv_base_address1_t;
+
+
+
+typedef union pore_sbe_oci_base_address0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 18;
+ uint64_t oci_mem_route : 14;
+ uint64_t oci_base_address : 32;
+#else
+ uint64_t oci_base_address : 32;
+ uint64_t oci_mem_route : 14;
+ uint64_t spare : 18;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_oci_base_address0_t;
+
+
+
+typedef union pore_sbe_oci_base_address1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t spare : 18;
+ uint64_t oci_mem_route : 14;
+ uint64_t oci_base_address : 32;
+#else
+ uint64_t oci_base_address : 32;
+ uint64_t oci_mem_route : 14;
+ uint64_t spare : 18;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_oci_base_address1_t;
+
+
+
+typedef union pore_sbe_table_base_addr {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 16;
+ uint64_t memory_space : 16;
+ uint64_t table_base_address : 32;
+#else
+ uint64_t table_base_address : 32;
+ uint64_t memory_space : 16;
+ uint64_t reserved : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_table_base_addr_t;
+
+
+
+typedef union pore_sbe_exe_trigger {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved : 8;
+ uint64_t start_vector : 4;
+ uint64_t zeroes : 8;
+ uint64_t unused : 12;
+ uint64_t mc_chiplet_select_mask : 32;
+#else
+ uint64_t mc_chiplet_select_mask : 32;
+ uint64_t unused : 12;
+ uint64_t zeroes : 8;
+ uint64_t start_vector : 4;
+ uint64_t reserved : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_exe_trigger_t;
+
+
+
+typedef union pore_sbe_scratch0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t zeroes : 8;
+ uint64_t scratch0 : 24;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t scratch0 : 24;
+ uint64_t zeroes : 8;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_scratch0_t;
+
+
+
+typedef union pore_sbe_scratch1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t scratch1 : 64;
+#else
+ uint64_t scratch1 : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_scratch1_t;
+
+
+
+typedef union pore_sbe_scratch2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t scratch2 : 64;
+#else
+ uint64_t scratch2 : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_scratch2_t;
+
+
+
+typedef union pore_sbe_ibuf_01 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ibuf0 : 32;
+ uint64_t ibuf1 : 32;
+#else
+ uint64_t ibuf1 : 32;
+ uint64_t ibuf0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_ibuf_01_t;
+
+
+
+typedef union pore_sbe_ibuf_2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t ibuf2 : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t ibuf2 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_ibuf_2_t;
+
+
+
+typedef union pore_sbe_dbg0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t last_completed_address : 32;
+ uint64_t last_pib_parity_fail : 1;
+ uint64_t last_ret_code_prv : 3;
+ uint64_t i2c_bad_status0 : 1;
+ uint64_t i2c_bad_status1 : 1;
+ uint64_t i2c_bad_status2 : 1;
+ uint64_t i2c_bad_status3 : 1;
+ uint64_t group_parity_error0 : 1;
+ uint64_t group_parity_error1 : 1;
+ uint64_t group_parity_error2 : 1;
+ uint64_t group_parity_error3 : 1;
+ uint64_t group_parity_error4 : 1;
+ uint64_t interrupt_counter : 8;
+ uint64_t _reserved0 : 11;
+#else
+ uint64_t _reserved0 : 11;
+ uint64_t interrupt_counter : 8;
+ uint64_t group_parity_error4 : 1;
+ uint64_t group_parity_error3 : 1;
+ uint64_t group_parity_error2 : 1;
+ uint64_t group_parity_error1 : 1;
+ uint64_t group_parity_error0 : 1;
+ uint64_t i2c_bad_status3 : 1;
+ uint64_t i2c_bad_status2 : 1;
+ uint64_t i2c_bad_status1 : 1;
+ uint64_t i2c_bad_status0 : 1;
+ uint64_t last_ret_code_prv : 3;
+ uint64_t last_pib_parity_fail : 1;
+ uint64_t last_completed_address : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_dbg0_t;
+
+
+
+typedef union pore_sbe_dbg1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_last_access : 48;
+ uint64_t oci_master_rd_parity_err : 1;
+ uint64_t last_ret_code_oci : 3;
+ uint64_t bad_instr_parity : 1;
+ uint64_t invalid_instr_code : 1;
+ uint64_t pc_overflow_underrun : 1;
+ uint64_t bad_scan_crc : 1;
+ uint64_t pc_stack_ovflw_undrn_err : 1;
+ uint64_t instruction_fetch_error : 1;
+ uint64_t invalid_instruction_operand : 1;
+ uint64_t invalid_instruction_path : 1;
+ uint64_t invalid_start_vector : 1;
+ uint64_t fast_i2c_protocol_hang : 1;
+ uint64_t spare : 1;
+ uint64_t debug_regs_locked : 1;
+#else
+ uint64_t debug_regs_locked : 1;
+ uint64_t spare : 1;
+ uint64_t fast_i2c_protocol_hang : 1;
+ uint64_t invalid_start_vector : 1;
+ uint64_t invalid_instruction_path : 1;
+ uint64_t invalid_instruction_operand : 1;
+ uint64_t instruction_fetch_error : 1;
+ uint64_t pc_stack_ovflw_undrn_err : 1;
+ uint64_t bad_scan_crc : 1;
+ uint64_t pc_overflow_underrun : 1;
+ uint64_t invalid_instr_code : 1;
+ uint64_t bad_instr_parity : 1;
+ uint64_t last_ret_code_oci : 3;
+ uint64_t oci_master_rd_parity_err : 1;
+ uint64_t pc_last_access : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_dbg1_t;
+
+
+
+typedef union pore_sbe_pc_stack0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_stack0 : 48;
+ uint64_t _reserved0 : 11;
+ uint64_t set_new_stack_pointer : 1;
+ uint64_t new_stack_pointer : 4;
+#else
+ uint64_t new_stack_pointer : 4;
+ uint64_t set_new_stack_pointer : 1;
+ uint64_t _reserved0 : 11;
+ uint64_t pc_stack0 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_pc_stack0_t;
+
+
+
+typedef union pore_sbe_pc_stack1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_stack1 : 48;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t pc_stack1 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_pc_stack1_t;
+
+
+
+typedef union pore_sbe_pc_stack2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t pc_stack2 : 48;
+ uint64_t _reserved0 : 16;
+#else
+ uint64_t _reserved0 : 16;
+ uint64_t pc_stack2 : 48;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_pc_stack2_t;
+
+
+
+typedef union pore_sbe_id_flags {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t reserved0 : 32;
+ uint64_t pib_parity_fail : 1;
+ uint64_t pib_status : 3;
+ uint64_t oci_parity_fail : 1;
+ uint64_t oci_status : 3;
+ uint64_t reserved1 : 8;
+ uint64_t ugt : 1;
+ uint64_t ult : 1;
+ uint64_t sgt : 1;
+ uint64_t slt : 1;
+ uint64_t c : 1;
+ uint64_t o : 1;
+ uint64_t n : 1;
+ uint64_t z : 1;
+ uint64_t reserved2 : 4;
+ uint64_t ibuf_id : 4;
+#else
+ uint64_t ibuf_id : 4;
+ uint64_t reserved2 : 4;
+ uint64_t z : 1;
+ uint64_t n : 1;
+ uint64_t o : 1;
+ uint64_t c : 1;
+ uint64_t slt : 1;
+ uint64_t sgt : 1;
+ uint64_t ult : 1;
+ uint64_t ugt : 1;
+ uint64_t reserved1 : 8;
+ uint64_t oci_status : 3;
+ uint64_t oci_parity_fail : 1;
+ uint64_t pib_status : 3;
+ uint64_t pib_parity_fail : 1;
+ uint64_t reserved0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_id_flags_t;
+
+
+
+typedef union pore_sbe_data0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t data0 : 32;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t data0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_data0_t;
+
+
+
+typedef union pore_sbe_memory_reloc {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t _reserved0 : 30;
+ uint64_t memory_reloc_region : 2;
+ uint64_t memory_reloc_base : 20;
+ uint64_t _reserved1 : 12;
+#else
+ uint64_t _reserved1 : 12;
+ uint64_t memory_reloc_base : 20;
+ uint64_t memory_reloc_region : 2;
+ uint64_t _reserved0 : 30;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_memory_reloc_t;
+
+
+
+typedef union pore_sbe_i2c_en_param {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t i2c_engine_identifier : 4;
+ uint64_t reserved0 : 1;
+ uint64_t i2c_engine_address_range : 3;
+ uint64_t reserved1 : 3;
+ uint64_t i2c_engine_port : 5;
+ uint64_t reserved2 : 1;
+ uint64_t i2c_engine_device_id : 7;
+ uint64_t reserved3 : 2;
+ uint64_t i2c_engine_speed : 2;
+ uint64_t i2c_poll_threshold : 4;
+ uint64_t _reserved0 : 32;
+#else
+ uint64_t _reserved0 : 32;
+ uint64_t i2c_poll_threshold : 4;
+ uint64_t i2c_engine_speed : 2;
+ uint64_t reserved3 : 2;
+ uint64_t i2c_engine_device_id : 7;
+ uint64_t reserved2 : 1;
+ uint64_t i2c_engine_port : 5;
+ uint64_t reserved1 : 3;
+ uint64_t i2c_engine_address_range : 3;
+ uint64_t reserved0 : 1;
+ uint64_t i2c_engine_identifier : 4;
+#endif // _BIG_ENDIAN
+ } fields;
+} pore_sbe_i2c_en_param_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __SBE_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/sbe_register_addresses.h b/src/ssx/pgp/registers/sbe_register_addresses.h
new file mode 100644
index 0000000..794acea
--- /dev/null
+++ b/src/ssx/pgp/registers/sbe_register_addresses.h
@@ -0,0 +1,48 @@
+#ifndef __SBE_REGISTER_ADDRESSES_H__
+#define __SBE_REGISTER_ADDRESSES_H__
+
+// $Id: sbe_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/sbe_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sbe_register_addresses.h
+/// \brief Symbolic addresses for the SBE unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define PORE_SBE_PIB_BASE 0x000e0000
+#define PORE_SBE_STATUS 0x000e0000
+#define PORE_SBE_CONTROL 0x000e0001
+#define PORE_SBE_RESET 0x000e0002
+#define PORE_SBE_ERROR_MASK 0x000e0003
+#define PORE_SBE_PRV_BASE_ADDRESS0 0x000e0004
+#define PORE_SBE_PRV_BASE_ADDRESS1 0x000e0005
+#define PORE_SBE_OCI_BASE_ADDRESS0 0x000e0006
+#define PORE_SBE_OCI_BASE_ADDRESS1 0x000e0007
+#define PORE_SBE_TABLE_BASE_ADDR 0x000e0008
+#define PORE_SBE_EXE_TRIGGER 0x000e0009
+#define PORE_SBE_SCRATCH0 0x000e000a
+#define PORE_SBE_SCRATCH1 0x000e000b
+#define PORE_SBE_SCRATCH2 0x000e000c
+#define PORE_SBE_IBUF_01 0x000e000d
+#define PORE_SBE_IBUF_2 0x000e000e
+#define PORE_SBE_DBG0 0x000e000f
+#define PORE_SBE_DBG1 0x000e0010
+#define PORE_SBE_PC_STACK0 0x000e0011
+#define PORE_SBE_PC_STACK1 0x000e0012
+#define PORE_SBE_PC_STACK2 0x000e0013
+#define PORE_SBE_ID_FLAGS 0x000e0014
+#define PORE_SBE_DATA0 0x000e0015
+#define PORE_SBE_MEMORY_RELOC 0x000e0016
+#define PORE_SBE_I2C_EN_PARAM(n) (PORE_SBE_I2C_E0_PARAM + ((PORE_SBE_I2C_E1_PARAM - PORE_SBE_I2C_E0_PARAM) * (n)))
+#define PORE_SBE_I2C_E0_PARAM 0x000e0017
+#define PORE_SBE_I2C_E1_PARAM 0x000e0018
+#define PORE_SBE_I2C_E2_PARAM 0x000e0019
+
+#endif // __SBE_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/sensors_firmware_registers.h b/src/ssx/pgp/registers/sensors_firmware_registers.h
new file mode 100755
index 0000000..9cb252e
--- /dev/null
+++ b/src/ssx/pgp/registers/sensors_firmware_registers.h
@@ -0,0 +1,668 @@
+#ifndef __SENSORS_FIRMWARE_REGISTERS_H__
+#define __SENSORS_FIRMWARE_REGISTERS_H__
+
+// $Id: sensors_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/sensors_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sensors_firmware_registers.h
+/// \brief C register structs for the SENSORS unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union sensors_v0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dts0 : 12;
+ uint64_t thermal_trip0 : 2;
+ uint64_t spare0 : 1;
+ uint64_t valid0 : 1;
+ uint64_t dts1 : 12;
+ uint64_t thermal_trip1 : 2;
+ uint64_t spare1 : 1;
+ uint64_t valid1 : 1;
+ uint64_t dts2 : 12;
+ uint64_t thermal_trip2 : 2;
+ uint64_t spare2 : 1;
+ uint64_t valid2 : 1;
+ uint64_t dts3 : 12;
+ uint64_t thermal_trip3 : 2;
+ uint64_t spare3 : 1;
+ uint64_t valid3 : 1;
+#else
+ uint64_t valid3 : 1;
+ uint64_t spare3 : 1;
+ uint64_t thermal_trip3 : 2;
+ uint64_t dts3 : 12;
+ uint64_t valid2 : 1;
+ uint64_t spare2 : 1;
+ uint64_t thermal_trip2 : 2;
+ uint64_t dts2 : 12;
+ uint64_t valid1 : 1;
+ uint64_t spare1 : 1;
+ uint64_t thermal_trip1 : 2;
+ uint64_t dts1 : 12;
+ uint64_t valid0 : 1;
+ uint64_t spare0 : 1;
+ uint64_t thermal_trip0 : 2;
+ uint64_t dts0 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v0_t;
+
+
+
+typedef union sensors_v1 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dts4 : 12;
+ uint64_t thermal_trip4 : 2;
+ uint64_t spare4 : 1;
+ uint64_t valid4 : 1;
+ uint64_t dts5 : 12;
+ uint64_t thermal_trip5 : 2;
+ uint64_t spare5 : 1;
+ uint64_t valid5 : 1;
+ uint64_t dts6 : 12;
+ uint64_t thermal_trip6 : 2;
+ uint64_t spare6 : 1;
+ uint64_t valid6 : 1;
+ uint64_t dts7 : 12;
+ uint64_t thermal_trip7 : 2;
+ uint64_t spare7 : 1;
+ uint64_t valid7 : 1;
+#else
+ uint64_t valid7 : 1;
+ uint64_t spare7 : 1;
+ uint64_t thermal_trip7 : 2;
+ uint64_t dts7 : 12;
+ uint64_t valid6 : 1;
+ uint64_t spare6 : 1;
+ uint64_t thermal_trip6 : 2;
+ uint64_t dts6 : 12;
+ uint64_t valid5 : 1;
+ uint64_t spare5 : 1;
+ uint64_t thermal_trip5 : 2;
+ uint64_t dts5 : 12;
+ uint64_t valid4 : 1;
+ uint64_t spare4 : 1;
+ uint64_t thermal_trip4 : 2;
+ uint64_t dts4 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v1_t;
+
+
+
+typedef union sensors_v2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dts8 : 12;
+ uint64_t thermal_trip8 : 2;
+ uint64_t spare8 : 1;
+ uint64_t valid8 : 1;
+ uint64_t dts9 : 12;
+ uint64_t thermal_trip9 : 2;
+ uint64_t spare9 : 1;
+ uint64_t valid9 : 1;
+ uint64_t dts10 : 12;
+ uint64_t thermal_trip10 : 2;
+ uint64_t spare10 : 1;
+ uint64_t valid10 : 1;
+ uint64_t dts12 : 12;
+ uint64_t thermal_trip12 : 2;
+ uint64_t spare12 : 1;
+ uint64_t valid12 : 1;
+#else
+ uint64_t valid12 : 1;
+ uint64_t spare12 : 1;
+ uint64_t thermal_trip12 : 2;
+ uint64_t dts12 : 12;
+ uint64_t valid10 : 1;
+ uint64_t spare10 : 1;
+ uint64_t thermal_trip10 : 2;
+ uint64_t dts10 : 12;
+ uint64_t valid9 : 1;
+ uint64_t spare9 : 1;
+ uint64_t thermal_trip9 : 2;
+ uint64_t dts9 : 12;
+ uint64_t valid8 : 1;
+ uint64_t spare8 : 1;
+ uint64_t thermal_trip8 : 2;
+ uint64_t dts8 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v2_t;
+
+
+
+typedef union sensors_v3 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t unknown : 64;
+#else
+ uint64_t unknown : 64;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v3_t;
+
+
+
+typedef union sensors_v5 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t raw_cpm0 : 12;
+ uint64_t spare0 : 4;
+ uint64_t raw_cpm1 : 12;
+ uint64_t spare1 : 4;
+ uint64_t raw_cpm2 : 12;
+ uint64_t spare2 : 4;
+ uint64_t raw_cpm3 : 12;
+ uint64_t spare3 : 4;
+#else
+ uint64_t spare3 : 4;
+ uint64_t raw_cpm3 : 12;
+ uint64_t spare2 : 4;
+ uint64_t raw_cpm2 : 12;
+ uint64_t spare1 : 4;
+ uint64_t raw_cpm1 : 12;
+ uint64_t spare0 : 4;
+ uint64_t raw_cpm0 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v5_t;
+
+
+
+typedef union sensors_v6 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t raw_cpm4 : 12;
+ uint64_t spare4 : 4;
+ uint64_t raw_cpm5 : 12;
+ uint64_t spare5 : 4;
+ uint64_t raw_cpm6 : 12;
+ uint64_t spare6 : 4;
+ uint64_t raw_cpm7 : 12;
+ uint64_t spare7 : 4;
+#else
+ uint64_t spare7 : 4;
+ uint64_t raw_cpm7 : 12;
+ uint64_t spare6 : 4;
+ uint64_t raw_cpm6 : 12;
+ uint64_t spare5 : 4;
+ uint64_t raw_cpm5 : 12;
+ uint64_t spare4 : 4;
+ uint64_t raw_cpm4 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v6_t;
+
+
+
+typedef union sensors_v7 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t raw_cpm8 : 12;
+ uint64_t spare8 : 4;
+ uint64_t raw_cpm9 : 12;
+ uint64_t spare9 : 4;
+ uint64_t raw_cpm10 : 12;
+ uint64_t spare10 : 4;
+ uint64_t raw_cpm11 : 12;
+ uint64_t spare11 : 4;
+#else
+ uint64_t spare11 : 4;
+ uint64_t raw_cpm11 : 12;
+ uint64_t spare10 : 4;
+ uint64_t raw_cpm10 : 12;
+ uint64_t spare9 : 4;
+ uint64_t raw_cpm9 : 12;
+ uint64_t spare8 : 4;
+ uint64_t raw_cpm8 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v7_t;
+
+
+
+typedef union sensors_v8 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dts0 : 12;
+ uint64_t thermal_trip0 : 2;
+ uint64_t spare0 : 1;
+ uint64_t valid0 : 1;
+ uint64_t dts1 : 12;
+ uint64_t thermal_trip1 : 2;
+ uint64_t spare1 : 1;
+ uint64_t valid1 : 1;
+ uint64_t dts2 : 12;
+ uint64_t thermal_trip2 : 2;
+ uint64_t spare2 : 1;
+ uint64_t valid2 : 1;
+ uint64_t encoded_cpm0 : 4;
+ uint64_t encoded_cpm1 : 4;
+ uint64_t encoded_cpm2 : 4;
+ uint64_t encoded_cpm3 : 4;
+#else
+ uint64_t encoded_cpm3 : 4;
+ uint64_t encoded_cpm2 : 4;
+ uint64_t encoded_cpm1 : 4;
+ uint64_t encoded_cpm0 : 4;
+ uint64_t valid2 : 1;
+ uint64_t spare2 : 1;
+ uint64_t thermal_trip2 : 2;
+ uint64_t dts2 : 12;
+ uint64_t valid1 : 1;
+ uint64_t spare1 : 1;
+ uint64_t thermal_trip1 : 2;
+ uint64_t dts1 : 12;
+ uint64_t valid0 : 1;
+ uint64_t spare0 : 1;
+ uint64_t thermal_trip0 : 2;
+ uint64_t dts0 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v8_t;
+
+
+
+typedef union sensors_v9 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dts4 : 12;
+ uint64_t thermal_trip4 : 2;
+ uint64_t spare4 : 1;
+ uint64_t valid4 : 1;
+ uint64_t dts5 : 12;
+ uint64_t thermal_trip5 : 2;
+ uint64_t spare5 : 1;
+ uint64_t valid5 : 1;
+ uint64_t dts6 : 12;
+ uint64_t thermal_trip6 : 2;
+ uint64_t spare6 : 1;
+ uint64_t valid6 : 1;
+ uint64_t encoded_cpm4 : 4;
+ uint64_t encoded_cpm5 : 4;
+ uint64_t encoded_cpm6 : 4;
+ uint64_t encoded_cpm7 : 4;
+#else
+ uint64_t encoded_cpm7 : 4;
+ uint64_t encoded_cpm6 : 4;
+ uint64_t encoded_cpm5 : 4;
+ uint64_t encoded_cpm4 : 4;
+ uint64_t valid6 : 1;
+ uint64_t spare6 : 1;
+ uint64_t thermal_trip6 : 2;
+ uint64_t dts6 : 12;
+ uint64_t valid5 : 1;
+ uint64_t spare5 : 1;
+ uint64_t thermal_trip5 : 2;
+ uint64_t dts5 : 12;
+ uint64_t valid4 : 1;
+ uint64_t spare4 : 1;
+ uint64_t thermal_trip4 : 2;
+ uint64_t dts4 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v9_t;
+
+
+
+typedef union sensors_v10 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dts8 : 12;
+ uint64_t thermal_trip8 : 2;
+ uint64_t spare8 : 1;
+ uint64_t valid8 : 1;
+ uint64_t dts9 : 12;
+ uint64_t thermal_trip9 : 2;
+ uint64_t spare9 : 1;
+ uint64_t valid9 : 1;
+ uint64_t dts10 : 12;
+ uint64_t thermal_trip10 : 2;
+ uint64_t spare10 : 1;
+ uint64_t valid10 : 1;
+ uint64_t encoded_cpm8 : 4;
+ uint64_t encoded_cpm9 : 4;
+ uint64_t encoded_cpm10 : 4;
+ uint64_t encoded_cpm11 : 4;
+#else
+ uint64_t encoded_cpm11 : 4;
+ uint64_t encoded_cpm10 : 4;
+ uint64_t encoded_cpm9 : 4;
+ uint64_t encoded_cpm8 : 4;
+ uint64_t valid10 : 1;
+ uint64_t spare10 : 1;
+ uint64_t thermal_trip10 : 2;
+ uint64_t dts10 : 12;
+ uint64_t valid9 : 1;
+ uint64_t spare9 : 1;
+ uint64_t thermal_trip9 : 2;
+ uint64_t dts9 : 12;
+ uint64_t valid8 : 1;
+ uint64_t spare8 : 1;
+ uint64_t thermal_trip8 : 2;
+ uint64_t dts8 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v10_t;
+
+
+
+typedef union sensors_v11 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dvs0 : 12;
+ uint64_t spare00 : 1;
+ uint64_t trip0 : 1;
+ uint64_t spare01 : 1;
+ uint64_t valid0 : 1;
+ uint64_t dvs1 : 12;
+ uint64_t spare10 : 1;
+ uint64_t trip1 : 1;
+ uint64_t spare11 : 1;
+ uint64_t valid1 : 1;
+ uint64_t dvs2 : 12;
+ uint64_t spare20 : 1;
+ uint64_t trip2 : 1;
+ uint64_t spare21 : 1;
+ uint64_t valid2 : 1;
+ uint64_t dvs3 : 12;
+ uint64_t spare30 : 1;
+ uint64_t trip3 : 1;
+ uint64_t spare31 : 1;
+ uint64_t valid3 : 1;
+#else
+ uint64_t valid3 : 1;
+ uint64_t spare31 : 1;
+ uint64_t trip3 : 1;
+ uint64_t spare30 : 1;
+ uint64_t dvs3 : 12;
+ uint64_t valid2 : 1;
+ uint64_t spare21 : 1;
+ uint64_t trip2 : 1;
+ uint64_t spare20 : 1;
+ uint64_t dvs2 : 12;
+ uint64_t valid1 : 1;
+ uint64_t spare11 : 1;
+ uint64_t trip1 : 1;
+ uint64_t spare10 : 1;
+ uint64_t dvs1 : 12;
+ uint64_t valid0 : 1;
+ uint64_t spare01 : 1;
+ uint64_t trip0 : 1;
+ uint64_t spare00 : 1;
+ uint64_t dvs0 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v11_t;
+
+
+
+typedef union sensors_v12 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dvs4 : 12;
+ uint64_t spare40 : 1;
+ uint64_t trip4 : 1;
+ uint64_t spare41 : 1;
+ uint64_t valid4 : 1;
+ uint64_t dvs5 : 12;
+ uint64_t spare50 : 1;
+ uint64_t trip5 : 1;
+ uint64_t spare51 : 1;
+ uint64_t valid5 : 1;
+ uint64_t dvs6 : 12;
+ uint64_t spare60 : 1;
+ uint64_t trip6 : 1;
+ uint64_t spare61 : 1;
+ uint64_t valid6 : 1;
+ uint64_t dvs7 : 12;
+ uint64_t spare70 : 1;
+ uint64_t trip7 : 1;
+ uint64_t spare71 : 1;
+ uint64_t valid7 : 1;
+#else
+ uint64_t valid7 : 1;
+ uint64_t spare71 : 1;
+ uint64_t trip7 : 1;
+ uint64_t spare70 : 1;
+ uint64_t dvs7 : 12;
+ uint64_t valid6 : 1;
+ uint64_t spare61 : 1;
+ uint64_t trip6 : 1;
+ uint64_t spare60 : 1;
+ uint64_t dvs6 : 12;
+ uint64_t valid5 : 1;
+ uint64_t spare51 : 1;
+ uint64_t trip5 : 1;
+ uint64_t spare50 : 1;
+ uint64_t dvs5 : 12;
+ uint64_t valid4 : 1;
+ uint64_t spare41 : 1;
+ uint64_t trip4 : 1;
+ uint64_t spare40 : 1;
+ uint64_t dvs4 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v12_t;
+
+
+
+typedef union sensors_v13 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t dvs8 : 12;
+ uint64_t spare80 : 1;
+ uint64_t trip8 : 1;
+ uint64_t spare81 : 1;
+ uint64_t valid8 : 1;
+ uint64_t dvs9 : 12;
+ uint64_t spare90 : 1;
+ uint64_t trip9 : 1;
+ uint64_t spare91 : 1;
+ uint64_t valid9 : 1;
+ uint64_t dvs10 : 12;
+ uint64_t spare100 : 1;
+ uint64_t trip10 : 1;
+ uint64_t spare101 : 1;
+ uint64_t valid10 : 1;
+ uint64_t dvs11 : 12;
+ uint64_t spare110 : 1;
+ uint64_t trip11 : 1;
+ uint64_t spare111 : 1;
+ uint64_t valid11 : 1;
+#else
+ uint64_t valid11 : 1;
+ uint64_t spare111 : 1;
+ uint64_t trip11 : 1;
+ uint64_t spare110 : 1;
+ uint64_t dvs11 : 12;
+ uint64_t valid10 : 1;
+ uint64_t spare101 : 1;
+ uint64_t trip10 : 1;
+ uint64_t spare100 : 1;
+ uint64_t dvs10 : 12;
+ uint64_t valid9 : 1;
+ uint64_t spare91 : 1;
+ uint64_t trip9 : 1;
+ uint64_t spare90 : 1;
+ uint64_t dvs9 : 12;
+ uint64_t valid8 : 1;
+ uint64_t spare81 : 1;
+ uint64_t trip8 : 1;
+ uint64_t spare80 : 1;
+ uint64_t dvs8 : 12;
+#endif // _BIG_ENDIAN
+ } fields;
+} sensors_v13_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __SENSORS_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/sensors_register_addresses.h b/src/ssx/pgp/registers/sensors_register_addresses.h
new file mode 100755
index 0000000..c815ace
--- /dev/null
+++ b/src/ssx/pgp/registers/sensors_register_addresses.h
@@ -0,0 +1,47 @@
+#ifndef __SENSORS_REGISTER_ADDRESSES_H__
+#define __SENSORS_REGISTER_ADDRESSES_H__
+
+// $Id: sensors_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/sensors_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sensors_register_addresses.h
+/// \brief Symbolic addresses for the SENSORS unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define SENSORS_CORE_PCB_BASE 0x10050000
+#define SENSORS_V0_OFFSET 0x00000000
+#define SENSORS_CORE_V0 0x10050000
+#define SENSORS_V1_OFFSET 0x00000001
+#define SENSORS_CORE_V1 0x10050001
+#define SENSORS_V2_OFFSET 0x00000002
+#define SENSORS_CORE_V2 0x10050002
+#define SENSORS_V3_OFFSET 0x00000003
+#define SENSORS_CORE_V3 0x10050003
+#define SENSORS_V5_OFFSET 0x00000005
+#define SENSORS_CORE_V5 0x10050005
+#define SENSORS_V6_OFFSET 0x00000006
+#define SENSORS_CORE_V6 0x10050006
+#define SENSORS_V7_OFFSET 0x00000007
+#define SENSORS_CORE_V7 0x10050007
+#define SENSORS_V8_OFFSET 0x00000008
+#define SENSORS_CORE_V8 0x10050008
+#define SENSORS_V9_OFFSET 0x00000009
+#define SENSORS_CORE_V9 0x10050009
+#define SENSORS_V10_OFFSET 0x0000000a
+#define SENSORS_CORE_V10 0x1005000a
+#define SENSORS_V11_OFFSET 0x0000000b
+#define SENSORS_CORE_V11 0x1005000b
+#define SENSORS_V12_OFFSET 0x0000000c
+#define SENSORS_CORE_V12 0x1005000c
+#define SENSORS_V13_OFFSET 0x0000000d
+#define SENSORS_CORE_V13 0x1005000d
+
+#endif // __SENSORS_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/sramctl_firmware_registers.h b/src/ssx/pgp/registers/sramctl_firmware_registers.h
new file mode 100755
index 0000000..c8a7c26
--- /dev/null
+++ b/src/ssx/pgp/registers/sramctl_firmware_registers.h
@@ -0,0 +1,211 @@
+#ifndef __SRAMCTL_FIRMWARE_REGISTERS_H__
+#define __SRAMCTL_FIRMWARE_REGISTERS_H__
+
+// $Id: sramctl_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:24 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/sramctl_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sramctl_firmware_registers.h
+/// \brief C register structs for the SRAMCTL unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union sramctl_srbar {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t sram_region_qualifier : 2;
+ uint32_t reserved : 3;
+ uint32_t sram_bar_region : 8;
+ uint32_t _reserved0 : 19;
+#else
+ uint32_t _reserved0 : 19;
+ uint32_t sram_bar_region : 8;
+ uint32_t reserved : 3;
+ uint32_t sram_region_qualifier : 2;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srbar_t;
+
+
+
+typedef union sramctl_srmr {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t sram_enable_remap : 1;
+ uint32_t sram_arb_en_send_all_writes : 1;
+ uint32_t sram_disable_lfsr : 1;
+ uint32_t sram_lfsr_fairness_mask : 5;
+ uint32_t sram_error_inject_enable : 1;
+ uint32_t sram_ctl_trace_en : 1;
+ uint32_t sram_ctl_trace_sel : 1;
+ uint32_t reserved : 5;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t reserved : 5;
+ uint32_t sram_ctl_trace_sel : 1;
+ uint32_t sram_ctl_trace_en : 1;
+ uint32_t sram_error_inject_enable : 1;
+ uint32_t sram_lfsr_fairness_mask : 5;
+ uint32_t sram_disable_lfsr : 1;
+ uint32_t sram_arb_en_send_all_writes : 1;
+ uint32_t sram_enable_remap : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srmr_t;
+
+
+
+typedef union sramctl_srmap {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t reserved : 1;
+ uint32_t sram_remap_source : 12;
+ uint32_t _reserved0 : 1;
+ uint32_t reserved1 : 3;
+ uint32_t sram_remap_dest : 13;
+ uint32_t reserved2 : 2;
+#else
+ uint32_t reserved2 : 2;
+ uint32_t sram_remap_dest : 13;
+ uint32_t reserved1 : 3;
+ uint32_t _reserved0 : 1;
+ uint32_t sram_remap_source : 12;
+ uint32_t reserved : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srmap_t;
+
+
+
+typedef union sramctl_srear {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t sram_error_address : 16;
+ uint32_t _reserved0 : 16;
+#else
+ uint32_t _reserved0 : 16;
+ uint32_t sram_error_address : 16;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srear_t;
+
+
+
+typedef union sramctl_srbv0 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t boot_vector_word0 : 32;
+#else
+ uint32_t boot_vector_word0 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srbv0_t;
+
+
+
+typedef union sramctl_srbv1 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t boot_vector_word1 : 32;
+#else
+ uint32_t boot_vector_word1 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srbv1_t;
+
+
+
+typedef union sramctl_srbv2 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t boot_vector_word2 : 32;
+#else
+ uint32_t boot_vector_word2 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srbv2_t;
+
+
+
+typedef union sramctl_srbv3 {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t boot_vector_word3 : 32;
+#else
+ uint32_t boot_vector_word3 : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srbv3_t;
+
+
+
+typedef union sramctl_srchsw {
+
+ uint32_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t chksw_wrfsm_dly_dis : 1;
+ uint32_t chksw_allow1_rd : 1;
+ uint32_t chksw_allow1_wr : 1;
+ uint32_t chksw_allow1_rdwr : 1;
+ uint32_t chksw_oci_parchk_dis : 1;
+ uint32_t chksw_tank_rddata_parchk_dis : 1;
+ uint32_t chksw_tank_sr_rderr_dis : 1;
+ uint32_t chksw_val_be_addr_chk_dis : 1;
+ uint32_t chksw_so_spare : 2;
+ uint32_t _reserved0 : 22;
+#else
+ uint32_t _reserved0 : 22;
+ uint32_t chksw_so_spare : 2;
+ uint32_t chksw_val_be_addr_chk_dis : 1;
+ uint32_t chksw_tank_sr_rderr_dis : 1;
+ uint32_t chksw_tank_rddata_parchk_dis : 1;
+ uint32_t chksw_oci_parchk_dis : 1;
+ uint32_t chksw_allow1_rdwr : 1;
+ uint32_t chksw_allow1_wr : 1;
+ uint32_t chksw_allow1_rd : 1;
+ uint32_t chksw_wrfsm_dly_dis : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} sramctl_srchsw_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __SRAMCTL_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/sramctl_register_addresses.h b/src/ssx/pgp/registers/sramctl_register_addresses.h
new file mode 100755
index 0000000..baec5d5
--- /dev/null
+++ b/src/ssx/pgp/registers/sramctl_register_addresses.h
@@ -0,0 +1,30 @@
+#ifndef __SRAMCTL_REGISTER_ADDRESSES_H__
+#define __SRAMCTL_REGISTER_ADDRESSES_H__
+
+// $Id: sramctl_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/sramctl_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file sramctl_register_addresses.h
+/// \brief Symbolic addresses for the SRAMCTL unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define SRAMCTL_OCI_BASE 0x40030000
+#define SRAMCTL_SRBAR 0x40030000
+#define SRAMCTL_SRMR 0x40030008
+#define SRAMCTL_SRMAP 0x40030010
+#define SRAMCTL_SREAR 0x40030018
+#define SRAMCTL_SRBV0 0x40030020
+#define SRAMCTL_SRBV1 0x40030028
+#define SRAMCTL_SRBV2 0x40030030
+#define SRAMCTL_SRBV3 0x40030038
+#define SRAMCTL_SRCHSW 0x40030040
+
+#endif // __SRAMCTL_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/tod_firmware_registers.h b/src/ssx/pgp/registers/tod_firmware_registers.h
new file mode 100755
index 0000000..7a700d7
--- /dev/null
+++ b/src/ssx/pgp/registers/tod_firmware_registers.h
@@ -0,0 +1,58 @@
+#ifndef __TOD_FIRMWARE_REGISTERS_H__
+#define __TOD_FIRMWARE_REGISTERS_H__
+
+// $Id: tod_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:23 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/tod_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file tod_firmware_registers.h
+/// \brief C register structs for the TOD unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union tod_value_reg {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t tod_incrementer : 60;
+ uint64_t tod_wof : 4;
+#else
+ uint64_t tod_wof : 4;
+ uint64_t tod_incrementer : 60;
+#endif // _BIG_ENDIAN
+ } fields;
+} tod_value_reg_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __TOD_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/tod_register_addresses.h b/src/ssx/pgp/registers/tod_register_addresses.h
new file mode 100755
index 0000000..ac7d136
--- /dev/null
+++ b/src/ssx/pgp/registers/tod_register_addresses.h
@@ -0,0 +1,22 @@
+#ifndef __TOD_REGISTER_ADDRESSES_H__
+#define __TOD_REGISTER_ADDRESSES_H__
+
+// $Id: tod_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/tod_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file tod_register_addresses.h
+/// \brief Symbolic addresses for the TOD unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define TOD_PIB_BASE 0x00040000
+#define TOD_VALUE_REG 0x00040020
+
+#endif // __TOD_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/registers/tpc_firmware_registers.h b/src/ssx/pgp/registers/tpc_firmware_registers.h
new file mode 100644
index 0000000..62f1c42
--- /dev/null
+++ b/src/ssx/pgp/registers/tpc_firmware_registers.h
@@ -0,0 +1,213 @@
+#ifndef __TPC_FIRMWARE_REGISTERS_H__
+#define __TPC_FIRMWARE_REGISTERS_H__
+
+// $Id: tpc_firmware_registers.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/tpc_firmware_registers.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file tpc_firmware_registers.h
+/// \brief C register structs for the TPC unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+#ifndef SIXTYFOUR_BIT_CONSTANT
+#ifdef __ASSEMBLER__
+#define SIXTYFOUR_BIT_CONSTANT(x) x
+#else
+#define SIXTYFOUR_BIT_CONSTANT(x) x##ull
+#endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+
+
+
+typedef union tpc_perv_gp3 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t tp_chiplet_chiplet_en_dc : 1;
+ uint64_t put_in_later0 : 25;
+ uint64_t tp_chiplet_fence_pcb_dc : 1;
+ uint64_t put_in_later1 : 37;
+#else
+ uint64_t put_in_later1 : 37;
+ uint64_t tp_chiplet_fence_pcb_dc : 1;
+ uint64_t put_in_later0 : 25;
+ uint64_t tp_chiplet_chiplet_en_dc : 1;
+#endif // _BIG_ENDIAN
+ } fields;
+} tpc_perv_gp3_t;
+
+
+
+typedef union tpc_gp0 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t put_in_later0 : 40;
+ uint64_t tc_node_id_dc : 3;
+ uint64_t tc_chip_id_dc : 3;
+ uint64_t put_in_later1 : 18;
+#else
+ uint64_t put_in_later1 : 18;
+ uint64_t tc_chip_id_dc : 3;
+ uint64_t tc_node_id_dc : 3;
+ uint64_t put_in_later0 : 40;
+#endif // _BIG_ENDIAN
+ } fields;
+} tpc_gp0_t;
+
+
+
+typedef union tpc_gp0_and {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t put_in_later0 : 40;
+ uint64_t tc_node_id_dc : 3;
+ uint64_t tc_chip_id_dc : 3;
+ uint64_t put_in_later1 : 18;
+#else
+ uint64_t put_in_later1 : 18;
+ uint64_t tc_chip_id_dc : 3;
+ uint64_t tc_node_id_dc : 3;
+ uint64_t put_in_later0 : 40;
+#endif // _BIG_ENDIAN
+ } fields;
+} tpc_gp0_and_t;
+
+
+
+typedef union tpc_gp0_or {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t put_in_later0 : 40;
+ uint64_t tc_node_id_dc : 3;
+ uint64_t tc_chip_id_dc : 3;
+ uint64_t put_in_later1 : 18;
+#else
+ uint64_t put_in_later1 : 18;
+ uint64_t tc_chip_id_dc : 3;
+ uint64_t tc_node_id_dc : 3;
+ uint64_t put_in_later0 : 40;
+#endif // _BIG_ENDIAN
+ } fields;
+} tpc_gp0_or_t;
+
+
+
+typedef union tpc_hpr2 {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t hang_pulse_reg : 6;
+ uint64_t suppress_hang : 1;
+ uint64_t _reserved0 : 57;
+#else
+ uint64_t _reserved0 : 57;
+ uint64_t suppress_hang : 1;
+ uint64_t hang_pulse_reg : 6;
+#endif // _BIG_ENDIAN
+ } fields;
+} tpc_hpr2_t;
+
+
+
+typedef union tpc_device_id {
+
+ uint64_t value;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint32_t high_order;
+ uint32_t low_order;
+#else
+ uint32_t low_order;
+ uint32_t high_order;
+#endif // _BIG_ENDIAN
+ } words;
+ struct {
+#ifdef _BIG_ENDIAN
+ uint64_t cfam_id : 32;
+ uint64_t fuse_nx_allow_crypto : 1;
+ uint64_t fuse_vmx_crypto_dis : 1;
+ uint64_t fuse_fp_throttle_en : 1;
+ uint64_t reserved32 : 1;
+ uint64_t socket_id : 3;
+ uint64_t chippos_id : 1;
+ uint64_t _reserved0 : 24;
+#else
+ uint64_t _reserved0 : 24;
+ uint64_t chippos_id : 1;
+ uint64_t socket_id : 3;
+ uint64_t reserved32 : 1;
+ uint64_t fuse_fp_throttle_en : 1;
+ uint64_t fuse_vmx_crypto_dis : 1;
+ uint64_t fuse_nx_allow_crypto : 1;
+ uint64_t cfam_id : 32;
+#endif // _BIG_ENDIAN
+ } fields;
+} tpc_device_id_t;
+
+
+#endif // __ASSEMBLER__
+#endif // __TPC_FIRMWARE_REGISTERS_H__
+
diff --git a/src/ssx/pgp/registers/tpc_register_addresses.h b/src/ssx/pgp/registers/tpc_register_addresses.h
new file mode 100644
index 0000000..50c7e97
--- /dev/null
+++ b/src/ssx/pgp/registers/tpc_register_addresses.h
@@ -0,0 +1,30 @@
+#ifndef __TPC_REGISTER_ADDRESSES_H__
+#define __TPC_REGISTER_ADDRESSES_H__
+
+// $Id: tpc_register_addresses.h,v 1.1.1.1 2013/12/11 21:03:24 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/registers/tpc_register_addresses.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file tpc_register_addresses.h
+/// \brief Symbolic addresses for the TPC unit
+
+// *** WARNING *** - This file is generated automatically, do not edit.
+
+
+#define TPC_PERVPIB_BASE 0x00050000
+#define TPC_PERV_GP3 0x0005001b
+#define TPC_PIB_BASE 0x01000000
+#define TPC_GP0 0x01000000
+#define TPC_GP0_AND 0x01000004
+#define TPC_GP0_OR 0x01000005
+#define TPC_MISCPIB_BASE 0x010f0000
+#define TPC_HPR2 0x010f0022
+#define TPC_TPCHIP_BASE 0x000f0000
+#define TPC_DEVICE_ID 0x000f000f
+
+#endif // __TPC_REGISTER_ADDRESSES_H__
+
diff --git a/src/ssx/pgp/ssx.mk b/src/ssx/pgp/ssx.mk
new file mode 100755
index 0000000..348718d
--- /dev/null
+++ b/src/ssx/pgp/ssx.mk
@@ -0,0 +1,424 @@
+# $Id: ssx.mk,v 1.2 2014/06/26 12:55:39 cmolsen Exp $
+# $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/ssx.mk,v $
+# Make header for PgP SSX builds
+#
+# The application may define the following variables to control the
+# build process:
+#
+# APP_INCLUDES : Aplication-specific header search paths
+#
+# DEFS : A string of -D<symbol>[=<value>] to control compilation
+#
+# SSX : Default ..; The path to the SSX source code.
+# The default is set for building the SSX
+# subdirectories.
+#
+# SSX_THREAD_SUPPORT : (0/1, default 1); Compile SSX thread and
+# semaphore suppprt
+#
+# SSX_TIMER_SUPPORT : (0/1, default 1); Compile SSX timer suppprt
+#
+# PPC405_MMU_SUPPORT : (0/1, default 1); Compile for PPC405 simple MMU protection
+#
+# SIMICS_ENVIRONMENT : (0/1, current default 0); Compile for Simics
+#
+# SIMICS_MAGIC_PANIC : (0/1, current default 0); Use Simics Magic
+# breakpoint for SSX_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.
+
+# >> gitprep
+# Use fips tracepp
+TRACEPP = /afs/austin/projects/esw/fips820/Builds/built/tools/x86/tracepp
+export OCCROOT = $(dir $(lastword $(MAKEFILE_LIST)))../../
+
+ifndef SIMICS_ENVIRONMENT
+SIMICS_ENVIRONMENT=0
+endif
+# << gitprep
+
+ifndef GCC-TOOL-PREFIX
+# >> gitprep
+# The new compiler for GNU builds
+GCC-TOOL-PREFIX = powerpc64-unknown-linux-gnu-
+endif
+
+ifndef HOST-PREFIX
+HOST-PREFIX = x86_64-pc-linux-gnu-
+endif
+
+JAIL = $(HOST-PREFIX)jail
+CC_ASM = $(GCC-TOOL-PREFIX)gcc # Assembly still doesn't use tracepp
+CC = $(TRACEPP) $(GCC-TOOL-PREFIX)gcc
+AS = $(JAIL) /usr/bin/as
+AR = $(JAIL) /usr/bin/ar
+LD = $(GCC-TOOL-PREFIX)ld
+OBJDUMP = $(GCC-TOOL-PREFIX)objdump
+OBJCOPY = $(JAIL) /usr/bin/objcopy
+CPP = $(JAIL) /usr/bin/cpp
+# << gitprep
+
+
+ifndef CTEPATH
+$(warning The CTEPATH variable is not defined; Defaulting to /afs/awd)
+CTEPATH = /afs/awd/projects/cte
+endif
+
+PORE-AS = $(CTEPATH)/tools/porebinutils/prod/bin/pore-elf64-as
+PORE-AS = $(CTEPATH)/tools/porebinutils/prod/bin/pore-elf64-as
+PORE-LD = $(CTEPATH)/tools/porebinutils/prod/bin/pore-elf64-ld
+PORE-OBJCOPY = $(CTEPATH)/tools/porebinutils/prod/bin/pore-elf64-objcopy
+
+ifeq "$(SSX)" ""
+SSX = ..
+endif
+
+ifeq "$(LIB)" ""
+LIB = ../../lib
+endif
+
+ifeq "$(SSX_TIMER_SUPPORT)" ""
+SSX_TIMER_SUPPORT = 1
+endif
+
+ifeq "$(SSX_THREAD_SUPPORT)" ""
+SSX_THREAD_SUPPORT = 1
+endif
+
+ifeq "$(PPC405_MMU_SUPPORT)" ""
+PPC405_MMU_SUPPORT = 1
+endif
+
+ifeq "$(PGP_ASYNC_SUPPORT)" ""
+PGP_ASYNC_SUPPORT = 1
+endif
+
+ifndef GCC-O-LEVEL
+GCC-O-LEVEL = -Os
+endif
+
+# >> gitprep
+GCC-DEFS += -DSIMICS_ENVIRONMENT=$(SIMICS_ENVIRONMENT)
+# << gitprep
+GCC-DEFS += -DSSX_TIMER_SUPPORT=$(SSX_TIMER_SUPPORT)
+GCC-DEFS += -DSSX_THREAD_SUPPORT=$(SSX_THREAD_SUPPORT)
+GCC-DEFS += -DPPC405_MMU_SUPPORT=$(PPC405_MMU_SUPPORT)
+DEFS += $(GCC-DEFS) -DPGAS_PPC=1 -DCONFIGURE_PTS_SLW=0
+PORE-DEFS += $(GCC-DEFS)
+
+############################################################################
+
+INCLUDES += $(APP_INCLUDES) \
+ -I$(SSX)/ssx -I$(SSX)/ppc32 -I$(SSX)/ppc405 \
+ -I$(SSX)/pgp -I$(SSX)/pgp/registers \
+ -I$(LIB)
+
+PIPE-CFLAGS = -pipe -Wa,-m405
+
+# >> gitprep
+# Update compile flags for GNU build, allow warnings
+GCC-CFLAGS += -g -Wall -fsigned-char -msoft-float \
+ -m32 -mcpu=405 -mmultiple -mstring \
+ -meabi -msdata=eabi -ffreestanding -fno-common \
+ -fno-inline-functions-called-once
+# << gitprep
+
+CFLAGS = -c $(GCC-CFLAGS) $(PIPE-CFLAGS) $(GCC-O-LEVEL) $(INCLUDES)
+PORE-CFLAGS = -E $(GCC-CFLAGS) $(OPT) $(INCLUDES)
+# >> gitprep
+# Add compile flags needed for the GNU build
+CPPFLAGS += -m32 -mcpu=405 -msdata=eabi -meabi -mstring -mmultiple
+# << gitprep
+
+############################################################################
+
+# Build object code
+#
+# %.o: %.c - Compile C code
+#
+# %.o: %.S - Compile PowerPC assembler (including PGAS-PPC assembly)
+
+%.o: %.c
+ $(CC) $(CFLAGS) $(DEFS) -o $@ $<
+
+%.o: %.S
+ $(CC_ASM) $(CFLAGS) $(DEFS) -o $@ $<
+
+#Temporary always use PGAS PPC Assembler for compiling .pS files.
+#relocatable symbols are being added to the GPE (.pS) files and
+#so need new way to compile using GNU assembler.
+PGAS_PPC=1
+
+# use "make PGAS_PPC=1" to compile .pS file using PGAS PPC assembler.
+# If PGAS_PPC=1 is not part of the make command, then GNU assembler is
+# used for compiling .pS files.
+ifdef PGAS_PPC
+
+ifneq ($(MAKE_PORE_HOOKS),)
+
+# This Makefile included here defines how to convert *.pS into both the object
+# file and the hooks object file.
+
+include $(MAKE_PORE_HOOKS)
+
+else
+
+%.o: %.pS
+# >> gitprep
+# Force use of PORE assembler for GNU builds
+# $(CC_ASM) -x assembler-with-cpp $(CFLAGS) $(DEFS) -o $@ $<
+ $(CC_ASM) -x assembler-with-cpp $(PORE-CFLAGS) $(PORE-DEFS) $< | $(PORE-AS) - -o $@
+# << gitprep
+endif
+
+%.lst: %.pS
+ $(CC_ASM) -x assembler-with-cpp $(CFLAGS) $(DEFS) \
+ -Wa,-al -Wa,--listing-cont-lines=20 $< > $@
+
+else
+%.o: %.pS
+ $(CPP_ASM) -x assembler-with-cpp $(PORE-CFLAGS) $(PORE-DEFS) $< | $(PORE-AS) - -o $@
+endif
+
+# Other useful targets
+#
+# %.S: %.c - See what the assembler produces from the C code, however you can
+# also just look at the final disassembly.
+#
+# %.lst: %.S - Get an assembler listing
+#
+# %.cpp: %.S - Preprocess PowerPC assembler source to stdout
+#
+# %.cpp: %.pS - Preprocess PORE assembler source to stdout
+#
+# %.cpp: %.c - Preprocess C source to stdout
+
+%.S: %.c
+ $(CC) $(CFLAGS) $(DEFS) -S -o $@ $<
+
+%.lst: %.S
+ $(CC_ASM) $(CFLAGS) $(DEFS) -Wa,-al -Wa,--listing-cont-lines=20 $< > $@
+
+%.cpp: %.S
+ $(CC_ASM) $(CFLAGS) $(DEFS) -E $<
+
+%.cpp: %.pS
+ $(CC) -x assembler-with-cpp $(CFLAGS) $(DEFS) -E $<
+
+%.cpp: %.c
+ $(CC) $(CFLAGS) $(DEFS) -E $<
+
+# 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.
+
+%.d: %.c
+ @set -e; rm -f $@; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< > $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+%.d: %.S
+ @set -e; rm -f $@; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< > $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+%.d: %.pS
+ @set -e; rm -f $@; \
+ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) -x assembler-with-cpp $(DEFS) $< > $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+############################################################################
+#
+# GCC Compiler flags used in these builds. Comments, or reasons for
+# non-obvious choices appear in [] after the GCC documentation.
+#
+#`-Os'
+# Optimize for size. `-Os' enables all `-O2' optimizations that do
+# not typically increase code size. It also performs further
+# optimizations designed to reduce code size.
+#
+# `-Os' disables the following optimization flags:
+# -falign-functions -falign-jumps -falign-loops
+# -falign-labels -freorder-blocks -freorder-blocks-and-partition
+# -fprefetch-loop-arrays -ftree-vect-loop-version
+#
+# If you use multiple `-O' options, with or without level numbers,
+# the last such option is the one that is effective.
+#
+#`-g'
+# Produce debugging information in the operating system's native
+# format (stabs, COFF, XCOFF, or DWARF 2). GDB can work with this
+# debugging information.
+#
+# On most systems that use stabs format, `-g' enables use of extra
+# debugging information that only GDB can use; this extra information
+# makes debugging work better in GDB but will probably make other
+# debuggers crash or refuse to read the program. If you want to
+# control for certain whether to generate the extra information, use
+# `-gstabs+', `-gstabs', `-gxcoff+', `-gxcoff', or `-gvms' (see
+# below).
+#
+# GCC allows you to use `-g' with `-O'. The shortcuts taken by
+# optimized code may occasionally produce surprising results: some
+# variables you declared may not exist at all; flow of control may
+# briefly move where you did not expect it; some statements may not
+# be executed because they compute constant results or their values
+# were already at hand; some statements may execute in different
+# places because they were moved out of loops.
+#
+# Nevertheless it proves possible to debug optimized output. This
+# makes it reasonable to use the optimizer for programs that might
+# have bugs.
+#
+#`-Wall'
+# Turns on all optional warnings which are desirable for normal code.
+# At present this is `-Wcomment', `-Wtrigraphs', `-Wmultichar' and a
+# warning about integer promotion causing a change of sign in `#if'
+# expressions. Note that many of the preprocessor's warnings are on
+# by default and have no options to control them.
+#
+#`-Werror'
+# Make all warnings into errors.
+#
+#`-fsigned-char'
+# Let the type `char' be signed, like `signed char'.
+#
+# Note that this is equivalent to `-fno-unsigned-char', which is the
+# negative form of `-funsigned-char'. Likewise, the option
+# `-fno-signed-char' is equivalent to `-funsigned-char'.
+#
+#`-msoft-float'
+# Generate output containing library calls for floating point.
+# *Warning:* the requisite libraries are not available for all ARM
+# targets. Normally the facilities of the machine's usual C
+# compiler are used, but this cannot be done directly in
+# cross-compilation. You must make your own arrangements to provide
+# suitable library functions for cross-compilation.
+#
+# `-msoft-float' changes the calling convention in the output file;
+# therefore, it is only useful if you compile _all_ of a program with
+# this option. In particular, you need to compile `libgcc.a', the
+# library that comes with GCC, with `-msoft-float' in order for this
+# to work.
+#
+#`-pipe'
+# Use pipes rather than temporary files for communication between the
+# various stages of compilation. This fails to work on some systems
+# where the assembler is unable to read from a pipe; but the GNU
+# assembler has no trouble.
+#
+#`-mmultiple'
+#`-mno-multiple'
+# Generate code that uses (does not use) the load multiple word
+# instructions and the store multiple word instructions. These
+# instructions are generated by default on POWER systems, and not
+# generated on PowerPC systems. Do not use `-mmultiple' on little
+# endian PowerPC systems, since those instructions do not work when
+# the processor is in little endian mode. The exceptions are PPC740
+# and PPC750 which permit the instructions usage in little endian
+# mode.
+#
+#`-mstring'
+#`-mno-string'
+# Generate code that uses (does not use) the load string instructions
+# and the store string word instructions to save multiple registers
+# and do small block moves. These instructions are generated by
+# default on POWER systems, and not generated on PowerPC systems.
+# Do not use `-mstring' on little endian PowerPC systems, since those
+# instructions do not work when the processor is in little endian
+# mode. The exceptions are PPC740 and PPC750 which permit the
+# instructions usage in little endian mode.
+#
+#`-meabi'
+#`-mno-eabi'
+# On System V.4 and embedded PowerPC systems do (do not) adhere to
+# the Embedded Applications Binary Interface (eabi) which is a set of
+# modifications to the System V.4 specifications. Selecting `-meabi'
+# means that the stack is aligned to an 8 byte boundary, a function
+# `__eabi' is called to from `main' to set up the eabi environment,
+# and the `-msdata' option can use both `r2' and `r13' to point to
+# two separate small data areas. Selecting `-mno-eabi' means that
+# the stack is aligned to a 16 byte boundary, do not call an
+# initialization function from `main', and the `-msdata' option will
+# only use `r13' to point to a single small data area. The `-meabi'
+# option is on by default if you configured GCC using one of the
+# `powerpc*-*-eabi*' options.
+#
+# [We elected to use the EABI to reduce stack requirements and possibly reduce
+# code size and improve performance. In practice it probably has little real
+# effect since the code size and performance improvements only apply to global
+# variables <= 8 bytes, and our applications will not have deeply nested call
+# trees. Still, much of the assembler code requires/assumes the EABI is in
+# place, and it certainly doesn't hurt anything to use it.]
+#
+#`-msdata=eabi'
+# On System V.4 and embedded PowerPC systems, put small initialized
+# `const' global and static data in the `.sdata2' section, which is
+# pointed to by register `r2'. Put small initialized non-`const'
+# global and static data in the `.sdata' section, which is pointed
+# to by register `r13'. Put small uninitialized global and static
+# data in the `.sbss' section, which is adjacent to the `.sdata'
+# section. The `-msdata=eabi' option is incompatible with the
+# `-mrelocatable' option. The `-msdata=eabi' option also sets the
+# `-memb' option.
+#
+#`-memb'
+# On embedded PowerPC systems, set the PPC_EMB bit in the ELF flags
+# header to indicate that `eabi' extended relocations are used.
+#
+#`-ffreestanding'
+# Assert that compilation takes place in a freestanding environment.
+# This implies `-fno-builtin'. A freestanding environment is one
+# in which the standard library may not exist, and program startup
+# may not necessarily be at `main'. The most obvious example is an
+# OS kernel. This is equivalent to `-fno-hosted'.
+#
+#`-fno-common'
+# In C, allocate even uninitialized global variables in the data
+# section of the object file, rather than generating them as common
+# blocks. This has the effect that if the same variable is declared
+# (without `extern') in two different compilations, you will get an
+# error when you link them. The only reason this might be useful is
+# if you wish to verify that the program will work on other systems
+# which always work this way.
+#
+# [It is always assumed to be an error if two C source files declare global
+# variables of the same name, since it is not clear whether this was intended
+# or not.]
+#
+#`-finline-functions-called-once'
+#`-fno-inline-functions-called-once'
+# Consider all `static' functions called once for inlining into their
+# caller even if they are not marked `inline'. If a call to a given
+# function is integrated, then the function is not output as
+# assembler code in its own right.
+#
+# Enabled if `-funit-at-a-time' is enabled.
+#
+# [There is a 'bug' in GCC related to inlining static, called-once
+# functions. GCC allocates stack space in the caller for the stacks of ALL
+# inlined functions of this type, even if they are called sequentially,
+# leading in some cases to kilobytes of wasted stack space. If you want to
+# inline a static called-once function you will need to explicity declare it
+# as 'inline'.]
+
+
diff --git a/src/ssx/pgp/ssx_port.h b/src/ssx/pgp/ssx_port.h
new file mode 100755
index 0000000..613ac43
--- /dev/null
+++ b/src/ssx/pgp/ssx_port.h
@@ -0,0 +1,19 @@
+#ifndef __SSX_PORT_H__
+#define __SSX_PORT_H__
+
+// $Id: ssx_port.h,v 1.1.1.1 2013/12/11 21:03:22 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/ssx_port.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_port.h
+/// \brief The top-level PGP environment header for SSX.
+
+#define CHIP_PGP
+
+#include "ppc405.h"
+
+#endif /* __SSX_PORT_H__ */
diff --git a/src/ssx/pgp/ssxpgpfiles.mk b/src/ssx/pgp/ssxpgpfiles.mk
new file mode 100755
index 0000000..dd12da1
--- /dev/null
+++ b/src/ssx/pgp/ssxpgpfiles.mk
@@ -0,0 +1,37 @@
+# $Id: ssxpgpfiles.mk,v 1.4 2014/06/26 12:56:28 cmolsen Exp $
+# $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/pgp/ssxpgpfiles.mk,v $
+# @file ssxpgpfiles.mk
+#
+# @brief mk for including pgp object files
+#
+# @page ChangeLogs Change Logs
+# @section ssxpgpfiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+# @pb00E pbavari 03/11/2012 Makefile ODE support
+#
+# @endverbatim
+#
+##########################################################################
+# Object Files
+##########################################################################
+PGP-C-SOURCES = pgp_init.c pgp_irq_init.c pgp_pmc.c pgp_ocb.c pgp_pba.c \
+ pgp_id.c pgp_centaur.c
+PGP-S-SOURCES = pgp_cache.S
+
+PGP-TIMER-C-SOURCES =
+PGP-TIMER-S-SOURCES =
+
+PGP-THREAD-C-SOURCES =
+PGP-THREAD-S-SOURCES =
+
+PGP-ASYNC-C-SOURCES = pgp_async.c pgp_async_pore.c pgp_async_ocb.c \
+ pgp_async_pba.c
+PGP-ASYNC-S-SOURCES =
+
+PGP_OBJECTS += $(PGP-C-SOURCES:.c=.o) $(PGP-S-SOURCES:.S=.o)
+
diff --git a/src/ssx/ppc32/Makefile b/src/ssx/ppc32/Makefile
new file mode 100755
index 0000000..920144e
--- /dev/null
+++ b/src/ssx/ppc32/Makefile
@@ -0,0 +1,33 @@
+# $Id: Makefile,v 1.2 2013/12/12 16:12:37 bcbrock Exp $
+
+# This Makefile is designed to be invoked with the -I argument set to
+# the location of the "ssx.mk" for the build.
+#
+# This makefile creates the libppc32.a library.
+
+# >> gitprep
+# Path cleanup for GNU builds
+SSX = ..
+PGP = $(SSX)/pgp
+
+include $(PGP)/ssx.mk
+# << gitprep
+include ssxppc32files.mk
+
+
+
+libppc32.a: ${PPC32_OBJECTS}
+ $(AR) crs libppc32.a ${PPC32_OBJECTS}
+
+.PHONY : clean
+clean:
+ rm -f *.o *.a *.d *.d.*
+
+
+# This clause prevents the dependencies from creating errors during a clean.
+# Whenever a header file is added or deleted it will likely be necessary to
+# 'make clean' to force recomputation of dependencies.
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(PPC32_OBJECTS:.o=.d)
+endif \ No newline at end of file
diff --git a/src/ssx/ppc32/div64.S b/src/ssx/ppc32/div64.S
new file mode 100755
index 0000000..04ee008
--- /dev/null
+++ b/src/ssx/ppc32/div64.S
@@ -0,0 +1,255 @@
+// $Id: div64.S,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc32/div64.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! 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 SSX 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 "ssx.h"
+ .list
+
+ .set r0, 0
+ .set r1, 1
+ .set r2, 2
+ .set r3, 3
+ .set r4, 4
+ .set r5, 5
+ .set r6, 6
+ .set r7, 7
+ .set r8, 8
+ .set r9, 9
+ .set r10, 10
+ .set r11, 11
+ .set r12, 12
+
+ .global_function __ppc32_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.
+ */
+
+__ppc32_udiv64: // SSX
+ /* Save result pointers on volatile spare registers */
+ ori r12, r8, 0 /* Save remainder address */
+ ori r11, 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? */
+ cmpwi cr1, r6, 0 /* dvd.lsw == 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 */
+ beq cr1, 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(r11)
+ stw r3, 0(r11)
+ stw r8, 4(r12) /* rem.lsw */
+ stw r7, 0(r12) /* rem.msw */
+ blr
+
+lab9:
+ /* Qoutient is 0, divisor > dividend */
+ addi r0, r0, 0
+ stw r3, 0(r12) /* Store remainder */
+ stw r4, 4(r12)
+ stw r0, 0(r11) /* Set quotient to zero */
+ stw r0, 4(r11)
+ blr
+
+lab10:
+ /* Divisor is 0 */
+ addi r0, r0, -1
+ stw r0, 0(r12) /* Set remainder to zero */
+ stw r0, 4(r12)
+ stw r0, 0(r11) /* Set quotient to zero */
+ stw r0, 4(r11)
+ blr
+
+ .epilogue __ppc32_udiv64
diff --git a/src/ssx/ppc32/gnu/stubs-32.h b/src/ssx/ppc32/gnu/stubs-32.h
new file mode 100644
index 0000000..3da2fb2
--- /dev/null
+++ b/src/ssx/ppc32/gnu/stubs-32.h
@@ -0,0 +1,21 @@
+/* This file is automatically generated.
+ It defines a symbol `__stub_FUNCTION' for each function
+ in the C library which is a stub, meaning it will fail
+ every time called, usually setting errno to ENOSYS. */
+
+#ifdef _LIBC
+ #error Applications may not define the macro _LIBC
+#endif
+
+#define __stub___kernel_rem_pio2l
+#define __stub_chflags
+#define __stub_fattach
+#define __stub_fchflags
+#define __stub_fdetach
+#define __stub_gtty
+#define __stub_lchmod
+#define __stub_revoke
+#define __stub_setlogin
+#define __stub_sigreturn
+#define __stub_sstk
+#define __stub_stty
diff --git a/src/ssx/ppc32/ppc32.h b/src/ssx/ppc32/ppc32.h
new file mode 100755
index 0000000..e7f7bf8
--- /dev/null
+++ b/src/ssx/ppc32/ppc32.h
@@ -0,0 +1,171 @@
+#ifndef __PPC32_H__
+#define __PPC32_H__
+
+// $Id: ppc32.h,v 1.2 2014/03/14 15:11:46 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc32/ppc32.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc32.h
+/// \brief Generic 32-bit PowerPC header for SSX
+///
+/// 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.
+
+
+#include "ppc32_asm.h"
+#include "ppc32_gcc.h"
+
+// 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 ("eieio" : : : "memory")
+
+/// Memory barrier
+#define sync() asm volatile ("sync" : : : "memory")
+
+/// Instruction barrier
+#define isync() asm volatile ("isync" : : : "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); eieio();} while(0)
+
+/// 8-bit MMIO Read
+#define in8(addr) \
+({uint8_t __data = *(volatile uint8_t *)(addr); eieio(); __data;})
+
+/// 16-bit MMIO Write
+#define out16(addr, data) \
+do {*(volatile uint16_t *)(addr) = (data); eieio();} while(0)
+
+/// 16-bit MMIO Read
+#define in16(addr) \
+({uint16_t __data = *(volatile uint16_t *)(addr); eieio(); __data;})
+
+/// 32-bit MMIO Write
+#define out32(addr, data) \
+do {*(volatile uint32_t *)(addr) = (data); eieio();} while(0)
+
+/// 32-bit MMIO Read
+#define in32(addr) \
+({uint32_t __data = *(volatile uint32_t *)(addr); eieio(); __data;})
+
+/// 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); \
+ eieio(); \
+ *__addr_lo = (__data & 0xffffffff); \
+ eieio(); \
+ } while(0)
+
+/// 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; \
+ eieio(); \
+ __data = (__data << 32) | *__addr_lo; \
+ eieio(); \
+ __data;})
+
+#endif /* __ASSEMBLER__ */
+
+
+#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__
+
+#endif /* __PPC32_H__ */
diff --git a/src/ssx/ppc32/ppc32_asm.h b/src/ssx/ppc32/ppc32_asm.h
new file mode 100755
index 0000000..0207c22
--- /dev/null
+++ b/src/ssx/ppc32/ppc32_asm.h
@@ -0,0 +1,408 @@
+#ifndef __PPC32_ASM_H__
+#define __PPC32_ASM_H__
+
+// $Id: ppc32_asm.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc32/ppc32_asm.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc32_asm.h
+/// \brief Generic assembler macros for 32-bit PowerPC
+
+// 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 ppc32_asm Generic assembler macros for 32-bit PowerPC
+///
+///
+/// \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
+
+#endif /* __ASSEMBLER__ */
+
+/// \endcond
+
+// Local Variables:
+// mode:asm
+// End:
+
+#endif /* __PPC32_ASM_H__ */
diff --git a/src/ssx/ppc32/ppc32_gcc.c b/src/ssx/ppc32/ppc32_gcc.c
new file mode 100755
index 0000000..a00ab48
--- /dev/null
+++ b/src/ssx/ppc32/ppc32_gcc.c
@@ -0,0 +1,309 @@
+// $Id: ppc32_gcc.c,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc32/ppc32_gcc.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc32_gcc.h
+/// \brief 32-bit PowerPC functions expected by GCC
+///
+/// GCC expects certain built-in functions to be defined in the environment.
+/// Since SSX 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 SSX
+/// 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 "ssx.h"
+#include "ppc32_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. This compiles to 22 PPC405 instructions.
+
+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 __ppc32_udiv64() assembles to 304 bytes. The full C
+// routine __ppc_sdiv64 compiles to 416 bytes with the most-negative checks,
+// but only 184 bytes as configured here.
+
+#if 0
+// 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.
+//
+#endif
+
+uint64_t
+__udivdi3(uint64_t u, uint64_t v)
+{
+ uint64_t quotient, remainder;
+
+ __ppc32_udiv64(u, v, &quotient, &remainder);
+ return quotient;
+}
+
+
+uint64_t
+__umoddi3(uint64_t u, uint64_t v)
+{
+ uint64_t quotient, remainder;
+
+ __ppc32_udiv64(u, v, &quotient, &remainder);
+ return remainder;
+}
+
+
+#if 0
+#define INT64_T_MIN ((int64_t)(0x8000000000000000ull))
+#endif
+
+void
+__ppc32_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
+
+ __ppc32_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;
+
+ __ppc32_sdiv64(u, v, &quotient, &remainder);
+ return quotient;
+}
+
+
+int64_t
+__moddi3(int64_t u, int64_t v)
+{
+ int64_t quotient, remainder;
+
+ __ppc32_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/ssx/ppc32/ppc32_gcc.h b/src/ssx/ppc32/ppc32_gcc.h
new file mode 100755
index 0000000..1925107
--- /dev/null
+++ b/src/ssx/ppc32/ppc32_gcc.h
@@ -0,0 +1,75 @@
+#ifndef __PPC32_GCC_H__
+#define __PPC32_GCC_H__
+
+// $Id: ppc32_gcc.h,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc32/ppc32_gcc.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc32_gcc.h
+/// \brief 32-bit PowerPC 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
+__ppc32_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
+__ppc32_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 /* __PPC32_GCC_H__ */
diff --git a/src/ssx/ppc32/savegpr.S b/src/ssx/ppc32/savegpr.S
new file mode 100755
index 0000000..854f22b
--- /dev/null
+++ b/src/ssx/ppc32/savegpr.S
@@ -0,0 +1,78 @@
+// $Id: savegpr.S,v 1.1.1.1 2013/12/11 21:03:25 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc32/savegpr.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+///
+/// \file savegpr.S
+/// \brief Push registers onto or load registers from the stack
+///
+/// This code was developed due to missing references to _savegpr_{X}
+/// and _restgpr_{X}_x that surfaced when moving to GCC 4.5.1 and
+/// using the -Os optimization level.
+///
+/// The open-source code was viewed to get the spec, but no
+/// code was copied.
+///
+
+
+ .macro SAVE reg
+ .global _savegpr_\reg
+ _savegpr_\reg\():
+ stw \reg,(((31-\reg)*4 +4)*-1)(11)
+ .endm
+
+ SAVE 14
+ SAVE 15
+ SAVE 16
+ SAVE 17
+ SAVE 18
+ SAVE 19
+ SAVE 20
+ SAVE 21
+ SAVE 22
+ SAVE 23
+ SAVE 24
+ SAVE 25
+ SAVE 26
+ SAVE 27
+ SAVE 28
+ SAVE 29
+ SAVE 30
+ SAVE 31
+ blr
+
+ .macro RESTX reg
+ .global _restgpr_\reg\()_x
+ _restgpr_\reg\()_x:
+ .ifeq (31-\reg)
+ lwz 0,4(11)
+ .endif
+ lwz \reg,(((31-\reg)*4 +4)*-1)(11)
+
+ .endm
+
+ RESTX 14
+ RESTX 15
+ RESTX 16
+ RESTX 17
+ RESTX 18
+ RESTX 19
+ RESTX 20
+ RESTX 21
+ RESTX 22
+ RESTX 23
+ RESTX 24
+ RESTX 25
+ RESTX 26
+ RESTX 27
+ RESTX 28
+ RESTX 29
+ RESTX 30
+ RESTX 31
+ mtlr 0
+ mr 1,11
+ blr
diff --git a/src/ssx/ppc32/ssxppc32files.mk b/src/ssx/ppc32/ssxppc32files.mk
new file mode 100755
index 0000000..8697550
--- /dev/null
+++ b/src/ssx/ppc32/ssxppc32files.mk
@@ -0,0 +1,29 @@
+# $Id: ssxppc32files.mk,v 1.2 2014/06/26 12:58:31 cmolsen Exp $
+# $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc32/ssxppc32files.mk,v $
+# @file ssxppc32files.mk
+#
+# @brief mk for including ppc32 object files
+#
+# @page ChangeLogs Change Logs
+# @section ssxppc32files.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+# @pb00E pbavari 03/11/2012 Makefile ODE support
+#
+# @endverbatim
+#
+
+##########################################################################
+# Object Files
+##########################################################################
+PPC32-C-SOURCES = ppc32_gcc.c
+PPC32-S-SOURCES = div64.S savegpr.S
+
+PPC32_OBJECTS = $(PPC32-C-SOURCES:.c=.o) $(PPC32-S-SOURCES:.S=.o)
+
+
+
diff --git a/src/ssx/ppc405/Makefile b/src/ssx/ppc405/Makefile
new file mode 100755
index 0000000..89c2c58
--- /dev/null
+++ b/src/ssx/ppc405/Makefile
@@ -0,0 +1,40 @@
+# $Id: Makefile,v 1.2 2013/12/12 16:12:38 bcbrock Exp $
+
+# This Makefile is designed to be invoked with the -I argument set to
+# the location of the "ssx.mk" for the build
+
+# >> gitprep
+# Path cleanup for GNU builds
+SSX = ..
+PGP = $(SSX)/pgp
+
+include $(PGP)/ssx.mk
+# << gitprep
+include ssxppc405files.mk
+
+ifeq "$(SSX_TIMER_SUPPORT)" "1"
+PPC405_OBJECTS += ${PPC405-TIMER-C-SOURCES:.c=.o} ${PPC405-TIMER-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(SSX_THREAD_SUPPORT)" "1"
+PPC405_OBJECTS += ${PPC405-THREAD-C-SOURCES:.c=.o} ${PPC405-THREAD-S-SOURCES:.S=.o}
+endif
+
+ifeq "$(PPC405_MMU_SUPPORT)" "1"
+PPC405_OBJECTS += ${PPC405-MMU-C-SOURCES:.c=.o} ${PPC405-MMU-S-SOURCES:.S=.o}
+endif
+
+
+all: local
+ $(MAKE) -I ../pgp -C ../ppc32
+
+local: $(PPC405_OBJECTS)
+
+.PHONY : clean
+clean:
+ rm -f *.o *.d *.d.*
+ $(MAKE) -I ../pgp -C ../ppc32 clean
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(PPC405_OBJECTS:.o=.d)
+endif \ No newline at end of file
diff --git a/src/ssx/ppc405/ppc405.h b/src/ssx/ppc405/ppc405.h
new file mode 100755
index 0000000..18b0c53
--- /dev/null
+++ b/src/ssx/ppc405/ppc405.h
@@ -0,0 +1,771 @@
+#ifndef __PPC405_H__
+#define __PPC405_H__
+
+// $Id: ppc405.h,v 1.3 2014/02/03 01:30:42 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405.h
+/// \brief PowerPC 405 port header for SSX
+
+// The 405 has a 32-byte line and 2-way set associative caches. The cache
+// configuration varies by chip/ASIC.
+//
+// Regarding the DCACHE_TAG_MASK, used by dcache_flush_all: The IBM
+// documentation on the D-cache tag sizes doesn't make any sense to me - it
+// claims the tag size is constant regardless of the size of the cache.
+// However the Xilinx documentation for their 405 core (which has the same
+// 16KB cache as PgP) is consistent with the way the DCACHE_TAG_MASK is
+// defined here.
+
+#define CACHE_LINE_SIZE 32
+#define LOG_CACHE_LINE_SIZE 5
+
+#define ICACHE_WAYS 2
+#define DCACHE_WAYS 2
+
+#define LOG_ICACHE_WAYS 1
+#define LOG_DCACHE_WAYS 1
+
+#define ICACHE_LINES (ICACHE_SIZE / CACHE_LINE_SIZE)
+#define DCACHE_LINES (DCACHE_SIZE / CACHE_LINE_SIZE)
+
+#define DCACHE_TAG_MASK \
+ ((0xffffffff << (LOG_DCACHE_SIZE - LOG_DCACHE_WAYS)) & 0xffffffff)
+
+#ifdef CHIP_PGP
+
+#define ICACHE_SIZE (16 * 1024)
+#define DCACHE_SIZE (16 * 1024)
+
+#define LOG_ICACHE_SIZE 14
+#define LOG_DCACHE_SIZE 14
+
+#else
+#error "Please define the cache configuration of the processor"
+#endif
+
+// Macros to define where declared code is actually compiled
+
+#ifdef __PPC405_C__
+#define IF__PPC405_CORE_C__(x) x
+#define UNLESS__PPC405_CORE_C__(x)
+#else
+#define IF__PPC405_CORE_C__(x)
+#define UNLESS__PPC405_CORE_C__(x) x
+#endif
+
+#ifdef __PPC405_IRQ_CORE_C__
+#define IF__PPC405_IRQ_CORE_C__(x) x
+#define UNLESS__PPC405_IRQ_CORE_C__(x)
+#else
+#define IF__PPC405_IRQ_CORE_C__(x)
+#define UNLESS__PPC405_IRQ_CORE_C__(x) x
+#endif
+
+
+#ifdef CHIP_PGP
+#include "pgp.h"
+#endif
+
+#include "ppc32.h"
+#include "ppc405_dcr.h"
+#include "ppc405_spr.h"
+#include "ppc405_msr.h"
+#include "ppc405_irq.h"
+#include "ppc405_cache.h"
+
+#if PPC405_MMU_SUPPORT
+
+#include "ppc405_mmu.h"
+
+#ifndef PPC405_IR_SUPPORT
+#define PPC405_IR_SUPPORT 1
+#endif
+
+#ifndef PPC405_DR_SUPPORT
+#define PPC405_DR_SUPPORT 1
+#endif
+
+#define PPC405_RELOCATION_MODE \
+ ((PPC405_IR_SUPPORT * MSR_IR) | (PPC405_DR_SUPPORT * MSR_DR))
+
+#ifndef __ASSEMBLER__
+void*
+memcpy_real(void* dest, const void* src, size_t n);
+#endif
+
+#else /* PPC405_MMU_SUPPORT */
+
+#define PPC405_RELOCATION_MODE 0
+
+#ifndef __ASSEMBLER__
+static inline void*
+memcpy_real(void* dest, const void* src, size_t n)
+{
+ memcpy(dest, src, n);
+ icache_invalidate_all();
+ return dest;
+}
+#endif
+
+#endif /* PPC405_MMU_SUPPORT */
+
+/// By default, in MMU mode free space is read/write only, just like normal
+/// data. Saome applications may need to execute from free space however, and
+/// can override this default.
+
+#ifndef EXECUTABLE_FREE_SPACE
+#define EXECUTABLE_FREE_SPACE 0
+#endif
+
+#include "ppc405_context.h"
+
+// PPC405 stack characteristics for SSX. The pre-pattern pattern is selected
+// to be easily recognizable yet be an illegal instruction.
+
+#define SSX_STACK_DIRECTION -1
+#define SSX_STACK_PRE_DECREMENT 1
+#define SSX_STACK_ALIGNMENT 8
+#define SSX_STACK_TYPE unsigned int
+#define SSX_STACK_PATTERN 0x03abcdef
+
+// Kernel data structure offsets for assembler code
+
+#define SSX_THREAD_OFFSET_SAVED_STACK_POINTER 0
+#define SSX_THREAD_OFFSET_STACK_LIMIT 4
+#define SSX_THREAD_OFFSET_STACK_BASE 8
+
+// SSX boot loader panic codes
+
+#define PPC405_BOOT_CCR0_MODIFY_FAILED 0x00405000
+#define PPC405_BOOT_VECTORS_NOT_ALIGNED 0x00405001
+
+// Interrupt handler panic codes
+
+#define PPC405_DEFAULT_IRQ_HANDLER 0x00405010
+#define PPC405_DEFAULT_SPECIAL_HANDLER 0x00405011
+#define PPC405_PHANTOM_INTERRUPT 0x00405012
+#define PPC405_PROGRAM_HALT 0x00405013
+
+
+// Exception handling invariant panic codes
+
+#define PPC405_IRQ_FULL_EXIT_INVARIANT 0x00405020
+#define PPC405_IRQ_FAST2FULL_INVARIANT 0x00405021
+
+
+// API error panic codes
+
+#define PPC405_CACHE_ALIGNMENT 0x00405030
+
+// 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 critical, non-critical and machine check
+/// exceptions. Debug interrupts are not enabled by default. This definition
+/// can be overriden by the application. If MMU protection is enabled then
+/// the IR/DR bits are also modeably set.
+
+#ifndef SSX_THREAD_MACHINE_CONTEXT_DEFAULT
+#define SSX_THREAD_MACHINE_CONTEXT_DEFAULT \
+ (MSR_CE | MSR_EE | MSR_ME | PPC405_RELOCATION_MODE)
+#endif
+
+
+#ifndef __ASSEMBLER__
+
+/// The SSX 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 SSX_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
+/// __ssx_panic_save_dbcr0 and __ssx_panic_save_r3 defined in ppc405_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 SSX_PANIC
+
+#define SSX_PANIC(code) \
+ do { \
+ barrier(); \
+ asm volatile ("stw %r3, __ssx_panic_save_r3@sda21(0)"); \
+ asm volatile ("mfdbcr0 %r3"); \
+ asm volatile ("stw %r3, __ssx_panic_save_dbcr0@sda21(0)"); \
+ asm volatile ("lwz %r3, __ssx_panic_dbcr0@sda21(0)"); \
+ asm volatile ("mtdbcr0 %r3"); \
+ asm volatile ("isync"); \
+ asm volatile ("lwz %r3, __ssx_panic_save_r3@sda21(0)"); \
+ asm volatile ("rlwimi 1,1,0,0,0"); \
+ asm volatile ("trap"); \
+ asm volatile (".long %0" : : "i" (code)); \
+ } while (0)
+
+// These variables are used by the SSX_PANIC() definition above to save and
+// restore state. __ssx_panic_dbcr0 is the value loaded into DBCR0 to force
+// traps to halt the OCC and freeze the timers.
+
+#ifdef __PPC405_CORE_C__
+uint32_t __ssx_panic_save_r3;
+uint32_t __ssx_panic_save_dbcr0;
+uint32_t __ssx_panic_dbcr0 = DBCR0_EDM | DBCR0_TDE | DBCR0_FT;
+#endif
+
+#endif // SSX_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 SSX 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 SSX_PANIC
+
+#define SSX_PANIC(code) _ssx_panic code
+
+ .macro _ssx_panic, code
+ _stwsd %r3, __ssx_panic_save_r3
+ _lwzsd %r3, __ssx_panic_dbcr0
+ mtdbcr0 %r3
+ isync
+ _lwzsd %r3, __ssx_panic_save_r3
+ rlwimi 1,1,0,0,0
+ trap
+ .long \code
+ .endm
+
+#endif // SSX_PANIC
+
+#endif // __ASSEMBLER__
+
+
+// Application-overridible definitions for the SSX 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 PPC405_DBCR0_INITIAL
+#define PPC405_DBCR0_INITIAL (DBCR0_EDM | DBCR0_TDE | DBCR0_FT)
+#endif
+
+/// This is the value of the MSR used during initialization. Once SSX threads
+/// are started (with \c ssx_start_threads()), all machine contexts derive
+/// from the default thread context \c
+/// SSX_THREAD_MACHINE_CONTEXT_DEFAULT. This definition can be overriden by
+/// the application.
+///
+/// The default is to enable machine checks only.
+
+#ifndef PPC405_MSR_INITIAL
+#define PPC405_MSR_INITIAL MSR_ME
+#endif
+
+/// This is the initial value of Cache Control Register 0 (CCR0). This
+/// definition can be overridden by the application.
+///
+/// The default sets the CCR0 to give priority to DCU and ICU operations. The
+/// user should consider setting other options in this register that affect
+/// performance, e.g., ICU prefetching. Other options can be set at run time
+/// with the API \c ppc405_ccr0_modify().
+
+#ifndef PPC405_CCR0_INITIAL
+#define PPC405_CCR0_INITIAL (CCR0_DPP1 | CCR0_IPP0 | CCR0_IPP1)
+#endif
+
+/// The \a argc argument passed to \c main(). This definition can be overriden
+/// by the application.
+
+#ifndef PPC405_ARGC_INITIAL
+#define PPC405_ARGC_INITIAL 0
+#endif
+
+/// The \a argv argument passed to \c main(). This definition can be overriden
+/// by the application.
+
+#ifndef PPC405_ARGV_INITIAL
+#define PPC405_ARGV_INITIAL 0
+#endif
+
+/// Optionally trap the reset for the debugger, which means that the PPC405
+/// 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 PPC405_RESET_TRAP
+#define PPC405_RESET_TRAP 0
+#endif
+
+#ifndef __ASSEMBLER__
+
+/// The PPC405 SSX machine context is simply the MSR, a 32-bit integer.
+
+typedef uint32_t SsxMachineContext;
+
+/// Disable interrupts at the given priority level, and return the current
+/// context.
+///
+/// \param priority The interrupt priority level to disable, either \c
+/// SSX_NONCRITICAL, \c SSX_CRITICAL or \c SSX_SUPERCRITICAL. For best
+/// efficiency, the \a priority parameter should be a manifest constant.
+///
+/// \param context A pointer to an SsxMachineContext, this is the context that
+/// existed before interrupts were disabled. Typically this
+/// context is restored at the end of a critical section.
+///
+/// The PPC405 supports a 'super-critical' context in which every possible
+/// maskable exception is disabled.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_INTERRUPT An illegal priority was specified.
+
+UNLESS__PPC405_CORE_C__(extern)
+inline int
+ssx_interrupt_disable(int priority, SsxMachineContext *context)
+{
+ *context = mfmsr();
+
+ if (priority == SSX_NONCRITICAL) {
+
+ wrteei(0);
+
+ } else if (priority == SSX_CRITICAL) {
+
+ mtmsr(*context & ~(MSR_EE | MSR_CE));
+
+ } else if (priority == SSX_SUPERCRITICAL) {
+
+ mtmsr(*context & ~(MSR_APE | MSR_WE | MSR_CE | MSR_EE | MSR_ME |
+ MSR_DWE | MSR_DE));
+
+ } else if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR(SSX_INVALID_ARGUMENT_INTERRUPT);
+ }
+
+ return SSX_OK;
+}
+
+
+/// Set the machine context.
+///
+/// \param context A pointer to an SsxMachineContext
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_CONTEXT_SET A null pointer was provided as
+/// the \a context argument or an illegal machine context was specified.
+
+UNLESS__PPC405_CORE_C__(extern)
+inline int
+ssx_machine_context_set(SsxMachineContext *context)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(context == 0, SSX_INVALID_ARGUMENT_CONTEXT_SET);
+ }
+
+ mtmsr(*context);
+
+ return SSX_OK;
+}
+
+
+/// Get the machine context.
+///
+/// \param context A pointer to an SsxMachineContext.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_CONTEXT_GET A null pointer was provided as
+/// the \a context argument.
+
+UNLESS__PPC405_CORE_C__(extern)
+inline int
+ssx_machine_context_get(SsxMachineContext *context)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(context == 0, SSX_INVALID_ARGUMENT_CONTEXT_GET);
+ }
+
+ *context = mfmsr();
+
+ return SSX_OK;
+}
+
+
+/// The SSX kernel thread context switch - PPC405 uses the system call
+/// exception.
+
+#define __ssx_switch() asm volatile ("sc")
+
+
+/// 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
+__ssx_stack_create_initial_frame(SsxAddress *stack, size_t *size) \
+{
+ *stack -= 8;
+ *size -= 8;
+ *((SSX_STACK_TYPE *)(*stack)) = 0;
+}
+
+
+/// The SSX Kernel Context for PPC405
+///
+/// The SSX portable kernel does not define how the kernel keeps track of
+/// whether SSX is running, interrupt levels, and other debug
+/// information. Instead it defines an API that the port must provide to the
+/// portable kernel.
+///
+/// In the PPC405 port, the kernel context is maintained in USPRG0. This
+/// 32-bit value is treated as 5 distinct fields as indicated in the structure
+/// definition. For certain tests it's also helpful to look at the two
+/// interrupt counters as a single 0/non-0 field.
+
+typedef union {
+
+ uint32_t value;
+
+ struct {
+
+ /// The critical interrupt nesting level. If this field is non-zero,
+ /// then interrupt priority and preemption rules guarantee that a
+ /// critical interrupt handler is running, and the \c irq field will
+ /// contain the SsxIrqId of the currently active critical interrupt.
+ unsigned critical_interrupts : 8;
+
+ /// The non-critical interrupt nesting level. If this field is
+ /// non-zero and the \c critical_interrupts field is 0, then interrupt
+ /// priority and preemption rules guarantee that a noncritical
+ /// interrupt handler is running, and the \c irq field will contain
+ /// the SsxIrqId of the currently active noncritical interrupt.
+ unsigned noncritical_interrupts : 8;
+
+ /// The SsxIrqId of the currently running (or last run) handler. If
+ /// either of the interrupt nesting levels are non-0, then this is the
+ /// SsxIrqId of the IRQ that is currently executing.
+ unsigned irq : 8;
+
+ /// A flag indicating that SSX is in thread mode after a call of
+ /// ssx_start_threads().
+ unsigned thread_mode : 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 : 7;
+
+ } fields;
+
+ struct {
+
+ /// Used as a 0/non-0 flag for interrupt context.
+ unsigned interrupt_context : 16;
+
+ /// Ignore
+ unsigned ignore : 16;
+
+ } merged_fields;
+
+} __SsxKernelContext;
+
+
+// These APIs are provided to the SSX portable kernel by the port.
+
+/// SSX threads have been started by a call of ssx_start_threads().
+
+#define __ssx_kernel_mode_thread() \
+ ({ \
+ __SsxKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_USPRG0); \
+ __ctx.fields.thread_mode;})
+
+
+/// SSX is executing in a thread context (not an interrupt handler).
+
+#define __ssx_kernel_context_thread() \
+ ({ \
+ __SsxKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_USPRG0); \
+ __ctx.fields.thread_mode && !__ctx.merged_fields.interrupt_context;})
+
+
+/// SSX is executing an interrupt handler of any priority.
+
+#define __ssx_kernel_context_any_interrupt() \
+ ({ \
+ __SsxKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_USPRG0); \
+ __ctx.merged_fields.interrupt_context;})
+
+
+/// SSX is executing a critical interrupt handler.
+
+#define __ssx_kernel_context_critical_interrupt() \
+ ({ \
+ __SsxKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_USPRG0); \
+ __ctx.fields.critical_interrupts;})
+
+
+/// SSX is executing a non-critical interrupt handler.
+
+#define __ssx_kernel_context_noncritical_interrupt() \
+ ({ \
+ __SsxKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_USPRG0); \
+ __ctx.fields.noncritical_interrupts && \
+ !__ctx.fields.critical_interrupts;})
+
+
+/// Return the noncritical interrupt nesting level
+
+#define __ssx_noncritical_level() \
+ ({ \
+ __SsxKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_USPRG0); \
+ __ctx.fields.noncritical_interrupts; })
+
+
+/// Return the critical interrupt nesting level
+
+#define __ssx_critical_level() \
+ ({ \
+ __SsxKernelContext __ctx; \
+ __ctx.value = mfspr(SPRN_USPRG0); \
+ __ctx.fields.critical_interrupts; })
+
+
+// SSX requires the port to define the type SsxThreadQueue, which is a
+// priority queue (where 0 is the highest priority). This queue must be able
+// to handle SSX_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 SSX_THREADS if
+// the queue is empty (or a queue could be initialized with that entry always
+// present - SSX 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 PPC405 with 32 threads (implied), this is a job for a uint32_t and
+// cntlzw().
+
+static inline void
+__ssx_thread_queue_clear(volatile SsxThreadQueue *queue)
+{
+ *queue = 0;
+}
+
+static inline void
+__ssx_thread_queue_insert(volatile SsxThreadQueue *queue, SsxThreadPriority priority)
+{
+ *queue |= (0x80000000u >> priority);
+}
+
+static inline void
+__ssx_thread_queue_delete(volatile SsxThreadQueue *queue, SsxThreadPriority priority)
+{
+ *queue &= ~(0x80000000u >> priority);
+}
+
+static inline SsxThreadPriority
+__ssx_thread_queue_min(volatile SsxThreadQueue *queue)
+{
+ return cntlzw(*queue);
+}
+
+static inline int
+__ssx_thread_queue_member(volatile SsxThreadQueue *queue, SsxThreadPriority priority)
+{
+ return ((*queue >> (31 - priority)) & 1);
+}
+
+static inline void
+__ssx_thread_queue_union(volatile SsxThreadQueue *queue0,
+ volatile SsxThreadQueue *queue1)
+{
+ *queue0 |= *queue1;
+}
+
+static inline int
+__ssx_thread_queue_count(volatile SsxThreadQueue* queue)
+{
+ return __builtin_popcount(*queue);
+}
+
+
+/// This macro is used to call __ssx_start_threads() using the kernel stack,
+/// in a SSX_NONCRITICAL critical section.
+
+#define __ssx_call_ssx_start_threads() \
+ do { \
+ SsxMachineContext ctx; \
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx); \
+ asm volatile ("mr 1, %0; mtlr %1; blrl" : : \
+ "r" (__ssx_noncritical_stack), \
+ "r" (__ssx_start_threads)); \
+ SSX_PANIC(SSX_START_THREADS_RETURNED); \
+ } while (0)
+
+
+#endif /* __ASSEMBLER__ */
+
+/// The __SsxKernelContext 'thread_mode' bit as a flag
+
+#define PPC405_THREAD_MODE 0x80
+
+
+#ifndef __ASSEMBLER__
+
+/// Code breakpoints for PPC405
+///
+/// This macro inserts a special PPC405-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 SSX_CRITICAL 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 PPC405 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) { \
+ SsxMachineContext __ctx; \
+ ssx_critical_section_enter(SSX_CRITICAL, &__ctx); \
+ _code_breakpoint_prologue(); \
+ _code_breakpoint_epilogue(); \
+ ssx_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 /* __PPC405_H__ */
diff --git a/src/ssx/ppc405/ppc405_boot.S b/src/ssx/ppc405/ppc405_boot.S
new file mode 100755
index 0000000..1f4a4f9
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_boot.S
@@ -0,0 +1,242 @@
+// $Id: ppc405_boot.S,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_boot.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_boot.S
+/// \brief SSX bootloader for PPC405
+
+ .nolist
+#include "ssx.h"
+ .list
+
+### SSX Bootloader for PPC405
+###
+### 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 SSX 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
+### DCCR - Data cache disabled
+### DCWR - Data cache write-through disabled
+### ESR - No exception syndromes
+### ICCR - Instruction cache disabled
+### MSR - No exceptions/interrupts are allowed
+### SLER - Storage is big-endian
+### SU0R - Storage is uncompressed
+###
+### 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 __ssx_boot
+ .global __reset_trap
+
+__ssx_boot:
+
+ ## Trap the reset for the debugger. Set R0 to a non-zero value in the
+ ## debugger to continue.
+
+ .if PPC405_RESET_TRAP
+ li %r0, 0
+__reset_trap:
+ cmpwi %r0, 0
+ beq __reset_trap
+ .endif
+
+ ## First the real-mode memory parameters are set up as configured
+ ## for the system and/or application. There are no defaults for these 6
+ ## configuration options - they must always be supplied.
+
+ _liwa %r3, PPC405_ICCR_INITIAL
+ mticcr %r3
+ _liwa %r3, PPC405_DCCR_INITIAL
+ mtdccr %r3
+ _liwa %r3, PPC405_DCWR_INITIAL
+ mtdcwr %r3
+ _liwa %r3, PPC405_SGR_INITIAL
+ mtsgr %r3
+ _liwa %r3, PPC405_SU0R_INITIAL
+ mtsu0r %r3
+ _liwa %r3, PPC405_SLER_INITIAL
+ mtsler %r3
+
+ ## Next the I and D caches are invalidated.
+ ## NB: The only reason we can do a BL at this point is because we
+ ## know that these routines do not try to save the LR on the stack.
+
+ bl icache_invalidate_all
+ bl dcache_invalidate_all
+
+ ## Set up PowerPC EABI constant registers. These registers are never
+ ## again touched by the SSX 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.
+
+ mttcr %r3
+
+ ## Several options are available for dynamic memory ...
+ ## If none of these options are defined, then it is assumed that
+ ## the memory area is already set up.
+
+#if defined(SSX_RUN_FROM_DCACHE)
+
+ ## SSX can run from the DCACHE. In order for this to work, the
+ ## the linker script must set the symbol __ssx_ram_vma to the
+ ## beginning of a 128MB memory region marked as cacheable in the
+ ## application-defined PPC405_DCCR_INITIAL.
+ ##
+ ## Note that there is typically no backing store for this data. Before
+ ## going further, all data cache blocks must be allocated with 'dcbz'.
+ ## Should a subsequent programming error cause the eviction of
+ ## a dirty line, a machine check exception will result.
+
+ _liw %r3, __ssx_ram_vma
+ _liwa %r4, DCACHE_LINES
+ mtctr %r4
+
+dcbz_loop:
+ dcbz %r0, %r3
+ addi %r3, %r3, CACHE_LINE_SIZE
+ bdnz dcbz_loop
+
+#elif defined(SSX_RUN_FROM_MEMORY)
+
+ ## Nothing to do here...
+
+#else
+
+#error "One of SSX_RUN_FROM_DCACHE or SSX_RUN_FROM_MEMORY must be defined"
+
+#endif /* SSX_RUN_FROM_xxx */
+
+ ## 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, _SSX_INITIAL_STACK
+ _clrfield %r1, %r1, 3, 29 # 8-byte align
+ li %r3, 0
+ stwu %r3, -8(%r1)
+
+ ## USPRG0 (__SsxKernelContext) is initialized to 0
+ ## indicating that the SSX kernel is not in thread mode, and no
+ ## interrupts are active.
+
+ li %r3, 0
+ mtusprg0 %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 405.
+
+#ifndef NO_INIT_DBCR0
+ _liwa %r3, PPC405_DBCR0_INITIAL
+ mtdbcr0 %r3
+#endif
+
+ ## The exception vector prefix is set - it must be 64KB aligned.
+
+ _liw %r3, __vectors
+ andi. %r4, %r3, 0xffff
+ beq 1f
+ _ssx_panic PPC405_BOOT_VECTORS_NOT_ALIGNED
+1:
+ mtevpr %r3
+ isync
+
+ ## The MSR to be used during the rest of intialization is
+ ## established. This MSR should NOT enable critical or non-critical
+ ## interrupts, but could enable machine check exceptions.
+
+ _liwa %r3, PPC405_MSR_INITIAL
+ mtmsr %r3
+ isync
+
+ ## Initialize the CCR0. If it returns non-zero, panic.
+
+ _liwa %r4, PPC405_CCR0_INITIAL # bits_to_set
+ not %r3, %r4 # bits_to_clear
+ bl ppc405_ccr0_modify
+ cmpwi %r3, 0
+ beq 1f
+ _ssx_panic PPC405_BOOT_CCR0_MODIFY_FAILED
+1:
+
+#ifdef SSX_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 SSX
+ ## 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, __ssx_ram_lma - 4 # src
+ liw %r4, __ssx_ram_vma - 4 # dest
+ liw %r5, __ssx_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 /* SSX_BOOT_FROM_ROM */
+
+
+ ## Call the system setup code.
+
+ bl __ppc405_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, PPC405_ARGC_INITIAL
+ _liw %r4, PPC405_ARGV_INITIAL
+ bl __ssx_main
+
+ b __ssx_idle_thread_from_bootloader
+
+ .epilogue __ssx_boot
+
diff --git a/src/ssx/ppc405/ppc405_breakpoint.S b/src/ssx/ppc405/ppc405_breakpoint.S
new file mode 100644
index 0000000..3adbd13
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_breakpoint.S
@@ -0,0 +1,103 @@
+// $Id: ppc405_breakpoint.S,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_breakpoint.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file breakpoint.S
+/// \brief Implementation of code breakpoints for VBU/VPO
+///
+/// The operation of these short assembler routines is introduced as part of
+/// the documentation for the CODE_BREAKPOINT macro.
+
+ .nolist
+#include "ssx.h"
+ .list
+
+#ifdef DOXYGEN_ONLY
+void _code_breakpoint_prologue(void);
+#endif
+
+/// \cond
+
+ _sprinstrs iac4, SPRN_IAC4
+
+ .global_function _code_breakpoint_prologue
+_code_breakpoint_prologue:
+
+ // Save the DBCR0/1 and IAC4
+
+ mfdbcr0 %r3
+ mfdbcr1 %r4
+ mfiac4 %r5
+ _stwsd %r3, _saved_dbcr0
+ _stwsd %r4, _saved_dbcr1
+ _stwsd %r5, _saved_iac4
+
+ // Set IAC4 to the contents of LR, which will cause a break in the
+ // caller's context.
+
+ mflr %r3
+ mtiac4 %r3
+
+ // Reprogram to external debug mode, trigger on IAC4 compare, freeze
+ // timers. Clear data compare setup for good measure.
+
+ _liwa %r3, DBCR0_EDM | DBCR0_IA4 | DBCR0_FT
+ mtdbcr0 %r3
+ _liwa %r3, 0
+ mtdbcr1 %r3
+
+ isync
+ blr
+
+ .epilogue _code_breakpoint_prologue
+
+ .section .sdata
+ .balign 4
+
+ .global _code_breakpoint_enable
+_code_breakpoint_enable:
+ .long 1
+
+_saved_dbcr0:
+ .long 0
+_saved_dbcr1:
+ .long 0
+_saved_iac4:
+ .long 0
+
+/// \endcond
+
+
+#ifdef DOXYGEN_ONLY
+void _code_breakpoint_epilogue(void);
+#endif
+
+/// \cond
+
+ .global_function _code_breakpoint_epilogue
+_code_breakpoint_epilogue:
+
+ // Restore the DBCR0/1 and IAC4
+
+ _lwzsd %r3, _saved_dbcr0
+ _lwzsd %r4, _saved_dbcr1
+ _lwzsd %r5, _saved_iac4
+ mtdbcr0 %r3
+ mtdbcr1 %r4
+ mtiac4 %r5
+
+ // Clear IA4 status
+
+ _liwa %r3, DBSR_IA4
+ mtdbsr %r3
+
+ isync
+ blr
+
+ .epilogue _code_breakpoint_epilogue
+
+/// \endcond
diff --git a/src/ssx/ppc405/ppc405_cache.h b/src/ssx/ppc405/ppc405_cache.h
new file mode 100755
index 0000000..02bd4f5
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_cache.h
@@ -0,0 +1,113 @@
+#ifndef __PPC405_CACHE_H__
+#define __PPC405_CACHE_H__
+
+// $Id: ppc405_cache.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_cache.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_cache.h
+/// \brief PowerPC 405 cache management header for SSX
+///
+/// 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")
+
+/// Instruction Cache Block Invalidate
+#define icbi(p) asm volatile ("icbi 0, %0" : : "r" (p) : "memory")
+
+/// Instruction Cache Block Touch
+#define icbt(p) asm volatile ("icbt 0, %0" : : "r" (p) : "memory")
+
+void
+icache_invalidate_all(void);
+
+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 /* __PPC405_CAHE_H__ */
diff --git a/src/ssx/ppc405/ppc405_cache_core.c b/src/ssx/ppc405/ppc405_cache_core.c
new file mode 100755
index 0000000..a03f5e2
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_cache_core.c
@@ -0,0 +1,115 @@
+// $Id: ppc405_cache_core.c,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_cache_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_cache_core.c
+/// \brief Core cache management routines required of any PPC405 configuration
+/// of SSX that interacts with DMA devices using cacheable memory.
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present at runtime in any SSX application.
+///
+/// \todo The compiler generates wierd assembly language for these cache
+/// management APIs - probably due to the "volatile" asm - it may be best to
+/// recode them directly in assembler.
+
+#include "ssx.h"
+
+/// Invalidate a range of addresses from the D-cache
+///
+/// \param p A pointer to the memory area to be invalidated.
+///
+/// \param bytes The size (in bytes) of the area to invalidate.
+///
+/// The dcache_invalidate() API is used to invalidate an arbitrary range of
+/// memory in the cache. Note that invalidation is a destructive operation
+/// that may cause the loss of information. This API will invalidate all
+/// cache lines from the line containing the address \a p, to the line
+/// containing the address \a p + \a size - 1. (If \a size == 0 this call is
+/// a NOP.) 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, even in the event
+/// of \a size == 0.
+///
+/// \note For invalidating small blocks of data where some alignmment
+/// constraints are known it may be more efficient to use
+/// dcache_invalidate_line() rather than this API.
+
+void
+dcache_invalidate(void *p, size_t bytes)
+{
+ size_t lines;
+
+ if (bytes != 0) {
+ lines = 1;
+ bytes -=
+ MIN((CACHE_LINE_SIZE - ((unsigned long)p % CACHE_LINE_SIZE)),
+ bytes);
+ lines += bytes / CACHE_LINE_SIZE;
+ if (!cache_aligned(bytes)) {
+ lines++;
+ }
+ while (lines--) {
+ dcbi(p);
+ p += CACHE_LINE_SIZE;
+ }
+ }
+ sync();
+}
+
+
+/// Flush and invalidate a range of addresses from the D-cache
+///
+/// \param p A pointer to a memory area to be invalidated.
+///
+/// \param bytes The size (in bytes) of the area to invalidate.
+///
+/// The dcache_flush() API is used to flush and invalidate an arbitrary range
+/// of memory from the D-cache. Note that flushing is not a destructive
+/// operation in the sense that no information is lost. This API will flush
+/// and invalidate all cache lines from the line containing the address \a p,
+/// to the line containing the address \a p + \a size - 1. (If \a size == 0
+/// this call is a NOP.) 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, even in the event of \a
+/// size == 0.
+///
+/// \note For flushing small blocks of data where some alignmment constraints
+/// are known it may be more efficient to use dcache_flush_line() rather than
+/// this API.
+
+
+void
+dcache_flush(void *p, size_t bytes)
+{
+ size_t lines;
+
+ if (bytes != 0) {
+ lines = 1;
+ bytes -=
+ MIN((CACHE_LINE_SIZE - ((unsigned long)p % CACHE_LINE_SIZE)),
+ bytes);
+ lines += bytes / CACHE_LINE_SIZE;
+ if (!cache_aligned(bytes)) {
+ lines++;
+ }
+ while (lines--) {
+ dcbf(p);
+ p += CACHE_LINE_SIZE;
+ }
+ }
+ sync();
+}
+
+
+
+
+
+
diff --git a/src/ssx/ppc405/ppc405_cache_init.S b/src/ssx/ppc405/ppc405_cache_init.S
new file mode 100755
index 0000000..c4bed0e
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_cache_init.S
@@ -0,0 +1,314 @@
+// $Id: ppc405_cache_init.S,v 1.3 2014/06/26 12:59:35 cmolsen Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_cache_init.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_cache_init.S
+/// \brief PPC405-specific procedures required for cache initialization
+///
+/// The routines in this file are not part of SSX per se, but are included
+/// with SSX because they are used during initialialization and boot.
+///
+/// These are 'initialization' routines used by the SSX bootloader and other
+/// application initialization code and may not be needed after
+/// boot/initialization of the SSX application.
+///
+/// See the documents './doc/PowerPC 405-S Core Errata' and './doc/PowerPC
+/// 405-S Core Errata Impact on PGP OCC Firmware' for information on the
+/// CPU_xxx errata.
+
+ .nolist
+#include "ssx.h"
+#include "ppc405_context.h"
+ .list
+
+/// \fn void icache_invalidate_all()
+/// \brief Invalidate the entire I-Cache
+///
+/// In the PPC405 a single instruction invalidates the entire I-Cache,
+/// therefore this routine need not be executed from a critical section.
+///
+///
+/// This API always issues an isync() after the invalidation.
+#ifdef DOXYGEN_ONLY
+void icache_invalidate_all();
+#endif
+/// \cond
+
+ .global_function icache_invalidate_all
+
+icache_invalidate_all:
+
+ _ssx_critical_section_enter SSX_SUPERCRITICAL, %r5, %r6
+
+ # Workaround for CPU_121: The iccci instruction may errantly
+ # cause a Data TLB exception. Workaround avoids this erratum by
+ # temporarily disabling data address translation.
+
+ mfmsr %r3
+ andi. %r4, %r3, 0xffef
+ mtmsr %r4
+ isync
+
+ ## On the 405, iccci invalidates the entire I-Cache.
+
+ iccci %r0,%r0
+
+ # Restore MSR/DR bit
+ mtmsr %r3
+ isync
+
+ _ssx_critical_section_exit %r5
+
+ blr
+
+ .epilogue icache_invalidate_all
+
+/// \endcond
+
+
+/// \fn void dcache_invalidate_all()
+/// \brief Invalidate the entire D-Cache
+///
+/// This API operates in an SSX_SUPERCRITICAL critical section. This API always
+/// issues a sync() after the invalidation.
+#ifdef DOXYGEN_ONLY
+void dcache_invalidate_all();
+#endif
+/// \cond
+
+ .global_function dcache_invalidate_all
+
+dcache_invalidate_all:
+
+ _ssx_critical_section_enter SSX_SUPERCRITICAL, %r5, %r6
+
+ ## We loop through addresses 0 ... (DCACHE_SIZE / DCACHE_WAYS) - 1
+ ## invalidating the D-Cache. The dccci instruction on the 405
+ ## invalidates both ways.
+
+ li %r3, 0
+ _liwa %r4, (DCACHE_LINES / DCACHE_WAYS)
+ mtctr %r4
+
+1:
+ dccci %r0, %r3
+ addi %r3, %r3, CACHE_LINE_SIZE
+ bdnz 1b
+
+ sync
+
+ _ssx_critical_section_exit %r5
+
+ blr
+
+ .epilogue dcache_invalidate_all
+
+/// \endcond
+
+
+#ifndef USE_GENERIC_DCACHE_FLUSH_ALL
+#define USE_GENERIC_DCACHE_FLUSH_ALL 1
+#endif
+
+/// \fn void dcache_flush_all()
+/// \brief Flush the entire D-Cache (Generic)
+///
+/// This API is necessary whenever it is required to change data cacheability
+/// after boot. The D-cache is scanned, and any lines present in the cache are
+/// flushed. This API operates in an SSX_SUPERCRITICAL critical section. This
+/// API always issues a sync() after the flush.
+///
+/// This is a generic implementation that should work on all PPC405
+/// systems. If something is known about the memory configuration then SSX
+/// ports can implement better/more efficient flush-all algorithms.
+///
+/// This API runs with data translation disabled. This is necessary for
+/// correctness, and also obviates the need to check whether a cache entry is
+/// valid before flushing the entry.
+///
+/// This API is currently a NOP in Simics simulations which complain that the
+/// dcread instruction is implemented as a NOP.
+#ifdef DOXYGEN_ONLY
+void dcache_flush_all();
+#endif
+/// \cond
+
+#if USE_GENERIC_DCACHE_FLUSH_ALL
+
+ .global_function dcache_flush_all
+dcache_flush_all:
+
+#if !SIMICS_ENVIRONMENT
+
+ ## %r3 used as temp throughout
+ ## %r4 holds the original MSR throughout
+ ## %r8 used as a temp throughout
+ ## %r9 used as a temp throughout
+
+ _ssx_critical_section_enter SSX_SUPERCRITICAL, %r4, %r3
+
+ mfmsr %r3
+ _clrbit %r3, %r3, MSR_DR_BIT
+ mtmsr %r3
+ isync
+
+ ## %r5 counts the congruence class address
+ ## CTR counts the number of congruence classes
+
+ li %r5, 0
+ _liwa %r9, (DCACHE_LINES / DCACHE_WAYS)
+ mtctr %r9
+
+ ## %r6 has the CCR0 value for reading DCACHE tag on way A
+ ## %r7 has the CCR0 value for reading DCACHE tag on way B
+ ## %r8 has the cache tag mask
+
+ mfccr0 %r6
+ _liwa %r9, 0x00000011
+ andc %r6, %r6, %r9 # Clear DCREAD control bits
+ ori %r6, %r6, 0x0010
+ ori %r7, %r6, 0x0001
+ _liwa %r8, DCACHE_TAG_MASK # Cache tag mask
+
+dflush_loop:
+
+ ## Way A
+
+ mtccr0 %r6 # Set CCR0 for DCREAD
+ dcread %r9, %r0, %r5
+ and %r9, %r9, %r8 # Mask out cache tag
+ or %r9, %r9, %r5 # OR in the congruence class address
+ dcbf %r0, %r9 # Flush the line
+
+ ## Way B
+
+ mtccr0 %r7 # Set CCR0 for DCREAD
+ dcread %r9, %r0, %r5
+ and %r9, %r9, %r8 # Mask out cache tag
+ or %r9, %r9, %r5 # OR in the congruence class address
+ dcbf %r0, %r9 # Flush the line
+
+ addi %r5, %r5, CACHE_LINE_SIZE
+ bdnz dflush_loop
+
+ ## Restore the MSR and return
+
+ _ssx_critical_section_exit %r4
+
+#endif // SIMICS_ENVIRONMENT
+
+ blr
+
+ .epilogue dcache_flush_all
+
+#endif // USE_GENERIC_DCACHE_FLUSH_ALL
+
+/// \endcond
+
+/// \fn int ppc405_ccr0_modify(uint32_t bits_to_clear, uint32_t bits_to_set)
+/// \brief A special code sequence to modify the Cache Control Register 0 (CCR0)
+///
+/// \param bits_to_clear A positive mask of bits in CCR0 that will be cleared
+/// by this call.
+///
+/// \param bits_to_set A positive mask of bits in CCR0 that will be set by
+/// this call.
+///
+/// The code that implements this procedure \e must be in I-cacheable memory.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_PPC405_CACHE The code implementing the API
+/// is not cacheable.
+///
+#ifdef DOXYGEN_ONLY
+int ppc405_ccr0_modify(uint32_t bits_to_clear, uint32_t bits_to_set);
+#endif
+/// \cond
+
+ ## The implementation is based on an example from the 405GP manual.
+
+ .global_function ppc405_ccr0_modify
+
+ppc405_ccr0_modify:
+
+ ## %r3 is parameter bits_to_clear
+ ## %r4 is parameter bits_to_set
+ ## %r5 will hold the original MSR
+ ## %r6 will hold the address of the update code.
+ ## %r7, %r8, %r9 are used for computation.
+
+ ## Disable external and critical interrupts
+
+ mfmsr %r5
+ _liwa %r6, (MSR_CE | MSR_EE)
+ andc %r6, %r5, %r6
+ mtmsr %r6 # Interrupts disabled
+ sync
+
+ .if SSX_ERROR_CHECK_API
+
+ ## Check for cacheability of the code sequence
+
+ _liw %r6, ccr0_modify_doit
+ extrwi %r7, %r6, 5, 0 # Upper 5 bits are address range
+ mficcr %r8
+ _liwa %r9, 0x80000000
+ srw %r9, %r9, %r7 # %r9 holds bit to check in %r8
+ and. %r9, %r9, %r8
+ bne ccr0_modify_continue
+
+ ## Whoops! Code not cacheable; restore MSR and return error code.
+
+ .if SSX_ERROR_PANIC
+
+ _ssx_panic SSX_ILLEGAL_CONTEXT_PPC405_CACHE
+
+ .else
+
+ _liwa %r3, -SSX_ILLEGAL_CONTEXT_PPC405_CACHE
+ mtmsr %r5
+ isync
+
+ .endif
+
+ blr
+
+ .endif
+
+ ## Touch the code sequence into the I-Cache and do it.
+
+ccr0_modify_continue:
+ icbt %r0, %r6
+ isync # Erratum CPU_208
+ b ccr0_modify_doit
+
+ ## The ICBT is repeated to insure that the code is really in
+ ## the cache. The bits are cleared, set, updated and we exit.
+
+ .cache_align # Must be cache-line aligned
+ccr0_modify_doit:
+ icbt %r0, %r6
+ isync
+ mfccr0 %r7
+ andc %r7, %r7, %r3 # Clear some bits
+ or %r7, %r7, %r4 # Set some bits
+ mtccr0 %r7
+ isync
+
+ ## Restore MSR and return 0.
+
+ li %r3, 0
+ mtmsr %r5
+ isync
+ blr
+
+ .epilogue ppc405_ccr0_modify
+
+/// \endcond
diff --git a/src/ssx/ppc405/ppc405_context.h b/src/ssx/ppc405/ppc405_context.h
new file mode 100755
index 0000000..3019358
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_context.h
@@ -0,0 +1,594 @@
+#ifndef __PPC405_CONTEXT_H__
+#define __PPC405_CONTEXT_H__
+
+// $Id: ppc405_context.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_context.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_context.h
+/// \brief PPC405 Machine and Thread context for SSX
+
+/// \page ppc405_machine_context PPC405 Assembler Macros for SSX Machine
+/// Context (Critical Sections)
+///
+/// \section _ssx_enter_critical \b _ssx_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 priority Either \c SSX_CRITICAL, \c SSX_NON_CRITICAL or
+/// SSX_SUPERCRITICAL (for \c ssx_critical_section_enter).
+///
+/// \arg \c ctxreg A register that will hold (holds) the machine context (MSR)
+/// prior to entering the critical section (to be restored) for \c
+/// _ssx_critical_section_enter (\c _ssx_critical_section_exit).
+///
+/// \arg \c scrreg A scratch register required for the computation of
+/// \c _ssx_critical_section_enter.
+///
+/// Forms:
+///
+/// \b _ssx_critical_section_enter \a priority, \a ctxreg, \a scrreg - Enter a
+/// critical section \n
+/// \b _ssx_critical_section_exit \a ctxreg - Exit a critical section
+
+#ifdef __ASSEMBLER__
+
+ .set _msr_ee_bit, MSR_EE_BIT
+ .set _msr_ce_bit, MSR_CE_BIT
+
+ .macro _ssx_critical_section_enter priority, ctxreg, scrreg
+ mfmsr \ctxreg
+ .if ((\priority) == SSX_CRITICAL)
+ _clrbit \scrreg, \ctxreg, _msr_ee_bit
+ _clrbit \scrreg, \scrreg, _msr_ce_bit
+ mtmsr \scrreg
+ .elseif ((\priority) == SSX_SUPERCRITICAL)
+ _liwa \scrreg, (MSR_APE | MSR_WE | MSR_CE | MSR_EE | MSR_ME | MSR_DWE | MSR_DE)
+ andc \scrreg, \ctxreg, \scrreg
+ mtmsr \scrreg
+ .elseif ((\priority) == SSX_NONCRITICAL)
+ wrteei 0
+ .else
+ .error "'priority' was not one of SSX_CRITICAL, SSX_NONCRITICAL or SSX_SUPERCRITICAL"
+ .endif
+ isync
+ .endm
+
+ .macro _ssx_critical_section_exit ctxreg
+ mtmsr \ctxreg
+ isync
+ .endm
+
+// ****************************************************************************
+// SSX context save/restore macros for 32-bit Embedded PowerPC
+// ****************************************************************************
+
+// All stack frames are 8-byte aligned in conformance with the EABI. SSX
+// 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.
+
+// A fair amount of complexity is involved in handling the non-critical and
+// critical interrupt levels, and the emphasis on performance of fast-mode
+// interrupt handlers. Several different approaches and philosophies could
+// have been implemented - this is only one. In this implementation
+// critical/non-critical interrupt levels are treated more or less the same,
+// and the interrupt priority is just that - a kind of preemption priority.
+// Critical interrupt handling does have a little less overhead because it
+// does not have a thread scheduling step at the end.
+
+// A full context save takes place in 3 or 4 steps. Thread switches always do
+// steps 1, 2 and 3.
+// 1. The fast context that is always saved in response to every interrupt;
+// 1a. The optional save/update of the kernel context for interrupts.
+// 2. The (volatile - fast) context that is saved if an interrupt handler
+// switches from fast-mode to full-mode.
+// 3. The non-volatile context that is saved when a thread is switched out.
+
+// USPRG0 holds the __SsxKernelContext structure (defined in ppc405.h) that
+// represents the current kernel context. The layout is as follows:
+//
+// Bits Meaning
+// ==============
+// 0:7 The critical interrupt count
+// 8:15 The non-critical interrupt count
+// 16:23 The IRQ currently being processed
+// 24 The 'thread_mode' flag
+// 25:31 The thread priority of the running thread
+//
+// When SSX is initialized USPRG0 is initialized to 0. When thread-mode is
+// entered (by ssx_start_threads()) bit 24 is set to 1. In order to support
+// PgP/OCC firmware, once initialized (with ssx_initialize()) SSX can simply
+// handle interrupts, reverting back to the non-thread-mode idle loop when
+// there's nothing to do.
+//
+// Note that it would require a serious error for the interrupt counts to ever
+// equal or exceed 2**8 as this would imply runaway reentrancy and stack
+// overflow. In fact it is most likely an error if an interrupt handler is
+// ever re-entered while active.
+
+// Registers SRR2 and SRR3 are always saved in IRQ context because
+// __ssx_irq_fast2full must save the (volatile - fast) context to provide
+// working registers before it can look at USPRG0 to determine critical
+// vs. non-critical context. However, when restoring a non-critical interrupt
+// or thread these registers need not be restored. SRR2 and SRR3 are never
+// saved or restored for thread context switches, because threads always
+// operate at noncritical level.
+
+// When MMU protection is enabled, relocation/protection is re-established
+// immediately upon entry to the interrupt handler, before any memory
+// operations (load/store) take place. This requires using SPRG0 and SPGR4
+// for temporary storage for noncritical/critical handlers respectively in
+// accordance with the SSX conventions for SPRGn usage by fast-mode
+// interrupts.
+
+ ## ------------------------------------------------------------
+ ## Unused registers for embedded PowerPC
+ ## ------------------------------------------------------------
+
+ ## 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
+
+ ## ------------------------------------------------------------
+ ## Flags for context push/pop
+ ## ------------------------------------------------------------
+
+ .set SSX_THREAD_CONTEXT, 0
+ .set SSX_IRQ_CONTEXT, 1
+
+ ## ------------------------------------------------------------
+ ## The SSX fast context layout for Embedded PowerPC
+ ## ------------------------------------------------------------
+
+ .set SSX_FAST_CTX_GPR1, 0x00 # Dedicated; Stack pointer
+ .set SSX_FAST_CTX_HANDLER_LR, 0x04 # Slot for handler to store LR
+ .set SSX_FAST_CTX_GPR3, 0x08 # Volatile; Parameter; Return Value
+ .set SSX_FAST_CTX_GPR4, 0x0c # Volatile; Parameter
+ .set SSX_FAST_CTX_GPR5, 0x10 # Volatile; Parameter
+ .set SSX_FAST_CTX_GPR6, 0x14 # Volatile; Parameter
+ .set SSX_FAST_CTX_GPR7, 0x18 # Volatile; Parameter
+ .set SSX_FAST_CTX_CR, 0x1c # Condition register
+ .set SSX_FAST_CTX_LR, 0x20 # Link register SPRN 0x008
+ .set SSX_FAST_CTX_KERNEL_CTX, 0x24 # Saved __SsxKernelContext for IRQ
+
+ .set SSX_FAST_CTX_SIZE, 0x28 # Must be 8-byte aligned
+
+ ## ------------------------------------------------------------
+ ## The SSX (volatile - fast) context layout for Embedded PowerPC
+ ## ------------------------------------------------------------
+
+ .set SSX_VOL_FAST_CTX_GPR1, 0x00 # Dedicated; Stack pointer
+ .set SSX_VOL_FAST_CTX_HANDLER_LR, 0x04 # Slot for handler to store LR
+ .set SSX_VOL_FAST_CTX_GPR0, 0x08 # Volatile; Language specific
+ .set SSX_VOL_FAST_CTX_GPR8, 0x0c # Volatile; Parameter
+ .set SSX_VOL_FAST_CTX_GPR9, 0x10 # Volatile; Parameter
+ .set SSX_VOL_FAST_CTX_GPR10, 0x14 # Volatile; Parameter
+ .set SSX_VOL_FAST_CTX_GPR11, 0x18 # Volatile
+ .set SSX_VOL_FAST_CTX_GPR12, 0x1c # Volatile
+ .set SSX_VOL_FAST_CTX_XER, 0x20 # Fixed-point exception register SPRN 0x001
+ .set SSX_VOL_FAST_CTX_CTR, 0x24 # Count register SPRN 0x009
+ .set SSX_VOL_FAST_CTX_SRR0, 0x28 # Save/restore register 0 SPRN 0x01a
+ .set SSX_VOL_FAST_CTX_SRR1, 0x2c # Save/restore register 1 SPRN 0x01b
+ .set SSX_VOL_FAST_CTX_SRR2, 0x30 # Save/restore register 2 SPRN 0x3de
+ .set SSX_VOL_FAST_CTX_SRR3, 0x34 # Save/restore register 3 SPRN 0x3df
+
+ .set SSX_VOL_FAST_CTX_SIZE, 0x38 # Must be 8-byte aligned
+
+ ## ------------------------------------------------------------
+ ## The SSX non-volatile context layout for Embedded PowerPC
+ ## ------------------------------------------------------------
+
+ ## The 'preferred form' for stmw is for the LSB of R31 to fall into the
+ ## end of a 16-byte aligned block.
+
+ .set SSX_NON_VOL_CTX_GPR1, 0x0 # Dedicated; Stack Pointer
+ .set SSX_NON_VOL_CTX_HANDLER_LR, 0x4 # Slot for handler to store LR
+ .set SSX_NON_VOL_CTX_GPR14, 0x8 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR15, 0xc # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR16, 0x10 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR17, 0x14 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR18, 0x18 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR19, 0x1c # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR20, 0x20 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR21, 0x24 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR22, 0x28 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR23, 0x2c # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR24, 0x30 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR25, 0x34 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR26, 0x38 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR27, 0x3c # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR28, 0x40 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR29, 0x44 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR30, 0x48 # Non-volatile
+ .set SSX_NON_VOL_CTX_GPR31, 0x4c # Non-volatile
+
+ .set SSX_NON_VOL_CTX_SIZE, 0x50 # Must be 8-byte aligned
+
+ ## ------------------------------------------------------------
+ ## Save/restore the fast context
+ ##
+ ## 11 Instructions, 8 Loads/Stores : If MMU is disabled
+ ## 17 Instructions, 8 Loads/Stores : If MMU is enabled
+ ## ------------------------------------------------------------
+ ##
+ ## Without MMU support, an EIEIO is always executed at the entry point
+ ## to gauarantee that all memory operations (especially MMIO
+ ## operations) have completed prior to execution of the interrupt
+ ## handler.
+ ##
+ ## If MMU support is enabled, address translation is re-established
+ ## immediately at the entry of each interrupt, prior to performing any
+ ## loads or stores. SSX currently only supports using the MMU for
+ ## protection, not for address translation. Therfore it is 'legal'
+ ## to change translation modes a with an MTMSR followed by an
+ ## ISYNC. This is much simpler then the complex instruction sequence
+ ## that would be required if we had to set up RFI/RFCI sequences to
+ ## change the execution context at this point.
+ ##
+ ## Note that since we are not really doing address translation, it
+ ## would also be in keeping with the 'fast interrupt' idea to defer
+ ## reenabling translation (protection) until the fast-to-full sequence
+ ## was executed for full-mode interrupts, and run fast-mode interrupts
+ ## unprotected. However here we chose to run all interrupts with MMU
+ ## protection.
+ ##
+ ## Unfortunately the simple MTMSR;ISYNC sequence exposes a serious bug
+ ## in the 405-S core that causes the stack-pointer store instruction
+ ## to generate a seemingly random, *real-mode* address in certain cases
+ ## when this instruction in a noncritical interrupt prologue is
+ ## interrupted by a critical interrupt. This bug is described in
+ ## HW239446. The workaround is to follow the ISYNC sith a SYNC - which
+ ## eliminates the problem for reasons still unknown. On the bright side
+ ## this SYNC might also serve the same purpose as the EIEIO in the
+ ## non-MMU case, guaranteeing that all MMIO has completed prior to the
+ ## interrupt handler. However without the initial EIEIO we still
+ ## experience failures, so this seemingly redundant instruction also
+ ## remains in place. This requirement is assumed to be related to the
+ ## HW239446 issue.
+
+ .macro _ssx_fast_ctx_push, critical
+
+ .if !PPC405_MMU_SUPPORT
+
+ eieio
+
+ .elseif \critical
+
+ eieio # HW239446?
+ mtsprg4 %r3
+ mfmsr %r3
+ ori %r3, %r3, PPC405_RELOCATION_MODE
+ mtmsr %r3
+ isync
+#ifndef ALLOW_HW239446
+ sync # HW239446!
+#endif
+ mfsprg4 %r3
+
+ .else
+
+ eieio # HW239446?
+ mtsprg0 %r3
+ mfmsr %r3
+ ori %r3, %r3, PPC405_RELOCATION_MODE
+ mtmsr %r3
+ isync
+#ifndef ALLOW_HW239446
+ sync # HW239446!
+#endif
+ mfsprg0 %r3
+
+ .endif
+
+ stwu %r1, -SSX_FAST_CTX_SIZE(%r1) # May be corrupted w/o HW239446
+
+ stw %r3, SSX_FAST_CTX_GPR3(%r1)
+ stw %r4, SSX_FAST_CTX_GPR4(%r1)
+ stw %r5, SSX_FAST_CTX_GPR5(%r1)
+ stw %r6, SSX_FAST_CTX_GPR6(%r1)
+ stw %r7, SSX_FAST_CTX_GPR7(%r1)
+
+ mfcr %r3
+ mflr %r4
+
+ stw %r3, SSX_FAST_CTX_CR(%r1)
+ stw %r4, SSX_FAST_CTX_LR(%r1)
+
+ .endm
+
+
+ .macro _ssx_fast_ctx_pop
+
+ lwz %r3, SSX_FAST_CTX_CR(%r1)
+ lwz %r4, SSX_FAST_CTX_LR(%r1)
+
+ mtcr %r3
+ mtlr %r4
+
+ lwz %r3, SSX_FAST_CTX_GPR3(%r1)
+ lwz %r4, SSX_FAST_CTX_GPR4(%r1)
+ lwz %r5, SSX_FAST_CTX_GPR5(%r1)
+ lwz %r6, SSX_FAST_CTX_GPR6(%r1)
+ lwz %r7, SSX_FAST_CTX_GPR7(%r1)
+
+ lwz %r1, 0(%r1)
+
+ .endm
+
+ ## ------------------------------------------------------------
+ ## Save/update the kernel context in response to an interrupt. This is
+ ## not part of the fast context save because for external interupts the
+ ## IRQ is not determined until later.
+ ## ------------------------------------------------------------
+
+ ## The kernel context is saved, then updated with the currently active
+ ## IRQ in bits 16:23. The correct interrupt count is incremented and
+ ## the context is returned to USPRG0.
+
+ .macro _save_update_kernel_context critical, irqreg, ctxreg
+
+ .if \critical
+ SSX_TRACE_CRITICAL_IRQ_ENTRY \irqreg, \ctxreg
+ .else
+ SSX_TRACE_NONCRITICAL_IRQ_ENTRY \irqreg, \ctxreg
+ .endif
+
+ mfusprg0 \ctxreg
+ stw \ctxreg, SSX_FAST_CTX_KERNEL_CTX(%r1)
+ rlwimi \ctxreg, \irqreg, 8, 16, 23
+ .if \critical
+ addis \ctxreg, \ctxreg, 0x0100
+ .else
+ addis \ctxreg, \ctxreg, 0x0001
+ .endif
+ mtusprg0 \ctxreg
+
+ .endm
+
+ ## ------------------------------------------------------------
+ ## Fast-mode context pop and RF(C)I. This is only used by
+ ## interrupt handlers - the thread context switch has its own
+ ## code to handle updating USPRG0 for thread mode.
+ ## ------------------------------------------------------------
+
+ .macro _ssx_fast_ctx_pop_exit critical
+
+ .if SSX_KERNEL_TRACE_ENABLE
+ .if \critical
+ bl __ssx_trace_critical_irq_exit
+ .else
+ bl __ssx_trace_noncritical_irq_exit
+ .endif
+ .endif
+
+ lwz %r3, SSX_FAST_CTX_KERNEL_CTX(%r1)
+ mtusprg0 %r3
+ _ssx_fast_ctx_pop
+ .if \critical
+ rfci
+ .else
+ rfi
+ .endif
+
+ .endm
+
+ ## ------------------------------------------------------------
+ ## Save/restore the (volatile - fast) context
+ ##
+ ## Thread - 15 Instructions, 11 Loads/Stores
+ ## IRQ - 19(15) Instructions, 13(11) Loads/Stores
+ ## ------------------------------------------------------------
+
+ .macro _ssx_vol_fast_ctx_push, irq_context, critical=1
+
+ stwu %r1, -SSX_VOL_FAST_CTX_SIZE(%r1)
+
+ stw %r0, SSX_VOL_FAST_CTX_GPR0(%r1)
+ stw %r8, SSX_VOL_FAST_CTX_GPR8(%r1)
+ stw %r9, SSX_VOL_FAST_CTX_GPR9(%r1)
+ stw %r10, SSX_VOL_FAST_CTX_GPR10(%r1)
+ stw %r11, SSX_VOL_FAST_CTX_GPR11(%r1)
+ stw %r12, SSX_VOL_FAST_CTX_GPR12(%r1)
+
+ mfxer %r8
+ mfctr %r9
+ mfsrr0 %r10
+ mfsrr1 %r11
+
+ stw %r8, SSX_VOL_FAST_CTX_XER(%r1)
+ stw %r9, SSX_VOL_FAST_CTX_CTR(%r1)
+ stw %r10, SSX_VOL_FAST_CTX_SRR0(%r1)
+ stw %r11, SSX_VOL_FAST_CTX_SRR1(%r1)
+
+ .if (\irq_context & \critical)
+ mfsrr2 %r8
+ mfsrr3 %r9
+
+ stw %r8, SSX_VOL_FAST_CTX_SRR2(%r1)
+ stw %r9, SSX_VOL_FAST_CTX_SRR3(%r1)
+ .endif
+
+ .endm
+
+
+ .macro _ssx_vol_fast_ctx_pop, irq_context, critical
+
+ .if (\irq_context & \critical)
+ lwz %r8, SSX_VOL_FAST_CTX_SRR2(%r1)
+ lwz %r9, SSX_VOL_FAST_CTX_SRR3(%r1)
+
+ mtsrr2 %r8
+ mtsrr3 %r9
+ .endif
+
+ lwz %r8, SSX_VOL_FAST_CTX_XER(%r1)
+ lwz %r9, SSX_VOL_FAST_CTX_CTR(%r1)
+ lwz %r10, SSX_VOL_FAST_CTX_SRR0(%r1)
+ lwz %r11, SSX_VOL_FAST_CTX_SRR1(%r1)
+
+ mtxer %r8
+ mtctr %r9
+ mtsrr0 %r10
+ mtsrr1 %r11
+
+ lwz %r0, SSX_VOL_FAST_CTX_GPR0(%r1)
+ lwz %r8, SSX_VOL_FAST_CTX_GPR8(%r1)
+ lwz %r9, SSX_VOL_FAST_CTX_GPR9(%r1)
+ lwz %r10, SSX_VOL_FAST_CTX_GPR10(%r1)
+ lwz %r11, SSX_VOL_FAST_CTX_GPR11(%r1)
+ lwz %r12, SSX_VOL_FAST_CTX_GPR12(%r1)
+
+ lwz %r1, 0(%r1)
+
+ .endm
+
+ ## ------------------------------------------------------------
+ ## Save/restore the non-volatile context on the stack
+ ##
+ ## 2 Instructions, 19 Loads/Stores
+ ## ------------------------------------------------------------
+
+ .macro _ssx_non_vol_ctx_push
+
+ stwu %r1, -SSX_NON_VOL_CTX_SIZE(%r1)
+ stmw %r14, SSX_NON_VOL_CTX_GPR14(%r1)
+
+ .endm
+
+
+ .macro _ssx_non_vol_ctx_pop
+
+ lmw %r14, SSX_NON_VOL_CTX_GPR14(%r1)
+ lwz %r1, 0(%r1)
+
+ .endm
+
+#else /* __ASSEMBLER__ */
+
+/// SSX 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_nv;
+ uint32_t link_nv;
+ uint32_t r14;
+ uint32_t r15;
+ uint32_t r16;
+ uint32_t r17;
+ uint32_t r18;
+ uint32_t r19;
+ uint32_t r20;
+ uint32_t r21;
+ uint32_t r22;
+ uint32_t r23;
+ uint32_t r24;
+ uint32_t r25;
+ uint32_t r26;
+ uint32_t r27;
+ uint32_t r28;
+ uint32_t r29;
+ uint32_t r30;
+ uint32_t r31;
+ uint32_t r1_vf;
+ uint32_t link_vf;
+ uint32_t r0;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t xer;
+ uint32_t ctr;
+ uint32_t srr0;
+ uint32_t srr1;
+ uint32_t srr2;
+ uint32_t srr3;
+ uint32_t r1;
+ uint32_t link_fast;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t cr;
+ uint32_t lr;
+ uint32_t usprg0;
+
+} SsxThreadContext;
+
+
+/// SSX thread context of an interrupted thread (full-mode handler)
+///
+/// When a thread is interrupted by a full-mode interrupt handler, this is the
+/// layout of the stack area pointed to by either __ssx_saved_sp_noncritical
+/// or __ssx_saved_sp_critical.
+
+typedef struct {
+
+ uint32_t r1_vf;
+ uint32_t link_vf;
+ uint32_t r0;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t xer;
+ uint32_t ctr;
+ uint32_t srr0;
+ uint32_t srr1;
+ uint32_t srr2;
+ uint32_t srr3;
+ uint32_t r1;
+ uint32_t link_fast;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t cr;
+ uint32_t lr;
+ uint32_t usprg0;
+
+} SsxThreadContextFullIrq;
+
+
+/// SSX thread context of an interrupted thread (fast-mode handler)
+///
+/// When a thread is interrupted by a fast-mode interrupt handler, this is the
+/// layout of the stack area pointed to by R1 - unless the fast-mode interrupt
+/// handler extends the stack.
+
+typedef struct {
+
+ uint32_t r1;
+ uint32_t link_fast;
+ uint32_t r3;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t cr;
+ uint32_t lr;
+ uint32_t usprg0;
+
+} SsxThreadContextFastIrq;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPC405_CONTEXT_H__ */
+
+
diff --git a/src/ssx/ppc405/ppc405_core.c b/src/ssx/ppc405/ppc405_core.c
new file mode 100755
index 0000000..5df0967
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_core.c
@@ -0,0 +1,183 @@
+// $Id: ppc405_core.c,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_core.c
+/// \brief The final bits of SSX runtime code required to complete the PPC405
+/// port.
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present during runtime in any SSX application.
+
+#define __PPC405_CORE_C__
+
+#include "ssx.h"
+
+/// Get the 64-bit timebase following the PowerPC protocol
+///
+/// Note that the only way to guarantee that the value returned is the value
+/// \e right \e now is to call this API from a critical section.
+
+SsxTimebase
+ssx_timebase_get(void)
+{
+ Uint64 tb;
+ uint32_t high;
+
+ do {
+ tb.word[0] = mftbu();
+ tb.word[1] = mftb();
+ high = mftbu();
+ } while (high != tb.word[0]);
+
+ return tb.value;
+}
+
+
+/// Set the 64-bit timebase in an SSX_CRITICAL critical section
+///
+/// It is assumed that the caller knows what they are doing; e.g., is aware of
+/// what may happen when time warps as a result of this call.
+
+void
+ssx_timebase_set(SsxTimebase timebase)
+{
+ SsxMachineContext ctx;
+ Uint64 tb;
+
+ tb.value = timebase;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ mttbl(0);
+ mttbu(tb.word[0]);
+ mttbl(tb.word[1]);
+
+ ssx_critical_section_exit(&ctx);
+}
+
+
+/// Enable interrupt preemption
+///
+/// This API can only be called from an interrupt context. Threads will
+/// always be preempted by interrupts unless they explicitly disable
+/// interrupts with the \c ssx_interrupt_disable() API. It is legal to call
+/// this API redundantly.
+///
+/// Be careful when enabling interrupt handler preemption that the interrupt
+/// being handled does not/can not trigger again, as this could rapidly lead
+/// to stack overflows.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_ILLEGAL_CONTEXT The API call was not made from an interrupt
+/// context.
+
+int
+ssx_interrupt_preemption_enable()
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_UNLESS_ANY_INTERRUPT_CONTEXT();
+ }
+
+ if (__ssx_kernel_context_noncritical_interrupt()) {
+ wrteei(1);
+ } else {
+ or_msr(MSR_CE);
+ }
+
+ return SSX_OK;
+}
+
+
+/// Disable interrupt preemption
+///
+/// This API can only be called from an interrupt context. Threads will
+/// always be preempted by interrupts unless they explicitly disable
+/// interrupts with the \c ssx_interrupt_disable() API. It is legal to call
+/// this API redundantly.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_ILLEGAL_CONTEXT The API call was not made from an interrupt
+/// context.
+
+int
+ssx_interrupt_preemption_disable()
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_UNLESS_ANY_INTERRUPT_CONTEXT();
+ }
+
+ if (__ssx_kernel_context_noncritical_interrupt()) {
+ wrteei(0);
+ } else {
+ andc_msr(MSR_CE);
+ }
+
+ return SSX_OK;
+}
+
+
+#if SSX_TIMER_SUPPORT
+
+// The tickless kernel timer mechanism for PPC405
+//
+// This routine must be called from an SSX_NONCRITICAL 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 - SSX 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
+// __ssx_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 SSX specification.
+
+void
+__ssx_schedule_hardware_timeout(SsxTimebase timeout)
+{
+ SsxTimebase now;
+ uint32_t pit;
+
+ if (timeout != SSX_TIMEBASE_MAX) {
+
+ now = ssx_timebase_get();
+
+ if (timeout <= now) {
+ pit = 1;
+ } else if ((timeout - now) > 0xffffffff) {
+ pit = 0xffffffff;
+ } else {
+ pit = timeout - now;
+ }
+
+ mtspr(SPRN_PIT, pit);
+ }
+}
+
+
+// Cancel the PPC405 tickless kernel timeout
+//
+// This routine must be called from an SSX_NONCRITICAL critical section. SSX
+// does not use auto-reload mode of the PIT, so simply writing the PIT with 0
+// effectively cancels the timer.
+
+void
+__ssx_cancel_hardware_timeout()
+{
+ mtspr(SPRN_PIT, 0);
+}
+
+
+#endif /* SSX_TIMER_SUPPORT */
+
+#undef __PPC405_CORE_C__
diff --git a/src/ssx/ppc405/ppc405_dcr.h b/src/ssx/ppc405/ppc405_dcr.h
new file mode 100755
index 0000000..1f389bf
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_dcr.h
@@ -0,0 +1,55 @@
+#ifndef __PPC405_DCR_H__
+#define __PPC405_DCR_H__
+
+// $Id: ppc405_dcr.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_dcr.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_dcr.h
+/// \brief Everything related to PPC405-specific DCRs
+///
+/// DCRs are chip-specific. This file only defines DCR access methods; DCR
+/// numbers will be defined by chip-specific headers.
+
+/// Move From DCR
+///
+/// Note that \a dcrn must be a compile-time constant.
+
+#define mfdcr(dcrn) \
+ ({uint32_t __value; \
+ asm volatile ("mfdcr %0, %1" : "=r" (__value) : "i" (dcrn)); \
+ __value;})
+
+
+/// Move to DCR
+///
+/// Note that \a dcrn must be a compile-time constant.
+
+#define mtdcr(dcrn, value) \
+ ({uint32_t __value = (value); \
+ asm volatile ("mtdcr %0, %1" : : "i" (dcrn), "r" (__value)); \
+ })
+
+
+/// Read-Modify-Write a DCR with OR (Set DCR bits)
+///
+/// Note that \a dcrn must be a compile-time constant. This operation is only
+/// guaranteed atomic in a critical section.
+
+#define or_dcr(dcrn, x) \
+ mtdcr(dcrn, mfdcr(dcrn) | (x))
+
+
+/// Read-Modify-Write a DCR with AND complement (Clear DCR bits)
+///
+/// Note that \a dcrn must be a compile-time constant. This operation is only
+/// guaranteed atomic in a critical section.
+
+#define andc_dcr(dcrn, x) \
+ mtdcr(dcrn, mfdcr(dcrn) & ~(x))
+
+#endif /* __PPC405_DCR_H__ */
diff --git a/src/ssx/ppc405/ppc405_exceptions.S b/src/ssx/ppc405/ppc405_exceptions.S
new file mode 100755
index 0000000..c8be2e3
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_exceptions.S
@@ -0,0 +1,832 @@
+// $Id: ppc405_exceptions.S,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_exceptions.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_exceptions.S
+/// \brief PPC405 exception vector area.
+///
+/// The PowerPC exception vector area has many small and large 'holes' in the
+/// SSX implementation. These are due to numerous unhandled exceptions and
+/// unimplemented exceptions in the exception vector area that comprises 8KB
+/// in the 405. SSX interrupt handling and other code is 'packed' into these
+/// holes to reduce the effective code footprint of SSX. The packing is done
+/// (hopefully) on a reasonable basis - we haven't tried to squeeze every last
+/// byte by chopping up routines willy-nilly and stitching them together with
+/// random branches - but some fragmentation has occurred in the interrupt
+/// handling code.
+///
+/// To facilitate the packing, the exception vector area is divided into 5 ELF
+/// sections (addresses are offsets into the exception area)
+///
+/// .vectors_0000 - Empty section for adding image header
+///
+/// .vectors_0100 - From 0x0100 to 0x0bff. The beginning of the table through
+/// the large space prior to the system call vector.
+///
+/// .vectors_0c00 - From 0x0c00 to 0x0eff. This is a moderately large area
+/// after the system call vector.
+///
+/// .vectors_0f00 - From 0x0f00 to 0x1fff. From the APU Unavailable vector
+/// through the major 3.5K hole above the Debug vector.
+///
+/// .vectors_2000 - From 0x2000 to 0x2003 - branch to the Debug handler.
+///
+/// The exception vector area must be aligned on a 64KB boundary.
+///
+/// Note that PgP mainstore boot and interrupt controller handling is
+/// currently hard-coded into this file - but it can easily be generalized if
+/// a port to another environment is required, assuming the new environment
+/// has something similar to a PgP or 405 ASIC interrupt controller.
+///
+/// \cond
+
+ .nolist
+#include "ssx.h"
+ .list
+
+### ****************************************************************************
+### .vectors_0000 - Empty section ( Image header will be placed in this section
+### from the linker command file )
+### ****************************************************************************
+
+ .section .vectors_0000, "a", @progbits
+ .global __vectors
+ .global __vectors_0000
+__vectors:
+__vectors_0000:
+
+### ****************************************************************************
+### .vectors_0100
+### ****************************************************************************
+ .section .vectors_0100, "ax", @progbits
+
+ .global __vectors_0100
+
+__vectors_0100:
+
+ ############################################################
+ # 0x0100 : Critical Interrupt
+ ############################################################
+
+__critical_interrupt:
+
+ ## The critical interrupt handler entry point is re-entrant - A handler
+ ## may allow preemption, which could cause another entry here.
+
+ ## Entry invariants:
+ ## 1. Critical interupts are disabled;
+ ## 2. The SP points to a thread stack, the non-critical stack or
+ ## critical stack
+
+ ## Since fast-mode handlers can not use SSX services or alter the
+ ## machine context, the exit of a fast mode handler is a simple RF(C)I.
+
+ ## Begin by pushing the fast context on the stack.
+
+ _ssx_fast_ctx_push SSX_CRITICAL
+
+ ## Load critical status 0 and the handler array base address. Check
+ ## for interrupts pending in status register 0 while the IRQ is
+ ## computed and R5 is loaded with the critical flag.
+
+ _lwzi %r3, %r3, OCB_OCISR0
+ _liw %r6, __ppc405_irq_handlers
+ cmpwi %r3, 0
+ cntlzw %r4, %r3
+ li %r5, SSX_CRITICAL
+ bne+ critical_irq_found
+
+ ## No IRQ pending in interrupt set 0. Try set 1.
+
+ _lwzi %r3, %r3, OCB_OCISR1
+ cmpwi %r3, 0
+ cntlzw %r4, %r3
+ addi %r4, %r4, 32
+ beq- critical_phantom
+
+ ## An active IRQ was found. At entry here R6 has the handler table
+ ## base address, R4 has the IRQ number, and R5 has the critical
+ ## flag. 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
+ ## R4 = irq
+ ## R5 = SSX_CRITICAL
+
+critical_irq_found:
+
+ _save_update_kernel_context SSX_CRITICAL, %r4, %r7
+ slwi %r3, %r4, 3
+ lwzux %r7, %r6, %r3
+ lwz %r3, 4(%r6)
+ mtlr %r7
+ blrl
+
+ ## Pop the stack/RFCI when (if) it returns here.
+
+fast_exit_critical:
+
+ _ssx_fast_ctx_pop_exit SSX_CRITICAL
+
+ ## This is a phantom interrupt - we got interrupted but no status bits
+ ## are set. The interrupt is marked as #64. The register used for the
+ ## handler table address (R6) is set to the special structure for the
+ ## phantom interrupt, with it's address adjusted to make it appear to
+ ## be the 64th entry in the table.
+
+critical_phantom:
+
+ _liw %r6, __ppc405_phantom_irq
+ subi %r6, %r6, (64 * 8)
+ b critical_irq_found
+
+
+ ############################################################
+ # 0x0200 : Machine Check, Data or Instruction
+ ############################################################
+
+ .org __vectors_0100 + 0x0100
+__machine_check:
+
+ PPC405_MACHINE_CHECK_HANDLER
+
+ .org __machine_check + 0x20
+
+ .global __ssx_irq_fast2full
+__ssx_irq_fast2full:
+
+ ## Convert a fast-mode to a full-mode interrupt by saving the
+ ## (volatile - fast) context, and switching to the appropriate system
+ ## stack.
+
+ ## Entry invariants:
+ ## 1. The SP/stack must be exactly as it was when the fast-mode
+ ## handler was entered.
+ ## 2. No changes have been made to the MSR - the interrupt level must
+ ## remain disabled.
+ ## 3. The handler owns the fast context and has not modified the other
+ ## register context. This routine can only use the (volatile -
+ ## fast) register context.
+
+ ## 41 (linear) instructions plus alignmenmt
+
+ ## Start by pushing the (volatile - fast) context. Technically we also
+ ## need to save the CR as our contract with the handler is not to
+ ## disturb any of its register state.
+
+ _ssx_vol_fast_ctx_push SSX_IRQ_CONTEXT
+ mfcr %r12
+
+ ## USPRG0 tells whether this is a critical or non-critical interrupt.
+ ## The high-order 8 bits of USPRG0 counts critical interrupt nesting,
+ ## and the SSX preemption rules guarantee that if the count is > 0 then
+ ## we are in a critical handler.
+
+ mfusprg0 %r8
+ extrwi. %r9, %r8, 8, 0
+ beq fast2full_noncritical
+
+ ## If the critical interrupt count is > 1, we are already in a
+ ## nested critical interrupt, so we're already on the critical stack
+ ## and there's nothing left to do.
+
+ cmpwi %r9, 1
+ bne 1f
+
+ ## Otherwise, save the current stack pointer and switch to the critical
+ ## stack.
+
+ _stwsd %r1, __ssx_saved_sp_critical
+ _lwzsd %r1, __ssx_critical_stack
+
+ ## Restore the CR and return to the now full-mode handler.
+
+1:
+ mtcr %r12
+ blr
+
+ ## Non-critical interrupts are handled analogously to the above,
+ ## except that bits 8:15 of R7 are the non-critical
+ ## count. At entry here the (volatile - fast) context has been pushed,
+ ## R8 has USPRG0 and R12 contains the saved CR.
+
+ ## Note that it would violate a kernel/API invariant if this routine
+ ## were entered from outside an interrupt context.
+
+ .cache_align
+fast2full_noncritical:
+
+ extrwi %r9, %r8, 8, 8
+ cmpwi %r9, 1
+ bne 1f
+
+ _stwsd %r1, __ssx_saved_sp_noncritical
+ _lwzsd %r1, __ssx_noncritical_stack
+
+1:
+
+ .if (SSX_ERROR_CHECK_KERNEL | SSX_ERROR_CHECK_API)
+ cmpwi %r9, 0
+ bne 2f
+ _ssx_panic PPC405_IRQ_FAST2FULL_INVARIANT
+2:
+ .endif
+
+ mtcr %r12
+ blr
+
+
+ ############################################################
+ # 0x0300 : Data Storage Interrupt
+ ############################################################
+
+ .org __vectors_0100 + 0x0200
+__data_storage:
+
+ PPC405_DATA_STORAGE_HANDLER
+
+ .org __data_storage + 0x20
+
+ .global __ssx_irq_full_mode_exit
+__ssx_irq_full_mode_exit:
+
+ ## Exit a full-mode handler.
+
+ ## Entry invariants:
+ ## 1. The SP/stack must be in exactly the same state it was left in at
+ ## the exit of __ssx_irq_fast2full.
+ ## 2. It is assumed the the preemption rules of SSX have been followed
+ ## - in particular that critical handlers have not enabled
+ ## non-critical interrupts.
+
+ ## We can freely modify the volatile context here - the handler is done
+ ## and we will restore the interrupted volatile context.
+
+ ## 22 linear instructions
+
+ ## If the critical count is non-zero, then the SSX preemption rules
+ ## guarantee that we are exiting from a critical interrupt
+ ## handler. This test is safe to make even if critical interrupts are
+ ## enabled, because the variable is set exactly once in a critical
+ ## section.
+
+ mfusprg0 %r3
+ extrwi. %r4, %r3, 8, 0
+ beq full_exit_noncritical
+
+ ## The context restore must be done from a critical section, in case
+ ## the handler enabled preemption.
+
+ _ssx_critical_section_enter SSX_CRITICAL, %r5, %r6
+
+ ## If the critical count (R4) is > 1 then this is a nested interrupt
+ ## and we can simply pop the context and RFCI.
+
+ cmpwi %r4, 1
+ bne full_exit_critical
+
+ ## Otherwise, restore the saved stack pointer before popping and RFCI.
+
+ _lwzsd %r1, __ssx_saved_sp_critical
+
+full_exit_critical:
+ _ssx_vol_fast_ctx_pop SSX_IRQ_CONTEXT, SSX_CRITICAL
+ b fast_exit_critical
+
+
+ ############################################################
+ # 0x0400 : Instruction Storage Interrupt
+ ############################################################
+
+ .org __vectors_0100 + 0x0300
+__instruction_storage:
+
+ PPC405_INSTRUCTION_STORAGE_HANDLER
+
+ .org __instruction_storage + 0x20
+
+ ## The idle thread has no permanent register context. The idle thread
+ ## entry point is re-entered whenever the idle thread is scheduled.
+
+ .global __ssx_idle_thread
+ .global __ssx_idle_thread_from_bootloader
+
+__ssx_idle_thread:
+
+ ## The idle thread 'uses' the non-critical 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 non-critical interrupts disabled.
+ ##
+ ## The kernel context is initialized to indicate that the idle thread
+ ## is running - the idle thread priority is SSX_THREADS, and the
+ ## 'thread-mode' bit is asserted as well.
+ ##
+ ## This loop can also be called from the SSX bootloader if main()
+ ## returns - in which case we don't muck with the USPRG0 or the stack
+ ## pointer.
+
+ li %r3, (SSX_THREADS | PPC405_THREAD_MODE)
+ mtusprg0 %r3
+ _lwzsd %r1, __ssx_noncritical_stack
+
+__ssx_idle_thread_from_bootloader:
+
+ li %r3, SSX_THREADS
+ SSX_TRACE_THREAD_SWITCH %r3, %r4
+ _lwzsd %r3, __ssx_thread_machine_context_default
+ _oriwa %r3, %r3, MSR_WE
+ mtmsr %r3
+ b .
+
+ ## ssx_halt() is implemented on the PPC405 by disabling all
+ ## interrupts, forcing external debug mode, and executing a trap. A
+ ## 0x0 word appears after the trap instruction similar to the default
+ ## SSX_PANIC macro. The caller may also call ssx_halt() with
+ ## parameters which will appear in R3, R4, etc. In the Simics
+ ## environment we use the Simics 'trap' since Simics does not handle
+ ## the PPC405 TRAP instruction correctly.
+
+ .global ssx_halt
+ssx_halt:
+ li %r31, 0
+ mtmsr %r31
+ isync
+ _liwa %r31, (DBCR0_EDM | DBCR0_TDE)
+ mtdbcr0 %r31
+ isync
+#if SIMICS_ENVIRONMENT
+ rlwimi 1, 1, 0, 0, 0
+#else
+ trap
+#endif
+ .long 0
+
+ ############################################################
+ # 0x0500 : External Interrupt
+ ############################################################
+
+ .org __vectors_0100 + 0x0400
+__external_interrupt:
+
+ ## The non-critical interrupt handler entry point is re-entrant - A
+ ## handler may allow preemption, which could cause another entry here.
+
+ ## Entry invariants:
+ ## 1. Non-critical interupts are disabled;
+ ## 2. The SP points to a thread stack or the non-critical stack.
+
+ ## Since fast-mode handlers can not use SSX services or alter the
+ ## machine context, the exit of a fast mode handler is a simple RF(C)I.
+
+ ## Begin by pushing the fast context on the current stack.
+
+ _ssx_fast_ctx_push SSX_NONCRITICAL
+
+ ## Load noncritical status 0 and the handler array base address. Check
+ ## for interrupts pending in status register 0 while the IRQ is
+ ## computed and R5 is loaded with the noncritical flag.
+
+ _lwzi %r3, %r3, OCB_ONISR0
+ _liw %r6, __ppc405_irq_handlers
+ cmpwi %r3, 0
+ cntlzw %r4, %r3
+ li %r5, SSX_NONCRITICAL
+ bne+ noncritical_irq_found
+
+ ## No IRQ pending in interrupt set 0. Try set 1.
+
+ _lwzi %r3, %r3, OCB_ONISR1
+ cmpwi %r3, 0
+ cntlzw %r4, %r3
+ addi %r4, %r4, 32
+ beq- noncritical_phantom
+
+ ## An active IRQ was found. At entry here R6 has the handler table
+ ## base address, R4 has the IRQ number, and R5 has the noncritical
+ ## flag. 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
+ ## R4 = irq
+ ## R5 = SSX_NONCRITICAL
+
+noncritical_irq_found:
+
+ _save_update_kernel_context SSX_NONCRITICAL, %r4, %r7
+ slwi %r3, %r4, 3
+ lwzux %r7, %r6, %r3
+ lwz %r3, 4(%r6)
+ mtlr %r7
+ blrl
+
+ ## Pop the stack/RFI when (if) it returns here.
+
+fast_exit_noncritical:
+
+ _ssx_fast_ctx_pop_exit SSX_NONCRITICAL
+
+ ## This is a phantom interrupt - we got interrupted but no status bits
+ ## are set. The interrupt is marked as #64. The register used for the
+ ## handler table address (R6) is set to the special structure for the
+ ## phantom interrupt, with it's address adjusted to make it appear to
+ ## be the 64th entry in the table.
+
+noncritical_phantom:
+
+ _liw %r6, __ppc405_phantom_irq
+ subi %r6, %r6, (64 * 8)
+ b noncritical_irq_found
+
+ ############################################################
+ # 0x0600 : Alignment Exception
+ ############################################################
+
+ .org __vectors_0100 + 0x0500
+__alignment_exception:
+
+ PPC405_ALIGNMENT_HANDLER
+
+ .org __alignment_exception + 0x20
+pit_handler:
+
+ ## The portable timer handler of SSX a full-mode handler with the prototype:
+ ## void (*ssx_timer_handler)(void).
+ ##
+ ## To support the portable specification, the kernel clears the
+ ## interrupt by writing the PIS back into the TSR before calling the
+ ## handler. SSX does not use the PIT in auto-reload mode - it is
+ ## tickless - so the interrupt will not fire again until reprogrammed
+ ## by the timer handler. The timer handler does not take any arguments.
+
+ ## 21 instructions
+
+ _ssx_fast_ctx_push SSX_NONCRITICAL
+ li %r3, PPC405_IRQ_PIT
+ _save_update_kernel_context SSX_NONCRITICAL, %r3, %r4
+
+ _liwa %r3, TSR_PIS
+ mttsr %r3
+ isync
+
+ _ssx_irq_fast2full __ssx_timer_handler
+
+
+ ############################################################
+ # 0x0700 : Program Interrupt
+ ############################################################
+
+ .org __vectors_0100 + 0x0600
+__program_interrupt:
+
+ PPC405_PROGRAM_HANDLER
+
+ .org __program_interrupt + 0x20
+
+ ## Exiting a full-mode non-critical handler is more complex than the
+ ## critical case, because the handler may have made a new
+ ## highest-priority thread runnable and we may need to go through a
+ ## delayed scheduling step.
+
+ ## Note that the idle thread is treated as a special case. The idle
+ ## thread has no permanent register context. To avoid having to
+ ## allocate a stack area for the idle thread, the idle thread
+ ## 'uses' the non-critical stack. When the idle thread is interrupted
+ ## the (redundant) context is pushed, but is then effectively lost.
+ ## Whenever we restore the idle thread we simply reenter the idle
+ ## thread entry point.
+
+ ## At entry:
+ ## 1. R3 holds the value of USPRG0 (__SsxKernelContext)
+
+ ## 33 linear instructions.
+
+full_exit_noncritical:
+
+ ## Enter a critical section for the return from interrupt, in the event
+ ## that the handler enabled preemption.
+
+ _ssx_critical_section_enter SSX_NONCRITICAL, %r4, %r5
+
+ ## If the non-critical count is > 1 then this is a nested interrupt
+ ## and we can simply pop the context and RFI. Note that it would
+ ## violate a kernel/API invariant if this routine were entered from
+ ## outside an interrupt context (interrupt level == 0).
+
+ extrwi. %r4, %r3, 8, 8
+
+ .if (SSX_ERROR_CHECK_KERNEL | SSX_ERROR_CHECK_API)
+ bne 1f
+ _ssx_panic PPC405_IRQ_FULL_EXIT_INVARIANT
+1:
+ .endif
+
+ cmpwi %r4, 1
+ bne exit_noncritical_without_switch
+
+ ## Otherwise, restore the saved stack pointer and continue.
+
+ _lwzsd %r1, __ssx_saved_sp_noncritical
+
+ ## If we are not in thread mode (i.e., we took an interrupt in an
+ ## interupt-only configuration of SSX or after ssx_initialize() but
+ ## before ssx_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.
+
+ andi. %r4, %r3, PPC405_THREAD_MODE
+ beq exit_noncritical_without_switch
+
+ ## Now, check for a delayed context switch. If none is pending, we can
+ ## exit (after a check for the idle thread special case).
+
+ _lwzsd %r3, __ssx_delayed_switch
+ cmpwi %r3, 0
+ bne noncritical_switch
+
+ _lwzsd %r3, __ssx_current_thread
+ cmpwi %r3, 0
+ beq __ssx_idle_thread
+
+exit_noncritical_without_switch:
+ _ssx_vol_fast_ctx_pop SSX_IRQ_CONTEXT, SSX_NONCRITICAL
+ b fast_exit_noncritical
+
+ ## The non-critical interrupt activated a delayed context switch. The
+ ## C-level code has taken care of the scheduling decisions - we simply
+ ## need to implement them here.
+
+noncritical_switch:
+
+ ## Clear the delayed switch flag and go to the context switch code to
+ ## finish the switch.
+
+ li %r3, 0
+ _stwsd %r3, __ssx_delayed_switch
+
+ b thread_save_non_volatile_and_switch
+
+
+ ############################################################
+ # 0x0800 : FPU Unavailable
+ ############################################################
+
+ .org __vectors_0100 + 0x0700
+__fpu_unavailable:
+
+ PPC405_FPU_UNAVAILABLE_HANDLER
+
+ .org __fpu_unavailable + 0x20
+
+
+ ## Exit traces are moved here because the code area (0x100 bytes)
+ ## reserved for individual interrupts is overflowing when tracing is
+ ## enabled. This is kind of a hack: We know that this trace only
+ ## occurs when we're about to exit the fast context, at a place
+ ## where we can use any of the fast registers.
+
+__ssx_trace_critical_irq_exit:
+ SSX_TRACE_CRITICAL_IRQ_EXIT %r3, %r4
+ blr
+
+__ssx_trace_noncritical_irq_exit:
+ SSX_TRACE_NONCRITICAL_IRQ_EXIT %r3, %r4
+ blr
+
+ ## >>>>>>>>>> Pack .vectors_0100 here. Room for ~900 bytes. <<<<<<<<<<
+
+### ****************************************************************************
+### .vectors_0c00
+### ****************************************************************************
+
+ .section .vectors_0c00, "ax", @progbits
+ .global __vectors_0c00
+__vectors_0c00:
+
+ ############################################################
+ # 0x0c00 : System Call
+ ############################################################
+
+ .org __vectors_0c00 + 0x0
+ .global __ssx_next_thread_resume
+
+__system_call:
+
+ ## The system call exception is used by SSX as a handy way to start a
+ ## context switch, as the continuation address and MSR of the thread to
+ ## be swapped out are saved in SRR0 and SRR1.
+
+ ## Non-critical interrupts are disabled at entry.
+
+ ## Note that the system call exception begins a large free area
+ ## so there is plenty of room for the context switch code.
+
+ ## Begin by saving the volatile context of the current thread.
+
+ _ssx_fast_ctx_push SSX_NONCRITICAL
+ _ssx_vol_fast_ctx_push SSX_THREAD_CONTEXT
+
+thread_save_non_volatile_and_switch:
+
+ ## Finish the thread context save by pushing the non-volatile context
+ ## and saving the resulting stack pointer in the thread structure. If
+ ## the current thread is the idle thread this step is bypassed.
+
+ ## This symbol is also used as an entry point by the non-critical
+ ## interrupt handler - non-critical interrupts are disabled here.
+
+ _lwzsd %r3, __ssx_current_thread
+ cmpwi %r3, 0
+ beq __ssx_next_thread_resume
+
+ _ssx_non_vol_ctx_push
+ stw %r1, SSX_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
+
+ ## The next thread becomes the current thread, and we switch to its
+ ## stack - unless the new thread is the idle thread, in which case it
+ ## (the idle thread) is simply resumed.
+
+__ssx_next_thread_resume:
+
+ _lwzsd %r3, __ssx_next_thread
+ _stwsd %r3, __ssx_current_thread
+
+ cmpwi %r3, 0
+ beq __ssx_idle_thread
+
+ lwz %r1, SSX_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
+
+ ## Restore the thread context and resume the new thread. The kernel
+ ## context in thread mode is simply the thread priority OR'ed with the
+ ## thread-mode flag. All other fields are cleared.
+
+ _ssx_non_vol_ctx_pop
+ _ssx_vol_fast_ctx_pop SSX_THREAD_CONTEXT, SSX_NONCRITICAL
+
+ _lbzsd %r3, __ssx_next_priority
+ SSX_TRACE_THREAD_SWITCH %r3, %r4
+ ori %r3, %r3, PPC405_THREAD_MODE
+ mtusprg0 %r3
+
+ _ssx_fast_ctx_pop
+ rfi
+
+ ## >>>>>>>> Pack .vectors_0c00 here - room for ~500 bytes <<<<<<<
+
+### ****************************************************************************
+### .vectors_0f00
+### ****************************************************************************
+
+ .section .vectors_0f00, "ax", @progbits
+ .global __vectors_0f00
+__vectors_0f00:
+
+ ############################################################
+ # 0x0f20 : APU Unavailable
+ ############################################################
+
+ .org __vectors_0f00 + 0x20 # 0x0f20
+__apu_unavailable:
+
+ PPC405_APU_UNAVAILABLE_HANDLER
+
+ .org __vectors_0f00 + 0x40 # 0x0f40
+
+fit_handler:
+
+ ## The FIT handler is user defined, and is a fast-mode handler. By
+ ## convention the kernel clears the interrupt by writing the FIS back
+ ## into the TSR.
+
+ _ssx_fast_ctx_push SSX_NONCRITICAL
+
+ _lwzsd %r3, __ppc405_fit_arg
+ li %r4, PPC405_IRQ_FIT
+ li %r5, SSX_NONCRITICAL
+
+ _save_update_kernel_context SSX_NONCRITICAL, %r4, %r6
+
+ _liwa %r6, TSR_FIS
+ mttsr %r6
+ isync
+
+ _lwzsd %r6, __ppc405_fit_routine
+ mtlr %r6
+ blrl
+
+ b fast_exit_noncritical
+
+
+ ############################################################
+ # 0x10x0 : PIT, FIT and Watchdog Interrupts
+ ############################################################
+
+ .org __vectors_0f00 + 0x100 # 0x1000
+__pit_interrupt:
+
+ b pit_handler
+
+ .org __vectors_0f00 + 0x110 # 0x1010
+__fit_interrupt:
+
+ b fit_handler
+
+ .org __vectors_0f00 + 0x120 # 0x1020
+__watchdog_interrupt:
+
+ ## Watchdog setup is described in the SSX Specification.
+ ## The kernel clears TSR[WIS] prior to calling the handler.
+ ## The watchdog handler is a critical, fast-mode handler.
+
+ _ssx_fast_ctx_push SSX_CRITICAL
+
+ _lwzsd %r3, __ppc405_watchdog_arg
+ li %r4, PPC405_IRQ_WATCHDOG
+ li %r5, SSX_CRITICAL
+
+ _save_update_kernel_context SSX_CRITICAL, %r4, %r6
+
+ _liwa %r6, TSR_WIS
+ mttsr %r6
+ isync
+
+ _lwzsd %r6, __ppc405_watchdog_routine
+ mtlr %r6
+ blrl
+
+ b fast_exit_critical
+
+
+ ############################################################
+ # 0x1100 : Data TLB Miss
+ ############################################################
+
+ .org __vectors_0f00 + 0x200 # 0x1100
+__data_tlb_miss:
+
+ PPC405_DATA_TLB_MISS_HANDLER
+
+ .org __data_tlb_miss + 0x20
+debug_handler:
+
+ ## SSX does nothing upon reception of the debug interrupt other
+ ## than calling the handler (if non-0). The debug handler is a
+ ## fast-mode handler.
+
+ _ssx_fast_ctx_push SSX_CRITICAL
+
+ _lwzsd %r3, __ppc405_debug_arg
+ li %r4, PPC405_IRQ_DEBUG
+ li %r5, SSX_CRITICAL
+
+ _save_update_kernel_context SSX_CRITICAL, %r4, %r6
+
+ _lwzsd %r6, __ppc405_debug_routine
+ cmpwi %r6, 0
+ mtlr %r6
+ beq debug_exit
+ blrl
+
+debug_exit:
+ b fast_exit_critical
+
+
+ ############################################################
+ # 0x1200 : Instruction TLB Miss
+ ############################################################
+
+ .org __vectors_0f00 + 0x300 # 0x1200
+__instruction_tlb_miss:
+
+ PPC405_INSTRUCTION_TLB_MISS_HANDLER
+
+ .org __instruction_tlb_miss + 0x20
+
+ ## >>>>>> Pack .vectors_0f00 A huge hole here - ~3.5KB <<<<<<
+
+### ****************************************************************************
+### .vectors_2000
+### ****************************************************************************
+
+ .section .vectors_2000, "ax", @progbits
+
+ .global __vectors_2000
+__vectors_2000:
+
+ ############################################################
+ # 0x2000 : Debug Interrupt
+ ############################################################
+
+__debug_interrupt:
+ b debug_handler
+
+/// \endcond
diff --git a/src/ssx/ppc405/ppc405_init.c b/src/ssx/ppc405/ppc405_init.c
new file mode 100755
index 0000000..e818737
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_init.c
@@ -0,0 +1,80 @@
+// $Id: ppc405_init.c,v 1.1.1.1 2013/12/11 21:03:26 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_init.c
+/// \brief PPC405 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 "ssx.h"
+
+// Note that __ppc405_system_setup() is called from the SSX bootloader early
+// in the initialization, at a point before the aplication has enabled
+// critical or external interruts.
+
+void
+__ppc405_system_setup()
+{
+ SsxIrqId irq;
+
+ // Initialize the interrupt vectors.
+
+ for (irq = 0; irq < PPC405_IRQS; irq++) {
+ __ppc405_irq_handlers[irq].handler = __ppc405_default_irq_handler;
+ __ppc405_irq_handlers[irq].arg = 0;
+ }
+
+ __ppc405_phantom_irq.handler = __ppc405_phantom_irq_handler;
+ __ppc405_phantom_irq.arg = 0;
+
+ // Initialize special interrupt handlers
+
+ __ppc405_fit_routine = __ppc405_default_irq_handler;
+ __ppc405_fit_arg = 0;
+
+ __ppc405_watchdog_routine = __ppc405_default_irq_handler;
+ __ppc405_watchdog_arg = 0;
+
+ __ppc405_debug_routine = __ppc405_default_irq_handler;
+ __ppc405_debug_arg = 0;
+
+ // Enable the PIT interrupt, but not auto-reload mode. Clear the status
+ // of all timers for good measure.
+
+ andc_spr(SPRN_TCR, TCR_ARE);
+ or_spr(SPRN_TCR, TCR_PIE);
+
+ or_spr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS);
+
+ // Call system-specific setup
+
+#ifdef CHIP_PGP
+ void __pgp_setup();
+ __pgp_setup();
+#endif
+
+}
+
+
+// Set the timebase using the PowerPC protocol.
+
+void
+__ssx_timebase_set(SsxTimebase t)
+{
+ Uint64 tb;
+
+ tb.value = t;
+
+ mttbl(0);
+ mttbu(tb.word[0]);
+ mttbl(tb.word[1]);
+}
+
+
diff --git a/src/ssx/ppc405/ppc405_irq.h b/src/ssx/ppc405/ppc405_irq.h
new file mode 100755
index 0000000..d85e9ce
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_irq.h
@@ -0,0 +1,342 @@
+#ifndef __PPC405_IRQ_H__
+#define __PPC405_IRQ_H__
+
+// $Id: ppc405_irq.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_irq.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_irq.h
+/// \brief PPC405 interrupt handling for SSX
+///
+/// Interrupt handling protocols and interrupt controller programming are
+/// inherently non-portable, however SSX defines APIs that may be useful among
+/// different machines.
+///
+/// The interrupt controllers in PPC405 ASICS and PGP allow interrupts to be
+/// programmed as critical or non-critical, with programmable polarity and
+/// edge or level sensitivity.
+
+
+// Define pseudo-IRQ numbers for PPC405 built-in interrupts. These numbers
+// will appear in bits 16:23 of USPRG0 (__SsxKernelContext) when the handlers
+// are active, and are also passed as the second argument of the handlers when
+// they are invoked.
+
+#define PPC405_IRQ_PIT 0x80
+#define PPC405_IRQ_FIT 0x81
+#define PPC405_IRQ_WATCHDOG 0x82
+#define PPC405_IRQ_DEBUG 0x83
+
+// These are suggested values to use for the IRQ in the __SsxKernelContext if
+// the application defines handlers for any of the 'unhandled exceptions'.
+
+#define PPC405_EXC_MACHINE_CHECK 0x90
+#define PPC405_EXC_DATA_STORAGE 0x91
+#define PPC405_EXC_INSTRUCTION_STORAGE 0x92
+#define PPC405_EXC_ALIGNMENT 0x93
+#define PPC405_EXC_PROGRAM 0x94
+#define PPC405_EXC_FPU_UNAVAILABLE 0x95
+#define PPC405_EXC_APU_UNAVAILABLE 0x96
+#define PPC405_EXC_DATA_TLB_MISS 0x97
+#define PPC405_EXC_INSTRUCTION_TLB_MISS 0x98
+
+
+// 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 PPC405_MACHINE_CHECK_HANDLER
+#define PPC405_MACHINE_CHECK_HANDLER SSX_PANIC(0x0200)
+#endif
+
+#ifndef PPC405_DATA_STORAGE_HANDLER
+#define PPC405_DATA_STORAGE_HANDLER SSX_PANIC(0x0300)
+#endif
+
+#ifndef PPC405_INSTRUCTION_STORAGE_HANDLER
+#define PPC405_INSTRUCTION_STORAGE_HANDLER SSX_PANIC(0x0400)
+#endif
+
+#ifndef PPC405_ALIGNMENT_HANDLER
+#define PPC405_ALIGNMENT_HANDLER SSX_PANIC(0x0600)
+#endif
+
+#ifndef PPC405_PROGRAM_HANDLER
+#define PPC405_PROGRAM_HANDLER SSX_PANIC(0x0700)
+#endif
+
+#ifndef PPC405_FPU_UNAVAILABLE_HANDLER
+#define PPC405_FPU_UNAVAILABLE_HANDLER SSX_PANIC(0x0800)
+#endif
+
+#ifndef PPC405_APU_UNAVAILABLE_HANDLER
+#define PPC405_APU_UNAVAILABLE_HANDLER SSX_PANIC(0x0f20)
+#endif
+
+#ifndef PPC405_DATA_TLB_MISS_HANDLER
+#define PPC405_DATA_TLB_MISS_HANDLER SSX_PANIC(0x1100)
+#endif
+
+#ifndef PPC405_INSTRUCTION_TLB_MISS_HANDLER
+#define PPC405_INSTRUCTION_TLB_MISS_HANDLER SSX_PANIC(0x1200)
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////
+// SSX API
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ASSEMBLER__
+
+/// An IRQ handler takes 3 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 .
+/// \arg \c priority - One of the values \c SSX_CRITICAL or \c
+/// SSX_NONCRITICAL; to enable a generic handler to choose
+/// a behavior appropriate for the interrupt priority.
+
+typedef void (*SsxIrqHandler)(void* arg,
+ SsxIrqId irq,
+ int priority);
+
+/// Declare a subroutine as an IRQ handler
+
+#define SSX_IRQ_HANDLER(f) void f(void *arg, SsxIrqId irq, int priority)
+
+int ssx_irq_setup(SsxIrqId irq,
+ int polarity,
+ int trigger);
+
+int ssx_irq_handler_set(SsxIrqId irq,
+ SsxIrqHandler handler,
+ void* arg,
+ int priority);
+
+void ssx_irq_enable(SsxIrqId irq);
+void ssx_irq_disable(SsxIrqId irq);
+void ssx_irq_statusclear(SsxIrqId irq);
+
+SSX_IRQ_HANDLER(__ppc405_default_irq_handler);
+SSX_IRQ_HANDLER(__ppc405_phantom_irq_handler);
+
+
+int
+ppc405_fit_setup(int tcr_fp, SsxIrqHandler handler, void* arg);
+
+
+/// The address of the optional FIT interrupt handler
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+volatile
+SsxIrqHandler __ppc405_fit_routine;
+
+
+/// The private data of the optional FIT interrupt handler
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+volatile
+void* __ppc405_fit_arg;
+
+
+int
+ppc405_watchdog_setup(int tcr_wp, int tcr_wrc,
+ SsxIrqHandler handler, void* arg);
+
+
+/// The address of the optional Watchdog interrupt handler
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+volatile
+SsxIrqHandler __ppc405_watchdog_routine;
+
+
+/// The private data of the optional Watchdog interrupt handler
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+volatile
+void* __ppc405_watchdog_arg;
+
+
+int
+ppc405_debug_setup(SsxIrqHandler handler, void* arg);
+
+
+/// The address of the optional Debug interrupt handler
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+volatile
+SsxIrqHandler __ppc405_debug_routine;
+
+
+/// The private data of the optional Watchdog interrupt handler
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+volatile
+void* __ppc405_debug_arg;
+
+
+// Note: Why SSX_IRQ_FAST2FULL (below) is implemented so strangely.
+//
+// I am adamant that I want to have a a macro in the 'C' environment to create
+// these bridge functions. However the limitations of the C preprocessor and
+// the intelligence of the GCC 'asm' facility consipre against a
+// straightforward solution. The only way that I was able to find to get
+// naked assembly code into the output stream is to use 'asm' with simple
+// strings - I couldn't make it work with any kind of argument, as 'asm' would
+// reinterpret the arguments and resulting assembler code in various ways.
+//
+// There is another alternative that I tried wherby I created a subroutine
+// call and then filled in the subroutine body with 'asm' code. However, the
+// subroutine wrapper that GCC creates only works for PowerPC fast-mode
+// handlers if GCC is invoked with optimization, which ensures that the
+// wrapper doesn't touch the stack pointer or other registers. True, we'll
+// always use optimization, but I did not want to have to make this
+// requirement for using this macro.
+
+/// This macro creates a 'bridge' handler that converts the initial fast-mode
+/// IRQ dispatch into a call of a full-mode IRQ handler. The full-mode
+/// handler is defined by the user (presumably as a \c C subroutine) and has
+/// the same prototype (type SsxIrqHandler) as the fast handler.
+///
+/// \param fast_handler This will be the global function name of the fast
+/// IRQ handler created by this macro. This is the symbol
+/// that should be passed in as the \a handler argument
+/// of \c ssx_irq_setup() and \c ssx_irq_handler_set().
+///
+/// \param full_handler This is the name of the user-defined full-mode
+/// handler which is invoked through this bridge.
+///
+/// \e BUG \e ALERT : Beware of passing the \c full_handler to IRQ setup
+/// APIs. This won't be caught by the compiler (because the \c full_handler
+/// has the correct prototype) and will lead to nasty bugs. Always pass in
+/// the \c fast_handler symbol to IRQ setup APIS.
+///
+/// The code stream injected into the GCC assembler output in response to
+///
+/// SSX_IRQ_FAST2FULL(fast_handler, full_handler)
+///
+/// is (comments added for clarification) :
+///
+/// \code
+/// .text
+/// .global fast_handler
+/// .align 5 # Hard-coded PPC405 cache-line alignment
+/// fast_handler = . # Can't macro expand LABEL: - this is equivalent
+/// bl __ssx_irq_fast2full # The fast-mode to full-mode conversion sequence
+/// bl full_handler
+/// b __ssx_irq_full_mode_exit
+/// \endcode
+///
+/// The macro also declares the prototype of the fast handler:
+///
+/// \code
+/// SSX_IRQ_HANDLER(fast_handler);
+/// \endcode
+///
+
+#define SSX_IRQ_FAST2FULL(fast_handler, full_handler) \
+ SSX_IRQ_HANDLER(fast_handler); \
+ __SSX_IRQ_FAST2FULL(.global fast_handler, fast_handler = ., bl full_handler)
+
+#define __SSX_IRQ_FAST2FULL(global, label, call) \
+asm(".text"); \
+asm(#global); \
+asm(".align 5"); \
+asm(#label); \
+asm("bl __ssx_irq_fast2full"); \
+asm(#call); \
+asm("b __ssx_irq_full_mode_exit");
+
+#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 CHIP_PGP
+#include "pgp_irq.h"
+#endif
+
+/// \page ppc405_irq_macros_page PPC405 SSX IRQ Assembler Macros
+///
+///
+/// \section fast2full_asm Fast-Mode to Full-Mode Handler Conversion
+///
+/// This macro produces the calling sequence required to convert a
+/// fast-mode interrupt handler to a full-mode interrupt handler. The
+/// full-mode handler is implemented by another subroutine. The
+/// requirements for invoking this macro are:
+///
+/// \li The stack pointer and stack must be exactly as they were when the
+/// fast-mode handler was entered.
+///
+/// \li No changes have been made to the MSR - the interrupt level must
+/// remain disabled.
+///
+/// \li The handler owns the fast context and has not modified the other
+/// register context. The conversion process will not modify any
+/// register in the fast context (other than the LR used for
+/// subroutine linkage).
+///
+/// The final condition above means that the \a full_handler will
+/// begin with the fast-mode context exactly as it was (save for LR)
+/// at conversion, including the contents of GPR3-7 (the first 5
+/// PowerPC ABI paramater passing registers) and the entire CR.
+///
+/// Forms:
+///
+/// \c _ssx_irq_fast2full \a full_handler
+/// \cond
+
+#ifdef __ASSEMBLER__
+
+ .macro _ssx_irq_fast2full full_handler
+ bl __ssx_irq_fast2full
+ bl \full_handler
+ b __ssx_irq_full_mode_exit
+ .endm
+
+#endif /* __ASSEMBLER__ */
+
+/// \endcond
+
+#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 {
+ SsxIrqHandler handler;
+ void *arg;
+} Ppc405IrqHandler;
+
+
+/// Interrupt handlers for real (implemented interrupts)
+
+UNLESS__PPC405_IRQ_CORE_C__(extern)
+Ppc405IrqHandler __ppc405_irq_handlers[PPC405_IRQS];
+
+
+/// 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__PPC405_IRQ_CORE_C__(extern)
+Ppc405IrqHandler __ppc405_phantom_irq;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPC405_IRQ_H__ */
diff --git a/src/ssx/ppc405/ppc405_irq_core.c b/src/ssx/ppc405/ppc405_irq_core.c
new file mode 100755
index 0000000..3cd7469
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_irq_core.c
@@ -0,0 +1,49 @@
+// $Id: ppc405_irq_core.c,v 1.1.1.1 2013/12/11 21:03:26 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_irq_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_irq_core.c
+/// \brief Core IRQ routines required of any PPC405 configuration of SSX
+///
+/// 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
+/// SSX application.
+
+#define __PPC405_IRQ_CORE_C__
+
+#include "ssx.h"
+
+/// This function is installed by default for interrupts not explicitly set up
+/// by the application. These interrupts should never fire.
+
+void
+__ppc405_default_irq_handler(void *arg,
+ SsxIrqId irq,
+ int critical)
+{
+ SSX_PANIC(PPC405_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 critical or
+/// non-critical 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 noncritical or critical interrupt input
+/// to the PPC405 core.
+
+void __ppc405_phantom_irq_handler(void *arg,
+ SsxIrqId irq,
+ int critical)
+{
+ SSX_PANIC(PPC405_PHANTOM_INTERRUPT);
+}
+
+
+#undef __PPC405_IRQ_CORE_C__
diff --git a/src/ssx/ppc405/ppc405_irq_init.c b/src/ssx/ppc405/ppc405_irq_init.c
new file mode 100755
index 0000000..da33947
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_irq_init.c
@@ -0,0 +1,169 @@
+// $Id: ppc405_irq_init.c,v 1.2 2014/02/03 01:30:42 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_irq_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_irq_init.c
+/// \brief PPC405 IRQ 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 "ssx.h"
+
+/// Set up a PPC405 Fixed Interval Timer (FIT) handler
+///
+/// See the SSX specification for full details on setting up a FIT handler.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_PPC405_FIT The \a tcr_fp argument was
+/// invalid when called with a non-null (non-0) \a handler.
+
+// Since the SSX_CRITICAL Watchdog interrupt is also controlled by the TCR, we
+// need to enter an SSX_CRITICAL critical section to manipulate the TCR.
+
+int
+ppc405_fit_setup(int tcr_fp, SsxIrqHandler handler, void* arg)
+{
+ SsxMachineContext ctx;
+ Ppc405TCR tcr;
+
+ if (SSX_ERROR_CHECK_API && handler) {
+ SSX_ERROR_IF((tcr_fp < 0) ||
+ (tcr_fp > 3),
+ SSX_INVALID_ARGUMENT_PPC405_FIT);
+ }
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ tcr.value = mfspr(SPRN_TCR);
+
+ if (handler) {
+
+ tcr.fields.fp = tcr_fp;
+ tcr.fields.fie = 1;
+
+ __ppc405_fit_routine = handler;
+ __ppc405_fit_arg = arg;
+
+ } else {
+
+ tcr.fields.fie = 0;
+ }
+
+ mtspr(SPRN_TCR, tcr.value);
+ isync();
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// Set up a PPC405 Watchdog interrupt handler
+///
+/// See the SSX specification for full details on setting up a watchdog
+/// handler.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_PPC405_WATCHDOG One or more of the \a tcr_wp
+/// or \a tcr_wrc arguments were invalid.
+
+int
+ppc405_watchdog_setup(int tcr_wp, int tcr_wrc,
+ SsxIrqHandler handler, void* arg)
+{
+ SsxMachineContext ctx;
+ Ppc405TCR tcr;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((tcr_wp < 0) ||
+ (tcr_wp > 3) ||
+ (tcr_wrc < 0) ||
+ (tcr_wrc > 3),
+ SSX_INVALID_ARGUMENT_PPC405_WATCHDOG);
+ }
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS);
+
+ tcr.value = mfspr(SPRN_TCR);
+
+ tcr.fields.wp = tcr_wp;
+ tcr.fields.wrc = tcr_wrc;
+
+ if (handler == 0) {
+
+ // Reinstall the default handler and clear the interrupt enable. Then
+ // clear any pending interrupt status.
+ // WIS.
+
+ __ppc405_watchdog_routine = __ppc405_default_irq_handler;
+ __ppc405_watchdog_arg = 0;
+
+ tcr.fields.wie = 0;
+ mtspr(SPRN_TCR, tcr.value);
+ isync();
+
+ mtspr(SPRN_TSR, TSR_WIS);
+ isync();
+
+ } else {
+
+ // Install the new handler and enable the watchdog interrup.
+
+ __ppc405_watchdog_routine = handler;
+ __ppc405_watchdog_arg = arg;
+
+ tcr.fields.wie = 1;
+ mtspr(SPRN_TCR, tcr.value);
+ isync();
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// Set up a PPC405 Debug interrupt handler
+///
+/// See the SSX specification for full details on setting up a debug handler.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_PPC405_DEBUG The \a handler argument
+/// is null (0).
+
+// The debug handler is installed in an SSX_CRITICAL critical section with all
+// debug interrupts disabled as well.
+
+int
+ppc405_debug_setup(SsxIrqHandler handler, void* arg)
+{
+ SsxMachineContext ctx;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+ andc_msr(MSR_DE | MSR_DWE);
+
+ __ppc405_debug_routine = handler;
+ __ppc405_debug_arg = arg;
+ isync();
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
diff --git a/src/ssx/ppc405/ppc405_lib_core.c b/src/ssx/ppc405/ppc405_lib_core.c
new file mode 100755
index 0000000..3086efb
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_lib_core.c
@@ -0,0 +1,42 @@
+// $Id: ppc405_lib_core.c,v 1.2 2014/06/26 13:00:11 cmolsen Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_lib_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_lib_core.c
+/// \brief PPC405-specific library procedures
+///
+/// The routines in this file are not part of SSX per se, but are included
+/// with SSX because they may be considered OS services.
+///
+/// These are core routines that will present in all PPC405 SSX applications.
+
+#include "ssx.h"
+
+/// Cause a PPC405 core reset by an action on DBCR0
+
+void
+ppc405_core_reset()
+{
+ or_spr(SPRN_DBCR0, DBCR0_RST_CORE);
+}
+
+/// Cause a PPC405 chip reset by an action on DBCR0
+
+void
+ppc405_chip_reset()
+{
+ or_spr(SPRN_DBCR0, DBCR0_RST_CHIP);
+}
+
+/// Cause a PPC405 system reset by an action on DBCR0
+
+void
+ppc405_system_reset()
+{
+ or_spr(SPRN_DBCR0, DBCR0_RST_SYSTEM);
+}
+
diff --git a/src/ssx/ppc405/ppc405_mmu.c b/src/ssx/ppc405/ppc405_mmu.c
new file mode 100755
index 0000000..1affc67
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_mmu.c
@@ -0,0 +1,474 @@
+// $Id: ppc405_mmu.c,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_mmu.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_mmu.c
+/// \brief Functions related to the PPC405 MMU and its use in SSX.
+///
+/// SSX currently only supports using the PPC405 MMU for instruction and data
+/// area translation and protection for the global SSX application and kernel.
+/// No support for demand paging, user vs. kernel protection or
+/// thread-specific protection is provided.
+///
+/// Instead, the ppc405_mmu_map() API is provided. This API sets up TLB
+/// entries that provide address translation and protection for a region of
+/// memory. TLB entries are "locked", that is, once a TLB entry is defined it
+/// is permanently defined. SSX makes use of the variable page sizes provided
+/// by the PPC405 to protect regions using the minimum number of TLB entries.
+/// The minimum page size is 1K, and all regions to be protected must be 1K
+/// aligned and have sizes that are multiples of 1K.
+///
+/// The ppc405_mmu_map() API optionally returns a Ppc405MmuMap descriptor.
+/// This descriptor can be later used as the argument to ppc405_mmu_unmap() to
+/// unmap the region.
+///
+/// The overall SSX configuration option is PPC405_MMU_SUPPORT, with
+/// suboptions PPC405_IR_SUPPORT and PPC405_DR_SUPPORT. The IR (instruction
+/// relocate) and DR (data relocate) bits of the MSR must be set to enable
+/// instruction and data translation/protection respectively. In SSX this is
+/// handled by the definition of a macro PPC405_RELOCATION_MODE that contains
+/// the IR and/or DR bits as configured. This macro is OR'ed with the default
+/// PPC405 SSX_THREAD_MACHINE_CONTEXT_DEFAULT. If the application defines its
+/// own SSX_THREAD_MACHINE_CONTEXT_DEFAULT then the application will have to
+/// take care of ensuring that the correct IR/DR settings go into the default.
+///
+/// During interrupts and context switches the relocation mode is
+/// re-established before any loads or stores take place which provides
+/// complete protection for interrupt handlers. Note the
+/// assumption/requirement that all kernel, interrupt and thread code will be
+/// run under the PPC405_RELOCATION_MODE.
+
+#include "ssx.h"
+#include "ppc405_mmu.h"
+
+// A map of free TLB entries.
+//
+// It's handy that the PPC405 TLB has 64 entries. Thus we can use a 64-bit
+// bit mask to represent free entries. The next free entry is quickly found
+// using cntlz64().
+uint64_t __ppc405_tlb_free = 0;
+
+/// Reset the PPC405 simple MMU translation/protection scheme
+///
+/// This API invalidates the TLB, clears the zone protection register, and
+/// otherwise resets the SSX simple translation/protcetion scheme for the
+/// PPC405. The application must not be running in a translated mode when
+/// this API is invoked.
+///
+/// \retval 0 Success
+///
+/// \retval -PPC405_MMU_ILLEGAL_CONTEXT The API was called with translation
+/// enabled.
+
+int
+ppc405_mmu_reset()
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(mfmsr() & (MSR_IR | MSR_DR),
+ PPC405_MMU_ILLEGAL_CONTEXT);
+ }
+
+ tlbia();
+ mtspr(SPRN_PID, 0);
+ mtspr(SPRN_ZPR, 0);
+ __ppc405_tlb_free = 0xffffffffffffffffull;
+ isync();
+
+ return 0;
+}
+
+
+/// Define a memory region for MMU protection purposes
+///
+/// \param effective_address The effective (virtual) base address of the
+/// region. This address must be at least 1KB aligned.
+///
+/// \param real_address The real base address of the region. This address
+/// must be at least 1KB aligned.
+///
+/// \param size The size of the region in bytes. The size must be a multiple
+/// of 1KB. A \a size of 0 is legal and creates no entries.
+///
+/// \param tlbhi_flags An OR combination of PPC405_TLBHI_* bits (excluding the
+/// V-bit). This parameter is unlikely to be non-0 as it contains only the
+/// little-endian (E) and U0 flags.
+///
+/// - TLBHI_E : Little Endian
+/// - TLBHI_U0 : U0 mode access
+///
+/// \param tlblo_flags An OR combination of PPC405_TLBLO_* bits. This
+/// parameter defines WR and EX protection, as well as the 'WIMG' bits.
+///
+/// - TLBLO_EX : Executable code
+/// - TLBLO_WR : Writable data
+/// - TLBLO_W : Write-through mode
+/// - TLBLO_I : Cache-inhibited
+/// - TLBLO_M : Memory Coherent (Implemented but Ignored)
+/// - TLBLO_G : Guarded
+///
+/// \param map If non-0, then a Ppc405TlbMap for the region is returned.
+/// This map can be later used as an argument to ppc405_mmu_unmap() to unmap
+/// the region.
+///
+/// This API creates fixed TLB entries that provide virtual-to-real address
+/// translation and protection using a minimum number of TLB entries. The
+/// number of TLB entries is fixed, so there is no guarantee in general that
+/// any particular memory map is feasible. In general it is helpful to make
+/// sure that the effective and real memory ranges have similar alignment,
+/// otherwise the algorithm will be forced to use small page sizes.
+///
+/// The caller is responsible for cache-correctness of this API. If necessary
+/// the caller should flush or invalidate memory areas whose protection
+/// attributes have changed prior to and/or after invoking this API.
+///
+/// Note the the simple translation/protection protocol supported by this SSX
+/// API does not support the "zone selection" field of the PPC405 TLB
+/// entry. In SSX the PID is always 0.
+///
+/// If SSX_ERROR_CHECK_API is configured, the API checks each new TLB entry to
+/// ensure that it does not duplicate an existing entry. The check only
+/// covers duplicated effective addresses (which are not supported by the
+/// hardware), not the real addresses.
+///
+/// \retval 0 Success
+///
+/// \retval -PPC405_MMU_INVALID_ARGUMENT Can be signalled by numerous errors
+/// including improperly aigned memory regions, region size not a multiple of
+/// 1KB, and illegal flags.
+///
+/// \retval -PPC405_TOO_MANY_TLB_ENTRIES There are not enough TLB entries left
+/// to completely map the region. The state of the TLB at this point may be
+/// inconsistent.
+///
+/// \retval -PPC405_DUPLICATE_TLB_ENTRY The requested mapping would duplicate
+/// all or part of a currently existing TLB entry. Duplicate entries are not
+/// supported in the 405 core and will cause a TLB miss if an address in a
+/// duplicated range is accessed.
+
+int
+ppc405_mmu_map(SsxAddress effective_address,
+ SsxAddress real_address,
+ size_t size, int tlbhi_flags, int tlblo_flags,
+ Ppc405MmuMap *map)
+{
+ size_t log_page_size;
+ size_t page_size = 0;
+ Ppc405Tlbhi tlbhi;
+ Ppc405Tlblo tlblo;
+ Ppc405MmuMap local_map = 0;
+ int tlb_entry;
+ uint64_t bit;
+ SsxMachineContext ctx;
+
+ if (SSX_ERROR_CHECK_API) {
+ uint64_t allocated;
+ SsxAddress this_effective_address;
+ int entry, overlap;
+
+ // Check alignment, wrapping and legal flags.
+
+ SSX_ERROR_IF((effective_address % PPC405_PAGE_SIZE_MIN) ||
+ (real_address % PPC405_PAGE_SIZE_MIN) ||
+ (size % PPC405_PAGE_SIZE_MIN) ||
+ ((effective_address + size - 1) < effective_address) ||
+ (tlbhi_flags & ~TLBHI_LEGAL_FLAGS) ||
+ (tlblo_flags & ~TLBLO_LEGAL_FLAGS),
+ PPC405_MMU_INVALID_ARGUMENT);
+
+ // The check for duplicate entries needs to be done iteratively since
+ // we don't use a fixed page size. Since this API will probably only
+ // be called during initialization or from thread contexts, and since
+ // the TLB size is small, this overhead is not considered too onerous.
+ // For complete correctness this check would need to be done in its
+ // entirity in an SSX_CRITICAL critical section. In order to reduce
+ // SSX_CRITICAL interrupt latency we simply check against the TLB
+ // entries that were allocated at the time of the API call. This code
+ // may not protect against multiple threads simultaneously creating
+ // mappings that duplicate each other (a super-bug), but it should
+ // protect against bugs in a single thread's updating of the TLB.
+
+ if (size != 0) {
+
+ // See if the requested effective address is already mapped in the
+ // TLB
+
+ overlap = tlbsx(effective_address, &entry);
+
+ // Iteratively check the other overlap condition, which is the
+ // case that the effective address of any TLB entry is in the
+ // range of the new request.
+
+ allocated = ~__ppc405_tlb_free;
+ while (!overlap && (allocated != 0)) {
+
+ entry = cntlz64(allocated);
+ allocated &= ~((uint64_t)1 << (63 - entry));
+
+ tlbhi.value = tlbrehi(entry);
+ if (tlbhi.fields.v) {
+
+ this_effective_address =
+ tlbhi.fields.epn << PPC405_LOG_PAGE_SIZE_MIN;
+
+
+ // See if the first byte of this entry is inside the
+ // requested effective address range. NB: use actual
+ // address ranges (addr + size - 1) to compute overlap to
+ // avoid overflow.
+
+ overlap |=
+ (this_effective_address >=
+ effective_address) &&
+ (this_effective_address <=
+ (effective_address + size - 1));
+ }
+ }
+ SSX_ERROR_IF(overlap, PPC405_DUPLICATE_TLB_ENTRY);
+ }
+ }
+
+ // NB: PPC405 page sizes go from 1K to 16M by factors of 4. This is a
+ // 'greedy' algorithm that packs the region into the fewest number of
+ // pages, by using the largest possible (aligned) page size for the
+ // remaining memory area.
+
+ while (size != 0) {
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL(__ppc405_tlb_free == 0,
+ PPC405_TOO_MANY_TLB_ENTRIES,
+ &ctx);
+ }
+
+ tlb_entry = cntlz64(__ppc405_tlb_free);
+ bit = 0x8000000000000000ull >> tlb_entry;
+ __ppc405_tlb_free &= ~bit;
+ local_map |= bit;
+
+ ssx_critical_section_exit(&ctx);
+
+ log_page_size = PPC405_LOG_PAGE_SIZE_MAX;
+ do {
+ page_size = POW2_32(log_page_size);
+ if ((size >= page_size) &&
+ ((effective_address & (page_size - 1)) == 0) &&
+ ((real_address & (page_size - 1)) == 0)) {
+ break;
+ } else {
+ log_page_size -= 2;
+ }
+ } while (1);
+
+ size -= page_size;
+
+ // Create and install the TLB entries. The installation is done in a
+ // critical section to avoid any chance of another entity seeing an
+ // inconsistent TLB.
+
+ tlbhi.value = tlbhi_flags;
+ tlbhi.fields.epn = effective_address >> PPC405_LOG_PAGE_SIZE_MIN;
+ tlbhi.fields.size = (log_page_size - PPC405_LOG_PAGE_SIZE_MIN) / 2;
+ tlbhi.fields.v = 1;
+
+ tlblo.value = tlblo_flags;
+ tlblo.fields.rpn = real_address >> PPC405_LOG_PAGE_SIZE_MIN;
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ tlbwelo(tlb_entry, tlblo.value);
+ tlbwehi(tlb_entry, tlbhi.value);
+ isync();
+
+ ssx_critical_section_exit(&ctx);
+
+ effective_address += page_size;
+ real_address += page_size;
+ }
+
+ if (map) {
+ *map = local_map;
+ }
+
+ return 0;
+}
+
+
+/// Un-define a memory region for MMU protection purposes
+///
+/// \param map A pointer to a Ppc405MmuMap object created by ppc405_mmu_map()
+/// when the memory region was mapped. This map is used to invalidate the TLB
+/// entries associated with the map, then the map itself is invalidated.
+///
+/// The caller is responsible for cache-correctness of this API. If necessary
+/// the caller should flush or invalidate memory areas whose protection
+/// attributes have changed prior to and/or after invoking this API.
+///
+/// \retval 0 Success
+///
+/// \retval -PPC405_MMU_INVALID_ARGUMENT The \a map pointer is null (0).
+
+int
+ppc405_mmu_unmap(Ppc405MmuMap *map)
+{
+ int tlb_entry;
+ uint64_t bit;
+ SsxMachineContext ctx;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(map == 0, PPC405_MMU_INVALID_ARGUMENT);
+ }
+
+ while ((tlb_entry = cntlz64(*map)) != 64) {
+
+ bit = 0x8000000000000000ull >> tlb_entry;
+ *map &= ~bit;
+ tlbwehi(tlb_entry, 0);
+ isync();
+
+ ssx_critical_section_enter(SSX_CRITICAL, &ctx);
+
+ __ppc405_tlb_free |= bit;
+
+ ssx_critical_section_exit(&ctx);
+ }
+
+ return 0;
+}
+
+
+/// Produce a dump of the TLB
+///
+/// \param[in] i_stream The output stream for the dump
+///
+/// \param[in] i_map An optional pointer. If NULL (0) then a full report is
+/// printed. If non-null then only the entries recorded in the \a i_map are
+/// printed.
+
+void
+ppc405_mmu_report(FILE* i_stream, Ppc405MmuMap* i_map)
+{
+ size_t i;
+ Ppc405Tlbhi tlbhi;
+ Ppc405Tlblo tlblo;
+ uint32_t size, eff_lo, eff_hi, real_lo, real_hi;
+ const char *size_string[] = {
+ " 1K", " 4K", " 16K", " 64K", "256K", " 1M", " 4M", " 16M"
+ };
+ Ppc405MmuMap map;
+
+ fprintf(i_stream, "------------------------------------------------------------------------------\n");
+ if (i_map == 0) {
+ fprintf(i_stream, "-- PPC405 MMU : Full Report --\n");
+ } else {
+ fprintf(i_stream, "-- PPC405 MMU : Partial Report --\n");
+ }
+ fprintf(i_stream, "------------------------------------------------------------------------------\n");
+ fprintf(i_stream, "-- # Effective Real Size EX/WR WIMG Other --\n");
+ fprintf(i_stream, "------------------------------------------------------------------------------\n");
+
+ if (i_map == 0) {
+ map = __ppc405_tlb_free;
+ } else {
+ map = ~*i_map;
+ }
+
+ for (i = 0; i < PPC405_TLB_ENTRIES; i++, map <<= 1) {
+
+ if (map & 0x8000000000000000ull) {
+ continue;
+ }
+
+ tlbhi.value = tlbrehi(i);
+ tlblo.value = tlbrelo(i);
+
+ if (tlbhi.fields.v) {
+
+ size =
+ POW2_32(PPC405_LOG_PAGE_SIZE_MIN) << (2 * tlbhi.fields.size);
+
+ eff_lo = tlbhi.fields.epn << PPC405_LOG_PAGE_SIZE_MIN;
+ eff_hi = eff_lo + size - 1;
+
+ real_lo = tlblo.fields.rpn << PPC405_LOG_PAGE_SIZE_MIN;
+ real_hi = real_lo + size - 1;
+
+ fprintf(i_stream, "-- %2d : %08x:%08x -> %08x:%08x : %s : %s %s : %s%s%s%s : %s%s --\n",
+ i,
+ eff_lo, eff_hi,
+ real_lo, real_hi,
+ size_string[tlbhi.fields.size],
+ tlblo.fields.ex ? "EX" : " ",
+ tlblo.fields.wr ? "WR" : " ",
+ tlblo.fields.w ? "W" : " ",
+ tlblo.fields.i ? "I" : " ",
+ tlblo.fields.m ? "M" : " ",
+ tlblo.fields.g ? "G" : " ",
+ tlbhi.fields.e ? "E" : " ",
+ tlbhi.fields.u0 ? "U0" : " ");
+ } else {
+ fprintf(i_stream, "-- %2d : ENTRY NOT VALID\n", i);
+ }
+ }
+
+ fprintf(i_stream, "------------------------------------------------------------------------------\n");
+}
+
+
+/// Perform a memcpy() without address translation (protection)
+///
+/// It sometimes arises that "read-only" data needs to be initialized at
+/// run-time. This can be accomplished in general by temporarily disabling
+/// translation (protection) while the "read-only" data is altered. Another
+/// option is to use the memcpy_real() API to copy an image of the data from
+/// writable memory to memory marked read-only by the MMU.
+///
+/// The memcpy_real() function copies \a n bytes from memory area \a src to
+/// memory area \a dest, with translation disabled. The memory areas should
+/// not overlap. The memcpy_real() function returns a pointer to dest.
+///
+/// This is a general-purpose API that makes no assumption about the
+/// cacheability of the data, and can also be used to move code from data
+/// areas to text areas as the I-cache is always invalidated after the copy.
+/// The algorithm is as follows:
+///
+/// - Flush the \a dest data from the D-cache
+/// - Disable translation
+/// - memcpy() the \a src to the \a dest
+/// - Flush the \a dest data from the D-cache
+/// - Invalidate the I-cache
+/// - Re-enable translation (if it had been previously enabled)
+///
+/// \note Any synchronization access required for \a dest or \a src is the
+/// responsibility of the caller.
+void*
+memcpy_real(void* dest, const void* src, size_t n)
+{
+ uint32_t msr;
+
+ dcache_flush(dest, n);
+
+ msr = mfmsr();
+ mtmsr(msr & ~(MSR_IR | MSR_DR));
+ sync(); /* HW239446! */
+
+ memcpy(dest, src, n);
+
+ dcache_flush(dest, n);
+
+ icache_invalidate_all();
+
+ mtmsr(msr);
+ sync(); /* HW239446! */
+
+ return dest;
+}
+
+
+
+
diff --git a/src/ssx/ppc405/ppc405_mmu.h b/src/ssx/ppc405/ppc405_mmu.h
new file mode 100755
index 0000000..cd7e249
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_mmu.h
@@ -0,0 +1,170 @@
+#ifndef __PPC405_MMU_H__
+#define __PPC405_MMU_H__
+
+// $Id: ppc405_mmu.h,v 1.1.1.1 2013/12/11 21:03:26 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_mmu.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_mmu.h
+/// \brief Definitions related to the PPC405 MMU and its use in SSX.
+
+#ifndef __ASSEMBLER__
+
+#include "ssx_io.h"
+#include <stdint.h>
+
+/// The PPC405 TLBHI (tag) structure
+///
+/// Note that in hardware this is a 36-bit register, as it includes the TID
+/// field. When writing, TID is set from the current PID, and when reading PID
+/// is set from the TID entry of the register.
+
+typedef union {
+ uint32_t value;
+ struct {
+ uint32_t epn : 22;
+ uint32_t size : 3;
+ uint32_t v : 1;
+ uint32_t e : 1;
+ uint32_t u0 : 1;
+ } fields;
+} Ppc405Tlbhi;
+
+
+/// The PPC405 TLBLO (Data) structure
+
+typedef union {
+ uint32_t value;
+ struct {
+ uint32_t rpn : 22;
+ uint32_t ex : 1;
+ uint32_t wr : 1;
+ uint32_t zsel : 4;
+ uint32_t w : 1;
+ uint32_t i : 1;
+ uint32_t m : 1;
+ uint32_t g : 1;
+ } fields;
+} Ppc405Tlblo;
+
+#endif /* __ASSEMBLER__ */
+
+// TLBHI contains little-endian and U0 flags (probably never used)
+
+#define TLBHI_E 0x00000020
+#define TLBHI_U0 0x00000010
+
+#define TLBHI_LEGAL_FLAGS (TLBHI_E | TLBHI_U0)
+
+// TLBLO contains WIMG + EX/WR bits
+
+#define TLBLO_EX 0x00000200
+#define TLBLO_WR 0x00000100
+#define TLBLO_W 0x00000008
+#define TLBLO_I 0x00000004
+#define TLBLO_M 0x00000002
+#define TLBLO_G 0x00000001
+
+#define TLBLO_LEGAL_FLAGS \
+ (TLBLO_EX | TLBLO_WR | TLBLO_W | TLBLO_I | TLBLO_M | TLBLO_G)
+
+
+#define PPC405_TLB_ENTRIES 64
+
+#define PPC405_PAGE_SIZE_MIN 1024
+#define PPC405_PAGE_SIZE_MAX (16 * 1024 * 1024)
+
+#define PPC405_LOG_PAGE_SIZE_MIN 10
+#define PPC405_LOG_PAGE_SIZE_MAX 24
+
+#define PPC405_PAGE_SIZE_1K 0
+#define PPC405_PAGE_SIZE_4K 1
+#define PPC405_PAGE_SIZE_16K 2
+#define PPC405_PAGE_SIZE_64K 3
+#define PPC405_PAGE_SIZE_256K 4
+#define PPC405_PAGE_SIZE_1M 5
+#define PPC405_PAGE_SIZE_4M 6
+#define PPC405_PAGE_SIZE_16M 7
+
+// PPC405 MMU error and panic codes
+
+#define PPC405_MMU_ILLEGAL_CONTEXT 0x00668001
+#define PPC405_MMU_INVALID_ARGUMENT 0x00668002
+#define PPC405_TOO_MANY_TLB_ENTRIES 0x00668003
+#define PPC405_DUPLICATE_TLB_ENTRY 0x00668004
+
+
+#ifndef __ASSEMBLER__
+
+/// A descriptor of a memory region statically defined in the TLB
+///
+/// These maps are returned by ppc405_mmu_map(), and can be used later
+/// to unmap the region with ppc405_mmu_unmap(). They can also be used to
+/// control what gets printed by ppc405_mmu_report().
+typedef uint64_t Ppc405MmuMap;
+
+/// TLBIA
+#define tlbia() asm volatile ("tlbia" : : : "memory")
+
+/// TLBWEHI
+#define tlbwehi(entry, tlbhi) \
+asm volatile ("tlbwehi %0, %1" : : "r" (tlbhi), "r" (entry) : "memory")
+
+/// TLBWELO
+#define tlbwelo(entry, tlblo) \
+asm volatile ("tlbwelo %0, %1" : : "r" (tlblo), "r" (entry) : "memory")
+
+/// TLBREHI
+#define tlbrehi(entry) \
+ ({ \
+ uint32_t __tlbhi; \
+ asm volatile ("tlbrehi %0, %1" : "=r" (__tlbhi) : "r" (entry)); \
+ __tlbhi;})
+
+/// TLBRELO
+#define tlbrelo(entry) \
+ ({ \
+ uint32_t __tlblo; \
+ asm volatile ("tlbrelo %0, %1" : "=r" (__tlblo) : "r" (entry)); \
+ __tlblo;})
+
+/// TLBSX
+///
+/// Returns 1 if the address is mapped, else 0. If positive the integer
+/// pointed to by \a entry is updated with the TLB index of the matching
+/// entry, otherwise the return value is undefined.
+#define tlbsx(address, entry) \
+ ({ \
+ uint32_t __cr, __entry; \
+ asm volatile ("tlbsx. %0, 0, %2; mfcr %1" : \
+ "=r" (__entry), "=r" (__cr) : "r" (address)); \
+ *(entry) = __entry; \
+ ((__cr & CR_EQ(0)) != 0);})
+
+
+int
+ppc405_mmu_reset(void);
+
+int
+ppc405_mmu_map(SsxAddress effective_address,
+ SsxAddress real_address,
+ size_t size, int tlbhi_flags, int tlblo_flags,
+ Ppc405MmuMap *map);
+
+int
+ppc405_mmu_unmap(Ppc405MmuMap *map);
+
+void
+ppc405_mmu_start(void);
+
+void
+ppc405_mmu_report(FILE* stream, Ppc405MmuMap* map);
+
+#endif /* __ASSEMBLER__ */
+
+
+#endif /* __PPC405_MMU_H__ */
diff --git a/src/ssx/ppc405/ppc405_mmu_asm.S b/src/ssx/ppc405/ppc405_mmu_asm.S
new file mode 100755
index 0000000..1118779
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_mmu_asm.S
@@ -0,0 +1,73 @@
+// $Id: ppc405_mmu_asm.S,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_mmu_asm.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_mmu_asm.S
+/// \brief Assembler support for PPC405 MMU operations
+///
+/// Currently the only API in this file - ppc405_mmu_start() - is likely an
+/// initialization-only API that could be removed from the run-time image.
+
+ .nolist
+#include "ssx.h"
+ .list
+
+/// Start MMU mode on the PPC405
+///
+/// This API enables PPC405 address translation of the type supported by SSX -
+/// simple 1 to 1 effective - real translation for the purpose of
+/// protection. It is coded in assembler to ensure that this transition is
+/// done as cache-safely as generically possible. The API enters a critical
+/// section and flushes the data cache and invalidates the I-cache, then
+/// enables the translation modes specifed by PPC405_RELOCATION_MODE.
+/// Following is a final invalidation of the I-cache.
+///
+/// \cond
+
+ .global_function ppc405_mmu_start
+ppc405_mmu_start:
+
+ ## Create and link a stack frame
+
+ stwu %r1, -16(%r1)
+ mflr %r0
+ stw %r0, 20(%r1)
+
+ ## Enter critical section, save original MSR in R31
+
+ stw %r31, 8(%r1)
+ _ssx_critical_section_enter SSX_CRITICAL, %r31, %r4
+
+ ## Flush D-cache, Invalidate I-Cache
+
+ bl dcache_flush_all
+ bl icache_invalidate_all
+
+ ## Enter translation mode on original MSR (removing critical section)
+
+ _liw %r3, 1f
+ mtsrr0 %r3
+ _liwa %r3, PPC405_RELOCATION_MODE
+ or %r3, %r31, %r3
+ mtsrr1 %r3
+ rfi
+1:
+ ## Invalidate I-cache again
+
+ bl icache_invalidate_all
+
+ ## Restore R31, Unwind stack and return
+
+ lwz %r31, 8(%r1)
+ lwz %r0, 20(%r1)
+ mtlr %r0
+ addi %r1, %r1, 16
+ blr
+
+ .epilogue ppc405_mmu_start
+
+/// \endcond
diff --git a/src/ssx/ppc405/ppc405_msr.h b/src/ssx/ppc405/ppc405_msr.h
new file mode 100755
index 0000000..645a052
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_msr.h
@@ -0,0 +1,85 @@
+#ifndef __PPC405_MSR_H__
+#define __PPC405_MSR_H__
+
+// $Id: ppc405_msr.h,v 1.1.1.1 2013/12/11 21:03:26 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_msr.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_msr.h
+/// \brief Everything related to the PPC405 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_AP 0x02000000 /* APU Available */
+#define MSR_APE 0x00080000 /* APU Exception Enable */
+#define MSR_WE 0x00040000 /* Wait State Enable */
+#define MSR_CE 0x00020000 /* Critical Interrupt Enable */
+#define MSR_EE 0x00008000 /* External Interrupt Enable */
+#define MSR_PR 0x00004000 /* Problem State */
+#define MSR_ME 0x00001000 /* Machine Check Exception Enable */
+#define MSR_FE0 0x00000800 /* Floating-Point Exception Mode 0 */
+#define MSR_DWE 0x00000400 /* Debug Wait Enable */
+#define MSR_DE 0x00000200 /* Debug Interrupt Enable */
+#define MSR_IR 0x00000020 /* Instruction Relocation */
+#define MSR_DR 0x00000010 /* Data Relocation */
+
+#define MSR_CE_BIT 14
+#define MSR_EE_BIT 16
+#define MSR_IR_BIT 26
+#define MSR_DR_BIT 27
+
+#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; isync" : : "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; isync" : : "i" (i) : "memory")
+
+
+/// Write MSR[EE] from the EE bit of another MSR
+
+#define wrtee(other_msr) \
+ asm volatile ("wrtee %0; isync" : : "r" (other_msr) : "memory")
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPC405_MSR_H__ */
diff --git a/src/ssx/ppc405/ppc405_spr.h b/src/ssx/ppc405/ppc405_spr.h
new file mode 100755
index 0000000..ede91cb
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_spr.h
@@ -0,0 +1,319 @@
+#ifndef __PPC405_SPR_H__
+#define __PPC405_SPR_H__
+
+// $Id: ppc405_spr.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_spr.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ppc405_spr.h
+/// \brief Everything related to PPC405-specific SPRs
+
+/// \defgroup ppc405_sprs PowerPC 405 SPRs
+///
+/// These are the documented SPRs of the PPC405. 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_CCR0 0x3b3 /// Core configuration register 0
+#define SPRN_CCR1 0x378 /// Core configuration register 1
+#define SPRN_CTR 0x009 /// Count register
+#define SPRN_DAC1 0x3f6 /// Data address compare 1
+#define SPRN_DAC2 0x3f7 /// Data address compare 2
+#define SPRN_DBCR0 0x3f2 /// Debug control register 0
+#define SPRN_DBCR1 0x3bd /// Debug control register 1
+#define SPRN_DBSR 0x3f0 /// Debug status register
+#define SPRN_DCCR 0x3fa /// Data cacheability (real mode)
+#define SPRN_DCWR 0x3ba /// Data cache writeback (real mode)
+#define SPRN_DEAR 0x3d5 /// Data exception address register
+#define SPRN_DVC1 0x3b6 /// Data value compare 1
+#define SPRN_DVC2 0x3b7 /// Data value compare 2
+#define SPRN_ESR 0x3d4 /// Exception syndrome register
+#define SPRN_EVPR 0x3d6 /// Exception. vec. prefix reg.
+#define SPRN_IAC1 0x3f4 /// Instruction address compare 1
+#define SPRN_IAC2 0x3f5 /// Instruction address compare 2
+#define SPRN_IAC3 0x3b4 /// Instruction address compare 3
+#define SPRN_IAC4 0x3b5 /// Instruction address compare 4
+#define SPRN_ICCR 0x3fb /// Instruction cache. (real mode)
+#define SPRN_ICDBDR 0x3d3 /// Instruction cache debug data reg.
+#define SPRN_LR 0x008 /// Link register
+#define SPRN_MCSR 0x23c /// Machine check syndrome register
+#define SPRN_PID 0x3b1 /// Process ID
+#define SPRN_PIT 0x3db /// Programmable interrupt timer
+#define SPRN_PVR 0x11f /// Processor version register
+#define SPRN_SGR 0x3b9 /// Storage guarded (real mode)
+#define SPRN_SLER 0x3bb /// Storage little-endian (real mode)
+#define SPRN_SPRG0 0x110 /// SPR general register 0
+#define SPRN_SPRG1 0x111 /// SPR general register 1
+#define SPRN_SPRG2 0x112 /// SPR general register 2
+#define SPRN_SPRG3 0x113 /// SPR general register 3
+#define SPRN_SPRG4 0x114 /// SPR general register 4 [SPRG4_W]
+#define SPRN_SPRG5 0x115 /// SPR general register 5 [SPRG5_W]
+#define SPRN_SPRG6 0x116 /// SPR general register 6 [SPRG6_W]
+#define SPRN_SPRG7 0x117 /// SPR general register 7 [SPRG7_W]
+#define SPRN_SRR0 0x01a /// Save/restore register 0
+#define SPRN_SRR1 0x01b /// Save/restore register 1
+#define SPRN_SRR2 0x3de /// Save/restore register 2
+#define SPRN_SRR3 0x3df /// Save/restore register 3
+#define SPRN_SU0R 0x3bc /// Storage user 0 (real mode)
+#define SPRN_TBL 0x11c /// Time base lower [TBL_W]
+#define SPRN_TBU 0x11d /// Time base upper [TBU_W]
+#define SPRN_TCR 0x3da /// Timer control register
+#define SPRN_TSR 0x3d8 /// Timer status register
+#define SPRN_USPRG0 0x100 /// User read/write SPR general 0
+#define SPRN_XER 0x001 /// Fixed-point exception register
+#define SPRN_ZPR 0x3b0 /// Zone protection register
+#define SPRN_UR_SPRG4 0x104 /// User-readable SPRG4 [SPRG4_R]
+#define SPRN_UR_SPRG5 0x105 /// User-readable SPRG5 [SPRG5_R]
+#define SPRN_UR_SPRG6 0x106 /// User-readable SPRG6 [SPRG6_R]
+#define SPRN_UR_SPRG7 0x107 /// User-readable SPRG7 [SPRG7_R]
+#define SPRN_UR_TBL 0x10c /// User-readable TBL [TBL, TBL_R]
+#define SPRN_UR_TBU 0x10d /// User-readable TBU [TBU, TBU_R]
+
+/// @}
+
+/// \defgroup ppc405_undocumented_sprs PowerPC 405 Undocumented SPRs
+///
+/// These are undocumented SPRs related to RISCWatch and debugging. These
+/// registers are also available in RISCWatch/eCMD.
+///
+/// - DBDR is a scratch register used by RISCwatch when "RAM-ing" data in/out of
+/// the core. This register can be read and written.
+///
+/// - DBSRS and TSRS are "hidden" registers connected to DBSR and TSR
+/// respectively. These are write-only registers. When written, any 1 bits in
+/// the write data are OR-ed into the DBSR and TSR respectively, as a way to
+/// force status bits and cause interrupts.
+///
+/// @{
+
+#define SPRN_DBDR 0x3f3 /// Debug data register 0x3f3 */
+#define SPRN_DBSRS 0x3f1 /// Debug status register set 0x3f1 */
+#define SPRN_TSRS 0x3d9 /// Timer status register set 0x3d9 */
+
+/// @}
+
+/* CCR0 - Cache Control Register 0 */
+
+#define CCR0_LWL 0x02000000 /* Load Word as Line */
+#define CCR0_LWOA 0x01000000 /* Load Without Allocate */
+#define CCR0_SWOA 0x00800000 /* Store Without Allocate */
+#define CCR0_DPP1 0x00400000 /* DCU PLB Priority Bit 1 */
+#define CCR0_IPP0 0x00200000 /* ICU PLB Priority Bit 0 */
+#define CCR0_IPP1 0x00100000 /* ICU PLB Priority Bit 1 */
+#define CCR0_DPE 0x00080000 /* Data Cache Parity Enable */
+#define CCR0_DPP 0x00040000 /* DCU Parity is Precise (0/1) */
+#define CCR0_U0XE 0x00020000 /* Enable U0 Exception */
+#define CCR0_LDBE 0x00010000 /* Load Debug Enable */
+#define CCR0_IPE 0x00002000 /* Instruction Cache Parity Enable */
+#define CCR0_TPE 0x00001000 /* TLB Parity Enable */
+#define CCR0_PFC 0x00000800 /* ICU Prefetching for Cacheable Regions */
+#define CCR0_PFNC 0x00000400 /* ICU Prefetching for Non-Cacheable Regions */
+#define CCR0_NCRS 0x00000200 /* Non-Cacheable ICU request is 16(0)/32(1)B */
+#define CCR0_FWOA 0x00000100 /* Fetch Without Allocate */
+#define CCR0_CIS 0x00000010 /* Cache Information Select Data(0)/Tag(1) */
+#define CCR0_PRS 0x00000008 /* Parity Read Select */
+#define CCR0_CWS 0x00000001 /* Cache Way Select A(0)/B(1) */
+
+/* CCR1 - Cache Control Register 1 */
+
+#define CCR1_ICTE 0x80000000 /* Instruction Cache Tag Parity Insertion */
+#define CCR1_ICDE 0x40000000 /* Instruction Cache Data Parity Insertion */
+#define CCR1_DCTE 0x20000000 /* Data Cache Tag Parity Insertion */
+#define CCR1_DCDE 0x10000000 /* Data Cache Data Parity Insertion */
+#define CCR1_TLBE 0x08000000 /* TLB Parity Insertion */
+
+/* DBCR0 - Debug Control Register 0 */
+
+#define DBCR0_EDM 0x80000000 /* External Debug Mode */
+#define DBCR0_IDM 0x40000000 /* Internal Debug Mode */
+#define DBCR0_RST_MASK 0x30000000 /* ReSeT */
+#define DBCR0_RST_NONE 0x00000000 /* No action */
+#define DBCR0_RST_CORE 0x10000000 /* Core reset */
+#define DBCR0_RST_CHIP 0x20000000 /* Chip reset */
+#define DBCR0_RST_SYSTEM 0x30000000 /* System reset */
+#define DBCR0_IC 0x08000000 /* Instruction Completion debug event */
+#define DBCR0_BT 0x04000000 /* Branch Taken debug event */
+#define DBCR0_EDE 0x02000000 /* Exception Debug Event */
+#define DBCR0_TDE 0x01000000 /* Trap Debug Event */
+#define DBCR0_IA1 0x00800000 /* IAC (Instruction Address Compare) 1 debug event */
+#define DBCR0_IA2 0x00400000 /* IAC 2 debug event */
+#define DBCR0_IA12 0x00200000 /* Instruction Address Range Compare 1-2 */
+#define DBCR0_IA12X 0x00100000 /* IA12 eXclusive */
+#define DBCR0_IA3 0x00080000 /* IAC 3 debug event */
+#define DBCR0_IA4 0x00040000 /* IAC 4 debug event */
+#define DBCR0_IA34 0x00020000 /* Instruction Address Range Compare 3-4 */
+#define DBCR0_IA34X 0x00010000 /* IA34 eXclusive */
+#define DBCR0_IA12T 0x00008000 /* Instruction Address Range Compare 1-2 range Toggle */
+#define DBCR0_IA34T 0x00004000 /* Instruction Address Range Compare 3-4 range Toggle */
+#define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */
+
+/* DBSR - Debug Status Register */
+
+#define DBSR_IC 0x80000000 /* Instruction completion debug event */
+#define DBSR_BT 0x40000000 /* Branch Taken debug event */
+#define DBSR_EDE 0x20000000 /* Exception debug event */
+#define DBSR_TIE 0x10000000 /* Trap Instruction debug event */
+#define DBSR_UDE 0x08000000 /* Unconditional debug event */
+#define DBSR_IA1 0x04000000 /* IAC1 debug event */
+#define DBSR_IA2 0x02000000 /* IAC2 debug event */
+#define DBSR_DR1 0x01000000 /* DAC1 Read debug event */
+#define DBSR_DW1 0x00800000 /* DAC1 Write debug event */
+#define DBSR_DR2 0x00400000 /* DAC2 Read debug event */
+#define DBSR_DW2 0x00200000 /* DAC2 Write debug event */
+#define DBSR_IDE 0x00100000 /* Imprecise debug event */
+#define DBSR_IA3 0x00080000 /* IAC3 debug event */
+#define DBSR_IA4 0x00040000 /* IAC4 debug event */
+#define DBSR_MRR 0x00000300 /* Most recent reset */
+
+/* TCR - Timer Control Register */
+
+#define TCR_WP_MASK 0xc0000000 /* Watchdog Period mask */
+#define TCR_WP_2_17 0x00000000 /* 2**17 clocks */
+#define TCR_WP_2_21 0x40000000 /* 2**21 clocks */
+#define TCR_WP_2_25 0x80000000 /* 2**25 clocks */
+#define TCR_WP_2_29 0xc0000000 /* 2**29 clocks */
+#define TCR_WRC_MASK 0x30000000 /* Watchdog Reset Control mask */
+#define TCR_WRC_NONE 0x00000000 /* No watchdog reset */
+#define TCR_WRC_CORE 0x10000000 /* Core reset */
+#define TCR_WRC_CHIP 0x20000000 /* Chip reset */
+#define TCR_WRC_SYSTEM 0x30000000 /* System reset */
+#define TCR_WIE 0x08000000 /* Watchdog Interrupt Enable */
+#define TCR_PIE 0x04000000 /* PIT Interrupt Enable */
+#define TCR_FP_MASK 0x03000000 /* FIT Period */
+#define TCR_FP_2_9 0x00000000 /* 2**9 clocks */
+#define TCR_FP_2_13 0x01000000 /* 2**13 clocks */
+#define TCR_FP_2_17 0x02000000 /* 2**17 clocks */
+#define TCR_FP_2_21 0x03000000 /* 2**21 clocks */
+#define TCR_FIE 0x00800000 /* FIT Interrupt Enable */
+#define TCR_ARE 0x00400000 /* Auto-reload Enable */
+
+#ifndef __ASSEMBLER__
+
+typedef union {
+ uint32_t value;
+ struct {
+ unsigned int wp : 2;
+ unsigned int wrc : 2;
+ unsigned int wie : 1;
+ unsigned int pie : 1;
+ unsigned int fp : 2;
+ unsigned int fie : 1;
+ unsigned int are : 1;
+ unsigned int reserved : 22;
+ } fields;
+} Ppc405TCR;
+
+#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_CORE 0x10000000 /* Core reset was forced by the watchdog */
+#define TSR_WRS_CHIP 0x20000000 /* Chip reset was forced by the watchdog */
+#define TSR_WRS_SYSTEM 0x30000000 /* System reset was forced by the watchdog */
+#define TSR_PIS 0x08000000 /* PIT Interrupt Status */
+#define TSR_FIS 0x04000000 /* FIT Interrupt Status */
+
+#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))
+
+
+/// Move From Time Base (Lower)
+
+#define mftb() mfspr(SPRN_TBL)
+
+/// Move To Time Base (Lower)
+
+#define mttbl(x) mtspr(SPRN_TBL, (x))
+
+/// Move From Time Base (Upper)
+
+#define mftbu() mfspr(SPRN_TBU)
+
+/// Move To Time Base (UPPER)
+
+#define mttbu(x) mtspr(SPRN_TBU, (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 ccr0, SPRN_CCR0
+ _sprinstrs ccr1, SPRN_CCR1
+ _sprinstrs dbcr0, SPRN_DBCR0
+ _sprinstrs dbcr1, SPRN_DBCR1
+ _sprinstrs dcwr, SPRN_DCWR
+ _sprinstrs mcsr, SPRN_MCSR
+ _sprinstrs pid, SPRN_PID
+ _sprinstrs sgr, SPRN_SGR
+ _sprinstrs sler, SPRN_SLER
+ _sprinstrs su0r, SPRN_SU0R
+ _sprinstrs usprg0, SPRN_USPRG0
+
+ /// \endcond
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PPC405_SPR_H__ */
diff --git a/src/ssx/ppc405/ppc405_thread_init.S b/src/ssx/ppc405/ppc405_thread_init.S
new file mode 100755
index 0000000..47f5813
--- /dev/null
+++ b/src/ssx/ppc405/ppc405_thread_init.S
@@ -0,0 +1,126 @@
+// $Id: ppc405_thread_init.S,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+
+/// \file ppc405_thread_init.S
+/// \brief PPC405-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 "ssx.h"
+ .list
+
+/// \fn void __ssx_thread_context_initialize(SsxThread *thread, SsxThreadRoutine 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
+/// ssx_complete().
+#ifdef DOXYGEN_ONLY
+void
+__ssx_thread_context_initialize(SsxThread *thread,
+ SsxThreadRoutine thread_routine,
+ void *private);
+#endif// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_thread_init.S,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \cond
+
+ .global_function __ssx_thread_context_initialize
+
+__ssx_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 a fast context on the thread stack. The CR is cleared,
+ ## the LR = ssx_complete(), R3 has the private parameter.
+
+ lwz %r6, SSX_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
+
+ stwu %r6, -SSX_FAST_CTX_SIZE(%r6)
+
+ li %r7, 0
+ stw %r7, SSX_FAST_CTX_CR(%r6)
+
+ _liw %r7, ssx_complete
+ stw %r7, SSX_FAST_CTX_LR(%r6)
+
+ stw %r5, SSX_FAST_CTX_GPR3(%r6)
+
+ _gpr_init SSX_FAST_CTX_GPR, 4, 0x0404
+ _gpr_init SSX_FAST_CTX_GPR, 5, 0x0505
+ _gpr_init SSX_FAST_CTX_GPR, 6, 0x0606
+ _gpr_init SSX_FAST_CTX_GPR, 7, 0x0707
+
+ ## Initialize the (volatile - fast) context on the thread stack. XER
+ ## and CTR are clear, SRR0 = thread_routine, SRR1 = default machine
+ ## context.
+
+ stwu %r6, -SSX_VOL_FAST_CTX_SIZE(%r6)
+
+ li %r7, 0
+ stw %r7, SSX_VOL_FAST_CTX_XER(%r6)
+ stw %r7, SSX_VOL_FAST_CTX_CTR(%r6)
+
+ stw %r4, SSX_VOL_FAST_CTX_SRR0(%r6)
+
+ _lwzsd %r7, __ssx_thread_machine_context_default
+ stw %r7, SSX_VOL_FAST_CTX_SRR1(%r6)
+
+ _gpr_init SSX_VOL_FAST_CTX_GPR, 0, 0x0000
+ _gpr_init SSX_VOL_FAST_CTX_GPR, 8, 0x0808
+ _gpr_init SSX_VOL_FAST_CTX_GPR, 9, 0x0909
+ _gpr_init SSX_VOL_FAST_CTX_GPR, 10, 0x1010
+ _gpr_init SSX_VOL_FAST_CTX_GPR, 11 0x1111
+ _gpr_init SSX_VOL_FAST_CTX_GPR, 12 0x1212
+
+ ## Initialize the non-volatile context on the thread stack.
+
+ stwu %r6, -SSX_NON_VOL_CTX_SIZE(%r6)
+
+ _gpr_init SSX_NON_VOL_CTX_GPR, 14, 0x1414
+ _gpr_init SSX_NON_VOL_CTX_GPR, 15, 0x1515
+ _gpr_init SSX_NON_VOL_CTX_GPR, 16, 0x1616
+ _gpr_init SSX_NON_VOL_CTX_GPR, 17, 0x1717
+ _gpr_init SSX_NON_VOL_CTX_GPR, 18, 0x1818
+ _gpr_init SSX_NON_VOL_CTX_GPR, 19, 0x1919
+ _gpr_init SSX_NON_VOL_CTX_GPR, 20, 0x2020
+ _gpr_init SSX_NON_VOL_CTX_GPR, 21, 0x2121
+ _gpr_init SSX_NON_VOL_CTX_GPR, 22, 0x2222
+ _gpr_init SSX_NON_VOL_CTX_GPR, 23, 0x2323
+ _gpr_init SSX_NON_VOL_CTX_GPR, 24, 0x2424
+ _gpr_init SSX_NON_VOL_CTX_GPR, 25, 0x2525
+ _gpr_init SSX_NON_VOL_CTX_GPR, 26, 0x2626
+ _gpr_init SSX_NON_VOL_CTX_GPR, 27, 0x2727
+ _gpr_init SSX_NON_VOL_CTX_GPR, 28, 0x2828
+ _gpr_init SSX_NON_VOL_CTX_GPR, 29, 0x2929
+ _gpr_init SSX_NON_VOL_CTX_GPR, 30, 0x3030
+ _gpr_init SSX_NON_VOL_CTX_GPR, 31, 0x3131
+
+ ## Initialization is done - the stack pointer is stored back in the
+ ## thread.
+
+ stw %r6, SSX_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
+ blr
+
+ .epilogue __ssx_thread_context_initialize
+
+/// \endcond
diff --git a/src/ssx/ppc405/ssx_port_types.h b/src/ssx/ppc405/ssx_port_types.h
new file mode 100755
index 0000000..f57951d
--- /dev/null
+++ b/src/ssx/ppc405/ssx_port_types.h
@@ -0,0 +1,44 @@
+#ifndef __SSX_PORT_TYPES_H__
+#define __SSX_PORT_TYPES_H__
+
+// $Id: ssx_port_types.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ssx_port_types.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_port_types.h
+/// \brief Type definitions required by the SSX port.
+///
+/// \todo GCC provides a portable version of cntlzw called __builtin_clz().
+/// We should make the SSX 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 SSX/port/chip headers are included.
+
+/// An SsxIrqId is an integer in the range of valid interrupts defined by the
+/// interrupt controller.
+
+typedef uint8_t SsxIrqId;
+
+/// SSX requires the port to define the type SsxThreadQueue, which is a
+/// priority queue (where 0 is the highest priority). This queue must be able
+/// to handle SSX_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 SSX_THREADS if
+/// the queue is empty. (Or a queue could be initialized with the SSX_THREADS
+/// entry always present - SSX 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 PPC405 with 32 threads (implied), this is a job for a uint32_t and
+/// cntlzw().
+
+typedef uint32_t SsxThreadQueue;
+
+#endif /* __SSX_PORT_TYPES_H__ */
diff --git a/src/ssx/ppc405/ssxppc405files.mk b/src/ssx/ppc405/ssxppc405files.mk
new file mode 100755
index 0000000..72d5ecb
--- /dev/null
+++ b/src/ssx/ppc405/ssxppc405files.mk
@@ -0,0 +1,53 @@
+# $Id: ssxppc405files.mk,v 1.2 2014/06/26 13:00:55 cmolsen Exp $
+# $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ssxppc405files.mk,v $
+# @file ssxppc405files.mk
+#
+# @brief mk for including ppc405 object files
+#
+# @page ChangeLogs Change Logs
+# @section ssxppc405files.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+# @pb00E pbavari 03/11/2012 Makefile ODE support
+#
+# @endverbatim
+#
+##########################################################################
+# Include Files
+##########################################################################
+
+
+
+##########################################################################
+# Object Files
+##########################################################################
+PPC405-C-SOURCES = ppc405_core.c \
+ ppc405_lib_core.c \
+ ppc405_cache_core.c \
+ ppc405_init.c \
+ ppc405_irq_core.c \
+ ppc405_irq_init.c
+
+PPC405-S-SOURCES = ppc405_boot.S \
+ ppc405_exceptions.S \
+ ppc405_cache_init.S \
+ ppc405_mmu_asm.S \
+ ppc405_breakpoint.S
+
+PPC405-TIMER-C-SOURCES =
+PPC405-TIMER-S-SOURCES =
+
+PPC405-THREAD-C-SOURCES +=
+PPC405-THREAD-S-SOURCES += ppc405_thread_init.S
+
+PPC405-MMU-C-SOURCES += ppc405_mmu.c
+PPC405-MMU-S-SOURCES +=
+
+PPC405_OBJECTS += $(PPC405-C-SOURCES:.c=.o) $(PPC405-S-SOURCES:.S=.o)
+
+
+
diff --git a/src/ssx/ssx/Makefile b/src/ssx/ssx/Makefile
new file mode 100755
index 0000000..ce1116f
--- /dev/null
+++ b/src/ssx/ssx/Makefile
@@ -0,0 +1,25 @@
+# $Id: Makefile,v 1.2 2013/12/12 16:12:38 bcbrock Exp $
+
+# This Makefile is designed to be invoked with the -I argument set to
+# the location of the "ssx.mk" for the build
+
+include ../pgp/ssx.mk
+include ssxssxfiles.mk
+
+ifeq "$(SSX_TIMER_SUPPORT)" "1"
+SSX_OBJECTS += ${SSX-TIMER-C-SOURCES:.c=.o}
+endif
+
+ifeq "$(SSX_THREAD_SUPPORT)" "1"
+SSX_OBJECTS += ${SSX-THREAD-C-SOURCES:.c=.o}
+endif
+
+all: $(SSX_OBJECTS)
+
+.PHONY : clean
+clean:
+ rm -f *.o *.d *.d.*
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(SSX_OBJECTS:.o=.d)
+endif
diff --git a/src/ssx/ssx/ssx.h b/src/ssx/ssx/ssx.h
new file mode 100755
index 0000000..5470968
--- /dev/null
+++ b/src/ssx/ssx/ssx.h
@@ -0,0 +1,126 @@
+#ifndef __SSX_H__
+#define __SSX_H__
+
+// $Id: ssx.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx.h
+/// \brief The combined header of the SSX kernel.
+///
+/// This header will be included in any C or assembler source file that
+/// requires any of the SSX API. All headers defined by SSX 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__ */
+
+#define __SSX__
+
+/// The application environment specifies whether or not it will provide an
+/// application configuration file, which must be named "ssx_app_cfg.h".
+
+#ifndef USE_SSX_APP_CFG_H
+#define USE_SSX_APP_CFG_H 0
+#endif
+
+#if USE_SSX_APP_CFG_H
+#include "ssx_app_cfg.h"
+#endif
+
+#include "ssx_macros.h"
+#include "ssx_api.h"
+#include "ssx_port.h"
+#include "ssx_kernel.h"
+#include "ssx_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, SsxIrqId irq, int priority)
+/// {
+/// SSX_PANIC(VALIDATION_CHECKSTOP);
+/// }
+///
+/// SSX_IRQ_FAST2FULL(_validationCheckstopHandler, _checkstop);
+///
+/// \endcode
+#define USED_ATTRIBUTE __attribute__ ((used))
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __SSX_H__ */
diff --git a/src/ssx/ssx/ssx_api.h b/src/ssx/ssx/ssx_api.h
new file mode 100755
index 0000000..c9657e4
--- /dev/null
+++ b/src/ssx/ssx/ssx_api.h
@@ -0,0 +1,888 @@
+#ifndef __SSX_API_H__
+#define __SSX_API_H__
+
+// $Id: ssx_api.h,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_api.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_api.h
+/// \brief Macros and declarations for the SSX API.
+
+// Basic constants
+
+/// Although the number of threads is defined as a manifest constant,
+/// numerous parts of the SSX code assume this definition. The number of
+/// supported threads _can not_ be changed simply by changing this constant.
+
+#define SSX_THREADS 32
+
+#define SSX_IDLE_THREAD_PRIORITY SSX_THREADS
+
+// Interrupt API
+
+#define SSX_NONCRITICAL 0
+#define SSX_CRITICAL 1
+#define SSX_SUPERCRITICAL 2
+
+#define SSX_IRQ_POLARITY_ACTIVE_LOW 0
+#define SSX_IRQ_POLARITY_ACTIVE_HIGH 1
+
+#define SSX_IRQ_TRIGGER_LEVEL_SENSITIVE 0
+#define SSX_IRQ_TRIGGER_EDGE_SENSITIVE 1
+
+// API return codes
+
+#define SSX_OK 0
+#define SSX_ILLEGAL_CONTEXT_CRITICAL_INTERRUPT 0x00779001
+#define SSX_ILLEGAL_CONTEXT_THREAD_CONTEXT 0x00779002
+#define SSX_ILLEGAL_CONTEXT_INTERRUPT_CONTEXT 0x00779003
+#define SSX_ILLEGAL_CONTEXT_THREAD 0x00779004
+#define SSX_ILLEGAL_CONTEXT_TIMER 0x00779005
+#define SSX_ILLEGAL_CONTEXT_PPC405_CACHE 0x00779006
+#define SSX_INVALID_THREAD_AT_RESUME1 0x00779007
+#define SSX_INVALID_THREAD_AT_RESUME2 0x00779008
+#define SSX_INVALID_THREAD_AT_SUSPEND1 0x00779009
+#define SSX_INVALID_THREAD_AT_SUSPEND2 0x0077900a
+#define SSX_INVALID_THREAD_AT_DELETE 0x0077900b
+#define SSX_INVALID_THREAD_AT_INFO 0x0077900c
+#define SSX_INVALID_THREAD_AT_CHANGE 0x0077900d
+#define SSX_INVALID_THREAD_AT_SWAP1 0x0077900e
+#define SSX_INVALID_THREAD_AT_SWAP2 0x0077900f
+#define SSX_INVALID_THREAD_AT_CREATE 0x00779010
+#define SSX_INVALID_SEMAPHORE_AT_POST 0x00779011
+#define SSX_INVALID_SEMAPHORE_AT_PEND 0x00779012
+#define SSX_INVALID_SEMAPHORE_AT_RELEASE 0x00779013
+#define SSX_INVALID_SEMAPHORE_AT_INFO 0x00779014
+#define SSX_INVALID_SEMAPHORE_AT_CREATE 0x00779015
+#define SSX_INVALID_TIMER_AT_SCHEDULE 0x00779016
+#define SSX_INVALID_TIMER_AT_CANCEL 0x00779017
+#define SSX_INVALID_TIMER_AT_INFO 0x00779018
+#define SSX_INVALID_TIMER_AT_CREATE 0x00779019
+#define SSX_INVALID_ARGUMENT_IRQ_SETUP 0x0077901a
+#define SSX_INVALID_ARGUMENT_IRQ_HANDLER 0x0077901b
+#define SSX_INVALID_ARGUMENT_INTERRUPT 0x00779024
+#define SSX_INVALID_ARGUMENT_CONTEXT_SET 0x00779025
+#define SSX_INVALID_ARGUMENT_CONTEXT_GET 0x00779026
+#define SSX_INVALID_ARGUMENT_PPC405_FIT 0x00779027
+#define SSX_INVALID_ARGUMENT_PPC405_WATCHDOG 0x00779028
+#define SSX_INVALID_ARGUMENT_INIT 0x00779029
+#define SSX_INVALID_ARGUMENT_SEMAPHORE 0x0077902a
+#define SSX_INVALID_ARGUMENT_THREAD_CHANGE 0x0077902b
+#define SSX_INVALID_ARGUMENT_THREAD_PRIORITY 0x0077902c
+#define SSX_INVALID_ARGUMENT_THREAD1 0x0077902d
+#define SSX_INVALID_ARGUMENT_THREAD2 0x0077902e
+#define SSX_INVALID_ARGUMENT_THREAD3 0x0077902f
+#define SSX_STACK_OVERFLOW 0x00779030
+#define SSX_TIMER_ACTIVE 0x00779031
+#define SSX_TIMER_NOT_ACTIVE 0x00779032
+#define SSX_PRIORITY_IN_USE_AT_RESUME 0x00779033
+#define SSX_PRIORITY_IN_USE_AT_CHANGE 0x00779034
+#define SSX_PRIORITY_IN_USE_AT_SWAP 0x00779035
+#define SSX_SEMAPHORE_OVERFLOW 0x00779036
+#define SSX_SEMAPHORE_PEND_NO_WAIT 0x00779037
+#define SSX_SEMAPHORE_PEND_TIMED_OUT 0x00779038
+#define SSX_SEMAPHORE_PEND_WOULD_BLOCK 0x00779039
+#define SSX_INVALID_DEQUE_SENTINEL 0x0077903a
+#define SSX_INVALID_DEQUE_ELEMENT 0x0077903b
+#define SSX_INVALID_OBJECT 0x0077903c
+
+// Kernel panics
+
+#define SSX_NO_TIMER_SUPPORT 0x0077903d
+#define SSX_START_THREADS_RETURNED 0x0077903e
+#define SSX_UNIMPLEMENTED 0x0077903f
+#define SSX_SCHEDULING_INVARIANT 0x00779040
+#define SSX_TIMER_HANDLER_INVARIANT 0x00779041
+#define SSX_THREAD_TIMEOUT_STATE 0x00779045
+
+
+/// \defgroup ssx_thread_states SSX Thread States
+///
+/// Threads are created in the state SSX_THREAD_STATE_SUSPENDED_RUNNABLE.
+/// When the thread is mapped it transitions to state SSX_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 SSX_THREAD_STATE_SUSPENDED_BLOCKED. For
+/// all threads the reason for blockage is detailed in the \a flags field of
+/// the thread; See \ref ssx_thread_flags. SSX_THREAD_STATE_DELETED and
+/// SSX_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 SSX semaphore as a thread barrier, as it supports a non-iterative
+/// implementation of ssx_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 SSX_THREAD_STATE_SUSPENDED_RUNNABLE 1
+#define SSX_THREAD_STATE_MAPPED 2
+#define SSX_THREAD_STATE_SUSPENDED_BLOCKED 3
+#define SSX_THREAD_STATE_COMPLETED 4
+#define SSX_THREAD_STATE_DELETED 5
+
+/// @}
+
+
+/// \defgroup ssx_thread_flags SSX Thread Flags
+///
+/// The \a flag field of the thread extends the information contained in the
+/// \a state field; See \ref ssx_thread_states. Blocked threads will show
+/// SSX_THREAD_FLAG_SEMAPHORE_PEND, SSX_THREAD_FLAG_TIMER_PEND or both (if
+/// blocked on a semaphore with timeout). The flag SSX_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 SSX_THREAD_FLAG_SEMAPHORE_PEND and/or SSX_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
+/// ssx_semaphore_release_all() as explained in \ref ssx_thread_states.
+///
+/// @{
+
+#define SSX_THREAD_FLAG_SEMAPHORE_PEND 0x1
+#define SSX_THREAD_FLAG_TIMER_PEND 0x2
+#define SSX_THREAD_FLAG_TIMED_OUT 0x4
+
+/// @}
+
+
+// Critical Sections
+
+/// Enter a critical section of a given priority, saving the current machine
+/// context.
+
+#define ssx_critical_section_enter(priority, pctx) \
+ ssx_interrupt_disable(priority, pctx)
+
+/// Exit a critical section by restoring the previous machine context.
+
+#define ssx_critical_section_exit(pctx) \
+ ssx_machine_context_set(pctx)
+
+
+/// Execute a statement atomically, in a particular interrupt priority
+/// context.
+
+#define SSX_ATOMIC(priority, stmt) \
+ do { \
+ SsxMachineContext __ctx; \
+ ssx_critical_section_enter((priority), &__ctx); \
+ stmt; \
+ ssx_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 SSX_ERROR_CHECK_API
+#define SSX_ERROR_CHECK_API 1
+#endif
+
+/// Control whether API errors cause kernel panics or return negative error
+/// codes.
+///
+/// This selection is only valid if \c SSX_ERROR_CHECK_API is defined
+/// non-0. This definition can be overriden by the application.
+
+#ifndef SSX_ERROR_PANIC
+#define SSX_ERROR_PANIC 1
+#endif
+
+/// Control whether or not the SSX kernel checks key invariants.
+///
+/// Violations of kernel invariants always cause kernel panics. This
+/// definition can be overriden by the application.
+
+#ifndef SSX_ERROR_CHECK_KERNEL
+#define SSX_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 SsxTimebase. This definition can be
+/// overridden by the application.
+
+#ifndef SSX_TIME_INTERVAL_TYPE
+#define SSX_TIME_INTERVAL_TYPE uint32_t
+#endif
+
+/// Provide support for the SsxTimer APIs in addition to the default
+/// initerrupt APIs. This definition can be overridden by the application.
+
+#ifndef SSX_TIMER_SUPPORT
+#define SSX_TIMER_SUPPORT 1
+#endif
+
+/// Provide support for the all SSX APIs. Thread support requires/implies
+/// support for time services and semaphores. This definition can be
+/// overridden by the application.
+
+#ifndef SSX_THREAD_SUPPORT
+#define SSX_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 ssx_initialize(). Thread stacks are prepatterned during
+/// \c ssx_thread_create().
+///
+/// 2 : (\b Default - Currently Unimplemented) In addition to prepatterning,
+/// stack utilization is computed at the exit of context switches and
+/// noncritical 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 SSX_STACK_CHECK
+#define SSX_STACK_CHECK 1
+#endif
+
+/// A hook for main()
+///
+/// This hook macro is expanded in the body of __ssx_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
+/// ssx_app_cfg.h. The SSX_MAIN_HOOK will run on the stack of main().
+
+#ifndef SSX_MAIN_HOOK
+#define SSX_MAIN_HOOK do {} while (0)
+#endif
+
+/// A hook for ssx_start_threads()
+///
+/// This hook macro is expanded in the call-tree of ssx_start_threads() before
+/// threads are actually started. The application can redefine this hook
+/// macro in (or in headers referred to in) the application header
+/// ssx_app_cfg.h.
+///
+/// The SSX_START_THREADS_HOOK runs as a pseudo-interrupt handler on the
+/// noncritical interrupt stack, with noncritical interrupts disabled.
+
+#ifndef SSX_START_THREADS_HOOK
+#define SSX_START_THREADS_HOOK do {} while (0)
+#endif
+
+/// The maximum value of the \c SsxTimebase type.
+
+#define SSX_TIMEBASE_MAX ((SsxTimebase)-1)
+
+/// A special value that specifies that the timebase will not be reset during
+/// ssx_init().
+
+#define SSX_TIMEBASE_CONTINUES SSX_TIMEBASE_MAX
+
+/// By convention, a timeout value indicating 'no waiting' in a call of \c
+/// ssx_semaphore_pend().
+
+#define SSX_NO_WAIT 0
+
+/// By convention, a timeout value indicating 'wait forever' in a call of \c
+/// ssx_semaphore_pend().
+
+#define SSX_WAIT_FOREVER ((SsxInterval)-1)
+
+/// The SSX timebase frequency in Hz
+///
+/// Earlier version of SSX defined the timbase frequency as a preprocessor
+/// macro. Now, the timebase frequency is specified as a parameter of the
+/// ssx_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 SSX_TIMEBASE_FREQUENCY_HZ __ssx_timebase_frequency_hz
+
+/// Convert a time in integral seconds to a time interval - overflows are
+/// ignored. The application can redefine this macro.
+
+#ifndef SSX_SECONDS
+#define SSX_SECONDS(s) ((SsxInterval)(__ssx_timebase_frequency_hz * (SsxInterval)(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 SSX_MILLISECONDS
+#define SSX_MILLISECONDS(m) ((SsxInterval)(__ssx_timebase_frequency_khz * (SsxInterval)(m)))
+#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 SSX_MICROSECONDS
+#define SSX_MICROSECONDS(u) ((SsxInterval)(__ssx_timebase_frequency_mhz * (SsxInterval)(u)))
+#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 SSX_NANOSECONDS
+#define SSX_NANOSECONDS(n) \
+ ((SsxInterval)((__ssx_timebase_frequency_mhz * (SsxInterval)(n)) / 1000))
+#endif
+
+
+// Application and kernel tracing. Tracing can only be enabled if the port
+// defines the trace macros in that case.
+
+/// Enable SSX application tracing
+#ifndef SSX_TRACE_ENABLE
+#define SSX_TRACE_ENABLE 0
+#endif
+
+/// Enable SSX kernel tracing
+#ifndef SSX_KERNEL_TRACE_ENABLE
+#define SSX_KERNEL_TRACE_ENABLE 0
+#endif
+
+#if !SSX_TRACE_ENABLE
+#define SSX_TRACE(event)
+#endif
+
+#if !SSX_KERNEL_TRACE_ENABLE
+
+#define SSX_TRACE_THREAD_SLEEP(priority)
+#define SSX_TRACE_THREAD_WAKEUP(priority)
+#define SSX_TRACE_THREAD_SEMAPHORE_PEND(priority)
+#define SSX_TRACE_THREAD_SEMAPHORE_POST(priority)
+#define SSX_TRACE_THREAD_SEMAPHORE_TIMEOUT(priority)
+#define SSX_TRACE_THREAD_SUSPENDED(priority)
+#define SSX_TRACE_THREAD_DELETED(priority)
+#define SSX_TRACE_THREAD_COMPLETED(priority)
+#define SSX_TRACE_THREAD_MAPPED_RUNNABLE(priority)
+#define SSX_TRACE_THREAD_MAPPED_SEMAPHORE_PEND(priority)
+#define SSX_TRACE_THREAD_MAPPED_SLEEPING(priority)
+
+
+#endif /* SSX_KERNEL_TRACE_ENABLE */
+
+
+#ifndef __ASSEMBLER__
+
+#include <stddef.h>
+#include <stdint.h>
+
+/// The timebase frequency in Hz; A parameter to ssx_initialize()
+extern uint32_t __ssx_timebase_frequency_hz;
+
+/// The timebase frequency in KHz
+extern uint32_t __ssx_timebase_frequency_khz;
+
+/// The timebase frequency in Mhz
+extern uint32_t __ssx_timebase_frequency_mhz;
+
+
+typedef unsigned long int SsxAddress;
+
+typedef uint8_t SsxThreadState;
+
+typedef uint8_t SsxThreadPriority;
+
+typedef uint8_t SsxThreadFlags;
+
+typedef uint32_t SsxSemaphoreCount;
+
+typedef uint64_t SsxTimebase;
+
+typedef SSX_TIME_INTERVAL_TYPE SsxInterval;
+
+#include "ssx_port_types.h"
+
+typedef struct {
+
+ /// A priority queue of threads pending on the semaphore.
+ SsxThreadQueue pending_threads;
+
+ /// The current semaphore count.
+ SsxSemaphoreCount count;
+
+ /// The maximum allowable count - for error checking.
+ SsxSemaphoreCount max_count;
+
+} SsxSemaphore;
+
+
+/// Compile-time initialize an SsxSemaphore structure
+///
+/// This low-level macro creates a structure initializatin of an SsxSemaphore
+/// structure. This can be used for example to create compile-time initialized
+/// arrays of semaphores.
+#define SSX_SEMAPHORE_INITIALIZATION(_initial_count, _max_count) \
+ {.pending_threads = 0, \
+ .count = (_initial_count), \
+ .max_count = (_max_count)}
+
+
+/// Declare and initialize a semaphore
+#define SSX_SEMAPHORE(sem, initial_count, max_count) \
+ SsxSemaphore sem = SSX_SEMAPHORE_INITIALIZATION(initial_count, max_count)
+
+
+/// 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 SSX API assumes that
+/// queueable structures will be defined with an SsxDeque 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 SsxDeque and vice-versa.
+
+typedef struct SsxDeque {
+
+ /// Pointer to the head or the next element in a deque.
+ ///
+ /// When an SsxDeque 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 SsxDeque. By convention the condition (\a next ==
+ /// 0) is used to indicate that a queue element is not enqueued.
+ struct SsxDeque* 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 SsxDeque* previous;
+
+} SsxDeque;
+
+
+typedef void (*SsxTimerCallback)(void *);
+
+#define SSX_TIMER_CALLBACK(callback) void callback(void *)
+
+struct SsxTimer;
+
+/// The SSX timer object
+
+typedef struct SsxTimer {
+
+ /// The time queue management pointers
+ ///
+ /// This pointer container is defined as the first element of the
+ /// structure to allow the SsxTimer to be cast to an SsxDeque and
+ /// vice-versa.
+ SsxDeque deque;
+
+ /// The absolute timeout of the timer.
+ SsxTimebase timeout;
+
+ /// The timer period
+ ///
+ /// If not 0, then this is a periodic timer and it will be automatically
+ /// rescheduled in absolute time from the previous timeout.
+ SsxInterval period;
+
+ /// The timer callback
+ ///
+ /// For SSX thread timers used to implement Sleep and semaphore pend
+ /// timeouts this field is initialized to __ssx_thread_timeout().
+ SsxTimerCallback callback;
+
+ /// Private data passed to the callback.
+ ///
+ /// For SSX thread timers used to implement Sleep and semaphore pend this
+ /// field is initialized to a pointer to the thread.
+ void *arg;
+
+ /// Options for timer processing; See \ref ssx_timer_options
+ uint8_t options;
+
+} SsxTimer;
+
+/// \defgroup ssx_timer_options SSX Timer Options
+/// @{
+
+/// Allow interrupt preemption during the callback
+///
+/// This is the normal mode for SsxTimer objects scheduled by SSX kernal
+/// mechanisms. The timer callbacks effectively run as if inside a
+/// highest-priority thread, allowing other interrupts to preempt them.
+#define SSX_TIMER_CALLBACK_PREEMPTIBLE 0x1
+
+/// @}
+
+
+// Threads
+
+typedef void (*SsxThreadRoutine)(void *arg);
+
+#define SSX_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.
+ SsxAddress 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
+ /// SsxAddress) from the thread pointer.
+ SsxAddress stack_limit;
+
+ /// This is the original base of the stack.
+ /// Assembler code expects this to always be at address offset 2 * (sizeof
+ /// SsxAddress) from the thread pointer.
+ SsxAddress stack_base;
+
+ /// If the thread is blocked on a semaphore, then this is the semaphore the
+ /// thread is blocked on.
+ SsxSemaphore *semaphore;
+
+ /// The thread priority.
+ SsxThreadPriority priority;
+
+ /// The thread state; See \ref ssx_thread_states
+ SsxThreadState state;
+
+ /// Thread flags; See \ref ssx_thread_flags
+ SsxThreadFlags flags;
+
+ /// The timer structure handles Sleep and blocking on a semaphore with
+ /// timeout.
+ SsxTimer timer;
+
+} SsxThread;
+
+
+// Initialization APIs
+
+int
+ssx_initialize(SsxAddress noncritical_stack,
+ size_t noncritical_stack_size,
+ SsxAddress critical_stack,
+ size_t critical_stack_size,
+ SsxTimebase initial_timebase,
+ uint32_t timebase_frequency_hz);
+
+
+// Timebase APIs
+
+SsxTimebase
+ssx_timebase_get(void);
+
+void
+ssx_timebase_set(SsxTimebase timebase);
+
+// Interrupt preemption APIs
+
+int
+ssx_interrupt_preemption_enable(void);
+
+int
+ssx_interrupt_preemption_disable(void);
+
+// Timer APIs
+
+int
+ssx_timer_create(SsxTimer *timer,
+ SsxTimerCallback callback,
+ void *arg);
+
+int
+ssx_timer_create_nonpreemptible(SsxTimer *timer,
+ SsxTimerCallback callback,
+ void *arg);
+
+int
+ssx_timer_schedule_absolute(SsxTimer *timer,
+ SsxTimebase time,
+ SsxInterval period);
+
+int
+ssx_timer_schedule(SsxTimer *timer,
+ SsxInterval interval,
+ SsxInterval period);
+
+int
+ssx_timer_cancel(SsxTimer *timer);
+
+int
+ssx_timer_info_get(SsxTimer *timer,
+ SsxTimebase *timeout,
+ int *active);
+
+// Thread APIs
+
+int
+ssx_thread_create(SsxThread *thread,
+ SsxThreadRoutine thread_routine,
+ void *arg,
+ SsxAddress stack,
+ size_t stack_size,
+ SsxThreadPriority priority);
+
+int
+ssx_start_threads(void);
+
+int
+ssx_thread_resume(SsxThread *thread);
+
+int
+ssx_thread_suspend(SsxThread *thread);
+
+int
+ssx_thread_delete(SsxThread *thread);
+
+int
+ssx_complete(void);
+
+int
+ssx_sleep_absolute(SsxTimebase time);
+
+int
+ssx_sleep(SsxInterval interval);
+
+int
+ssx_thread_info_get(SsxThread *thread,
+ SsxThreadState *state,
+ SsxThreadPriority *priority,
+ int *runnable);
+
+int
+ssx_thread_priority_change(SsxThread *thread,
+ SsxThreadPriority new_priority,
+ SsxThreadPriority *old_priority);
+
+int
+ssx_thread_at_priority(SsxThreadPriority priority,
+ SsxThread **thread);
+
+int
+ssx_thread_priority_swap(SsxThread* thread_a, SsxThread* thread_b);
+
+
+// Semaphore APIs
+
+int
+ssx_semaphore_create(SsxSemaphore *semaphore,
+ SsxSemaphoreCount initial_count,
+ SsxSemaphoreCount max_count);
+
+int
+ssx_semaphore_post(SsxSemaphore *semaphore);
+
+int
+ssx_semaphore_pend(SsxSemaphore *semaphore,
+ SsxInterval timeout);
+
+int
+ssx_semaphore_release_all(SsxSemaphore *semaphore);
+
+
+int
+ssx_semaphore_info_get(SsxSemaphore *semaphore,
+ SsxSemaphoreCount *count,
+ int *pending);
+
+void
+ssx_semaphore_post_handler(void *arg,
+ SsxIrqId irq,
+ int priority);
+
+// Misc. APIs
+
+void
+ssx_halt() __attribute__ ((noreturn));
+
+// Deque APIs
+
+int
+ssx_deque_sentinel_create(SsxDeque *deque);
+
+int
+ssx_deque_element_create(SsxDeque *element);
+
+
+/// Check for an empty SsxDeque
+///
+/// \param deque The sentinel node of a deque
+///
+/// \retval 0 The SsxDeque is not empty
+///
+/// \retval 1 The SsxDeque is empty
+
+static inline int
+ssx_deque_is_empty(SsxDeque *deque)
+{
+ return (deque == deque->next);
+}
+
+
+/// Check if an SsxDeque element is currently enqueued
+///
+/// \param element Typically the SsxDeque object of a queable structure
+///
+/// \retval 0 The element is not currently enqueued
+///
+/// \retval 1 The element is currently enqueued
+
+static inline int
+ssx_deque_is_queued(SsxDeque *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 SsxDeque 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
+ssx_deque_push_back(SsxDeque *deque, SsxDeque *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 SsxDeque 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
+ssx_deque_push_front(SsxDeque *deque, SsxDeque *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 SsxDeque 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 SsxDeque *
+ssx_deque_pop_front(SsxDeque *deque)
+{
+ SsxDeque *head;
+
+ if (ssx_deque_is_empty(deque)) {
+ return 0;
+ } else {
+ head = (SsxDeque *)(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 SsxDeque 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
+ssx_deque_delete(SsxDeque *element)
+{
+ element->previous->next = element->next;
+ element->next->previous = element->previous;
+ element->next = 0;
+}
+
+
+/// Cast a pointer to another type, in a way that won't cause warnings
+
+#define SSX_CAST_POINTER(t, p) ((t)((SsxAddress)(p)))
+
+
+/// \page ssx_errors SSX API and Kernel Error Handling
+///
+/// Error checking in the SSX 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
+/// SSX 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 SSX default is to check for API errors and kernel
+/// invariants, and panic should errors occur.
+///
+/// SSX follows the Unix convention that a successful call of an API returns 0
+/// (SSX_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 SSX 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
+/// SSX API and kernel:
+///
+/// \c SSX_ERROR_CHECK_API
+///
+/// \arg \b 0 - No SSX API error checking. APIs that potentially return error
+/// codes will always return 0 (SSX_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 SSX API errors are checked. The behavior in
+/// the event of an error is defined by the configuration option
+/// SSX_ERROR_PANIC.
+///
+/// \c SSX_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 SSX_ERROR_PANIC
+///
+/// \arg \b 0 - SSX API calls return negative error codes in the event of
+/// errors. Note that SSX kernel invariants always cause a panic if
+/// violations occur.
+///
+/// \arg \b 1 - (Default) In the event of errors SSX APIs invoke SSX_PANIC(code),
+/// where code is a positive error code. Kernel invariant checks always
+/// cause a panic if violations are detected.
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __SSX_API_H__ */
diff --git a/src/ssx/ssx/ssx_core.c b/src/ssx/ssx/ssx_core.c
new file mode 100755
index 0000000..7fa484a
--- /dev/null
+++ b/src/ssx/ssx/ssx_core.c
@@ -0,0 +1,81 @@
+// $Id: ssx_core.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_core.c
+/// \brief Core routines for the SSX kernel.
+///
+/// The entry points in this file are routines that are expected to be needed
+/// at runtime by all SSX applications. This file also serves as a place for
+/// kernel global variables to be realized.
+
+#define __SSX_CORE_C__
+
+#include "ssx.h"
+
+#if !SSX_TIMER_SUPPORT
+
+/// If there is no timer support, then any call of the timer interrupt handler
+/// is considered a fatal error.
+
+void
+__ssx_timer_handler()
+{
+ SSX_PANIC(SSX_NO_TIMER_SUPPORT);
+}
+
+#endif /* SSX_TIMER_SUPPORT */
+
+
+/// Initialize an SsxDeque sentinel node
+///
+/// \param deque The sentinel node of the deque
+///
+/// SSX 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 -SSX_INVALID_DEQUE_SENTINEL The \a deque pointer was null
+
+int
+ssx_deque_sentinel_create(SsxDeque *deque)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(deque == 0, SSX_INVALID_DEQUE_SENTINEL);
+ }
+
+ deque->next = deque->previous = deque;
+ return 0;
+}
+
+
+/// Initialize an SsxDeque element
+///
+/// \param element Typically the SsxDeque object of a queable structure
+///
+/// SSX 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 -SSX_INVALID_DEQUE_ELEMENT The \a element pointer was null
+
+int
+ssx_deque_element_create(SsxDeque *element)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(element == 0, SSX_INVALID_DEQUE_ELEMENT);
+ }
+
+ element->next = 0;
+ return 0;
+}
+
+#undef __SSX_CORE_C__
diff --git a/src/ssx/ssx/ssx_init.c b/src/ssx/ssx/ssx_init.c
new file mode 100755
index 0000000..fc12a9b
--- /dev/null
+++ b/src/ssx/ssx/ssx_init.c
@@ -0,0 +1,159 @@
+// $Id: ssx_init.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_init.c
+/// \brief SSX initialization
+///
+/// The entry points in this file are initialization routines - they are never
+/// needed after SSX initialization and their code space could be reclaimed by
+/// the application after initialization if required.
+
+#include "ssx.h"
+
+uint32_t __ssx_timebase_frequency_hz;
+uint32_t __ssx_timebase_frequency_khz;
+uint32_t __ssx_timebase_frequency_mhz;
+
+
+/// Initialize SSX.
+///
+/// \param noncritical_stack A stack area for noncritical interrupt handlers.
+///
+/// \param noncritical_stack_size The size (in bytes) of the stack area for
+/// noncritical interrupt handlers.
+///
+/// \param critical_stack A stack area for critical interrupt handlers.
+///
+/// \param critical_stack_size The size (in bytes) of the stack area for
+/// critical interrupt handlers.
+///
+/// \param initial_timebase The initial value of the SSX timebase. If this
+/// argument is given as the special value \c SSX_TIMEBASE_CONTINUE, then the
+/// timebase is not reset.
+///
+/// \param timebase_frequency_hz The frequency of the SSX timebase in Hz.
+///
+/// This routine \e must be called before any other SSX / routines, and \e
+/// should be called before any interrupts are enabled.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_ARGUMENT_INIT A stack pointer is 0 or is given
+/// a 0 size.
+///
+/// \retval -SSX_STACK_OVERFLOW One or both stacks are not large enough to
+/// support a minimum context save in the event of an interrupt.
+
+// Note that SSX does not rely on any static initialization of dynamic
+// variables. In debugging sessions using RAM-resident SSX images it is
+// assumed that the processor may be reset at any time, so we always need to
+// reset everything at initialization.
+
+int
+ssx_initialize(SsxAddress noncritical_stack,
+ size_t noncritical_stack_size,
+ SsxAddress critical_stack,
+ size_t critical_stack_size,
+ SsxTimebase initial_timebase,
+ uint32_t timebase_frequency_hz)
+{
+ int rc;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((noncritical_stack == 0) ||
+ (noncritical_stack_size == 0) ||
+ (critical_stack == 0) ||
+ (critical_stack_size == 0),
+ SSX_INVALID_ARGUMENT_INIT);
+ }
+
+ if (initial_timebase != SSX_TIMEBASE_CONTINUES) {
+ __ssx_timebase_set(initial_timebase);
+ }
+
+ __ssx_timebase_frequency_hz = timebase_frequency_hz;
+ __ssx_timebase_frequency_khz = timebase_frequency_hz / 1000;
+ __ssx_timebase_frequency_mhz = timebase_frequency_hz / 1000000;
+
+ __ssx_thread_machine_context_default = SSX_THREAD_MACHINE_CONTEXT_DEFAULT;
+
+ rc = __ssx_stack_init(&noncritical_stack, &noncritical_stack_size);
+ if (rc) {
+ return rc;
+ }
+
+ __ssx_noncritical_stack = noncritical_stack;
+ __ssx_noncritical_stack_size = noncritical_stack_size;
+
+ rc = __ssx_stack_init(&critical_stack, &critical_stack_size);
+ if (rc) {
+ return rc;
+ }
+
+ __ssx_critical_stack = critical_stack;
+ __ssx_critical_stack_size = critical_stack_size;
+
+#if SSX_TIMER_SUPPORT
+
+ // Initialize the time queue sentinel as a circular queue, set the next
+ // timeout and clear the cursor.
+
+ ssx_deque_sentinel_create((SsxDeque*)&__ssx_time_queue);
+ __ssx_time_queue.cursor = 0;
+ __ssx_time_queue.next_timeout = SSX_TIMEBASE_MAX;
+
+#endif /* SSX_TIMER_SUPPORT */
+
+#if SSX_THREAD_SUPPORT
+
+ // Clear the priority map. The final entry [SSX_THREADS] is for the idle
+ // thread.
+
+ int i;
+ for (i = 0; i <= SSX_THREADS; i++) {
+ __ssx_priority_map[i] = 0;
+ }
+
+ // Initialize the thread scheduler
+
+ __ssx_thread_queue_clear(&__ssx_run_queue);
+ __ssx_current_thread = 0;
+ __ssx_next_thread = 0;
+ __ssx_delayed_switch = 0;
+
+#endif /* SSX_THREAD_SUPPORT */
+
+ return SSX_OK;
+}
+
+
+/// Call the application main()
+///
+/// __ssx_main() is called from the bootloader. It's only purpose is to
+/// provide a place for the SSX_MAIN_HOOK to be called before main() is
+/// called.
+
+void
+__ssx_main(int argc, char **argv)
+{
+ SSX_MAIN_HOOK;
+
+ int main(int argc, char **argv);
+ main(argc, argv);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/ssx/ssx/ssx_kernel.h b/src/ssx/ssx/ssx_kernel.h
new file mode 100755
index 0000000..c6a70ca
--- /dev/null
+++ b/src/ssx/ssx/ssx_kernel.h
@@ -0,0 +1,281 @@
+#ifndef __SSX_KERNEL_H__
+#define __SSX_KERNEL_H__
+
+// $Id: ssx_kernel.h,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_kernel.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_kernel.h
+/// \brief SSX 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 SSX code. These have been added to the PPC405 port, so
+/// we should try it.
+
+#ifdef __SSX_CORE_C__
+#define IF__SSX_CORE_C__(x) x
+#define UNLESS__SSX_CORE_C__(x)
+#else
+#define IF__SSX_CORE_C__(x)
+#define UNLESS__SSX_CORE_C__(x) x
+#endif
+
+#if SSX_MINIMIZE_KERNEL_CODE_SPACE
+#define IF_SSX_MINIMIZE_KERNEL_CODE_SPACE(x) x
+#define UNLESS_SSX_MINIMIZE_KERNEL_CODE_SPACE(x)
+#else
+#define IF_SSX_MINIMIZE_KERNEL_CODE_SPACE(x)
+#define UNLESS_SSX_MINIMIZE_KERNEL_CODE_SPACE(x) x
+#endif
+
+
+#ifndef __ASSEMBLER__
+
+/// This is the stack pointer saved when switching from a thread or
+/// non-critical interrupt context to a full-mode critical interrupt context.
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxAddress __ssx_saved_sp_critical;
+
+/// The critical interrupt stack; constant once defined by the call of
+/// ssx_initialize().
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxAddress __ssx_critical_stack;
+
+/// This is the stack pointer saved when switching from a thread context to a
+/// full-mode non-critical interrupt context.
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxAddress __ssx_saved_sp_noncritical;
+
+/// The non-critical interrupt stack; constant once defined by the call of
+/// ssx_initialize().
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxAddress __ssx_noncritical_stack;
+
+/// This is the run queue - the queue of mapped runnable tasks.
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxThreadQueue __ssx_run_queue;
+
+/// This flag is set by \c __ssx_schedule() if a new highest-priority thread
+/// becomes runnable during an interrupt handler. The context switch will
+/// take place at the end of non-critical interrupt processing, and the
+/// interrupt handling code will clear the flag.
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+int __ssx_delayed_switch;
+
+/// The currently running thread, or NULL (0) to indicate the idle thread
+///
+/// \a __ssx_current_thread holds a pointer to the currently executing
+/// thread. This pointer will be NULL (0) under the following conditions:
+///
+/// - After ssx_initialize() but prior to ssx_start_threads()
+///
+/// - After ssx_start_threads(), when no threads are runnable. In this case
+/// the NULL (0) value indicates that the SSX idle thread is 'running'.
+///
+/// - After ssx_start_threads(), when the current (non-idle) thread has
+/// completed or been deleted.
+///
+/// If \a __ssx_current_thread == 0 then there is no requirement to save any
+/// register state on a context switch, either because the SSX idle thread has
+/// no permanent context, or because any thread context on the kernel stack is
+/// associated with a deleted thread.
+///
+/// If \a __ssx_current_thread != 0 then \a __ssx_current_thread is a pointer
+/// to the currently executing thread. In an interrupt handler \a
+/// ssx_current_thread is a pointer to the thread whose context is saved on
+/// the kernel stack.
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxThread* __ssx_current_thread;
+
+/// The thread to switch to during the next context switch, or NULL (0).
+///
+/// \a __ssx_next_thread is computed by __ssx_schedule(). \a
+/// __ssx_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
+/// __ssx_next_thread == 0 or \a __ssx_next_thread != \a __ssx_current_thread.
+/// In an interrupt context the check happens at the end of processing all
+/// SSX_NONCRITICAL interrupts.
+///
+/// \a __ssx_next_thread may be NULL (0) under the following
+/// conditions:
+///
+/// - After ssx_initialize() but prior to ssx_start_threads(), assuming no
+/// threads have been made runnable.
+///
+/// - After ssx_start_threads(), when no threads are runnable. In this case
+/// the NULL (0) value indicates that the SSX idle thread is the next thread
+/// to 'run'.
+///
+/// If \a __ssx_next_thread == 0 then there is no requirement to restore
+/// any register state on a context switch, because the SSX idle thread has
+/// no permanent context.
+///
+/// If \a __ssx_next_thread != 0 then \a __ssx_next_thread is a pointer
+/// to the thread whose context will be restored at the next context switch.
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxThread* __ssx_next_thread;
+
+/// The priority of \a __ssx_next_thread
+///
+/// If \a __ssx_next_thread == 0, the \a __ssx_next_priority == SSX_THREADS.
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxThreadPriority __ssx_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 ssx_initialize().
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxMachineContext __ssx_thread_machine_context_default;
+
+
+/// The size of the noncritical stack (bytes).
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+size_t __ssx_noncritical_stack_size;
+
+/// The size of the critical stack (bytes).
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+size_t __ssx_critical_stack_size;
+
+/// This table maps priorities to threads, and contains SSX_THREADS + 1
+/// entries. The final entry is for the idle thread and will always be null
+/// after initizlization.
+
+UNLESS__SSX_CORE_C__(extern)
+volatile
+SsxThread* __ssx_priority_map[SSX_THREADS + 1];
+
+/// The SSX 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 SsxDeque 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 SsxTimeQueue to be cast to an SsxDeque.
+ SsxDeque queue;
+
+ /// The next timeout in absolute time.
+ SsxTimebase 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.
+ SsxDeque* cursor;
+
+} SsxTimeQueue;
+
+UNLESS__SSX_CORE_C__(extern)
+SsxTimeQueue __ssx_time_queue;
+
+/// Return a pointer to the SsxThread object of the currently running thread,
+/// or NULL (0) if SSX 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 SSX kernel
+/// does not (must not) use this API.
+
+UNLESS__SSX_CORE_C__(extern)
+inline SsxThread *
+ssx_current(void)
+{
+ return (SsxThread *)__ssx_current_thread;
+}
+
+
+/// Set the timebase. This is only called at initialization. Machine
+/// specific.
+
+void
+__ssx_timebase_set(SsxTimebase t);
+
+/// Schedule the next timeout in a machine-specific way.
+
+void
+__ssx_schedule_hardware_timeout(SsxTimebase timeout);
+
+/// Cancel the next timeout in a machine-specific way.
+
+void
+__ssx_cancel_hardware_timeout(void);
+
+/// The thread timeout handler. Portable.
+
+SSX_TIMER_CALLBACK(__ssx_thread_timeout);
+
+/// Generic stack initialization. Portable.
+
+int
+__ssx_stack_init(SsxAddress *stack,
+ size_t *size);
+
+/// Machine-specific thread context initialization.
+
+void
+__ssx_thread_context_initialize(SsxThread *thread,
+ SsxThreadRoutine thread_routine,
+ void *arg);
+
+/// Machine specific resumption of __ssx_next_thread at __ssx_next_priority
+/// without saving the current context.
+void
+__ssx_next_thread_resume(void);
+
+/// Schedule a timer in the time queue. Portable.
+void
+__ssx_timer_schedule(SsxTimer *timer);
+
+/// Remove a timer from the time queue. Portable.
+int
+__ssx_timer_cancel(SsxTimer *timer);
+
+void
+__ssx_schedule(void);
+
+
+// Call the application main(). Portable.
+
+void
+__ssx_main(int argc, char **argv);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __SSX_KERNEL_H__ */
diff --git a/src/ssx/ssx/ssx_macros.h b/src/ssx/ssx/ssx_macros.h
new file mode 100755
index 0000000..76d3ba7
--- /dev/null
+++ b/src/ssx/ssx/ssx_macros.h
@@ -0,0 +1,119 @@
+#ifndef __SSX_MACROS_H__
+#define __SSX_MACROS_H__
+
+// $Id: ssx_macros.h,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_macros.h,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_macros.h
+/// \brief Boilerplate macros for SSX
+
+/// This macro encapsulates error handling boilerplate for code that uses the
+/// SSX API-type error handling, for errors that do not occur in critical
+/// sections.
+
+#define SSX_ERROR(code) \
+ do { \
+ if (SSX_ERROR_PANIC) { \
+ SSX_PANIC(code); \
+ } else { \
+ return -(code); \
+ } \
+ } while (0)
+
+
+/// This macro encapsulates error handling boilerplate in the SSX API
+/// functions, for errors that do not occur in critical sections.
+
+#define SSX_ERROR_IF(condition, code) \
+ do { \
+ if (condition) { \
+ SSX_ERROR(code); \
+ } \
+ } while (0)
+
+
+/// This macro encapsulates error handling boilerplate in the SSX API
+/// functions, for errors that do not occur in critical sections and always
+/// force a kernel panic, indicating a kernel or API bug.
+
+#define SSX_PANIC_IF(condition, code) \
+ do { \
+ if (condition) { \
+ SSX_PANIC(code); \
+ } \
+ } while (0)
+
+
+/// This macro encapsulates error handling boilerplate in the SSX API
+/// functions, for errors that do not occur in critical sections.
+/// The error handling will only be enabled when SSX_ERROR_CHECK_API
+/// is enabled.
+
+#define SSX_ERROR_IF_CHECK_API(condition, code) \
+ do { \
+ if (SSX_ERROR_CHECK_API) { \
+ SSX_ERROR_IF(condition, code); \
+ } \
+ } while (0)
+
+/// This macro encapsulates error handling boilerplate in the SSX API
+/// functions, for errors that occur in critical sections.
+
+#define SSX_ERROR_IF_CRITICAL(condition, code, context) \
+ do { \
+ if (condition) { \
+ if (SSX_ERROR_PANIC) { \
+ SSX_PANIC(code); \
+ ssx_critical_section_exit(context); \
+ } else { \
+ ssx_critical_section_exit(context); \
+ return -(code); \
+ } \
+ } \
+ } while (0)
+
+
+/// This is a general macro for errors that require cleanup before returning
+/// the error code.
+
+#define SSX_ERROR_IF_CLEANUP(condition, code, cleanup) \
+ do { \
+ if (condition) { \
+ if (SSX_ERROR_PANIC) { \
+ SSX_PANIC(code); \
+ cleanup; \
+ } else { \
+ cleanup; \
+ return -(code); \
+ } \
+ } \
+ } while (0)
+
+
+/// Most SSX APIs can not be called from critical interrupt contexts.
+
+#define SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT() \
+ SSX_ERROR_IF(__ssx_kernel_context_critical_interrupt(), \
+ SSX_ILLEGAL_CONTEXT_CRITICAL_INTERRUPT)
+
+
+/// Some SSX APIs can only be called from thread contexts - these are APIs
+/// that threads call on 'themselves'.
+
+#define SSX_ERROR_UNLESS_THREAD_CONTEXT() \
+ SSX_ERROR_IF(!__ssx_kernel_context_thread(), \
+ SSX_ILLEGAL_CONTEXT_THREAD_CONTEXT)
+
+
+/// Some SSX APIs must be called from an interrupt context only.
+
+#define SSX_ERROR_UNLESS_ANY_INTERRUPT_CONTEXT() \
+ SSX_ERROR_IF(!__ssx_kernel_context_any_interrupt(), \
+ SSX_ILLEGAL_CONTEXT_INTERRUPT_CONTEXT)
+
+#endif /* __SSX_MACROS_H__ */
diff --git a/src/ssx/ssx/ssx_semaphore_core.c b/src/ssx/ssx/ssx_semaphore_core.c
new file mode 100755
index 0000000..f1f64e8
--- /dev/null
+++ b/src/ssx/ssx/ssx_semaphore_core.c
@@ -0,0 +1,331 @@
+// $Id: ssx_semaphore_core.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_semaphore_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_semaphore_core.c
+/// \brief SSX semaphore APIs
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present at runtime in any SSX application that enables
+/// semaphores.
+
+#include "ssx.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 SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical interrupt
+/// context.
+///
+/// \retval -SSX_INVALID_SEMAPHORE_AT_POST The \a semaphore is a null (0) pointer.
+///
+/// \retval -SSX_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
+ssx_semaphore_post(SsxSemaphore *semaphore)
+{
+ SsxMachineContext ctx;
+ SsxThreadPriority priority;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(semaphore == 0, SSX_INVALID_SEMAPHORE_AT_POST);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ priority = __ssx_thread_queue_min(&(semaphore->pending_threads));
+
+ if (priority != SSX_IDLE_THREAD_PRIORITY) {
+
+ __ssx_thread_queue_delete(&(semaphore->pending_threads), priority);
+ __ssx_thread_queue_insert(&__ssx_run_queue, priority);
+
+ SSX_TRACE_THREAD_SEMAPHORE_POST(priority);
+
+ __ssx_schedule();
+
+ } else {
+
+ semaphore->count++;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((semaphore->max_count > 0) &&
+ (semaphore->count > semaphore->max_count),
+ SSX_SEMAPHORE_OVERFLOW);
+ }
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// Pend on a semaphore with timeout
+///
+/// \param semaphore A pointer to the semaphore
+///
+/// \param timeout A relative timeout in SSX timebase ticks, including the
+/// special values SSX_NO_WAIT and SSX_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
+/// SSX_NO_WAIT (0) then the call returns immediately with the informational
+/// code -SSX_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 -SSX_SEMAPHORE_PEND_WOULD_BLOCK.
+///
+/// Once timed out the thread is removed from the semaphore pending queue and
+/// made runnable, and the ssx_semaphore_pend() operation will fail, even if
+/// the semaphore count becomes available before the thread runs again. The
+/// ssx_semaphore_pend() API returns the informational code
+/// -SSX_SEMAPHORE_PEND_TIMED_OUT in this case.
+///
+/// By convention, a timeout interval equal to the maximum possible value of
+/// the \c SsxInterval type is taken to mean "wait forever". A thread blocked
+/// on a semaphore in this mode will never time out. SSX provides this
+/// constant as \c SSX_WAIT_FOREVER.
+///
+/// Return values other than SSX_OK (0) are not necessarily errors; see \ref
+/// ssx_errors
+///
+/// The following return codes are non-error codes:
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_SEMAPHORE_PEND_NO_WAIT timeout is set to SSX_NO_WAIT
+///
+/// \retval -SSX_SEMAPHORE_PEND_TIMED_OUT The semaphore was not acquired
+/// before the timeout expired.
+///
+/// The following return codes are error codes:
+///
+/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical interrupt
+/// context.
+///
+/// \retval -SSX_INVALID_SEMAPHORE_AT_PEND The \a semaphore is a null (0)
+/// pointer.
+///
+/// \retval -SSX_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 __ssx_current_thread removes the 'volatile' attribute.
+
+int
+ssx_semaphore_pend(SsxSemaphore *semaphore,
+ SsxInterval timeout)
+{
+ SsxMachineContext ctx;
+ SsxThreadPriority priority;
+ SsxThread *thread;
+ SsxTimer *timer = 0;
+ int rc = SSX_OK;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(semaphore == 0, SSX_INVALID_SEMAPHORE_AT_PEND);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ if (semaphore->count != 0) {
+
+ semaphore->count--;
+
+ } else if (timeout == SSX_NO_WAIT) {
+
+ rc = -SSX_SEMAPHORE_PEND_NO_WAIT;
+
+ } else {
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL(!__ssx_kernel_context_thread(),
+ SSX_SEMAPHORE_PEND_WOULD_BLOCK,
+ &ctx);
+ }
+
+ thread = (SsxThread *)__ssx_current_thread;
+ priority = thread->priority;
+
+ __ssx_thread_queue_insert(&(semaphore->pending_threads), priority);
+
+ thread->semaphore = semaphore;
+ thread->flags |= SSX_THREAD_FLAG_SEMAPHORE_PEND;
+
+ SSX_TRACE_THREAD_SEMAPHORE_PEND(priority);
+
+ if (timeout != SSX_WAIT_FOREVER) {
+ timer = &(thread->timer);
+ timer->timeout = ssx_timebase_get() + timeout;
+ __ssx_timer_schedule(timer);
+ thread->flags |= SSX_THREAD_FLAG_TIMER_PEND;
+ }
+
+ __ssx_thread_queue_delete(&__ssx_run_queue, priority);
+ __ssx_schedule();
+
+ thread->flags &= ~SSX_THREAD_FLAG_SEMAPHORE_PEND;
+
+ if (thread->flags & SSX_THREAD_FLAG_TIMER_PEND) {
+ if (thread->flags & SSX_THREAD_FLAG_TIMED_OUT) {
+ rc = -SSX_SEMAPHORE_PEND_TIMED_OUT;
+ } else {
+ __ssx_timer_cancel(timer);
+ }
+ thread->flags &=
+ ~(SSX_THREAD_FLAG_TIMER_PEND | SSX_THREAD_FLAG_TIMED_OUT);
+ }
+ }
+
+ ssx_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 SSX semaphore to be used as a thread
+/// barrier. ssx_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
+/// ssx_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 SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical interrupt
+/// context.
+///
+/// \retval -SSX_INVALID_SEMAPHORE_AT_RELEASE The \a semaphore is a null (0)
+/// pointer.
+
+int
+ssx_semaphore_release_all(SsxSemaphore* semaphore)
+{
+ SsxMachineContext ctx;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(semaphore == 0, SSX_INVALID_SEMAPHORE_AT_RELEASE);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ __ssx_thread_queue_union(&__ssx_run_queue, &(semaphore->pending_threads));
+ __ssx_thread_queue_clear(&(semaphore->pending_threads));
+ __ssx_schedule();
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// Get information about a semaphore.
+///
+/// \param semaphore A pointer to the SsxSemaphore 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 an SSX_NONCRITICAL critical section. Since the
+/// implementation of this API does not require a critical section, it is not
+/// an error to call this API from a critical interrupt context.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_SEMAPHORE_AT_INFO The \a semaphore is a null (0)
+/// pointer.
+
+int
+ssx_semaphore_info_get(SsxSemaphore* semaphore,
+ SsxSemaphoreCount* count,
+ int* pending)
+
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(semaphore == 0, SSX_INVALID_SEMAPHORE_AT_INFO);
+ }
+
+ if (count) {
+ *count = semaphore->count;
+ }
+ if (pending) {
+ *pending = __ssx_thread_queue_count(&(semaphore->pending_threads));
+ }
+
+ return SSX_OK;
+}
+
+
+/// An simple interrupt handler that posts to a semaphore.
+///
+/// To implement basic event-driven blocking of a thread, install
+/// ssx_semaphore_post_handler() as the handler for a non-critical interrupt
+/// and provide a pointer to the semaphore as the \a arg argument in
+/// ssx_irq_handler_set(). The semaphore should be initialized with
+/// ssx_semaphore_create(&sem, 0, 1). This handler simply disables (masks)
+/// the interrupt, clears the status and calls ssx_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.
+
+void
+ssx_semaphore_post_handler_full(void *arg, SsxIrqId irq, int priority)
+{
+ ssx_irq_disable(irq);
+ ssx_irq_status_clear(irq);
+ ssx_semaphore_post((SsxSemaphore *)arg);
+}
+
+SSX_IRQ_FAST2FULL(ssx_semaphore_post_handler, ssx_semaphore_post_handler_full);
diff --git a/src/ssx/ssx/ssx_semaphore_init.c b/src/ssx/ssx/ssx_semaphore_init.c
new file mode 100755
index 0000000..98bba89
--- /dev/null
+++ b/src/ssx/ssx/ssx_semaphore_init.c
@@ -0,0 +1,84 @@
+// $Id: ssx_semaphore_init.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_semaphore_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_semaphore_init.c
+/// \brief SSX 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 "ssx.h"
+
+/// Create (initialize) a semaphore
+///
+/// \param semaphore A pointer to an SsxSemaphore 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
+/// ssx_semaphore_create(), using an application-provided instance of an \c
+/// SsxSemaphore structure. This structure \e is the semaphore, so the
+/// application must never modify the structure if the semaphore is in use.
+/// SSX has no way to know if an \c SsxSemaphore structure provided to
+/// \c ssx_semaphore_create() is safe to use as a semaphore, and will silently
+/// modify whatever memory is provided.
+///
+/// SSX provides two simple overflow semantics based on the value of max_count
+/// in the call of \c ssx_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 ssx_semaphore_post() will
+/// return the error \c -SSX_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 SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_SEMAPHORE_AT_CREATE The \a semaphore is a null (0)
+/// pointer.
+///
+/// \retval -SSX_INVALID_ARGUMENT_SEMAPHORE The \a max_count is non-zero
+/// and less than the \a initial_count.
+
+int
+ssx_semaphore_create(SsxSemaphore *semaphore,
+ SsxSemaphoreCount initial_count,
+ SsxSemaphoreCount max_count)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(semaphore == 0, SSX_INVALID_SEMAPHORE_AT_CREATE);
+ SSX_ERROR_IF((max_count != 0) && (initial_count > max_count),
+ SSX_INVALID_ARGUMENT_SEMAPHORE);
+ }
+
+ __ssx_thread_queue_clear(&(semaphore->pending_threads));
+ semaphore->count = initial_count;
+ semaphore->max_count = max_count;
+
+ return SSX_OK;
+}
+
+
+
+
+
diff --git a/src/ssx/ssx/ssx_stack_init.c b/src/ssx/ssx/ssx_stack_init.c
new file mode 100755
index 0000000..9d6331a
--- /dev/null
+++ b/src/ssx/ssx/ssx_stack_init.c
@@ -0,0 +1,87 @@
+// $Id: ssx_stack_init.c,v 1.1.1.1 2013/12/11 21:03:28 bcbrock Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_stack_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_stack_init.c
+/// \brief SSX stack initialization
+///
+/// The entry points in this file are initialization routines - they are never
+/// needed after SSX initialization and their code space could be reclaimed by
+/// the application after initialization if required.
+///
+/// This code was split out from "ssx_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 ssx_initialize().
+
+#include "ssx.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 SSX_STACK_TYPE.
+///
+/// SSX 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
+__ssx_stack_init(SsxAddress *stack,
+ size_t *size)
+{
+ SsxAddress mask;
+ size_t excess, i, count;
+ SSX_STACK_TYPE *p;
+
+ if (SSX_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 (!SSX_STACK_PRE_DECREMENT) {
+ *stack -= sizeof(SSX_STACK_TYPE);
+ *size -= sizeof(SSX_STACK_TYPE);
+ }
+
+ mask = SSX_STACK_ALIGNMENT - 1;
+ excess = *stack & mask;
+ *stack -= excess;
+ *size -= excess;
+ *size = (*size / sizeof(SSX_STACK_TYPE)) * sizeof(SSX_STACK_TYPE);
+
+ if (SSX_STACK_CHECK) {
+ p = (SSX_STACK_TYPE *)(*stack);
+ count = *size / sizeof(SSX_STACK_TYPE);
+ for (i = 0; i < count; i++) {
+ if (SSX_STACK_PRE_DECREMENT) {
+ *(--p) = SSX_STACK_PATTERN;
+ } else {
+ *(p--) = SSX_STACK_PATTERN;
+ }
+ }
+ }
+
+ __ssx_stack_create_initial_frame(stack, size);
+
+ } else {
+
+ SSX_PANIC(SSX_UNIMPLEMENTED);
+ }
+
+ return SSX_OK;
+}
+
diff --git a/src/ssx/ssx/ssx_thread_core.c b/src/ssx/ssx/ssx_thread_core.c
new file mode 100755
index 0000000..d6124e8
--- /dev/null
+++ b/src/ssx/ssx/ssx_thread_core.c
@@ -0,0 +1,946 @@
+// $Id: ssx_thread_core.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_thread_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_thread_core.c
+/// \brief SSX thread APIs
+///
+/// The entry points in this file are considered 'core' routines that will
+/// always be present at runtime in any SSX application that enables threads.
+
+#include "ssx.h"
+
+#define __SSX_THREAD_CORE_C__
+
+
+// This routine is only used locally. Noncritical interrupts must be disabled
+// at entry.
+
+static inline int
+__ssx_thread_is_active(SsxThread *thread)
+{
+ return ((thread->state != SSX_THREAD_STATE_COMPLETED) &&
+ (thread->state != SSX_THREAD_STATE_DELETED));
+}
+
+
+// This routine is only used locally. Noncritical interrupts must be disabled
+// at entry.
+
+static inline int
+__ssx_thread_is_mapped(SsxThread *thread)
+{
+ return (thread->state == SSX_THREAD_STATE_MAPPED);
+}
+
+
+// This routine is only used locally. Noncritical interrupts must be disabled
+// at entry. This is only called on mapped threads.
+
+static inline int
+__ssx_thread_is_runnable(SsxThread *thread)
+{
+ return __ssx_thread_queue_member(&__ssx_run_queue, thread->priority);
+}
+
+
+// This routine is only used locally. Noncritical interrupts must be disabled
+// at entry.
+
+static inline SsxThread*
+__ssx_thread_at_priority(SsxThreadPriority priority)
+{
+ return (SsxThread*)__ssx_priority_map[priority];
+}
+
+
+// This routine is only used locally. Noncritical 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 SSX_THREAD_STATE_SUSPENDED_RUNNABLE or
+// SSX_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
+__ssx_thread_map(SsxThread* thread)
+{
+ SsxThreadPriority priority;
+
+ priority = thread->priority;
+ __ssx_priority_map[priority] = thread;
+
+ if (thread->state == SSX_THREAD_STATE_SUSPENDED_RUNNABLE) {
+
+ __ssx_thread_queue_insert(&__ssx_run_queue, priority);
+
+ } else if (thread->flags & SSX_THREAD_FLAG_SEMAPHORE_PEND) {
+
+ if (thread->semaphore->count) {
+
+ thread->semaphore->count--;
+ __ssx_thread_queue_insert(&__ssx_run_queue, priority);
+
+ } else {
+
+ __ssx_thread_queue_insert(&(thread->semaphore->pending_threads),
+ priority);
+ }
+ }
+
+ thread->state = SSX_THREAD_STATE_MAPPED;
+
+ if (SSX_KERNEL_TRACE_ENABLE) {
+ if (__ssx_thread_is_runnable(thread)) {
+ SSX_TRACE_THREAD_MAPPED_RUNNABLE(priority);
+ } else if (thread->flags & SSX_THREAD_FLAG_SEMAPHORE_PEND) {
+ SSX_TRACE_THREAD_MAPPED_SEMAPHORE_PEND(priority);
+ } else {
+ SSX_TRACE_THREAD_MAPPED_SLEEPING(priority);
+ }
+ }
+}
+
+
+// This routine is only used locally. Noncritical interrupts must be disabled
+// at entry. This routine is only ever called on threads in the
+// SSX_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
+// __ssx_thread_unmap().
+
+void
+__ssx_thread_unmap(SsxThread *thread)
+{
+ SsxThreadPriority priority;
+
+ priority = thread->priority;
+ __ssx_priority_map[priority] = 0;
+
+ if (__ssx_thread_is_runnable(thread)) {
+
+ thread->state = SSX_THREAD_STATE_SUSPENDED_RUNNABLE;
+ __ssx_thread_queue_delete(&__ssx_run_queue, priority);
+
+ } else {
+
+ thread->state = SSX_THREAD_STATE_SUSPENDED_BLOCKED;
+ if (thread->flags & SSX_THREAD_FLAG_SEMAPHORE_PEND) {
+ __ssx_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
+// SSX_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 SsxThread pointers.
+//
+// If we are not yet in thread mode we're done - threads will be started by
+// ssx_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 SSX_NONCRITICAL interrupt processing.
+
+void
+__ssx_schedule(void)
+{
+ __ssx_next_priority = __ssx_thread_queue_min(&__ssx_run_queue);
+ __ssx_next_thread = __ssx_priority_map[__ssx_next_priority];
+
+ if ((__ssx_next_thread == 0) ||
+ (__ssx_next_thread != __ssx_current_thread)) {
+
+ if (__ssx_kernel_mode_thread()) {
+ if (__ssx_kernel_context_thread()) {
+ if (__ssx_current_thread != 0) {
+ __ssx_switch();
+ } else {
+ __ssx_next_thread_resume();
+ }
+ } else {
+ __ssx_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
+// __ssx_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
+__ssx_thread_delete(SsxThread *thread, SsxThreadState final_state)
+{
+ SsxMachineContext ctx;
+ int mapped;
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ mapped = __ssx_thread_is_mapped(thread);
+
+ if (mapped) {
+ __ssx_thread_unmap(thread);
+ }
+
+ __ssx_timer_cancel(&(thread->timer));
+ thread->state = final_state;
+
+ if (mapped) {
+
+ if (SSX_KERNEL_TRACE_ENABLE) {
+ if (final_state == SSX_THREAD_STATE_DELETED) {
+ SSX_TRACE_THREAD_DELETED(thread->priority);
+ } else {
+ SSX_TRACE_THREAD_COMPLETED(thread->priority);
+ }
+ }
+
+ if (thread == __ssx_current_thread) {
+ __ssx_current_thread = 0;
+ }
+ __ssx_schedule();
+ }
+
+ ssx_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
+// ssx_semaphore_release_all(), cancelling any semaphore timeouts is deferred
+// until the thread runs again.
+//
+// __ssx_thread_timeout() is currenly the only timer interrupt called from a
+// critical section.
+//
+// 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
+__ssx_thread_timeout(void *arg)
+{
+ SsxThread *thread = (SsxThread *)arg;
+
+ switch (thread->state) {
+
+ case SSX_THREAD_STATE_MAPPED:
+ if (!__ssx_thread_is_runnable(thread)) {
+ thread->flags |= SSX_THREAD_FLAG_TIMED_OUT;
+ __ssx_thread_queue_insert(&__ssx_run_queue, thread->priority);
+ __ssx_schedule();
+ }
+ break;
+
+ case SSX_THREAD_STATE_SUSPENDED_RUNNABLE:
+ break;
+
+ case SSX_THREAD_STATE_SUSPENDED_BLOCKED:
+ thread->flags |= SSX_THREAD_FLAG_TIMED_OUT;
+ thread->state = SSX_THREAD_STATE_SUSPENDED_RUNNABLE;
+ break;
+
+ default:
+ SSX_PANIC(SSX_THREAD_TIMEOUT_STATE);
+ }
+}
+
+
+// This routine serves as a container for the SSX_START_THREADS_HOOK and
+// actually starts threads. The helper routine __ssx_call_ssx_start_threads()
+// arranges this routine to be called with interrupts disabled while running
+// on the noncritical interrupt 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
+// noncritical interrupt stack. However to do this safely we need to make sure
+// that no interrupts will happen during this time. When __ssx_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 ssx_start_threads() and so is also considered a
+// 'core' routine.
+
+void
+__ssx_start_threads(void)
+{
+ SSX_START_THREADS_HOOK;
+
+ __ssx_next_thread_resume();
+
+ SSX_PANIC(SSX_START_THREADS_RETURNED);
+}
+
+
+/// Start SSX threads
+///
+/// This routine starts the SSX thread scheduler infrastructure. This routine
+/// must be called after a call of \c ssx_initialize(). This routine never
+/// returns. Interrupt (+ timer) only configurations of SSX 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 ssx_errors
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_THREAD The API was called twice.
+
+int
+ssx_start_threads(void)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(__ssx_kernel_mode_thread(), SSX_ILLEGAL_CONTEXT_THREAD);
+ }
+
+ __ssx_call_ssx_start_threads();
+
+ return 0;
+}
+
+
+/// Resume a suspended thread
+///
+/// \param thread The thread to resume
+///
+/// SSX 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
+/// ssx_thread_resume(). This API will succeed only if no other active thread
+/// is currently mapped at the priority assigned to the thread. SSX provides
+/// the ssx_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 ssx_thread_resume() on a mapped
+/// thread. However it is an error to call ssx_thread_resume() on a completed
+/// or deleted thread.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion, including calls on a \a thread that is
+/// already mapped.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_THREAD The API was called
+/// from a critical interrupt context.
+///
+/// \retval -SSX_INVALID_THREAD_AT_RESUME1 The \a thread is a null (0) pointer.
+///
+/// \retval -SSX_INVALID_THREAD_AT_RESUME2 The \a thread is not active,
+/// i.e. has completed or been deleted.
+///
+/// \retval -SSX_PRIORITY_IN_USE_AT_RESUME Another thread is already mapped at
+/// the priority of the \a thread.
+
+int
+ssx_thread_resume(SsxThread *thread)
+{
+ SsxMachineContext ctx;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_RESUME1);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL(!__ssx_thread_is_active(thread),
+ SSX_INVALID_THREAD_AT_RESUME2,
+ &ctx);
+ }
+
+ if (!__ssx_thread_is_mapped(thread)) {
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL(__ssx_priority_map[thread->priority] != 0,
+ SSX_PRIORITY_IN_USE_AT_RESUME,
+ &ctx);
+ }
+ __ssx_thread_map(thread);
+ __ssx_schedule();
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_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 ssx_semaphore_pend() will return the
+/// timeout code -SSX_SEMAPHORE_PEND_TIMED_OUT.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion, including calls on a \a thread that is
+/// already suspended.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_THREAD The API was called from a critical
+/// interrupt context.
+///
+/// \retval -SSX_INVALID_THREAD_AT_SUSPEND1 The \a thread is a null (0) pointer
+///
+/// \retval -SSX_INVALID_THREAD_AT_SUSPEND2 The \a thread is not active,
+/// i.e. has completed or been deleted.
+
+int
+ssx_thread_suspend(SsxThread *thread)
+{
+ SsxMachineContext ctx;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF((thread == 0), SSX_INVALID_THREAD_AT_SUSPEND1);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL(!__ssx_thread_is_active(thread),
+ SSX_INVALID_THREAD_AT_SUSPEND2,
+ &ctx);
+ }
+
+ if (__ssx_thread_is_mapped(thread)) {
+
+ SSX_TRACE_THREAD_SUSPENDED(thread->priority);
+ __ssx_thread_unmap(thread);
+ __ssx_schedule();
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_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 SSX_OK (0) are errors; see \ref ssx_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 -SSX_ILLEGAL_CONTEXT_THREAD The API was called from a critical
+/// interrupt context.
+///
+/// \retval -SSX_INVALID_THREAD_AT_DELETE The \a thread is a null (0) pointer.
+
+int
+ssx_thread_delete(SsxThread *thread)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_DELETE);
+ }
+
+ __ssx_thread_delete(thread, SSX_THREAD_STATE_DELETED);
+
+ return SSX_OK;
+}
+
+
+/// Complete a thread
+///
+/// If a thread ever returns from the subroutine defining the thread entry
+/// point, the thread is removed from all SSX kernel data structures and
+/// marked completed. The thread routine can also use the API ssx_complete()
+/// to make this more explicit if desired. SSX 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 ssx_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 -SSX_ILLEGAL_CONTEXT_THREAD The API was not called from a thread
+/// context.
+
+// Note: Casting __ssx_current_thread removes the 'volatile' attribute.
+
+int
+ssx_complete(void)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_UNLESS_THREAD_CONTEXT();
+ }
+
+ __ssx_thread_delete((SsxThread *)__ssx_current_thread,
+ SSX_THREAD_STATE_COMPLETED);
+
+ return SSX_OK;
+}
+
+
+/// Sleep a thread until an absolute time
+///
+/// \param time An absolute time as measured by the SSX timebase
+///
+/// Threads can use this API to sleep until an absolute time. 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 SSX specification for a full discussion of how SSX handles
+/// scheduling events at absolute times "in the past". Briefly stated, if the
+/// \a time is in the past, the thread will Sleep for the briefest possible
+/// period supported by the hardware.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_THREAD The API was not called from a thread
+/// context.
+
+// Note: Casting __ssx_current_thread removes the 'volatile' attribute.
+
+int
+ssx_sleep_absolute(SsxTimebase time)
+{
+ SsxMachineContext ctx;
+ SsxThread *current;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_UNLESS_THREAD_CONTEXT();
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ current = (SsxThread *)__ssx_current_thread;
+
+ current->timer.timeout = time;
+ __ssx_timer_schedule(&(current->timer));
+
+ current->flags |= SSX_THREAD_FLAG_TIMER_PEND;
+
+ SSX_TRACE_THREAD_SLEEP(current->priority);
+
+ __ssx_thread_queue_delete(&__ssx_run_queue, current->priority);
+ __ssx_schedule();
+
+ current->flags &= ~(SSX_THREAD_FLAG_TIMER_PEND | SSX_THREAD_FLAG_TIMED_OUT);
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_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 ssx_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 SSX specification for a full discussion of how SSX 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 SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_THREAD The API was not called from a thread
+/// context.
+
+int
+ssx_sleep(SsxInterval interval)
+{
+ return ssx_sleep_absolute(ssx_timebase_get() + interval);
+}
+
+
+/// Get information about a thread.
+///
+/// \param thread A pointer to the SsxThread to query
+///
+/// \param state The value returned through this pointer is the current state
+/// of the thread; See \ref ssx_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 SSX_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 an SSX_NONCRITICAL critical section. Since the
+/// implementation of this API does not enforce a critical section, it is not
+/// an error to call this API from a critical interrupt context.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_THREAD_AT_INFO The \a thread is a null (0) pointer.
+
+int
+ssx_thread_info_get(SsxThread *thread,
+ SsxThreadState *state,
+ SsxThreadPriority *priority,
+ int *runnable)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_INFO);
+ }
+
+ if (state) {
+ *state = thread->state;
+ }
+ if (priority) {
+ *priority = thread->priority;
+ }
+ if (runnable) {
+ *runnable = ((thread->state == SSX_THREAD_STATE_MAPPED) &&
+ __ssx_thread_queue_member(&__ssx_run_queue,
+ thread->priority));
+ }
+ return SSX_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 ssx_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 SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion, including the redundant case of
+/// attempting to change the priority of the thread to its current priority.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_THREAD the API was called from a critical
+/// interrupt context.
+///
+/// \retval -SSX_INVALID_THREAD_AT_CHANGE The \a thread is null (0) or
+/// otherwise invalid.
+///
+/// \retval -SSX_INVALID_ARGUMENT_THREAD_CHANGE The \a new_priority is invalid.
+///
+/// \retval -SSX_PRIORITY_IN_USE_AT_CHANGE The \a thread is mapped and the \a
+/// new_priority is currently in use by another thread.
+
+int
+ssx_thread_priority_change(SsxThread *thread,
+ SsxThreadPriority new_priority,
+ SsxThreadPriority *old_priority)
+{
+ SsxMachineContext ctx;
+ SsxThreadPriority priority;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_CHANGE);
+ SSX_ERROR_IF(new_priority > SSX_THREADS,
+ SSX_INVALID_ARGUMENT_THREAD_CHANGE);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ priority = thread->priority;
+
+ if (priority != new_priority) {
+
+ if (!__ssx_thread_is_mapped(thread)) {
+
+ thread->priority = new_priority;
+
+ } else {
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL(__ssx_priority_map[new_priority] != 0,
+ SSX_PRIORITY_IN_USE_AT_CHANGE,
+ &ctx);
+ }
+
+ __ssx_thread_unmap(thread);
+ thread->priority = new_priority;
+ __ssx_thread_map(thread);
+ __ssx_schedule();
+ }
+ }
+
+ if (old_priority) {
+ *old_priority = priority;
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_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 an SSX_NONCRITICAL critical section. Since the
+/// implementation of this API does not require a critical section, it is not
+/// an error to call this API from a critical interrupt context.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion.
+///
+/// \retval -SSX_INVALID_ARGUMENT_THREAD_PRIORITY The \a priority is invalid
+/// or the \a thread parameter is null (0).
+
+int
+ssx_thread_at_priority(SsxThreadPriority priority,
+ SsxThread **thread)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((priority > SSX_THREADS) || (thread == 0),
+ SSX_INVALID_ARGUMENT_THREAD_PRIORITY);
+ }
+
+ *thread = __ssx_thread_at_priority(priority);
+
+ return SSX_OK;
+}
+
+
+/// Swap thread priorities
+///
+/// \param thread_a A pointer to an initialized SsxThread
+///
+/// \param thread_b A pointer to an initialized SsxThread
+///
+/// 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 SsxThread 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 ssx_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
+/// SSX_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 SSX_OK (0) are errors; see \ref ssx_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 -SSX_ILLEGAL_CONTEXT_THREAD the API was called from a critical
+/// interrupt context.
+///
+/// \retval -SSX_INVALID_THREAD_AT_SWAP1 One or both of \a thread_a and
+/// \a thread_b is null (0) or otherwise invalid,
+///
+/// \retval -SSX_INVALID_THREAD_AT_SWAP2 the priorities of One or both of
+/// \a thread_a and \a thread_b are invalid.
+///
+/// \retval -SSX_INVALID_ARGUMENT One or both of the priorities
+/// of \a thread_a and \a thread_b is invalid.
+///
+/// \retval -SSX_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
+ssx_thread_priority_swap(SsxThread* thread_a, SsxThread* thread_b)
+{
+ SsxMachineContext ctx;
+ SsxThreadPriority priority_a, priority_b;
+ int mapped_a, mapped_b;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF((thread_a == 0) || (thread_b == 0),
+ SSX_INVALID_THREAD_AT_SWAP1);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ if (thread_a != thread_b) {
+
+ mapped_a = __ssx_thread_is_mapped(thread_a);
+ mapped_b = __ssx_thread_is_mapped(thread_b);
+ priority_a = thread_a->priority;
+ priority_b = thread_b->priority;
+
+ if (SSX_ERROR_CHECK_API) {
+ int priority_in_use;
+ SSX_ERROR_IF_CRITICAL((priority_a > SSX_THREADS) ||
+ (priority_b > SSX_THREADS),
+ SSX_INVALID_THREAD_AT_SWAP2,
+ &ctx);
+ priority_in_use =
+ (mapped_a && !mapped_b &&
+ (__ssx_thread_at_priority(priority_b) != 0)) ||
+ (!mapped_a && mapped_b &&
+ (__ssx_thread_at_priority(priority_a) != 0));
+ SSX_ERROR_IF_CRITICAL(priority_in_use,
+ SSX_PRIORITY_IN_USE_AT_SWAP, &ctx);
+ }
+
+ if (mapped_a) {
+ __ssx_thread_unmap(thread_a);
+ }
+ if (mapped_b) {
+ __ssx_thread_unmap(thread_b);
+ }
+ thread_a->priority = priority_b;
+ thread_b->priority = priority_a;
+ if (mapped_a) {
+ __ssx_thread_map(thread_a);
+ }
+ if (mapped_b) {
+ __ssx_thread_map(thread_b);
+ }
+ __ssx_schedule();
+ }
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+#undef __SSX_THREAD_CORE_C__
diff --git a/src/ssx/ssx/ssx_thread_init.c b/src/ssx/ssx/ssx_thread_init.c
new file mode 100755
index 0000000..c1a71b5
--- /dev/null
+++ b/src/ssx/ssx/ssx_thread_init.c
@@ -0,0 +1,140 @@
+// $Id: ssx_thread_init.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_thread_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_thread_init.c
+/// \brief SSX 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 "ssx.h"
+
+/// Create (initialize) a thread
+///
+/// \param thread A pointer to an SsxThread 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 SsxThread structure \em is the thread, so this
+/// memory area must not be modified by the application until the thread
+/// completes or is deleted. SSX can not tell if an SsxThread structure is
+/// currently in use as a thread control block.ssx_thread_create() will
+/// silently overwrite an SsxThread 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. SSX 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 ssx_thread_resume() targets the
+/// thread.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_THREAD_AT_CREATE The \a thread is a null (0) pointer.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT The API was called from a critical interrupt
+/// context.
+///
+/// \retval -SSX_INVALID_ARGUMENT_THREAD1 the \a thread_routine is null (0)
+///
+/// \retval -SSX_INVALID_ARGUMENT_THREAD2 the \a priority is invalid,
+///
+/// \retval -SSX_INVALID_ARGUMENT_THREAD3 the stack area wraps around
+/// the end of memory.
+///
+/// \retval -SSX_STACK_OVERFLOW The stack area at thread creation is smaller
+/// than the minimum safe size.
+
+int
+ssx_thread_create(SsxThread *thread,
+ SsxThreadRoutine thread_routine,
+ void *arg,
+ SsxAddress stack,
+ size_t stack_size,
+ SsxThreadPriority priority)
+{
+ int rc;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(thread == 0, SSX_INVALID_THREAD_AT_CREATE);
+ SSX_ERROR_IF((thread_routine == 0) ||
+ (priority >= SSX_THREADS),
+ SSX_INVALID_ARGUMENT_THREAD1);
+ }
+
+ rc = __ssx_stack_init(&stack, &stack_size);
+ if (rc) {
+ return rc;
+ }
+
+ thread->saved_stack_pointer = stack;
+ thread->stack_base = stack;
+
+ if (SSX_STACK_DIRECTION < 0) {
+
+ thread->stack_limit = stack - stack_size;
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(thread->stack_limit > thread->stack_base,
+ SSX_INVALID_ARGUMENT_THREAD2);
+ }
+
+ } else {
+
+ thread->stack_limit = stack + stack_size;
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(thread->stack_limit < thread->stack_base,
+ SSX_INVALID_ARGUMENT_THREAD3);
+ }
+ }
+
+ thread->semaphore = 0;
+ thread->priority = priority;
+ thread->state = SSX_THREAD_STATE_SUSPENDED_RUNNABLE;
+ thread->flags = 0;
+
+ ssx_timer_create_nonpreemptible(&(thread->timer),
+ __ssx_thread_timeout,
+ (void *)thread);
+
+ __ssx_thread_context_initialize(thread, thread_routine, arg);
+
+ return rc;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ssx/ssx/ssx_timer_core.c b/src/ssx/ssx/ssx_timer_core.c
new file mode 100755
index 0000000..8153acf
--- /dev/null
+++ b/src/ssx/ssx/ssx_timer_core.c
@@ -0,0 +1,447 @@
+// $Id: ssx_timer_core.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_timer_core.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_timer_core.c
+/// \brief SSX portable kernel timer handler
+///
+/// This file contains core routines that would be needed by any application
+/// that requires SSX timer support at runtime.
+///
+/// SSX implements a 'tickless' kernel - all events are scheduled at absolute
+/// times of the SSX 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". SSX
+/// 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 noncritical interrupt context.
+///
+/// SSX 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:
+///
+/// - SSX 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.
+///
+/// - SSX 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 is rescheduled if necessary (periodic events)
+/// and its callback is 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 SSX 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 SSX 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 __SSX_TIMER_CORE_C__
+
+#include "ssx.h"
+
+// This routine is only used in this file, and will always be called in
+// critical section.
+
+static inline int
+timer_active(SsxTimer* timer)
+{
+ return ssx_deque_is_queued((SsxDeque*)timer);
+}
+
+
+// This is the kernel version of ssx_timer_cancel().
+//
+// This routine is used here and by thread and semaphore routines.
+// Noncritical 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 __ssx_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
+__ssx_timer_cancel(SsxTimer *timer)
+{
+ int rc;
+ SsxDeque* timer_deque = (SsxDeque*)timer;
+ SsxTimeQueue* tq = &__ssx_time_queue;
+
+ if (!timer_active(timer)) {
+
+ rc = -SSX_TIMER_NOT_ACTIVE;
+
+ } else {
+
+ if (timer_deque == tq->cursor) {
+ tq->cursor = tq->cursor->next;
+ }
+ ssx_deque_delete(timer_deque);
+ rc = 0;
+ }
+ return rc;
+}
+
+
+// This is the kernel version of ssx_timer_schedule().
+//
+// This routine is used here and by thread and semaphore routines.
+// Noncritical 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
+__ssx_timer_schedule(SsxTimer* timer)
+{
+ SsxTimeQueue* tq = &__ssx_time_queue;
+
+ if (!timer_active(timer)) {
+ ssx_deque_push_back((SsxDeque*)tq, (SsxDeque*)timer);
+ }
+
+ if (timer->timeout < tq->next_timeout) {
+ tq->next_timeout = timer->timeout;
+ if (tq->cursor == 0) {
+ __ssx_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).
+//
+// Noncritical interrupts are (must be) disabled at entry, and this invariant
+// is checked. 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 callbacks with interrupts disabled either during or after the
+// call for timed out events, and also after every check for events that have
+// not timed out.
+//
+// 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 SsxDeque form of the time queue, casting each
+// element back up to the SsxTimer as it is processed.
+
+void
+__ssx_timer_handler()
+{
+ SsxTimeQueue* tq;
+ SsxTimebase now;
+ SsxTimer* timer;
+ SsxDeque* timer_deque;
+ SsxTimerCallback callback;
+
+ tq = &__ssx_time_queue;
+
+ if (SSX_ERROR_CHECK_KERNEL) {
+ if (tq->cursor != 0) {
+ SSX_PANIC(SSX_TIMER_HANDLER_INVARIANT);
+ }
+ }
+
+ while ((now = ssx_timebase_get()) >= tq->next_timeout) {
+
+ tq->next_timeout = SSX_TIMEBASE_MAX;
+ timer_deque = ((SsxDeque*)tq)->next;
+
+ while (timer_deque != (SsxDeque*)tq) {
+
+ timer = (SsxTimer*)timer_deque;
+ tq->cursor = timer_deque->next;
+
+ if (timer->timeout <= now) {
+
+ // The timer timed out. It is removed from the queue unless
+ // it is a peridic timer that needs to be rescheduled. We do
+ // rescheduling here in the critical section to correctly
+ // handle timers whose callbacks may cancel the timer. The
+ // timer is rescheduled in absolute time.
+ //
+ // 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.
+
+ if (timer->period == 0) {
+ ssx_deque_delete(timer_deque);
+ } else {
+ timer->timeout += timer->period;
+ tq->next_timeout = MIN(timer->timeout, tq->next_timeout);
+ }
+
+ callback = timer->callback;
+ if (callback) {
+ if (timer->options & SSX_TIMER_CALLBACK_PREEMPTIBLE) {
+ ssx_interrupt_preemption_enable();
+ callback(timer->arg);
+ } else {
+ callback(timer->arg);
+ ssx_interrupt_preemption_enable();
+ }
+ }
+ ssx_interrupt_preemption_disable();
+
+ } else {
+
+ // This timer has not timed out. Its timeout will simply
+ // participate in the computation of the next timeout. For
+ // interrupt latency reasons we always allow a period of
+ // interrupt preemption.
+
+ tq->next_timeout = MIN(timer->timeout, tq->next_timeout);
+ ssx_interrupt_preemption_enable();
+ ssx_interrupt_preemption_disable();
+ }
+
+ timer_deque = tq->cursor;
+ }
+ }
+
+ tq->cursor = 0;
+
+ // Finally, reschedule the next timeout
+
+ __ssx_schedule_hardware_timeout(tq->next_timeout);
+}
+
+
+/// Schedule a timer in absolute time.
+///
+/// \param timer The SsxTimer to schedule.
+///
+/// \param timeout The timer will be scheduled to time out at this absolute
+/// time. Note that if the \a timeout is less than the current time then the
+/// timer will be scheduled at a minimum timeout in the future and the
+/// callback will be executed in an interrupt context.
+///
+/// \param period If non-0, then when the timer times out it will rescheduled
+/// to time out again at the absolute time equal to the last timeout time plus
+/// the \a period. By convention a \a period of 0 indicates a one-shot
+/// timer that is not rescheduled.
+///
+/// Once created with ssx_timer_create() a timer can be \e scheduled, which
+/// queues the timer in the kernel time queue. It is not an error to call
+/// ssx_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 SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_TIMER_AT_SCHEDULE A a null (0) pointer was provided as
+/// the \a timer argument.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_TIMER The call was made from a critical
+/// interrupt context.
+
+int
+ssx_timer_schedule_absolute(SsxTimer *timer,
+ SsxTimebase timeout,
+ SsxInterval period)
+
+{
+ SsxMachineContext ctx;
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(timer == 0, SSX_INVALID_TIMER_AT_SCHEDULE);
+ SSX_ERROR_IF(__ssx_kernel_context_critical_interrupt(),
+ SSX_ILLEGAL_CONTEXT_TIMER);
+ }
+
+ timer->timeout = timeout;
+ timer->period = period;
+ __ssx_timer_schedule(timer);
+
+ ssx_critical_section_exit(&ctx);
+
+ return SSX_OK;
+}
+
+
+/// Schedule a timer for an interval relative to the current time.
+///
+/// \param timer The SsxTimer to schedule.
+///
+/// \param interval The timer will be scheduled to time out at the current
+/// time (ssx_timebase_get()) plus this \a interval.
+///
+/// \param period If non-0, then when the timer times out it will rescheduled
+/// to time out again at the absolute time equal to the last timeout time plus
+/// the \a period. By convention a \a period of 0 indicates a one-shot
+/// timer that is not rescheduled.
+///
+/// Once created with ssx_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
+/// ssx_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 SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_TIMER_AT_SCHEDULE A a null (0) pointer was provided as
+/// the \a timer argument.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_TIMER The call was made from a critical
+/// interrupt context.
+
+int
+ssx_timer_schedule(SsxTimer *timer,
+ SsxInterval interval,
+ SsxInterval period)
+{
+ return ssx_timer_schedule_absolute(timer,
+ ssx_timebase_get() + interval,
+ period);
+}
+
+
+/// Cancel (dequeue) a timer.
+///
+/// \param timer The SsxTimer to cancel.
+///
+/// Timers can be canceled at any time. It is never an error to call
+/// ssx_timer_cancel() on an SsxTimer object after it is created. Memory used
+/// by an SsxTimer can be safely reused for another purpose after a successful
+/// call ofssx_timer_cancel().
+///
+/// Return values other than SSX_OK (0) are not necessarily errors; see \ref
+/// ssx_errors
+///
+/// The following return codes are non-error codes:
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_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 -SSX_INVALID_TIMER_AT_CANCEL The \a timer is a null (0) pointer.
+///
+/// \retval -SSX_ILLEGAL_CONTEXT_TIMER The call was made from a critical
+/// interrupt context.
+///
+
+int
+ssx_timer_cancel(SsxTimer *timer)
+{
+ SsxMachineContext ctx;
+ int rc = SSX_OK;
+
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF_CRITICAL_INTERRUPT_CONTEXT();
+ SSX_ERROR_IF(timer == 0, SSX_INVALID_TIMER_AT_CANCEL);
+ }
+
+ ssx_critical_section_enter(SSX_NONCRITICAL, &ctx);
+
+ rc = __ssx_timer_cancel(timer);
+
+ ssx_critical_section_exit(&ctx);
+
+ return rc;
+}
+
+
+/// Get information about a timer.
+///
+/// \param timer The SsxTimer 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 an SSX_NONCRITICAL critical section. Since the
+/// implementation of this API does not require a critical section, it is not
+/// an error to call this API from a critical interrupt context.
+///
+/// Return values other than SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_TIMER_AT_INFO The \a timer is a null (0) pointer.
+
+int
+ssx_timer_info_get(SsxTimer *timer,
+ SsxTimebase *timeout,
+ int *active)
+
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF(timer == 0, SSX_INVALID_TIMER_AT_INFO);
+ }
+
+ if (timeout) {
+ *timeout = timer->timeout;
+ }
+ if (active) {
+ *active = timer_active(timer);
+ }
+
+ return SSX_OK;
+}
+
+#undef __SSX_TIMER_CORE_C__
diff --git a/src/ssx/ssx/ssx_timer_init.c b/src/ssx/ssx/ssx_timer_init.c
new file mode 100755
index 0000000..6c35ea6
--- /dev/null
+++ b/src/ssx/ssx/ssx_timer_init.c
@@ -0,0 +1,124 @@
+// $Id: ssx_timer_init.c,v 1.2 2014/02/03 01:30:44 daviddu Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssx_timer_init.c,v $
+//-----------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2013
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//-----------------------------------------------------------------------------
+
+/// \file ssx_timer_init.c
+/// \brief SSX 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 "ssx.h"
+
+// Implementation of timer creation
+
+static int
+_ssx_timer_create(SsxTimer *timer,
+ SsxTimerCallback callback,
+ void *arg,
+ int options)
+{
+ if (SSX_ERROR_CHECK_API) {
+ SSX_ERROR_IF((timer == 0), SSX_INVALID_TIMER_AT_CREATE);
+ }
+
+ ssx_deque_element_create((SsxDeque*)timer);
+ timer->timeout = 0;
+ timer->period = 0;
+ timer->callback = callback;
+ timer->arg = arg;
+ timer->options = options;
+
+ return SSX_OK;
+}
+
+
+/// Create (initialize) a preemptible timer.
+///
+/// \param timer The SsxTimer to initialize.
+///
+/// \param callback The timer callback
+///
+/// \param arg Private data provided to the callback.
+///
+/// Once created with ssx_timer_create() a timer can be scheduled with
+/// ssx_timer_schedule() or ssx_timer_schedule_absolute(), which queues the
+/// timer in the kernel time queue. Timers can be cancelled by a call of
+/// ssx_timer_cancel().
+///
+/// Timers created with ssx_timer_create() are always run as noncritical
+/// interrupt handlers with interrupt preemption enabled. Timer callbacks are
+/// free to enter critical sections of any priorioty if required, but must
+/// always exit with noncritical interrupts enabled.
+///
+/// Caution: SSX has no way to know if an SsxTimer structure provided to
+/// ssx_timer_create() is safe to use as a timer, and will silently modify
+/// whatever memory is provided.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_TIMER_AT_CREATE The \a timer is a null (0) pointer.
+
+int
+ssx_timer_create(SsxTimer *timer,
+ SsxTimerCallback callback,
+ void *arg)
+{
+ return _ssx_timer_create(timer, callback, arg,
+ SSX_TIMER_CALLBACK_PREEMPTIBLE);
+}
+
+
+/// Create (initialize) a nonpreemptible timer.
+///
+/// \param timer The SsxTimer to initialize.
+///
+/// \param callback The timer callback
+///
+/// \param arg Private data provided to the callback.
+///
+/// Once created with ssx_timer_create_preemptible() a timer can be scheduled
+/// with ssx_timer_schedule() or ssx_timer_schedule_absolute(), which queues
+/// the timer in the kernel time queue. Timers can be cancelled by a call of
+/// ssx_timer_cancel().
+///
+/// Timers created with ssx_timer_create_nonpreemptible() are always run as
+/// noncritical interrupt handlers with interrupt preemption disabled. Timer
+/// callbacks are free to later enable preemption if desired, but must always
+/// exit with noncritical interrupts disabled.
+///
+/// \note The use of ssx_timer_create_nonpreemptible() should be rare, and the
+/// timer callbacks should be short and sweet to avoid long interrupt
+/// latencies for other interrupts. This API was initially introduced for use
+/// by the SSX kernel itself when scheduling thread-timer callbacks to avoid
+/// potential race conditions with other interrupts that may modify thread
+/// state or the state of the time queue. Applications may also require this
+/// facility to guarantee a consistent state in the event that other
+/// interrupts may cancel the timer.
+///
+/// Caution: SSX has no way to know if an SsxTimer structure provided to
+/// ssx_timer_create() is safe to use as a timer, and will silently modify
+/// whatever memory is provided.
+///
+/// Return values other then SSX_OK (0) are errors; see \ref ssx_errors
+///
+/// \retval 0 Successful completion
+///
+/// \retval -SSX_INVALID_TIMER_AT_CREATE The \a timer is a null (0) pointer.
+
+int
+ssx_timer_create_nonpreemptible(SsxTimer *timer,
+ SsxTimerCallback callback,
+ void *arg)
+{
+ return _ssx_timer_create(timer, callback, arg, 0);
+}
+
+
diff --git a/src/ssx/ssx/ssxssxfiles.mk b/src/ssx/ssx/ssxssxfiles.mk
new file mode 100755
index 0000000..e78e986
--- /dev/null
+++ b/src/ssx/ssx/ssxssxfiles.mk
@@ -0,0 +1,35 @@
+# $Id: ssxssxfiles.mk,v 1.2 2014/06/26 13:02:00 cmolsen Exp $
+# $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ssx/ssxssxfiles.mk,v $
+# @file ssxpgpfiles.mk
+#
+# @brief mk for including pgp object files
+#
+# @page ChangeLogs Change Logs
+# @section ssxpgpfiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+# @pb00E pbavari 03/11/2012 Makefile ODE support
+#
+# @endverbatim
+#
+##########################################################################
+# Include
+##########################################################################
+
+
+##########################################################################
+# Object Files
+##########################################################################
+SSX-C-SOURCES = ssx_core.c ssx_init.c ssx_stack_init.c
+
+SSX-TIMER-C-SOURCES += ssx_timer_core.c ssx_timer_init.c
+
+SSX-THREAD-C-SOURCES += ssx_thread_init.c ssx_thread_core.c \
+ ssx_semaphore_init.c ssx_semaphore_core.c
+
+SSX_OBJECTS += $(SSX-C-SOURCES:.c=.o)
+
OpenPOWER on IntegriCloud