mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 18:23:57 -06:00
ppc/pnv: Introduce PBA registers
The PBA bridge unit (Power Bus Access) connects the OCC (On Chip Controller) to the Power bus and System Memory. The PBA is used to gather sensor data, for power management, for sleep states, for initial boot, among other things. The PBA logic provides a set of four registers PowerBus Access Base Address Registers (PBABAR0..3) which map the OCC address space to the PowerBus space. These registers are setup by the initial FW and define the PowerBus Range of system memory that can be accessed by PBA. The current modeling of the PBABAR registers is done under the common XSCOM handlers. We introduce a specific XSCOM regions for these registers and fix : - BAR sizes and BAR masks - The mapping of the OCC common area. It is common to all chips and should be mapped once. We will address per-OCC area in the next change. - OCC common area is in BAR 3 on P8 Inspired by previous work of Balamuruhan S <bala24@linux.ibm.com> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20191211082912.2625-2-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
90cce00c7b
commit
8f09231631
6 changed files with 134 additions and 44 deletions
|
@ -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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue