aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/pnv.c12
-rw-r--r--hw/ppc/pnv_homer.c109
-rw-r--r--hw/ppc/pnv_xscom.c32
-rw-r--r--include/hw/ppc/pnv.h16
-rw-r--r--include/hw/ppc/pnv_homer.h3
-rw-r--r--include/hw/ppc/pnv_xscom.h6
6 files changed, 134 insertions, 44 deletions
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 67d0ad5..af7317a 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1065,7 +1065,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
/* OCC SRAM model */
- memory_region_add_subregion(get_system_memory(), PNV_OCC_COMMON_AREA(chip),
+ memory_region_add_subregion(get_system_memory(), PNV_OCC_COMMON_AREA_BASE,
&chip8->occ.sram_regs);
/* HOMER */
@@ -1077,6 +1077,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
+ /* Homer Xscom region */
+ pnv_xscom_add_subregion(chip, PNV_XSCOM_PBA_BASE, &chip8->homer.pba_regs);
+
+ /* Homer mmio region */
memory_region_add_subregion(get_system_memory(), PNV_HOMER_BASE(chip),
&chip8->homer.regs);
}
@@ -1274,7 +1278,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
/* OCC SRAM model */
- memory_region_add_subregion(get_system_memory(), PNV9_OCC_COMMON_AREA(chip),
+ memory_region_add_subregion(get_system_memory(), PNV9_OCC_COMMON_AREA_BASE,
&chip9->occ.sram_regs);
/* HOMER */
@@ -1286,6 +1290,10 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
+ /* Homer Xscom region */
+ pnv_xscom_add_subregion(chip, PNV9_XSCOM_PBA_BASE, &chip9->homer.pba_regs);
+
+ /* Homer mmio region */
memory_region_add_subregion(get_system_memory(), PNV9_HOMER_BASE(chip),
&chip9->homer.regs);
}
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
index 994a378..a08b791 100644
--- a/hw/ppc/pnv_homer.c
+++ b/hw/ppc/pnv_homer.c
@@ -17,6 +17,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "qapi/error.h"
#include "exec/hwaddr.h"
#include "exec/memory.h"
@@ -25,6 +26,7 @@
#include "hw/qdev-properties.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_homer.h"
+#include "hw/ppc/pnv_xscom.h"
static bool core_max_array(PnvHomer *homer, hwaddr addr)
@@ -114,10 +116,67 @@ static const MemoryRegionOps pnv_power8_homer_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
+/* P8 PBA BARs */
+#define PBA_BAR0 0x00
+#define PBA_BAR1 0x01
+#define PBA_BAR2 0x02
+#define PBA_BAR3 0x03
+#define PBA_BARMASK0 0x04
+#define PBA_BARMASK1 0x05
+#define PBA_BARMASK2 0x06
+#define PBA_BARMASK3 0x07
+
+static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ PnvHomer *homer = PNV_HOMER(opaque);
+ PnvChip *chip = homer->chip;
+ uint32_t reg = addr >> 3;
+ uint64_t val = 0;
+
+ switch (reg) {
+ case PBA_BAR0:
+ val = PNV_HOMER_BASE(chip);
+ break;
+ case PBA_BARMASK0: /* P8 homer region mask */
+ val = (PNV_HOMER_SIZE - 1) & 0x300000;
+ break;
+ case PBA_BAR3: /* P8 occ common area */
+ val = PNV_OCC_COMMON_AREA_BASE;
+ break;
+ case PBA_BARMASK3: /* P8 occ common area mask */
+ val = (PNV_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+ }
+ return val;
+}
+
+static void pnv_homer_power8_pba_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+}
+
+static const MemoryRegionOps pnv_homer_power8_pba_ops = {
+ .read = pnv_homer_power8_pba_read,
+ .write = pnv_homer_power8_pba_write,
+ .valid.min_access_size = 8,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 8,
+ .impl.max_access_size = 8,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
static void pnv_homer_power8_class_init(ObjectClass *klass, void *data)
{
PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
+ homer->pba_size = PNV_XSCOM_PBA_SIZE;
+ homer->pba_ops = &pnv_homer_power8_pba_ops;
homer->homer_size = PNV_HOMER_SIZE;
homer->homer_ops = &pnv_power8_homer_ops;
homer->core_max_base = PNV8_CORE_MAX_BASE;
@@ -210,10 +269,57 @@ static const MemoryRegionOps pnv_power9_homer_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
+static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ PnvHomer *homer = PNV_HOMER(opaque);
+ PnvChip *chip = homer->chip;
+ uint32_t reg = addr >> 3;
+ uint64_t val = 0;
+
+ switch (reg) {
+ case PBA_BAR0:
+ val = PNV9_HOMER_BASE(chip);
+ break;
+ case PBA_BARMASK0: /* P9 homer region mask */
+ val = (PNV9_HOMER_SIZE - 1) & 0x300000;
+ break;
+ case PBA_BAR2: /* P9 occ common area */
+ val = PNV9_OCC_COMMON_AREA_BASE;
+ break;
+ case PBA_BARMASK2: /* P9 occ common area size */
+ val = (PNV9_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+ }
+ return val;
+}
+
+static void pnv_homer_power9_pba_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
+ HWADDR_PRIx "\n", addr >> 3);
+}
+
+static const MemoryRegionOps pnv_homer_power9_pba_ops = {
+ .read = pnv_homer_power9_pba_read,
+ .write = pnv_homer_power9_pba_write,
+ .valid.min_access_size = 8,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 8,
+ .impl.max_access_size = 8,
+ .endianness = DEVICE_BIG_ENDIAN,
+};
+
static void pnv_homer_power9_class_init(ObjectClass *klass, void *data)
{
PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
+ homer->pba_size = PNV9_XSCOM_PBA_SIZE;
+ homer->pba_ops = &pnv_homer_power9_pba_ops;
homer->homer_size = PNV9_HOMER_SIZE;
homer->homer_ops = &pnv_power9_homer_ops;
homer->core_max_base = PNV9_CORE_MAX_BASE;
@@ -233,6 +339,9 @@ static void pnv_homer_realize(DeviceState *dev, Error **errp)
assert(homer->chip);
+ pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops,
+ homer, "xscom-pba", hmrc->pba_size);
+
/* homer region */
memory_region_init_io(&homer->regs, OBJECT(dev),
hmrc->homer_ops, homer, "homer-main-memory",
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index fd48d4e..df92600 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -36,16 +36,6 @@
#define PRD_P9_IPOLL_REG_MASK 0x000F0033
#define PRD_P9_IPOLL_REG_STATUS 0x000F0034
-/* PBA BARs */
-#define P8_PBA_BAR0 0x2013f00
-#define P8_PBA_BAR2 0x2013f02
-#define P8_PBA_BARMASK0 0x2013f04
-#define P8_PBA_BARMASK2 0x2013f06
-#define P9_PBA_BAR0 0x5012b00
-#define P9_PBA_BAR2 0x5012b02
-#define P9_PBA_BARMASK0 0x5012b04
-#define P9_PBA_BARMASK2 0x5012b06
-
static void xscom_complete(CPUState *cs, uint64_t hmer_bits)
{
/*
@@ -90,26 +80,6 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
case 0x18002: /* ECID2 */
return 0;
- case P9_PBA_BAR0:
- return PNV9_HOMER_BASE(chip);
- case P8_PBA_BAR0:
- return PNV_HOMER_BASE(chip);
-
- case P9_PBA_BARMASK0: /* P9 homer region size */
- return PNV9_HOMER_SIZE;
- case P8_PBA_BARMASK0: /* P8 homer region size */
- return PNV_HOMER_SIZE;
-
- case P9_PBA_BAR2: /* P9 occ common area */
- return PNV9_OCC_COMMON_AREA(chip);
- case P8_PBA_BAR2: /* P8 occ common area */
- return PNV_OCC_COMMON_AREA(chip);
-
- case P9_PBA_BARMASK2: /* P9 occ common area size */
- return PNV9_OCC_COMMON_AREA_SIZE;
- case P8_PBA_BARMASK2: /* P8 occ common area size */
- return PNV_OCC_COMMON_AREA_SIZE;
-
case 0x1010c00: /* PIBAM FIR */
case 0x1010c03: /* PIBAM FIR MASK */
@@ -130,9 +100,7 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
case 0x202000f: /* ADU stuff, receive status register*/
return 0;
case 0x2013f01: /* PBA stuff */
- case 0x2013f03: /* PBA stuff */
case 0x2013f05: /* PBA stuff */
- case 0x2013f07: /* PBA stuff */
return 0;
case 0x2013028: /* CAPP stuff */
case 0x201302a: /* CAPP stuff */
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 56d1161..301c7e6 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -244,12 +244,10 @@ IPMIBmc *pnv_bmc_create(void);
#define PNV_XSCOM_BASE(chip) \
(0x0003fc0000000000ull + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
-#define PNV_OCC_COMMON_AREA_SIZE 0x0000000000700000ull
-#define PNV_OCC_COMMON_AREA(chip) \
- (0x7fff800000ull + ((uint64_t)PNV_CHIP_INDEX(chip) * \
- PNV_OCC_COMMON_AREA_SIZE))
+#define PNV_OCC_COMMON_AREA_SIZE 0x0000000000800000ull
+#define PNV_OCC_COMMON_AREA_BASE 0x7fff800000ull
-#define PNV_HOMER_SIZE 0x0000000000300000ull
+#define PNV_HOMER_SIZE 0x0000000000400000ull
#define PNV_HOMER_BASE(chip) \
(0x7ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV_HOMER_SIZE)
@@ -312,12 +310,10 @@ IPMIBmc *pnv_bmc_create(void);
#define PNV9_XSCOM_SIZE 0x0000000400000000ull
#define PNV9_XSCOM_BASE(chip) PNV9_CHIP_BASE(chip, 0x00603fc00000000ull)
-#define PNV9_OCC_COMMON_AREA_SIZE 0x0000000000700000ull
-#define PNV9_OCC_COMMON_AREA(chip) \
- (0x203fff800000ull + ((uint64_t)PNV_CHIP_INDEX(chip) * \
- PNV9_OCC_COMMON_AREA_SIZE))
+#define PNV9_OCC_COMMON_AREA_SIZE 0x0000000000800000ull
+#define PNV9_OCC_COMMON_AREA_BASE 0x203fff800000ull
-#define PNV9_HOMER_SIZE 0x0000000000300000ull
+#define PNV9_HOMER_SIZE 0x0000000000400000ull
#define PNV9_HOMER_BASE(chip) \
(0x203ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV9_HOMER_SIZE)
diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h
index abaec43..1e91c95 100644
--- a/include/hw/ppc/pnv_homer.h
+++ b/include/hw/ppc/pnv_homer.h
@@ -33,6 +33,7 @@ typedef struct PnvHomer {
DeviceState parent;
struct PnvChip *chip;
+ MemoryRegion pba_regs;
MemoryRegion regs;
} PnvHomer;
@@ -44,6 +45,8 @@ typedef struct PnvHomer {
typedef struct PnvHomerClass {
DeviceClass parent_class;
+ int pba_size;
+ const MemoryRegionOps *pba_ops;
int homer_size;
const MemoryRegionOps *homer_ops;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 5ad2735..09188d7 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -68,6 +68,9 @@ typedef struct PnvXScomInterfaceClass {
#define PNV_XSCOM_OCC_BASE 0x0066000
#define PNV_XSCOM_OCC_SIZE 0x6000
+#define PNV_XSCOM_PBA_BASE 0x2013f00
+#define PNV_XSCOM_PBA_SIZE 0x40
+
/*
* Layout of the XSCOM PCB addresses (POWER 9)
*/
@@ -82,6 +85,9 @@ typedef struct PnvXScomInterfaceClass {
#define PNV9_XSCOM_OCC_BASE PNV_XSCOM_OCC_BASE
#define PNV9_XSCOM_OCC_SIZE 0x8000
+#define PNV9_XSCOM_PBA_BASE 0x5012b00
+#define PNV9_XSCOM_PBA_SIZE 0x40
+
#define PNV9_XSCOM_PSIHB_BASE 0x5012900
#define PNV9_XSCOM_PSIHB_SIZE 0x100