diff options
Diffstat (limited to 'hw/ppc')
-rw-r--r-- | hw/ppc/pegasos2.c | 30 | ||||
-rw-r--r-- | hw/ppc/pnv_core.c | 11 | ||||
-rw-r--r-- | hw/ppc/pnv_nest_pervasive.c | 2 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 2 | ||||
-rw-r--r-- | hw/ppc/spapr_cpu_core.c | 1 |
5 files changed, 41 insertions, 5 deletions
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 8ff4a00c34..16abeaac82 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -14,6 +14,7 @@ #include "hw/sysbus.h" #include "hw/pci/pci_host.h" #include "hw/irq.h" +#include "hw/or-irq.h" #include "hw/pci-host/mv64361.h" #include "hw/isa/vt82c686.h" #include "hw/ide/pci.h" @@ -73,8 +74,11 @@ OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE) struct Pegasos2MachineState { MachineState parent_obj; + PowerPCCPU *cpu; DeviceState *mv; + IRQState pci_irqs[PCI_NUM_PINS]; + OrIRQState orirq[PCI_NUM_PINS]; qemu_irq mv_pirq[PCI_NUM_PINS]; qemu_irq via_pirq[PCI_NUM_PINS]; Vof *vof; @@ -177,7 +181,6 @@ static void pegasos2_init(MachineState *machine) pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i); } pci_bus = mv64361_get_pci_bus(pm->mv, 1); - pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS); /* VIA VT8231 South Bridge (multifunction PCI device) */ via = OBJECT(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA)); @@ -209,6 +212,31 @@ static void pegasos2_init(MachineState *machine) /* other PC hardware */ pci_vga_init(pci_bus); + /* PCI interrupt routing: lines from pci.0 and pci.1 are ORed */ + for (int h = 0; h < 2; h++) { + DeviceState *pd; + g_autofree const char *pn = g_strdup_printf("pcihost%d", h); + + pd = DEVICE(object_resolve_path_component(OBJECT(pm->mv), pn)); + assert(pd); + for (i = 0; i < PCI_NUM_PINS; i++) { + OrIRQState *ori = &pm->orirq[i]; + + if (h == 0) { + g_autofree const char *n = g_strdup_printf("pci-orirq[%d]", i); + + object_initialize_child_with_props(OBJECT(pm), n, + ori, sizeof(*ori), + TYPE_OR_IRQ, &error_fatal, + "num-lines", "2", NULL); + qdev_realize(DEVICE(ori), NULL, &error_fatal); + qemu_init_irq(&pm->pci_irqs[i], pegasos2_pci_irq, pm, i); + qdev_connect_gpio_out(DEVICE(ori), 0, &pm->pci_irqs[i]); + } + qdev_connect_gpio_out(pd, i, qdev_get_gpio_in(DEVICE(ori), h)); + } + } + if (machine->kernel_filename) { sz = load_elf(machine->kernel_filename, NULL, NULL, NULL, &pm->kernel_entry, &pm->kernel_addr, NULL, NULL, 1, diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index a30693990b..e6b02294b1 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -217,8 +217,8 @@ static uint64_t pnv_core_power10_xscom_read(void *opaque, hwaddr addr, case PNV10_XSCOM_EC_CORE_RAS_STATUS: for (i = 0; i < nr_threads; i++) { PowerPCCPU *cpu = pc->threads[i]; - CPUState *cs = CPU(cpu); - if (cs->stopped) { + CPUPPCState *env = &cpu->env; + if (env->quiesced) { val |= PPC_BIT(0 + 8 * i) | PPC_BIT(1 + 8 * i); } } @@ -244,20 +244,25 @@ static void pnv_core_power10_xscom_write(void *opaque, hwaddr addr, for (i = 0; i < nr_threads; i++) { PowerPCCPU *cpu = pc->threads[i]; CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; if (val & PPC_BIT(7 + 8 * i)) { /* stop */ val &= ~PPC_BIT(7 + 8 * i); cpu_pause(cs); + env->quiesced = true; } if (val & PPC_BIT(6 + 8 * i)) { /* start */ val &= ~PPC_BIT(6 + 8 * i); + env->quiesced = false; cpu_resume(cs); } if (val & PPC_BIT(4 + 8 * i)) { /* sreset */ val &= ~PPC_BIT(4 + 8 * i); + env->quiesced = false; pnv_cpu_do_nmi_resume(cs); } if (val & PPC_BIT(3 + 8 * i)) { /* clear maint */ + env->quiesced = false; /* * Hardware has very particular cases for where clear maint * must be used and where start must be used to resume a @@ -317,6 +322,8 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp, pir_spr->default_value = pir; tir_spr->default_value = tir; + env->chip_index = pc->chip->chip_id; + if (pc->big_core) { /* 2 "small cores" get the same core index for SMT operations */ env->core_index = core_hwid >> 1; diff --git a/hw/ppc/pnv_nest_pervasive.c b/hw/ppc/pnv_nest_pervasive.c index 77476753a4..780fa69dde 100644 --- a/hw/ppc/pnv_nest_pervasive.c +++ b/hw/ppc/pnv_nest_pervasive.c @@ -177,7 +177,7 @@ static void pnv_nest_pervasive_realize(DeviceState *dev, Error **errp) pnv_xscom_region_init(&nest_pervasive->xscom_ctrl_regs_mr, OBJECT(nest_pervasive), &pnv_nest_pervasive_control_xscom_ops, - nest_pervasive, "pervasive-control", + nest_pervasive, "xscom-pervasive-control", PNV10_XSCOM_CHIPLET_CTRL_REGS_SIZE); } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5c02037c56..0d4efaa0c0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -701,7 +701,7 @@ static void spapr_dt_cpu(CPUState *cs, void *fdt, int offset, uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ]; int i; - drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, index); + drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, env->core_index); if (drc) { drc_index = spapr_drc_index(drc); _FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index))); diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index ada439e831..135f86a622 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -313,6 +313,7 @@ static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp) return NULL; } + env->chip_index = sc->node_id; env->core_index = cc->core_id; cpu->node_id = sc->node_id; |