Add CPU unassigned access handler in place of special MemoryRegion to catch exception returns.
Signed-off-by: Michael Davidsaver <mdavidsa...@gmail.com> --- hw/arm/armv7m.c | 8 -------- target-arm/cpu.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index a80d2ad..68146de 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -176,7 +176,6 @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq, uint64_t entry; uint64_t lowaddr; int big_endian; - MemoryRegion *hack = g_new(MemoryRegion, 1); if (cpu_model == NULL) { cpu_model = "cortex-m3"; @@ -221,13 +220,6 @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq, } } - /* Hack to map an additional page of ram at the top of the address - space. This stops qemu complaining about executing code outside RAM - when returning from an exception. */ - memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000, &error_fatal); - vmstate_register_ram_global(hack); - memory_region_add_subregion(system_memory, 0xfffff000, hack); - qemu_register_reset(armv7m_reset, cpu); return nvic; } diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 30739fc..be026bc 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -280,6 +280,23 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) +static void arm_v7m_unassigned_access(CPUState *cpu, hwaddr addr, + bool is_write, bool is_exec, int opaque, + unsigned size) +{ + ARMCPU *arm = ARM_CPU(cpu); + CPUARMState *env = &arm->env; + + if (env->v7m.exception != 0 && addr >= 0xfffffff0 && !is_write) { + cpu->exception_index = EXCP_EXCEPTION_EXIT; + cpu_loop_exit(cpu); + } else { + /* TODO, signal some *Fault? */ + cpu_abort(cpu, "Trying to access outside RAM or ROM at 0x" + TARGET_FMT_plx "\n", addr); + } +} + static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { CPUClass *cc = CPU_GET_CLASS(cs); @@ -909,6 +926,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) cc->do_interrupt = arm_v7m_cpu_do_interrupt; #endif + cc->do_unassigned_access = arm_v7m_unassigned_access; cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; } -- 2.1.4