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:
parent
c07d9251aa
commit
43ebdd47a5
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue