target/riscv: define register printers

`riscv_debug_reg_to_s()` can be used to decode register value.  If the
pointer to buffer is `NULL` it does not print anything, just returns the
length of the string.

The format is:
`<register_value> { <field_name>=<field_value_name or field_value>, ..., }`

e.g:

`0x400382 { version=2, ... ndmresetpending=false, }`

`0x321009 { regno=0x1009, ... cmdtype=0, }`

Change-Id: I63733d8d36385d89ca15de1a43139134bc488c4f
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
This commit is contained in:
Evgeniy Naydanov 2023-07-17 21:09:37 +03:00
parent c07d9251aa
commit 43ebdd47a5
7 changed files with 4747 additions and 242 deletions

View File

@ -5,6 +5,7 @@ noinst_LTLIBRARIES += %D%/libriscv.la
%D%/asm.h \
%D%/batch.h \
%D%/debug_defines.h \
%D%/debug_reg_printer.h \
%D%/encoding.h \
%D%/gdb_regs.h \
%D%/opcodes.h \
@ -15,4 +16,6 @@ noinst_LTLIBRARIES += %D%/libriscv.la
%D%/riscv-011.c \
%D%/riscv-013.c \
%D%/riscv.c \
%D%/riscv_semihosting.c
%D%/riscv_semihosting.c \
%D%/debug_defines.c \
%D%/debug_reg_printer.c

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,10 @@
/*
* This file is auto-generated by running 'make debug_defines.h' in
* https://github.com/riscv/riscv-debug-spec/ (d749752)
* This file is auto-generated by running 'make debug_defines' in
* https://github.com/riscv/riscv-debug-spec/ (f546ddf)
*/
#ifndef DEBUG_DEFINES_H
#define DEBUG_DEFINES_H
#define DTM_IDCODE 0x01
/*
* Identifies the release version of this part.
@ -30,6 +32,39 @@
#define DTM_IDCODE_1_LENGTH 1
#define DTM_IDCODE_1 1
#define DTM_DTMCS 0x10
/*
* This optional field may provide additional detail about an error
* that occurred when communicating with a DM. It is updated whenever
* \FdtmDmiOp is updated by the hardware or when 1 is written to
* \FdtmDtmcsDmireset.
*/
#define DTM_DTMCS_ERRINFO_OFFSET 0x12
#define DTM_DTMCS_ERRINFO_LENGTH 3
#define DTM_DTMCS_ERRINFO 0x1c0000
/*
* not implemented: This field is not implemented.
*/
#define DTM_DTMCS_ERRINFO_NOT_IMPLEMENTED 0
/*
* dmi error: There was an error between the DTM and DMI.
*/
#define DTM_DTMCS_ERRINFO_DMI_ERROR 1
/*
* communication error: There was an error between the DMI and a DMI subordinate.
*/
#define DTM_DTMCS_ERRINFO_COMMUNICATION_ERROR 2
/*
* device error: The DMI subordinate reported an error.
*/
#define DTM_DTMCS_ERRINFO_DEVICE_ERROR 3
/*
* unknown: There is no error to report, or no further information available
* about the error. This is the reset value if the field is implemented.
*/
#define DTM_DTMCS_ERRINFO_UNKNOWN 4
/*
* Other values are reserved for future use by this specification.
*/
/*
* Writing 1 to this bit does a hard reset of the DTM,
* causing the DTM to forget about any outstanding DMI transactions, and
@ -39,12 +74,12 @@
* complete (e.g. a reset condition caused an inflight DMI transaction to
* be cancelled).
*/
#define DTM_DTMCS_DMIHARDRESET_OFFSET 0x11
#define DTM_DTMCS_DMIHARDRESET_LENGTH 1
#define DTM_DTMCS_DMIHARDRESET 0x20000
#define DTM_DTMCS_DTMHARDRESET_OFFSET 0x11
#define DTM_DTMCS_DTMHARDRESET_LENGTH 1
#define DTM_DTMCS_DTMHARDRESET 0x20000
/*
* Writing 1 to this bit clears the sticky error state, but does
* not affect outstanding DMI transactions.
* Writing 1 to this bit clears the sticky error state and resets
* \FdtmDtmcsErrinfo, but does not affect outstanding DMI transactions.
*/
#define DTM_DTMCS_DMIRESET_OFFSET 0x10
#define DTM_DTMCS_DMIRESET_LENGTH 1
@ -98,10 +133,12 @@
/*
* Address used for DMI access. In Update-DR this value is used
* to access the DM over the DMI.
* \FdtmDmiOp defines what this register contains after every possible
* operation.
*/
#define DTM_DMI_ADDRESS_OFFSET 0x22
#define DTM_DMI_ADDRESS_LENGTH(abits) abits
#define DTM_DMI_ADDRESS(abits) ((0x400000000ULL * (1ULL<<abits)) + -0x400000000ULL)
#define DTM_DMI_ADDRESS_LENGTH(abits) (abits)
#define DTM_DMI_ADDRESS(abits) ((0x400000000ULL * (1ULL << (abits))) + -0x400000000ULL)
/*
* The data to send to the DM over the DMI during Update-DR, and
* the data returned from the DM as a result of the previous operation.
@ -122,14 +159,24 @@
* This operation should never result in a busy or error response.
* The address and data reported in the following Capture-DR
* are undefined.
*
* This operation leaves the values in \FdtmDmiAddress and \FdtmDmiData
* \unspecified.
*/
#define DTM_DMI_OP_NOP 0
/*
* read: Read from \FdmSbaddressZeroAddress.
* read: Read from \FdtmDmiAddress.
*
* When this operation succeeds, \FdtmDmiAddress contains the address
* that was read from, and \FdtmDmiData contains the value that was
* read.
*/
#define DTM_DMI_OP_READ 1
/*
* write: Write \FdmSbdataZeroData to \FdmSbaddressZeroAddress.
* write: Write \FdtmDmiData to \FdtmDmiAddress.
*
* This operation leaves the values in \FdtmDmiAddress and \FdtmDmiData
* \unspecified.
*/
#define DTM_DMI_OP_WRITE 2
/*
@ -150,10 +197,13 @@
* this access will be ignored. This status is sticky and can be
* cleared by writing \FdtmDtmcsDmireset in \RdtmDtmcs.
*
* This indicates that the DM itself responded with an error.
* This indicates that the DM itself or the DMI responded with an error.
* There are no specified cases in which the DM would
* respond with an error, and DMI is not required to support
* returning errors.
*
* If a debugger sees this status, there might be additional
* information in \FdtmDtmcsErrinfo.
*/
#define DTM_DMI_OP_FAILED 2
/*
@ -259,11 +309,14 @@
#define CSR_DCSR_STEPIE_LENGTH 1
#define CSR_DCSR_STEPIE 0x800
/*
* interrupts disabled: Interrupts (including NMI) are disabled during single stepping.
* interrupts disabled: Interrupts (including NMI) are disabled during single stepping
* with \FcsrDcsrStep set.
* This value should be supported.
*/
#define CSR_DCSR_STEPIE_INTERRUPTS_DISABLED 0
/*
* interrupts enabled: Interrupts (including NMI) are enabled during single stepping.
* interrupts enabled: Interrupts (including NMI) are enabled during single stepping
* with \FcsrDcsrStep set.
*/
#define CSR_DCSR_STEPIE_INTERRUPTS_ENABLED 1
/*
@ -295,13 +348,16 @@
#define CSR_DCSR_STOPTIME_LENGTH 1
#define CSR_DCSR_STOPTIME 0x200
/*
* normal: Increment \Rtime as usual.
* normal: \Rtime continues to reflect \Rmtime.
*/
#define CSR_DCSR_STOPTIME_NORMAL 0
/*
* freeze: Don't increment \Rtime while in Debug Mode. If all harts
* have \FcsrDcsrStoptime=1 and are in Debug Mode then \Rmtime
* is also allowed to stop incrementing.
* freeze: \Rtime is frozen at the time that Debug Mode was entered. When
* leaving Debug Mode, \Rtime will reflect the latest
* value of \Rmtime again.
*
* While all harts have \FcsrDcsrStoptime=1 and are in Debug Mode,
* \Rmtime is allowed to stop incrementing.
*/
#define CSR_DCSR_STOPTIME_FREEZE 1
/*
@ -407,18 +463,18 @@
#define CSR_DCSR_PRV 3
#define CSR_DPC 0x7b1
#define CSR_DPC_DPC_OFFSET 0
#define CSR_DPC_DPC_LENGTH(DXLEN) DXLEN
#define CSR_DPC_DPC(DXLEN) ((1ULL<<DXLEN) + -1)
#define CSR_DPC_DPC_LENGTH(DXLEN) (DXLEN)
#define CSR_DPC_DPC(DXLEN) ((1ULL << (DXLEN)) + -1)
#define CSR_DSCRATCH0 0x7b2
#define CSR_DSCRATCH1 0x7b3
#define CSR_TSELECT 0x7a0
#define CSR_TSELECT_INDEX_OFFSET 0
#define CSR_TSELECT_INDEX_LENGTH(XLEN) XLEN
#define CSR_TSELECT_INDEX(XLEN) ((1ULL<<XLEN) + -1)
#define CSR_TSELECT_INDEX_LENGTH(XLEN) (XLEN)
#define CSR_TSELECT_INDEX(XLEN) ((1ULL << (XLEN)) + -1)
#define CSR_TDATA1 0x7a1
#define CSR_TDATA1_TYPE_OFFSET(XLEN) (XLEN + -4)
#define CSR_TDATA1_TYPE_OFFSET(XLEN) ((XLEN) + -4)
#define CSR_TDATA1_TYPE_LENGTH 4
#define CSR_TDATA1_TYPE(XLEN) (0xf * (1ULL<<(XLEN + -4)))
#define CSR_TDATA1_TYPE(XLEN) (0xf * (1ULL << ((XLEN) + -4)))
/*
* none: There is no trigger at this \RcsrTselect.
*/
@ -468,8 +524,9 @@
/*
* disabled: This trigger is disabled. In this state, \RcsrTdataTwo and
* \RcsrTdataThree can be written with any value that is supported for
* any of the types this trigger implements. The remaining bits in this
* register are ignored.
* any of the types this trigger implements.
* The remaining bits in this register, except for \FcsrTdataOneDmode,
* are ignored.
*/
#define CSR_TDATA1_TYPE_DISABLED 15
/*
@ -478,9 +535,9 @@
/*
* If \FcsrTdataOneType is 0, then this bit is hard-wired to 0.
*/
#define CSR_TDATA1_DMODE_OFFSET(XLEN) (XLEN + -5)
#define CSR_TDATA1_DMODE_OFFSET(XLEN) ((XLEN) + -5)
#define CSR_TDATA1_DMODE_LENGTH 1
#define CSR_TDATA1_DMODE(XLEN) (1ULL<<(XLEN + -5))
#define CSR_TDATA1_DMODE(XLEN) (1ULL << ((XLEN) + -5))
/*
* both: Both Debug and M-mode can write the {\tt tdata} registers at the
* selected \RcsrTselect.
@ -505,17 +562,42 @@
* Trigger-specific data.
*/
#define CSR_TDATA1_DATA_OFFSET 0
#define CSR_TDATA1_DATA_LENGTH(XLEN) (XLEN + -5)
#define CSR_TDATA1_DATA(XLEN) ((1ULL<<(XLEN + -5)) + -1)
#define CSR_TDATA1_DATA_LENGTH(XLEN) ((XLEN) + -5)
#define CSR_TDATA1_DATA(XLEN) ((1ULL << ((XLEN) + -5)) + -1)
#define CSR_TDATA2 0x7a2
#define CSR_TDATA2_DATA_OFFSET 0
#define CSR_TDATA2_DATA_LENGTH(XLEN) XLEN
#define CSR_TDATA2_DATA(XLEN) ((1ULL<<XLEN) + -1)
#define CSR_TDATA2_DATA_LENGTH(XLEN) (XLEN)
#define CSR_TDATA2_DATA(XLEN) ((1ULL << (XLEN)) + -1)
#define CSR_TDATA3 0x7a3
#define CSR_TDATA3_DATA_OFFSET 0
#define CSR_TDATA3_DATA_LENGTH(XLEN) XLEN
#define CSR_TDATA3_DATA(XLEN) ((1ULL<<XLEN) + -1)
#define CSR_TDATA3_DATA_LENGTH(XLEN) (XLEN)
#define CSR_TDATA3_DATA(XLEN) ((1ULL << (XLEN)) + -1)
#define CSR_TINFO 0x7a4
/*
* Contains the version of the Sdtrig extension implemented.
*/
#define CSR_TINFO_VERSION_OFFSET 0x18
#define CSR_TINFO_VERSION_LENGTH 8
#define CSR_TINFO_VERSION 0xff000000U
/*
* 0: Supports triggers as described in this spec at commit 5a5c078,
* made on February 2, 2023.
*
* \begin{steps}{In these older versions:}
* \item \RcsrMcontrolSix has a timing bit identical to
* \FcsrMcontrolTiming
* \item \FcsrMcontrolSixHitZero behaves just as \FcsrMcontrolHit.
* \item \FcsrMcontrolSixHitOne is read-only 0.
* \item Encodings for \FcsrMcontrolSixSize for access sizes larger
* than 64 bits are different.
* \end{steps}
*/
#define CSR_TINFO_VERSION_0 0
/*
* 1: Supports triggers as described in the ratified version 1.0 of
* this document.
*/
#define CSR_TINFO_VERSION_1 1
/*
* One bit for each possible \FcsrTdataOneType enumerated in \RcsrTdataOne. Bit N
* corresponds to type N. If the bit is set, then that type is
@ -573,8 +655,8 @@
* and 14 on RV64.
*/
#define CSR_HCONTEXT_HCONTEXT_OFFSET 0
#define CSR_HCONTEXT_HCONTEXT_LENGTH(XLEN) XLEN
#define CSR_HCONTEXT_HCONTEXT(XLEN) ((1ULL<<XLEN) + -1)
#define CSR_HCONTEXT_HCONTEXT_LENGTH(XLEN) (XLEN)
#define CSR_HCONTEXT_HCONTEXT(XLEN) ((1ULL << (XLEN)) + -1)
#define CSR_SCONTEXT 0x5a8
/*
* Supervisor mode software can write a context number to this
@ -586,17 +668,17 @@
* 34 on RV64.
*/
#define CSR_SCONTEXT_DATA_OFFSET 0
#define CSR_SCONTEXT_DATA_LENGTH(XLEN) XLEN
#define CSR_SCONTEXT_DATA(XLEN) ((1ULL<<XLEN) + -1)
#define CSR_SCONTEXT_DATA_LENGTH(XLEN) (XLEN)
#define CSR_SCONTEXT_DATA(XLEN) ((1ULL << (XLEN)) + -1)
#define CSR_MCONTEXT 0x7a8
#define CSR_MSCONTEXT 0x7aa
#define CSR_MCONTROL 0x7a1
#define CSR_MCONTROL_TYPE_OFFSET(XLEN) (XLEN + -4)
#define CSR_MCONTROL_TYPE_OFFSET(XLEN) ((XLEN) + -4)
#define CSR_MCONTROL_TYPE_LENGTH 4
#define CSR_MCONTROL_TYPE(XLEN) (0xf * (1ULL<<(XLEN + -4)))
#define CSR_MCONTROL_DMODE_OFFSET(XLEN) (XLEN + -5)
#define CSR_MCONTROL_TYPE(XLEN) (0xf * (1ULL << ((XLEN) + -4)))
#define CSR_MCONTROL_DMODE_OFFSET(XLEN) ((XLEN) + -5)
#define CSR_MCONTROL_DMODE_LENGTH 1
#define CSR_MCONTROL_DMODE(XLEN) (1ULL<<(XLEN + -5))
#define CSR_MCONTROL_DMODE(XLEN) (1ULL << ((XLEN) + -5))
/*
* Specifies the largest naturally aligned powers-of-two (NAPOT) range
* supported by the hardware when \FcsrMcontrolMatch is 1. The value is the
@ -605,9 +687,9 @@
* A value of 63 corresponds to the maximum NAPOT range, which is
* $2^{63}$ bytes in size.
*/
#define CSR_MCONTROL_MASKMAX_OFFSET(XLEN) (XLEN + -0xb)
#define CSR_MCONTROL_MASKMAX_OFFSET(XLEN) ((XLEN) + -0xb)
#define CSR_MCONTROL_MASKMAX_LENGTH 6
#define CSR_MCONTROL_MASKMAX(XLEN) (0x3f * (1ULL<<(XLEN + -0xb)))
#define CSR_MCONTROL_MASKMAX(XLEN) (0x3f * (1ULL << ((XLEN) + -0xb)))
/*
* This field only exists when XLEN is at least 64.
* It contains the 2 high bits of the access size. The low bits
@ -654,8 +736,8 @@
#define CSR_MCONTROL_TIMING 0x40000
/*
* before: The action for this trigger will be taken just before the
* instruction that triggered it is committed, but after all preceding
* instructions are committed. \Rxepc or \RcsrDpc (depending
* instruction that triggered it is retired, but after all preceding
* instructions are retired. \Rxepc or \RcsrDpc (depending
* on \FcsrMcontrolAction) must be set to the virtual address of the
* instruction that matched.
*
@ -669,8 +751,8 @@
#define CSR_MCONTROL_TIMING_BEFORE 0
/*
* after: The action for this trigger will be taken after the instruction
* that triggered it is committed. It should be taken before the next
* instruction is committed, but it is better to implement triggers imprecisely
* that triggered it is retired. It should be taken before the next
* instruction is retired, but it is better to implement triggers imprecisely
* than to not implement them at all. \Rxepc or
* \RcsrDpc (depending on \FcsrMcontrolAction) must be set to
* the virtual address of the next instruction that must be executed to
@ -946,12 +1028,33 @@
#define CSR_MCONTROL_LOAD_LENGTH 1
#define CSR_MCONTROL_LOAD 1
#define CSR_MCONTROL6 0x7a1
#define CSR_MCONTROL6_TYPE_OFFSET(XLEN) (XLEN + -4)
#define CSR_MCONTROL6_TYPE_OFFSET(XLEN) ((XLEN) + -4)
#define CSR_MCONTROL6_TYPE_LENGTH 4
#define CSR_MCONTROL6_TYPE(XLEN) (0xf * (1ULL<<(XLEN + -4)))
#define CSR_MCONTROL6_DMODE_OFFSET(XLEN) (XLEN + -5)
#define CSR_MCONTROL6_TYPE(XLEN) (0xf * (1ULL << ((XLEN) + -4)))
#define CSR_MCONTROL6_DMODE_OFFSET(XLEN) ((XLEN) + -5)
#define CSR_MCONTROL6_DMODE_LENGTH 1
#define CSR_MCONTROL6_DMODE(XLEN) (1ULL<<(XLEN + -5))
#define CSR_MCONTROL6_DMODE(XLEN) (1ULL << ((XLEN) + -5))
/*
* This bit should be updated every time that \FcsrMcontrolSixHitZero
* or \FcsrMcontrolSixHitOne is updated.
*/
#define CSR_MCONTROL6_UNCERTAIN_OFFSET 0x1a
#define CSR_MCONTROL6_UNCERTAIN_LENGTH 1
#define CSR_MCONTROL6_UNCERTAIN 0x4000000
/*
* certain: The trigger that fired satisfied the configured conditions, or
* this bit is not implemented.
*/
#define CSR_MCONTROL6_UNCERTAIN_CERTAIN 0
/*
* uncertain: The trigger that fired might not have perfectly satisfied the
* configured conditions. Due to the implementation the hardware
* cannot be certain.
*/
#define CSR_MCONTROL6_UNCERTAIN_UNCERTAIN 1
#define CSR_MCONTROL6_HIT1_OFFSET 0x19
#define CSR_MCONTROL6_HIT1_LENGTH 1
#define CSR_MCONTROL6_HIT1 0x2000000
/*
* When set, enable this trigger in VS-mode.
* This bit is hard-wired to 0 if the hart does not support
@ -969,16 +1072,50 @@
#define CSR_MCONTROL6_VU_LENGTH 1
#define CSR_MCONTROL6_VU 0x800000
/*
* If this bit is implemented then it must become set when this
* trigger fires and may become set when this trigger matches.
* The trigger's user can set or clear it at any
* time. It is used to determine which
* trigger(s) matched. If the bit is not implemented, it is always 0
* and writing it has no effect.
* If they are implemented, \FcsrMcontrolSixHitOne (MSB) and
* \FcsrMcontrolSixHitZero (LSB) combine into a single 2-bit field.
* The TM updates this field when the trigger fires. After the debugger
* has seen the update, it will normally write 0 to this field to so it
* can see future changes.
*
* If either of the bits is not implemented, the unimplemented bits
* will be read-only 0.
*/
#define CSR_MCONTROL6_HIT_OFFSET 0x16
#define CSR_MCONTROL6_HIT_LENGTH 1
#define CSR_MCONTROL6_HIT 0x400000
#define CSR_MCONTROL6_HIT0_OFFSET 0x16
#define CSR_MCONTROL6_HIT0_LENGTH 1
#define CSR_MCONTROL6_HIT0 0x400000
/*
* false: The trigger did not fire.
*/
#define CSR_MCONTROL6_HIT0_FALSE 0
/*
* before: The trigger fired just before the instruction that triggered it was
* retired, but after all preceding instructions are retired.
* \Rxepc or \RcsrDpc (depending on \FcsrMcontrolSixAction) must be set
* to the virtual address of the instruction that matched.
*
* If a load operation matched and \FcsrMcontrolSixSelect=1 then a
* memory access has been performed (including any side effects of
* performing such an access) even though the load has not updated its
* destination register.
*/
#define CSR_MCONTROL6_HIT0_BEFORE 1
/*
* after: The trigger fired after the instruction that triggered and at least
* one additional instruction were retired.
* \Rxepc or \RcsrDpc (depending on \FcsrMcontrolSixAction) must be set
* to the virtual address of the next instruction that must be executed
* to preserve the program flow.
*/
#define CSR_MCONTROL6_HIT0_AFTER 2
/*
* immediately after: The trigger fired just after the instruction that triggered it was
* retired, but before any subsequent instructions were executed.
* \Rxepc or \RcsrDpc (depending on \FcsrMcontrolSixAction) must be set
* to the virtual address of the next instruction that must be executed
* to preserve the program flow.
*/
#define CSR_MCONTROL6_HIT0_IMMEDIATELY_AFTER 3
/*
* This bit determines the contents of the XLEN-bit compare values.
*/
@ -1000,54 +1137,9 @@
* Any bits beyond the size of the data access will contain 0.
*/
#define CSR_MCONTROL6_SELECT_DATA 1
#define CSR_MCONTROL6_TIMING_OFFSET 0x14
#define CSR_MCONTROL6_TIMING_LENGTH 1
#define CSR_MCONTROL6_TIMING 0x100000
/*
* before: The action for this trigger will be taken just before the
* instruction that triggered it is committed, but after all preceding
* instructions are committed. \Rxepc or \RcsrDpc (depending
* on \FcsrMcontrolSixAction) must be set to the virtual address of the
* instruction that matched.
*
* If this is combined with \FcsrMcontrolSixLoad and
* \FcsrMcontrolSixSelect=1 then a memory access will be
* performed (including any side effects of performing such an access) even
* though the load will not update its destination register. Debuggers
* should consider this when setting such breakpoints on, for example,
* memory-mapped I/O addresses.
*/
#define CSR_MCONTROL6_TIMING_BEFORE 0
/*
* after: The action for this trigger will be taken after the instruction
* that triggered it is committed. It should be taken before the next
* instruction is committed, but it is better to implement triggers imprecisely
* than to not implement them at all. \Rxepc or
* \RcsrDpc (depending on \FcsrMcontrolSixAction) must be set to
* the virtual address of the next instruction that must be executed to
* preserve the program flow.
*/
#define CSR_MCONTROL6_TIMING_AFTER 1
/*
* Most hardware will only implement one timing or the other, possibly
* dependent on \FcsrMcontrolSixSelect, \FcsrMcontrolSixExecute,
* \FcsrMcontrolSixLoad, and \FcsrMcontrolSixStore. This bit
* primarily exists for the hardware to communicate to the debugger
* what will happen. Hardware may implement the bit fully writable, in
* which case the debugger has a little more control.
*
* Data load triggers with \FcsrMcontrolSixTiming of 0 will result in the same load
* happening again when the debugger lets the hart run. For data load
* triggers, debuggers must first attempt to set the breakpoint with
* \FcsrMcontrolSixTiming of 1.
*
* If a trigger with \FcsrMcontrolSixTiming of 0 matches, it is
* implementation-dependent whether that prevents a trigger with
* \FcsrMcontrolSixTiming of 1 matching as well.
*/
#define CSR_MCONTROL6_SIZE_OFFSET 0x10
#define CSR_MCONTROL6_SIZE_LENGTH 4
#define CSR_MCONTROL6_SIZE 0xf0000
#define CSR_MCONTROL6_SIZE_LENGTH 3
#define CSR_MCONTROL6_SIZE 0x70000
/*
* any: The trigger will attempt to match against an access of any size.
* The behavior is only well-defined if $|select|=0$, or if the access
@ -1077,23 +1169,11 @@
* execution of 64-bit instructions.
*/
#define CSR_MCONTROL6_SIZE_64BIT 5
/*
* 80bit: The trigger will only match against execution of 80-bit instructions.
*/
#define CSR_MCONTROL6_SIZE_80BIT 6
/*
* 96bit: The trigger will only match against execution of 96-bit instructions.
*/
#define CSR_MCONTROL6_SIZE_96BIT 7
/*
* 112bit: The trigger will only match against execution of 112-bit instructions.
*/
#define CSR_MCONTROL6_SIZE_112BIT 8
/*
* 128bit: The trigger will only match against 128-bit memory accesses or
* execution of 128-bit instructions.
*/
#define CSR_MCONTROL6_SIZE_128BIT 9
#define CSR_MCONTROL6_SIZE_128BIT 6
/*
* An implementation must support the value of 0, but all other values
* are optional. When an implementation supports address triggers
@ -1257,6 +1337,20 @@
#define CSR_MCONTROL6_M_OFFSET 6
#define CSR_MCONTROL6_M_LENGTH 1
#define CSR_MCONTROL6_M 0x40
#define CSR_MCONTROL6_UNCERTAINEN_OFFSET 5
#define CSR_MCONTROL6_UNCERTAINEN_LENGTH 1
#define CSR_MCONTROL6_UNCERTAINEN 0x20
/*
* disabled: This trigger will only match if the hardware can perfectly
* evaluate it.
*/
#define CSR_MCONTROL6_UNCERTAINEN_DISABLED 0
/*
* enabled: This trigger will match if it's possible that it would match if
* the Trigger Module had perfect information about the operations
* being performed.
*/
#define CSR_MCONTROL6_UNCERTAINEN_ENABLED 1
/*
* When set, enable this trigger in S/HS-mode.
* This bit is hard-wired to 0 if the hart does not support
@ -1295,12 +1389,12 @@
#define CSR_MCONTROL6_LOAD_LENGTH 1
#define CSR_MCONTROL6_LOAD 1
#define CSR_ICOUNT 0x7a1
#define CSR_ICOUNT_TYPE_OFFSET(XLEN) (XLEN + -4)
#define CSR_ICOUNT_TYPE_OFFSET(XLEN) ((XLEN) + -4)
#define CSR_ICOUNT_TYPE_LENGTH 4
#define CSR_ICOUNT_TYPE(XLEN) (0xf * (1ULL<<(XLEN + -4)))
#define CSR_ICOUNT_DMODE_OFFSET(XLEN) (XLEN + -5)
#define CSR_ICOUNT_TYPE(XLEN) (0xf * (1ULL << ((XLEN) + -4)))
#define CSR_ICOUNT_DMODE_OFFSET(XLEN) ((XLEN) + -5)
#define CSR_ICOUNT_DMODE_LENGTH 1
#define CSR_ICOUNT_DMODE(XLEN) (1ULL<<(XLEN + -5))
#define CSR_ICOUNT_DMODE(XLEN) (1ULL << ((XLEN) + -5))
/*
* When set, enable this trigger in VS-mode.
* This bit is hard-wired to 0 if the hart does not support
@ -1400,12 +1494,12 @@
*/
#define CSR_ICOUNT_ACTION_EXTERNAL1 9
#define CSR_ITRIGGER 0x7a1
#define CSR_ITRIGGER_TYPE_OFFSET(XLEN) (XLEN + -4)
#define CSR_ITRIGGER_TYPE_OFFSET(XLEN) ((XLEN) + -4)
#define CSR_ITRIGGER_TYPE_LENGTH 4
#define CSR_ITRIGGER_TYPE(XLEN) (0xf * (1ULL<<(XLEN + -4)))
#define CSR_ITRIGGER_DMODE_OFFSET(XLEN) (XLEN + -5)
#define CSR_ITRIGGER_TYPE(XLEN) (0xf * (1ULL << ((XLEN) + -4)))
#define CSR_ITRIGGER_DMODE_OFFSET(XLEN) ((XLEN) + -5)
#define CSR_ITRIGGER_DMODE_LENGTH 1
#define CSR_ITRIGGER_DMODE(XLEN) (1ULL<<(XLEN + -5))
#define CSR_ITRIGGER_DMODE(XLEN) (1ULL << ((XLEN) + -5))
/*
* If this bit is implemented, the hardware sets it when this
* trigger matches. The trigger's user can set or clear it at any
@ -1413,9 +1507,9 @@
* trigger(s) matched. If the bit is not implemented, it is always 0
* and writing it has no effect.
*/
#define CSR_ITRIGGER_HIT_OFFSET(XLEN) (XLEN + -6)
#define CSR_ITRIGGER_HIT_OFFSET(XLEN) ((XLEN) + -6)
#define CSR_ITRIGGER_HIT_LENGTH 1
#define CSR_ITRIGGER_HIT(XLEN) (1ULL<<(XLEN + -6))
#define CSR_ITRIGGER_HIT(XLEN) (1ULL << ((XLEN) + -6))
/*
* When set, enable this trigger for interrupts that are taken from VS
* mode.
@ -1502,12 +1596,12 @@
*/
#define CSR_ITRIGGER_ACTION_EXTERNAL1 9
#define CSR_ETRIGGER 0x7a1
#define CSR_ETRIGGER_TYPE_OFFSET(XLEN) (XLEN + -4)
#define CSR_ETRIGGER_TYPE_OFFSET(XLEN) ((XLEN) + -4)
#define CSR_ETRIGGER_TYPE_LENGTH 4
#define CSR_ETRIGGER_TYPE(XLEN) (0xf * (1ULL<<(XLEN + -4)))
#define CSR_ETRIGGER_DMODE_OFFSET(XLEN) (XLEN + -5)
#define CSR_ETRIGGER_TYPE(XLEN) (0xf * (1ULL << ((XLEN) + -4)))
#define CSR_ETRIGGER_DMODE_OFFSET(XLEN) ((XLEN) + -5)
#define CSR_ETRIGGER_DMODE_LENGTH 1
#define CSR_ETRIGGER_DMODE(XLEN) (1ULL<<(XLEN + -5))
#define CSR_ETRIGGER_DMODE(XLEN) (1ULL << ((XLEN) + -5))
/*
* If this bit is implemented, the hardware sets it when this
* trigger matches. The trigger's user can set or clear it at any
@ -1515,9 +1609,9 @@
* trigger(s) matched. If the bit is not implemented, it is always 0
* and writing it has no effect.
*/
#define CSR_ETRIGGER_HIT_OFFSET(XLEN) (XLEN + -6)
#define CSR_ETRIGGER_HIT_OFFSET(XLEN) ((XLEN) + -6)
#define CSR_ETRIGGER_HIT_LENGTH 1
#define CSR_ETRIGGER_HIT(XLEN) (1ULL<<(XLEN + -6))
#define CSR_ETRIGGER_HIT(XLEN) (1ULL << ((XLEN) + -6))
/*
* When set, enable this trigger for exceptions that are taken from VS
* mode.
@ -1597,12 +1691,12 @@
*/
#define CSR_ETRIGGER_ACTION_EXTERNAL1 9
#define CSR_TMEXTTRIGGER 0x7a1
#define CSR_TMEXTTRIGGER_TYPE_OFFSET(XLEN) (XLEN + -4)
#define CSR_TMEXTTRIGGER_TYPE_OFFSET(XLEN) ((XLEN) + -4)
#define CSR_TMEXTTRIGGER_TYPE_LENGTH 4
#define CSR_TMEXTTRIGGER_TYPE(XLEN) (0xf * (1ULL<<(XLEN + -4)))
#define CSR_TMEXTTRIGGER_DMODE_OFFSET(XLEN) (XLEN + -5)
#define CSR_TMEXTTRIGGER_TYPE(XLEN) (0xf * (1ULL << ((XLEN) + -4)))
#define CSR_TMEXTTRIGGER_DMODE_OFFSET(XLEN) ((XLEN) + -5)
#define CSR_TMEXTTRIGGER_DMODE_LENGTH 1
#define CSR_TMEXTTRIGGER_DMODE(XLEN) (1ULL<<(XLEN + -5))
#define CSR_TMEXTTRIGGER_DMODE(XLEN) (1ULL << ((XLEN) + -5))
/*
* If this bit is implemented, the hardware sets it when this
* trigger matches. The trigger's user can set or clear it at any
@ -1610,9 +1704,9 @@
* trigger(s) matched. If the bit is not implemented, it is always 0
* and writing it has no effect.
*/
#define CSR_TMEXTTRIGGER_HIT_OFFSET(XLEN) (XLEN + -6)
#define CSR_TMEXTTRIGGER_HIT_OFFSET(XLEN) ((XLEN) + -6)
#define CSR_TMEXTTRIGGER_HIT_LENGTH 1
#define CSR_TMEXTTRIGGER_HIT(XLEN) (1ULL<<(XLEN + -6))
#define CSR_TMEXTTRIGGER_HIT(XLEN) (1ULL << ((XLEN) + -6))
/*
* This optional bit, when set, causes this trigger to fire whenever an attached
* interrupt controller signals a trigger.
@ -1621,7 +1715,7 @@
#define CSR_TMEXTTRIGGER_INTCTL_LENGTH 1
#define CSR_TMEXTTRIGGER_INTCTL 0x400000
/*
* Selects any combination of up to 16 external debug trigger inputs
* Selects any combination of up to 16 TM external trigger inputs
* that cause this trigger to fire.
*/
#define CSR_TMEXTTRIGGER_SELECT_OFFSET 6
@ -1677,15 +1771,17 @@
*/
#define CSR_TEXTRA32_MHSELECT_IGNORE 0
/*
* mcontext: This trigger will only match if the low bits of
* mcontext: This trigger will only match or fire if the low bits of
* \RcsrMcontext/\RcsrHcontext equal \FcsrTextraThirtytwoMhvalue.
*/
#define CSR_TEXTRA32_MHSELECT_MCONTEXT 4
/*
* 1, 5 (mcontext\_select): This trigger will only match if the low bits of
* 1, 5 (mcontext\_select): This trigger will only match or fire if the
* low bits of
* \RcsrMcontext/\RcsrHcontext equal \{\FcsrTextraThirtytwoMhvalue, mhselect[2]\}.
*
* 2, 6 (vmid\_select): This trigger will only match if VMID in hgatp equals the lower VMIDMAX
* 2, 6 (vmid\_select): This trigger will only match or fire if VMID in
* hgatp equals the lower VMIDMAX
* (defined in the Privileged Spec) bits of \{\FcsrTextraThirtytwoMhvalue, mhselect[2]\}.
*
* 3, 7 (reserved): Reserved.
@ -1717,12 +1813,12 @@
*/
#define CSR_TEXTRA32_SSELECT_IGNORE 0
/*
* scontext: This trigger will only match if the low bits of
* scontext: This trigger will only match or fire if the low bits of
* \RcsrScontext equal \FcsrTextraThirtytwoSvalue.
*/
#define CSR_TEXTRA32_SSELECT_SCONTEXT 1
/*
* asid: This trigger will only match if:
* asid: This trigger will only match or fire if:
* \begin{itemize}[noitemsep,nolistsep]
* \item the mode is VS-mode or VU-mode and ASID in \Rvsatp
* equals the lower ASIDMAX (defined in the Privileged Spec) bits
@ -2187,9 +2283,8 @@
* If \FdmHartinfoDataaccess is 1: Number of 32-bit words in the memory map
* dedicated to shadowing the {\tt data} registers.
*
* If this value is non-zero, then the {tt data} registers must go
* beyond being MRs and guarantee they each store a single value, that is
* readable/writable by either side.
* If this value is non-zero, then the {tt data} registers must be
* traditional registers and not MRs.
*
* Since there are at most 12 {\tt data} registers, the value in this
* register must be 12 or smaller.
@ -2250,12 +2345,19 @@
* permission checks that apply based on the current architectural
* state of the hart performing the access, or with a relaxed set of
* permission checks (e.g. PMP restrictions are ignored). The
* details of the latter are implementation-specific. When set to 0,
* full permissions apply; when set to 1, relaxed permissions apply.
* details of the latter are implementation-specific.
*/
#define DM_ABSTRACTCS_RELAXEDPRIV_OFFSET 0xb
#define DM_ABSTRACTCS_RELAXEDPRIV_LENGTH 1
#define DM_ABSTRACTCS_RELAXEDPRIV 0x800
/*
* full checks: Full permission checks apply.
*/
#define DM_ABSTRACTCS_RELAXEDPRIV_FULL_CHECKS 0
/*
* relaxed checks: Relaxed permission checks apply.
*/
#define DM_ABSTRACTCS_RELAXEDPRIV_RELAXED_CHECKS 1
/*
* Gets set if an abstract command fails. The bits in this field remain set until
* they are cleared by writing 1 to them. No abstract command is
@ -2524,7 +2626,7 @@
#define DM_SBCS_SBBUSYERROR_LENGTH 1
#define DM_SBCS_SBBUSYERROR 0x400000
/*
* When 1, indicates the system bus master is busy. (Whether the
* When 1, indicates the system bus manager is busy. (Whether the
* system bus itself is busy is related, but not the same thing.) This
* bit goes high immediately when a read or write is requested for any
* reason, and does not go low until the access is fully completed.
@ -2589,7 +2691,7 @@
#define DM_SBCS_SBREADONDATA 0x8000
/*
* When the Debug Module's system bus
* master encounters an error, this field gets set. The bits in this
* manager encounters an error, this field gets set. The bits in this
* field remain set until they are cleared by writing 1 to them.
* While this field is non-zero, no more system bus accesses can be
* initiated by the Debug Module.
@ -2908,6 +3010,10 @@
* {\tt arg1} (which contains the address used) by the number of bytes
* encoded in \FacAccessmemoryAamsize.
*
* Implementations that allow this bit to be 1 must implement the
* relevant {\tt data} registers as traditional registers instead of
* MRs.
*
* Supporting this variant is optional, but highly recommended for
* performance reasons.
*/
@ -3059,3 +3165,93 @@
#define DMI_SERRX_DATA_OFFSET 0
#define DMI_SERRX_DATA_LENGTH 0x20
#define DMI_SERRX_DATA 0xffffffffU
enum riscv_debug_reg_ordinal {
DTM_IDCODE_ORDINAL,
DTM_DTMCS_ORDINAL,
DTM_DMI_ORDINAL,
DTM_BYPASS_ORDINAL,
CSR_DCSR_ORDINAL,
CSR_DPC_ORDINAL,
CSR_TSELECT_ORDINAL,
CSR_TDATA1_ORDINAL,
CSR_TDATA2_ORDINAL,
CSR_TDATA3_ORDINAL,
CSR_TINFO_ORDINAL,
CSR_TCONTROL_ORDINAL,
CSR_HCONTEXT_ORDINAL,
CSR_SCONTEXT_ORDINAL,
CSR_MCONTROL_ORDINAL,
CSR_MCONTROL6_ORDINAL,
CSR_ICOUNT_ORDINAL,
CSR_ITRIGGER_ORDINAL,
CSR_ETRIGGER_ORDINAL,
CSR_TMEXTTRIGGER_ORDINAL,
CSR_TEXTRA32_ORDINAL,
CSR_TEXTRA64_ORDINAL,
DM_DMSTATUS_ORDINAL,
DM_DMCONTROL_ORDINAL,
DM_HARTINFO_ORDINAL,
DM_HAWINDOWSEL_ORDINAL,
DM_HAWINDOW_ORDINAL,
DM_ABSTRACTCS_ORDINAL,
DM_COMMAND_ORDINAL,
DM_ABSTRACTAUTO_ORDINAL,
DM_CONFSTRPTR0_ORDINAL,
DM_CONFSTRPTR1_ORDINAL,
DM_CONFSTRPTR2_ORDINAL,
DM_CONFSTRPTR3_ORDINAL,
DM_NEXTDM_ORDINAL,
DM_DATA0_ORDINAL,
DM_PROGBUF0_ORDINAL,
DM_AUTHDATA_ORDINAL,
DM_DMCS2_ORDINAL,
DM_HALTSUM0_ORDINAL,
DM_HALTSUM1_ORDINAL,
DM_HALTSUM2_ORDINAL,
DM_HALTSUM3_ORDINAL,
DM_SBCS_ORDINAL,
DM_SBADDRESS0_ORDINAL,
DM_SBADDRESS1_ORDINAL,
DM_SBADDRESS2_ORDINAL,
DM_SBADDRESS3_ORDINAL,
DM_SBDATA0_ORDINAL,
DM_SBDATA1_ORDINAL,
DM_SBDATA2_ORDINAL,
DM_SBDATA3_ORDINAL,
SHORTNAME_ORDINAL,
AC_ACCESS_REGISTER_ORDINAL,
AC_QUICK_ACCESS_ORDINAL,
AC_ACCESS_MEMORY_ORDINAL,
VIRT_PRIV_ORDINAL,
DMI_SERCS_ORDINAL,
DMI_SERTX_ORDINAL,
DMI_SERRX_ORDINAL
};
typedef struct {
struct {
unsigned int value; int is_set;
} DXLEN;
struct {
unsigned int value; int is_set;
} XLEN;
struct {
unsigned int value; int is_set;
} abits;
} riscv_debug_reg_ctx_t;
typedef struct {
const char *name;
unsigned int lsb; // inclusive
unsigned int msb; // inclusive
const char **values; // If non-NULL, array of human-readable string for each possible value
} riscv_debug_reg_field_info_t;
typedef struct riscv_debug_reg_field_list_t {
riscv_debug_reg_field_info_t field;
struct riscv_debug_reg_field_list_t (*get_next)(riscv_debug_reg_ctx_t context);
} riscv_debug_reg_field_list_t;
typedef struct {
const char *name;
struct riscv_debug_reg_field_list_t (* const get_fields_head)(riscv_debug_reg_ctx_t context);
} riscv_debug_reg_info_t;
riscv_debug_reg_info_t get_riscv_debug_reg_info(enum riscv_debug_reg_ordinal reg_ordinal);
#endif

View File

@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <stdio.h>
#include <inttypes.h>
#include <assert.h>
#include <stdarg.h>
#include "debug_reg_printer.h"
static unsigned int get_len_or_sprintf(char *buf, unsigned int curr, const char *format, ...)
{
assert(format);
va_list args;
int length;
va_start(args, format);
if (buf)
length = vsprintf(buf + curr, format, args);
else
length = vsnprintf(NULL, 0, format, args);
va_end(args);
assert(length >= 0);
return (unsigned int)length;
}
static unsigned int print_number(char *buf, unsigned int offset, uint64_t value)
{
const char * const format = value > 9 ? "0x%" PRIx64 : "%" PRIx64;
return get_len_or_sprintf(buf, offset, format, value);
}
static unsigned int riscv_debug_reg_field_value_to_s(char *buf, unsigned int offset,
const char * const *field_value_names, uint64_t field_value)
{
const char * const field_value_name = field_value_names ?
field_value_names[field_value] :
NULL;
if (!field_value_name)
return print_number(buf, offset, field_value);
return get_len_or_sprintf(buf, offset, "%s", field_value_name);
}
static unsigned int riscv_debug_reg_field_to_s(char *buf, unsigned int offset,
riscv_debug_reg_field_info_t field, riscv_debug_reg_ctx_t context,
uint64_t field_value)
{
const unsigned int name_len = get_len_or_sprintf(buf, offset, "%s=", field.name);
return name_len + riscv_debug_reg_field_value_to_s(buf, offset + name_len,
field.values, field_value);
}
static uint64_t riscv_debug_reg_field_value(riscv_debug_reg_field_info_t field, uint64_t value)
{
assert(field.msb < 64);
assert(field.msb >= field.lsb);
const uint64_t trailing_ones_mask = (uint64_t)(-1) >> (63 - field.msb);
return (value & trailing_ones_mask) >> field.lsb;
}
static unsigned int riscv_debug_reg_fields_to_s(char *buf, unsigned int offset,
riscv_debug_reg_field_list_t list, riscv_debug_reg_ctx_t context, uint64_t value)
{
unsigned int curr = offset;
curr += get_len_or_sprintf(buf, curr, " { ");
for (; list.get_next; list = list.get_next(context)) {
curr += riscv_debug_reg_field_to_s(buf, curr, list.field, context,
riscv_debug_reg_field_value(list.field, value));
curr += get_len_or_sprintf(buf, curr, ", ");
}
curr += get_len_or_sprintf(buf, curr, "}");
return curr - offset;
}
unsigned int riscv_debug_reg_to_s(char *buf, enum riscv_debug_reg_ordinal reg_ordinal,
riscv_debug_reg_ctx_t context, uint64_t value)
{
unsigned int length = 0;
riscv_debug_reg_info_t reg = get_riscv_debug_reg_info(reg_ordinal);
length += get_len_or_sprintf(buf, length, "%s=", reg.name);
length += print_number(buf, length, value);
if (reg.get_fields_head)
length += riscv_debug_reg_fields_to_s(buf, length, reg.get_fields_head(context),
context, value);
if (buf)
buf[length] = '\0';
return length;
}

View File

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "debug_defines.h"
/**
* This function is used to fill a buffer with a decoded string representation
* of register's value.
* @param buf If non-NULL, the buffer to write the string into.
* Otherwise, the function does not perform any writes,
* it just calculates the number of characters used.
* @param reg_ordinal
* The ordinal of the register.
* @param context The structure, containing the information about the target,
* necessary to decode the register.
* @param value The value to be decoded.
*
* Returns the number of characters used by the string representation
* (excluding '\0').
*
* Example:
* const struct riscv_debug_reg_ctx_t context = {
* .abits = { .value = <abits value>, .is_set = true }
* };
* char buf[riscv_debug_reg_to_s(NULL, DTM_DMI_ORDINAL, context, <dmi value>) + 1]
* riscv_debug_reg_to_s(buf, DTM_DMI_ORDINAL, context, <dmi value>);
*/
unsigned int riscv_debug_reg_to_s(char *buf, enum riscv_debug_reg_ordinal reg_ordinal,
riscv_debug_reg_ctx_t context, uint64_t value);

View File

@ -28,6 +28,7 @@
#include "program.h"
#include "asm.h"
#include "batch.h"
#include "debug_reg_printer.h"
static int riscv013_on_step_or_resume(struct target *target, bool step);
static int riscv013_step_or_resume_current_hart(struct target *target,
@ -285,6 +286,29 @@ static dm013_info_t *get_dm(struct target *target)
return dm;
}
static riscv_debug_reg_ctx_t get_riscv_debug_reg_ctx(struct target *target)
{
RISCV_INFO(r);
RISCV013_INFO(info);
const riscv_debug_reg_ctx_t context = {
.XLEN = { .value = r->xlen, .is_set = true },
.DXLEN = { .value = r->xlen, .is_set = true },
.abits = { .value = info->abits, .is_set = true },
};
return context;
}
static void log_debug_reg(struct target *target, enum riscv_debug_reg_ordinal reg,
riscv_reg_t value)
{
if (debug_level < LOG_LVL_DEBUG)
return;
const riscv_debug_reg_ctx_t context = get_riscv_debug_reg_ctx(target);
char buf[riscv_debug_reg_to_s(NULL, reg, context, value) + 1];
riscv_debug_reg_to_s(buf, reg, context, value);
LOG_TARGET_DEBUG(target, "%s", buf);
}
static uint32_t set_dmcontrol_hartsel(uint32_t initial, int hart_index)
{
assert(hart_index != HART_INDEX_UNKNOWN);
@ -306,91 +330,40 @@ static uint32_t set_dmcontrol_hartsel(uint32_t initial, int hart_index)
return initial;
}
static void decode_dm(char *text, unsigned int address, unsigned int data)
static unsigned int decode_dm(char *text, unsigned int address, unsigned int data)
{
static const struct {
unsigned int address;
uint64_t mask;
const char *name;
enum riscv_debug_reg_ordinal ordinal;
} description[] = {
{ DM_DMCONTROL, DM_DMCONTROL_HALTREQ, "haltreq" },
{ DM_DMCONTROL, DM_DMCONTROL_RESUMEREQ, "resumereq" },
{ DM_DMCONTROL, DM_DMCONTROL_HARTRESET, "hartreset" },
{ DM_DMCONTROL, DM_DMCONTROL_HASEL, "hasel" },
{ DM_DMCONTROL, DM_DMCONTROL_HARTSELHI, "hartselhi" },
{ DM_DMCONTROL, DM_DMCONTROL_HARTSELLO, "hartsello" },
{ DM_DMCONTROL, DM_DMCONTROL_NDMRESET, "ndmreset" },
{ DM_DMCONTROL, DM_DMCONTROL_DMACTIVE, "dmactive" },
{ DM_DMCONTROL, DM_DMCONTROL_ACKHAVERESET, "ackhavereset" },
{ DM_DMSTATUS, DM_DMSTATUS_IMPEBREAK, "impebreak" },
{ DM_DMSTATUS, DM_DMSTATUS_ALLHAVERESET, "allhavereset" },
{ DM_DMSTATUS, DM_DMSTATUS_ANYHAVERESET, "anyhavereset" },
{ DM_DMSTATUS, DM_DMSTATUS_ALLRESUMEACK, "allresumeack" },
{ DM_DMSTATUS, DM_DMSTATUS_ANYRESUMEACK, "anyresumeack" },
{ DM_DMSTATUS, DM_DMSTATUS_ALLNONEXISTENT, "allnonexistent" },
{ DM_DMSTATUS, DM_DMSTATUS_ANYNONEXISTENT, "anynonexistent" },
{ DM_DMSTATUS, DM_DMSTATUS_ALLUNAVAIL, "allunavail" },
{ DM_DMSTATUS, DM_DMSTATUS_ANYUNAVAIL, "anyunavail" },
{ DM_DMSTATUS, DM_DMSTATUS_ALLRUNNING, "allrunning" },
{ DM_DMSTATUS, DM_DMSTATUS_ANYRUNNING, "anyrunning" },
{ DM_DMSTATUS, DM_DMSTATUS_ALLHALTED, "allhalted" },
{ DM_DMSTATUS, DM_DMSTATUS_ANYHALTED, "anyhalted" },
{ DM_DMSTATUS, DM_DMSTATUS_AUTHENTICATED, "authenticated" },
{ DM_DMSTATUS, DM_DMSTATUS_AUTHBUSY, "authbusy" },
{ DM_DMSTATUS, DM_DMSTATUS_HASRESETHALTREQ, "hasresethaltreq" },
{ DM_DMSTATUS, DM_DMSTATUS_CONFSTRPTRVALID, "confstrptrvalid" },
{ DM_DMSTATUS, DM_DMSTATUS_VERSION, "version" },
{ DM_ABSTRACTCS, DM_ABSTRACTCS_PROGBUFSIZE, "progbufsize" },
{ DM_ABSTRACTCS, DM_ABSTRACTCS_BUSY, "busy" },
{ DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR, "cmderr" },
{ DM_ABSTRACTCS, DM_ABSTRACTCS_DATACOUNT, "datacount" },
{ DM_COMMAND, DM_COMMAND_CMDTYPE, "cmdtype" },
{ DM_SBCS, DM_SBCS_SBVERSION, "sbversion" },
{ DM_SBCS, DM_SBCS_SBBUSYERROR, "sbbusyerror" },
{ DM_SBCS, DM_SBCS_SBBUSY, "sbbusy" },
{ DM_SBCS, DM_SBCS_SBREADONADDR, "sbreadonaddr" },
{ DM_SBCS, DM_SBCS_SBACCESS, "sbaccess" },
{ DM_SBCS, DM_SBCS_SBAUTOINCREMENT, "sbautoincrement" },
{ DM_SBCS, DM_SBCS_SBREADONDATA, "sbreadondata" },
{ DM_SBCS, DM_SBCS_SBERROR, "sberror" },
{ DM_SBCS, DM_SBCS_SBASIZE, "sbasize" },
{ DM_SBCS, DM_SBCS_SBACCESS128, "sbaccess128" },
{ DM_SBCS, DM_SBCS_SBACCESS64, "sbaccess64" },
{ DM_SBCS, DM_SBCS_SBACCESS32, "sbaccess32" },
{ DM_SBCS, DM_SBCS_SBACCESS16, "sbaccess16" },
{ DM_SBCS, DM_SBCS_SBACCESS8, "sbaccess8" },
{DM_DMCONTROL, DM_DMCONTROL_ORDINAL},
{DM_DMSTATUS, DM_DMSTATUS_ORDINAL},
{DM_ABSTRACTCS, DM_ABSTRACTCS_ORDINAL},
{DM_COMMAND, DM_COMMAND_ORDINAL},
{DM_SBCS, DM_SBCS_ORDINAL}
};
text[0] = 0;
for (unsigned i = 0; i < ARRAY_SIZE(description); i++) {
if (description[i].address == address) {
uint64_t mask = description[i].mask;
unsigned value = get_field(data, mask);
if (value) {
if (i > 0)
*(text++) = ' ';
if (mask & (mask >> 1)) {
/* If the field is more than 1 bit wide. */
sprintf(text, "%s=%d", description[i].name, value);
} else {
strcpy(text, description[i].name);
}
text += strlen(text);
}
const riscv_debug_reg_ctx_t context = {
.XLEN = { .value = 0, .is_set = false },
.DXLEN = { .value = 0, .is_set = false },
.abits = { .value = 0, .is_set = false },
};
return riscv_debug_reg_to_s(text, description[i].ordinal,
context, data);
}
}
return 0;
}
static void decode_dmi(struct target *target, char *text, unsigned int address, unsigned int data)
static unsigned int decode_dmi(struct target *target, char *text, unsigned int address,
unsigned int data)
{
dm013_info_t *dm = get_dm(target);
if (!dm)
return;
decode_dm(text, address - dm->base, data);
return 0;
return decode_dm(text, address - dm->base, data);
}
static void dump_field(struct target *target, int idle, const struct scan_field *field)
@ -417,13 +390,13 @@ static void dump_field(struct target *target, int idle, const struct scan_field
field->num_bits, op_string[out_op], out_data, out_address,
status_string[in_op], in_data, in_address, idle);
char out_text[500];
char in_text[500];
decode_dmi(target, out_text, out_address, out_data);
decode_dmi(target, in_text, in_address, in_data);
char out_text[decode_dmi(target, NULL, out_address, out_data) + 1];
unsigned int out_len = decode_dmi(target, out_text, out_address, out_data);
char in_text[decode_dmi(target, NULL, in_address, in_data) + 1];
unsigned int in_len = decode_dmi(target, in_text, in_address, in_data);
if (in_text[0] || out_text[0]) {
log_printf_lf(LOG_LVL_DEBUG, __FILE__, __LINE__, "scan", "%s -> %s",
out_text, in_text);
log_printf_lf(LOG_LVL_DEBUG, __FILE__, __LINE__, "scan", "%.*s -> %.*s",
out_len, out_text, in_len, in_text);
}
}
@ -880,14 +853,7 @@ static int execute_abstract_command(struct target *target, uint32_t command)
if (debug_level >= LOG_LVL_DEBUG) {
switch (get_field(command, DM_COMMAND_CMDTYPE)) {
case 0:
LOG_TARGET_DEBUG(target, "command=0x%x; access register, size=%d, postexec=%d, "
"transfer=%d, write=%d, regno=0x%x",
command,
8 << get_field(command, AC_ACCESS_REGISTER_AARSIZE),
get_field(command, AC_ACCESS_REGISTER_POSTEXEC),
get_field(command, AC_ACCESS_REGISTER_TRANSFER),
get_field(command, AC_ACCESS_REGISTER_WRITE),
get_field(command, AC_ACCESS_REGISTER_REGNO));
log_debug_reg(target, AC_ACCESS_REGISTER_ORDINAL, command);
break;
default:
LOG_TARGET_DEBUG(target, "command=0x%x", command);

View File

@ -1355,7 +1355,7 @@ static int riscv_hit_trigger_hit_bit(struct target *target, uint32_t *unique_id)
hit_mask = CSR_MCONTROL_HIT;
break;
case CSR_TDATA1_TYPE_MCONTROL6:
hit_mask = CSR_MCONTROL6_HIT;
hit_mask = CSR_MCONTROL6_HIT0 | CSR_MCONTROL6_HIT1;
break;
case CSR_TDATA1_TYPE_ICOUNT:
hit_mask = CSR_ICOUNT_HIT;