[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 40/77] ppc/pnv: Wire up XICS native with PowerNV pla
From: |
Benjamin Herrenschmidt |
Subject: |
[Qemu-devel] [PATCH 40/77] ppc/pnv: Wire up XICS native with PowerNV platform |
Date: |
Wed, 11 Nov 2015 11:27:53 +1100 |
Signed-off-by: Benjamin Herrenschmidt <address@hidden>
---
hw/ppc/pnv.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/pnv.h | 2 ++
include/hw/ppc/xics.h | 2 ++
3 files changed, 73 insertions(+)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 2eac877..a7a9b0f 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -41,6 +41,7 @@
#include "hw/ppc/ppc.h"
#include "hw/ppc/pnv.h"
#include "hw/loader.h"
+#include "hw/ppc/xics.h"
#include "hw/ppc/pnv_xscom.h"
#include "exec/address-spaces.h"
@@ -81,6 +82,59 @@ struct sPowerNVMachineState {
PnvSystem sys;
};
+static XICSState *try_create_xics(const char *type, int nr_servers,
+ int nr_irqs, Error **errp)
+{
+ Error *err = NULL;
+ DeviceState *dev;
+
+ dev = qdev_create(NULL, type);
+ qdev_prop_set_uint32(dev, "nr_servers", nr_servers);
+ object_property_set_bool(OBJECT(dev), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ object_unparent(OBJECT(dev));
+ return NULL;
+ }
+
+ return XICS_COMMON(dev);
+}
+
+static XICSState *xics_system_init(int nr_servers, int nr_irqs)
+{
+ XICSState *xics = NULL;
+
+#if 0 /* Some fixing needed to handle native ICS in KVM mode */
+ if (kvm_enabled()) {
+ QemuOpts *machine_opts = qemu_get_machine_opts();
+ bool irqchip_allowed = qemu_opt_get_bool(machine_opts,
+ "kernel_irqchip", true);
+ bool irqchip_required = qemu_opt_get_bool(machine_opts,
+ "kernel_irqchip", false);
+ if (irqchip_allowed) {
+ icp = try_create_xics(TYPE_KVM_XICS, nr_servers, nr_irqs,
+ &error_abort);
+ }
+
+ if (irqchip_required && !icp) {
+ perror("Failed to create in-kernel XICS\n");
+ abort();
+ }
+ }
+#endif
+
+ if (!xics) {
+ xics = try_create_xics(TYPE_XICS_NATIVE, nr_servers, nr_irqs,
+ &error_abort);
+ }
+
+ if (!xics) {
+ perror("Failed to create XICS\n");
+ abort();
+ }
+ return xics;
+}
+
static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop,
size_t maxsize)
{
@@ -366,6 +420,13 @@ static void *powernv_create_fdt(PnvSystem *sys, uint32_t
initrd_base, uint32_t i
_FDT((fdt_end_node(fdt)));
+ /* ICPs */
+ CPU_FOREACH(cs) {
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ uint32_t base_server = ppc_get_vcpu_dt_id(cpu);
+ xics_create_native_icp_node(sys->xics, fdt, base_server, smt);
+ }
+
/* Memory */
_FDT((powernv_populate_memory(fdt)));
@@ -451,11 +512,17 @@ static void ppc_powernv_init(MachineState *machine)
MemoryRegion *ram = g_new(MemoryRegion, 1);
sPowerNVMachineState *pnv_machine = POWERNV_MACHINE(machine);
PnvSystem *sys = &pnv_machine->sys;
+ XICSState *xics;
long fw_size;
char *filename;
void *fdt;
int i;
+ /* Set up Interrupt Controller before we create the VCPUs */
+ xics = xics_system_init(smp_cpus * kvmppc_smt_threads() / smp_threads,
+ XICS_IRQS_POWERNV);
+ sys->xics = xics;
+
/* init CPUs */
if (cpu_model == NULL) {
cpu_model = kvm_enabled() ? "host" : "POWER8";
@@ -475,6 +542,8 @@ static void ppc_powernv_init(MachineState *machine)
/* MSR[IP] doesn't exist nowadays */
env->msr_mask &= ~(1 << 6);
+ xics_cpu_setup(xics, cpu);
+
qemu_register_reset(powernv_cpu_reset, cpu);
}
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index cb157eb..80617b4 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -21,6 +21,7 @@
#include "hw/hw.h"
typedef struct XScomBus XScomBus;
+typedef struct XICSState XICSState;
/* Should we turn that into a QOjb of some sort ? */
typedef struct PnvChip {
@@ -29,6 +30,7 @@ typedef struct PnvChip {
} PnvChip;
typedef struct PnvSystem {
+ XICSState *xics;
uint32_t num_chips;
#define PNV_MAX_CHIPS 1
PnvChip chips[PNV_MAX_CHIPS];
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 1cf7037..85d2fb9 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -183,6 +183,8 @@ struct ICSIRQState {
};
#define XICS_IRQS_SPAPR 1024
+#define XICS_IRQS_POWERNV (1 << 19)
+
qemu_irq xics_get_qirq(XICSState *icp, int irq);
--
2.5.0
- Re: [Qemu-devel] [Qemu-ppc] [PATCH 26/77] ppc/pnv: Add skeletton PowerNV platform, (continued)
[Qemu-devel] [PATCH 27/77] ppc/pnv: Add XSCOM infrastructure, Benjamin Herrenschmidt, 2015/11/10
[Qemu-devel] [PATCH 34/77] ppc/xics: An ICS with offset 0 is assumed to be uninitialized, Benjamin Herrenschmidt, 2015/11/10
[Qemu-devel] [PATCH 45/77] qdev: Add a hook for a bus to device if it can add devices, Benjamin Herrenschmidt, 2015/11/10
[Qemu-devel] [PATCH 40/77] ppc/pnv: Wire up XICS native with PowerNV platform,
Benjamin Herrenschmidt <=
[Qemu-devel] [PATCH 33/77] ppc/xics: Make the ICSState a list, Benjamin Herrenschmidt, 2015/11/10
[Qemu-devel] [PATCH 38/77] ppc/xics: Add "native" XICS subclass, Benjamin Herrenschmidt, 2015/11/10
[Qemu-devel] [PATCH 41/77] ppc/pnv: Add LPC controller and hook it up with a UART and RTC, Benjamin Herrenschmidt, 2015/11/10
[Qemu-devel] [PATCH 44/77] pci-bridge: Set a supported devfn_min for bridge, Benjamin Herrenschmidt, 2015/11/10