Revision 983fe826

b/hw/armv7m.c
151 151
}
152 152

  
153 153
/* Board init.  */
154

  
155
static void armv7m_reset(void *opaque)
156
{
157
    cpu_reset((CPUState *)opaque);
158
}
159

  
154 160
/* Init CPU and memory for a v7-M based board.
155 161
   flash_size and sram_size are in kb.
156 162
   Returns the NVIC array.  */
......
163 169
    /* FIXME: make this local state.  */
164 170
    static qemu_irq pic[64];
165 171
    qemu_irq *cpu_pic;
166
    uint32_t pc;
167 172
    int image_size;
168 173
    uint64_t entry;
169 174
    uint64_t lowaddr;
......
201 206
    armv7m_bitband_init();
202 207

  
203 208
    nvic = qdev_create(NULL, "armv7m_nvic");
204
    env->v7m.nvic = nvic;
209
    env->nvic = nvic;
205 210
    qdev_init_nofail(nvic);
206 211
    cpu_pic = arm_pic_init_cpu(env);
207 212
    sysbus_connect_irq(sysbus_from_qdev(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
......
227 232
        exit(1);
228 233
    }
229 234

  
230
    /* If the image was loaded at address zero then assume it is a
231
       regular ROM image and perform the normal CPU reset sequence.
232
       Otherwise jump directly to the entry point.  */
233
    if (lowaddr == 0) {
234
	env->regs[13] = ldl_phys(0);
235
	pc = ldl_phys(4);
236
    } else {
237
	pc = entry;
238
    }
239
    env->thumb = pc & 1;
240
    env->regs[15] = pc & ~1;
241

  
242 235
    /* Hack to map an additional page of ram at the top of the address
243 236
       space.  This stops qemu complaining about executing code outside RAM
244 237
       when returning from an exception.  */
245 238
    cpu_register_physical_memory(0xfffff000, 0x1000,
246 239
                                 qemu_ram_alloc(0x1000) | IO_MEM_RAM);
247 240

  
241
    qemu_register_reset(armv7m_reset, env);
248 242
    return pic;
249 243
}
250 244

  
b/target-arm/cpu.h
146 146
        int current_sp;
147 147
        int exception;
148 148
        int pending_exception;
149
        void *nvic;
150 149
    } v7m;
151 150

  
152 151
    /* Coprocessor IO used by peripherals */
......
205 204
    CPU_COMMON
206 205

  
207 206
    /* These fields after the common ones so they are preserved on reset.  */
207
    void *nvic;
208 208
    struct arm_boot_info *boot_info;
209 209
} CPUARMState;
210 210

  
b/target-arm/helper.c
8 8
#include "helpers.h"
9 9
#include "qemu-common.h"
10 10
#include "host-utils.h"
11
#include "hw/loader.h"
11 12

  
12 13
static uint32_t cortexa9_cp15_c0_c1[8] =
13 14
{ 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
......
204 205
#else
205 206
    /* SVC mode with interrupts disabled.  */
206 207
    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
208
    env->regs[15] = 0;
207 209
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
208
       clear at reset.  */
209
    if (IS_M(env))
210
       clear at reset.  Initial SP and PC are loaded from ROM.  */
211
    if (IS_M(env)) {
212
        uint32_t pc;
213
        uint8_t *rom;
210 214
        env->uncached_cpsr &= ~CPSR_I;
215
        rom = rom_ptr(0);
216
        if (rom) {
217
            /* We should really use ldl_phys here, in case the guest
218
               modified flash and reset itself.  However images
219
               loaded via -kenrel have not been copied yet, so load the
220
               values directly from there.  */
221
            env->regs[13] = ldl_p(rom);
222
            pc = ldl_p(rom + 4);
223
            env->thumb = pc & 1;
224
            env->regs[15] = pc & ~1;
225
        }
226
    }
211 227
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
212 228
    env->cp15.c2_base_mask = 0xffffc000u;
213 229
#endif
214
    env->regs[15] = 0;
215 230
    tlb_flush(env, 1);
216 231
}
217 232

  
......
624 639

  
625 640
    type = env->regs[15];
626 641
    if (env->v7m.exception != 0)
627
        armv7m_nvic_complete_irq(env->v7m.nvic, env->v7m.exception);
642
        armv7m_nvic_complete_irq(env->nvic, env->v7m.exception);
628 643

  
629 644
    /* Switch to the target stack.  */
630 645
    switch_v7m_sp(env, (type & 4) != 0);
......
666 681
       one we're raising.  */
667 682
    switch (env->exception_index) {
668 683
    case EXCP_UDEF:
669
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_USAGE);
684
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
670 685
        return;
671 686
    case EXCP_SWI:
672 687
        env->regs[15] += 2;
673
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_SVC);
688
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
674 689
        return;
675 690
    case EXCP_PREFETCH_ABORT:
676 691
    case EXCP_DATA_ABORT:
677
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_MEM);
692
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
678 693
        return;
679 694
    case EXCP_BKPT:
680 695
        if (semihosting_enabled) {
......
686 701
                return;
687 702
            }
688 703
        }
689
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_DEBUG);
704
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
690 705
        return;
691 706
    case EXCP_IRQ:
692
        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->v7m.nvic);
707
        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic);
693 708
        break;
694 709
    case EXCP_EXCEPTION_EXIT:
695 710
        do_v7m_exception_exit(env);

Also available in: Unified diff