All of lore.kernel.org
 help / color / mirror / Atom feed
* Possible bug in Aarch64 single-stepping
@ 2022-05-07 13:42 Chris Howard
  2022-05-07 14:16 ` Chris Howard
  2022-05-08 12:08 ` Possible bug in Aarch64 single-stepping Peter Maydell
  0 siblings, 2 replies; 8+ messages in thread
From: Chris Howard @ 2022-05-07 13:42 UTC (permalink / raw)
  To: qemu-devel

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:


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible bug in Aarch64 single-stepping
  2022-05-07 13:42 Possible bug in Aarch64 single-stepping Chris Howard
@ 2022-05-07 14:16 ` Chris Howard
  2022-05-08 12:18   ` Peter Maydell
  2022-05-08 12:08 ` Possible bug in Aarch64 single-stepping Peter Maydell
  1 sibling, 1 reply; 8+ messages in thread
From: Chris Howard @ 2022-05-07 14:16 UTC (permalink / raw)
  To: qemu-devel

On 7. May 2022, at 15:42, Chris Howard <cvz185@web.de> wrote:
> 
> 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:

Oh, and the exception occurs immediately (after the ERET), rather than after the instruction has been executed. It appears to be acting like a hardware breakpoint.


PS. In plain gdb (ie. no nice user interface) a large number (but not all) of the system registers gets displayed after each step. It would be nice if these were sorted in some way. At the moment they’re completely jumbled — not alphabetic, not grouped by EL, nor by “meaning”  (DBGWVR0_EL1 isn’t necessarily next to DBGWCR0_EL1).

Also, there are multiple (identical?) instances of “DBGBVR” and “DBGBCR” (and  “DBGWVR” and “DBGWCR”) rather than the expected “DBGWVR0_EL1”, “DBGWVR1_EL1” etc.

Would this be a QEMU or a GDB issue? Or isn’t it an issue at all? :-)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible bug in Aarch64 single-stepping
  2022-05-07 13:42 Possible bug in Aarch64 single-stepping Chris Howard
  2022-05-07 14:16 ` Chris Howard
@ 2022-05-08 12:08 ` Peter Maydell
  2022-05-08 19:35   ` Chris Howard
  1 sibling, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2022-05-08 12:08 UTC (permalink / raw)
  To: Chris Howard; +Cc: qemu-devel

On Sat, 7 May 2022 at 14:44, Chris Howard <cvz185@web.de> wrote:
>
> 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?

I think you've misunderstood how the architectural single
step works. This is described in section D2.12 of the Arm ARM
(DDI0487H.a), but briefly, there is a state machine with three
states: Inactive, Active-not-pending, and Active-pending.

* Inactive is when MDSCR_EL1.SS is 0 or debug exceptions are
disabled from the current EL or security state.

* Active-not-pending is when we're not Inactive (ie MDSCR_EL1.SS is 1
and so on) and PSTATE.SS is 1. This is the state for "we're currently
pointing at the instruction we would like to step". The CPU
does the step by doing "execute this one instruction, and then
clear PSTATE.SS". It does *not* take a "single step completed"
exception. (I ignore for the moment the possibility that the
insn resulted in some other exception.)

* Active-pending is when we're not Inactive and PSTATE.SS is 0.
This state means "Software step is active, and a software step
is pending on the current instruction".
The usual way we get here is that we were in Active-not-pending
and then we executed the instruction and cleared PSTATE.SS.
But you can also get here in other ways (as your test case does).
In Active-pending state, the CPU does "take a software step
exception immediately, without doing anything else" -- which is
what you see.

In other words, the design effectively separates out the
"execute one instruction" part from the "take the exception
that says we completed a step" part. (This separation is
irrelevant for the 'normal case' where the stepped instruction
doesn't cause any exceptions and no interrupts arrive either,
but it can matter if there is some interrupt to be taken. For
instance, suppose that we do a step, and while the insn is
executing an interrupt comes in that is routed to EL3. We
want to take that interrupt first, before taking the
'single step complete' exception. Because the distinction
between 'active-not-pending' and 'active-pending' is stored
in PSTATE.SS, this works automatically -- we go to EL3, do
whatever the interrupt handler does, and then on the eret
to where we started, PSTATE.SS is restored to 0: so we then
correctly take the 'single step complete' exception without
executing another instruction.)

So if you don't want to see single-step exceptions you need
to make sure you stay in the Inactive state.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible bug in Aarch64 single-stepping
  2022-05-07 14:16 ` Chris Howard
@ 2022-05-08 12:18   ` Peter Maydell
  2022-05-08 12:19     ` Peter Maydell
  2022-05-08 19:27     ` Possible bug in Aarch64 single-stepping [PATCH] Chris Howard
  0 siblings, 2 replies; 8+ messages in thread
From: Peter Maydell @ 2022-05-08 12:18 UTC (permalink / raw)
  To: Chris Howard; +Cc: qemu-devel

Introduction

This document will explain how setup Mutt email client using OAuth2
(modern authentication) to access your emails.

Authentication will be done using "bearer tokens" instead of a
combination of a username and an application password.

You can find more details about bearer tokens and the python script we
will use to generate them following this link.


Prerequisites

1) A working GPG setup on your machine. If you don't have this setup
please follow below steps:

Install gpg.

sudo apt install gpg or yum install gnupg2

Run gpg --gen-key

Answer the questions (your name, email address...)

Check you GPG setup

Create a text file with foo in it

echo foo > foo.txt

Encrypt your text file with your gpg key

gpg --batch --yes -e -r franck.iaropoli@arm.com foo.txt

Decrypt your foo.txt.gpg file

$ gpg -d foo.txt.gpg
gpg: encrypted with 3072-bit RSA key, ID 5F5E76BC0AD59EFD, created 2022-04-29
      "Franck Iaropoli <franck.iaropoli@arm.com>"
foo

Enter your passphrase (you may not asked if you entered it recently)
and you should see foo as result.

2) Download mutt_oauth2.py python script and make it executable.

For example

To download the script in your home directory and make it executable:

wget -O ~/mutt_oauth2.py
https://gitlab.com/muttmua/mutt/-/raw/master/contrib/mutt_oauth2.py
cd
chmod +x mutt_oauth2.py

Note: The mutt_oauth2.py script requires at least Python 3.7

3) At least Mutt 2.0.0. Earlier versions do not have the
imap_oauth_refresh_command function (see release notes with more
information in XOAUTH2 part).

4) The Mutt Azure application client_id which is
e86f5911-84ec-4635-b69a-313d29aa3858

5) For the gpg-agent to be able to ask you to unlock passphrase, set
the environment variable GPG_TTY to the current tty.

If you are using bash shell, put the following inside your .bashrc or
equivalent (.zshrc with zsh for example)

export GPG_TTY=$(tty)

Note: If you are not using an interactive session, you must export
GPG_TTY variable in your .bashrc_profile or equivalent (.zshenv with
zsh for example)

6) Edit the mutt_oauth2.py script :

Put your GPG identity in 'YOUR_GPG_IDENTITY' (your email address or
whatever you have set instead during gpg setup) in the ENCRYPTION_PIPE
line.

ENCRYPTION_PIPE = ['gpg', '--encrypt', '--recipient', 'YOUR_GPG_IDENTITY']

For example:

ENCRYPTION_PIPE = ['gpg', '--encrypt', '--recipient', 'franck.iaropoli@arm.com']

In the registrations, the microsoft one, enter the client_id
e86f5911-84ec-4635-b69a-313d29aa3858

registrations = {
    'google': {
...
    },
    'microsoft': {
...
        'client_id': 'e86f5911-84ec-4635-b69a-313d29aa3858',
        'client_secret': '',
    },
}

Create your tokens

Run the mutt_oauth2.py script with the path to the file that will
contain your tokens, the verbose and authorize options:

./mutt_oauth2.py <path to file with tokens> --verbose --authorize

For example:

./mutt_oauth2.py franck.iaropoli@arm.com.tokens --verbose --authorize

Note:

You should be asked to enter your gpg passphrase:

Select microsoft as app and endpoint registration:

$ ./mutt_oauth2.py franck.iaropoli@arm.com.tokens --verbose --authorize
Available app and endpoint registrations: google microsoft
OAuth2 registration: microsoft

Select your preferred OAuth2 flow:

- "authcode": you paste a complicated URL into a browser, then
manually extract a "code" parameter from a subsequent URL in the
browser address bar and paste that back to the script.

- "localhostauthcode": you again paste the complicated URL into a
browser but that's it --- the code is automatically extracted from the
response relying on a localhost redirect and temporarily listening on
a localhost port.
This flow can only be used if the web browser opening the redirect URL
sits on the same machine as where mutt is running, in other words can
not be used if you ssh to a remote machine and run mutt on that remote
machine while your web browser remains on your local machine.

- "devicecode": you go to a simple URL and just enter a short code.

We will use devicecode as it can work with a local or a remote session:

$ ./mutt_oauth2.py franck.iaropoli@arm.com.tokens --verbose --authorize
Available app and endpoint registrations: google microsoft
OAuth2 registration: microsoft
Preferred OAuth2 flow ("authcode" or "localhostauthcode" or
"devicecode"): devicecode

Enter your email address:

$ ./mutt_oauth2.py franck.iaropoli@arm.com.tokens --verbose --authorize
Available app and endpoint registrations: google microsoft
OAuth2 registration: microsoft
Preferred OAuth2 flow ("authcode" or "localhostauthcode" or
"devicecode"): devicecode
Account e-mail address: franck.iaropoli@arm.com

Now open the link given in the terminal in your preferred web browser:

$ ./mutt_oauth2.py franck.iaropoli@arm.com.tokens --verbose --authorize
Available app and endpoint registrations: google microsoft
OAuth2 registration: microsoft
Preferred OAuth2 flow ("authcode" or "localhostauthcode" or
"devicecode"): devicecode
Account e-mail address: franck.iaropoli@arm.com
To sign in, use a web browser to open the page
https://microsoft.com/devicelogin and enter the code D59TF5YCJ to
authenticate.
Polling...

Enter the code available in the terminal and click Next

Note: If you have recently done the authentication process you may
just have to select you account and not doing a full authentication:

Otherwise you will have to do the full authentication process as
explained below.

Enter your email address:

Enter your password:

Approve the sign in request with your preferred 2FA solution (here the
Microsoft Authenticator application was used)

Click Continue

You have now signed into Mutt application.

You can close the window.

Come back to the terminal. You will see that an access token has been obtained.

$ ./mutt_oauth2.py franck.iaropoli@arm.com.tokens --verbose --authorize
Available app and endpoint registrations: google microsoft
OAuth2 registration: microsoft
Preferred OAuth2 flow ("authcode" or "localhostauthcode" or
"devicecode"): devicecode
Account e-mail address: franck.iaropoli@arm.com
To sign in, use a web browser to open the page
https://microsoft.com/devicelogin and enter the code D59TF5YCJ to
authenticate.
Polling.............................................
NOTICE: Obtained new access token, expires 2022-04-28T14:07:59.922548.
Access Token: eyJ0eXAiOiJKV1QiLCJub25jZSI6Ii1lNzlNSXFWc1ZrUllzS3FjZ1lQa3VzenpaX25ZLWN6MGVxOXFERWlLVkEiLCJhbGciOiJSUzI1NiIsIng1dCI6ImpTMVhvMU9XRGpfNTJ2YndHTmd2UU8yVnpNYyIsImtpZCI6ImpTMVhvMU9XRGpfNTJ2YndHTmd2UU8yVnpNYyJ9.eyJhdWQiOiJodHRwczovL291dGxvb2sub2ZmaWNlLmNvbSIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2YzNGU1OTc5LTU3ZDktNGFhYS1hZDRkLWIxMjJhNjYyMTg0ZC8iLCJpYXQiOjE2NTExNDM2NDMsIm5iZiI6MTY1MTE0MzY0MywiZXhwIjoxNjUxMTQ3Njc4LCJhY2N0IjowLCJhY3IiOiIxIiwiYWlvIjoiQVZRQXEvOFRBQUFBdEMybW55VitBaWViQkhxOG1lTDlWRlBOYWFTUnI0V2pCV1g2VWZpenJINkp6SVM1c1Fob0ludHB6QkJTWlIzelNMYStCNkJyZmxRemFvZUxsVFpvZk1pVzNpVWJMZXdqdXNQbWN4TTljbjQ9IiwiYW1yIjpbInB3ZCIsIm1mYSJdLCJhcHBfZGlzcGxheW5hbWUiOiJNdXR0IiwiYXBwaWQiOiJlODZmNTkxMS04NGVjLTQ2MzUtYjY5YS0zMTNkMjlhYTM4NTgiLCJhcHBpZGFjciI6IjAiLCJlbmZwb2xpZHMiOltdLCJmYW1pbHlfbmFtZSI6Iklhcm9wb2xpIiwiZ2l2ZW5fbmFtZSI6IkZyYW5jayIsImlwYWRkciI6IjIxNy4xNDAuMTA2LjM5IiwibmFtZSI6IkZyYW5jayBJYXJvcG9saSIsIm9pZCI6ImY2NTc5MTIwLTBkODAtNGRkYS04ZmIzLTE0OWU4YTkyNTQyNyIsIm9ucHJlbV9zaWQiOiJTLTEtNS0yMS0xNzE1NTY3ODIxLTE2NDQ0OTE5MzctNzI1MzQ1NTQzLTkxOTQ1IiwicHVpZCI6IjEwMDM3RkZFOTE2MUZGNzUiLCJyaCI6IjAuQVJBQWVWbE84OWxYcWtxdFRiRWlwbUlZVFFJQUFBQUFBUEVQemdBQUFBQUFBQUFRQU1JLiIsInNjcCI6IklNQVAuQNGQtOWVhMS04NjU1MmY1NTUzODIiLCJzaWduaW5fc3RhdGUiOlsiaW5rbm93bm50d2siLCJrbXNpIl0sInN1YiI6InFjZFRSNG5xNjFCbmRlNWE0a0t3UzNrZzJlcm1IY2g0UnptdGF1NkpKQjAiLCJ0aWQiOiJmMzRlNTk3OS01N2Q5LTRhYWEtYWQ0ZC1iMTIyYTY2MjE4NGQiLCJ1bmlxdWVfbmFtZSI6IkZyYW5jay5JYXJvcG9saUBhcm0uY29tIiwidXBuIjoiRnJhbmNrLklhcm9wb2xpQGFybS5jb20iLCJ1dGkiOiJNVm5WeHNVdmMwaUM3bnNYdEtwekFBIiwidmVyIjoiMS4wIiwid2lkcyI6WyI3Mjk4MjdlMy05YzE0LTQ5ZjctYmIxYi05NjA4ZjE1NmJiYjgiLCJmZTkzMGJlNy01ZTYyLTQ3ZGItOTFhZi05OGMzYTQ5YTM4YjEiLCJiNzlmYmY0ZC0zZWY5LTQ2ODktODE0My03NmIxOTRlODU1MDkiXX0.Iwehvs9MSqTwsRTM4z6a_9reDde0Bh_cOhT1Brny1KtDyWhTOlStlx1CgGpckI7zdGEXxwYDmo4BON6PszehcjThQM9lp-dYhSzjp1Dn_P6C1N3iBw59IhhTKxfW9ZIsPx60Pcs0FJXmMQoJLnIbn3jqEzkzbkupu4nsuDTfSw886TsHQ1lS17dvO1qJDctLMMZzrQ0ZklmxQoIUypcqTb9a0plwIXiSMarm2uzybyEA3vgZOCFRzUohCVflyJBUa9Vm_z444gOEbFAPaMuPdo_-JNkFDzszxVrSI1c2zDJlN8ofq2VAScp5P_UELX72KyOkhl52jpcPmlrCpdmC-Q


Test your tokens

Run mutt_oauth2.py script with the path to your tokens file, the
verbose and the test option:

./mutt_oauth2.py <path to file with tokens> --verbose --test

For example:

$ ./mutt_oauth2.py franck.iaropoli@arm.com.tokens --verbose --test
Access Token: eyJ0eXAiOiJKV1QiLCJub25jZSI6Ii1CUGYtdWR1ZU9pZXBVSmZpaExBakpKSl9UdXVkcllPRjlYOGZWUTlLaGciLCJhbGciOiJSUzI1NiIsIng1dCI6ImpTMVhvMU9XRGpfNTJ2YndHTmd2UU8yVnpNYyIsImtpZCI6ImpTMVhvMU9XRGpfNTJ2YndHTmd2UU8yVnpNYyJ9.eyJhdWQiOiJodHRwczovL291dGxvb2sub2ZmaWNlLmNvbSIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2YzNGU1OTc5LTU3ZDktNGFhYS1hZDRkLWIxMjJhNjYyMTg0ZC8iLCJpYXQiOjE2NTExNTQ3MDYsIm5iZiI6MTY1MTE1NDcwNiwiZXhwIjoxNjUxMTU5ODM0LCJhY2N0IjowLCJhY3IiOiIxIiwiYWlvIjoiQVZRQXEvOFRBQUFBVndRbnZJMmlRenJ0NEdPTGxHUWYzeDMvc3FQekxLZ3c5N244SFN0L3RHcFl1Z21jRHdiMFJZeWcyb2J6cHVYTkU1NUZSS1l6aCtIM2NNbGxneUpNbEIyelVSaWtSaHlvbXBlZFlMMVVMV289IiwiYW1yIjpbInB3ZCIsIm1mYSJdLCJhcHBfZGlzcGxheW5hbWUiOiJNdXR0IiwiYXBwaWQiOiJlODZmNTkxMS04NGVjLTQ2MzUtYjY5YS0zMTNkMjlhYTM4NTgiLCJhcHBpZGFjciI6IjAiLCJlbmZwb2xpZHMiOltdLCJmYW1pbHlfbmFtZSI6Iklhcm9wb2xpIiwiZ2l2ZW5fbmFtZSI6IkZyYW5jayIsImlwYWRkciI6IjIxNy4xNDAuMTA2LjM5IiwibmFtZSI6IkZyYW5jaytNS0yMS0xNzE1NTY3ODIxLTE2NDQ0OTE5MzctNzI1MzQ1NTQzLTkxOTQ1IiwicHVpZCI6IjEwMDM3RkZFOTE2MUZGNzUiLCJyaCI6IjAuQVJBQWVWbE84OWxYcWtxdFRiRWlwbUlZVFFJQUFBQUFBUEVQemdBQUFBQUFBQUFRQU1JLiIsInNjcCI6IklNQVAuQWNjZXNzQXNVc2VyLkFsbCBQT1AuQWNjZXNzQXNVc2VyLkFsbCBTTVRQLlNlbmQiLCJzaWQiOiJkMTExZGM4Ni00NGUxLTRiZjktYTk4ZS0yYThmYjA2NTU3NTMiLCJzaWduaW5fc3RhdGUiOlsiaW5rbm93bm50d2siXSwic3ViIjoicWNkVFI0bnE2MUJuZGU1YTRrS3dTM2tnMmVybUhjaDRSem10YXU2SkpCMCIsInRpZCI6ImYzNGU1OTc5LTU3ZDktNGFhYS1hZDRkLWIxMjJhNjYyMTg0ZCIsInVuaXF1ZV9uYW1lIjoiRnJhbmNrLklhcm9wb2xpQGFybS5jb20iLCJ1cG4iOiJGcmFuY2suSWFyb3BvbGlAYXJtLmNvbSIsInV0aSI6IjJ4eVBpZG41Q2txdy1fbWdpTzhOQUEiLCJ2ZXIiOiIxLjAiLCJ3aWRzIjpbIjcyOTgyN2UzLTljMTQtNDlmNy1iYjFiLTk2MDhmMTU2YmJiOCIsImZlOTMwYmU3LTVlNjItNDdkYi05MWFmLTk4YzNhNDlhMzhiMSIsImI3OWZiZjRkLTNlZjktNDY4OS04MTQzLTc2YjE5NGU4NTUwOSJdfQ.fAjkZGM1Z5XQ7R1xD3raGuNbJzgcaWKKb5FS-MM1sFoGS8PdCS--0oWCi2VD7X43fgXaAWoHjMMCbXpTjF569gaQCEMCH-QelxRx_nQi7kk7N6ljWMFULLufIWyNegSVun8M_VqnxBxxPfdGZLqdxfKZAxFAM3YMY4d_-W2uSzBGFprF5PpT644O3Coro1ir1pWaRRhpOgY78HRbZEH8vfeG_L763STjWmTVGNeEw5cIR8_AcdgJaHWfP4DrwOcD3n5MmqlrQrfM9h1Ev6LaaX_0FPlmBmOOyBxH90o2JAFoEV3wG1kOghxTAmmG8SH_TUV4xISbi9XOBJa1dmZXuQ
IMAP authentication succeeded
POP authentication FAILED (does your account allow POP?): -ERR
Authentication failure: unknown user name or bad password.
SMTP authentication succeeded

IMAP and SMTP authentication should be marked as succeeded.

Note:

If IMAP and SMTP authentication are not working:

Check you network connection
Check that all settings in mutt_oauth2.py script are correct

The client_id which is e86f5911-84ec-4635-b69a-313d29aa3858
Your GPG identity in ENCRYPTION_PIPE variable

Restart the tokens creation process.

Delete the file that contains your tokens (in this example
franck.iaropoli@arm.com.tokens file)
Redo all the steps in the previous paragraph "create tokens" (running
script mutt_oauth2.py with the path to your tokens file, the verbose
and authorize options)

Configure Mutt

You now need to add below additional settings to your Mutt config file
to start using OAuth2 authentication (settings between <> must be
changed)

# setup modern auth
set imap_user="<your Arm email address"
set folder="imaps://outlook.office365.com:993/"
set smtp_url="smtp://${imap_user}@smtp.office365.com:587/"
set imap_authenticators="xoauth2"
set imap_oauth_refresh_command="<path to mutt_oauth2.py script> <name
of the tokens file>"
set smtp_authenticators=${imap_authenticators}
set smtp_oauth_refresh_command=${imap_oauth_refresh_command}

For example:

# setup modern auth
set imap_user="franck.iaropoli@arm.com"
set folder="imaps://outlook.office365.com:993/"
set smtp_url="smtp://${imap_user}@smtp.office365.com:587/"
set imap_authenticators="xoauth2"
set imap_oauth_refresh_command="/home/fraiar01/mutt_oauth2.py
${imap_user}.tokens"
set smtp_authenticators=${imap_authenticators}
set smtp_oauth_refresh_command=${imap_oauth_refresh_command}

Note:

You will be asked to re-enter your passphrase to access your tokens
and to renew them.

Known limitations

At present, mutt_oauth2.py access tokens have a limited lifetime,
meaning they must be regenerated every couple of hours.



On Sat, 7 May 2022 at 15:18, Chris Howard <cvz185@web.de> wrote:
> PS. In plain gdb (ie. no nice user interface) a large number (but not all) of the system registers gets displayed after each step. It would be nice if these were sorted in some way. At the moment they’re completely jumbled — not alphabetic, not grouped by EL, nor by “meaning”  (DBGWVR0_EL1 isn’t necessarily next to DBGWCR0_EL1).
>
> Also, there are multiple (identical?) instances of “DBGBVR” and “DBGBCR” (and  “DBGWVR” and “DBGWCR”) rather than the expected “DBGWVR0_EL1”, “DBGWVR1_EL1” etc.
>
> Would this be a QEMU or a GDB issue? Or isn’t it an issue at all? :-)

My gdb doesn't do that. Basically QEMU provides gdb with some XML
telling it that the sysregs are present, but it's up to gdb at
what points it chooses to display what registers and how it does that.

The system register read access via the gdbstub is "best-effort"
on QEMU's part -- we implement it to the extent that it wasn't too
difficult to do, but there are some sharp edges, like the
register names not always being quite right, and also the way
that if you try to read a register that isn't supposed to be
accessible by the current EL you might find it's not correct.
Trying to read SP_EL2 while at EL2 is an example of that.

The reason register names are sometimes funny is that the
infrastructure for system registers within QEMU was originally
written with the assumption that the name strings were merely
for convenience when debugging QEMU itself, so it's sometimes
a bit careless about them. We only added the "tell GDB about
these" part later.

That said, adding the numbers into the watchpoint and breakpoint
registers would be pretty easy, so we should do that. That is,
in this code:
https://gitlab.com/qemu-project/qemu/-/blob/master/target/arm/helper.c#L6567
we should use g_strdup_printf() to create unique per-register
names, the same way we do for the PMU registers already here:
https://gitlab.com/qemu-project/qemu/-/blob/master/target/arm/helper.c#L6632

thanks
-- PMM


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible bug in Aarch64 single-stepping
  2022-05-08 12:18   ` Peter Maydell
@ 2022-05-08 12:19     ` Peter Maydell
  2022-05-08 19:27     ` Possible bug in Aarch64 single-stepping [PATCH] Chris Howard
  1 sibling, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2022-05-08 12:19 UTC (permalink / raw)
  To: Chris Howard; +Cc: qemu-devel

On Sun, 8 May 2022 at 13:18, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> Introduction
>
> This document will explain how setup Mutt email client using OAuth2
> (modern authentication) to access your emails.

Argh, sorry about this. I mis-clicked something and pasted a
load of bogus text :-(

-- PMM


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible bug in Aarch64 single-stepping [PATCH]
  2022-05-08 12:18   ` Peter Maydell
  2022-05-08 12:19     ` Peter Maydell
@ 2022-05-08 19:27     ` Chris Howard
  2022-05-10  9:59       ` Peter Maydell
  1 sibling, 1 reply; 8+ messages in thread
From: Chris Howard @ 2022-05-08 19:27 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel

On 8. May 2022, at 14:18, Peter Maydell <peter.maydell@linaro.org> wrote:

> On Sat, 7 May 2022 at 15:18, Chris Howard <cvz185@web.de> wrote:
>> PS. In plain gdb (ie. no nice user interface) a large number (but not all) of the system registers gets displayed after each step. It would be nice if these were sorted in some way. At the moment they’re completely jumbled — not alphabetic, not grouped by EL, nor by “meaning”  (DBGWVR0_EL1 isn’t necessarily next to DBGWCR0_EL1).
>> 
>> Also, there are multiple (identical?) instances of “DBGBVR” and “DBGBCR” (and  “DBGWVR” and “DBGWCR”) rather than the expected “DBGWVR0_EL1”, “DBGWVR1_EL1” etc.
>> 
>> Would this be a QEMU or a GDB issue? Or isn’t it an issue at all? :-)
> 
> My gdb doesn't do that. Basically QEMU provides gdb with some XML
> telling it that the sysregs are present, but it's up to gdb at
> what points it chooses to display what registers and how it does that.
> 
> The system register read access via the gdbstub is "best-effort"
> on QEMU's part -- we implement it to the extent that it wasn't too
> difficult to do, but there are some sharp edges, like the
> register names not always being quite right, and also the way
> that if you try to read a register that isn't supposed to be
> accessible by the current EL you might find it's not correct.
> Trying to read SP_EL2 while at EL2 is an example of that.
> 
> The reason register names are sometimes funny is that the
> infrastructure for system registers within QEMU was originally
> written with the assumption that the name strings were merely
> for convenience when debugging QEMU itself, so it's sometimes
> a bit careless about them. We only added the "tell GDB about
> these" part later.
> 
> That said, adding the numbers into the watchpoint and breakpoint
> registers would be pretty easy, so we should do that. That is,
> in this code:
> https://gitlab.com/qemu-project/qemu/-/blob/master/target/arm/helper.c#L6567
> we should use g_strdup_printf() to create unique per-register
> names, the same way we do for the PMU registers already here:
> https://gitlab.com/qemu-project/qemu/-/blob/master/target/arm/helper.c#L6632
> 
> thanks
> -- PMM

Thanks for the explanation. What with this being “pretty easy” I’m attempting my first ever patch!  :-)

BE WARNED!

This is a context diff with respect to the cloned git repository (Version 7.0.50)

$ git clone https://gitlab.com/qemu-project/qemu.git

created with

$ diff -c qemu/target/arm/helper.c qemu-patch/target/arm/helper.c > aarch-dbg-regnames.patch

to be applied (in the target/arm directory) with

$ patch -p3 <../../../aarch-dbg-regnames.patch


— chris


 
*** qemu/target/arm/helper.c	2022-05-08 20:41:48.000000000 +0200
--- qemu-patch/target/arm/helper.c	2022-05-08 20:55:25.000000000 +0200
***************
*** 6551,6559 ****
          define_one_arm_cp_reg(cpu, &dbgdidr);
      }
  
!     /* Note that all these register fields hold "number of Xs minus 1". */
!     brps = arm_num_brps(cpu);
!     wrps = arm_num_wrps(cpu);
      ctx_cmps = arm_num_ctx_cmps(cpu);
  
      assert(ctx_cmps <= brps);
--- 6551,6559 ----
          define_one_arm_cp_reg(cpu, &dbgdidr);
      }
  
!     /* Note that all these reg fields (in ID_AA64DFR0_EL1) hold "number of Xs minus 1". */
!     brps = arm_num_brps(cpu);			/* returns actual number of breakpoints */
!     wrps = arm_num_wrps(cpu);			/* returns actual number of watchpoints */
      ctx_cmps = arm_num_ctx_cmps(cpu);
  
      assert(ctx_cmps <= brps);
***************
*** 6565,6578 ****
      }
  
      for (i = 0; i < brps; i++) {
          ARMCPRegInfo dbgregs[] = {
!             { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
                .writefn = dbgbvr_write, .raw_writefn = raw_write
              },
!             { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
--- 6565,6580 ----
      }
  
      for (i = 0; i < brps; i++) {
+ 		char *dbgbvr_el1_name = g_strdup_printf("DBGBVR%d_EL1", i);
+ 		char *dbgbcr_el1_name = g_strdup_printf("DBGBCR%d_EL1", i);
          ARMCPRegInfo dbgregs[] = {
!             { .name = dbgbvr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
                .writefn = dbgbvr_write, .raw_writefn = raw_write
              },
!             { .name = dbgbcr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
***************
*** 6580,6596 ****
              },
          };
          define_arm_cp_regs(cpu, dbgregs);
      }
  
      for (i = 0; i < wrps; i++) {
          ARMCPRegInfo dbgregs[] = {
!             { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
                .writefn = dbgwvr_write, .raw_writefn = raw_write
              },
!             { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
--- 6582,6602 ----
              },
          };
          define_arm_cp_regs(cpu, dbgregs);
+         g_free(dbgbvr_el1_name);
+         g_free(dbgbcr_el1_name);
      }
  
      for (i = 0; i < wrps; i++) {
+ 		char *dbgwvr_el1_name = g_strdup_printf("DBGWVR%d_EL1", i);
+ 		char *dbgwcr_el1_name = g_strdup_printf("DBGWCR%d_EL1", i);
          ARMCPRegInfo dbgregs[] = {
!             { .name = dbgwvr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
                .writefn = dbgwvr_write, .raw_writefn = raw_write
              },
!             { .name = dbgwcr_el1_name, .state = ARM_CP_STATE_BOTH,
                .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
                .access = PL1_RW, .accessfn = access_tda,
                .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
***************
*** 6598,6603 ****
--- 6604,6611 ----
              },
          };
          define_arm_cp_regs(cpu, dbgregs);
+         g_free(dbgwvr_el1_name);
+         g_free(dbgwcr_el1_name);
      }
  }
  



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible bug in Aarch64 single-stepping
  2022-05-08 12:08 ` Possible bug in Aarch64 single-stepping Peter Maydell
@ 2022-05-08 19:35   ` Chris Howard
  0 siblings, 0 replies; 8+ messages in thread
From: Chris Howard @ 2022-05-08 19:35 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel

On 8. May 2022, at 14:08, Peter Maydell <peter.maydell@linaro.org> wrote:
> 
> On Sat, 7 May 2022 at 14:44, Chris Howard <cvz185@web.de> wrote:
>> 
>> 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?
> 
> I think you've misunderstood how the architectural single
> step works. This is described in section D2.12 of the Arm ARM
> (DDI0487H.a), but briefly, there is a state machine with three
> states: Inactive, Active-not-pending, and Active-pending.
> 
> * Inactive is when MDSCR_EL1.SS is 0 or debug exceptions are
> disabled from the current EL or security state.
> 
> * Active-not-pending is when we're not Inactive (ie MDSCR_EL1.SS is 1
> and so on) and PSTATE.SS is 1. This is the state for "we're currently
> pointing at the instruction we would like to step". The CPU
> does the step by doing "execute this one instruction, and then
> clear PSTATE.SS". It does *not* take a "single step completed"
> exception. (I ignore for the moment the possibility that the
> insn resulted in some other exception.)
> 
> * Active-pending is when we're not Inactive and PSTATE.SS is 0.
> This state means "Software step is active, and a software step
> is pending on the current instruction".
> The usual way we get here is that we were in Active-not-pending
> and then we executed the instruction and cleared PSTATE.SS.
> But you can also get here in other ways (as your test case does).
> In Active-pending state, the CPU does "take a software step
> exception immediately, without doing anything else" -- which is
> what you see.
> 
> In other words, the design effectively separates out the
> "execute one instruction" part from the "take the exception
> that says we completed a step" part. (This separation is
> irrelevant for the 'normal case' where the stepped instruction
> doesn't cause any exceptions and no interrupts arrive either,
> but it can matter if there is some interrupt to be taken. For
> instance, suppose that we do a step, and while the insn is
> executing an interrupt comes in that is routed to EL3. We
> want to take that interrupt first, before taking the
> 'single step complete' exception. Because the distinction
> between 'active-not-pending' and 'active-pending' is stored
> in PSTATE.SS, this works automatically -- we go to EL3, do
> whatever the interrupt handler does, and then on the eret
> to where we started, PSTATE.SS is restored to 0: so we then
> correctly take the 'single step complete' exception without
> executing another instruction.)
> 
> So if you don't want to see single-step exceptions you need
> to make sure you stay in the Inactive state.
> 
> thanks
> — PMM


I had indeed misunderstood :-) even though I had looked at that
section (and the state machine diagram)  :-/

Thanks for the EXCELLENT explanation! Very much appreciated.

—chris



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Possible bug in Aarch64 single-stepping [PATCH]
  2022-05-08 19:27     ` Possible bug in Aarch64 single-stepping [PATCH] Chris Howard
@ 2022-05-10  9:59       ` Peter Maydell
  0 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2022-05-10  9:59 UTC (permalink / raw)
  To: Chris Howard; +Cc: qemu-devel

On Sun, 8 May 2022 at 20:27, Chris Howard <cvz185@web.de> wrote:
> Thanks for the explanation. What with this being “pretty easy” I’m attempting my first ever patch!  :-)

Thanks for having a go at this. You've got the right basic
idea, but the process details of how to submit a patch aren't
quite right. We document all that stuff here:
https://www.qemu.org/docs/master/devel/submitting-a-patch.html
It's a pretty long document, but we've tried to put the important
stuff at the top. The really important bit is that patches must
have a "Signed-off-by:" line, which is how you say "I wrote
this code and it's OK for it to go into QEMU"; I can fix up
most of the other minor stuff at my end but without that we
can't take the patch at all.

It's also best to send patches as new threads, not as replies
to existing ones: the tooling (and some humans) assumes that.

> This is a context diff with respect to the cloned git repository (Version 7.0.50)

Unified diffs are much easier to read than context ones.
(If you create a proper git commit then "git show" and
"git format-patch" and so on ought to default to unified.)

> *** qemu/target/arm/helper.c    2022-05-08 20:41:48.000000000 +0200
> --- qemu-patch/target/arm/helper.c      2022-05-08 20:55:25.000000000 +0200
> ***************
> *** 6551,6559 ****
>           define_one_arm_cp_reg(cpu, &dbgdidr);
>       }
>
> !     /* Note that all these register fields hold "number of Xs minus 1". */
> !     brps = arm_num_brps(cpu);
> !     wrps = arm_num_wrps(cpu);
>       ctx_cmps = arm_num_ctx_cmps(cpu);
>
>       assert(ctx_cmps <= brps);
> --- 6551,6559 ----
>           define_one_arm_cp_reg(cpu, &dbgdidr);
>       }
>
> !     /* Note that all these reg fields (in ID_AA64DFR0_EL1) hold "number of Xs minus 1". */
> !     brps = arm_num_brps(cpu);                 /* returns actual number of breakpoints */
> !     wrps = arm_num_wrps(cpu);                 /* returns actual number of watchpoints */
>       ctx_cmps = arm_num_ctx_cmps(cpu);
>
>       assert(ctx_cmps <= brps);

I agree that the comment here is wrong, but this is an unrelated
change. We prefer to put separate changes in separate patches,
even if they're in close areas of the code.
I would just delete the existing comment line (as a separate patch)
-- it's clear enough that arm_num_brps() returns the number of
breakpoints, so we don't need to add extra comments saying so.
(The old comment is an accidental leftover from before we defined
those functions, when the code used to in-line extract values from
the ID register fields. The definitions of arm_num_brps() etc in
internals.h, where the ID-register reading now happens, already
have comments remarking about the fields being "num bps - 1".)

> ***************
> *** 6565,6578 ****

The rest of the change looks OK, assuming I'm reading the
context-diff correctly.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-05-10 10:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-07 13:42 Possible bug in Aarch64 single-stepping Chris Howard
2022-05-07 14:16 ` Chris Howard
2022-05-08 12:18   ` Peter Maydell
2022-05-08 12:19     ` Peter Maydell
2022-05-08 19:27     ` Possible bug in Aarch64 single-stepping [PATCH] Chris Howard
2022-05-10  9:59       ` Peter Maydell
2022-05-08 12:08 ` Possible bug in Aarch64 single-stepping Peter Maydell
2022-05-08 19:35   ` Chris Howard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.