I wanted to express my gratitude for your insightful solution concerning
the INVSTATE fault I was encountering. After recompiling my code with the
-mthumb compiler flag, the exception is no longer being raised, which marks
a significant step forward in my project.

However, I've encountered another challenge while working with a specific
version of QEMU (QEMU emulator version 7.1.0, v2.6.0-55433-g23b643ba16).
While the code runs flawlessly on QEMU version 8.1.50
(v8.1.0-2375-g516fffc993), the earlier version throws a hard fault, which
is critical to my use case.

The use case involves attaching a remote port to the MPS2-AN505, and for
this, I need to utilize Xilinx’s fork of QEMU, which is based on version
7.1.0 (v2.6.0-55433-g23b643ba16). The error I encounter during emulation is
as follows:

Loaded reset SP 0x0 PC 0x0 from vector table
Loaded reset SP 0x10080000 PC 0x10000009 from vector table
Taking exception 3 [Prefetch Abort] on CPU 0
...at fault address 0x10800000
...with CFSR.IBUSERR
...taking pending secure exception 3
...loading from element 3 000000c
...loaded new PC 0x10000011 of secure vector table at 0x1
Taking exception 3 [Prefetch Abort] on CPU 0
...at fault address 0x10800000
...with CFSR.IBUSERR
qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)

Observations: When I trace it using the GDB:

Remote debugging using: 1234


Reset_Handler () at boot.s:20

20          blx     helper

(gdb) l

15         blx     R0

16

17      .type Reset_Handler, function

18      .global Reset_Handler

19      Reset_Handler:

20          blx     helper

21          bx      lr

22

(gdb) s

Remote connection closed



It goes to prefetch abort as soon as I step into reset handler and the
connection gets closed.
What I do not understand is:

1) Why is my PC going to address 0x10800000?


2) When I use Qemu version 8.1.50 (v8.1.0-2375-g516fffc993), the PC goes to
the right address and does not throw a prefetch abort.


Please give me your insights on how I can fix this.


Some of my code for your reference:


My startup code :

.syntax unified

.thumb


.section .isr_vector

    .long    __StackTop

    .long    Reset_Handler




.text

.type helper,function

.global helper

helper :

   ldr     R0, = main

   blx     R0


.type Reset_Handler, function

.global Reset_Handler

Reset_Handler:

    blx     helper

    bx      lr



( Like you mentioned  previously , In the .isr_vector section I tried making
the other exception handlers  point to branch-to-self instructions but that
gives me the same error )


My linker code :


/* Linker script to configure memory regions. */

MEMORY

{

   NS_CODE (rx)     : ORIGIN = 0x00000000, LENGTH = 512K

   S_CODE_BOOT (rx) : ORIGIN = 0x10000000, LENGTH = 512K

   RAM   (rwx) : ORIGIN = 0x20000000, LENGTH = 512K

}


/* Entry Point */

ENTRY(Reset_Handler)


SECTIONS

{

    .text :

    {

        KEEP(*(.isr_vector))

        *(.text)

        *(.data)

    *(.bss)

    } > S_CODE_BOOT

    /* Set stack top to end of S_CODE_BOOT. */

    __StackTop = ORIGIN(S_CODE_BOOT) + LENGTH(S_CODE_BOOT);




}


kernel.list file :


kernel.elf:     file format elf32-littlearm


Disassembly of section .text:

10000000 <helper-0x8>:
10000000: 10080000 .word 0x10080000
10000004: 1000000d .word 0x1000000d

10000008 <helper>:
10000008: 4802       ldr r0, [pc, #8] @ (10000014 <Reset_Handler+0x8>)
1000000a: 4780       blx r0

1000000c <Reset_Handler>:
1000000c: f7ff fffc bl 10000008 <helper>
10000010: 4770       bx lr
10000012: 0000       .short 0x0000
10000014: 10000019 .word 0x10000019

10000018 <main>:
10000018: b480       push {r7}
1000001a: af00       add r7, sp, #0
1000001c: e7fe       b.n 1000001c <main+0x4>






On Thu, 18 Jan 2024 at 15:34, Peter Maydell <peter.mayd...@linaro.org>
wrote:

> On Thu, 18 Jan 2024 at 06:30, sanjana gogte <sanj27...@gmail.com> wrote:
> >
> > Hi,
> > 1) I am using QEMU Version 7.1.0. I am currently using this version with
> a plan to connect the remote port from Xilinx to the mps2an505 board. The
> decision to use this specific version is heavily influenced by the fact
> that it is the same version utilized by Xilinx's QEMU.
> >
> > 2) Debug Logs :
> > guest_errors:
> >
> > Invalid read at addr 0x10000000, size 4, region '(null)', reason:
> rejected
> > Invalid read at addr 0x10000004, size 4, region '(null)', reason:
> rejected
> > Invalid read at addr 0x10800000, size 2, region '(null)', reason:
> rejected
> > qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)
> >
> > in_asm:
>
> >
> > IN:
> > 0x10000008:
> > OBJD-T: 00480047
>
> Whoever built your QEMU didn't do it with libcapstone-dev
> installed, so the debug logs have only binary dumps of
> instructions, not the actual instructions, which is a pity
> (--enable-capstone will force configure to either find the
> necessary library or else give you an error message.)
>
> Also, I did not mean "do logs of every -d option separately",
> I meant "do a single log, with -d
> in_asm,exec,cpu,int,cpu_reset,unimp,guest_errors,nochain"
> That way you get the different bits of logging in their
> correct sequence relative to each other.
>
> Luckily, this bit is enough to figure out what's going on:
>
> > Loaded reset SP 0x0 PC 0x0 from vector table
> > Loaded reset SP 0x10080000 PC 0x10000008 from vector table
>
> We load the PC from the vector table, but it does not
> have the low bit set, which is not correct. (All entries
> in the vector table must be function pointers in the
> usual Thumb convention, where the lowest bit is set to
> indicate Thumb mode and clear to indicate Arm mode.)
> This means that we will start without the Thumb T bit set...
>
> > Taking exception 18 [v7M INVSTATE UsageFault] on CPU 0
>
> ...which on M-profile means we immediately take a fault trying
> to execute the first instruction...
>
> > ...taking pending secure exception 3
> > ...loading from element 3 of secure vector table at 0x1000000c
> > ...loaded new PC 0x10000011
>
> ...but because your vector table includes no entry for
> the hardfault vector, we instead load a PC value which
> doesn't point anywhere useful...
>
> > Taking exception 3 [Prefetch Abort] on CPU 0
> > ...at fault address 0x10800000
> > ...with CFSR.IBUSERR
> > qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)
>
> ...and eventually we execute off the end of the ROM memory,
> and then take a bus fault on the instruction fetch. This
> is a Lockup because we were already in a HardFault handler
> when we took this fault.
>
> > 3) You said the vector table is too small so I tried something like this
> from your reference files but it gives me the same error:
> >
> > Boot.s ( Startup file )
> >
> > .thumb
> > .syntax unified
> >
> > .section .isr_vector
> >     .long __StackTop
> >     .long Reset_Handler
> >     .word 0
>
> Zeroes here aren't very helpful because the CPU will try
> to jump to address 0 (and then immediately take another
> fault because the Thumb bit isn't set, which will be
> a Lockup condition again). If you at least make them point to
> branch-to-self instructions it'll be a bit clearer when
> you take an exception you weren't expecting, because in
> the debugger you'll see execution looping at that insn.
>
> >     .word 0
> >     .rept 7
> >     .word 0
> >     .endr
> >     .word 0
> >     .word 0
> >     .word 0
> >     .word 0
> >     .word 0
> >     .rept 32
> >     .word 0
> >     .endr
> >
> >
> > .text
> > .global Reset_Handler
> > Reset_Handler:
> >     ldr     R0, = main
> >     bx      R0
>
> But really your problem is here. You haven't told the assembler
> that "Reset_Handler" is a function entry point, and so it treats
> it like a data label. That means that the least significant bit
> is not set when you reference it in the vector table.
>
> Something like this will do what you want:
>         .type Reset_Handler, function
>         .global Reset_Handler
> Reset_Handler:
>
> PS: a hint for later: your code here does not do anything
> to enable the FPU before it jumps into C code. If your
> C compiler is generating code to use the FPU this will
> mean it will take an exception. So either make sure the
> C compiler is configured not to use the FPU, or else enable
> the FPU first.
>
> thanks
> -- PMM
>

Reply via email to