qemu-devel
[Top][All Lists]
Advanced

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

Possible bug in Aarch64 single-stepping


From: Chris Howard
Subject: Possible bug in Aarch64 single-stepping
Date: Sat, 7 May 2022 15:42:40 +0200

Hi, I’m writing a simple debugger in assembly code for the Raspberry Pi 3B (in 
aarch64).

I’m using QEMU 7.0.0. Everything is running in EL1. (I have MDE and KDE set in 
MDSCR_EL1).

I’m coming across Unexpected Behaviour when playing with single-stepping:

It appears that single-stepping is enabled (ie. an exception is generated after 
every instruction) when the SS bit (bit-0) is set in MDSCR_EL1 and debug events 
are enabled in the CPSR (“D” bit clear) *** irrespective of whether the SS bit 
(bit-21) is set in CPSR or not ***.

I thought the SS bit (bit-21) needs to be set in CPSR for single-stepping to 
occur (and that it gets cleared whenever an exception is taken and needs to be 
reset if one wants to single-step again).

Have I misunderstood / misconfigured something, or is this a bug?

Attached is a minimal(ish) example:


Regards,

chris


/* 
******************************************************************************************

**** built with ****

aarch64-elf-as -march=armv8-a+crc+crypto -mcpu=cortex-a53 --gstabs minimal.s -o 
minimal.o
aarch64-elf-ld minimal.o -T memmap -o minimal.elf
aarch64-elf-objcopy -O binary minimal.elf minimal.img
aarch64-elf-objdump -d -j .text minimal.elf > minimal.list

**** memmap is ****

MEMORY
{
    ram : ORIGIN = 0x80000, LENGTH = 0x80000000
}

SECTIONS
{
    .init : { *(.init*) } > ram
    .text : { *(.text*) } > ram
    .data : { *(.data*) } > ram
    .bss  : { *(.bss*)  } > ram
}

**** qemu cmd ****

qemu-7.0.0/build/qemu-system-aarch64 -M raspi3b -kernel minimal.img -serial 
null -serial stdio -s -S

**** gdb cmd ****

/opt/local/gnuaarch64/bin/aarch64-none-elf-gdb -x gdb.cmds minimal.elf

**** gdb.cmds is ****

target remote :1234
set $pc = 0x80000

******************************************************************************************
 */

.section .text

.global _start
_start:

    mrs     x0, mpidr_el1               // x0 = 00000000.8000.0000
    and     x0, x0, 0b11
    cbz     x0, 2f                      // branch fwd if core == 0 ...
1:
    wfe                                 // ...  else wait for exception (ie 
sleep)
    b       1b
2:
//  mrs     x0, scr_el3                 // Can't access this from EL2. But gdb 
says it's 0x0501
                                        // 0000.0101|0000.0001  10:RW=1  
8:HCE=1  0:NS=1

//  mrs     x0, hcr_el2                 // x0 -> 1<<31 (34:E2H=0  31:RW=1  
27:TGE=0  2:C=0  1:M=0)

//  mrs     x0, sctlr_el1               // x0 -> 00c5.0838 = 
0000.0000|1100.0101|0000.1000|0011.1000
    mov     x0, 0x0800                  // -SA -SA0, -CP15BEN -nTWE -nTWI 
+20:RES1 +28:RES1 +29:RES1
    movk    x0, 0x30d0, lsl 16          // x0 -> 30d0.0800 = 
0011.0000|1101.0000|0000.1000|0000.0000
    msr     sctlr_el1, x0

    adr     x0, vectors
    msr     vbar_el1, x0

    adr     x0, _start                  // 0x0008.0000 = 512k
    msr     sp_el1, x0                  // set EL1's SP

    mov     x0, 0x3c5                   // NOTE: bit 21:SS is NOT set
    msr     spsr_el2, x0                // DAIF exceptions masked. A64 state. 
EL1. SP = SP_ELx

    adr     x0, init
    msr     elr_el2, x0

    eret                                // We're in EL2. Pretend we're 
"returning" to EL1 init:


init:
    msr     OSLAR_EL1, xzr              // unlock OS lock

    mov     x0, 0b101<<13               // 15:MDE (enable debugging) and 13:KDE 
(and kernel debug events)
    orr     x0, x0, 0b1<<0              // enable SS debug exceptions
    msr     MDSCR_EL1, x0

    mov     w0, 0                       // these all execute ok
    mov     w0, 1
    b       1f
    mov     w0, -1
1:

    msr     daifclr, 0b1111             // enable all interrupts and debugging 
exceptions

    mov     w0, 3                       // this causes an exception ESR_EL1 = 
0xce000022 (see ARMv8ARM D1-1801)
    mov     w0, 4                       // 0xce = 0b1100.1110|- >> 26 = 
0b0011.0011 = 0x33 = exception class
                                        // ie. SS from same EL. ** even though 
CPSR was 0x00000005 **
    svc     124

    mov     w0, 5
    b       2f
    mov     w0, -2
2:
    mov     w0, 6


loop:
    b       loop


// 
******************************************************************************************************

exc_svc:
    and     w0, w0, 0xffff
    cmp     w0, 123
    beq     svc_123
    cmp     w0, 124
    beq     svc_124
    b       exception_return            // undefined SVCs ignored


svc_123:
    mrs     x0, SPSR_EL1
    orr     x0, x0, 0b1<<21             // (re)enable SS in CPSR
    msr     SPSR_EL1, x0
    b       exception_return


svc_124:
    mrs     x0, SPSR_EL1
    bic     x0, x0, 0b1<<21             // disable SS in CPSR (not really 
necessary since SS gets
    msr     SPSR_EL1, x0                // cleared when an exception (eg. SVC) 
gets taken anyway)
    b       exception_return


exc_dbg:
    mrs     x0, elr_el1

    mrs     x0, SPSR_EL1
    bic     x0, x0, 0b1<<21             // (re)enable SS in CPSR
    msr     SPSR_EL1, x0

    b       exception_return


exception_return:
    ldp     x2, x3, [sp], 16
    ldp     x0, x1, [sp], 16
    eret


.align 11
vectors:
// ************************ from current EL using SP_EL0 
***************************
v0:                                     // Synchronous
    b       v0
.align 7
v1:                                     // IRQ
    b       v1
.align 7
v2:                                     // FIQ
    b       v2
.align 7
v3:                                     // SError
    b       v3
// ************************ from current EL using SP_EL1+ 
**************************
.align 7
v10:                                    // Synchronous (SVC, MMU, DEBUG)
    stp     x0, x1, [sp, -16]!
    stp     x2, x3, [sp, -16]!

    mrs     x0, esr_el1                 // exception syndrome (ARMv8ARM p. 
D1-1801)
    mov     w1, w0, lsr 26              // w1 -> exception class

    cmp     w1, 0x15                    // SVC 
    beq     exc_svc

    b       exc_dbg

.align 7
v11:                                    // IRQ
    b       v11
.align 7
v12:                                    // FIQ
    b       v12
.align 7
v13:                                    // SError
    b       v13
// ************************ from lower EL using A64 
********************************
.align 7
v20:                                    // Synchronous
    b       v20
.align 7
v21:                                    // IRQ
    b       v21
.align 7
v22:                                    // FIQ
    b       v22
.align 7
v23:                                    // SError
    b       v23
// 
*********************************************************************************

data:



reply via email to

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