diff --git a/Makefile.am b/Makefile.am
index d7a0e31..281da87 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,7 +12,8 @@ GIT_SHA1 ?= `git --work-tree=$(top_srcdir) --git-dir=$(top_srcdir)/.git describe
 libpdbg_tests = libpdbg_target_test \
 		libpdbg_probe_test1 \
 		libpdbg_probe_test2 \
-		libpdbg_probe_test3
+		libpdbg_probe_test3 \
+		libpdbg_p9_fapi_translation_test
 
 bin_PROGRAMS = pdbg
 check_PROGRAMS = $(libpdbg_tests) optcmd_test hexdump_test cronus_proxy
@@ -230,6 +231,13 @@ libpdbg_probe_test3_LDADD = $(libpdbg_test_ldadd)
 
 src/tests/libpdbg_probe_test.c: fake.dt.h
 
+libpdbg_p9_fapi_translation_test_SOURCES = src/tests/libpdbg_p9_fapi_translation_test.C \
+					   src/tests/p9_scominfo.C
+libpdbg_p9_fapi_translation_test_CFLAGS = $(libpdbg_test_cflags)
+libpdbg_p9_fapi_translation_test_LDFLAGS = $(libpdbg_test_ldflags)
+libpdbg_p9_fapi_translation_test_LDADD = $(libpdbg_test_ldadd)
+
+
 M4_V = $(M4_V_$(V))
 M4_V_ = $(M4_V_$(AM_DEFAULT_VERBOSITY))
 M4_V_0 = @echo "  M4      " $@;
diff --git a/configure.ac b/configure.ac
index c41e13a..f92d337 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,6 +3,7 @@ AM_INIT_AUTOMAKE([subdir-objects])
 AM_SILENT_RULES([yes])
 
 AC_PROG_CC
+AC_PROG_CXX
 AM_PROG_AS
 AC_PROG_LIBTOOL
 
diff --git a/src/tests/libpdbg_p9_fapi_translation_test.C b/src/tests/libpdbg_p9_fapi_translation_test.C
new file mode 100644
index 0000000..0b2d23b
--- /dev/null
+++ b/src/tests/libpdbg_p9_fapi_translation_test.C
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <inttypes.h>
+
+#define class klass
+#include "libpdbg/libpdbg.h"
+#include "libpdbg/hwunit.h"
+#include "libpdbg/target.h"
+#undef class
+
+#include "p9_scominfo.H"
+
+#define MAX_INDEX 30
+
+extern struct hw_unit_info p9_core_hw_unit;
+extern struct hw_unit_info p9_ex_hw_unit;
+extern struct hw_unit_info p9_mba_hw_unit;
+extern struct hw_unit_info p9_mcs_hw_unit;
+extern struct hw_unit_info p9_xbus_hw_unit;
+extern struct hw_unit_info p9_abus_hw_unit;
+extern struct hw_unit_info p9_l4_hw_unit;
+extern struct hw_unit_info p9_eq_hw_unit;
+extern struct hw_unit_info p9_mca_hw_unit;
+extern struct hw_unit_info p9_mcbist_hw_unit;
+extern struct hw_unit_info p9_mi_hw_unit;
+extern struct hw_unit_info p9_dmi_hw_unit;
+extern struct hw_unit_info p9_obus_hw_unit;
+extern struct hw_unit_info p9_obus_brick_hw_unit;
+extern struct hw_unit_info p9_sbe_hw_unit;
+extern struct hw_unit_info p9_ppe_hw_unit;
+extern struct hw_unit_info p9_pec_hw_unit;
+extern struct hw_unit_info p9_phb_hw_unit;
+extern struct hw_unit_info p9_mc_hw_unit;
+extern struct hw_unit_info p9_mem_port_hw_unit;
+extern struct hw_unit_info p9_nmmu_hw_unit;
+extern struct hw_unit_info p9_pau_hw_unit;
+extern struct hw_unit_info p9_iohs_hw_unit;
+extern struct hw_unit_info p9_fc_hw_unit;
+extern struct hw_unit_info p9_pauc_hw_unit;
+extern struct hw_unit_info p9_chiplet_hw_unit;
+
+int test_unit_translation(struct pdbg_target *target, p9ChipUnits_t cu, int index, uint64_t addr)
+{
+	uint64_t pdbg_addr, fapi_addr;
+
+	target->index = index;
+
+	/* TODO: Check standard chiplet translation */
+	if (!target->translate)
+		return 1;
+
+	pdbg_addr = target->translate(target, addr);
+	fapi_addr = p9_scominfo_createChipUnitScomAddr(cu, index, addr, 0);
+
+	if (pdbg_addr != fapi_addr)
+		printf("PDBG Address 0x%016" PRIx64 " does not match FAPI Address 0x%016" PRIx64
+		       " for address 0x%016" PRIx64 " on target %s@%d\n",
+		       pdbg_addr, fapi_addr, addr, pdbg_target_path(target), index);
+
+	return pdbg_addr == fapi_addr;
+}
+
+int main(void)
+{
+	uint64_t addr;
+	int i, index;
+	struct pdbg_target *p9_cu[NONE] = {0};
+
+	pdbg_set_logfunc(NULL);
+
+	p9_cu[PU_C_CHIPUNIT] = (struct pdbg_target *) p9_core_hw_unit.hw_unit;
+        p9_cu[PU_EQ_CHIPUNIT] = (struct pdbg_target *) p9_eq_hw_unit.hw_unit;
+        p9_cu[PU_EX_CHIPUNIT] = (struct pdbg_target *) p9_ex_hw_unit.hw_unit;
+        p9_cu[PU_XBUS_CHIPUNIT] = (struct pdbg_target *) p9_xbus_hw_unit.hw_unit;
+        p9_cu[PU_OBUS_CHIPUNIT] = (struct pdbg_target *) p9_obus_hw_unit.hw_unit;
+        p9_cu[PU_PEC_CHIPUNIT] = (struct pdbg_target *) p9_pec_hw_unit.hw_unit;
+        p9_cu[PU_PHB_CHIPUNIT] = (struct pdbg_target *) p9_phb_hw_unit.hw_unit;
+        p9_cu[PU_MI_CHIPUNIT] = (struct pdbg_target *) p9_mi_hw_unit.hw_unit;
+        p9_cu[PU_DMI_CHIPUNIT] = (struct pdbg_target *) p9_dmi_hw_unit.hw_unit;
+        p9_cu[PU_MCS_CHIPUNIT] = (struct pdbg_target *) p9_mcs_hw_unit.hw_unit;
+        p9_cu[PU_MCA_CHIPUNIT] = (struct pdbg_target *) p9_mca_hw_unit.hw_unit;
+        p9_cu[PU_MCBIST_CHIPUNIT] = (struct pdbg_target *) p9_mcbist_hw_unit.hw_unit;
+        p9_cu[PU_PERV_CHIPUNIT] = (struct pdbg_target *) p9_chiplet_hw_unit.hw_unit;
+        p9_cu[PU_PPE_CHIPUNIT] = (struct pdbg_target *) p9_ppe_hw_unit.hw_unit;
+        p9_cu[PU_SBE_CHIPUNIT] = (struct pdbg_target *) p9_sbe_hw_unit.hw_unit;
+        p9_cu[PU_MC_CHIPUNIT] = (struct pdbg_target *) p9_mc_hw_unit.hw_unit;
+
+
+	/* Need to initialise the dn_name so pdbg_target_path doesn't segfault */
+	((struct pdbg_target *) p9_core_hw_unit.hw_unit)->dn_name = "p9_core";
+	((struct pdbg_target *) p9_chiplet_hw_unit.hw_unit)->dn_name = "p9_chiplet";
+	((struct pdbg_target *) p9_ex_hw_unit.hw_unit)->dn_name = "p9_ex";
+	((struct pdbg_target *) p9_mba_hw_unit.hw_unit)->dn_name = "p9_mba";
+	((struct pdbg_target *) p9_mcs_hw_unit.hw_unit)->dn_name = "p9_mcs";
+	((struct pdbg_target *) p9_xbus_hw_unit.hw_unit)->dn_name = "p9_xbus";
+	((struct pdbg_target *) p9_abus_hw_unit.hw_unit)->dn_name = "p9_abus";
+	((struct pdbg_target *) p9_l4_hw_unit.hw_unit)->dn_name = "p9_l4";
+	((struct pdbg_target *) p9_eq_hw_unit.hw_unit)->dn_name = "p9_eq";
+	((struct pdbg_target *) p9_mca_hw_unit.hw_unit)->dn_name = "p9_mca";
+	((struct pdbg_target *) p9_mcbist_hw_unit.hw_unit)->dn_name = "p9_mcbist";
+	((struct pdbg_target *) p9_mi_hw_unit.hw_unit)->dn_name = "p9_mi";
+	((struct pdbg_target *) p9_dmi_hw_unit.hw_unit)->dn_name = "p9_dmi";
+	((struct pdbg_target *) p9_obus_hw_unit.hw_unit)->dn_name = "p9_obus";
+	((struct pdbg_target *) p9_obus_brick_hw_unit.hw_unit)->dn_name = "p9_obus_brick";
+	((struct pdbg_target *) p9_sbe_hw_unit.hw_unit)->dn_name = "p9_sbe";
+	((struct pdbg_target *) p9_ppe_hw_unit.hw_unit)->dn_name = "p9_ppe";
+	((struct pdbg_target *) p9_pec_hw_unit.hw_unit)->dn_name = "p9_pec";
+	((struct pdbg_target *) p9_phb_hw_unit.hw_unit)->dn_name = "p9_phb";
+	((struct pdbg_target *) p9_mc_hw_unit.hw_unit)->dn_name = "p9_mc";
+	((struct pdbg_target *) p9_mem_port_hw_unit.hw_unit)->dn_name = "p9_mem_port";
+	((struct pdbg_target *) p9_nmmu_hw_unit.hw_unit)->dn_name = "p9_nmmu";
+	((struct pdbg_target *) p9_pau_hw_unit.hw_unit)->dn_name = "p9_pau";
+	((struct pdbg_target *) p9_iohs_hw_unit.hw_unit)->dn_name = "p9_iohs";
+	((struct pdbg_target *) p9_fc_hw_unit.hw_unit)->dn_name = "p9_fc";
+	((struct pdbg_target *) p9_pauc_hw_unit.hw_unit)->dn_name = "p9_pauc";
+
+	for (i = 0; i < NONE; i++) {
+		if (p9_cu[i])
+			for (index = 0; index < MAX_INDEX; index++) {
+				printf("Testing %s@%d\n", pdbg_target_path(p9_cu[i]), index);
+
+				/* Test every sat offset */
+				for (addr = 0; addr < 0xffffffff; addr += 0x40)
+					assert(test_unit_translation(p9_cu[i], (p9ChipUnits_t) i, index, addr));
+			}
+	}
+}
diff --git a/src/tests/p9_cu.H b/src/tests/p9_cu.H
new file mode 100644
index 0000000..3abcd14
--- /dev/null
+++ b/src/tests/p9_cu.H
@@ -0,0 +1,119 @@
+/* IBM_PROLOG_BEGIN_TAG                                                   */
+/* This is an automatically generated prolog.                             */
+/*                                                                        */
+/* $Source: chips/p9/common/scominfo/p9_cu.H $                            */
+/*                                                                        */
+/* IBM CONFIDENTIAL                                                       */
+/*                                                                        */
+/* EKB Project                                                            */
+/*                                                                        */
+/* COPYRIGHT 2015,2018                                                    */
+/* [+] International Business Machines Corp.                              */
+/*                                                                        */
+/*                                                                        */
+/* The source code for this program is not published or otherwise         */
+/* divested of its trade secrets, irrespective of what has been           */
+/* deposited with the U.S. Copyright Office.                              */
+/*                                                                        */
+/* IBM_PROLOG_END_TAG                                                     */
+///
+/// @file p9_cu.H
+/// @brief P9 chip unit definitions
+///
+/// HWP HWP Owner: jmcgill@us.ibm.com
+/// HWP FW Owner: dcrowell@us.ibm.com
+/// HWP Team: Infrastructure
+/// HWP Level: 2
+/// HWP Consumed by: FSP/HB
+///
+
+#ifndef P9_CU_H
+#define P9_CU_H
+
+// includes
+#include <stdint.h>
+
+extern "C"
+{
+
+    /// P9 chip unit type enumeration
+    typedef enum
+    {
+        P9C_CHIP,            ///< Cumulus chip (included for future expansion)
+        P9N_CHIP,            ///< Nimbus chip (included for future expansion)
+        P9A_CHIP,            ///< Axone chip (included for future expansion)
+        PU_C_CHIPUNIT,       ///< Core
+        PU_EQ_CHIPUNIT,      ///< Quad
+        PU_EX_CHIPUNIT,      ///< EX
+        PU_XBUS_CHIPUNIT,    ///< XBUS
+        PU_OBUS_CHIPUNIT,    ///< OBUS
+        PU_NV_CHIPUNIT,      ///< NV Link Brick
+        PU_PEC_CHIPUNIT,     ///< PCIe (PEC)
+        PU_PHB_CHIPUNIT,     ///< PCIe (PHB)
+        PU_MI_CHIPUNIT,      ///< MI (Cumulus only)
+        PU_DMI_CHIPUNIT,     ///< DMI (Cumulus only)
+        PU_MCC_CHIPUNIT,     ///< MCC MC Channels (Axone only)
+        PU_OMIC_CHIPUNIT,    ///< OMI Cplt (Axone only)
+        PU_OMI_CHIPUNIT,     ///< OMI (Axone only)
+        PU_MCS_CHIPUNIT,     ///< MCS (Nimbus only)
+        PU_MCA_CHIPUNIT,     ///< MCA (Nimbus only)
+        PU_MCBIST_CHIPUNIT,  ///< MCBIST (Nimbus only)
+        PU_PERV_CHIPUNIT,    ///< Pervasive
+        PU_PPE_CHIPUNIT,     ///< PPE
+        PU_SBE_CHIPUNIT,     ///< SBE
+        PU_CAPP_CHIPUNIT,    ///< CAPP
+        PU_MC_CHIPUNIT,    ///< mc
+        NONE,                ///< None/Invalid
+    } p9ChipUnits_t;
+
+    /// P9 chip unit pairing struct
+    struct p9_chipUnitPairing_t
+    {
+        /// @brief Default constructor
+        p9_chipUnitPairing_t()
+            : chipUnitType(NONE), chipUnitNum(0) {}
+        /// @brief Construct from type/instance number
+        p9_chipUnitPairing_t (p9ChipUnits_t type, uint32_t num)
+            : chipUnitType(type), chipUnitNum(num) {}
+
+        p9ChipUnits_t chipUnitType;  ///< chip unit type
+        uint32_t chipUnitNum;        ///< chip unit instance number
+    };
+
+    /// P9 PPE Chip Unit Instance Number enumeration
+    /// PPE name        Nimbus    Cumulus   Axone
+    /// SBE             0         0         0
+    /// GPE0..3         10..13    10..13    10..13
+    /// CME0            20..25    20..25    20..25
+    /// CME1            30..35    30..35    30..35
+    /// IO PPE (xbus)   40        40        40
+    /// IO PPE (obus)   41,44     41..44    41,44
+    /// IO PPE (dmi)    NA        45,46     NA
+    /// Powerbus PPEs   50        50        50
+    /// IO PPE (omi)    NA        NA        56..61
+    typedef enum
+    {
+        PPE_SBE_CHIPUNIT_NUM         =  0,
+        PPE_GPE0_CHIPUNIT_NUM        = 10,
+        PPE_GPE3_CHIPUNIT_NUM        = 13,
+        PPE_EQ0_CME0_CHIPUNIT_NUM    = 20,   // Quad0-CME0
+        PPE_EQ5_CME0_CHIPUNIT_NUM    = 25,   // Quad5-CME0
+        PPE_EQ0_CME1_CHIPUNIT_NUM    = 30,   // Quad0-CME1
+        PPE_EQ5_CME1_CHIPUNIT_NUM    = 35,   // Quad5-CME1
+        PPE_IO_XBUS_CHIPUNIT_NUM     = 40,
+        PPE_IO_OB0_CHIPUNIT_NUM      = 41,
+        PPE_IO_OB1_CHIPUNIT_NUM      = 42,
+        PPE_IO_OB2_CHIPUNIT_NUM      = 43,
+        PPE_IO_OB3_CHIPUNIT_NUM      = 44,
+        PPE_IO_DMI0_CHIPUNIT_NUM     = 45,
+        PPE_IO_DMI1_CHIPUNIT_NUM     = 46,
+        PPE_PB0_CHIPUNIT_NUM         = 50,
+        PPE_PB2_CHIPUNIT_NUM         = 52,
+        PPE_OMI_CHIPUNIT_NUM         = 56,
+        PPE_LAST_CHIPUNIT_NUM        = PPE_OMI_CHIPUNIT_NUM,
+    } p9_ppe_chip_unit_instance_num_t;
+
+} // extern "C"
+
+#endif /* P9_CU_H */
+
diff --git a/src/tests/p9_scom_addr.H b/src/tests/p9_scom_addr.H
new file mode 100644
index 0000000..c4c1202
--- /dev/null
+++ b/src/tests/p9_scom_addr.H
@@ -0,0 +1,647 @@
+/* IBM_PROLOG_BEGIN_TAG                                                   */
+/* This is an automatically generated prolog.                             */
+/*                                                                        */
+/* $Source: chips/p9/common/scominfo/p9_scom_addr.H $                     */
+/*                                                                        */
+/* IBM CONFIDENTIAL                                                       */
+/*                                                                        */
+/* EKB Project                                                            */
+/*                                                                        */
+/* COPYRIGHT 2015,2018                                                    */
+/* [+] International Business Machines Corp.                              */
+/*                                                                        */
+/*                                                                        */
+/* The source code for this program is not published or otherwise         */
+/* divested of its trade secrets, irrespective of what has been           */
+/* deposited with the U.S. Copyright Office.                              */
+/*                                                                        */
+/* IBM_PROLOG_END_TAG                                                     */
+///
+/// @file p9_scom_addr.H
+/// @brief P9 SCOM address class
+///
+/// HWP HWP Owner: jmcgill@us.ibm.com
+/// HWP FW Owner: dcrowell@us.ibm.com
+/// HWP Team: Infrastructure
+/// HWP Level: 2
+/// HWP Consumed by: FSP/HB
+///
+
+#ifndef P9_SCOM_ADDR_H
+#define P9_SCOM_ADDR_H
+
+// includes
+#include <stdint.h>
+
+extern "C"
+{
+    /// P9 Chiplet ID enumeration
+    typedef enum
+    {
+        PIB_CHIPLET_ID  = 0x00,     ///< PIB chiplet
+        PERV_CHIPLET_ID = 0x01,     ///< TP chiplet
+        N0_CHIPLET_ID   = 0x02,     ///< Nest0 (North) chiplet
+        N1_CHIPLET_ID   = 0x03,     ///< Nest1 (East) chiplet
+        N2_CHIPLET_ID   = 0x04,     ///< Nest2 (South) chiplet
+        N3_CHIPLET_ID   = 0x05,     ///< Nest3 (West) chiplet
+        XB_CHIPLET_ID   = 0x06,     ///< XBus chiplet
+        MC01_CHIPLET_ID = 0x07,     ///< MC01 (West) chiplet
+        MC23_CHIPLET_ID = 0x08,     ///< MC23 (East) chiplet
+        OB0_CHIPLET_ID  = 0x09,     ///< OBus0 chiplet
+        OB1_CHIPLET_ID  = 0x0A,     ///< OBus1 chiplet (Cumulus only)
+        OB2_CHIPLET_ID  = 0x0B,     ///< OBus2 chiplet (Cumulus only)
+        OB3_CHIPLET_ID  = 0x0C,     ///< OBus3 chiplet
+        PCI0_CHIPLET_ID = 0x0D,     ///< PCIe0 chiplet
+        PCI1_CHIPLET_ID = 0x0E,     ///< PCIe1 chiplet
+        PCI2_CHIPLET_ID = 0x0F,     ///< PCIe2 chiplet
+        EP00_CHIPLET_ID = 0x10,     ///< Quad0 chiplet (EX0/1)
+        EP01_CHIPLET_ID = 0x11,     ///< Quad1 chiplet (EX2/3)
+        EP02_CHIPLET_ID = 0x12,     ///< Quad2 chiplet (EX4/5)
+        EP03_CHIPLET_ID = 0x13,     ///< Quad3 chiplet (EX6/7)
+        EP04_CHIPLET_ID = 0x14,     ///< Quad4 chiplet (EX8/9)
+        EP05_CHIPLET_ID = 0x15,     ///< Quad5 chiplet (EX10/11)
+        EC00_CHIPLET_ID = 0x20,     ///< Core0 chiplet (Quad0, EX0, C0)
+        EC01_CHIPLET_ID = 0x21,     ///< Core1 chiplet (Quad0, EX0, C1)
+        EC02_CHIPLET_ID = 0x22,     ///< Core2 chiplet (Quad0, EX1, C0)
+        EC03_CHIPLET_ID = 0x23,     ///< Core3 chiplet (Quad0, EX1, C1)
+        EC04_CHIPLET_ID = 0x24,     ///< Core4 chiplet (Quad1, EX2, C0)
+        EC05_CHIPLET_ID = 0x25,     ///< Core5 chiplet (Quad1, EX2, C1)
+        EC06_CHIPLET_ID = 0x26,     ///< Core6 chiplet (Quad1, EX3, C0)
+        EC07_CHIPLET_ID = 0x27,     ///< Core7 chiplet (Quad1, EX3, C1)
+        EC08_CHIPLET_ID = 0x28,     ///< Core8 chiplet (Quad2, EX4, C0)
+        EC09_CHIPLET_ID = 0x29,     ///< Core9 chiplet (Quad2, EX4, C1)
+        EC10_CHIPLET_ID = 0x2A,     ///< Core10 chiplet (Quad2, EX5, C0)
+        EC11_CHIPLET_ID = 0x2B,     ///< Core11 chiplet (Quad2, EX5, C1)
+        EC12_CHIPLET_ID = 0x2C,     ///< Core12 chiplet (Quad3, EX6, C0)
+        EC13_CHIPLET_ID = 0x2D,     ///< Core13 chiplet (Quad3, EX6, C1)
+        EC14_CHIPLET_ID = 0x2E,     ///< Core14 chiplet (Quad3, EX7, C0)
+        EC15_CHIPLET_ID = 0x2F,     ///< Core15 chiplet (Quad3, EX7, C1)
+        EC16_CHIPLET_ID = 0x30,     ///< Core16 chiplet (Quad4, EX8, C0)
+        EC17_CHIPLET_ID = 0x31,     ///< Core17 chiplet (Quad4, EX8, C1)
+        EC18_CHIPLET_ID = 0x32,     ///< Core18 chiplet (Quad4, EX9, C0)
+        EC19_CHIPLET_ID = 0x33,     ///< Core19 chiplet (Quad4, EX9, C1)
+        EC20_CHIPLET_ID = 0x34,     ///< Core20 chiplet (Quad5, EX10, C0)
+        EC21_CHIPLET_ID = 0x35,     ///< Core21 chiplet (Quad5, EX10, C1)
+        EC22_CHIPLET_ID = 0x36,     ///< Core22 chiplet (Quad5, EX11, C0)
+        EC23_CHIPLET_ID = 0x37      ///< Core23 chiplet (Quad5, EX11, C1)
+    } p9_chiplet_id_t;
+
+    /// P9 Chiplet ID enumeration
+    typedef enum
+    {
+        PPE_EP00_CHIPLET_ID = 0x09,     ///< Quad0
+        PPE_EP01_CHIPLET_ID = 0x0A,     ///< Quad1
+        PPE_EP02_CHIPLET_ID = 0x0B,     ///< Quad2
+        PPE_EP03_CHIPLET_ID = 0x0C,     ///< Quad3
+        PPE_EP04_CHIPLET_ID = 0x0D,     ///< Quad4
+        PPE_EP05_CHIPLET_ID = 0x0E      ///< Quad5
+    } p9_ppe_chiplet_id_t;
+
+    /// P9 SCOM port ID enumeration
+    typedef enum
+    {
+        GPREG_PORT_ID = 0x0,        ///< GP registers
+        UNIT_PORT_ID = 0x1,         ///< Functional registers
+        CME_PORT_ID = 0x2,          ///< CME registers
+        CC_PORT_ID = 0x3,           ///< Clock control registers
+        FIR_PORT_ID = 0x4,          ///< Common FIR registers
+        CPM_PORT_ID = 0x5,          ///< CPM registers
+        GPE_PORT_ID = 0x6,          ///< PPE GPE registers (For TP only)
+        SBE_PORT_ID = 0xE,          ///< SBE PM registers (For TP only)
+        PCBSLV_PORT_ID = 0xF        ///< PCB Slave registers
+    } p9_port_id_t;
+
+    /// P9 Core chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_core_top.vhdl
+    typedef enum
+    {
+        EC_PSCM_RING_ID = 0x0,      ///< PSCOM
+        EC_PERV_RING_ID = 0x1,      ///< PERV
+        EC_PC_0_RING_ID = 0x2,      ///< PC_0
+        EC_PC_1_RING_ID = 0x3,      ///< PC_1
+        EC_PC_2_RING_ID = 0x4,      ///< PC_2
+        EC_PC_3_RING_ID = 0x5       ///< PC_3
+    } p9_ec_ring_id_t;
+
+    /// P9 Quad chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_l3_top.vhdl
+    typedef enum
+    {
+        EQ_PSCM_RING_ID = 0x0,      ///< PSCOM
+        EQ_PERV_RING_ID = 0x1,      ///< PERV
+        EQ_L2_0_RING_ID = 0x2,      ///< L2_0
+        EQ_L2_1_RING_ID = 0x3,      ///< L2_1
+        EQ_NC_0_RING_ID = 0x4,      ///< NC_0
+        EQ_NC_1_RING_ID = 0x5,      ///< NC_1
+        EQ_L3_0_RING_ID = 0x6,      ///< L3_0
+        EQ_L3_1_RING_ID = 0x7,      ///< L3_1
+        EQ_CME_0_RING_ID = 0x8,     ///< CME_0
+        EQ_CME_1_RING_ID = 0x9,     ///< CME_1
+        EQ_L2_0_TRA_RING_ID = 0xA,  ///< L2_0_TRA
+        EQ_L2_1_TRA_RING_ID = 0xB   ///< L2_1_TRA
+    } p9_eq_ring_id_t;
+
+    /// P9 N0 chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_n0_top.vhdl
+    typedef enum
+    {
+        N0_PSCM_RING_ID = 0x0,      ///< PSCOM
+        N0_PERV_RING_ID = 0x1,      ///< PERV
+        N0_CXA0_0_RING_ID = 0x2,    ///< CXA0_0
+        N0_NX_0_RING_ID = 0x4,      ///< NX_0
+        N0_PBIOE0_0_RING_ID = 0x6,  ///< PBIOE0_0
+        N0_PBIOE1_0_RING_ID = 0x7,  ///< PBIOE1_0
+        N0_PBIOE2_0_RING_ID = 0x8   ///< PBIOE2_0
+    } p9_n0_ring_id_t;
+
+    /// P9 N1 chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_n1_top.vhdl
+    typedef enum
+    {
+        N1_PSCM_RING_ID = 0x0,      ///< PSCOM
+        N1_PERV_RING_ID = 0x1,      ///< PERV
+        N1_MC23_0_RING_ID = 0x2,    ///< MC23_0
+        N1_MCD_0_RING_ID = 0x4,     ///< MCD_0
+        N1_MCD_1_RING_ID = 0x5,     ///< MCD_1
+        N1_VA_0_RING_ID = 0x6       ///< VA_0
+    } p9_n1_ring_id_t;
+
+    /// P9 N2 chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_n2_top.vhdl
+    typedef enum
+    {
+        N2_PSCM_RING_ID = 0x0,      ///< PSCOM
+        N2_PERV_RING_ID = 0x1,      ///< PERV
+        N2_CXA1_0_RING_ID = 0x2,    ///< CXA1_0
+        N2_PCIS0_0_RING_ID = 0x3,   ///< PCIS0_0
+        N2_PCIS1_0_RING_ID = 0x4,   ///< PCIS1_0
+        N2_PCIS2_0_RING_ID = 0x5,   ///< PCIS2_0
+        N2_IOPSI_0_RING_ID = 0x6    ///< IOPSI_0
+    } p9_n2_ring_id_t;
+
+    typedef enum
+    {
+        PEC_SAT_ID = 0x0
+    } p9_pec_sat_id_t;
+
+    /// P9 N3 chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_n3_top.vhdl
+    typedef enum
+    {
+        N3_PSCM_RING_ID = 0x0,      ///< PSCOM
+        N3_PERV_RING_ID = 0x1,      ///< PERV
+        N3_MC01_0_RING_ID = 0x2,    ///< MC01_0
+        N3_NPU_0_RING_ID = 0x4,     ///< NPU_0
+        N3_NPU_1_RING_ID = 0x5,     ///< NPU_1
+        N3_PB_0_RING_ID = 0x6,      ///< PB_0
+        N3_PB_1_RING_ID = 0x7,      ///< PB_1
+        N3_PB_2_RING_ID = 0x8,      ///< PB_2
+        N3_PB_3_RING_ID = 0x9,      ///< PB_3
+        N3_BR_0_RING_ID = 0xa,      ///< BR_0
+        N3_MM_0_RING_ID = 0xb,      ///< MM_0
+        N3_INT_0_RING_ID = 0xc,     ///< INT_0
+        N3_PB_4_RING_ID = 0xd,      ///< PB_4
+        N3_PB_5_RING_ID = 0xe,      ///< PB_5
+        N3_NPU_2_RING_ID = 0xf,     ///< NPU_2
+    } p9_n3_ring_id_t;
+
+
+    /// P9 N3 satellite ids
+    typedef enum
+    {
+        P9_N3_MCS01_SAT_ID = 0,
+        P9_N3_MCS23_SAT_ID = 2
+    } p9_n3_sat_id_t;
+
+    /// P9 XBUS chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_xb_top.vhdl
+    typedef enum
+    {
+        XB_PSCM_RING_ID = 0x0,      ///< PSCOM
+        XB_PERV_RING_ID = 0x1,      ///< PERV
+        XB_IOPPE_0_RING_ID = 0x2,   ///< IOPPE
+        XB_IOX_0_RING_ID = 0x3,     ///< IOX_0
+        XB_IOX_1_RING_ID = 0x4,     ///< IOX_1
+        XB_IOX_2_RING_ID = 0x5,     ///< IOX_2
+        XB_PBIOX_0_RING_ID = 0x6,   ///< PBIOX_0
+        XB_PBIOX_1_RING_ID = 0x7,   ///< PBIOX_1
+        XB_PBIOX_2_RING_ID = 0x8    ///< PBIOX_2
+    } p9_xb_ring_id_t;
+
+    typedef enum
+    {
+        XB_PB_SAT_ID = 0x0
+    } p9_xb_pb_sat_id_t;
+
+    typedef enum
+    {
+        XB_IOF_SAT_ID = 0x0,
+        XB_PPE_SAT_ID = 0x1
+    } p9_xb_iof_sat_id_t;
+
+    /// P9 MC chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_mcslow_top.vhdl
+    typedef enum
+    {
+        MC_PSCM_RING_ID = 0x0,      ///< PSCOM
+        MC_PERV_RING_ID = 0x1,      ///< PERV
+        MC_MC01_0_RING_ID = 0x2,    ///< MC01_0 / MC23_0
+        MC_MCTRA_0_RING_ID = 0x3,   ///< MCTRA01_0 / MCTRA23_0
+        MC_IOM01_0_RING_ID = 0x4,   ///< IOM01_0 / IOM45_0
+        MC_IOM01_1_RING_ID = 0x5,   ///< IOM01_1 / IOM45_1
+        MC_IOM23_0_RING_ID = 0x6,   ///< IOM23_0 / IOM67_0
+        MC_IOM23_1_RING_ID = 0x7,   ///< IOM23_1 / IOM67_1
+        MC_MC01_1_RING_ID = 0x8,    ///< MC01_1 / MC23_1
+    } p9_mc_ring_id_t;
+
+    typedef enum
+    {
+        MC_DIR_SAT_ID_PBI_01 = 0x0,
+        MC_DIR_SAT_ID_PBI_23 = 0x2,
+        MC_DIR_SAT_ID_SRQ_0 = 0x4,
+        MC_DIR_SAT_ID_SRQ_1 = 0x5,
+        MC_DIR_SAT_ID_SRQ_2 = 0x6,
+        MC_DIR_SAT_ID_SRQ_3 = 0x7,
+        MC_DIR_SAT_ID_ECC64_0 = 0x8,
+        MC_DIR_SAT_ID_ECC64_1 = 0x9,
+        MC_DIR_SAT_ID_ECC64_2 = 0xa,
+        MC_DIR_SAT_ID_ECC64_3 = 0xb
+    } p9_mc_dir0_sat_id_t;
+
+    //These are for registers that reside in the MCS chiplet, but
+    //are used for MCA registers and should be targetted with MCA
+    //target type.  There is no way to identify them other than by
+    //register offset value.  All registers know of this type are
+    //listed bellow, but a range is used for checking
+    typedef enum
+    {
+        MC_MCS_MCA_OFFSET_MCP0XLT0  = 0x20,
+        MC_MCS_MCA_OFFSET_MCP0XLT1  = 0x21,
+        MC_MCS_MCA_OFFSET_MCP0XLT2  = 0x22,
+        MC_MCS_MCA_OFFSET_MCPERF0  = 0x23,
+        MC_MCS_MCA_OFFSET_MCPERF2  = 0x24,
+        MC_MCS_MCA_OFFSET_MCAMOC  = 0x25,
+        MC_MCS_MCA_OFFSET_MCEPSQ  = 0x26,
+        MC_MCS_MCA_OFFSET_MCBUSYQ  = 0x27,
+        MC_MCS_MCA_OFFSET_MCERRINJ  = 0x28,
+        MC_MCS_MCA_OFFSET_MCEBUSCL  = 0x29,
+        MC_MCS_MCA_OFFSET_MCWAT  = 0x2A,
+        MC_MCS_MCA_OFFSET_MCPERF3  = 0x2B
+    } p9_mcs_mca_offset_t;
+
+    typedef enum
+    {
+        MC_IND_SAT_ID = 0x0,
+        MC_DIR_SAT_ID_MCBIST = 0xC,
+        P9C_SAT_ID_CHAN_MCBIST = 0xD
+    } p9_mc_dir1_sat_id_t;
+
+
+    /// Cumulus mc rings
+    typedef enum
+    {
+        P9C_MC_PSCM_RING_ID  = 0x0,
+        P9C_MC_PERV_RING_ID  = 0x1,
+        P9C_MC_CHAN_RING_ID  = 0x2,
+        P9C_MC_MCTRA_RING_ID = 0x3,
+        P9C_MC_IO_RING_ID    = 0x4,
+        P9C_MC_PPE_RING_ID   = 0x5,
+        P9C_MC_BIST_RING_ID  = 0x8
+    } p9c_mc_ring_id_t;
+
+    typedef enum
+    {
+        P9C_MC_PPE_SAT_ID = 0x1
+    } p9c_mc_ppe_sat_id_t;
+
+    typedef enum
+    {
+        P9C_MC_OFFSET_IND = 0x3F
+    } p9c_mc_sat_offset_t;
+
+    /// P9 OB chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_ob_top.vhdl
+    typedef enum
+    {
+        OB_PSCM_RING_ID = 0x0,      ///< PSCOM
+        OB_PERV_RING_ID = 0x1,      ///< PERV
+        OB_PBIOA_0_RING_ID = 0x2,   ///< PBIOA_0
+        OB_IOO_0_RING_ID = 0x3,     ///< IOO_0
+        OB_PPE_RING_ID = 0x4        ///< PPE
+    } p9_ob_ring_id_t;
+
+    typedef enum
+    {
+        OB_PB_SAT_ID = 0x0
+    } p9_ob_pb_sat_id_t;
+
+    typedef enum
+    {
+        OB_IOO_SAT_ID = 0x0,
+        OB_PPE_SAT_ID = 0x1
+    } p9_ob_ioo_sat_id_t;
+
+    /// P9 PCIe chiplet SCOM ring ID enumeration
+    /// source: tpc_p9_pci[012]_top.vhdl
+    typedef enum
+    {
+        PCI_PSCM_RING_ID = 0x0,      ///< PSCOM
+        PCI_PERV_RING_ID = 0x1,      ///< TRA
+        PCI_PE_0_RING_ID = 0x2,      ///< PE_0
+        PCI_IOPCI_0_RING_ID = 0x3    ///< IOPCI_0
+    } p9_pci_ring_id_t;
+
+    /// P9 PPE GPE ring enumeration (bits 16:21)
+    typedef enum
+    {
+        PPE_SBE_RING_ID  = 0x00,
+        PPE_GPE0_RING_ID = 0x00,
+        PPE_GPE1_RING_ID = 0x08,
+        PPE_GPE2_RING_ID = 0x10,
+        PPE_GPE3_RING_ID = 0x18,
+    } p9_tp_ring_id_t;
+
+    /// Satellite ID for PERV
+    typedef enum
+    {
+        PERV_DBG_SAT_ID = 0xF,
+    } p9_perv_sat_id_t;
+
+    /// Satellite ID for SBE
+    typedef enum
+    {
+        PPE_SBE_SAT_ID = 0x0,
+    } p9_tp_sbe_sat_id_t;
+
+    /// Satellite ID for PPE GPE
+    typedef enum
+    {
+        PPE_GPE_SAT_ID = 0x0,
+    } p9_tp_gpe_sat_id_t;
+
+    /// Satellite ID for PPE CME
+    typedef enum
+    {
+        PPE_CME_SAT_ID = 0x0,
+    } p9_eq_ppe_sat_id_t;
+
+    /// Satellite ID for PPE PB
+    typedef enum
+    {
+        PPE_PB_SAT_ID = 0x0,
+    } p9_n3_ppe_sat_id;
+
+    /// P9A MC chiplet SCOM ring ID enumeration
+    /// source: tpc_p9u_mc01_top.vhdl
+    typedef enum
+    {
+        P9A_MC_PSCM_RING_ID = 0x0,       ///< PSCOM
+        P9A_MC_PERV_RING_ID = 0x1,       ///< PERV
+        P9A_MC_CHAN_RING_ID = 0x2,       ///< Channel registers
+        P9A_MC_OMIC0_RING_ID = 0x4,      ///< OMIC0
+        P9A_MC_OMIC1_RING_ID = 0x5,      ///< OMIC1
+        P9A_MC_OMIC2_RING_ID = 0x6,      ///< OMIC2
+        P9A_MC_MC01_RING_ID = 0x8,       ///< MC01
+        P9A_MC_OMIC0_PPE_RING_ID = 0x9,  ///< OMIC0 PPE
+        P9A_MC_OMIC1_PPE_RING_ID = 0xA,  ///< OMIC1 PPE
+        P9A_MC_OMIC2_PPE_RING_ID = 0xB,  ///< OMIC2 PPE
+        P9A_MC_OMI_DL_RING_ID = 0xC,     ///< OMI DL rings
+    } p9a_mc_ring_id_t;
+
+    // P9A Sat id enumeration
+    typedef enum
+    {
+        P9A_MC_IND_SAT_ID = 0x0,          ///< Indirect sat_id
+        P9A_MC_DSTL_CHAN0_SAT_ID = 0x4,   ///< USTL registers channel 0
+        P9A_MC_DSTL_CHAN1_SAT_ID = 0x5,   ///< USTL registers channel 1
+        P9A_MC_DSTL_CHAN2_SAT_ID = 0x6,   ///< USTL registers channel 2
+        P9A_MC_DSTL_CHAN3_SAT_ID = 0x7,   ///< USTL registers channel 3
+        P9A_MC_USTL_CHAN0_SAT_ID = 0x8,   ///< USTL registers channel 0
+        P9A_MC_USTL_CHAN1_SAT_ID = 0x9,   ///< USTL registers channel 1
+        P9A_MC_USTL_CHAN2_SAT_ID = 0xA,   ///< USTL registers channel 2
+        P9A_MC_USTL_CHAN3_SAT_ID = 0xB,   ///< USTL registers channel 3
+        P9A_MC_DL_REG0_SAT_ID = 0xD,      ///< OMI reg0 (omi0..2)
+        P9A_MC_DL_REG1_SAT_ID = 0xE,      ///< OMI reg1 (omi3..5)
+        P9A_MC_DL_REG2_SAT_ID = 0xF,      ///< OMI reg2 (omi6..7)
+    } p9a_mc_sat_id_t;
+
+    typedef enum
+    {
+        P9A_MC_DL_OMI0_FRST_REG = 0x10,   ///< First register of OMI % 3 == 0
+        P9A_MC_DL_OMI1_FRST_REG = 0x20,   ///< First register of OMI % 3 == 1
+        P9A_MC_DL_OMI2_FRST_REG = 0x30,   ///< First register of OMI % 3 == 2
+        P9A_MC_IND_REG = 0x3F,            ///< Indirect regiser
+    } p9a_mc_reg_offsets_t;
+
+    typedef enum
+    {
+        P9A_MC_OMI0_FRST_LANE = 0x0,      ///< First lane of OMI % 3 = 0
+        P9A_MC_OMI1_FRST_LANE = 0x8,      ///< First lane of OMI % 3 = 1
+        P9A_MC_OMI2_FRST_LANE = 0x10,     ///< First lane of OMI % 3 = 2
+    } p9a_mc_lane_t;
+
+//        8             7             6             5             4             3          2         1
+//
+//  |0 1 2 3| |4 5 6 7| |8 9 10 11| |12 13 14 15| |16 17 18 19| |20 21 22 23| |24 25 26 27| |28 29 30 31|
+//    {A}{     B      }             {   C    }          {      D      }{     E      }{        F          }
+//
+// A - Is multiCast if bit 1 = 0x1
+// B - Contains Chiplet ID (6 bits) [2:7]
+// C - Contains Port Number (4 bits) [12:15]
+// D - Ring (4 bits) [18:21]
+// E - Sat ID (4 bits) [22:25]
+// F - Sat Offset (6 bits) [26:31]
+
+    /// P9 SCOM address class
+    class p9_scom_addr
+    {
+
+        public:
+            /// @brief Construct a SCOM address object
+            /// @param[in] i_addr 64-bit raw SCOM address
+            p9_scom_addr(const uint64_t i_addr)
+                : iv_addr(i_addr)
+            {
+            }
+
+            /// @brief Set full/raw SCOM address
+            /// @param[in] i_addr 64-bit SCOM address
+            /// @retval none
+            inline void set_addr(const uint64_t i_addr)
+            {
+                iv_addr = i_addr;
+                return;
+            }
+
+            /// @brief Retrieve full/raw SCOM address
+            /// @retval uint64_t 64-bit SCOM address
+            inline uint64_t get_addr() const
+            {
+                return (iv_addr);
+            }
+
+            /// @brief Determine if SCOM address is direct-form
+            /// @retval bool True if SCOM address is direct-form, false otherwise
+            inline bool is_direct() const
+            {
+                return (((iv_addr >> 63) & 0x1) == 0x0);
+            }
+
+            /// @brief Determine if SCOM address is indirect-form
+            /// @retval bool True if SCOM address is indirect-form, false otherwise
+            inline bool is_indirect() const
+            {
+                return (!is_direct());
+            }
+
+            /// @brief Determine if SCOM address is unicast
+            /// @retval bool True if SCOM address is unicast, false otherwise
+            inline bool is_unicast() const
+            {
+                return (!(is_multicast()));
+            }
+
+            /// @brief Determine if SCOM address is multicast
+            /// @retval bool True if SCOM address is multicast, false otherwise
+            inline bool is_multicast() const
+            {
+                return (((iv_addr >> 30) & 0x1) == 0x1);
+            }
+
+            /// @brief Extract pervasive chiplet ID from SCOM address
+            /// @retval uint8_t Pervasive chiplet ID value
+            inline uint8_t get_chiplet_id() const
+            {
+                return ((iv_addr >> 24) & 0x3F);
+            }
+
+            /// @brief Modify SCOM address, update pervasive chiplet ID
+            /// @param[in] i_chiplet_id Chiplet ID value to write
+            /// @retval none
+            inline void set_chiplet_id(const uint8_t i_chiplet_id)
+            {
+                iv_addr &= 0xFFFFFFFFC0FFFFFFULL;
+                iv_addr |= ((i_chiplet_id & 0x3F) << 24);
+                return;
+            }
+
+            /// @brief Extract port field from SCOM address
+            /// @retval uint8_t Port field value
+            inline uint8_t get_port() const
+            {
+                return ((iv_addr >> 16) & 0xF);
+            }
+
+            /// @brief Modify the port field from SCOM address
+            /// @retval uint8_t Port field value
+            inline void set_port(const uint8_t i_port)
+            {
+                iv_addr &= 0xFFFFFFFFFFF0FFFFULL;
+                iv_addr |= ((i_port & 0xF) << 16);
+                return;
+            }
+
+            /// @brief Extract ring field from SCOM address
+            /// @retval uint8_t Ring field value
+            inline uint8_t get_ring() const
+            {
+                return ((iv_addr >> 10) & 0x3F);
+            }
+
+            /// @brief Modify SCOM address, update ring field value
+            /// @param[in] i_ring Ring field value to write
+            /// @retval none
+            inline void set_ring(const uint8_t i_ring)
+            {
+                iv_addr &= 0xFFFFFFFFFFFF03FFULL;
+                iv_addr |= ((i_ring & 0x3F) << 10);
+                return;
+            }
+
+            /// @brief Extract satellite ID field from SCOM address
+            /// @retval uint8_t Satellite ID field value
+            inline uint8_t get_sat_id() const
+            {
+                return ((iv_addr >> 6) & 0xF);
+            }
+
+            /// @brief Modify SCOM address, update satellite ID field
+            /// @param[in] i_sat_id Satellite ID value to write
+            /// @retval none
+            inline void set_sat_id(const uint8_t i_sat_id)
+            {
+                iv_addr &= 0xFFFFFFFFFFFFFC3FULL;
+                iv_addr |= ((i_sat_id & 0xF) << 6);
+                return;
+            }
+
+            /// @brief Extract satellite register offset field from SCOM address
+            /// @retval uint8_t Satellite register offset field value
+            inline uint8_t get_sat_offset() const
+            {
+                return (iv_addr & 0x3F);
+            }
+
+            /// @brief Modify SCOM address, update satellite offset field
+            /// @param[in] i_sat_offset Satellite offset value to write
+            /// @retval none
+            inline void set_sat_offset(const uint8_t i_sat_offset)
+            {
+                iv_addr &= 0xFFFFFFFFFFFFFFC0ULL;
+                iv_addr |= (i_sat_offset & 0x3F);
+                return;
+            }
+
+            /// @brief Extract the RX or TX Group ID of an indirect scom address
+            /// @retval uint8_t RX/TX group id
+            inline uint8_t get_rxtx_group_id()
+            {
+                return (iv_addr >> 37) & 0x3F;
+            }
+
+            /// @brief Modify SCOM address, update the RX or TX Group ID
+            /// @param[in] i_grp_id Group id to set
+            /// @retval none
+            inline void set_rxtx_group_id(uint8_t i_grp_id)
+            {
+                iv_addr &= 0xFFFFF81FFFFFFFFFULL;
+                iv_addr |= (i_grp_id & 0x3FULL) << 37;
+            }
+
+            /// @brief Extract the RX or TX Group ID of an indirect scom address
+            /// @retval uint8_t RX/TX group id
+            inline uint8_t get_lane_id()
+            {
+                return (iv_addr >> 32) & 0x1F;
+            }
+
+            /// @brief Modify SCOM address, update the RX or TX Group ID
+            /// @param[in] i_grp_id Group id to set
+            /// @retval none
+            inline void set_lane_id(uint8_t i_grp_id)
+            {
+                iv_addr &= 0xFFFFFFE0FFFFFFFFULL;
+                iv_addr |= (i_grp_id & 0x1FULL) << 32;
+            }
+
+            /// @brief Extract the indirect address field of a scom address
+            /// @retval uint16_t indirect address field
+            inline uint16_t get_ind_addr()
+            {
+                return (iv_addr >> 43) & 0x1FF;
+            }
+
+            /// @brief Determine if SCOM address is valid/well-formed
+            /// @retval bool True if SCOM address is valid, false otherwise
+            inline bool is_valid() const
+            {
+                return true;
+            }
+
+        private:
+            uint64_t iv_addr;   ///< 64-bit raw SCOM address
+    };
+
+} // extern "C"
+
+#endif /* P9_SCOM_ADDR_H */
diff --git a/src/tests/p9_scominfo.C b/src/tests/p9_scominfo.C
new file mode 100644
index 0000000..745fb35
--- /dev/null
+++ b/src/tests/p9_scominfo.C
@@ -0,0 +1,1494 @@
+/* IBM_PROLOG_BEGIN_TAG                                                   */
+/* This is an automatically generated prolog.                             */
+/*                                                                        */
+/* $Source: chips/p9/common/scominfo/p9_scominfo.C $                      */
+/*                                                                        */
+/* IBM CONFIDENTIAL                                                       */
+/*                                                                        */
+/* EKB Project                                                            */
+/*                                                                        */
+/* COPYRIGHT 2015,2018                                                    */
+/* [+] International Business Machines Corp.                              */
+/*                                                                        */
+/*                                                                        */
+/* The source code for this program is not published or otherwise         */
+/* divested of its trade secrets, irrespective of what has been           */
+/* deposited with the U.S. Copyright Office.                              */
+/*                                                                        */
+/* IBM_PROLOG_END_TAG                                                     */
+///
+/// @file p9_scominfo.C
+/// @brief P9 chip unit SCOM address platform translation code
+///
+/// HWP HWP Owner: jmcgill@us.ibm.com
+/// HWP FW Owner: dcrowell@us.ibm.com
+/// HWP Team: Infrastructure
+/// HWP Level: 1
+/// HWP Consumed by: FSP/HB
+///
+
+// includes
+#include "p9_scominfo.H"
+#include "p9_scom_addr.H"
+
+#define P9_SCOMINFO_C
+
+// bgass Aug 13 2018.  The decision was made to make
+// OMI target numbers line up logically with the memory
+// parent targets (MC, MI, MCC)                  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
+const static int P9_SCOMINFO_OMI_SWIZZLE[]   = { 4, 5, 6, 7, 2, 3, 0, 1, 12, 13, 14, 15, 10, 11, 8, 9 };
+const static int P9_SCOMINFO_OMI_UNSWIZZLE[] = { 6, 7, 4, 5, 0, 1, 2, 3, 14, 15, 12, 13, 8, 9, 10, 11 };
+
+extern "C"
+{
+    uint64_t p9_scominfo_createChipUnitScomAddr(const p9ChipUnits_t i_p9CU, const uint8_t i_chipUnitNum,
+            const uint64_t i_scomAddr, const uint32_t i_mode)
+    {
+        p9_scom_addr l_scom(i_scomAddr);
+        uint8_t l_ring = l_scom.get_ring();
+        uint8_t l_chiplet_id = l_scom.get_chiplet_id();
+        uint8_t l_sat_id = l_scom.get_sat_id();
+        uint8_t l_sat_offset = l_scom.get_sat_offset();
+
+
+        //Used to help generate entries for the SCOMdef documentation,
+        //These aren't general PIB addresses
+        if ((i_mode & PPE_MODE) == PPE_MODE)
+        {
+            switch (i_p9CU)
+            {
+
+                case PU_EX_CHIPUNIT:
+                    if (PPE_EP05_CHIPLET_ID >= l_scom.get_chiplet_id() &&
+                        l_scom.get_chiplet_id() >= PPE_EP00_CHIPLET_ID)
+                    {
+                        l_scom.set_chiplet_id(PPE_EP00_CHIPLET_ID + (i_chipUnitNum / 2));
+                        l_scom.set_port( ( i_chipUnitNum % 2 ) + 1 );
+                    }
+
+                    break;
+
+                default:
+                    l_scom.set_addr(FAILED_TRANSLATION);
+                    break;
+            }
+        }
+        //Regular PIB addresses (not PPE)
+        else
+        {
+            switch (i_p9CU)
+            {
+                case PU_PERV_CHIPUNIT:
+                    l_scom.set_chiplet_id(i_chipUnitNum);
+                    break;
+
+                case PU_C_CHIPUNIT:
+                    l_scom.set_chiplet_id(EC00_CHIPLET_ID + i_chipUnitNum);
+                    break;
+
+                case PU_EX_CHIPUNIT:
+                    if (EP05_CHIPLET_ID >= l_scom.get_chiplet_id() &&
+                        l_scom.get_chiplet_id() >= EP00_CHIPLET_ID)
+                    {
+                        l_scom.set_chiplet_id(EP00_CHIPLET_ID + (i_chipUnitNum / 2));
+                        uint8_t l_ringId = (l_scom.get_ring() & 0xF); // Clear bits 16:17
+                        l_ringId = ( l_ringId - ( l_ringId % 2 ) ) + ( i_chipUnitNum % 2 );
+                        l_scom.set_ring( l_ringId & 0xF );
+                    }
+                    else if (EC23_CHIPLET_ID >= l_scom.get_chiplet_id() &&
+                             l_scom.get_chiplet_id() >= EC00_CHIPLET_ID)
+                    {
+                        l_scom.set_chiplet_id( EC00_CHIPLET_ID +
+                                               (l_scom.get_chiplet_id() % 2) +
+                                               (i_chipUnitNum * 2));
+                    }
+
+                    break;
+
+                case PU_EQ_CHIPUNIT:
+                    l_scom.set_chiplet_id(EP00_CHIPLET_ID + i_chipUnitNum);
+                    break;
+
+                case PU_CAPP_CHIPUNIT:
+                    l_scom.set_chiplet_id(N0_CHIPLET_ID + (i_chipUnitNum * 2));
+                    break;
+
+                case PU_MCS_CHIPUNIT:
+                    l_scom.set_chiplet_id(N3_CHIPLET_ID - (2 * (i_chipUnitNum / 2)));
+                    l_scom.set_sat_id(2 * (i_chipUnitNum % 2));
+                    break;
+
+                case PU_MCBIST_CHIPUNIT:
+                    l_scom.set_chiplet_id(MC01_CHIPLET_ID + i_chipUnitNum);
+                    break;
+
+                case PU_MCA_CHIPUNIT:
+                    if (l_scom.get_chiplet_id() == MC01_CHIPLET_ID || l_scom.get_chiplet_id() ==  MC23_CHIPLET_ID)
+                    {
+                        l_scom.set_chiplet_id(MC01_CHIPLET_ID + (i_chipUnitNum / 4));
+
+                        if ( (l_scom.get_ring() & 0xF) == MC_MC01_0_RING_ID)
+                        {
+                            // mc
+                            l_scom.set_sat_id( ( l_scom.get_sat_id() - ( l_scom.get_sat_id() % 4 ) ) +
+                                               ( i_chipUnitNum % 4 ));
+                        }
+                        else
+                        {
+                            // iomc
+                            l_scom.set_ring( (MC_IOM01_0_RING_ID + (i_chipUnitNum % 4)) & 0xF );
+                        }
+                    }
+                    else
+                    {
+                        //mcs->mca regisers
+                        uint8_t i_mcs_unitnum = ( i_chipUnitNum / 2 );
+                        l_scom.set_chiplet_id(N3_CHIPLET_ID - (2 * (i_mcs_unitnum / 2)));
+                        l_scom.set_sat_id(2 * (i_mcs_unitnum % 2));
+                        uint8_t i_mcs_sat_offset = (0x2F & l_scom.get_sat_offset());
+                        i_mcs_sat_offset |= ((i_chipUnitNum % 2) << 4);
+                        l_scom.set_sat_offset(i_mcs_sat_offset);
+                    }
+
+                    break;
+
+                case PU_MC_CHIPUNIT:
+                    l_scom.set_chiplet_id(MC01_CHIPLET_ID + i_chipUnitNum);
+                    break;
+
+                case PU_MI_CHIPUNIT:
+                    //-------------------------------------------
+                    // MI
+                    //-------------------------------------------
+                    //          Chiplet   Ring   Satid   Off
+                    //MCS0           05     02       0   !SCOM3
+                    //MCS1           05     02       2   !SCOM3
+                    //MCS2           03     02       0   !SCOM3
+                    //MCS3           03     02       2   !SCOM3
+                    l_scom.set_chiplet_id(N3_CHIPLET_ID - (2 * (i_chipUnitNum / 2)));
+                    l_scom.set_sat_id(2 * (i_chipUnitNum % 2));
+                    break;
+
+                case PU_DMI_CHIPUNIT:
+                    if (((l_chiplet_id == N3_CHIPLET_ID) || (l_chiplet_id == N1_CHIPLET_ID)))
+                    {
+                        //SCOM3   (See mc_clscom_rlm.fig <= 0xB vs mc_scomfir_rlm.fig > 0xB)
+                        //DMI0           05     02       0   0x2X (X <= 0xB)
+                        //DMI1           05     02       0   0x3X (X <= 0xB)
+                        //DMI2           05     02       2   0x2X (X <= 0xB)
+                        //DMI3           05     02       2   0x3X (X <= 0xB)
+                        //DMI4           03     02       0   0x2X (X <= 0xB)
+                        //DMI5           03     02       0   0x3X (X <= 0xB)
+                        //DMI6           03     02       2   0x2X (X <= 0xB)
+                        //DMI7           03     02       2   0x3X (X <= 0xB)
+                        l_scom.set_chiplet_id(N3_CHIPLET_ID - (2 * (i_chipUnitNum / 4)));
+                        l_scom.set_sat_id(2 * ((i_chipUnitNum / 2) % 2));
+                        l_sat_offset = (l_sat_offset & 0xF) + ((2 + (i_chipUnitNum % 2)) << 4);
+                        l_scom.set_sat_offset(l_sat_offset);
+                    }
+
+                    if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)))
+                    {
+                        //-------------------------------------------
+                        // DMI
+                        //-------------------------------------------
+                        //SCOM1,2
+                        //DMI0           07     02       0
+                        //DMI1           07     02       1
+                        //DMI2           07     02       2
+                        //DMI3           07     02       3
+                        //DMI4           08     02       0
+                        //DMI5           08     02       1
+                        //DMI6           08     02       2
+                        //DMI7           08     02       3
+                        if (l_ring == P9C_MC_CHAN_RING_ID)
+                        {
+                            l_scom.set_chiplet_id(MC01_CHIPLET_ID + (i_chipUnitNum / 4));
+                            uint8_t l_msat = l_scom.get_sat_id();
+                            l_msat = l_msat & 0xC;
+                            l_scom.set_sat_id(l_msat + i_chipUnitNum % 4);
+                        }
+
+                        //SCOM4
+                        //DMI0           07     08     0xD   0x0X
+                        //DMI1           07     08     0xD   0x1X
+                        //DMI2           07     08     0xD   0x2X
+                        //DMI3           07     08     0xD   0x3X
+                        //DMI4           08     08     0xD   0x0X
+                        //DMI5           08     08     0xD   0x1X
+                        //DMI6           08     08     0xD   0x2X
+                        //DMI7           08     08     0xD   0x3X
+                        if (l_ring == P9C_MC_BIST_RING_ID)
+                        {
+                            l_scom.set_chiplet_id(MC01_CHIPLET_ID + (i_chipUnitNum / 4));
+                            l_sat_offset = (l_sat_offset & 0xF) + ((i_chipUnitNum % 4) << 4);
+                            l_scom.set_sat_offset(l_sat_offset);
+                        }
+
+                        //-------------------------------------------
+                        // DMI IO
+                        //-------------------------------------------
+                        //          Chiplet   Ring   Satid    Off    RXTXGrp
+                        //DMI0           07     04       0   0x3F       0x00
+                        //DMI1           07     04       0   0x3F       0x01
+                        //DMI2           07     04       0   0x3F       0x02
+                        //DMI3           07     04       0   0x3F       0x03
+                        //DMI4           08     04       0   0x3F       0x00
+                        //DMI5           08     04       0   0x3F       0x01
+                        //DMI6           08     04       0   0x3F       0x02
+                        //DMI7           08     04       0   0x3F       0x03
+
+                        //DMI0           07     04       0   0x3F       0x20
+                        //DMI1           07     04       0   0x3F       0x21
+                        //DMI2           07     04       0   0x3F       0x22
+                        //DMI3           07     04       0   0x3F       0x23
+                        //DMI4           08     04       0   0x3F       0x20
+                        //DMI5           08     04       0   0x3F       0x21
+                        //DMI6           08     04       0   0x3F       0x22
+                        //DMI7           08     04       0   0x3F       0x23
+                        //
+                        //0 MC01.CHAN0  IOM01.TX_WRAP.TX3
+                        //1 MC01.CHAN1  IOM01.TX_WRAP.TX2
+                        //2 MC01.CHAN2  IOM01.TX_WRAP.TX0
+                        //3 MC01.CHAN3  IOM01.TX_WRAP.TX1
+                        //4 MC23.CHAN0  IOM23.TX_WRAP.TX3
+                        //5 MC23.CHAN1  IOM23.TX_WRAP.TX2
+                        //6 MC23.CHAN2  IOM23.TX_WRAP.TX0
+                        //7 MC23.CHAN3  IOM23.TX_WRAP.TX1
+                        // 3, 2, 0, 1
+                        if (l_ring == P9C_MC_IO_RING_ID)
+                        {
+                            l_scom.set_chiplet_id(MC01_CHIPLET_ID + (i_chipUnitNum / 4));
+                            uint8_t l_rxtx_grp = l_scom.get_rxtx_group_id();
+                            l_rxtx_grp = l_rxtx_grp & 0xF0;
+
+                            switch ((i_chipUnitNum % 4))
+                            {
+                                case  0:
+                                    l_rxtx_grp += 3;
+                                    break;
+
+                                case  1:
+                                    l_rxtx_grp += 2;
+                                    break;
+
+                                case  2:
+                                    l_rxtx_grp += 0;
+                                    break;
+
+                                case  3:
+                                    l_rxtx_grp += 1;
+                                    break;
+
+                                default:
+                                    //escape to bunker - math broke
+                                    break;
+                            }
+
+                            l_scom.set_rxtx_group_id(l_rxtx_grp); // 3,2,0,1
+                        }
+
+                    }
+
+                    break;
+
+                case PU_MCC_CHIPUNIT:
+                    if (((l_chiplet_id == N3_CHIPLET_ID) || (l_chiplet_id == N1_CHIPLET_ID)))
+                    {
+                        //SCOM3   (See mc_clscom_rlm.fig <= 0xB vs mc_scomfir_rlm.fig > 0xB)
+                        //DMI0           05     02       0   0x2X (X <= 0xB)
+                        //DMI1           05     02       0   0x3X (X <= 0xB)
+                        //DMI2           05     02       2   0x2X (X <= 0xB)
+                        //DMI3           05     02       2   0x3X (X <= 0xB)
+                        //DMI4           03     02       0   0x2X (X <= 0xB)
+                        //DMI5           03     02       0   0x3X (X <= 0xB)
+                        //DMI6           03     02       2   0x2X (X <= 0xB)
+                        //DMI7           03     02       2   0x3X (X <= 0xB)
+                        l_scom.set_chiplet_id(N3_CHIPLET_ID - (2 * (i_chipUnitNum / 4)));
+                        l_scom.set_sat_id(2 * ((i_chipUnitNum / 2) % 2));
+                        uint8_t l_satoff = (l_sat_offset & 0xF) + ((2 + (i_chipUnitNum % 2)) << 4);
+                        l_scom.set_sat_offset(l_satoff);
+                    }
+
+                    if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)))
+                    {
+                        //CHANX.USTL.  Sat_id: 10 + port_id (8,9,10,11)
+                        //CHANX.DSTL.  Sat_id: 01 + port_id (4,5,6,7)
+                        l_scom.set_chiplet_id(MC01_CHIPLET_ID + (i_chipUnitNum / 4));
+
+                        if (P9A_MC_DSTL_CHAN0_SAT_ID <= l_sat_id && l_sat_id <= P9A_MC_DSTL_CHAN3_SAT_ID)
+                        {
+                            l_scom.set_sat_id(P9A_MC_DSTL_CHAN0_SAT_ID + (i_chipUnitNum % 4));
+                        }
+
+                        if (P9A_MC_USTL_CHAN0_SAT_ID <= l_sat_id && l_sat_id <= P9A_MC_USTL_CHAN3_SAT_ID)
+                        {
+                            l_scom.set_sat_id(P9A_MC_USTL_CHAN0_SAT_ID + (i_chipUnitNum % 4));
+                        }
+                    }
+
+                    break;
+
+                case PU_OMIC_CHIPUNIT:
+                    l_scom.set_chiplet_id(MC01_CHIPLET_ID + (i_chipUnitNum / 3));
+
+                    if (P9A_MC_OMIC0_RING_ID <= l_ring && l_ring <= P9A_MC_OMIC2_RING_ID)
+                    {
+                        l_scom.set_ring(P9A_MC_OMIC0_RING_ID + (i_chipUnitNum % 3));
+                    }
+
+                    if (P9A_MC_OMIC0_PPE_RING_ID <= l_ring && l_ring <= P9A_MC_OMIC2_PPE_RING_ID)
+                    {
+                        l_scom.set_ring(P9A_MC_OMIC0_PPE_RING_ID + (i_chipUnitNum % 3));
+                    }
+
+                    break;
+
+                case PU_OMI_CHIPUNIT:
+                    {
+                        //Unswizzle the OMI chip unit number
+                        uint8_t l_chipUnitNum = P9_SCOMINFO_OMI_UNSWIZZLE[i_chipUnitNum];
+
+                        l_scom.set_chiplet_id(MC01_CHIPLET_ID + (l_chipUnitNum / 8));
+
+                        if (P9A_MC_OMIC0_RING_ID <= l_ring && l_ring <= P9A_MC_OMIC2_RING_ID)
+                        {
+                            // IO Ind regsiters  (Ring 4,5,6) reg == 63
+                            // 0701103F MCP_OMI0. Lanes 0-7    omi0
+                            // 0701103F MCP_OMI0. Lanes 8-15   omi1
+                            // 0701103F MCP_OMI0. Lanes 16-23  omi2
+                            // 0701143F MCP_OMI1. Lanes 0-7    omi3
+                            // 0701143F MCP_OMI1. Lanes 8-15   omi4
+                            // 0701143F MCP_OMI1. Lanes 16-23  omi5
+                            // 0701183F MCP_OMI2. Lanes 0-7    omi6
+                            // 0701183F MCP_OMI2. Lanes 8-15   omi7
+                            l_scom.set_ring(P9A_MC_OMIC0_RING_ID + ((l_chipUnitNum % 8) / 3));
+                            uint8_t l_lane = l_scom.get_lane_id();
+                            l_lane = l_lane % 8;
+                            uint8_t l_chipnum = l_chipUnitNum;
+
+                            if (l_chipnum >= 8)
+                            {
+                                l_chipnum++;
+                            }
+
+                            l_scom.set_lane_id(((l_chipnum % 3) * 8) + l_lane);
+                        }
+
+                        if (l_ring == P9A_MC_OMI_DL_RING_ID)
+                        {
+                            // DL Registers
+                            // reg0 dl0 -> omi0  ring: 12  sat_id: 13  regs 16..31
+                            // reg0 dl1 -> omi1  ring: 12  sat_id: 13  regs 32..47
+                            // reg0 dl2 -> omi2  ring: 12  sat_id: 13  regs 48..63
+                            // reg1 dl0 -> omi3  ring: 12  sat_id: 14  regs 16..31
+                            // reg1 dl1 -> omi4  ring: 12  sat_id: 14  regs 32..47
+                            // reg1 dl2 -> omi5  ring: 12  sat_id: 14  regs 48..63
+                            // reg2 dl0 -> omi6  ring: 12  sat_id: 15  regs 16..31
+                            // reg2 dl1 -> omi7  ring: 12  sat_id: 15  regs 32..47
+                            l_scom.set_sat_id(P9A_MC_DL_REG0_SAT_ID + ((l_chipUnitNum % 8) / 3));
+                            uint8_t l_satoff = l_sat_offset % 16;
+                            uint8_t l_chipnum = l_chipUnitNum;
+
+                            if (l_chipnum >= 8)
+                            {
+                                l_chipnum++;
+                            }
+
+                            l_scom.set_sat_offset((((l_chipnum % 3) * 16) + P9A_MC_DL_OMI0_FRST_REG) +
+                                                  l_satoff);
+                        }
+                    }
+                    break;
+
+                case PU_NV_CHIPUNIT:
+                    if (i_mode == P9N_DD1_SI_MODE)
+                    {
+                        l_scom.set_sat_id((l_scom.get_sat_id() % 4) + ((i_chipUnitNum / 2) * 4));
+                        l_scom.set_sat_offset( (l_scom.get_sat_offset() % 32) +
+                                               (32 * (i_chipUnitNum % 2)));
+                    }
+                    else if (i_mode != P9A_DD1_SI_MODE && i_mode != P9A_DD2_SI_MODE)
+                    {
+                        uint64_t l_sa = i_scomAddr;
+
+                        //                       rrrrrrSTIDxxx---
+                        //                       000100       yyy
+                        //       x"4900" & "00" when "00100010", -- stk0, ntl0, 00-07, hyp-only
+                        //       x"0b00" & "11" when "00101001", -- stk0, ntl1, 24-31, user-acc
+                        //                             STID
+                        //       x"5900" & "00" when "01100010", -- stk1, ntl0, 00-07, hyp-only
+                        //       x"1b00" & "11" when "01101001", -- stk1, ntl1, 24-31, user-acc
+                        //                             STID
+                        //       x"6900" & "00" when "10100010", -- stk2, ntl0, 00-07, hyp-only
+                        //       x"2b00" & "11" when "10101001", -- stk2, ntl1, 24-31, user-acc
+
+                        if ((i_chipUnitNum / 2) == 0)
+                        {
+                            l_sa = (l_sa & 0xFFFFFFFFFFFF007FULL) | 0x0000000000001100ULL ;
+                        }
+
+                        if ((i_chipUnitNum / 2) == 1)
+                        {
+                            l_sa = (l_sa & 0xFFFFFFFFFFFF007FULL) | 0x0000000000001300ULL ;
+                        }
+
+                        if ((i_chipUnitNum / 2) == 2)
+                        {
+                            l_sa = (l_sa & 0xFFFFFFFFFFFF007FULL) | 0x0000000000001500ULL ;
+                        }
+
+                        uint64_t l_eo = (l_sa & 0x71) >> 3;
+
+                        if (l_eo > 5 && (i_chipUnitNum % 2 == 0))
+                        {
+                            l_sa -= 0x20ULL; // 0b100 000
+                        }
+
+                        if (l_eo <= 5 && (i_chipUnitNum % 2 == 1))
+                        {
+                            l_sa += 0x20ULL; // 0b100 000
+                        }
+
+                        l_scom.set_addr(l_sa);
+                    }
+                    else
+                    {
+                        //NV not supported on Axone - unused
+                        l_scom.set_addr(FAILED_TRANSLATION);
+                    }
+
+                    break;
+
+                case PU_PEC_CHIPUNIT:
+                    if (l_scom.get_chiplet_id() == N2_CHIPLET_ID)
+                    {
+                        // nest
+                        l_scom.set_ring( (N2_PCIS0_0_RING_ID + i_chipUnitNum) & 0xF);
+                    }
+                    else
+                    {
+                        // iopci / pci
+                        l_scom.set_chiplet_id(PCI0_CHIPLET_ID + i_chipUnitNum);
+                    }
+
+                    break;
+
+                case PU_PHB_CHIPUNIT:
+                    if (l_scom.get_chiplet_id() == N2_CHIPLET_ID)
+                    {
+                        // nest
+                        if (i_chipUnitNum == 0)
+                        {
+                            l_scom.set_ring(N2_PCIS0_0_RING_ID & 0xF);
+                            l_scom.set_sat_id(((l_scom.get_sat_id() < 4) ? (1) : (4)));
+                        }
+                        else
+                        {
+                            l_scom.set_ring( (N2_PCIS0_0_RING_ID + (i_chipUnitNum / 3) + 1) & 0xF);
+                            l_scom.set_sat_id( ((l_scom.get_sat_id() < 4) ? (1) : (4)) +
+                                               ((i_chipUnitNum % 2) ? (0) : (1)) +
+                                               (2 * (i_chipUnitNum / 5)));
+                        }
+                    }
+                    else
+                    {
+                        // pci
+                        if (i_chipUnitNum == 0)
+                        {
+                            l_scom.set_chiplet_id(PCI0_CHIPLET_ID);
+                            l_scom.set_sat_id(((l_scom.get_sat_id() < 4) ? (1) : (4)));
+                        }
+                        else
+                        {
+                            l_scom.set_chiplet_id(PCI0_CHIPLET_ID + (i_chipUnitNum / 3) + 1);
+                            l_scom.set_sat_id(((l_scom.get_sat_id() < 4) ? (1) : (4)) +
+                                              ((i_chipUnitNum % 2) ? (0) : (1)) +
+                                              (2 * (i_chipUnitNum / 5)));
+                        }
+                    }
+
+                    break;
+
+                case PU_OBUS_CHIPUNIT:
+                    l_scom.set_chiplet_id(OB0_CHIPLET_ID + i_chipUnitNum);
+                    break;
+
+                case PU_XBUS_CHIPUNIT:
+
+                    l_ring &= 0xF;
+
+                    if (XB_IOX_2_RING_ID >= l_ring &&
+                        l_ring >= XB_IOX_0_RING_ID)
+                    {
+                        l_scom.set_ring( (XB_IOX_0_RING_ID + i_chipUnitNum) & 0xF);
+                    }
+
+                    else if (XB_PBIOX_2_RING_ID >= l_ring &&
+                             l_ring >= XB_PBIOX_0_RING_ID)
+                    {
+                        l_scom.set_ring( (XB_PBIOX_0_RING_ID + i_chipUnitNum) & 0xF);
+                    }
+
+                    break;
+
+                case PU_SBE_CHIPUNIT:
+                    l_scom.set_chiplet_id(i_chipUnitNum);
+                    break;
+
+                case PU_PPE_CHIPUNIT:
+
+                    // PPE SBE
+                    if (i_chipUnitNum == PPE_SBE_CHIPUNIT_NUM)
+                    {
+                        l_scom.set_chiplet_id(PIB_CHIPLET_ID);
+                        l_scom.set_port(SBE_PORT_ID);
+                        l_scom.set_ring(PPE_SBE_RING_ID);
+                        l_scom.set_sat_id(PPE_SBE_SAT_ID);
+                        l_scom.set_sat_offset(0x0F & l_scom.get_sat_offset());
+                        break;
+                    }
+
+                    // Need to set SAT offset if address is that of PPE SBE
+                    if (l_scom.get_port() == SBE_PORT_ID)
+                    {
+                        // Adjust offset if input address is of SBE
+                        // (ex: 000E0005 --> GPE: xxxxxx1x)
+                        l_scom.set_sat_offset(l_scom.get_sat_offset() | 0x10);
+                    }
+
+                    // PPE GPE
+                    if ( (i_chipUnitNum >= PPE_GPE0_CHIPUNIT_NUM) && (i_chipUnitNum <= PPE_GPE3_CHIPUNIT_NUM) )
+                    {
+                        l_scom.set_chiplet_id(PIB_CHIPLET_ID);
+                        l_scom.set_port(GPE_PORT_ID);
+                        l_scom.set_ring( (i_chipUnitNum - PPE_GPE0_CHIPUNIT_NUM) * 8 );
+                        l_scom.set_sat_id(PPE_GPE_SAT_ID);
+                    }
+
+                    // PPE CME
+                    else if ( (i_chipUnitNum >= PPE_EQ0_CME0_CHIPUNIT_NUM) && (i_chipUnitNum <= PPE_EQ5_CME1_CHIPUNIT_NUM) )
+                    {
+                        if (i_chipUnitNum >= PPE_EQ0_CME1_CHIPUNIT_NUM)
+                        {
+                            l_scom.set_chiplet_id(EP00_CHIPLET_ID +
+                                                  (i_chipUnitNum % PPE_EQ0_CME1_CHIPUNIT_NUM));
+                        }
+                        else
+                        {
+                            l_scom.set_chiplet_id(EP00_CHIPLET_ID +
+                                                  (i_chipUnitNum % PPE_EQ0_CME0_CHIPUNIT_NUM));
+                        }
+
+                        l_scom.set_port(UNIT_PORT_ID);
+                        l_scom.set_ring( ((i_chipUnitNum / PPE_EQ0_CME1_CHIPUNIT_NUM) + 8) & 0xF );
+                        l_scom.set_sat_id(PPE_CME_SAT_ID);
+                    }
+
+                    // PPE IO (XBUS/OBUS)
+                    else if ( (i_chipUnitNum >= PPE_IO_XBUS_CHIPUNIT_NUM) && (i_chipUnitNum <= PPE_IO_OB3_CHIPUNIT_NUM) )
+                    {
+                        l_scom.set_chiplet_id( XB_CHIPLET_ID +
+                                               (i_chipUnitNum % PPE_IO_XBUS_CHIPUNIT_NUM) +
+                                               ((i_chipUnitNum / PPE_IO_OB0_CHIPUNIT_NUM) * 2) );
+                        l_scom.set_port(UNIT_PORT_ID);
+
+                        if (i_chipUnitNum == PPE_IO_XBUS_CHIPUNIT_NUM)
+                        {
+                            l_scom.set_ring(XB_IOPPE_0_RING_ID & 0xF);
+                        }
+                        else
+                        {
+                            l_scom.set_ring(OB_PPE_RING_ID & 0xF);
+                        }
+
+                        l_scom.set_sat_id(OB_PPE_SAT_ID); // Same SAT_ID value for XBUS
+                    }
+
+                    // PPE IO (DMI)
+                    else if ( (i_chipUnitNum >= PPE_IO_DMI0_CHIPUNIT_NUM) && (i_chipUnitNum <= PPE_IO_DMI1_CHIPUNIT_NUM))
+                    {
+                        l_scom.set_chiplet_id(MC01_CHIPLET_ID + (i_chipUnitNum - PPE_IO_DMI0_CHIPUNIT_NUM));
+                        l_scom.set_ring(MC_IOM01_1_RING_ID);
+                        l_scom.set_port(UNIT_PORT_ID);
+                        l_scom.set_sat_id(P9C_MC_PPE_SAT_ID);
+                    }
+
+                    // PPE PB
+                    else if ( (i_chipUnitNum >= PPE_PB0_CHIPUNIT_NUM) && (i_chipUnitNum <= PPE_PB2_CHIPUNIT_NUM) )
+                    {
+                        l_scom.set_chiplet_id(N3_CHIPLET_ID); // TODO: Need to set ChipID for PB1 and PB2 in Cummulus
+                        l_scom.set_port(UNIT_PORT_ID);
+                        l_scom.set_ring(N3_PB_3_RING_ID & 0xF);
+                        l_scom.set_sat_id(PPE_PB_SAT_ID);
+                    }
+
+                    // Invalid i_chipUnitNum
+                    else
+                    {
+                        l_scom.set_addr(FAILED_TRANSLATION);
+                    }
+
+                    break;
+
+                default:
+                    l_scom.set_addr(FAILED_TRANSLATION);
+                    break;
+            }
+        }
+
+        return l_scom.get_addr();
+    }
+
+
+    uint32_t p9_scominfo_xlate_mi(bool& o_chipUnitRelated, std::vector<p9_chipUnitPairing_t>& o_chipUnitPairing,
+                                  p9_scom_addr& i_scom, const p9ChipUnits_t mcc_dmi, const int i_low0, const int i_low1, const uint32_t i_mode)
+    {
+        uint8_t l_chiplet_id = i_scom.get_chiplet_id();
+        uint8_t l_port = i_scom.get_port();
+        uint8_t l_ring = i_scom.get_ring();
+        uint8_t l_sat_id = i_scom.get_sat_id();
+        uint8_t l_sat_offset = i_scom.get_sat_offset();
+
+        //==== AXONE MC/MI/OMIC/OMI  ============================================================================
+        //==== MI target ===============================================
+        if (((l_chiplet_id == N3_CHIPLET_ID) || (l_chiplet_id == N1_CHIPLET_ID)) &&
+            (l_port == UNIT_PORT_ID) &&
+            (l_ring == N3_MC01_0_RING_ID) &&
+            (l_sat_id == P9_N3_MCS01_SAT_ID || l_sat_id == P9_N3_MCS23_SAT_ID))
+        {
+            //-------------------------------------------
+            // DMI/MCC
+            //-------------------------------------------
+            //SCOM3   (See mc_clscom_rlm.fig <= 0xB vs mc_scomfir_rlm.fig > 0xB)
+            //DMI0           05     02       0   0x2X (X <= 0xB)
+            //DMI1           05     02       0   0x3X (X <= 0xB)
+            //DMI2           05     02       2   0x2X (X <= 0xB)
+            //DMI3           05     02       2   0x3X (X <= 0xB)
+            //DMI4           03     02       0   0x2X (X <= 0xB)
+            //DMI5           03     02       0   0x3X (X <= 0xB)
+            //DMI6           03     02       2   0x2X (X <= 0xB)
+            //DMI7           03     02       2   0x3X (X <= 0xB)
+            if ((i_low0 <= l_sat_offset && l_sat_offset <= 0x2B) ||
+                (i_low1 <= l_sat_offset && l_sat_offset <= 0x3B))
+            {
+                uint8_t l_off_nib0 = (l_sat_offset >> 4);
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(mcc_dmi,
+                                            ((l_chiplet_id == N3_CHIPLET_ID) ? (0) : (4)) +
+                                            (l_off_nib0 - 2) + l_sat_id));
+            }
+            //-------------------------------------------
+            // MI
+            //-------------------------------------------
+            //          Chiplet   Ring   Satid   Off
+            //MCS0           05     02       0   !SCOM3
+            //MCS1           05     02       2   !SCOM3
+            //MCS2           03     02       0   !SCOM3
+            //MCS3           03     02       2   !SCOM3
+            else
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MI_CHIPUNIT,
+                                            (l_sat_id / 2) +
+                                            ((l_chiplet_id == N3_CHIPLET_ID) ? (0) : (2))));
+            }
+        }
+
+        return 0;
+    }
+
+    uint32_t p9_scominfo_isChipUnitScom(const uint64_t i_scomAddr, bool& o_chipUnitRelated,
+                                        std::vector<p9_chipUnitPairing_t>& o_chipUnitPairing, const uint32_t i_mode)
+    {
+        p9_scom_addr l_scom(i_scomAddr);
+        o_chipUnitRelated = false;
+
+        uint32_t rc = 0;
+
+        uint8_t l_chiplet_id = l_scom.get_chiplet_id();
+        uint8_t l_port = l_scom.get_port();
+        uint8_t l_ring = l_scom.get_ring();
+        uint8_t l_sat_id = l_scom.get_sat_id();
+        uint8_t l_sat_offset = l_scom.get_sat_offset();
+
+        if ((i_mode & PPE_MODE) == PPE_MODE)
+        {
+            if (PPE_EP00_CHIPLET_ID <= l_chiplet_id &&
+                l_chiplet_id <= PPE_EP05_CHIPLET_ID)
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_EX_CHIPUNIT,
+                                            ((l_chiplet_id - PPE_EP00_CHIPLET_ID) * 2) +
+                                            (l_port - 1)));
+
+            }
+
+        }
+
+        else if (l_scom.is_unicast())
+        {
+            // common 'pervasive' registers associated with each pervasive chiplet type
+            // permit addressing by PERV target type (for all pervasive chiplet instances)
+            // or by C/EX/EQ target types (by their associated pervasive chiplet instances)
+            if (((l_port == GPREG_PORT_ID) ||
+                 ((l_port >= CME_PORT_ID) && (l_port <= CPM_PORT_ID)) ||
+                 (l_port == PCBSLV_PORT_ID) ||
+                 (l_port == UNIT_PORT_ID && l_ring == EC_PSCM_RING_ID) || //Catches all PSCOM regs
+                 (l_port == UNIT_PORT_ID && l_ring == EC_PERV_RING_ID
+                  && l_sat_id == PERV_DBG_SAT_ID))) // Each chiplet also has a DBG macro
+            {
+                o_chipUnitRelated = true;
+                // PU_PERV_CHIPUNIT
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PERV_CHIPUNIT,
+                                            l_chiplet_id));
+
+                // PU_C_CHIPUNIT / PU_EX_CHIPUNIT
+                if ((l_chiplet_id >= EC00_CHIPLET_ID) && (l_chiplet_id <= EC23_CHIPLET_ID))
+                {
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_C_CHIPUNIT,
+                                                l_chiplet_id - EC00_CHIPLET_ID));
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_EX_CHIPUNIT,
+                                                (l_chiplet_id - EC00_CHIPLET_ID) / 2));
+                }
+
+                // PU_EQ_CHIPUNIT
+                if ((l_chiplet_id >= EP00_CHIPLET_ID) && (l_chiplet_id <= EP05_CHIPLET_ID))
+                {
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_EQ_CHIPUNIT,
+                                                l_chiplet_id - EP00_CHIPLET_ID));
+                }
+            }
+
+            // core registers which can be addressed by either C/EX target types
+            // c: 0..24
+            if (((l_chiplet_id >= EC00_CHIPLET_ID) && (l_chiplet_id <= EC23_CHIPLET_ID)) &&
+                (l_port == UNIT_PORT_ID) &&
+                ((l_ring >= EC_PERV_RING_ID) && (l_ring <= EC_PC_3_RING_ID)))
+            {
+                o_chipUnitRelated = true;
+                // PU_C_CHIPUNIT
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_C_CHIPUNIT,
+                                            l_chiplet_id - EC00_CHIPLET_ID));
+                // PU_EX_CHIPUNIT
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_EX_CHIPUNIT,
+                                            (l_chiplet_id - EC00_CHIPLET_ID) / 2));
+            }
+
+            // quad registers which can be addressed by either EQ/EX target types
+            // ex: 0..12
+            // eq: 0..6
+            if (((l_chiplet_id >= EP00_CHIPLET_ID) && (l_chiplet_id <= EP05_CHIPLET_ID)) &&
+                (l_port == UNIT_PORT_ID) &&
+                (((l_ring >= EQ_PERV_RING_ID)  && (l_ring <= EQ_L3_1_RING_ID)) ||
+                 ((l_ring >= EQ_CME_0_RING_ID) && (l_ring <= EQ_L2_1_TRA_RING_ID))))
+            {
+                o_chipUnitRelated = true;
+                // PU_EQ_CHIPUNIT
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_EQ_CHIPUNIT,
+                                            l_chiplet_id - EP00_CHIPLET_ID));
+
+                // PU_EX_CHIPUNIT
+                if ((l_ring == EQ_L2_0_RING_ID)  || (l_ring == EQ_NC_0_RING_ID) || (l_ring == EQ_L3_0_RING_ID) ||
+                    (l_ring == EQ_CME_0_RING_ID) || (l_ring == EQ_L2_0_TRA_RING_ID))
+                {
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_EX_CHIPUNIT,
+                                                (l_chiplet_id - EP00_CHIPLET_ID) * 2));
+                }
+                // PU_EX_CHIPUNIT
+                else if ((l_ring == EQ_L2_1_RING_ID)  || (l_ring == EQ_NC_1_RING_ID) || (l_ring == EQ_L3_1_RING_ID) ||
+                         (l_ring == EQ_CME_1_RING_ID) || (l_ring == EQ_L2_1_TRA_RING_ID))
+                {
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_EX_CHIPUNIT,
+                                                ((l_chiplet_id - EP00_CHIPLET_ID) * 2) + 1));
+                }
+            }
+
+            // PU_CAPP_CHIPUNIT
+            // capp: 0..1
+            if ((((l_chiplet_id == N0_CHIPLET_ID) && (l_ring == N0_CXA0_0_RING_ID)) ||
+                 ((l_chiplet_id == N2_CHIPLET_ID) && (l_ring == N2_CXA1_0_RING_ID))) &&
+                (l_port == UNIT_PORT_ID))
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_CAPP_CHIPUNIT,
+                                            (l_chiplet_id / 2) - 1));
+            }
+
+            //==== NIMBUS MCBIST/MCA =======================================================================================================
+            if (i_mode == P9N_DD1_SI_MODE || i_mode == P9N_DD2_SI_MODE)
+            {
+                // PU_MCS_CHIPUNIT (nest)
+                // mcs: 0..3
+                if (((l_chiplet_id == N3_CHIPLET_ID) || (l_chiplet_id == N1_CHIPLET_ID)) &&
+                    (l_port == UNIT_PORT_ID) &&
+                    (l_ring == N3_MC01_0_RING_ID) &&
+                    ((l_sat_id == MC_DIR_SAT_ID_PBI_01) || (l_sat_id == MC_DIR_SAT_ID_PBI_23)) &&
+                    (((0x2F & l_sat_offset) < MC_MCS_MCA_OFFSET_MCP0XLT0 || MC_MCS_MCA_OFFSET_MCPERF3 < (0x2F & l_sat_offset))))
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MCS_CHIPUNIT,
+                                                ((l_chiplet_id == N3_CHIPLET_ID) ? (0) : (2)) +
+                                                (l_sat_id / 2)));
+                }
+
+                // PU_MCBIST_CHIPUNIT (mc)
+                // mcbist: 0..1
+                if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)) &&
+                    (((l_port == UNIT_PORT_ID) &&
+                      (((l_ring == MC_MC01_1_RING_ID) &&
+                        ((l_sat_id & 0xC) == MC_DIR_SAT_ID_MCBIST)) || //MCBIST has 2 bit sat_id
+                       ((l_ring == MC_PERV_RING_ID) || //Translate MC perv regs with MCBIST
+                        (l_ring == XB_PSCM_RING_ID) ||
+                        (l_ring == MC_MCTRA_0_RING_ID)) )) || //Translate TRA regs with MCBIST
+                     (l_port != UNIT_PORT_ID)) )   //Translate MC perv regs with MCBIST
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MCBIST_CHIPUNIT,
+                                                l_chiplet_id - MC01_CHIPLET_ID));
+                }
+
+                // PU_MCA_CHIPUNIT (mc)
+                // mca: 0..7
+                // These regisers are in the mcs chiplet but are logically mca targetted
+                if (((l_chiplet_id == N3_CHIPLET_ID) || (l_chiplet_id == N1_CHIPLET_ID)) &&
+                    (l_port == UNIT_PORT_ID) &&
+                    (l_ring == N3_MC01_0_RING_ID) &&
+                    ((l_sat_id == MC_DIR_SAT_ID_PBI_01) || (l_sat_id == MC_DIR_SAT_ID_PBI_23)) &&
+                    (((0x2F & l_sat_offset) >= MC_MCS_MCA_OFFSET_MCP0XLT0 && MC_MCS_MCA_OFFSET_MCPERF3 >= (0x2F & l_sat_offset))))
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MCA_CHIPUNIT,
+                                                ((((l_chiplet_id == N3_CHIPLET_ID) ? (0) : (2)) +
+                                                  (l_sat_id / 2)) * 2) +
+                                                ((l_sat_offset & 0x10) >> 4) ));
+                }
+
+                // PU_MCA_CHIPUNIT (mc)
+                // mca: 0..7
+                if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)) &&
+                    (l_port == UNIT_PORT_ID) &&
+                    (l_ring == MC_MC01_0_RING_ID) &&
+                    ((l_sat_id >= MC_DIR_SAT_ID_SRQ_0) && (l_sat_id <= MC_DIR_SAT_ID_ECC64_3)))
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MCA_CHIPUNIT,
+                                                (4 * (l_chiplet_id - MC01_CHIPLET_ID)) +
+                                                (l_sat_id % 4)));
+                }
+
+                // PU_MCA_CHIPUNIT (iomc)
+                // mca: 0..7
+                if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)) &&
+                    (l_port == UNIT_PORT_ID) &&
+                    ((l_ring >= MC_IOM01_0_RING_ID) && (l_ring <= MC_IOM23_1_RING_ID)) &&
+                    (l_sat_id == MC_IND_SAT_ID))
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MCA_CHIPUNIT,
+                                                (4 * (l_chiplet_id - MC01_CHIPLET_ID)) +
+                                                (l_ring - MC_IOM01_0_RING_ID)));
+                }
+
+                //<<< END OF NIMBUS MCBIST/MCA ===========================================================================
+            }
+            else if (i_mode == P9C_DD1_SI_MODE || i_mode == P9C_DD2_SI_MODE)
+            {
+                //==== CUMULUS MC/MI/DMI==================================================================================
+                rc = p9_scominfo_xlate_mi(o_chipUnitRelated, o_chipUnitPairing, l_scom, PU_DMI_CHIPUNIT, 0x20, 0x30, i_mode);
+
+                if (rc)
+                {
+                    return rc;
+                }
+
+                // Figtree references: mc_top_baseaddr.fig, e9_uchip_offset.fig
+                //-------------------------------------------
+                // MC
+                //-------------------------------------------
+                // MC            07     08     0xC(!0xD)
+                // MC            08     08     0xC(!0xD)
+                //Probably any other chipelt 07/08 registers that don't fall into the DMI target range
+                if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)) &&
+                    ( ( (l_port == UNIT_PORT_ID) &&
+                        (
+                            ( (l_ring == P9C_MC_BIST_RING_ID) &&
+                              (l_sat_id != P9C_SAT_ID_CHAN_MCBIST)
+                            ) ||
+                            ( (l_ring == P9C_MC_PERV_RING_ID) || //Translate MC perv regs with MC
+                              (l_ring == P9C_MC_PSCM_RING_ID) ||
+                              (l_ring == P9C_MC_MCTRA_RING_ID) ||
+                              (l_ring == P9C_MC_PPE_RING_ID)
+                            ) ||
+                            ( (l_ring == P9C_MC_IO_RING_ID) &&
+                              (l_sat_id == MC_IND_SAT_ID) &&
+                              (l_sat_offset != P9C_MC_OFFSET_IND)
+                            )
+                        )
+                      ) || //Translate TRA regs with MCBIST
+                      (l_port != UNIT_PORT_ID)
+                    ) )   //Translate MC perv regs with MCBIST
+                {
+
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MC_CHIPUNIT,
+                                                l_chiplet_id - MC01_CHIPLET_ID));
+
+                }
+
+                if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)) &&
+                    (l_port == UNIT_PORT_ID))
+                {
+                    //-------------------------------------------
+                    // DMI
+                    //-------------------------------------------
+                    //SCOM1,2
+                    //DMI0           07     02       0
+                    //DMI1           07     02       1
+                    //DMI2           07     02       2
+                    //DMI3           07     02       3
+                    //DMI4           08     02       0
+                    //DMI5           08     02       1
+                    //DMI6           08     02       2
+                    //DMI7           08     02       3
+                    if (l_ring == P9C_MC_CHAN_RING_ID)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_DMI_CHIPUNIT,
+                                                    ((l_chiplet_id == MC01_CHIPLET_ID ? (0) : (4))) +
+                                                    (0x3 & l_sat_id)));
+
+                    }
+
+                    //SCOM4
+                    //DMI0           07     08     0xD   0x0X
+                    //DMI1           07     08     0xD   0x1X
+                    //DMI2           07     08     0xD   0x2X
+                    //DMI3           07     08     0xD   0x3X
+                    //DMI4           08     08     0xD   0x0X
+                    //DMI5           08     08     0xD   0x1X
+                    //DMI6           08     08     0xD   0x2X
+                    //DMI7           08     08     0xD   0x3X
+                    if (l_ring == P9C_MC_BIST_RING_ID && l_sat_id == P9C_SAT_ID_CHAN_MCBIST)
+                    {
+                        uint8_t l_off_nib0 = (l_sat_offset >> 4);
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_DMI_CHIPUNIT,
+                                                    ((l_chiplet_id == MC01_CHIPLET_ID ? (0) : (4))) +
+                                                    l_off_nib0));
+
+                    }
+
+                    //-------------------------------------------
+                    // DMI IO
+                    //-------------------------------------------
+                    //          Chiplet   Ring   Satid    Off    RXTXGrp
+                    //DMI0           07     04       0   0x3F       0x00
+                    //DMI1           07     04       0   0x3F       0x01
+                    //DMI2           07     04       0   0x3F       0x02
+                    //DMI3           07     04       0   0x3F       0x03
+                    //DMI4           08     04       0   0x3F       0x00
+                    //DMI5           08     04       0   0x3F       0x01
+                    //DMI6           08     04       0   0x3F       0x02
+                    //DMI7           08     04       0   0x3F       0x03
+
+                    //DMI0           07     04       0   0x3F       0x20
+                    //DMI1           07     04       0   0x3F       0x21
+                    //DMI2           07     04       0   0x3F       0x22
+                    //DMI3           07     04       0   0x3F       0x23
+                    //DMI4           08     04       0   0x3F       0x20
+                    //DMI5           08     04       0   0x3F       0x21
+                    //DMI6           08     04       0   0x3F       0x22
+                    //DMI7           08     04       0   0x3F       0x23
+                    //
+                    //0 MC01.CHAN0  IOM01.TX_WRAP.TX3
+                    //1 MC01.CHAN1  IOM01.TX_WRAP.TX2
+                    //2 MC01.CHAN2  IOM01.TX_WRAP.TX0
+                    //3 MC01.CHAN3  IOM01.TX_WRAP.TX1
+                    //4 MC23.CHAN0  IOM23.TX_WRAP.TX3
+                    //5 MC23.CHAN1  IOM23.TX_WRAP.TX2
+                    //6 MC23.CHAN2  IOM23.TX_WRAP.TX0
+                    //7 MC23.CHAN3  IOM23.TX_WRAP.TX1
+                    // 3, 2, 0, 1
+                    if (l_ring == P9C_MC_IO_RING_ID && l_sat_id == MC_IND_SAT_ID &&
+                        l_sat_offset == P9C_MC_OFFSET_IND )
+                    {
+                        uint32_t l_rxtx_grp = l_scom.get_rxtx_group_id();
+                        uint32_t l_ind_addr = l_scom.get_ind_addr();
+
+                        //From iofrc_bus_reg_intf.vhdl
+                        //gcr_pkt_equal_addr  <=     (gcr_reg_reg_addr(0 to 3) = "1111")
+                        //                            and not (gcr_reg_reg_addr = "111111111");  --Ignore protected FIR address
+                        if (((l_ind_addr & 0x1E0) == 0x1E0) && (l_ind_addr != 0x1FF))
+                        {
+                            o_chipUnitRelated = true;
+                            o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MC_CHIPUNIT,
+                                                        l_chiplet_id - MC01_CHIPLET_ID));
+
+                        }
+                        else
+                        {
+
+                            if (l_rxtx_grp >= 0x20)
+                            {
+                                l_rxtx_grp -= 0x20;
+                            }
+
+                            uint8_t l_adder = 0;
+
+                            switch (l_rxtx_grp % 4)
+                            {
+                                case 3:
+                                    l_adder = 0;
+                                    break;
+
+                                case 2:
+                                    l_adder = 1;
+                                    break;
+
+                                case 0:
+                                    l_adder = 2;
+                                    break;
+
+                                case 1:
+                                    l_adder = 3;
+                                    break;
+
+                                default:
+                                    //escape to bunker - math broke
+                                    break;
+                            }
+
+                            o_chipUnitRelated = true;
+                            o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_DMI_CHIPUNIT,
+                                                        ((l_chiplet_id == MC01_CHIPLET_ID ? (0) : (4))) +
+                                                        l_adder));
+                        }
+                    }
+
+                    //DMI PPE Registers
+                    if ( l_ring == P9C_MC_PPE_RING_ID )
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PPE_CHIPUNIT,
+                                                    (l_chiplet_id - MC01_CHIPLET_ID) + PPE_IO_DMI0_CHIPUNIT_NUM));
+                    }
+                }
+
+                //<<< END OF CUMULUS MC/MI/DMI===========================================================================
+            }
+            else
+            {
+                //==== AXONE MC/MI/OMIC/OMI  ============================================================================
+                rc = p9_scominfo_xlate_mi(o_chipUnitRelated, o_chipUnitPairing, l_scom, PU_MCC_CHIPUNIT, 0x23, 0x33, i_mode);
+
+                if (rc)
+                {
+                    return rc;
+                }
+
+                // Unused rings: 3,7,13-15   Used, 1*,2*,4*,5*,6*,8*,9*,10*,11*,12*
+                //==== MC target ===============================================
+                //Ring 1, 8 (All registers can include MC type as needed
+                if (((l_chiplet_id == MC01_CHIPLET_ID) || (l_chiplet_id == MC23_CHIPLET_ID)))
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MC_CHIPUNIT,
+                                                l_chiplet_id - MC01_CHIPLET_ID));
+
+                    //==== MCC/DMI target ==========================================
+                    //  tc_unit_scom_cch_out(2) => tc_mc01_0_scom_cch_int Ring: 2
+                    //CHANX.USTL.  Sat_id: 10 + port_id (8,9,10,11)
+                    //CHANX.DSTL.  Sat_id: 01 + port_id (4,5,6,7)
+                    if (l_ring == P9A_MC_CHAN_RING_ID && l_port == UNIT_PORT_ID)
+                    {
+                        if ((P9A_MC_DSTL_CHAN0_SAT_ID <= l_sat_id && l_sat_id <= P9A_MC_DSTL_CHAN3_SAT_ID) ||
+                            (P9A_MC_USTL_CHAN0_SAT_ID <= l_sat_id && l_sat_id <= P9A_MC_USTL_CHAN3_SAT_ID))
+                        {
+                            o_chipUnitRelated = true;
+                            o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_MCC_CHIPUNIT,
+                                                        ((l_chiplet_id - MC01_CHIPLET_ID) * 4) + (l_sat_id % 4)));
+                        }
+                    }
+
+                    //==== OMIC target =============================================
+                    //tc_unit_scom_cch_out(9)  => tc_omippe00_0_scom_cch_int
+                    //tc_unit_scom_cch_out(10) => tc_omippe01_0_scom_cch_int
+                    //tc_unit_scom_cch_out(11) => tc_omippe02_0_scom_cch_int
+                    //Ring (9,10,11) (OMI0,1,2) PPE
+                    //Ring (4,5,6)   (OMI0,1,2) BUSCTL Include indirect registers so
+                    //               they can be accessed via OMIC and OMI
+                    if (P9A_MC_OMIC0_RING_ID <= l_ring && l_ring <= P9A_MC_OMIC2_RING_ID  && l_port == UNIT_PORT_ID)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_OMIC_CHIPUNIT,
+                                                    ((l_chiplet_id - MC01_CHIPLET_ID) * 3) +
+                                                    (l_ring - P9A_MC_OMIC0_RING_ID)));
+
+                        // IO Ind regsiters  (Ring 4,5,6) reg == 63
+                        // 0701103F MCP_OMI0. Lanes 0-7    omi0
+                        // 0701103F MCP_OMI0. Lanes 8-15   omi1
+                        // 0701103F MCP_OMI0. Lanes 16-23  omi2
+                        // 0701143F MCP_OMI1. Lanes 0-7    omi3
+                        // 0701143F MCP_OMI1. Lanes 8-15   omi4
+                        // 0701143F MCP_OMI1. Lanes 16-23  omi5
+                        // 0701183F MCP_OMI2. Lanes 0-7    omi6
+                        // 0701183F MCP_OMI2. Lanes 8-15   omi7
+                        if (l_sat_id == P9A_MC_IND_SAT_ID && l_sat_offset == P9A_MC_IND_REG)
+                        {
+                            uint32_t l_ind_reg = l_scom.get_ind_addr();
+
+                            //Bit 0 of the ind register address == 0 indicates if it is per-lane
+                            if ((l_ind_reg & 0x100) == 0x000)
+                            {
+                                uint32_t l_ind_lane = l_scom.get_lane_id();
+                                o_chipUnitRelated = true;
+                                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_OMI_CHIPUNIT,
+                                                            P9_SCOMINFO_OMI_SWIZZLE[((l_chiplet_id - MC01_CHIPLET_ID) * 8) +
+                                                                    ((l_ring - P9A_MC_OMIC0_RING_ID) * 3) +
+                                                                    ((l_ind_lane / 8))]));
+                            }
+                        }
+                    }
+
+                    if (P9A_MC_OMIC0_PPE_RING_ID <= l_ring && l_ring < P9A_MC_OMIC2_PPE_RING_ID  && l_port == UNIT_PORT_ID)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_OMIC_CHIPUNIT,
+                                                    ((l_chiplet_id - MC01_CHIPLET_ID) * 3) +
+                                                    (l_ring - P9A_MC_OMIC0_PPE_RING_ID)));
+                    }
+
+                    //==== OMI target ==============================================
+                    // DL Registers
+                    // reg0 dl0 -> omi0  ring: 12  sat_id: 13  regs 16..31
+                    // reg0 dl1 -> omi1  ring: 12  sat_id: 13  regs 32..47
+                    // reg0 dl2 -> omi2  ring: 12  sat_id: 13  regs 48..63
+                    // reg1 dl0 -> omi3  ring: 12  sat_id: 14  regs 16..31
+                    // reg1 dl1 -> omi4  ring: 12  sat_id: 14  regs 32..47
+                    // reg1 dl2 -> omi5  ring: 12  sat_id: 14  regs 48..63
+                    // reg2 dl0 -> omi6  ring: 12  sat_id: 15  regs 16..31
+                    // reg2 dl1 -> omi7  ring: 12  sat_id: 15  regs 32..47
+                    if (l_ring == P9A_MC_OMI_DL_RING_ID && l_port == UNIT_PORT_ID)
+                    {
+                        if (P9A_MC_DL_REG0_SAT_ID <= l_sat_id && l_sat_id <= P9A_MC_DL_REG2_SAT_ID)
+                        {
+                            if (P9A_MC_DL_OMI0_FRST_REG <= l_sat_offset)
+                            {
+                                o_chipUnitRelated = true;
+                                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_OMI_CHIPUNIT,
+                                                            P9_SCOMINFO_OMI_SWIZZLE[((l_chiplet_id - MC01_CHIPLET_ID) * 8) +
+                                                                    ((l_sat_id - P9A_MC_DL_REG0_SAT_ID) * 3) +
+                                                                    ((l_sat_offset / 16) - 1)]));
+                            }
+                        }
+                    }
+                }
+            }
+
+            // PU_NV_CHIPUNIT
+            if (i_mode == P9N_DD1_SI_MODE)
+            {
+                // See npu_misc_regs.vhdl, line 2710,
+                // sc_addr(0 to 6) represents sat_id(0..3) and sat_offset(0..2)
+                // only stkX, ntlX registers are translated to NX target type
+                // nv: 0..5
+                if ((l_chiplet_id == N3_CHIPLET_ID) &&
+                    (l_port == UNIT_PORT_ID) &&
+                    (((l_ring == N3_NPU_0_RING_ID) && ((l_sat_id % 4) == 3) && l_sat_id <= 11)))
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NV_CHIPUNIT,
+                                                (2 * (l_sat_id / 4)) +
+                                                (l_sat_offset / 32)));
+                }
+            }
+            else if (i_mode != P9A_DD1_SI_MODE && i_mode != P9A_DD2_SI_MODE)
+            {
+                //DD2 NV link (and Cumulus until we know better)
+                // See npu_misc_regs.vhdl
+                // sc_addr(0 to 7)  bits 1 to 4 are the sat_id bit 0 is the lsb of the ring
+                //  rings 4 and 5 are used.
+                //                       rrrrrrSTIDxxx---
+                //                       000100
+                //       x"4900" & "00" when "00100010", -- stk0, ntl0, 00-07, hyp-only
+                //       x"4900" & "01" when "00100011", -- stk0, ntl0, 08-15, hyp-only
+                //       x"4900" & "10" when "00100100", -- stk0, ntl0, 16-23, hyp-only
+                //       x"0900" & "11" when "00100101", -- stk0, ntl0, 24-31, user-acc
+                //       x"4b00" & "00" when "00100110", -- stk0, ntl1, 00-07, hyp-only
+                //       x"4b00" & "01" when "00100111", -- stk0, ntl1, 08-15, hyp-only
+                //       x"4b00" & "10" when "00101000", -- stk0, ntl1, 16-23, hyp-only --          addresses 0x140-147
+                //       x"0b00" & "11" when "00101001", -- stk0, ntl1, 24-31, user-acc
+                //                             STID
+                //       x"5900" & "00" when "01100010", -- stk1, ntl0, 00-07, hyp-only
+                //       x"5900" & "01" when "01100011", -- stk1, ntl0, 08-15, hyp-only
+                //       x"5900" & "10" when "01100100", -- stk1, ntl0, 16-23, hyp-only
+                //       x"1900" & "11" when "01100101", -- stk1, ntl0, 24-31, user-acc
+                //       x"5b00" & "00" when "01100110", -- stk1, ntl1, 00-07, hyp-only
+                //       x"5b00" & "01" when "01100111", -- stk1, ntl1, 08-15, hyp-only
+                //       x"5b00" & "10" when "01101000", -- stk1, ntl1, 16-23, hyp-only --          addresses 0x340-347
+                //       x"1b00" & "11" when "01101001", -- stk1, ntl1, 24-31, user-acc
+                //                             STID
+                //       x"6900" & "00" when "10100010", -- stk2, ntl0, 00-07, hyp-only
+                //       x"6900" & "01" when "10100011", -- stk2, ntl0, 08-15, hyp-only
+                //       x"6900" & "10" when "10100100", -- stk2, ntl0, 16-23, hyp-only
+                //       x"2900" & "11" when "10100101", -- stk2, ntl0, 24-31, user-acc
+                //       x"6b00" & "00" when "10100110", -- stk2, ntl1, 00-07, hyp-only
+                //       x"6b00" & "01" when "10100111", -- stk2, ntl1, 08-15, hyp-only
+                //       x"6b00" & "10" when "10101000", -- stk2, ntl1, 16-23, hyp-only --          addresses 0x540-54f
+                //       x"2b00" & "11" when "10101001", -- stk2, ntl1, 24-31, user-acc
+                if ((l_chiplet_id == N3_CHIPLET_ID) &&
+                    (l_port == UNIT_PORT_ID))
+                {
+
+                    //We have to do ugly bit manipulation here anyway.  It is clearer
+                    //just to do it with the raw scom address.
+                    //Combine the ring(6) sat_id(4) and high order 3 bits of sat_offset
+                    //to compare with vhdl values for NV registers
+                    uint64_t npuaddr = (i_scomAddr & 0xFFF8ULL) >> 3;
+
+                    if (0x0222ULL <= npuaddr && npuaddr <= 0x0225ULL)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NV_CHIPUNIT, 0));
+                    }
+
+                    if (0x0226ULL <= npuaddr && npuaddr <= 0x0229ULL)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NV_CHIPUNIT, 1));
+                    }
+
+                    if (0x0262ULL <= npuaddr && npuaddr <= 0x0265ULL)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NV_CHIPUNIT, 2));
+                    }
+
+                    if (0x0266ULL <= npuaddr && npuaddr <= 0x0269ULL)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NV_CHIPUNIT, 3));
+                    }
+
+                    if (0x02A2ULL <= npuaddr && npuaddr <= 0x02A5ULL)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NV_CHIPUNIT, 4));
+                    }
+
+                    if (0x02A6ULL <= npuaddr && npuaddr <= 0x02A9ULL)
+                    {
+                        o_chipUnitRelated = true;
+                        o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_NV_CHIPUNIT, 5));
+                    }
+                }
+
+            }
+
+            // PU_PEC_CHIPUNIT (nest)
+            // pec: 0..2
+            if ((l_chiplet_id == N2_CHIPLET_ID) &&
+                (l_port == UNIT_PORT_ID) &&
+                ((l_ring >= N2_PCIS0_0_RING_ID) && (l_ring <= N2_PCIS2_0_RING_ID)) &&
+                (l_sat_id == PEC_SAT_ID))
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PEC_CHIPUNIT,
+                                            (l_ring - N2_PCIS0_0_RING_ID)));
+            }
+
+            // PU_PEC_CHIPUNIT (iopci/pci)
+            // source: iop_scom_cntl_rlm_mac.vhdl
+            // pec: 0..2
+            if (((l_chiplet_id >= PCI0_CHIPLET_ID) && (l_chiplet_id <= PCI2_CHIPLET_ID)) &&
+                ((l_port != UNIT_PORT_ID) ||
+                 ((l_port == UNIT_PORT_ID) &&
+                  ((l_ring == PCI_IOPCI_0_RING_ID) || (l_ring == PCI_PE_0_RING_ID) ||
+                   (l_ring == PCI_PERV_RING_ID)) &&
+                  (l_sat_id == PEC_SAT_ID))))
+            {
+                if ((l_chiplet_id >= PCI0_CHIPLET_ID) && (l_chiplet_id <= PCI2_CHIPLET_ID))
+                {
+                    o_chipUnitRelated = true;
+                    o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PEC_CHIPUNIT,
+                                                (l_chiplet_id - PCI0_CHIPLET_ID)));
+                }
+            }
+
+            // PU_PHB_CHIPUNIT (nest)
+            // phb: 0..5
+            if ((l_chiplet_id == N2_CHIPLET_ID) &&
+                (l_port == UNIT_PORT_ID) &&
+                ((l_ring >= N2_PCIS0_0_RING_ID) && (l_ring <= N2_PCIS2_0_RING_ID)) &&
+                (((l_ring - l_sat_id) >= 2) && ((l_ring - l_sat_id) < l_ring)))
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PHB_CHIPUNIT,
+                                            ((l_ring - N2_PCIS0_0_RING_ID) ?
+                                             (((l_ring - N2_PCIS0_0_RING_ID) * 2) - 1) :
+                                             (0)) +
+                                            (l_sat_id - 1)));
+            }
+
+            // PU_PHB_CHIPUNIT (pci)
+            // phb: 0..5
+            if (((l_chiplet_id >= PCI0_CHIPLET_ID) && (l_chiplet_id <= PCI2_CHIPLET_ID)) &&
+                (l_port == UNIT_PORT_ID) &&
+                (l_ring == PCI_PE_0_RING_ID) &&
+                (((l_sat_id >= 1) && (l_sat_id <= (l_chiplet_id - PCI0_CHIPLET_ID + 1))) || // aib_stack
+                 ((l_sat_id >= 4) && (l_sat_id <= (l_chiplet_id - PCI0_CHIPLET_ID + 4)))))  // pbcq_etu
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PHB_CHIPUNIT,
+                                            ((l_chiplet_id - PCI0_CHIPLET_ID) ?
+                                             (((l_chiplet_id - PCI0_CHIPLET_ID) * 2) - 1) :
+                                             (0)) +
+                                            l_sat_id -
+                                            ((l_sat_id >= 4) ? (4) : (1))));
+            }
+
+            // PU_OBUS_CHIPUNIT
+            // obus: 0..3
+            if (((l_chiplet_id >= OB0_CHIPLET_ID) && (l_chiplet_id <= OB3_CHIPLET_ID)))
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_OBUS_CHIPUNIT,
+                                            (l_chiplet_id - OB0_CHIPLET_ID)));
+            }
+
+            // PU_XBUS_CHIPUNIT
+            // xbus: 0..2
+            if ((l_chiplet_id == XB_CHIPLET_ID) &&
+                (l_port == UNIT_PORT_ID) &&
+                (((l_ring >= XB_IOX_0_RING_ID) && (l_ring <= XB_IOX_2_RING_ID) && (l_sat_id == XB_IOF_SAT_ID)) ||
+                 ((l_ring >= XB_PBIOX_0_RING_ID) && (l_ring <= XB_PBIOX_2_RING_ID) && (l_sat_id == XB_PB_SAT_ID))))
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_XBUS_CHIPUNIT,
+                                            l_ring % 3));
+            }
+
+            // -----------------------------------------------------------------------------
+            // Common 'ppe' registers associated with each pervasive chiplet type
+            // Permit addressing by PPE target type (for all ppe chiplet instances)
+            // -----------------------------------------------------------------------------
+
+            // SBE PM registers
+            //    Port ID = 14
+            if ( (l_port == SBE_PORT_ID) &&
+                 (l_chiplet_id == PIB_CHIPLET_ID) &&
+                 (l_ring == PPE_SBE_RING_ID) &&
+                 (l_sat_id == PPE_SBE_SAT_ID) )
+            {
+                o_chipUnitRelated = true;
+                // PU_SBE_CHIPUNIT
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_SBE_CHIPUNIT,
+                                            l_chiplet_id));
+                // PU_PPE_CHIPUNIT
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PPE_CHIPUNIT,
+                                            l_chiplet_id));
+            }
+
+            // GPE registers
+            //    Port ID = 1
+            if ( (l_port == GPE_PORT_ID) &&
+                 (l_chiplet_id == PIB_CHIPLET_ID) &&
+                 ( (l_ring == PPE_GPE0_RING_ID) ||
+                   (l_ring == PPE_GPE1_RING_ID) ||
+                   (l_ring == PPE_GPE2_RING_ID) ||
+                   (l_ring == PPE_GPE3_RING_ID) ) &&
+                 (l_sat_id == PPE_GPE_SAT_ID) )
+            {
+                o_chipUnitRelated = true;
+                // PU_PPE_CHIPUNIT
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(
+                                                PU_PPE_CHIPUNIT,
+                                                PPE_GPE0_CHIPUNIT_NUM + (l_ring / 8)));
+            }
+
+            // CME registers which can be addressed by PPE target type
+            //    Port ID = 1
+            //    0x10 <= Chiplet ID <= 0x15
+            //    Ring_ID = 0x8 or Ring_ID = 0x9
+            //    SAT_ID = 0
+            if ( (l_port == UNIT_PORT_ID) &&
+                 ((l_chiplet_id >= EP00_CHIPLET_ID) && (l_chiplet_id <= EP05_CHIPLET_ID)) &&
+                 ( (l_ring == EQ_CME_0_RING_ID) || (l_ring == EQ_CME_1_RING_ID) ) &&
+                 (l_sat_id == PPE_CME_SAT_ID) )
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PPE_CHIPUNIT,
+                                            (l_chiplet_id - EP00_CHIPLET_ID) +
+                                            PPE_EQ0_CME0_CHIPUNIT_NUM +
+                                            ((l_ring % 8) * 10)));
+            }
+
+            // PB registers which can be addressed by PPE target type
+            //    Port ID = 1
+            //    Chiplet ID = 0x05
+            //    Ring_ID = 0x9
+            //    SAT_ID = 0
+            if ( (l_port == UNIT_PORT_ID) &&
+                 (l_chiplet_id == N3_CHIPLET_ID) &&
+                 (l_ring == N3_PB_3_RING_ID) &&
+                 (l_sat_id == PPE_PB_SAT_ID) )
+            {
+                o_chipUnitRelated = true;
+                // TODO: Need to update for PB1/PB2 of Cummulus whenever address
+                //       values are available.
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PPE_CHIPUNIT,
+                                            PPE_PB0_CHIPUNIT_NUM));
+            }
+
+            // XBUS registers which can be addressed by PPE target type (IOPPE)
+            //    Port ID = 1
+            //    Chiplet ID = 0x06
+            //    Ring_ID = 0x2
+            //    SAT_ID = 1
+            if ( (l_port == UNIT_PORT_ID) &&
+                 (l_chiplet_id == XB_CHIPLET_ID) &&
+                 (l_ring == XB_IOPPE_0_RING_ID) &&
+                 (l_sat_id == XB_PPE_SAT_ID) )
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PPE_CHIPUNIT,
+                                            PPE_IO_XBUS_CHIPUNIT_NUM));
+            }
+
+            // OBUS registers which can be addressed by PPE target type (IOPPE)
+            //    Port ID = 1
+            //    Chiplet ID = 0x09, 0x0A, 0x0B, or 0x0C
+            //    Ring_ID = 0x4
+            //    SAT_ID = 1
+            if ( (l_port == UNIT_PORT_ID) &&
+                 ((l_chiplet_id >= OB0_CHIPLET_ID) && (l_chiplet_id <= OB3_CHIPLET_ID)) &&
+                 (l_ring == OB_PPE_RING_ID) &&
+                 (l_sat_id == OB_PPE_SAT_ID) )
+            {
+                o_chipUnitRelated = true;
+                o_chipUnitPairing.push_back(p9_chipUnitPairing_t(PU_PPE_CHIPUNIT,
+                                            (l_chiplet_id - OB0_CHIPLET_ID) + PPE_IO_OB0_CHIPUNIT_NUM));
+            }
+        }
+
+        return (!l_scom.is_valid());
+    }
+
+    uint32_t p9_scominfo_fixChipUnitScomAddrOrTarget(const p9ChipUnits_t i_p9CU, const uint32_t i_targetChipUnitNum,
+            const uint64_t i_scomaddr, uint64_t& o_modifiedScomAddr, p9ChipUnits_t& o_p9CU,
+            uint32_t& o_modifiedChipUnitNum, const uint32_t i_mode)
+    {
+        uint32_t rc = 0;
+
+        o_modifiedScomAddr = i_scomaddr;
+        o_p9CU = i_p9CU;
+        o_modifiedChipUnitNum = i_targetChipUnitNum;
+
+        return rc;
+    }
+
+
+} // extern "C"
+
+#undef P9_SCOMINFO_C
diff --git a/src/tests/p9_scominfo.H b/src/tests/p9_scominfo.H
new file mode 100644
index 0000000..d153213
--- /dev/null
+++ b/src/tests/p9_scominfo.H
@@ -0,0 +1,94 @@
+/* IBM_PROLOG_BEGIN_TAG                                                   */
+/* This is an automatically generated prolog.                             */
+/*                                                                        */
+/* $Source: chips/p9/common/scominfo/p9_scominfo.H $                      */
+/*                                                                        */
+/* IBM CONFIDENTIAL                                                       */
+/*                                                                        */
+/* EKB Project                                                            */
+/*                                                                        */
+/* COPYRIGHT 2015,2017                                                    */
+/* [+] International Business Machines Corp.                              */
+/*                                                                        */
+/*                                                                        */
+/* The source code for this program is not published or otherwise         */
+/* divested of its trade secrets, irrespective of what has been           */
+/* deposited with the U.S. Copyright Office.                              */
+/*                                                                        */
+/* IBM_PROLOG_END_TAG                                                     */
+///
+/// @file p9_scominfo.H
+/// @brief P9 chip unit SCOM address platform translation code
+///
+/// HWP HWP Owner: jmcgill@us.ibm.com
+/// HWP FW Owner: dcrowell@us.ibm.com
+/// HWP Team: Infrastructure
+/// HWP Level: 1
+/// HWP Consumed by: FSP/HB
+///
+
+#ifndef P9_SCOMINFO_H
+#define P9_SCOMINFO_H
+
+// includes
+#include <stdint.h>
+#include <vector>
+#include "p9_cu.H"
+
+extern "C"
+{
+
+    //Modes for scominfo functions
+    static const uint32_t P9N_DD1_SI_MODE = 0x0;
+    static const uint32_t PPE_MODE = 0x1;
+    static const uint32_t P9N_DD2_SI_MODE = 0x2;
+    static const uint32_t P9C_DD1_SI_MODE = 0x4;
+    static const uint32_t P9C_DD2_SI_MODE = 0x8;
+    static const uint32_t P9A_DD1_SI_MODE = 0x10;
+    static const uint32_t P9A_DD2_SI_MODE = 0x20;
+
+    typedef enum
+    {
+        STANDARD_MODE = 0
+    } p9TranslationMode_t;
+
+    typedef enum
+    {
+        FAILED_TRANSLATION = 0xFFFFFFFFFFFFFFF1ull
+    } p9TranslationResult_t;
+
+    /// @brief Creates the actual SCOM address based on the chip unit type, instance, and the input SCOM address (relative to chip unit instance 0)
+    /// @param[in] i_p9CU Enumeration of the chip unit type
+    /// @param[in] i_chipUnitNum Instance number of the chip unit
+    /// @param[in] i_scomAddr The input SCOM address associated with the chip unit type
+    /// @param[in] i_mode Used for special purposes, default to 0 = p9n dd1, 1 = ppe_mode, 2 = p9n dd2.X, 4 = p9c dd1.X, 8 = p9c dd2
+    /// @retval uint64_t Actual SCOM address for the chip unit instance passed in
+    uint64_t p9_scominfo_createChipUnitScomAddr(const p9ChipUnits_t i_p9CU, const uint8_t i_chipUnitNum,
+            const uint64_t i_scomAddr, const uint32_t i_mode = 0);
+
+    /// @brief Determine if the provided SCOM address correlates to any chip units (if so creates a list of chipUnitPairing structures which correspond)
+    /// @param[in] i_scomAddr SCOM address to be tested
+    /// @param[out] o_chipUnitRelated Returns true if SCOM address is associated with any chip units
+    /// @param[out] o_chipUnitPairing Collection of chipUnitPairing enums
+    /// @param[in] i_mode Used for special purposes, default to 0
+    /// @retval uint32_t Return non-zero for error
+    uint32_t p9_scominfo_isChipUnitScom(const uint64_t i_scomAddr, bool& o_chipUnitRelated,
+                                        std::vector<p9_chipUnitPairing_t>& o_chipUnitPairing, const uint32_t i_mode = 0);
+
+
+    /// @brief Alter the unit/unitnum of a target for spys where the clocks-on vs clocks-off targets are different.
+    /// @param[in] i_p9CU target used for the spy request
+    /// @param[in] i_targetChipUnitNum the instance number of the target used for the spy request
+    /// @param[in] i_scomaddr the scom from the clocks-on portion of the spy
+    /// @param[out] o_modifiedScomAddr the translated scom address (none may be needed)
+    /// @param[out] o_p9CU the translated target type
+    /// @param[out] o_modifiedChipUnitNum the translated target instance number
+    /// @param[in] i_mode Could be used in the future to indicate if the translation is from clocks-on or clocks-off state
+    /// @retval uint32_t Return non-zero for error
+    uint32_t p9_scominfo_fixChipUnitScomAddrOrTarget(const p9ChipUnits_t i_p9CU, const uint32_t i_targetChipUnitNum,
+            const uint64_t i_scomaddr, uint64_t& o_modifiedScomAddr, p9ChipUnits_t& o_p9CU,
+            uint32_t& o_modifiedChipUnitNum, const uint32_t i_mode = 0);
+
+} // extern "C"
+
+#endif /* P9_SCOMINFO_H */
