qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] armv7m/stm32f205 not starting if code linked from 0x080


From: Peter Maydell
Subject: Re: [Qemu-devel] armv7m/stm32f205 not starting if code linked from 0x08000000
Date: Mon, 8 Jun 2015 18:43:36 +0100

On 8 June 2015 at 18:32, Liviu Ionescu <address@hidden> wrote:
> Hi Alistair/Peter,
>
> I am having difficulties to make the armv7m code run if linked from 
> 0x08000000.
>
> based on the tracing info that I have (copied below), it seems that the cpu 
> throws an early exception, properly caught by the cpu and displayed (see the 
> indented lines).
>
> this is weird, since displaying these lines inside the UsageFault_Handler 
> means the alias works and the core can execute code from 0x08000000.
>
> my guess is that there is a bug in the reset code preventing the cpu to fetch 
> the Reset_Handler address from the first words in memory.
>
> I traced the cpu.c: arm_cpu_reset(CPUState *s) function and around line 170 
> there are two calls to initialise msp and pc:
>
>             initial_msp = ldl_phys(s->as, 0);
>             initial_pc = ldl_phys(s->as, 4);
>
> in my environment both return 0, probably not being able to fetch data from 
> the aliased region.

I think the problem here is that we're taking the "not a ROM
blob" branch of this if(), when we should be taking the "is
a rom blob" branch:

        rom = rom_ptr(0);
        if (rom) {
            /* Address zero is covered by ROM which hasn't yet been
             * copied into physical memory.
             */
            initial_msp = ldl_p(rom);
            initial_pc = ldl_p(rom + 4);
        } else {
            /* Address zero not covered by a ROM blob, or the ROM blob
             * is in non-modifiable memory and this is a second reset after
             * it got copied into memory. In the latter case, rom_ptr
             * will return a NULL pointer and we should use ldl_phys instead.
             */
            initial_msp = ldl_phys(s->as, 0);
            initial_pc = ldl_phys(s->as, 4);
        }

As the comments explain, for ROMs we need to load directly from
the ROM blob, not via load-from-physical-memory, because at the
point where the CPU is reset the ROM blob hasn't been copied
into memory. (Image contents loaded via -kernel are a kind of
ROM blob. This is what QEMU uses for "binary blob that needs
to be copied into memory at startup and on reset"; the name is
because on x86 that's what you need to do with ROM images.)
Unfortunately the test we're doing to decide is calling rom_ptr(),
which only looks at the addresses the ROMs are registered to
be copied into; it doesn't know about aliasing.

If you fudge the if() statement to use 0x08000000 rather
than 0 as the address passed to rom_ptr() it will probably
work. I'm not sure what the correct fix for this is, though.

(Really the problem is that we do the initial PC/SP load
in CPU reset, and we don't have two-phase reset. In hardware
PC/SP load happens when the CPU *comes out* of reset, as
the first thing it does. But we don't have any good place
to put that in QEMU, so the reset function is the best we
can do, and you end up with this ugly hack.)

-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]