qemu-ppc
[Top][All Lists]
Advanced

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

Re: [Qemu-ppc] [PATCH 08/17] e500: additional CCSR registers


From: David Gibson
Subject: Re: [Qemu-ppc] [PATCH 08/17] e500: additional CCSR registers
Date: Wed, 6 Dec 2017 14:13:19 +1100
User-agent: Mutt/1.9.1 (2017-09-22)

On Mon, Dec 04, 2017 at 08:30:13PM +1100, David Gibson wrote:
> On Sun, Nov 26, 2017 at 03:59:06PM -0600, Michael Davidsaver wrote:
> > Add CCSRBAR to allow CCSR region to be relocated.
> > 
> > Guest memory size introspection via RAM config
> > registers.
> > 
> > Dummy RAM error controls.
> > 
> > Clock introspection via Power on Reset PLL
> > Status Register.
> > 
> > Signed-off-by: Michael Davidsaver <address@hidden>
> 
> Applied to ppc-for-2.12.

Sorry, I've pulled this from ppc-for-2.12 because it depended on the
guts patch which brokem make check.

> 
> > 
> > ccsrbase also update iack
> > ---
> >  hw/ppc/e500.c      |  5 ++-
> >  hw/ppc/e500_ccsr.c | 93 
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 95 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> > index b90f4231a6..e22919f4f1 100644
> > --- a/hw/ppc/e500.c
> > +++ b/hw/ppc/e500.c
> > @@ -51,7 +51,9 @@
> >  
> >  #define RAM_SIZES_ALIGN            (64UL << 20)
> >  
> > -/* TODO: parameterize */
> > +/* TODO: parameterize
> > + * Some CCSR offsets duplicated in e500_ccsr.c
> > + */
> >  #define MPC8544_CCSRBAR_SIZE       0x00100000ULL
> >  #define MPC8544_MPIC_REGS_OFFSET   0x40000ULL
> >  #define MPC8544_MSI_REGS_OFFSET   0x41600ULL
> > @@ -856,6 +858,7 @@ void ppce500_init(MachineState *machine, PPCE500Params 
> > *params)
> >      object_property_add_child(qdev_get_machine(), "e500-ccsr",
> >                                OBJECT(dev), NULL);
> >      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);
> >  
> > diff --git a/hw/ppc/e500_ccsr.c b/hw/ppc/e500_ccsr.c
> > index 1b586c3f42..9400d7cf13 100644
> > --- a/hw/ppc/e500_ccsr.c
> > +++ b/hw/ppc/e500_ccsr.c
> > @@ -30,13 +30,26 @@
> >  #include "hw/sysbus.h"
> >  
> >  /* E500_ denotes registers common to all */
> > +/* Some CCSR offsets duplicated in e500.c */
> >  
> > +#define E500_CCSRBAR     (0)
> > +
> > +#define E500_CS0_BNDS    (0x2000)
> > +
> > +#define E500_CS0_CONFIG  (0x2080)
> > +
> > +#define E500_ERR_DETECT  (0x2e40)
> > +#define E500_ERR_DISABLE (0x2e44)
> > +
> > +#define E500_PORPLLSR    (0xE0000)
> >  #define E500_PVR         (0xE00A0)
> >  #define E500_SVR         (0xE00A4)
> >  
> >  #define MPC8544_RSTCR       (0xE00B0)
> >  #define MPC8544_RSTCR_RESET      (0x02)
> >  
> > +#define E500_MPIC_OFFSET   (0x40000ULL)
> > +
> >  typedef struct {
> >      /*< private >*/
> >      SysBusDevice parent_obj;
> > @@ -44,19 +57,59 @@ typedef struct {
> >  
> >      MemoryRegion iomem;
> >  
> > -    uint32_t defbase;
> > +    uint32_t defbase, base;
> > +    uint32_t ram_size;
> > +    uint32_t merrd;
> > +
> > +    uint32_t porpllsr;
> > +
> > +    DeviceState *pic;
> >  } CCSRState;
> >  
> >  #define TYPE_E500_CCSR "e500-ccsr"
> >  #define E500_CCSR(obj) OBJECT_CHECK(CCSRState, (obj), TYPE_E500_CCSR)
> >  
> > +/* call after changing CCSRState::base */
> > +static void e500_ccsr_post_move(CCSRState *ccsr)
> > +{
> > +    CPUState *cs;
> > +
> > +    CPU_FOREACH(cs) {
> > +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> > +        CPUPPCState *env = &cpu->env;
> > +
> > +        env->mpic_iack = ccsr->base +
> > +                         E500_MPIC_OFFSET + 0xa0;
> > +    }
> > +
> > +    sysbus_mmio_map(SYS_BUS_DEVICE(ccsr), 0, ccsr->base);
> > +}
> > +
> >  static uint64_t e500_ccsr_read(void *opaque, hwaddr addr,
> >                                    unsigned size)
> >  {
> > +    CCSRState *ccsr = opaque;
> >      PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
> >      CPUPPCState *env = &cpu->env;
> >  
> >      switch (addr) {
> > +    case E500_CCSRBAR:
> > +        return ccsr->base >> 12;
> > +    case E500_CS0_BNDS:
> > +        /* we model all RAM in a single chip with addresses [0, ram_size) 
> > */
> > +        return (ccsr->ram_size - 1) >> 24;
> > +    case E500_CS0_CONFIG:
> > +        return 1 << 31;
> > +    case E500_ERR_DETECT:
> > +        return 0; /* (errors not modeled) */
> > +    case E500_ERR_DISABLE:
> > +        return ccsr->merrd;
> > +    case E500_PORPLLSR:
> > +        if (!ccsr->porpllsr) {
> > +            qemu_log_mask(LOG_UNIMP,
> > +                          "Machine does not provide valid PORPLLSR\n");
> > +        }
> > +        return ccsr->porpllsr;
> >      case E500_PVR:
> >          return env->spr[SPR_PVR];
> >      case E500_SVR:
> > @@ -72,10 +125,22 @@ static uint64_t e500_ccsr_read(void *opaque, hwaddr 
> > addr,
> >  static void e500_ccsr_write(void *opaque, hwaddr addr,
> >                                 uint64_t value, unsigned size)
> >  {
> > +    CCSRState *ccsr = opaque;
> >      PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
> >      CPUPPCState *env = &cpu->env;
> >      uint32_t svr = env->spr[SPR_E500_SVR] >> 16;
> >  
> > +    switch (addr) {
> > +    case E500_CCSRBAR:
> > +        value &= 0x000fff00;
> > +        ccsr->base = value << 12;
> > +        e500_ccsr_post_move(ccsr);
> > +        return;
> > +    case E500_ERR_DISABLE:
> > +        ccsr->merrd = value & 0xd;
> > +        return;
> > +    }
> > +
> >      switch (svr) {
> >      case 0: /* generic.  assumed to be mpc8544ds or e500plat board */
> >      case 0x8034: /* mpc8544 */
> > @@ -104,11 +169,20 @@ static const MemoryRegionOps e500_ccsr_ops = {
> >      }
> >  };
> >  
> > +static int e500_ccsr_post_load(void *opaque, int version_id)
> > +{
> > +    CCSRState *ccsr = opaque;
> > +
> > +    e500_ccsr_post_move(ccsr);
> > +    return 0;
> > +}
> > +
> >  static void e500_ccsr_reset(DeviceState *dev)
> >  {
> >      CCSRState *ccsr = E500_CCSR(dev);
> >  
> > -    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ccsr->defbase);
> > +    ccsr->base = ccsr->defbase;
> > +    e500_ccsr_post_move(ccsr);
> >  }
> >  
> >  static void e500_ccsr_initfn(Object *obj)
> > @@ -123,15 +197,30 @@ static void e500_ccsr_initfn(Object *obj)
> >  
> >  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),
> >      DEFINE_PROP_END_OF_LIST()
> >  };
> >  
> > +static const VMStateDescription vmstate_e500_ccsr = {
> > +    .name = TYPE_E500_CCSR,
> > +    .version_id = 1,
> > +    .minimum_version_id = 1,
> > +    .post_load = e500_ccsr_post_load,
> > +    .fields = (VMStateField[]) {
> > +        VMSTATE_UINT32(base, CCSRState),
> > +        VMSTATE_UINT32(merrd, CCSRState),
> > +        VMSTATE_END_OF_LIST()
> > +    }
> > +};
> > +
> >  static
> >  void e500_ccsr_class_initfn(ObjectClass *klass, void *data)
> >  {
> >      DeviceClass *dc = DEVICE_CLASS(klass);
> >  
> >      dc->props = e500_ccsr_props;
> > +    dc->vmsd = &vmstate_e500_ccsr;
> >      dc->reset = e500_ccsr_reset;
> >  }
> >  
> 



-- 
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]