qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] [PATCH 09/17] e500: move mpic under CCSR


From: David Gibson
Subject: Re: [Qemu-ppc] [PATCH 09/17] e500: move mpic under CCSR
Date: Tue, 5 Dec 2017 17:34:02 +1100
User-agent: Mutt/1.9.1 (2017-09-22)

On Sun, Nov 26, 2017 at 03:59:07PM -0600, Michael Davidsaver wrote:
> Start moving code out of ppce500_init()
> 
> Existing ppce500_init_mpic() suggests that MPIC may not be created w/ KVM.
> However, ppce500_init() used mpicdev unconditionally, and would
> fail if the MPIC isn't created.  So require creation.
> 
> Not tested with KVM for lack of hardware.
> 
> Signed-off-by: Michael Davidsaver <address@hidden>
> ---
>  hw/ppc/e500.c      | 102 
> +++--------------------------------------------------
>  hw/ppc/e500_ccsr.c |  85 +++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 84 insertions(+), 103 deletions(-)
> 
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index e22919f4f1..1872bb8eaa 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -29,7 +29,6 @@
>  #include "sysemu/kvm.h"
>  #include "kvm_ppc.h"
>  #include "sysemu/device_tree.h"
> -#include "hw/ppc/openpic.h"
>  #include "hw/ppc/ppc.h"
>  #include "hw/loader.h"
>  #include "elf.h"
> @@ -679,92 +678,6 @@ static void ppce500_cpu_reset(void *opaque)
>      mmubooke_create_initial_mapping(env);
>  }
>  
> -static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params,
> -                                           qemu_irq **irqs)
> -{
> -    DeviceState *dev;
> -    SysBusDevice *s;
> -    int i, j, k;
> -
> -    dev = qdev_create(NULL, TYPE_OPENPIC);
> -    object_property_add_child(qdev_get_machine(), "pic", OBJECT(dev),
> -                              &error_fatal);
> -    qdev_prop_set_uint32(dev, "model", params->mpic_version);
> -    qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
> -
> -    qdev_init_nofail(dev);
> -    s = SYS_BUS_DEVICE(dev);
> -
> -    k = 0;
> -    for (i = 0; i < smp_cpus; i++) {
> -        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
> -            sysbus_connect_irq(s, k++, irqs[i][j]);
> -        }
> -    }
> -
> -    return dev;
> -}
> -
> -static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
> -                                          qemu_irq **irqs, Error **errp)
> -{
> -    Error *err = NULL;
> -    DeviceState *dev;
> -    CPUState *cs;
> -
> -    dev = qdev_create(NULL, TYPE_KVM_OPENPIC);
> -    qdev_prop_set_uint32(dev, "model", params->mpic_version);
> -
> -    object_property_set_bool(OBJECT(dev), true, "realized", &err);
> -    if (err) {
> -        error_propagate(errp, err);
> -        object_unparent(OBJECT(dev));
> -        return NULL;
> -    }
> -
> -    CPU_FOREACH(cs) {
> -        if (kvm_openpic_connect_vcpu(dev, cs)) {
> -            fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
> -                    __func__);
> -            abort();
> -        }
> -    }
> -
> -    return dev;
> -}
> -
> -static DeviceState *ppce500_init_mpic(MachineState *machine,
> -                                      PPCE500Params *params,
> -                                      MemoryRegion *ccsr,
> -                                      qemu_irq **irqs)
> -{
> -    DeviceState *dev = NULL;
> -    SysBusDevice *s;
> -
> -    if (kvm_enabled()) {
> -        Error *err = NULL;
> -
> -        if (machine_kernel_irqchip_allowed(machine)) {
> -            dev = ppce500_init_mpic_kvm(params, irqs, &err);
> -        }
> -        if (machine_kernel_irqchip_required(machine) && !dev) {
> -            error_reportf_err(err,
> -                              "kernel_irqchip requested but unavailable: ");
> -            exit(1);
> -        }
> -    }
> -
> -    if (!dev) {
> -        dev = ppce500_init_mpic_qemu(params, irqs);
> -    }
> -
> -    s = SYS_BUS_DEVICE(dev);
> -    memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET,
> -                                s->mmio[0].memory);
> -
> -    return dev;
> -}
> -
>  static void ppce500_power_off(void *opaque, int line, int on)
>  {
>      if (on) {
> @@ -794,18 +707,14 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>      /* irq num for pin INTA, INTB, INTC and INTD is 1, 2, 3 and
>       * 4 respectively */
>      unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
> -    qemu_irq **irqs;
>      DeviceState *dev, *mpicdev;
>      CPUPPCState *firstenv = NULL;
>      MemoryRegion *ccsr_addr_space;
>      SysBusDevice *s;
>  
> -    irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
> -    irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
>      for (i = 0; i < smp_cpus; i++) {
>          PowerPCCPU *cpu;
>          CPUState *cs;
> -        qemu_irq *input;
>  
>          cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
>          env = &cpu->env;
> @@ -821,13 +730,7 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>              firstenv = env;
>          }
>  
> -        irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB);
> -        input = (qemu_irq *)env->irq_inputs;
> -        irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
> -        irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
>          env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i;
> -        env->mpic_iack = params->ccsrbar_base +
> -                         MPC8544_MPIC_REGS_OFFSET + 0xa0;
>  
>          ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
>  
> @@ -857,12 +760,15 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> *params)
>      dev = qdev_create(NULL, "e500-ccsr");
>      object_property_add_child(qdev_get_machine(), "e500-ccsr",
>                                OBJECT(dev), NULL);
> +    qdev_prop_set_uint32(dev, "mpic-model", params->mpic_version);
>      qdev_prop_set_uint32(dev, "base", params->ccsrbar_base);
>      qdev_prop_set_uint32(dev, "ram-size", ram_size);
>      qdev_init_nofail(dev);
>      ccsr_addr_space = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
>  
> -    mpicdev = ppce500_init_mpic(machine, params, ccsr_addr_space, irqs);
> +    /* created under "e500-ccsr" */
> +    mpicdev = DEVICE(object_resolve_path("/machine/pic", 0));
> +    assert(mpicdev);
>  
>      /* Serial */
>      if (serial_hds[0]) {
> diff --git a/hw/ppc/e500_ccsr.c b/hw/ppc/e500_ccsr.c
> index 9400d7cf13..68d952794e 100644
> --- a/hw/ppc/e500_ccsr.c
> +++ b/hw/ppc/e500_ccsr.c
> @@ -24,10 +24,14 @@
>  #include "qemu-common.h"
>  #include "qemu/log.h"
>  #include "qemu/error-report.h"
> +#include "qapi/error.h"
>  #include "cpu.h"
>  #include "hw/hw.h"
> +#include "hw/boards.h"
>  #include "sysemu/sysemu.h"
> +#include "sysemu/kvm.h"
>  #include "hw/sysbus.h"
> +#include "hw/ppc/openpic.h"
>  
>  /* E500_ denotes registers common to all */
>  /* Some CCSR offsets duplicated in e500.c */
> @@ -185,20 +189,90 @@ static void e500_ccsr_reset(DeviceState *dev)
>      e500_ccsr_post_move(ccsr);
>  }
>  
> -static void e500_ccsr_initfn(Object *obj)
> +static void e500_ccsr_init(Object *obj)
>  {
> -    CCSRState *ccsr = E500_CCSR(obj);
> +    DeviceState *dev = DEVICE(obj);
> +    CCSRState *ccsr = E500_CCSR(dev);
> +
> +    assert(current_machine);
> +    if (kvm_enabled()) {
> +
> +        if (!machine_kernel_irqchip_allowed(current_machine)) {
> +            error_report("Machine does not allow PIC,"
> +                         " but this is not supported");
> +            exit(1);

You've changed the logic here from the original; this now always
requires a kernel irqchip with kvm, whereas previously it would allow
fallback to the non kernel irqchip unless
machine_kernel_irqchip_required().

> +        }
>  
> -    memory_region_init_io(&ccsr->iomem, obj, &e500_ccsr_ops,
> +        ccsr->pic = qdev_create(NULL, TYPE_KVM_OPENPIC);
> +    } else {
> +        ccsr->pic = qdev_create(NULL, TYPE_OPENPIC);
> +    }
> +
> +    if (!ccsr->pic) {
> +        error_report("Failed to create PIC");
> +        exit(1);
> +    }
> +
> +    object_property_add_child(qdev_get_machine(), "pic", OBJECT(ccsr->pic),
> +                              &error_fatal);
> +
> +    qdev_prop_set_uint32(ccsr->pic, "nb_cpus", smp_cpus);
> +
> +    object_property_add_alias(obj, "mpic-model",
> +                              OBJECT(ccsr->pic), "model",
> +                              &error_fatal);
> +}
> +
> +static void e500_ccsr_realize(DeviceState *dev, Error **errp)
> +{
> +    CCSRState *ccsr = E500_CCSR(dev);
> +    SysBusDevice *pic;
> +
> +    /* Base 1MB CCSR Region */
> +    memory_region_init_io(&ccsr->iomem, OBJECT(dev), &e500_ccsr_ops,
>                            ccsr, "e500-ccsr", 1024 * 1024);
> -    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &ccsr->iomem);
> +    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &ccsr->iomem);
> +
> +    qdev_init_nofail(ccsr->pic);
> +    pic = SYS_BUS_DEVICE(ccsr->pic);
> +
> +    /* connect MPIC to CPU(s) */
> +    if (kvm_enabled()) {
> +        CPUState *cs;
> +
> +        CPU_FOREACH(cs) {
> +            if (kvm_openpic_connect_vcpu(ccsr->pic, cs)) {
> +                error_setg(errp, "%s: failed to connect vcpu to irqchip",
> +                           __func__);
> +                return;
> +            }
> +        }
> +
> +    } else {
> +        CPUState *cs;
> +
> +        CPU_FOREACH(cs) {
> +            PowerPCCPU *cpu = POWERPC_CPU(cs);
> +            CPUPPCState *env = &cpu->env;
> +            qemu_irq *inputs = (qemu_irq *)env->irq_inputs;
> +            int base = cs->cpu_index * PPCE500_INPUT_NB;
> +
> +            sysbus_connect_irq(pic, base + OPENPIC_OUTPUT_INT,
> +                               inputs[PPCE500_INPUT_INT]);
> +            sysbus_connect_irq(pic, base + OPENPIC_OUTPUT_CINT,
> +                               inputs[PPCE500_INPUT_CINT]);
> +        }
> +    }
>  
> +    memory_region_add_subregion(&ccsr->iomem, E500_MPIC_OFFSET,
> +                                sysbus_mmio_get_region(pic, 0));
>  }
>  
>  static Property e500_ccsr_props[] = {
>      DEFINE_PROP_UINT32("base", CCSRState, defbase, 0xff700000),
>      DEFINE_PROP_UINT32("ram-size", CCSRState, ram_size, 0),
>      DEFINE_PROP_UINT32("porpllsr", CCSRState, porpllsr, 0),
> +    /* "mpic-model" aliased from MPIC */
>      DEFINE_PROP_END_OF_LIST()
>  };
>  
> @@ -221,6 +295,7 @@ void e500_ccsr_class_initfn(ObjectClass *klass, void 
> *data)
>  
>      dc->props = e500_ccsr_props;
>      dc->vmsd = &vmstate_e500_ccsr;
> +    dc->realize = e500_ccsr_realize;
>      dc->reset = e500_ccsr_reset;
>  }
>  
> @@ -228,7 +303,7 @@ static const TypeInfo e500_ccsr_info = {
>      .name          = TYPE_E500_CCSR,
>      .parent        = TYPE_SYS_BUS_DEVICE,
>      .instance_size = sizeof(CCSRState),
> -    .instance_init = e500_ccsr_initfn,
> +    .instance_init = e500_ccsr_init,
>      .class_size    = sizeof(SysBusDeviceClass),
>      .class_init    = e500_ccsr_class_initfn
>  };

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]