summaryrefslogtreecommitdiffstats
path: root/hw/ppc/pnv_lpc.c
diff options
context:
space:
mode:
authorPeter Maydell2019-12-17 12:52:04 +0100
committerPeter Maydell2019-12-17 12:52:04 +0100
commit98ac38cd5ad5e9496277c943020bc4bf16adf10b (patch)
treecbcd38b8289c65f607064a17e4de4799497bf5a6 /hw/ppc/pnv_lpc.c
parentMerge remote-tracking branch 'remotes/ehabkost/tags/x86-next-pull-request' in... (diff)
parentpseries: Update SLOF firmware image (diff)
downloadqemu-98ac38cd5ad5e9496277c943020bc4bf16adf10b.tar.gz
qemu-98ac38cd5ad5e9496277c943020bc4bf16adf10b.tar.xz
qemu-98ac38cd5ad5e9496277c943020bc4bf16adf10b.zip
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-5.0-20191217' into staging
ppc patch queue 2019-12-17 This is the first pull request for the qemu-5.0 branch. It has a lot of accumulated changes, including: * SLOF update to support boot using the IOMMU (will become necessary for secure guests) * Clean ups to pnv handling of chip models * A number of extensions to the powernv machine model * TCG extensions to allow powernv emulated systems to run KVM guests * Outline support for POWER10 chips in powernv * Cleanups to the ibm,client-architecture-support feature negotiation path * XIVE reworks to better handle the powernv machine * Improvements to not waste interrupt queues and other semi-scarce resources when using XIVE under KVM # gpg: Signature made Tue 17 Dec 2019 04:42:20 GMT # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full] # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full] # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full] # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown] # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-5.0-20191217: (88 commits) pseries: Update SLOF firmware image ppc/pnv: Drop PnvChipClass::type ppc/pnv: Introduce PnvChipClass::xscom_pcba() method ppc/pnv: Drop pnv_chip_is_power9() and pnv_chip_is_power10() helpers ppc/pnv: Pass content of the "compatible" property to pnv_dt_xscom() ppc/pnv: Pass XSCOM base address and address size to pnv_dt_xscom() ppc/pnv: Introduce PnvChipClass::xscom_core_base() method ppc/pnv: Introduce PnvChipClass::intc_print_info() method ppc/pnv: Drop pnv_is_power9() and pnv_is_power10() helpers ppc/pnv: Introduce PnvMachineClass::dt_power_mgt() ppc/pnv: Introduce PnvMachineClass and PnvMachineClass::compat ppc/pnv: Drop PnvPsiClass::chip_type ppc/pnv: Introduce PnvPsiClass::compat ppc: Drop useless extern annotation for functions ppc/pnv: Fix OCC common area region mapping ppc/pnv: Introduce PBA registers ppc/pnv: Make PnvXScomInterface an incomplete type ppc/pnv: populate the DT with realized XSCOM devices ppc/pnv: Loop on the whole hierarchy to populate the DT with the XSCOM nodes target/ppc: Add SPR TBU40 ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/pnv_lpc.c')
-rw-r--r--hw/ppc/pnv_lpc.c76
1 files changed, 56 insertions, 20 deletions
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 9466d4a1be..18256d9ba3 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -24,7 +24,7 @@
#include "qemu/module.h"
#include "hw/irq.h"
#include "hw/isa/isa.h"
-
+#include "hw/qdev-properties.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_lpc.h"
#include "hw/ppc/pnv_xscom.h"
@@ -86,7 +86,7 @@ enum {
#define ISA_FW_SIZE 0x10000000
#define LPC_IO_OPB_ADDR 0xd0010000
#define LPC_IO_OPB_SIZE 0x00010000
-#define LPC_MEM_OPB_ADDR 0xe0010000
+#define LPC_MEM_OPB_ADDR 0xe0000000
#define LPC_MEM_OPB_SIZE 0x10000000
#define LPC_FW_OPB_ADDR 0xf0000000
#define LPC_FW_OPB_SIZE 0x10000000
@@ -122,26 +122,36 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
}
/* POWER9 only */
-int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
+int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset, uint64_t lpcm_addr,
+ uint64_t lpcm_size)
{
const char compat[] = "ibm,power9-lpcm-opb\0simple-bus";
const char lpc_compat[] = "ibm,power9-lpc\0ibm,lpc";
char *name;
int offset, lpcm_offset;
- uint64_t lpcm_addr = PNV9_LPCM_BASE(chip);
uint32_t opb_ranges[8] = { 0,
cpu_to_be32(lpcm_addr >> 32),
cpu_to_be32((uint32_t)lpcm_addr),
- cpu_to_be32(PNV9_LPCM_SIZE / 2),
- cpu_to_be32(PNV9_LPCM_SIZE / 2),
+ cpu_to_be32(lpcm_size / 2),
+ cpu_to_be32(lpcm_size / 2),
cpu_to_be32(lpcm_addr >> 32),
- cpu_to_be32(PNV9_LPCM_SIZE / 2),
- cpu_to_be32(PNV9_LPCM_SIZE / 2),
+ cpu_to_be32(lpcm_size / 2),
+ cpu_to_be32(lpcm_size / 2),
};
uint32_t opb_reg[4] = { cpu_to_be32(lpcm_addr >> 32),
cpu_to_be32((uint32_t)lpcm_addr),
- cpu_to_be32(PNV9_LPCM_SIZE >> 32),
- cpu_to_be32((uint32_t)PNV9_LPCM_SIZE),
+ cpu_to_be32(lpcm_size >> 32),
+ cpu_to_be32((uint32_t)lpcm_size),
+ };
+ uint32_t lpc_ranges[12] = { 0, 0,
+ cpu_to_be32(LPC_MEM_OPB_ADDR),
+ cpu_to_be32(LPC_MEM_OPB_SIZE),
+ cpu_to_be32(1), 0,
+ cpu_to_be32(LPC_IO_OPB_ADDR),
+ cpu_to_be32(LPC_IO_OPB_SIZE),
+ cpu_to_be32(3), 0,
+ cpu_to_be32(LPC_FW_OPB_ADDR),
+ cpu_to_be32(LPC_FW_OPB_SIZE),
};
uint32_t reg[2];
@@ -211,6 +221,8 @@ int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
_FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
_FDT((fdt_setprop(fdt, offset, "compatible", lpc_compat,
sizeof(lpc_compat))));
+ _FDT((fdt_setprop(fdt, offset, "ranges", lpc_ranges,
+ sizeof(lpc_ranges))));
return 0;
}
@@ -679,20 +691,24 @@ static const TypeInfo pnv_lpc_power9_info = {
.class_init = pnv_lpc_power9_class_init,
};
+static void pnv_lpc_power10_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->desc = "PowerNV LPC Controller POWER10";
+}
+
+static const TypeInfo pnv_lpc_power10_info = {
+ .name = TYPE_PNV10_LPC,
+ .parent = TYPE_PNV9_LPC,
+ .class_init = pnv_lpc_power10_class_init,
+};
+
static void pnv_lpc_realize(DeviceState *dev, Error **errp)
{
PnvLpcController *lpc = PNV_LPC(dev);
- Object *obj;
- Error *local_err = NULL;
- obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
- if (!obj) {
- error_propagate(errp, local_err);
- error_prepend(errp, "required link 'psi' not found: ");
- return;
- }
- /* The LPC controller needs PSI to generate interrupts */
- lpc->psi = PNV_PSI(obj);
+ assert(lpc->psi);
/* Reg inits */
lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
@@ -734,12 +750,18 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
&lpc->lpc_hc_regs);
}
+static Property pnv_lpc_properties[] = {
+ DEFINE_PROP_LINK("psi", PnvLpcController, psi, TYPE_PNV_PSI, PnvPsi *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void pnv_lpc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pnv_lpc_realize;
dc->desc = "PowerNV LPC Controller";
+ dc->props = pnv_lpc_properties;
}
static const TypeInfo pnv_lpc_info = {
@@ -755,6 +777,7 @@ static void pnv_lpc_register_types(void)
type_register_static(&pnv_lpc_info);
type_register_static(&pnv_lpc_power8_info);
type_register_static(&pnv_lpc_power9_info);
+ type_register_static(&pnv_lpc_power10_info);
}
type_init(pnv_lpc_register_types)
@@ -801,6 +824,7 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
ISABus *isa_bus;
qemu_irq *irqs;
qemu_irq_handler handler;
+ PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
/* let isa_bus_new() create its own bridge on SysBus otherwise
* devices speficied on the command line won't find the bus and
@@ -825,5 +849,17 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS);
isa_bus_irqs(isa_bus, irqs);
+
+ /*
+ * TODO: Map PNOR on the LPC FW address space on demand ?
+ */
+ memory_region_add_subregion(&lpc->isa_fw, PNOR_SPI_OFFSET,
+ &pnv->pnor->mmio);
+ /*
+ * Start disabled. The HIOMAP protocol will activate the mapping
+ * with HIOMAP_C_CREATE_WRITE_WINDOW
+ */
+ memory_region_set_enabled(&pnv->pnor->mmio, false);
+
return isa_bus;
}