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 >