Message ID | 20200709003608.3834629-9-hskinnemoen@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add Nuvoton NPCM730/NPCM750 SoCs and two BMC machines | expand |
On 7/9/20 2:36 AM, Havard Skinnemoen wrote: > This just implements the bare minimum to cause the boot block to skip > memory initialization. > > Reviewed-by: Tyrone Ting <kfting@nuvoton.com> > Reviewed-by: Cédric Le Goater <clg@kaod.org> > Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com> > --- > include/hw/arm/npcm7xx.h | 2 + > include/hw/mem/npcm7xx_mc.h | 36 ++++++++++++++++ > hw/arm/npcm7xx.c | 6 +++ > hw/mem/npcm7xx_mc.c | 84 +++++++++++++++++++++++++++++++++++++ > hw/mem/Makefile.objs | 1 + > 5 files changed, 129 insertions(+) > create mode 100644 include/hw/mem/npcm7xx_mc.h > create mode 100644 hw/mem/npcm7xx_mc.c > > diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h > index 0fd4ae4133..3ae9e5dca2 100644 > --- a/include/hw/arm/npcm7xx.h > +++ b/include/hw/arm/npcm7xx.h > @@ -18,6 +18,7 @@ > > #include "hw/boards.h" > #include "hw/cpu/a9mpcore.h" > +#include "hw/mem/npcm7xx_mc.h" > #include "hw/misc/npcm7xx_clk.h" > #include "hw/misc/npcm7xx_gcr.h" > #include "hw/nvram/npcm7xx_otp.h" > @@ -71,6 +72,7 @@ typedef struct NPCM7xxState { > NPCM7xxTimerCtrlState tim[3]; > NPCM7xxOTPState key_storage; > NPCM7xxOTPState fuse_array; > + NPCM7xxMCState mc; > } NPCM7xxState; > > #define TYPE_NPCM7XX "npcm7xx" > diff --git a/include/hw/mem/npcm7xx_mc.h b/include/hw/mem/npcm7xx_mc.h > new file mode 100644 > index 0000000000..7ed38be243 > --- /dev/null > +++ b/include/hw/mem/npcm7xx_mc.h > @@ -0,0 +1,36 @@ > +/* > + * Nuvoton NPCM7xx Memory Controller stub > + * > + * Copyright 2020 Google LLC > + * > + * This program 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. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > + * for more details. > + */ > +#ifndef NPCM7XX_MC_H > +#define NPCM7XX_MC_H > + > +#include "exec/memory.h" > +#include "hw/sysbus.h" > + > +/** > + * struct NPCM7xxMCState - Device state for the memory controller. > + * @parent: System bus device. > + * @mmio: Memory region through which registers are accessed. > + */ > +typedef struct NPCM7xxMCState { > + SysBusDevice parent; > + > + MemoryRegion mmio; > +} NPCM7xxMCState; > + > +#define TYPE_NPCM7XX_MC "npcm7xx-mc" > +#define NPCM7XX_MC(obj) OBJECT_CHECK(NPCM7xxMCState, (obj), TYPE_NPCM7XX_MC) > + > +#endif /* NPCM7XX_MC_H */ > diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c > index 70eaa2347f..4d227bb74b 100644 > --- a/hw/arm/npcm7xx.c > +++ b/hw/arm/npcm7xx.c > @@ -42,6 +42,7 @@ > #define NPCM7XX_CPUP_BA (0xf03fe000) > #define NPCM7XX_GCR_BA (0xf0800000) > #define NPCM7XX_CLK_BA (0xf0801000) > +#define NPCM7XX_MC_BA (0xf0824000) > > /* Internal AHB SRAM */ > #define NPCM7XX_RAM3_BA (0xc0008000) > @@ -165,6 +166,7 @@ static void npcm7xx_init(Object *obj) > TYPE_NPCM7XX_KEY_STORAGE); > object_initialize_child(obj, "otp2", &s->fuse_array, > TYPE_NPCM7XX_FUSE_ARRAY); > + object_initialize_child(obj, "mc", &s->mc, TYPE_NPCM7XX_MC); > > for (i = 0; i < ARRAY_SIZE(s->tim); i++) { > object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER); > @@ -230,6 +232,10 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) > sysbus_mmio_map(SYS_BUS_DEVICE(&s->fuse_array), 0, NPCM7XX_OTP2_BA); > npcm7xx_init_fuses(s); > > + /* Fake Memory Controller (MC) */ > + sysbus_realize(SYS_BUS_DEVICE(&s->mc), &error_abort); > + sysbus_mmio_map(SYS_BUS_DEVICE(&s->mc), 0, NPCM7XX_MC_BA); > + > /* Timer Modules (TIM) */ > QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim)); > for (i = 0; i < ARRAY_SIZE(s->tim); i++) { > diff --git a/hw/mem/npcm7xx_mc.c b/hw/mem/npcm7xx_mc.c > new file mode 100644 > index 0000000000..0435d06ab4 > --- /dev/null > +++ b/hw/mem/npcm7xx_mc.c > @@ -0,0 +1,84 @@ > +/* > + * Nuvoton NPCM7xx Memory Controller stub > + * > + * Copyright 2020 Google LLC > + * > + * This program 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. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > + * for more details. > + */ > + > +#include "qemu/osdep.h" > + > +#include "hw/mem/npcm7xx_mc.h" > +#include "qapi/error.h" > +#include "qemu/log.h" > +#include "qemu/module.h" > +#include "qemu/units.h" > + > +#define NPCM7XX_MC_REGS_SIZE (4 * KiB) > + > +static uint64_t npcm7xx_mc_read(void *opaque, hwaddr addr, unsigned int size) > +{ > + /* > + * If bits 8..11 @ offset 0 are not zero, the boot block thinks the memory > + * controller has already been initialized and will skip DDR training. > + */ > + if (addr == 0) { > + return 0x100; Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> > + } > + > + qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__); > + > + return 0; > +} > + > +static void npcm7xx_mc_write(void *opaque, hwaddr addr, uint64_t v, > + unsigned int size) > +{ > + qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__); > +} > + > +static const MemoryRegionOps npcm7xx_mc_ops = { > + .read = npcm7xx_mc_read, > + .write = npcm7xx_mc_write, > + .endianness = DEVICE_LITTLE_ENDIAN, > + .valid = { > + .min_access_size = 4, > + .max_access_size = 4, > + .unaligned = false, > + }, > +}; > + > +static void npcm7xx_mc_realize(DeviceState *dev, Error **errp) > +{ > + NPCM7xxMCState *s = NPCM7XX_MC(dev); > + > + memory_region_init_io(&s->mmio, OBJECT(s), &npcm7xx_mc_ops, s, "regs", > + NPCM7XX_MC_REGS_SIZE); > + sysbus_init_mmio(&s->parent, &s->mmio); > +} > + > +static void npcm7xx_mc_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->desc = "NPCM7xx Memory Controller stub"; > + dc->realize = npcm7xx_mc_realize; > +} > + > +static const TypeInfo npcm7xx_mc_types[] = { > + { > + .name = TYPE_NPCM7XX_MC, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(NPCM7xxMCState), > + .class_init = npcm7xx_mc_class_init, > + }, > +}; > +DEFINE_TYPES(npcm7xx_mc_types); > diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs > index 56345befd0..9a33ef7b35 100644 > --- a/hw/mem/Makefile.objs > +++ b/hw/mem/Makefile.objs > @@ -1,3 +1,4 @@ > common-obj-$(CONFIG_DIMM) += pc-dimm.o > common-obj-y += memory-device.o > +common-obj-$(CONFIG_NPCM7XX) += npcm7xx_mc.o > common-obj-$(CONFIG_NVDIMM) += nvdimm.o >
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h index 0fd4ae4133..3ae9e5dca2 100644 --- a/include/hw/arm/npcm7xx.h +++ b/include/hw/arm/npcm7xx.h @@ -18,6 +18,7 @@ #include "hw/boards.h" #include "hw/cpu/a9mpcore.h" +#include "hw/mem/npcm7xx_mc.h" #include "hw/misc/npcm7xx_clk.h" #include "hw/misc/npcm7xx_gcr.h" #include "hw/nvram/npcm7xx_otp.h" @@ -71,6 +72,7 @@ typedef struct NPCM7xxState { NPCM7xxTimerCtrlState tim[3]; NPCM7xxOTPState key_storage; NPCM7xxOTPState fuse_array; + NPCM7xxMCState mc; } NPCM7xxState; #define TYPE_NPCM7XX "npcm7xx" diff --git a/include/hw/mem/npcm7xx_mc.h b/include/hw/mem/npcm7xx_mc.h new file mode 100644 index 0000000000..7ed38be243 --- /dev/null +++ b/include/hw/mem/npcm7xx_mc.h @@ -0,0 +1,36 @@ +/* + * Nuvoton NPCM7xx Memory Controller stub + * + * Copyright 2020 Google LLC + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#ifndef NPCM7XX_MC_H +#define NPCM7XX_MC_H + +#include "exec/memory.h" +#include "hw/sysbus.h" + +/** + * struct NPCM7xxMCState - Device state for the memory controller. + * @parent: System bus device. + * @mmio: Memory region through which registers are accessed. + */ +typedef struct NPCM7xxMCState { + SysBusDevice parent; + + MemoryRegion mmio; +} NPCM7xxMCState; + +#define TYPE_NPCM7XX_MC "npcm7xx-mc" +#define NPCM7XX_MC(obj) OBJECT_CHECK(NPCM7xxMCState, (obj), TYPE_NPCM7XX_MC) + +#endif /* NPCM7XX_MC_H */ diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index 70eaa2347f..4d227bb74b 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -42,6 +42,7 @@ #define NPCM7XX_CPUP_BA (0xf03fe000) #define NPCM7XX_GCR_BA (0xf0800000) #define NPCM7XX_CLK_BA (0xf0801000) +#define NPCM7XX_MC_BA (0xf0824000) /* Internal AHB SRAM */ #define NPCM7XX_RAM3_BA (0xc0008000) @@ -165,6 +166,7 @@ static void npcm7xx_init(Object *obj) TYPE_NPCM7XX_KEY_STORAGE); object_initialize_child(obj, "otp2", &s->fuse_array, TYPE_NPCM7XX_FUSE_ARRAY); + object_initialize_child(obj, "mc", &s->mc, TYPE_NPCM7XX_MC); for (i = 0; i < ARRAY_SIZE(s->tim); i++) { object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER); @@ -230,6 +232,10 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->fuse_array), 0, NPCM7XX_OTP2_BA); npcm7xx_init_fuses(s); + /* Fake Memory Controller (MC) */ + sysbus_realize(SYS_BUS_DEVICE(&s->mc), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->mc), 0, NPCM7XX_MC_BA); + /* Timer Modules (TIM) */ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim)); for (i = 0; i < ARRAY_SIZE(s->tim); i++) { diff --git a/hw/mem/npcm7xx_mc.c b/hw/mem/npcm7xx_mc.c new file mode 100644 index 0000000000..0435d06ab4 --- /dev/null +++ b/hw/mem/npcm7xx_mc.c @@ -0,0 +1,84 @@ +/* + * Nuvoton NPCM7xx Memory Controller stub + * + * Copyright 2020 Google LLC + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "qemu/osdep.h" + +#include "hw/mem/npcm7xx_mc.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/units.h" + +#define NPCM7XX_MC_REGS_SIZE (4 * KiB) + +static uint64_t npcm7xx_mc_read(void *opaque, hwaddr addr, unsigned int size) +{ + /* + * If bits 8..11 @ offset 0 are not zero, the boot block thinks the memory + * controller has already been initialized and will skip DDR training. + */ + if (addr == 0) { + return 0x100; + } + + qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__); + + return 0; +} + +static void npcm7xx_mc_write(void *opaque, hwaddr addr, uint64_t v, + unsigned int size) +{ + qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__); +} + +static const MemoryRegionOps npcm7xx_mc_ops = { + .read = npcm7xx_mc_read, + .write = npcm7xx_mc_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + .unaligned = false, + }, +}; + +static void npcm7xx_mc_realize(DeviceState *dev, Error **errp) +{ + NPCM7xxMCState *s = NPCM7XX_MC(dev); + + memory_region_init_io(&s->mmio, OBJECT(s), &npcm7xx_mc_ops, s, "regs", + NPCM7XX_MC_REGS_SIZE); + sysbus_init_mmio(&s->parent, &s->mmio); +} + +static void npcm7xx_mc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->desc = "NPCM7xx Memory Controller stub"; + dc->realize = npcm7xx_mc_realize; +} + +static const TypeInfo npcm7xx_mc_types[] = { + { + .name = TYPE_NPCM7XX_MC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(NPCM7xxMCState), + .class_init = npcm7xx_mc_class_init, + }, +}; +DEFINE_TYPES(npcm7xx_mc_types); diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs index 56345befd0..9a33ef7b35 100644 --- a/hw/mem/Makefile.objs +++ b/hw/mem/Makefile.objs @@ -1,3 +1,4 @@ common-obj-$(CONFIG_DIMM) += pc-dimm.o common-obj-y += memory-device.o +common-obj-$(CONFIG_NPCM7XX) += npcm7xx_mc.o common-obj-$(CONFIG_NVDIMM) += nvdimm.o