Weird SPSR behaviour

I was trying to write a register context saving/restoring when I came across a weird behaviour.

My code (sorry, tried to format tens of times, but the editor WANTS to make asm a table):

asm volatile (
...
"pop {r0 - r3}"
"push {r0 - r3}"
"mov r0, r3"
"bl dbg_out" - outputs 60000013
"pop {r0 - r3}"
"msr cpsr_fsxc, r2"
"@dsb"
"@isb"
"msr spsr_fsxc, r3" - set value
"@dsb"
"@isb"
"mov lr, r1"
"mov sp, r0"
"push {r0 - r4, lr}"
"mov r0, lr"
"bl dbg_out"
"mov r0, sp"
"bl dbg_out"
"mrs r2, cpsr"
"mrs r3, spsr" - read value
"mov r0, r2"
"bl dbg_out"
"mov r0, r3" - outputs 00000002
"bl dbg_out"
...
);

When the exception is returned from, the calling function:

asm volatile ("svc #0\n\t");

    msg = "returned from SVC\r\n";

    serial_io.put_string(msg, util_str_len(msg)+1);

    asm volatile (

"mrs %[retreg], cpsr\n\t"
:[retreg] "=r" (tmp1) ::

    );

    msg = "cpsr = ";

    serial_io.put_string(msg, util_str_len(msg)+1);

    util_word_to_hex(scratchpad, tmp1);

    serial_io.put_string(scratchpad, 9);

    serial_io.put_string("\r\n", 3);

outputs "returned from SVC" and "cpsr = 60000013".

Why the "00000002"? the barriers don't seem to have any effect.

Parents
  • Now that you've seen my struggle, I wanted to give a status update:

    I can now load a program with GDB through my stub, run the loaded program. set and delete breakpoints, and the program really breaks there and the GDB is notified about it. Just the PC gets some weird value, and I haven't found out yet where that comes from, but if I correct it manually from GDB (set $pc = 0x?????) I can 'cont' forward. The weird PC value is not in the memory area of the stub nor the debuggee.

    I also tried with branch prediction and caches enabled, and it worked.

    Now the code also copies itself into upper memory (0x1f000000) to let the debuggee to load to the default address 0x8000.

    I wonder if I could use the hivec, and route all non-stub exceptions to lovec bu just jumping there. Then the debuggee could install its own exception vectors. Stub would just filter its own exceptions in the way (UART0 and BKPT). I could pre-install lovecs to unhandled exception handlers, and the debuggee then - if it wants to handle them - just overwrites them.

Reply
  • Now that you've seen my struggle, I wanted to give a status update:

    I can now load a program with GDB through my stub, run the loaded program. set and delete breakpoints, and the program really breaks there and the GDB is notified about it. Just the PC gets some weird value, and I haven't found out yet where that comes from, but if I correct it manually from GDB (set $pc = 0x?????) I can 'cont' forward. The weird PC value is not in the memory area of the stub nor the debuggee.

    I also tried with branch prediction and caches enabled, and it worked.

    Now the code also copies itself into upper memory (0x1f000000) to let the debuggee to load to the default address 0x8000.

    I wonder if I could use the hivec, and route all non-stub exceptions to lovec bu just jumping there. Then the debuggee could install its own exception vectors. Stub would just filter its own exceptions in the way (UART0 and BKPT). I could pre-install lovecs to unhandled exception handlers, and the debuggee then - if it wants to handle them - just overwrites them.

Children