Merge tag 'pull-ppc-20230303' of https://gitlab.com/danielhb/qemu into staging
ppc patch queue for 2023-03-03:
This queue includes a stub implementation for the dcblc instruction to
avoid an illegal instrunction exception when using u-boot with mpc85xx.
It also includes a PHB fix with user-created pnv-phb devices and
Skiboot.
# -----BEGIN PGP SIGNATURE-----
#
# iIwEABYKADQWIQQX6/+ZI9AYAK8oOBk82cqW3gMxZAUCZAJllhYcZGFuaWVsaGI0
# MTNAZ21haWwuY29tAAoJEDzZypbeAzFk02YA/2YnJl0aRw6hgiayI2rLbcwQcVfp
# oGAhh4QmqFL2UJw2AQDra0kh9sxBSEcqhltNnOa08tBnHPts3W/A8nmFtCd4Cw==
# =VRNM
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 03 Mar 2023 21:24:38 GMT
# gpg: using EDDSA key 17EBFF9923D01800AF2838193CD9CA96DE033164
# gpg: issuer "danielhb413@gmail.com"
# gpg: Good signature from "Daniel Henrique Barboza <danielhb413@gmail.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 17EB FF99 23D0 1800 AF28 3819 3CD9 CA96 DE03 3164
* tag 'pull-ppc-20230303' of https://gitlab.com/danielhb/qemu:
pnv_phb4_pec: Simplify/align code to parent user-created PHBs
pnv_phb4_pec: Move pnv_phb4_get_pec() to rightful file
pnv_phb4_pec: Only export existing PHBs to the device tree
pnv_phb4_pec: Keep track of instantiated PHBs
target/ppc/translate: Add dummy implementation for dcblc instruction
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c
index c62b085..82332d7 100644
--- a/hw/pci-host/pnv_phb.c
+++ b/hw/pci-host/pnv_phb.c
@@ -62,6 +62,15 @@
return true;
}
+static Object *pnv_phb_user_get_parent(PnvChip *chip, PnvPHB *phb, Error **errp)
+{
+ if (phb->version == 3) {
+ return OBJECT(pnv_chip_add_phb(chip, phb));
+ } else {
+ return OBJECT(pnv_pec_add_phb(chip, phb, errp));
+ }
+}
+
/*
* User created devices won't have the initial setup that default
* devices have. This setup consists of assigning a parent device
@@ -79,7 +88,7 @@
return false;
}
- parent = pnv_chip_add_phb(chip, phb, errp);
+ parent = pnv_phb_user_get_parent(chip, phb, errp);
if (!parent) {
return false;
}
diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index 43267a4..3b2850f 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -112,9 +112,50 @@
.endianness = DEVICE_BIG_ENDIAN,
};
-static void pnv_pec_default_phb_realize(PnvPhb4PecState *pec,
- int stack_no,
- Error **errp)
+PnvPhb4PecState *pnv_pec_add_phb(PnvChip *chip, PnvPHB *phb, Error **errp)
+{
+ PnvPhb4PecState *pecs = NULL;
+ int chip_id = phb->chip_id;
+ int index = phb->phb_id;
+ int i, j;
+
+ if (phb->version == 4) {
+ Pnv9Chip *chip9 = PNV9_CHIP(chip);
+
+ pecs = chip9->pecs;
+ } else if (phb->version == 5) {
+ Pnv10Chip *chip10 = PNV10_CHIP(chip);
+
+ pecs = chip10->pecs;
+ } else {
+ g_assert_not_reached();
+ }
+
+ for (i = 0; i < chip->num_pecs; i++) {
+ /*
+ * For each PEC, check the amount of phbs it supports
+ * and see if the given phb4 index matches an index.
+ */
+ PnvPhb4PecState *pec = &pecs[i];
+
+ for (j = 0; j < pec->num_phbs; j++) {
+ if (index == pnv_phb4_pec_get_phb_id(pec, j)) {
+ pec->phbs[j] = phb;
+ phb->pec = pec;
+ return pec;
+ }
+ }
+ }
+ error_setg(errp,
+ "pnv-phb4 chip-id %d index %d didn't match any existing PEC",
+ chip_id, index);
+
+ return NULL;
+}
+
+static PnvPHB *pnv_pec_default_phb_realize(PnvPhb4PecState *pec,
+ int stack_no,
+ Error **errp)
{
PnvPHB *phb = PNV_PHB(qdev_new(TYPE_PNV_PHB));
int phb_id = pnv_phb4_pec_get_phb_id(pec, stack_no);
@@ -128,8 +169,9 @@
&error_fatal);
if (!sysbus_realize(SYS_BUS_DEVICE(phb), errp)) {
- return;
+ return NULL;
}
+ return phb;
}
static void pnv_pec_realize(DeviceState *dev, Error **errp)
@@ -148,8 +190,9 @@
/* Create PHBs if running with defaults */
if (defaults_enabled()) {
+ g_assert(pec->num_phbs <= MAX_PHBS_PER_PEC);
for (i = 0; i < pec->num_phbs; i++) {
- pnv_pec_default_phb_realize(pec, i, errp);
+ pec->phbs[i] = pnv_pec_default_phb_realize(pec, i, errp);
}
}
@@ -197,9 +240,12 @@
pecc->compat_size)));
for (i = 0; i < pec->num_phbs; i++) {
- int phb_id = pnv_phb4_pec_get_phb_id(pec, i);
int stk_offset;
+ if (!pec->phbs[i]) {
+ continue;
+ }
+
name = g_strdup_printf("stack@%x", i);
stk_offset = fdt_add_subnode(fdt, offset, name);
_FDT(stk_offset);
@@ -207,7 +253,8 @@
_FDT((fdt_setprop(fdt, stk_offset, "compatible", pecc->stk_compat,
pecc->stk_compat_size)));
_FDT((fdt_setprop_cell(fdt, stk_offset, "reg", i)));
- _FDT((fdt_setprop_cell(fdt, stk_offset, "ibm,phb-index", phb_id)));
+ _FDT((fdt_setprop_cell(fdt, stk_offset, "ibm,phb-index",
+ pec->phbs[i]->phb_id)));
}
return 0;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 44b1fbb..11cb48a 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -284,73 +284,19 @@
g_free(reg);
}
-static PnvPhb4PecState *pnv_phb4_get_pec(PnvChip *chip, PnvPHB4 *phb,
- Error **errp)
-{
- PnvPHB *phb_base = phb->phb_base;
- PnvPhb4PecState *pecs = NULL;
- int chip_id = phb->chip_id;
- int index = phb->phb_id;
- int i, j;
-
- if (phb_base->version == 4) {
- Pnv9Chip *chip9 = PNV9_CHIP(chip);
-
- pecs = chip9->pecs;
- } else if (phb_base->version == 5) {
- Pnv10Chip *chip10 = PNV10_CHIP(chip);
-
- pecs = chip10->pecs;
- } else {
- g_assert_not_reached();
- }
-
- for (i = 0; i < chip->num_pecs; i++) {
- /*
- * For each PEC, check the amount of phbs it supports
- * and see if the given phb4 index matches an index.
- */
- PnvPhb4PecState *pec = &pecs[i];
-
- for (j = 0; j < pec->num_phbs; j++) {
- if (index == pnv_phb4_pec_get_phb_id(pec, j)) {
- return pec;
- }
- }
- }
- error_setg(errp,
- "pnv-phb4 chip-id %d index %d didn't match any existing PEC",
- chip_id, index);
-
- return NULL;
-}
-
/*
- * Adds a PnvPHB to the chip. Returns the parent obj of the
- * PHB which varies with each version (phb version 3 is parented
- * by the chip, version 4 and 5 are parented by the PEC
- * device).
- *
- * TODO: for version 3 we're still parenting the PHB with the
- * chip. We should parent with a (so far not implemented)
- * PHB3 PEC device.
+ * Adds a PnvPHB to the chip on P8.
+ * Implemented here, like for defaults PHBs
*/
-Object *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb, Error **errp)
+PnvChip *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb)
{
- if (phb->version == 3) {
- Pnv8Chip *chip8 = PNV8_CHIP(chip);
+ Pnv8Chip *chip8 = PNV8_CHIP(chip);
- phb->chip = chip;
+ phb->chip = chip;
- chip8->phbs[chip8->num_phbs] = phb;
- chip8->num_phbs++;
-
- return OBJECT(chip);
- }
-
- phb->pec = pnv_phb4_get_pec(chip, PNV_PHB4(phb->backend), errp);
-
- return OBJECT(phb->pec);
+ chip8->phbs[chip8->num_phbs] = phb;
+ chip8->num_phbs++;
+ return chip;
}
static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
index 28d61b9..2d026db 100644
--- a/include/hw/pci-host/pnv_phb4.h
+++ b/include/hw/pci-host/pnv_phb4.h
@@ -157,6 +157,7 @@
void pnv_phb4_pic_print_info(PnvPHB4 *phb, Monitor *mon);
int pnv_phb4_pec_get_phb_id(PnvPhb4PecState *pec, int stack_index);
+PnvPhb4PecState *pnv_pec_add_phb(PnvChip *chip, PnvPHB *phb, Error **errp);
void pnv_phb4_bus_init(DeviceState *dev, PnvPHB4 *phb);
extern const MemoryRegionOps pnv_phb4_xscom_ops;
@@ -185,6 +186,8 @@
/* PHBs */
uint32_t num_phbs;
+#define MAX_PHBS_PER_PEC 3
+ PnvPHB *phbs[MAX_PHBS_PER_PEC];
PnvChip *chip;
};
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 96fb850..409f3bf 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -100,7 +100,7 @@
};
PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id);
-Object *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb, Error **errp);
+PnvChip *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb);
#define PNV_FDT_ADDR 0x01000000
#define PNV_TIMEBASE_FREQ 512000000ULL
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 2956021..37b67d5 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -5253,6 +5253,14 @@
tcg_temp_free(t0);
}
+/* dcblc */
+static void gen_dcblc(DisasContext *ctx)
+{
+ /*
+ * interpreted as no-op
+ */
+}
+
/* dcbz */
static void gen_dcbz(DisasContext *ctx)
{
@@ -6824,6 +6832,7 @@
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
GEN_HANDLER_E(dcbtstep, 0x1F, 0x1F, 0x07, 0x00000001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
+GEN_HANDLER_E(dcblc, 0x1F, 0x06, 0x0c, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),