Message ID | 20171120032420.9134-1-mdavidsaver@gmail.com |
---|---|
Headers | show |
Series | Add MVME3100 PPC SBC | expand |
On Sun, Nov 19, 2017 at 09:24:10PM -0600, Michael Davidsaver wrote: > Preparation for adding more MPCxxxx control > registers. > > Use e500 SVR to enable part specific registers. > Only the mpc8544 reset register at present. > > Expose CCSR as SysBusDevice region to eliminate > e500-ccsr.h. > > Track CCSR base address within device, and map on reset, > in preparation for CCSRBAR. > > Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com> Applied to ppc-for-2.12. > --- > hw/pci-host/ppce500.c | 10 ++-- > hw/ppc/Makefile.objs | 3 +- > hw/ppc/e500-ccsr.h | 17 ------ > hw/ppc/e500.c | 37 +----------- > hw/ppc/e500_ccsr.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++ > hw/ppc/mpc8544_guts.c | 143 ----------------------------------------------- > 6 files changed, 162 insertions(+), 200 deletions(-) > delete mode 100644 hw/ppc/e500-ccsr.h > create mode 100644 hw/ppc/e500_ccsr.c > delete mode 100644 hw/ppc/mpc8544_guts.c > > diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c > index 39cd24464d..f2d108bc8a 100644 > --- a/hw/pci-host/ppce500.c > +++ b/hw/pci-host/ppce500.c > @@ -16,7 +16,6 @@ > > #include "qemu/osdep.h" > #include "hw/hw.h" > -#include "hw/ppc/e500-ccsr.h" > #include "hw/pci/pci.h" > #include "hw/pci/pci_host.h" > #include "qemu/bswap.h" > @@ -420,16 +419,17 @@ static const VMStateDescription vmstate_ppce500_pci = { > static void e500_pcihost_bridge_realize(PCIDevice *d, Error **errp) > { > PPCE500PCIBridgeState *b = PPC_E500_PCI_BRIDGE(d); > - PPCE500CCSRState *ccsr = CCSR(container_get(qdev_get_machine(), > - "/e500-ccsr")); > + SysBusDevice *ccsr = SYS_BUS_DEVICE(container_get(qdev_get_machine(), > + "/e500-ccsr")); > + MemoryRegion *ccsr_mr = sysbus_mmio_get_region(ccsr, 0); > > pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI); > d->config[PCI_HEADER_TYPE] = > (d->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) | > PCI_HEADER_TYPE_BRIDGE; > > - memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0", &ccsr->ccsr_space, > - 0, int128_get64(ccsr->ccsr_space.size)); > + memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0", ccsr_mr, > + 0, memory_region_size(ccsr_mr)); > pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &b->bar0); > } > > diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs > index 7efc686748..c1a63d0c39 100644 > --- a/hw/ppc/Makefile.objs > +++ b/hw/ppc/Makefile.objs > @@ -24,6 +24,7 @@ obj-$(CONFIG_MAC) += mac_oldworld.o > obj-$(CONFIG_MAC) += mac_newworld.o > # e500 > obj-$(CONFIG_E500) += e500.o mpc8544ds.o e500plat.o > -obj-$(CONFIG_E500) += mpc8544_guts.o ppce500_spin.o > +obj-$(CONFIG_E500) += ppce500_spin.o > +obj-$(CONFIG_E500) += e500_ccsr.o > # PowerPC 440 Xilinx ML507 reference board. > obj-$(CONFIG_XILINX) += virtex_ml507.o > diff --git a/hw/ppc/e500-ccsr.h b/hw/ppc/e500-ccsr.h > deleted file mode 100644 > index 12a2ba4b97..0000000000 > --- a/hw/ppc/e500-ccsr.h > +++ /dev/null > @@ -1,17 +0,0 @@ > -#ifndef E500_CCSR_H > -#define E500_CCSR_H > - > -#include "hw/sysbus.h" > - > -typedef struct PPCE500CCSRState { > - /*< private >*/ > - SysBusDevice parent; > - /*< public >*/ > - > - MemoryRegion ccsr_space; > -} PPCE500CCSRState; > - > -#define TYPE_CCSR "e500-ccsr" > -#define CCSR(obj) OBJECT_CHECK(PPCE500CCSRState, (obj), TYPE_CCSR) > - > -#endif /* E500_CCSR_H */ > diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c > index 9e7e1b29c4..474a46a985 100644 > --- a/hw/ppc/e500.c > +++ b/hw/ppc/e500.c > @@ -15,10 +15,10 @@ > */ > > #include "qemu/osdep.h" > +#include "qemu/log.h" > #include "qapi/error.h" > #include "qemu-common.h" > #include "e500.h" > -#include "e500-ccsr.h" > #include "net/net.h" > #include "qemu/config-file.h" > #include "hw/hw.h" > @@ -795,7 +795,6 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) > CPUPPCState *firstenv = NULL; > MemoryRegion *ccsr_addr_space; > SysBusDevice *s; > - PPCE500CCSRState *ccsr; > > irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); > irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); > @@ -854,11 +853,9 @@ 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, "base", params->ccsrbar_base); > qdev_init_nofail(dev); > - ccsr = CCSR(dev); > - ccsr_addr_space = &ccsr->ccsr_space; > - memory_region_add_subregion(address_space_mem, params->ccsrbar_base, > - ccsr_addr_space); > + ccsr_addr_space = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); > > mpicdev = ppce500_init_mpic(machine, params, ccsr_addr_space, irqs); > > @@ -875,13 +872,6 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) > serial_hds[1], DEVICE_BIG_ENDIAN); > } > > - /* General Utility device */ > - dev = qdev_create(NULL, "mpc8544-guts"); > - qdev_init_nofail(dev); > - s = SYS_BUS_DEVICE(dev); > - memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET, > - sysbus_mmio_get_region(s, 0)); > - > /* PCI */ > dev = qdev_create(NULL, "e500-pcihost"); > qdev_prop_set_uint32(dev, "first_slot", params->pci_first_slot); > @@ -1039,24 +1029,3 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) > boot_info->dt_base = dt_base; > boot_info->dt_size = dt_size; > } > - > -static void e500_ccsr_initfn(Object *obj) > -{ > - PPCE500CCSRState *ccsr = CCSR(obj); > - memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr", > - MPC8544_CCSRBAR_SIZE); > -} > - > -static const TypeInfo e500_ccsr_info = { > - .name = TYPE_CCSR, > - .parent = TYPE_SYS_BUS_DEVICE, > - .instance_size = sizeof(PPCE500CCSRState), > - .instance_init = e500_ccsr_initfn, > -}; > - > -static void e500_register_types(void) > -{ > - type_register_static(&e500_ccsr_info); > -} > - > -type_init(e500_register_types) > diff --git a/hw/ppc/e500_ccsr.c b/hw/ppc/e500_ccsr.c > new file mode 100644 > index 0000000000..1b586c3f42 > --- /dev/null > +++ b/hw/ppc/e500_ccsr.c > @@ -0,0 +1,152 @@ > +/* > + * MPC8540 and MPC8544 specific control registers. > + * Not really part of e500 spec, but common to many > + * Freescale parts w/ e500 cores. > + * > + * Copyright (c) 2017 Michael Davidsaver > + * Copyright (C) 2011 Freescale Semiconductor, Inc. All rights reserved. > + * > + * Authors: Alexander Graf, <alex@csgraf.de> > + * Michael Davidsaver <mdavidsaver@gmail.com> > + * > + * This work is licensed under the terms of the GNU GPL, version 2. See > + * the LICENSE file in the top-level directory. > + * > + * This model was developed according to: > + * > + * MPC8544E PowerQUICC III Integrated Host Processor Family Reference Manual > + * Rev. 1 > + * > + * MPC8540 PowerQUICC III Integrated Host Processor Reference Manual, Rev. 1 > + */ > + > +#include "qemu/osdep.h" > +#include "qemu-common.h" > +#include "qemu/log.h" > +#include "qemu/error-report.h" > +#include "cpu.h" > +#include "hw/hw.h" > +#include "sysemu/sysemu.h" > +#include "hw/sysbus.h" > + > +/* E500_ denotes registers common to all */ > + > +#define E500_PVR (0xE00A0) > +#define E500_SVR (0xE00A4) > + > +#define MPC8544_RSTCR (0xE00B0) > +#define MPC8544_RSTCR_RESET (0x02) > + > +typedef struct { > + /*< private >*/ > + SysBusDevice parent_obj; > + /*< public >*/ > + > + MemoryRegion iomem; > + > + uint32_t defbase; > +} CCSRState; > + > +#define TYPE_E500_CCSR "e500-ccsr" > +#define E500_CCSR(obj) OBJECT_CHECK(CCSRState, (obj), TYPE_E500_CCSR) > + > +static uint64_t e500_ccsr_read(void *opaque, hwaddr addr, > + unsigned size) > +{ > + PowerPCCPU *cpu = POWERPC_CPU(current_cpu); > + CPUPPCState *env = &cpu->env; > + > + switch (addr) { > + case E500_PVR: > + return env->spr[SPR_PVR]; > + case E500_SVR: > + return env->spr[SPR_E500_SVR]; > + } > + > + qemu_log_mask(LOG_GUEST_ERROR | LOG_UNIMP, > + "can't read undefined ccsr regster %x\n", > + (unsigned)addr); > + return 0; > +} > + > +static void e500_ccsr_write(void *opaque, hwaddr addr, > + uint64_t value, unsigned size) > +{ > + PowerPCCPU *cpu = POWERPC_CPU(current_cpu); > + CPUPPCState *env = &cpu->env; > + uint32_t svr = env->spr[SPR_E500_SVR] >> 16; > + > + switch (svr) { > + case 0: /* generic. assumed to be mpc8544ds or e500plat board */ > + case 0x8034: /* mpc8544 */ > + case 0x803C: /* mpc8544E */ > + switch (addr) { > + case MPC8544_RSTCR: > + if (value & MPC8544_RSTCR_RESET) { > + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); > + } > + return; > + } > + } > + > + qemu_log_mask(LOG_GUEST_ERROR | LOG_UNIMP, > + "can't write undefined ccsr regster %x <- %08x\n", > + (unsigned)addr, (unsigned)value); > +} > + > +static const MemoryRegionOps e500_ccsr_ops = { > + .read = e500_ccsr_read, > + .write = e500_ccsr_write, > + .endianness = DEVICE_BIG_ENDIAN, > + .impl = { > + .min_access_size = 4, > + .max_access_size = 4, > + } > +}; > + > +static void e500_ccsr_reset(DeviceState *dev) > +{ > + CCSRState *ccsr = E500_CCSR(dev); > + > + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ccsr->defbase); > +} > + > +static void e500_ccsr_initfn(Object *obj) > +{ > + CCSRState *ccsr = E500_CCSR(obj); > + > + memory_region_init_io(&ccsr->iomem, obj, &e500_ccsr_ops, > + ccsr, "e500-ccsr", 1024 * 1024); > + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &ccsr->iomem); > + > +} > + > +static Property e500_ccsr_props[] = { > + DEFINE_PROP_UINT32("base", CCSRState, defbase, 0xff700000), > + DEFINE_PROP_END_OF_LIST() > +}; > + > +static > +void e500_ccsr_class_initfn(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->props = e500_ccsr_props; > + dc->reset = e500_ccsr_reset; > +} > + > +static const TypeInfo e500_ccsr_info = { > + .name = TYPE_E500_CCSR, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(CCSRState), > + .instance_init = e500_ccsr_initfn, > + .class_size = sizeof(SysBusDeviceClass), > + .class_init = e500_ccsr_class_initfn > +}; > + > +static void e500_ccsr_register_types(void) > +{ > + type_register_static(&e500_ccsr_info); > +} > + > +type_init(e500_ccsr_register_types) > diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c > deleted file mode 100644 > index ce1254b5d4..0000000000 > --- a/hw/ppc/mpc8544_guts.c > +++ /dev/null > @@ -1,143 +0,0 @@ > -/* > - * QEMU PowerPC MPC8544 global util pseudo-device > - * > - * Copyright (C) 2011 Freescale Semiconductor, Inc. All rights reserved. > - * > - * Author: Alexander Graf, <alex@csgraf.de> > - * > - * This is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 of the License, or > - * (at your option) any later version. > - * > - * ***************************************************************** > - * > - * The documentation for this device is noted in the MPC8544 documentation, > - * file name "MPC8544ERM.pdf". You can easily find it on the web. > - * > - */ > - > -#include "qemu/osdep.h" > -#include "qemu-common.h" > -#include "cpu.h" > -#include "hw/hw.h" > -#include "sysemu/sysemu.h" > -#include "hw/sysbus.h" > - > -#define MPC8544_GUTS_MMIO_SIZE 0x1000 > -#define MPC8544_GUTS_RSTCR_RESET 0x02 > - > -#define MPC8544_GUTS_ADDR_PORPLLSR 0x00 > -#define MPC8544_GUTS_ADDR_PORBMSR 0x04 > -#define MPC8544_GUTS_ADDR_PORIMPSCR 0x08 > -#define MPC8544_GUTS_ADDR_PORDEVSR 0x0C > -#define MPC8544_GUTS_ADDR_PORDBGMSR 0x10 > -#define MPC8544_GUTS_ADDR_PORDEVSR2 0x14 > -#define MPC8544_GUTS_ADDR_GPPORCR 0x20 > -#define MPC8544_GUTS_ADDR_GPIOCR 0x30 > -#define MPC8544_GUTS_ADDR_GPOUTDR 0x40 > -#define MPC8544_GUTS_ADDR_GPINDR 0x50 > -#define MPC8544_GUTS_ADDR_PMUXCR 0x60 > -#define MPC8544_GUTS_ADDR_DEVDISR 0x70 > -#define MPC8544_GUTS_ADDR_POWMGTCSR 0x80 > -#define MPC8544_GUTS_ADDR_MCPSUMR 0x90 > -#define MPC8544_GUTS_ADDR_RSTRSCR 0x94 > -#define MPC8544_GUTS_ADDR_PVR 0xA0 > -#define MPC8544_GUTS_ADDR_SVR 0xA4 > -#define MPC8544_GUTS_ADDR_RSTCR 0xB0 > -#define MPC8544_GUTS_ADDR_IOVSELSR 0xC0 > -#define MPC8544_GUTS_ADDR_DDRCSR 0xB20 > -#define MPC8544_GUTS_ADDR_DDRCDR 0xB24 > -#define MPC8544_GUTS_ADDR_DDRCLKDR 0xB28 > -#define MPC8544_GUTS_ADDR_CLKOCR 0xE00 > -#define MPC8544_GUTS_ADDR_SRDS1CR1 0xF04 > -#define MPC8544_GUTS_ADDR_SRDS2CR1 0xF10 > -#define MPC8544_GUTS_ADDR_SRDS2CR3 0xF18 > - > -#define TYPE_MPC8544_GUTS "mpc8544-guts" > -#define MPC8544_GUTS(obj) OBJECT_CHECK(GutsState, (obj), TYPE_MPC8544_GUTS) > - > -struct GutsState { > - /*< private >*/ > - SysBusDevice parent_obj; > - /*< public >*/ > - > - MemoryRegion iomem; > -}; > - > -typedef struct GutsState GutsState; > - > -static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr, > - unsigned size) > -{ > - uint32_t value = 0; > - PowerPCCPU *cpu = POWERPC_CPU(current_cpu); > - CPUPPCState *env = &cpu->env; > - > - addr &= MPC8544_GUTS_MMIO_SIZE - 1; > - switch (addr) { > - case MPC8544_GUTS_ADDR_PVR: > - value = env->spr[SPR_PVR]; > - break; > - case MPC8544_GUTS_ADDR_SVR: > - value = env->spr[SPR_E500_SVR]; > - break; > - default: > - fprintf(stderr, "guts: Unknown register read: %x\n", (int)addr); > - break; > - } > - > - return value; > -} > - > -static void mpc8544_guts_write(void *opaque, hwaddr addr, > - uint64_t value, unsigned size) > -{ > - addr &= MPC8544_GUTS_MMIO_SIZE - 1; > - > - switch (addr) { > - case MPC8544_GUTS_ADDR_RSTCR: > - if (value & MPC8544_GUTS_RSTCR_RESET) { > - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); > - } > - break; > - default: > - fprintf(stderr, "guts: Unknown register write: %x = %x\n", > - (int)addr, (unsigned)value); > - break; > - } > -} > - > -static const MemoryRegionOps mpc8544_guts_ops = { > - .read = mpc8544_guts_read, > - .write = mpc8544_guts_write, > - .endianness = DEVICE_BIG_ENDIAN, > - .valid = { > - .min_access_size = 4, > - .max_access_size = 4, > - }, > -}; > - > -static void mpc8544_guts_initfn(Object *obj) > -{ > - SysBusDevice *d = SYS_BUS_DEVICE(obj); > - GutsState *s = MPC8544_GUTS(obj); > - > - memory_region_init_io(&s->iomem, OBJECT(s), &mpc8544_guts_ops, s, > - "mpc8544.guts", MPC8544_GUTS_MMIO_SIZE); > - sysbus_init_mmio(d, &s->iomem); > -} > - > -static const TypeInfo mpc8544_guts_info = { > - .name = TYPE_MPC8544_GUTS, > - .parent = TYPE_SYS_BUS_DEVICE, > - .instance_size = sizeof(GutsState), > - .instance_init = mpc8544_guts_initfn, > -}; > - > -static void mpc8544_guts_register_types(void) > -{ > - type_register_static(&mpc8544_guts_info); > -} > - > -type_init(mpc8544_guts_register_types)
On Sun, Nov 19, 2017 at 09:24:08PM -0600, Michael Davidsaver wrote: > This series adds simulation of MVME3100 powerpc SBCs, originally from Motorola, > and now sold by Artesyn[1]. There are two variants differing in CPU > speed and memory size. > > I've been working on this sporadically for the past 2 year. Recently I've > finished all the features which I have in mind. If this series is accepted > there is a continuation which adds VME bus. I've found it > useful in software compatibility testing. I wonder if there is > any interest at large? > > > There are two main parts of this series. 1-5 are changing code common > with the "ppce500" and "mpc8544ds" boards, with the remainder being > additions. > > The changes are to how the CCSR region is handled in order to support > the CCSRBAR register which allows the whole region to be relocated. > Also added are a couple of memory and clock configuration registers > which RTEMS guests read. > > #3 is actually a minor issue I found recently with the mpc8544 PCI host bridge, > which I'm uncertain how to address. The host bridge device 0:0 identifies > itself as a bridge, but doesn't properly implement the bridge config registers. > This confuses Linux, which then does a full re-enumeration (successfully). > > The rest are additions of an I2C controller, an I2C eeprom, an I2C RTC, > and new board code. > > My testing has been almost exclusively with an RTEMS guest[2]. > Though I have recently done a little with Linux. > > RTEMS guests (and Linux too for now) require a stub bootloader[3] to > put the system in the same state as the real bootloader. > RTEMS has an unfortunately strong dependence on bootloader > provided configuration (eg. it doesn't re-enumerate the PCI bus). I've applied several patches from this series to ppc-for-2.12, others I've commented on. If you could address the comments and rebase what's left on ppc-for-2.12, that would be great.
On 11/21/2017 10:12 PM, David Gibson wrote: ... > I've applied several patches from this series to ppc-for-2.12, others > I've commented on. If you could address the comments and rebase > what's left on ppc-for-2.12, that would be great. Will do.
On Wed, Nov 22, 2017 at 02:36:43PM +1100, David Gibson wrote: > On Sun, Nov 19, 2017 at 09:24:10PM -0600, Michael Davidsaver wrote: > > Preparation for adding more MPCxxxx control > > registers. > > > > Use e500 SVR to enable part specific registers. > > Only the mpc8544 reset register at present. > > > > Expose CCSR as SysBusDevice region to eliminate > > e500-ccsr.h. > > > > Track CCSR base address within device, and map on reset, > > in preparation for CCSRBAR. > > > > Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com> > > Applied to ppc-for-2.12. Sorry. I've now pulled this from ppc-for-2.12, because it caused a breakage of make check (specifically the boot-serial-test with ppc64).
On 12/05/2017 10:12 PM, David Gibson wrote: > On Wed, Nov 22, 2017 at 02:36:43PM +1100, David Gibson wrote: >> On Sun, Nov 19, 2017 at 09:24:10PM -0600, Michael Davidsaver wrote: >>> Preparation for adding more MPCxxxx control >>> registers. >>> >>> Use e500 SVR to enable part specific registers. >>> Only the mpc8544 reset register at present. >>> >>> Expose CCSR as SysBusDevice region to eliminate >>> e500-ccsr.h. >>> >>> Track CCSR base address within device, and map on reset, >>> in preparation for CCSRBAR. >>> >>> Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com> >> >> Applied to ppc-for-2.12. > > Sorry. I've now pulled this from ppc-for-2.12, because it caused a > breakage of make check (specifically the boot-serial-test with ppc64). Oops, I'll begin running this test myself. So far I've only been running tests for i386, amd64, arm, and ppc.
On Tue, Dec 05, 2017 at 10:18:56PM -0500, Michael Davidsaver wrote: > On 12/05/2017 10:12 PM, David Gibson wrote: > > On Wed, Nov 22, 2017 at 02:36:43PM +1100, David Gibson wrote: > >> On Sun, Nov 19, 2017 at 09:24:10PM -0600, Michael Davidsaver wrote: > >>> Preparation for adding more MPCxxxx control > >>> registers. > >>> > >>> Use e500 SVR to enable part specific registers. > >>> Only the mpc8544 reset register at present. > >>> > >>> Expose CCSR as SysBusDevice region to eliminate > >>> e500-ccsr.h. > >>> > >>> Track CCSR base address within device, and map on reset, > >>> in preparation for CCSRBAR. > >>> > >>> Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com> > >> > >> Applied to ppc-for-2.12. > > > > Sorry. I've now pulled this from ppc-for-2.12, because it caused a > > breakage of make check (specifically the boot-serial-test with ppc64). > > Oops, I'll begin running this test myself. So far I've only been running > tests for i386, amd64, arm, and ppc. I really recommend running a build and make check smoke test for all targets ("./configure && make && make check SPEED=slow") before posting patches for submission. It takes a while, but not stupidly long.