#include "qemu/osdep.h"
#include "hw/arm/armv7m.h"
#include "qapi/error.h"
-#include "qemu-common.h"
#include "cpu.h"
#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
+#include "hw/arm/boot.h"
#include "hw/loader.h"
+#include "hw/qdev-properties.h"
#include "elf.h"
#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
#include "qemu/error-report.h"
+#include "qemu/module.h"
#include "exec/address-spaces.h"
+#include "target/arm/idau.h"
/* Bitbanded IO. Each word corresponds to a single bit. */
memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
- object_initialize(&s->nvic, sizeof(s->nvic), TYPE_NVIC);
- qdev_set_parent_bus(DEVICE(&s->nvic), sysbus_get_default());
+ sysbus_init_child_obj(obj, "nvnic", &s->nvic, sizeof(s->nvic), TYPE_NVIC);
object_property_add_alias(obj, "num-irq",
- OBJECT(&s->nvic), "num-irq", &error_abort);
+ OBJECT(&s->nvic), "num-irq");
for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
- object_initialize(&s->bitband[i], sizeof(s->bitband[i]), TYPE_BITBAND);
- qdev_set_parent_bus(DEVICE(&s->bitband[i]), sysbus_get_default());
+ sysbus_init_child_obj(obj, "bitband[*]", &s->bitband[i],
+ sizeof(s->bitband[i]), TYPE_BITBAND);
}
}
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
- s->cpu = ARM_CPU(object_new(s->cpu_type));
+ s->cpu = ARM_CPU(object_new_with_props(s->cpu_type, OBJECT(s), "cpu",
+ &err, NULL));
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory",
&error_abort);
+ if (object_property_find(OBJECT(s->cpu), "idau", NULL)) {
+ object_property_set_link(OBJECT(s->cpu), s->idau, "idau", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+ if (object_property_find(OBJECT(s->cpu), "init-svtor", NULL)) {
+ object_property_set_uint(OBJECT(s->cpu), s->init_svtor,
+ "init-svtor", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+ if (object_property_find(OBJECT(s->cpu), "start-powered-off", NULL)) {
+ object_property_set_bool(OBJECT(s->cpu), s->start_powered_off,
+ "start-powered-off", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+ if (object_property_find(OBJECT(s->cpu), "vfp", NULL)) {
+ object_property_set_bool(OBJECT(s->cpu), s->vfp,
+ "vfp", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+ if (object_property_find(OBJECT(s->cpu), "dsp", NULL)) {
+ object_property_set_bool(OBJECT(s->cpu), s->dsp,
+ "dsp", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+
+ /*
+ * Tell the CPU where the NVIC is; it will fail realize if it doesn't
+ * have one. Similarly, tell the NVIC where its CPU is.
+ */
+ s->cpu->env.nvic = &s->nvic;
+ s->nvic.cpu = s->cpu;
+
object_property_set_bool(OBJECT(s->cpu), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
*/
qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
+ qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");
/* Wire the NVIC up to the CPU */
sbd = SYS_BUS_DEVICE(&s->nvic);
sysbus_connect_irq(sbd, 0,
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
- s->cpu->env.nvic = &s->nvic;
memory_region_add_subregion(&s->container, 0xe000e000,
sysbus_mmio_get_region(sbd, 0));
- for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
- Object *obj = OBJECT(&s->bitband[i]);
- SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
-
- object_property_set_int(obj, bitband_input_addr[i], "base", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- object_property_set_link(obj, OBJECT(s->board_memory),
- "source-memory", &error_abort);
- object_property_set_bool(obj, true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
+ if (s->enable_bitband) {
+ for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
+ Object *obj = OBJECT(&s->bitband[i]);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
+
+ object_property_set_int(obj, bitband_input_addr[i], "base", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ object_property_set_link(obj, OBJECT(s->board_memory),
+ "source-memory", &error_abort);
+ object_property_set_bool(obj, true, "realized", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ memory_region_add_subregion(&s->container, bitband_output_addr[i],
+ sysbus_mmio_get_region(sbd, 0));
}
-
- memory_region_add_subregion(&s->container, bitband_output_addr[i],
- sysbus_mmio_get_region(sbd, 0));
}
}
DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type),
DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION,
MemoryRegion *),
+ DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
+ DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
+ DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
+ DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
+ false),
+ DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
+ DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
DEFINE_PROP_END_OF_LIST(),
};
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = armv7m_realize;
- dc->props = armv7m_properties;
+ device_class_set_props(dc, armv7m_properties);
}
static const TypeInfo armv7m_info = {
cpu_reset(CPU(cpu));
}
-/* Init CPU and memory for a v7-M based board.
- mem_size is in bytes.
- Returns the ARMv7M device. */
-
-DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
- const char *kernel_filename, const char *cpu_type)
-{
- DeviceState *armv7m;
-
- armv7m = qdev_create(NULL, TYPE_ARMV7M);
- qdev_prop_set_uint32(armv7m, "num-irq", num_irq);
- qdev_prop_set_string(armv7m, "cpu-type", cpu_type);
- object_property_set_link(OBJECT(armv7m), OBJECT(get_system_memory()),
- "memory", &error_abort);
- /* This will exit with an error if the user passed us a bad cpu_type */
- qdev_init_nofail(armv7m);
-
- armv7m_load_kernel(ARM_CPU(first_cpu), kernel_filename, mem_size);
- return armv7m;
-}
-
void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
{
int image_size;
uint64_t entry;
uint64_t lowaddr;
int big_endian;
+ AddressSpace *as;
+ int asidx;
+ CPUState *cs = CPU(cpu);
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
big_endian = 0;
#endif
- if (!kernel_filename && !qtest_enabled()) {
- fprintf(stderr, "Guest image must be specified (using -kernel)\n");
- exit(1);
+ if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
+ asidx = ARMASIdx_S;
+ } else {
+ asidx = ARMASIdx_NS;
}
+ as = cpu_get_address_space(cs, asidx);
if (kernel_filename) {
- image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
- NULL, big_endian, EM_ARM, 1, 0);
+ image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
+ &entry, &lowaddr, NULL,
+ NULL, big_endian, EM_ARM, 1, 0, as);
if (image_size < 0) {
- image_size = load_image_targphys(kernel_filename, 0, mem_size);
+ image_size = load_image_targphys_as(kernel_filename, 0,
+ mem_size, as);
lowaddr = 0;
}
if (image_size < 0) {
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = bitband_realize;
- dc->props = bitband_properties;
+ device_class_set_props(dc, bitband_properties);
}
static const TypeInfo bitband_info = {