[Pdbg] [RFC PATCH 05/11] libpdbg: Add translation support for EKB targets
Amitay Isaacs
amitay at ozlabs.org
Tue Nov 12 13:12:45 AEDT 2019
From: Alistair Popple <alistair at popple.id.au>
This adds support for the address translation scheme used by targets
in the EKB.
Signed-off-by: Alistair Popple <alistair at popple.id.au>
---
Makefile.am | 4 +-
libpdbg/hwunit.h | 120 +++++++
libpdbg/p9_fapi_targets.c | 652 ++++++++++++++++++++++++++++++++++++++
3 files changed, 774 insertions(+), 2 deletions(-)
create mode 100644 libpdbg/p9_fapi_targets.c
diff --git a/Makefile.am b/Makefile.am
index e4905b7..44f5d7c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -190,10 +190,10 @@ libpdbg_la_SOURCES = \
libpdbg/operations.h \
libpdbg/p8chip.c \
libpdbg/p9chip.c \
+ libpdbg/p9_fapi_targets.c \
libpdbg/sbefifo.c \
libpdbg/target.c \
- libpdbg/target.h \
- libpdbg/xbus.c
+ libpdbg/target.h
libpdbg_la_CFLAGS = -Wall -Werror
libpdbg_la_LIBADD = libcronus.la libsbefifo.la
diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h
index 06e5fca..93b814d 100644
--- a/libpdbg/hwunit.h
+++ b/libpdbg/hwunit.h
@@ -144,4 +144,124 @@ struct xbus {
};
#define target_to_xbus(x) container_of(x, struct xbus, target)
+struct ex {
+ struct pdbg_target target;
+};
+#define target_to_ex(x) container_of(x, struct ex, target)
+
+struct mba {
+ struct pdbg_target target;
+};
+#define target_to_mba(x) container_of(x, struct mba, target)
+
+struct mcs {
+ struct pdbg_target target;
+};
+#define target_to_mcs(x) container_of(x, struct mcs, target)
+
+struct abus {
+ struct pdbg_target target;
+};
+#define target_to_abus(x) container_of(x, struct abus, target)
+
+struct l4 {
+ struct pdbg_target target;
+};
+#define target_to_l4(x) container_of(x, struct l4, target)
+
+struct eq {
+ struct pdbg_target target;
+};
+#define target_to_eq(x) container_of(x, struct eq, target)
+
+struct mca {
+ struct pdbg_target target;
+};
+#define target_to_mca(x) container_of(x, struct mca, target)
+
+struct mcbist {
+ struct pdbg_target target;
+};
+#define target_to_mcbist(x) container_of(x, struct mcbist, target)
+
+struct mi {
+ struct pdbg_target target;
+};
+#define target_to_mi(x) container_of(x, struct mi, target)
+
+struct dmi {
+ struct pdbg_target target;
+};
+#define target_to_dmi(x) container_of(x, struct dmi, target)
+
+struct obus {
+ struct pdbg_target target;
+};
+#define target_to_obus(x) container_of(x, struct obus, target)
+
+struct obus_brick {
+ struct pdbg_target target;
+};
+#define target_to_obus_brick(x) container_of(x, struct obus_brick, target)
+
+struct sbe {
+ struct pdbg_target target;
+};
+#define target_to_sbe(x) container_of(x, struct sbe, target)
+
+struct ppe {
+ struct pdbg_target target;
+};
+#define target_to_ppe(x) container_of(x, struct ppe, target)
+
+struct perv {
+ struct pdbg_target target;
+};
+#define target_to_perv(x) container_of(x, struct perv, target)
+
+struct pec {
+ struct pdbg_target target;
+};
+#define target_to_pec(x) container_of(x, struct pec, target)
+
+struct phb {
+ struct pdbg_target target;
+};
+#define target_to_phb(x) container_of(x, struct phb, target)
+
+struct mc {
+ struct pdbg_target target;
+};
+#define target_to_mc(x) container_of(x, struct mc, target)
+
+struct mem_port {
+ struct pdbg_target target;
+};
+#define target_to_mem_port(x) container_of(x, struct mem_port, target)
+
+struct nmmu {
+ struct pdbg_target target;
+};
+#define target_to_nmmu(x) container_of(x, struct nmmu, target)
+
+struct pau {
+ struct pdbg_target target;
+};
+#define target_to_pau(x) container_of(x, struct pau, target)
+
+struct iohs {
+ struct pdbg_target target;
+};
+#define target_to_iohs(x) container_of(x, struct iohs, target)
+
+struct fc {
+ struct pdbg_target target;
+};
+#define target_to_fc(x) container_of(x, struct fc, target)
+
+struct pauc {
+ struct pdbg_target target;
+};
+#define target_to_pauc(x) container_of(x, struct pauc, target)
+
#endif /* __HWUNIT_H */
diff --git a/libpdbg/p9_fapi_targets.c b/libpdbg/p9_fapi_targets.c
new file mode 100644
index 0000000..b6de79b
--- /dev/null
+++ b/libpdbg/p9_fapi_targets.c
@@ -0,0 +1,652 @@
+/* Copyright 2018 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include "hwunit.h"
+#include "bitutils.h"
+#include "p9_scom_addr.h"
+
+#define t(x) (&(x)->target)
+
+/* There is a FAPI target type but no scominfo, not sure how to do
+ * translation in this case so just explode. */
+static uint64_t p9_unknown_translation(struct pdbg_target *target, uint64_t addr)
+{
+ pdbg_log(PDBG_ERROR, "Translation of address 0x%016" PRIx64 " unknown for target %s\n",
+ addr, pdbg_target_path(target));
+ return -1;
+}
+
+static uint64_t p9_ex_translate(struct ex *ex, uint64_t addr)
+{
+ if (get_chiplet_id(addr) >= EP00_CHIPLET_ID &&
+ get_chiplet_id(addr) <= EP05_CHIPLET_ID) {
+ uint8_t ring_id = get_ring(addr) & 0xf;
+ addr = set_chiplet_id(addr, EP00_CHIPLET_ID + pdbg_target_index(t(ex)) / 2);
+ ring_id = ring_id - ring_id % 2 + pdbg_target_index(t(ex)) % 2;
+ return set_ring(addr, ring_id & 0xf);
+ } else if (get_chiplet_id(addr) >= EC00_CHIPLET_ID &&
+ get_chiplet_id(addr) <= EC23_CHIPLET_ID) {
+ return set_chiplet_id(addr, EC00_CHIPLET_ID +
+ get_chiplet_id(addr) % 2 +
+ pdbg_target_index(t(ex)) * 2);
+ } else {
+ pdbg_log(PDBG_WARNING, "Invalid ex address 0x%016" PRIx64 "\n", addr);
+ return addr;
+ }
+}
+
+struct ex p9_ex = {
+ .target = {
+ .name = "POWER9 ex",
+ .compatible = "ibm,power9-ex",
+ .class = "ex",
+ .translate = translate_cast(p9_ex_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_ex);
+
+struct mba p9_mba = {
+ .target = {
+ .name = "POWER9 mba",
+ .compatible = "ibm,power9-mba",
+ .class = "mba",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_mba);
+
+static uint64_t p9_mcs_translate(struct mcs *mcs, uint64_t addr)
+{
+ uint32_t chiplet = N3_CHIPLET_ID - 2 * (pdbg_target_index(t(mcs)) / 2);
+ uint32_t sat = 2 * (pdbg_target_index(t(mcs)) % 2);
+
+ addr = set_chiplet_id(addr, chiplet);
+ addr = set_sat_id(addr, sat);
+
+ return addr;
+}
+
+struct mcs p9_mcs = {
+ .target = {
+ .name = "POWER9 mcs",
+ .compatible = "ibm,power9-mcs",
+ .class = "mcs",
+ .translate = translate_cast(p9_mcs_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_mcs);
+
+/* XBus addressing is more complicated. This comes from p9_scominfo.C
+ * in the ekb. */
+static uint64_t p9_xbus_translate(struct xbus *xbus, uint64_t addr)
+{
+ int chip_unitnum = pdbg_target_index(t(xbus));
+ uint64_t ring = get_ring(addr) & 0xf;
+
+ if (ring >= XB_IOX_0_RING_ID &&
+ ring <= XB_IOX_2_RING_ID)
+ return set_ring(addr, (XB_IOX_0_RING_ID + chip_unitnum) & 0xf);
+ else if (ring >= XB_PBIOX_0_RING_ID &&
+ ring <= XB_PBIOX_2_RING_ID)
+ return set_ring(addr, (XB_PBIOX_0_RING_ID + chip_unitnum) & 0xf);
+ else {
+ pdbg_log(PDBG_WARNING, "Invalid xbus address 0x%016" PRIx64 "\n", addr);
+ return addr;
+ }
+}
+
+static int p9_xbus_probe(struct pdbg_target *target)
+{
+ struct xbus *xbus = target_to_xbus(target);
+
+ if (pdbg_target_u32_property(&xbus->target, "ring-id", &xbus->ring_id)) {
+ printf("Unknown ring-id on %s@%d\n", pdbg_target_name(&xbus->target),
+ pdbg_target_index(&xbus->target));
+ return -1;
+ }
+
+ return 0;
+}
+
+struct xbus p9_xbus = {
+ .target = {
+ .name = "POWER9 xbus",
+ .compatible = "ibm,power9-xbus",
+ .class = "xbus",
+ .probe = p9_xbus_probe,
+ .translate = translate_cast(p9_xbus_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_xbus);
+
+struct abus p9_abus = {
+ .target = {
+ .name = "POWER9 abus",
+ .compatible = "ibm,power9-abus",
+ .class = "abus",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_abus);
+
+struct l4 p9_l4 = {
+ .target = {
+ .name = "POWER9 l4",
+ .compatible = "ibm,power9-l4",
+ .class = "l4",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_l4);
+
+/* EQ targets just get translated based on the chiplet they fall
+ * under */
+struct eq p9_eq = {
+ .target = {
+ .name = "POWER9 eq",
+ .compatible = "ibm,power9-eq",
+ .class = "eq",
+ },
+};
+DECLARE_HW_UNIT(p9_eq);
+
+static uint64_t p9_mca_translate(struct mca *mca, uint64_t addr)
+{
+ int chiplet_unitnum = pdbg_target_index(t(mca));
+
+ if (get_chiplet_id(addr) == MC01_CHIPLET_ID ||
+ get_chiplet_id(addr) == MC23_CHIPLET_ID) {
+ addr = set_chiplet_id(addr, MC01_CHIPLET_ID + chiplet_unitnum / 4);
+ if ((get_ring(addr) & 0xf) == MC_MC01_0_RING_ID)
+ /* mc */
+ return set_sat_id(addr, get_sat_id(addr) - get_sat_id(addr) % 4 +
+ chiplet_unitnum % 4);
+ else
+ /* iomc */
+ return set_ring(addr, (MC_IOM01_0_RING_ID + chiplet_unitnum % 4) & 0xf);
+ } else {
+ //mcs->mca regisers
+ uint8_t mcs_unitnum = chiplet_unitnum / 2;
+ uint8_t mcs_sat_offset = get_sat_offset(addr) & 0x2f;
+
+ addr = set_chiplet_id(addr, N3_CHIPLET_ID - 2 * (mcs_unitnum / 2));
+ addr = set_sat_id(addr, 2 * (mcs_unitnum % 2));
+
+ mcs_sat_offset |= (chiplet_unitnum % 2) << 4;
+ addr = set_sat_offset(addr, mcs_sat_offset);
+
+ return addr;
+ }
+}
+
+struct mca p9_mca = {
+ .target = {
+ .name = "POWER9 mca",
+ .compatible = "ibm,power9-mca",
+ .class = "mca",
+ .translate = translate_cast(p9_mca_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_mca);
+
+struct mcbist p9_mcbist = {
+ .target = {
+ .name = "POWER9 mcbist",
+ .compatible = "ibm,power9-mcbist",
+ .class = "mcbist",
+ },
+};
+DECLARE_HW_UNIT(p9_mcbist);
+
+/* TODO: This could be modelled directly under the N1/N3 chiplet */
+static uint64_t p9_mi_translate(struct mi *mi, uint64_t addr)
+{
+ int chip_unitnum = pdbg_target_index(t(mi));
+
+ addr = set_chiplet_id(addr, N3_CHIPLET_ID - 2 * (chip_unitnum / 2));
+ return set_sat_id(addr, 2 * (chip_unitnum % 2));
+}
+
+struct mi p9_mi = {
+ .target = {
+ .name = "POWER9 mi",
+ .compatible = "ibm,power9-mi",
+ .class = "mi",
+ .translate = translate_cast(p9_mi_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_mi);
+
+static uint64_t p9_dmi_translate(struct dmi *dmi, uint64_t addr)
+{
+ uint8_t ring = get_ring(addr);
+ uint8_t chiplet_id = get_chiplet_id(addr);
+ uint8_t sat_offset = get_sat_offset(addr);
+ int chip_unitnum = pdbg_target_index(t(dmi));
+
+ if (chiplet_id == N3_CHIPLET_ID || 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)
+ addr = set_chiplet_id(addr, N3_CHIPLET_ID - 2 * (chip_unitnum / 4));
+ addr = set_sat_id(addr, 2 * ((chip_unitnum / 2) % 2));
+ sat_offset = (sat_offset & 0xf) + ((2 + (chip_unitnum % 2)) << 4);
+
+ return set_sat_offset(addr, sat_offset);
+ } else if (chiplet_id == MC01_CHIPLET_ID || chiplet_id == MC23_CHIPLET_ID) {
+ if (ring == P9C_MC_CHAN_RING_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
+ */
+ uint8_t msat = get_sat_id(addr) & 0xc;
+
+ addr = set_chiplet_id(addr, MC01_CHIPLET_ID + chip_unitnum / 4);
+ return set_sat_id(addr, msat + chip_unitnum % 4);
+ } else if (ring == P9C_MC_BIST_RING_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
+ */
+ addr = set_chiplet_id(addr, MC01_CHIPLET_ID + chip_unitnum / 4);
+ sat_offset = (sat_offset & 0xf) + ((chip_unitnum % 4) << 4);
+ return set_sat_offset(addr, sat_offset);
+ } else if (ring == P9C_MC_IO_RING_ID) {
+ /*
+ * -------------------------------------------
+ * 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
+ */
+ uint8_t rxtx_grp = get_rxtx_group_id(addr);
+
+ addr = set_chiplet_id(addr, MC01_CHIPLET_ID + (chip_unitnum / 4));
+ rxtx_grp = rxtx_grp & 0xF0;
+
+ switch (chip_unitnum % 4)
+ {
+ case 0:
+ rxtx_grp += 3;
+ break;
+
+ case 1:
+ rxtx_grp += 2;
+ break;
+
+ case 2:
+ rxtx_grp += 0;
+ break;
+
+ case 3:
+ rxtx_grp += 1;
+ break;
+ }
+
+ return set_rxtx_group_id(addr, rxtx_grp); // 3,2,0,1
+ }
+ }
+
+ pdbg_log(PDBG_WARNING, "Invalid dmi address 0x%016" PRIx64 "\n", addr);
+ return addr;
+}
+
+struct dmi p9_dmi = {
+ .target = {
+ .name = "POWER9 dmi",
+ .compatible = "ibm,power9-dmi",
+ .class = "dmi",
+ .translate = translate_cast(p9_dmi_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_dmi);
+
+struct obus p9_obus = {
+ .target = {
+ .name = "POWER9 obus",
+ .compatible = "ibm,power9-obus",
+ .class = "obus",
+ },
+};
+DECLARE_HW_UNIT(p9_obus);
+
+struct obus_brick p9_obus_brick = {
+ .target = {
+ .name = "POWER9 obus_brick",
+ .compatible = "ibm,power9-obus_brick",
+ .class = "obus_brick",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_obus_brick);
+
+struct sbe p9_sbe = {
+ .target = {
+ .name = "POWER9 sbe",
+ .compatible = "ibm,power9-sbe",
+ .class = "sbe",
+ },
+};
+DECLARE_HW_UNIT(p9_sbe);
+
+static uint64_t p9_ppe_translate(struct ppe *ppe, uint64_t addr)
+{
+ int chip_unitnum = pdbg_target_index(t(ppe));
+
+ /* PPE SBE */
+ if (chip_unitnum == PPE_SBE_CHIPUNIT_NUM) {
+ addr = set_chiplet_id(addr, PIB_CHIPLET_ID);
+ addr = set_port(addr, SBE_PORT_ID);
+ addr = set_ring(addr, PPE_SBE_RING_ID);
+ addr = set_sat_id(addr, PPE_SBE_SAT_ID);
+ addr = set_sat_offset(addr, get_sat_offset(addr) & 0xf);
+ return addr;
+ } else {
+ /* Need to set SAT offset if address is that of PPE SBE */
+ if (get_port(addr) == SBE_PORT_ID) {
+ /* Adjust offset if input address is of SBE
+ * (ex: 000E0005 --> GPE: xxxxxx1x) */
+ addr = set_sat_offset(addr, get_sat_offset(addr) | 0x10);
+ }
+
+ if (chip_unitnum >= PPE_GPE0_CHIPUNIT_NUM &&
+ chip_unitnum <= PPE_GPE3_CHIPUNIT_NUM)
+ {
+ /* PPE GPE */
+ addr = set_chiplet_id(addr, PIB_CHIPLET_ID);
+ addr = set_port(addr, GPE_PORT_ID);
+ addr = set_ring(addr, (chip_unitnum - PPE_GPE0_CHIPUNIT_NUM) * 8);
+ addr = set_sat_id(addr, PPE_GPE_SAT_ID);
+ } else if (chip_unitnum >= PPE_EQ0_CME0_CHIPUNIT_NUM &&
+ chip_unitnum <= PPE_EQ5_CME1_CHIPUNIT_NUM) {
+ /* PPE CME */
+ if (chip_unitnum >= PPE_EQ0_CME1_CHIPUNIT_NUM)
+ addr = set_chiplet_id(addr, EP00_CHIPLET_ID +
+ chip_unitnum % PPE_EQ0_CME1_CHIPUNIT_NUM);
+ else
+ addr = set_chiplet_id(addr, EP00_CHIPLET_ID +
+ chip_unitnum % PPE_EQ0_CME0_CHIPUNIT_NUM);
+
+ addr = set_port(addr, UNIT_PORT_ID);
+ addr = set_ring(addr, ((chip_unitnum / PPE_EQ0_CME1_CHIPUNIT_NUM) + 8) & 0xF);
+ addr = set_sat_id(addr, PPE_CME_SAT_ID);
+ } else if (chip_unitnum >= PPE_IO_XBUS_CHIPUNIT_NUM &&
+ chip_unitnum <= PPE_IO_OB3_CHIPUNIT_NUM) {
+ /* PPE IO (XBUS/OBUS) */
+ addr = set_chiplet_id(addr, XB_CHIPLET_ID +
+ chip_unitnum % PPE_IO_XBUS_CHIPUNIT_NUM +
+ (chip_unitnum / PPE_IO_OB0_CHIPUNIT_NUM) * 2);
+ addr = set_port(addr, UNIT_PORT_ID);
+
+ if (chip_unitnum == PPE_IO_XBUS_CHIPUNIT_NUM)
+ addr = set_ring(addr, XB_IOPPE_0_RING_ID & 0xF);
+ else
+ addr = set_ring(addr, OB_PPE_RING_ID & 0xF);
+
+ addr = set_sat_id(addr,OB_PPE_SAT_ID); // Same SAT_ID value for XBUS
+ } else if (chip_unitnum >= PPE_IO_DMI0_CHIPUNIT_NUM &&
+ chip_unitnum <= PPE_IO_DMI1_CHIPUNIT_NUM) {
+ /* PPE IO (DMI) */
+ addr = set_chiplet_id(addr, MC01_CHIPLET_ID + (chip_unitnum - PPE_IO_DMI0_CHIPUNIT_NUM));
+ addr = set_ring(addr, MC_IOM01_1_RING_ID);
+ addr = set_port(addr, UNIT_PORT_ID);
+ addr = set_sat_id(addr, P9C_MC_PPE_SAT_ID);
+ } else if (chip_unitnum >= PPE_PB0_CHIPUNIT_NUM &&
+ chip_unitnum <= PPE_PB2_CHIPUNIT_NUM) {
+ /* PPE PB */
+ addr = set_chiplet_id(addr, N3_CHIPLET_ID); // TODO: Need to set ChipID for PB1 and PB2 in Cummulus
+ addr = set_port(addr, UNIT_PORT_ID);
+ addr = set_ring(addr, N3_PB_3_RING_ID & 0xF);
+ addr = set_sat_id(addr, PPE_PB_SAT_ID);
+ } else {
+ pdbg_log(PDBG_WARNING, "Invalid ppe address 0x%016" PRIx64 "\n", addr);
+ return 0xfffffffffffffff1ull;
+ }
+
+ return addr;
+ }
+}
+
+struct ppe p9_ppe = {
+ .target = {
+ .name = "POWER9 ppe",
+ .compatible = "ibm,power9-ppe",
+ .class = "ppe",
+ .translate = translate_cast(p9_ppe_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_ppe);
+
+static uint64_t p9_pec_translate(struct pec *pec, uint64_t addr)
+{
+ if (get_chiplet_id(addr) == N2_CHIPLET_ID)
+ return set_ring(addr, (N2_PCIS0_0_RING_ID + pdbg_target_index(t(pec))) & 0xF);
+ else
+ return set_chiplet_id(addr, PCI0_CHIPLET_ID + pdbg_target_index(t(pec)));
+}
+
+struct pec p9_pec = {
+ .target = {
+ .name = "POWER9 pec",
+ .compatible = "ibm,power9-pec",
+ .class = "pec",
+ .translate = translate_cast(p9_pec_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_pec);
+
+static uint64_t p9_phb_translate(struct phb *phb, uint64_t addr)
+{
+ int chip_unitnum = pdbg_target_index(t(phb));
+
+ if (get_chiplet_id(addr) == N2_CHIPLET_ID) {
+ // nest
+ if (chip_unitnum == 0)
+ {
+ addr = set_ring(addr, N2_PCIS0_0_RING_ID & 0xF);
+ addr = set_sat_id(addr, get_sat_id(addr) < 4 ? 1 : 4);
+
+ return addr;
+ } else {
+ addr = set_ring(addr, (N2_PCIS0_0_RING_ID + (chip_unitnum / 3) + 1) & 0xF);
+ addr = set_sat_id(addr, (get_sat_id(addr) < 4 ? 1 : 4) +
+ (chip_unitnum % 2 ? 0 : 1) +
+ (2 * (chip_unitnum / 5)));
+
+ return addr;
+ }
+ } else {
+ // pci
+ if (chip_unitnum == 0) {
+ addr = set_chiplet_id(addr, PCI0_CHIPLET_ID);
+ addr = set_sat_id(addr, (get_sat_id(addr) < 4 ? 1 : 4));
+
+ return addr;
+ } else {
+ addr = set_chiplet_id(addr, PCI0_CHIPLET_ID + (chip_unitnum / 3) + 1);
+ addr = set_sat_id(addr, (get_sat_id(addr) < 4 ? 1 : 4) +
+ (chip_unitnum % 2 ? 0 : 1) +
+ (2 * (chip_unitnum / 5)));
+
+ return addr;
+ }
+ }
+}
+
+struct phb p9_phb = {
+ .target = {
+ .name = "POWER9 phb",
+ .compatible = "ibm,power9-phb",
+ .class = "phb",
+ .translate = translate_cast(p9_phb_translate),
+ },
+};
+DECLARE_HW_UNIT(p9_phb);
+
+struct mc p9_mc = {
+ .target = {
+ .name = "POWER9 mc",
+ .compatible = "ibm,power9-mc",
+ .class = "mc",
+ },
+};
+DECLARE_HW_UNIT(p9_mc);
+
+struct mem_port p9_mem_port = {
+ .target = {
+ .name = "POWER9 mem_port",
+ .compatible = "ibm,power9-mem_port",
+ .class = "mem_port",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_mem_port);
+
+struct nmmu p9_nmmu = {
+ .target = {
+ .name = "POWER9 nmmu",
+ .compatible = "ibm,power9-nmmu",
+ .class = "nmmu",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_nmmu);
+
+struct pau p9_pau = {
+ .target = {
+ .name = "POWER9 pau",
+ .compatible = "ibm,power9-pau",
+ .class = "pau",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_pau);
+
+struct iohs p9_iohs = {
+ .target = {
+ .name = "POWER9 iohs",
+ .compatible = "ibm,power9-iohs",
+ .class = "iohs",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_iohs);
+
+struct fc p9_fc = {
+ .target = {
+ .name = "POWER9 fc",
+ .compatible = "ibm,power9-fc",
+ .class = "fc",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_fc);
+
+struct pauc p9_pauc = {
+ .target = {
+ .name = "POWER9 pauc",
+ .compatible = "ibm,power9-pauc",
+ .class = "pauc",
+ .translate = p9_unknown_translation,
+ },
+};
+DECLARE_HW_UNIT(p9_pauc);
+
+__attribute__((constructor))
+static void register_p9_fapi_targets(void)
+{
+ pdbg_hwunit_register(&p9_ex_hw_unit);
+ pdbg_hwunit_register(&p9_mba_hw_unit);
+ pdbg_hwunit_register(&p9_mcs_hw_unit);
+ pdbg_hwunit_register(&p9_xbus_hw_unit);
+ pdbg_hwunit_register(&p9_abus_hw_unit);
+ pdbg_hwunit_register(&p9_l4_hw_unit);
+ pdbg_hwunit_register(&p9_eq_hw_unit);
+ pdbg_hwunit_register(&p9_mca_hw_unit);
+ pdbg_hwunit_register(&p9_mcbist_hw_unit);
+ pdbg_hwunit_register(&p9_mi_hw_unit);
+ pdbg_hwunit_register(&p9_dmi_hw_unit);
+ pdbg_hwunit_register(&p9_obus_hw_unit);
+ pdbg_hwunit_register(&p9_obus_brick_hw_unit);
+ pdbg_hwunit_register(&p9_sbe_hw_unit);
+ pdbg_hwunit_register(&p9_ppe_hw_unit);
+ pdbg_hwunit_register(&p9_pec_hw_unit);
+ pdbg_hwunit_register(&p9_phb_hw_unit);
+ pdbg_hwunit_register(&p9_mc_hw_unit);
+ pdbg_hwunit_register(&p9_mem_port_hw_unit);
+ pdbg_hwunit_register(&p9_nmmu_hw_unit);
+ pdbg_hwunit_register(&p9_pau_hw_unit);
+ pdbg_hwunit_register(&p9_iohs_hw_unit);
+ pdbg_hwunit_register(&p9_fc_hw_unit);
+ pdbg_hwunit_register(&p9_pauc_hw_unit);
+}
--
2.21.0
More information about the Pdbg
mailing list