I am a bit against the merge of AHB and APB initialization into the same function. A grlib system can have any number of AHB and APB buses, so there really should be a separate init routine per bus as in the original patch.
Jiri. On 10/09/2014 01:05 PM, Fabien Chouteau wrote: > From: Jiri Gaisler <j...@gaisler.se> > > AMBA plug&play is used by kernels to probe available devices (Timers, > UART, etc...). This is a static declaration of devices implemented in > QEMU. In the future, a more advanced version could compute those > information directly from the device tree. > > Signed-off-by: Fabien Chouteau <chout...@adacore.com> > --- > > V2: > - AHB and APB PNP are now grouped in one device > - Initialisation moved to .instance_init > - Minor fixes > > hw/sparc/Makefile.objs | 1 + > hw/sparc/grlib_ambapnp.c | 149 > ++++++++++++++++++++++++++++++++++++++++++++++ > hw/sparc/leon3.c | 3 + > include/hw/sparc/grlib.h | 22 +++++++ > 4 files changed, 175 insertions(+) > create mode 100644 hw/sparc/grlib_ambapnp.c > > diff --git a/hw/sparc/Makefile.objs b/hw/sparc/Makefile.objs > index c987b5b..e763701 100644 > --- a/hw/sparc/Makefile.objs > +++ b/hw/sparc/Makefile.objs > @@ -1 +1,2 @@ > obj-y += sun4m.o leon3.o > +obj-$(CONFIG_GRLIB) += grlib_ambapnp.o > diff --git a/hw/sparc/grlib_ambapnp.c b/hw/sparc/grlib_ambapnp.c > new file mode 100644 > index 0000000..dd53004 > --- /dev/null > +++ b/hw/sparc/grlib_ambapnp.c > @@ -0,0 +1,149 @@ > +/* > + * QEMU GRLIB AMBA Plug&Play Emulator > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > copy > + * of this software and associated documentation files (the "Software"), to > deal > + * in the Software without restriction, including without limitation the > rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > + * THE SOFTWARE. > + */ > + > +#include "hw/sysbus.h" > +#include "hw/sparc/grlib.h" > + > +/* Size of memory mapped registers */ > +#define APBPNP_REG_SIZE (4096 - 8) > +#define AHBPNP_REG_SIZE 4096 > + > +#define GRLIB_AMBA_PNP(obj) \ > + OBJECT_CHECK(AMBAPNP, (obj), TYPE_GRLIB_AMBA_PNP) > + > +typedef struct AMBAPNP { > + SysBusDevice parent_obj; > + MemoryRegion ahb_iomem; > + MemoryRegion apb_iomem; > +} AMBAPNP; > + > +/* APB PNP */ > + > +static uint64_t grlib_apbpnp_read(void *opaque, hwaddr addr, > + unsigned size) > +{ > + uint64_t read_data; > + addr &= 0xfff; > + > + /* Unit registers */ > + switch (addr & 0xffc) { > + case 0x00: > + read_data = 0x0400f000; /* Memory controller */ > + break; > + case 0x04: > + read_data = 0x0000fff1; > + break; > + case 0x08: > + read_data = 0x0100c023; /* APBUART */ > + break; > + case 0x0C: > + read_data = 0x0010fff1; > + break; > + case 0x10: > + read_data = 0x0100d040; /* IRQMP */ > + break; > + case 0x14: > + read_data = 0x0020fff1; > + break; > + case 0x18: > + read_data = 0x01011006; /* GPTIMER */ > + break; > + case 0x1C: > + read_data = 0x0030fff1; > + break; > + > + default: > + read_data = 0; > + } > + if (size == 1) { > + read_data >>= (24 - (addr & 3) * 8); > + read_data &= 0x0ff; > + } > + return read_data; > +} > + > +static const MemoryRegionOps grlib_apbpnp_ops = { > + .read = grlib_apbpnp_read, > + .endianness = DEVICE_NATIVE_ENDIAN, > +}; > + > +/* AHB PNP */ > + > +static uint64_t grlib_ahbpnp_read(void *opaque, hwaddr addr, > + unsigned size) > +{ > + addr &= 0xffc; > + > + /* Unit registers */ > + switch (addr) { > + case 0: > + return 0x01003000; /* LEON3 */ > + case 0x800: > + return 0x0400f000; /* Memory controller */ > + case 0x810: > + return 0x0003e002; > + case 0x814: > + return 0x2000e002; > + case 0x818: > + return 0x4003c002; > + case 0x820: > + return 0x01006000; /* APB bridge @ 0x80000000 */ > + case 0x830: > + return 0x8000fff2; > + > + default: > + return 0; > + } > +} > + > +static const MemoryRegionOps grlib_ahbpnp_ops = { > + .read = grlib_ahbpnp_read, > + .endianness = DEVICE_NATIVE_ENDIAN, > +}; > + > +static void grlib_ambapnp_init(Object *obj) > +{ > + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); > + AMBAPNP *pnp = GRLIB_AMBA_PNP(obj); > + > + memory_region_init_io(&pnp->ahb_iomem, OBJECT(pnp), &grlib_ahbpnp_ops, > pnp, > + "ahbpnp", AHBPNP_REG_SIZE); > + sysbus_init_mmio(sbd, &pnp->ahb_iomem); > + > + memory_region_init_io(&pnp->apb_iomem, OBJECT(pnp), &grlib_apbpnp_ops, > pnp, > + "apbpnp", APBPNP_REG_SIZE); > + sysbus_init_mmio(sbd, &pnp->apb_iomem); > +} > + > +static const TypeInfo grlib_ambapnp_info = { > + .name = TYPE_GRLIB_AMBA_PNP, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(AMBAPNP), > + .instance_init = grlib_ambapnp_init, > +}; > + > +static void grlib_ambapnp_register_types(void) > +{ > + type_register_static(&grlib_ambapnp_info); > +} > + > +type_init(grlib_ambapnp_register_types) > diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c > index 751392e..2962539 100644 > --- a/hw/sparc/leon3.c > +++ b/hw/sparc/leon3.c > @@ -207,6 +207,9 @@ static void leon3_generic_hw_init(MachineState *machine) > } > } > > + /* Allocate AHB/APB PNP */ > + grlib_ambapnp_create(0xFFFFF000 /* AHB */, 0x800FF000 /* APB */); > + > /* Allocate timers */ > grlib_gptimer_create(0x80000300, 2, CPU_CLK, cpu_irqs, 6); > > diff --git a/include/hw/sparc/grlib.h b/include/hw/sparc/grlib.h > index 470ce72..5c098df 100644 > --- a/include/hw/sparc/grlib.h > +++ b/include/hw/sparc/grlib.h > @@ -123,4 +123,26 @@ DeviceState *grlib_apbuart_create(hwaddr base, > return dev; > } > > + > +/* AMBA PNP */ > + > +#define TYPE_GRLIB_AMBA_PNP "grlib,ambapnp" > + > +static inline > +DeviceState *grlib_ambapnp_create(hwaddr ahbpnp_base, hwaddr apbpnp_base) > +{ > + DeviceState *dev; > + > + dev = qdev_create(NULL, TYPE_GRLIB_AMBA_PNP); > + > + if (qdev_init(dev)) { > + return NULL; > + } > + > + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ahbpnp_base); > + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, apbpnp_base); > + > + return dev; > +} > + > #endif /* ! _GRLIB_H_ */ >