diff options
-rw-r--r-- | hw/ppc/pnv.c | 12 | ||||
-rw-r--r-- | hw/ppc/pnv_homer.c | 109 | ||||
-rw-r--r-- | hw/ppc/pnv_xscom.c | 32 | ||||
-rw-r--r-- | include/hw/ppc/pnv.h | 16 | ||||
-rw-r--r-- | include/hw/ppc/pnv_homer.h | 3 | ||||
-rw-r--r-- | include/hw/ppc/pnv_xscom.h | 6 |
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 |