'virtm' is a hardware target that is designed to be used for compiler and library testing on Cortex-M processors. It supports all cortex-m processors and includes sufficient memory to run even large test cases.
Signed-off-by: Keith Packard <kei...@keithp.com> --- MAINTAINERS | 9 +++- hw/arm/Makefile.objs | 2 +- hw/arm/virtm.c | 112 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 hw/arm/virtm.c diff --git a/MAINTAINERS b/MAINTAINERS index 1b40446c73..4c7e394dd6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -850,9 +850,16 @@ Virt M: Peter Maydell <peter.mayd...@linaro.org> L: qemu-...@nongnu.org S: Maintained -F: hw/arm/virt* +F: hw/arm/virt.c +F: hw/arm/virt-acpi-build.c F: include/hw/arm/virt.h +Virt M +M: Keith Packard <kei...@keithp.com> +L: qemu-...@nongnu.org +S: Maintained +F: hw/arm/virtm.c + Xilinx Zynq M: Edgar E. Iglesias <edgar.igles...@gmail.com> M: Alistair Francis <alist...@alistair23.me> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 534a6a119e..54be15b40a 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -1,6 +1,6 @@ obj-y += boot.o obj-$(CONFIG_PLATFORM_BUS) += sysbus-fdt.o -obj-$(CONFIG_ARM_VIRT) += virt.o +obj-$(CONFIG_ARM_VIRT) += virt.o virtm.o obj-$(CONFIG_ACPI) += virt-acpi-build.o obj-$(CONFIG_DIGIC) += digic_boards.o obj-$(CONFIG_EXYNOS4) += exynos4_boards.o diff --git a/hw/arm/virtm.c b/hw/arm/virtm.c new file mode 100644 index 0000000000..beda3644f5 --- /dev/null +++ b/hw/arm/virtm.c @@ -0,0 +1,112 @@ +/* + * Virtual ARM Cortex M + * + * Copyright © 2020, Keith Packard <kei...@keithp.com> + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/arm/boot.h" +#include "hw/boards.h" +#include "exec/address-spaces.h" +#include "hw/arm/armv7m.h" +#include "hw/misc/unimp.h" +#include "cpu.h" + +#define NUM_IRQ_LINES 32 +#define ROM_BASE 0x00000000 +#define ROM_SIZE 0x20000000 +#define RAM_BASE 0x20000000 +#define RAM_SIZE 0x20000000 + +static const char *valid_cpus[] = { + ARM_CPU_TYPE_NAME("cortex-m0"), + ARM_CPU_TYPE_NAME("cortex-m3"), + ARM_CPU_TYPE_NAME("cortex-m33"), + ARM_CPU_TYPE_NAME("cortex-m4"), + ARM_CPU_TYPE_NAME("cortex-m7"), +}; + +static bool cpu_type_valid(const char *cpu) +{ + int i; + + return true; + for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) { + if (strcmp(cpu, valid_cpus[i]) == 0) { + return true; + } + } + return false; +} + +static void machvirtm_init(MachineState *ms) +{ + DeviceState *nvic; + + if (!cpu_type_valid(ms->cpu_type)) { + error_report("virtm: CPU type %s not supported", ms->cpu_type); + exit(1); + } + + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *rom = g_new(MemoryRegion, 1); + MemoryRegion *system_memory = get_system_memory(); + + /* Flash programming is done via the SCU, so pretend it is ROM. */ + memory_region_init_rom(rom, NULL, "virtm.rom", ROM_SIZE, + &error_fatal); + memory_region_add_subregion(system_memory, ROM_BASE, rom); + + memory_region_init_ram(ram, NULL, "virtm.ram", RAM_SIZE, + &error_fatal); + memory_region_add_subregion(system_memory, RAM_BASE, ram); + + nvic = qdev_new(TYPE_ARMV7M); + qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES); + qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type); + qdev_prop_set_bit(nvic, "enable-bitband", true); + object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()), + "memory", &error_abort); + /* This will exit with an error if the user passed us a bad cpu_type */ + sysbus_realize_and_unref(SYS_BUS_DEVICE(nvic), &error_fatal); + + armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, ROM_SIZE); +} + +static void virtm_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "Virtual Cortex-M"; + mc->init = machvirtm_init; + mc->ignore_memory_transaction_failures = true; + mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3"); +} + +static const TypeInfo virtm_type = { + .name = MACHINE_TYPE_NAME("virtm"), + .parent = TYPE_MACHINE, + .class_init = virtm_class_init, +}; + +static void virtm_machine_init(void) +{ + type_register_static(&virtm_type); +} + +type_init(virtm_machine_init) -- 2.27.0