[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v4 26/28] pnv: add a physical mapping array describing
From: |
Cédric Le Goater |
Subject: |
[Qemu-ppc] [PATCH v4 26/28] pnv: add a physical mapping array describing MMIO ranges in each chip |
Date: |
Thu, 7 Jun 2018 17:50:01 +0200 |
Based on previous work done in skiboot, the physical mapping array
helps in calculating the MMIO ranges of each controller depending on
the chip id and the chip type. This is will be particularly useful for
the P9 models which use less the XSCOM bus and rely more on MMIOs.
A link on the chip is now necessary to calculate MMIO BARs and
sizes. This is why such a link is introduced in the PSIHB model.
Signed-off-by: Cédric Le Goater <address@hidden>
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
Signed-off-by: Cédric Le Goater <address@hidden>
---
include/hw/ppc/pnv.h | 51 ++++++++++++++++++++++++++++++++++----------------
hw/ppc/pnv.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--------
hw/ppc/pnv_psi.c | 15 ++++++++++++---
hw/ppc/pnv_xscom.c | 8 ++++----
4 files changed, 96 insertions(+), 31 deletions(-)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 90759240a7b1..ffa4a0899705 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -53,7 +53,6 @@ typedef struct PnvChip {
uint64_t cores_mask;
void *cores;
- hwaddr xscom_base;
MemoryRegion xscom_mmio;
MemoryRegion xscom;
AddressSpace xscom_as;
@@ -64,6 +63,18 @@ typedef struct PnvChip {
PnvOCC occ;
} PnvChip;
+typedef enum PnvPhysMapType {
+ PNV_MAP_XSCOM,
+ PNV_MAP_ICP,
+ PNV_MAP_PSIHB,
+ PNV_MAP_PSIHB_FSP,
+} PnvPhysMapType;
+
+typedef struct PnvPhysMapEntry {
+ uint64_t base;
+ uint64_t size;
+} PnvPhysMapEntry;
+
typedef struct PnvChipClass {
/*< private >*/
SysBusDeviceClass parent_class;
@@ -73,9 +84,10 @@ typedef struct PnvChipClass {
uint64_t chip_cfam_id;
uint64_t cores_mask;
- hwaddr xscom_base;
+ const PnvPhysMapEntry *phys_map;
uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
+ uint64_t (*map_base)(const PnvChip *chip, PnvPhysMapType type);
} PnvChipClass;
#define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
@@ -159,9 +171,21 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
/*
* POWER8 MMIO base addresses
*/
-#define PNV_XSCOM_SIZE 0x800000000ull
-#define PNV_XSCOM_BASE(chip) \
- (chip->xscom_base + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
+static inline uint64_t pnv_map_size(const PnvChip *chip, PnvPhysMapType type)
+{
+ PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+ const PnvPhysMapEntry *map = &pcc->phys_map[type];
+
+ return map->size;
+}
+
+static inline uint64_t pnv_map_base(const PnvChip *chip, PnvPhysMapType type)
+{
+ return PNV_CHIP_GET_CLASS(chip)->map_base(chip, type);
+}
+
+#define PNV_XSCOM_SIZE(chip) pnv_map_size(chip, PNV_MAP_XSCOM)
+#define PNV_XSCOM_BASE(chip) pnv_map_base(chip, PNV_MAP_XSCOM)
/*
* XSCOM 0x20109CA defines the ICP BAR:
@@ -177,18 +201,13 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
* 0xffffe02200000000 -> 0x0003ffff80800000
* 0xffffe02600000000 -> 0x0003ffff80900000
*/
-#define PNV_ICP_SIZE 0x0000000000100000ull
-#define PNV_ICP_BASE(chip) \
- (0x0003ffff80000000ull + (uint64_t) PNV_CHIP_INDEX(chip) * PNV_ICP_SIZE)
-
+#define PNV_ICP_SIZE(chip) pnv_map_size(chip, PNV_MAP_ICP)
+#define PNV_ICP_BASE(chip) pnv_map_base(chip, PNV_MAP_ICP)
-#define PNV_PSIHB_SIZE 0x0000000000100000ull
-#define PNV_PSIHB_BASE(chip) \
- (0x0003fffe80000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * PNV_PSIHB_SIZE)
+#define PNV_PSIHB_SIZE(chip) pnv_map_size(chip, PNV_MAP_PSIHB)
+#define PNV_PSIHB_BASE(chip) pnv_map_base(chip, PNV_MAP_PSIHB)
-#define PNV_PSIHB_FSP_SIZE 0x0000000100000000ull
-#define PNV_PSIHB_FSP_BASE(chip) \
- (0x0003ffe000000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * \
- PNV_PSIHB_FSP_SIZE)
+#define PNV_PSIHB_FSP_SIZE(chip) pnv_map_size(chip, PNV_MAP_PSIHB_FSP)
+#define PNV_PSIHB_FSP_BASE(chip) pnv_map_base(chip, PNV_MAP_PSIHB_FSP)
#endif /* _PPC_PNV_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 031488131629..77caaea64b2f 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -712,6 +712,24 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip,
uint32_t core_id)
*/
#define POWER9_CORE_MASK (0xffffffffffffffull)
+/*
+ * POWER8 MMIOs
+ */
+static const PnvPhysMapEntry pnv_chip_power8_phys_map[] = {
+ [PNV_MAP_XSCOM] = { 0x0003fc0000000000ull, 0x0000000800000000ull },
+ [PNV_MAP_ICP] = { 0x0003ffff80000000ull, 0x0000000000100000ull },
+ [PNV_MAP_PSIHB] = { 0x0003fffe80000000ull, 0x0000000000100000ull },
+ [PNV_MAP_PSIHB_FSP] = { 0x0003ffe000000000ull, 0x0000000100000000ull },
+};
+
+static uint64_t pnv_chip_map_base_p8(const PnvChip *chip, PnvPhysMapType type)
+{
+ PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+ const PnvPhysMapEntry *map = &pcc->phys_map[type];
+
+ return map->base + chip->chip_id * map->size;
+}
+
static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -721,7 +739,8 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass,
void *data)
k->chip_cfam_id = 0x221ef04980000000ull; /* P8 Murano DD2.1 */
k->cores_mask = POWER8E_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p8;
- k->xscom_base = 0x003fc0000000000ull;
+ k->map_base = pnv_chip_map_base_p8;
+ k->phys_map = pnv_chip_power8_phys_map;
dc->desc = "PowerNV Chip POWER8E";
}
@@ -734,7 +753,8 @@ static void pnv_chip_power8_class_init(ObjectClass *klass,
void *data)
k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
k->cores_mask = POWER8_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p8;
- k->xscom_base = 0x003fc0000000000ull;
+ k->map_base = pnv_chip_map_base_p8;
+ k->phys_map = pnv_chip_power8_phys_map;
dc->desc = "PowerNV Chip POWER8";
}
@@ -747,10 +767,27 @@ static void pnv_chip_power8nvl_class_init(ObjectClass
*klass, void *data)
k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */
k->cores_mask = POWER8_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p8;
- k->xscom_base = 0x003fc0000000000ull;
+ k->map_base = pnv_chip_map_base_p8;
+ k->phys_map = pnv_chip_power8_phys_map;
dc->desc = "PowerNV Chip POWER8NVL";
}
+/*
+ * POWER9 MMIOs
+ */
+static const PnvPhysMapEntry pnv_chip_power9_phys_map[] = {
+ [PNV_MAP_XSCOM] = { 0x000603fc00000000ull, 0x0000000400000000ull },
+};
+
+/* Each chip has a 4TB range for its MMIOs */
+static uint64_t pnv_chip_map_base_p9(const PnvChip *chip, PnvPhysMapType type)
+{
+ PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+ const PnvPhysMapEntry *map = &pcc->phys_map[type];
+
+ return map->base + ((uint64_t) chip->chip_id << 42);
+}
+
static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -760,7 +797,8 @@ static void pnv_chip_power9_class_init(ObjectClass *klass,
void *data)
k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
k->cores_mask = POWER9_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p9;
- k->xscom_base = 0x00603fc00000000ull;
+ k->map_base = pnv_chip_map_base_p9;
+ k->phys_map = pnv_chip_power9_phys_map;
dc->desc = "PowerNV Chip POWER9";
}
@@ -797,15 +835,14 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error
**errp)
static void pnv_chip_init(Object *obj)
{
PnvChip *chip = PNV_CHIP(obj);
- PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
-
- chip->xscom_base = pcc->xscom_base;
object_initialize(&chip->lpc, sizeof(chip->lpc), TYPE_PNV_LPC);
object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL);
object_initialize(&chip->psi, sizeof(chip->psi), TYPE_PNV_PSI);
object_property_add_child(obj, "psi", OBJECT(&chip->psi), NULL);
+ object_property_add_const_link(OBJECT(&chip->psi), "chip", obj,
+ &error_abort);
object_property_add_const_link(OBJECT(&chip->psi), "xics",
OBJECT(qdev_get_machine()), &error_abort);
@@ -829,7 +866,7 @@ static void pnv_chip_icp_realize(PnvChip *chip, Error
**errp)
XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
name = g_strdup_printf("icp-%x", chip->chip_id);
- memory_region_init(&chip->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
+ memory_region_init(&chip->icp_mmio, OBJECT(chip), name,
PNV_ICP_SIZE(chip));
sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip->icp_mmio);
g_free(name);
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 5b969127c303..882b5d4b9f99 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -465,11 +465,20 @@ static void pnv_psi_realize(DeviceState *dev, Error
**errp)
Object *obj;
Error *err = NULL;
unsigned int i;
+ PnvChip *chip;
+
+ obj = object_property_get_link(OBJECT(dev), "chip", &err);
+ if (!obj) {
+ error_propagate(errp, err);
+ error_prepend(errp, "required link 'chip' not found: ");
+ return;
+ }
+ chip = PNV_CHIP(obj);
obj = object_property_get_link(OBJECT(dev), "xics", &err);
if (!obj) {
- error_setg(errp, "%s: required link 'xics' not found: %s",
- __func__, error_get_pretty(err));
+ error_propagate(errp, err);
+ error_prepend(errp, "required link 'xics' not found: ");
return;
}
@@ -497,7 +506,7 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
/* Initialize MMIO region */
memory_region_init_io(&psi->regs_mr, OBJECT(dev), &psi_mmio_ops, psi,
- "psihb", PNV_PSIHB_SIZE);
+ "psihb", PNV_PSIHB_SIZE(chip));
/* Default BAR for MMIO region */
pnv_psi_set_bar(psi, psi->bar | PSIHB_BAR_EN);
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 46fae41f32b0..20ffc233174c 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -50,7 +50,7 @@ static void xscom_complete(CPUState *cs, uint64_t hmer_bits)
static uint32_t pnv_xscom_pcba(PnvChip *chip, uint64_t addr)
{
- addr &= (PNV_XSCOM_SIZE - 1);
+ addr &= (PNV_XSCOM_SIZE(chip) - 1);
if (pnv_chip_is_power9(chip)) {
return addr >> 3;
@@ -179,10 +179,10 @@ void pnv_xscom_realize(PnvChip *chip, Error **errp)
name = g_strdup_printf("xscom-%x", chip->chip_id);
memory_region_init_io(&chip->xscom_mmio, OBJECT(chip), &pnv_xscom_ops,
- chip, name, PNV_XSCOM_SIZE);
+ chip, name, PNV_XSCOM_SIZE(chip));
sysbus_init_mmio(sbd, &chip->xscom_mmio);
- memory_region_init(&chip->xscom, OBJECT(chip), name, PNV_XSCOM_SIZE);
+ memory_region_init(&chip->xscom, OBJECT(chip), name, PNV_XSCOM_SIZE(chip));
address_space_init(&chip->xscom_as, &chip->xscom, name);
g_free(name);
}
@@ -225,7 +225,7 @@ static const char compat_p9[] =
"ibm,power9-xscom\0ibm,xscom";
int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
{
uint64_t reg[] = { cpu_to_be64(PNV_XSCOM_BASE(chip)),
- cpu_to_be64(PNV_XSCOM_SIZE) };
+ cpu_to_be64(PNV_XSCOM_SIZE(chip)) };
int xscom_offset;
ForeachPopulateArgs args;
char *name;
--
2.13.6
- [Qemu-ppc] [PATCH v4 16/28] spapr: introdude a new machine IRQ backend for XIVE, (continued)
- [Qemu-ppc] [PATCH v4 16/28] spapr: introdude a new machine IRQ backend for XIVE, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 17/28] spapr: add hcalls support for the XIVE exploitation interrupt mode, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 18/28] spapr: add device tree support for the XIVE exploitation mode, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 19/28] spapr: allocate the interrupt thread context under the CPU core, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 20/28] spapr: introduce a 'pseries-3.0-xive' QEMU machine, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 21/28] spapr: add classes for the XIVE models, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 22/28] target/ppc/kvm: add Linux KVM definitions for XIVE, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 23/28] spapr/xive: add common realize routine for KVM, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 24/28] spapr/xive: add KVM support, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 25/28] spapr: fix XICS migration, Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 26/28] pnv: add a physical mapping array describing MMIO ranges in each chip,
Cédric Le Goater <=
- [Qemu-ppc] [PATCH v4 27/28] ppc: externalize ppc_get_vcpu_by_pir(), Cédric Le Goater, 2018/06/07
- [Qemu-ppc] [PATCH v4 28/28] ppc/pnv: add XIVE support, Cédric Le Goater, 2018/06/07