OpenOCD使用简介
基本信息
OpenOCD(Open On-Chip Debugger)
提供依赖JTAG接口的分层架构的片上编程和调试支持和TAP支持,包括:
- (X)SVF回放,便于自动边界扫描和FPGA/CPLD编程;
- 调试目标支持(如ARM、MIPS):单步调试、断点/监控点、gprof性能分析等;
- Flash芯片驱动(如CFI、NAND、内部闪存);
- 内嵌TCL解释器,方便脚本编写;
OpenOCD支持众多网络接口与之交互:包括:telnet、TCL和GDB。GDB server可以使得OpenOCD作为“远程目标”,使用标准的GNU GDB程序(和其他使用GDB协议的工具,如IDA Pro)源码级调试嵌入式系统。
官方手册
工程编译
源码解析
自动生成配置
配置命令
Linux环境中,执行./configure xxx配置后会返回1
2
3
4
5
6
7
8
9$ ./configure --prefix=/usr/local/OpenOCD --datarootdir=/usr/local/OpenOCD --enable-ftdi=no --enable-remote-bitbang=no --enable-ep93xx=no --enable-amtjtagaccel=no --enable-jtag_dpi=no --enable-vdebug=no --enable-jtag_vpi=no --enable-buspirate=no --enable-openjtag=no --enable-presto=no --enable-stlink=no --enable-ti-icdi=no --enable-ulink=no --enable-usb-blaster-2=no --enable-ft232r=no --enable-vsllink=no --enable-xds110=no --enable-osbdm=no --enable-opendous=no --enable-armjtagew=no --enable-rlink=no --enable-usbprog=no --enable-esp-usb-jtag=no --enable-nulink=no --enable-kitprog=no --enable-usb-blaster=no --enable-parport-giveio=no --disable-werror --enable-dummy=yes
OpenOCD configuration summary
--------------------------------------------------
Linux GPIO bitbang through libgpiod no
SEGGER J-Link Programmer yes (auto)
Dummy Adapter yes
RISC-V Link Adapter yes
Use Capstone disassembly framework no
新增rvlink适配器
configure.ac中新增RVLINK_ADAPTER配置项1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21m4_define([DUMMY_ADAPTER],
[[[dummy], [Dummy Adapter], [DUMMY]]])
m4_define([RVLINK_ADAPTER],
[[[rvlink], [RISC-V Link Adapter], [RVLINK]]])
...
AC_ARG_ADAPTERS([DUMMY_ADAPTER],[no])
AC_ARG_ADAPTERS([RVLINK_ADAPTER],[yes])
...
PROCESS_ADAPTERS([DUMMY_ADAPTER], [true], [unused])
PROCESS_ADAPTERS([RVLINK_ADAPTER], [true], [unused])
...
m4_foreach([adapter], [USB1_ADAPTERS,
HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS,
LIBFTDI_USB1_ADAPTERS,
LIBGPIOD_ADAPTERS,
LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS, SERIAL_PORT_ADAPTERS,
DUMMY_ADAPTER,
RVLINK_ADAPTER,
...
例如,对于rvlink适配器,其名称是RISC-V Link Adapter,编译宏为BUILD_RVLINK。
JTAG驱动编控制文件src/jtag/drivers/Makefile.am中可以使用编译宏RVLINK控制编译的代码。1
2
3
4
5
6if DUMMY
DRIVERFILES += %D%/dummy.c
endif
if RVLINK
DRIVERFILES += %D%/rvlink.c
endif
Linux环境中编译会包含rvlink.c文件。
src/jtag/interfaces.c文件适配器驱动列表新增适配器。1
2
3
4
5
6
7
8struct adapter_driver *adapter_drivers[] = {
#if BUILD_DUMMY == 1
&dummy_adapter_driver,
#endif
#if BUILD_RVLINK == 1
&rvlink_adapter_driver,
#endif
};
数据结构
调试目标target
1 | // src/target/target.h |
调试目标列表1
2
3
4
5
6// src/target/target.c
static struct target_type *target_types[] = {
&stm8_target,
&riscv_target,
NULL,
};
对于ARM架构处理器,可以通过container_of(target->arch_info, struct cortex_a_common, armv7a_common.arm),将target转换为cortex_a_common,然后可以获取ADI版本版本。1
2
3
4// struct adiv5_dap->adi_version
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
armv7a->debug_ap->dap->adi_version == 5; /** Indicates ADI version (5, 6 or 0 for unknown) being used */
适配器adapter
1 | // icd_openocd/src/jtag/interface.h |
JTAG接口1
2
3
4
5// icd_openocd/src/jtag/interface.h
struct jtag_interface {
unsigned supported; // 驱动支持能力的位表
int (*execute_queue)(struct jtag_command *cmd_queue); // 执行队列中的命令
};
服务service
服务service,主要用于管理服务。在创建服务时会复制对应的服务驱动接口。1
2
3
4
5
6
7
8// src/server/server.h
struct service {
char *name;
struct connection *connections;
int (*new_connection)(struct connection *connection);
int (*input)(struct connection *connection);
void (*keep_client_alive)(struct connection *connection);
};
服务驱动service_driver,主要定义基本结构1
2
3
4
5
6
7// src/server/server.h
struct service_driver {
const char *name;
int (*new_connection_handler)(struct connection *connection);
int (*input_handler)(struct connection *connection);
void (*keep_client_alive_handler)(struct connection *connection);
};
GDB服务驱动1
2
3
4
5
6
7
8
9// src/server/gdb_server.c
static const struct service_driver gdb_service_driver = {
.name = "gdb",
.new_connection_during_keep_alive_handler = NULL,
.new_connection_handler = gdb_new_connection,
.input_handler = gdb_input,
.connection_closed_handler = gdb_connection_closed,
.keep_client_alive_handler = gdb_keep_client_alive,
};
连接connection1
2
3
4
5
6
7
8
9
10
11// src/server/server.h
struct connection {
int fd;
int fd_out; /* When using pipes we're writing to a different fd */
struct sockaddr_in sin;
struct command_context *cmd_ctx;
struct service *service;
bool input_pending;
void *priv;
struct connection *next;
};
启动OpenOCD
运行命令./src/openocd -s tcl -f tcl/interface/cmsis-dap.cfg -f tcl/target/xxxx.cfg启动OpenOCD。
配置文件解析
适配器驱动处理,各tcl配置文件1
2
3
4
5
6
7
8
9
10// 适配器驱动文件 tcl/interface/cmsis-dap.cfg
adapter driver cmsis-dap
transport select jtag
adapter speed 2000
// 目标配置文件 tcl/target/xxxx.cfg
telnet_port 4444
gdb_port 3333
jtag newtap $_CHIPNAME cpu -enable -irlen 32
target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid $_HARTID
解析tcl配置文件主流程1
2
3
4
5
6
7
8// 主流程 src/openocd.c
openocd_main
setup_command_handler // 注册命令处理函数
adapter_register_commands // 注册adapter命令处理服务
openocd_thread
parse_config_file // 解析配置文件
// 处理 tcl/interface/cmsis-dap.cfg 配置文件
// 处理 tcl/target/xxxx.cfg
adapter命令匹配"cmsis-dap"流程1
2
3
4// adapter命令回调,适配器配置解析匹配名称 src/jtag/adapter.c
interface_command_handlers // 匹配命令adapter
adapter_command_handlers // 匹配命令driver
handle_adapter_driver_command // 若驱动名称匹配,则切换adapter_driver,注册驱动的命令列表并更新allowed_transports列表
适配器列表1
2
3
4
5
6
7
8
9
10// 适配器驱动列表 src/jtag/interfaces.c
struct adapter_driver *adapter_drivers[] = {
#if BUILD_CMSIS_DAP_USB == 1 || BUILD_CMSIS_DAP_HID == 1
&cmsis_dap_adapter_driver,
#endif
};
// "cmsis-dap"适配器驱动
struct adapter_driver cmsis_dap_adapter_driver = {
.name = "cmsis-dap",
};
其他命令处理1
2
3
4// 解析目标配置文件,处理文件中各行命令
// 处理命令telnet_port,handle_telnet_port_command设置telnet_port
// 处理命令gdb_port,handle_gdb_port_command设置gdb_port
// 处理命令transport select,handle_transport_select在allowed_transports列表中匹配传输
主函数流程概览
openocd_main函数初始化逻辑1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28// src/openocd.c
int openocd_main(int argc, char *argv[])
{
...
// 注册各命令的处理函数
struct command_context *cmd_ctx;
cmd_ctx = setup_command_handler(NULL);
...
ret = openocd_thread(argc, argv, cmd_ctx);
...
}
// src/openocd.c
static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ctx)
{
...
// 解析命令行参数
parse_cmdline_args(cmd_ctx, argc, argv);
...
// 解析配置文件,对调试器进行配置
ret = parse_config_file(cmd_ctx);
...
ret = server_init(cmd_ctx);
...
ret = command_run_line(cmd_ctx, "init");
...
ret = server_loop(cmd_ctx);
}
server_init函数初始化逻辑1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35// src/server/server.c
int server_init(struct command_context *cmd_ctx)
{
int ret = tcl_init();
ret = telnet_init("Open On-Chip Debugger");
}
// src/server/tcl_server.c
int tcl_init(void)
{
return add_service(&tcl_service_driver, tcl_port, CONNECTION_LIMIT_UNLIMITED, NULL);
}
static const struct service_driver tcl_service_driver = {
.name = "tcl",
.new_connection_during_keep_alive_handler = NULL,
.new_connection_handler = tcl_new_connection,
.input_handler = tcl_input,
.connection_closed_handler = tcl_closed,
.keep_client_alive_handler = NULL,
};
// src/server/telnet_server.c
int telnet_init(char *banner)
{
int ret = add_service(&telnet_service_driver, telnet_port, CONNECTION_LIMIT_UNLIMITED,
telnet_service);
}
static const struct service_driver telnet_service_driver = {
.name = "telnet",
.new_connection_during_keep_alive_handler = NULL,
.new_connection_handler = telnet_new_connection,
.input_handler = telnet_input,
.connection_closed_handler = telnet_connection_closed,
.keep_client_alive_handler = NULL,
};
server_loop主循环1
2
3
4
5
6
7
8
9
10
11
12
13// src/server/server.c
int server_loop(struct command_context *command_context)
{
// 循环处理services中所有服务的连接列表
while(shutdown_openocd == CONTINUE_MAIN_LOOP)
{
// socket_select多路复用监听fd
// 轮询监听间隔为100ms
// 若服务有数据(service->fd),则接受连接并创建新的连接
// 若连接有数据(c->fd),则调用service->input进行处理
...
}
}
RISC-V架构目标示例
NEMU是RISC-V架构处理器硬件模拟器,OpenOCD通过TCP/51234接口连接它。
启动命令:./src/openocd -s tcl -f tcl/interface/rvlink.cfg -f tcl/target/simu/nemu.cfg
TCL配置文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// tcl/interface/rvlink.cfg
adapter driver RV-LINK
transport select jtag
rvlink connect 127.0.0.1 51234
// tcl/target/simu/nemu.cfg
if { ![info exists _SMP_MODE] } {
set _SMP_MODE 1
}
if {![info exists _HARTID]} {
set _HARTID 0x00
}
if {![info exists _CHIPNAME]} {
set _CHIPNAME nemu
}
set _TARGETNAME $_CHIPNAME.cpu
adapter speed 2000
telnet_port 4444
gdb_port 3333
jtag newtap $_CHIPNAME cpu -enable -irlen 32
set _SMP_GROUP ""
target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid $_HARTID
set _SMP_GROUP "$::_SMP_GROUP $_TARGETNAME"
if { $_SMP_MODE == 1 } {
eval "target smp $_SMP_GROUP"
}
成功启动并连接时的输出1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21$ ./src/openocd -s tcl -f tcl/interface/rvlink.cfg -f tcl/target/simu/nemu.cfg
Open On-Chip Debugger 0.12.0+dev-03889-g5fefbc2da-dirty (2024-09-10-10:57)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : Connected to server 127.0.0.1:51234
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Note: The adapter "RV-LINK" doesn't support configurable speed
Info : JTAG tap: nemu.cpu tap/device found: 0x3ba0184d (mfg: 0x426 (Google Inc), part: 0xba01, ver: 0x3)
Info : [nemu.cpu] datacount=1 progbufsize=0
Warn : [nemu.cpu] We won't be able to execute fence instructions on this target. Memory may not always appear consistent. (progbufsize=0, impebreak=0)
Info : [nemu.cpu] Vector support with vlenb=0
Info : [nemu.cpu] S?aia detected with IMSIC
Info : [nemu.cpu] Core 0 made part of halt group 1.
Info : [nemu.cpu] Examined RISC-V core
Info : [nemu.cpu] XLEN=32, misa=0x40000000
[nemu.cpu] Target successfully examined.
Info : [nemu.cpu] Examination succeed
Info : [nemu.cpu] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
rvlink.cfg文件
adapter命令匹配"RV-LINK"流程1
2
3
4// adapter命令回调,适配器配置解析匹配名称 src/jtag/adapter.c
interface_command_handlers // 匹配命令adapter
adapter_command_handlers // 匹配命令driver
handle_adapter_driver_command // 若驱动名称匹配,则切换adapter_driver,注册驱动的命令列表并更新allowed_transports列表
适配器列表1
2
3
4
5
6
7
8
9
10// 适配器驱动列表 src/jtag/interfaces.c
struct adapter_driver *adapter_drivers[] = {
#if BUILD_RVLINK == 1
&rvlink_adapter_driver,
#endif
};
// "RV-LINK"适配器驱动 src/jtag/drivers/rvlink.c
struct adapter_driver rvlink_adapter_driver = {
.name = "RV-LINK",
};
transport命令选择jtag流程1
2
3
4
5// transport命令回调 src/transport/transport.c
transport_group // 匹配命令transport
transport_commands // 匹配命令select
handle_transport_select // 若名称匹配,则更新transport
transport_select // 调用select回调函数,并更新session
内置jtag传输1
2
3
4
5
6// src/jtag/core.c
static struct transport jtag_transport = {
.name = "jtag",
.select = jtag_select,
.init = jtag_init,
};
rvlink命令执行流程1
2
3
4// src/jtag/drivers/rvlink.c
rvlink_commands // 匹配命令rvlink
rvlink_subcommands // 匹配命令connect
rvlink_connect // 为目标建立TCP连接
nemu.cfg文件
telnet_port命令修改telnet端口1
2
3
4// src/server/telnet_server.c
telnet_command_handlers // 匹配命令telnet_port
handle_telnet_port_command // 直接调用函数
server_pipe_command // 修改telnet_port字符串的值
gdb_port命令修改gdb远程连接端口1
2
3// src/server/gdb_server.c
gdb_command_handlers // 匹配gdb_port
handle_gdb_port_command // 修改gdb_port字符串的值,并同步更新gdb_port_next
jtag命令创建新的tap1
2
3
4
5
6
7// jtag newtap nemu cpu -enable -irlen 32
// src/jtag/tcl.c
jtag_command_handlers // 匹配jtag
jtag_subcommand_handlers // 匹配newtap
handle_jtag_newtap // 创建nemu.cpu的tap对象
handle_jtag_newtap_args // 初始化tap对象,名称、ir配置
jtag_tap_init // 配置tap并将其加入tap列表__jtag_all_taps
target命令创建连接目标1
2
3
4
5
6// target create nemu.cpu riscv -chain-position nemu.cpu -coreid 0x00
// src/target/target.c
target_command_handlers // 匹配target
target_subcommand_handlers // 匹配create
jim_target_create // 调整参数并调用函数
target_create // 创建并匹配"riscv"调试目标,注册调试命令,更新all_targets
target命令设置smp1
2
3
4
5// target smp nemu.cpu
// src/target/target.c
target_command_handlers // 匹配target
target_subcommand_handlers // 匹配smp
handle_target_smp // 将所有target加入到smp列表中,每个组的smp编号从1开始
初始化命令
init命令初始化openocd,将会通过command_run_line函数触发一系列初始化函数。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// src/openocd.c
openocd_command_handlers // 匹配init
handle_init_command // 执行初始化函数。执行过程中jtag_poll_en为false,执行完成后恢复。
// target init命令
adapter_init // 适配器初始化 src/jtag/adapter.c
adapter_driver_gpios_init // 适配器驱动通用IO口初始化
// 特定(示例的rvlink)适配器初始化接口
// transport init命令
// dap init命令
target_examine // 循环检查调试目标列表;
// 延时检查
target_examine_one // 单次检查
target->type->examine(target) // 调用特定(示例为riscv)架构对应的检查接口
// flash init命令
// nand init命令
// pld init命令
// tpiu init命令
gdb_target_add_all // 循环调试目标列表,启动对应的GDB server
// _run_post_init_commands命令
target命令初始化所有调试目标1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// target init
// src/target/target.c
target_command_handlers // 匹配target
target_subcommand_handlers // 匹配init
handle_target_init_command // 直接调用startup.tcl脚本命令 init_targets init_target_events init_board
// init_targets 初始化函数为空
// src/target/startup.tcl
proc init_targets {} {
}
// init_target_events // 循环遍历目标列表,通过set_default_target_event为所有目标设置默认事件命令
// src/target/startup.tcl
proc init_target_events {} {
set targets [target names] // 获取到所有调试目标名称
foreach t $targets {
set_default_target_event $t gdb-flash-erase-start "reset init"
set_default_target_event $t gdb-flash-write-end "reset halt"
set_default_target_event $t gdb-attach "halt 1000"
}
}
// init_board 初始化函数为空
// src/target/startup.tcl
proc init_board {} {
}
transport传输初始化1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25// transport init
// src/transport/transport.c
transport_group // 匹配transport
transport_commands // 匹配init
handle_transport_init // 校验是否设置session变量,并调用特定(示例为jtag)的初始化接口
// jtag适配器初始化
// src/jtag/core.c
jtag_init // 初始化jtag适配器并执行jtag_init命令
// jtag_init
// src/jtag/startup.tcl
proc jtag_init {} {
if {[catch {jtag arp_init} err]!=0} {
# try resetting additionally
init_reset startup
}
}
// jtag arp_init
// src/jtag/tcl.c
jtag_command_handlers // 匹配jtag
jtag_subcommand_handlers // 匹配arp_init
handle_jtag_arp_init // 直接调用内部函数
jtag_init_inner // 执行jtag tap等初始化
dap初始化处理逻辑1
2
3
4
5
6// dap init
// src/target/arm_dap.c
dap_commands // 匹配dap
dap_subcommand_handlers // 匹配init
handle_dap_init // 直接调用函数
dap_init_all // 初始化所有dap对象
简单命令:flash init nand init pld init tpiu init
_run_post_init_commands初始化结束脚本命令1
2
3
4
5
6
7
8
9
10
11
12
13
14// src/helper/startup.tcl
// 循环处理post_init_commands列表
proc _run_post_init_commands {} {
if {[info exists ::post_init_commands]} {
foreach cmd $::post_init_commands {
eval $cmd
}
}
}
// src/target/startup.tcl
// 将以下脚本函数加入到post_init_commands列表
lappend post_init_commands _post_init_target_array_mem
lappend post_init_commands _post_init_target_cortex_a_cache_auto
GDB交互
GDB连接处理
server_loop主循环1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// src/server/server.c
int server_loop(struct command_context *command_context)
{
// 循环处理services中所有服务的连接列表
while(shutdown_openocd == CONTINUE_MAIN_LOOP)
{
socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); // select处理所有服务连接,默认超时polling_period为100ms
target_call_timer_callbacks(); // 调试目标计时器回调;会调用keep_alive和server_keep_clients_alive处理各服务的保活逻辑
process_jim_events(command_context); // jim事件处理函数
// 循环遍历所有服务
for (service = services; service; service = service->next) {
// 若服务连接有数据,则创建连接
if (FD_ISSET(service->fd, &read_fds)) {
add_connection(service, command_context);
}
// 循环遍历服务下所有客户端连接,调用服务输入处理接口
for (c = service->connections; c; ) {
service->input(c);
}
}
}
}
创建连接
服务创建连接,并将其加入到服务连接队列中1
2
3
4
5
6// src/server/server.c
add_connection
// 创建connection对象
accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
service->new_connection // gdb服务创建连接回调
// connection对象加入到service->connections尾部
GDB创建连接1
2
3
4
5
6
7
8// src/server/gdb_server.c
// service->new_connection
gdb_service_driver
gdb_new_connection // 初始化gdb连接目标
// 创建gdb连接对象
breakpoint_clear_target(target);
watchpoint_clear_target(target);
target_call_event_callbacks(target, TARGET_EVENT_GDB_ATTACH);
输入处理
GDB输入处理1
2
3
4
5
6
7
8
9
10
11
12
13// src/server/gdb_server.c
// service->input
gdb_service_driver
gdb_input // gdb输入处理回调函数,直接调用函数
gdb_input_inner // gdb输入处理函数
gdb_get_packet // 从连接获取协议包
gdb_get_packet_inner // 从连接中读取数据包,若成功则回复ACK('+')
gdb_get_char // 读取数据包,返回第一个字符
fetch_packet // 解析剩余数据,并计算校验和;当切换到noack模式,则不会校验校验和,并跳过回复ACK('+')
/*
根据packet[0]第一个字符,执行对应的处理函数
一般小写为读操作函数,大写为写操作函数
*/
GDB远程协议
具体协议需要参考GDB远程协议章节(Appendix E gdb Remote Serial Protocol)。
连接OpenOCD
GDB执行命令连接OpenOCD。执行GDB命令set debug remote 1打开远程调试后,再连接远程目标可以看到通信日志。1
2(gdb) target remote :3333
0x80000004 in ?? ()
qSupported
探测OpenOCD支持哪些特性1
2
3
4
5
6
7
8
9 [remote] Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+;xmlRegisters=i386#77
[remote] Received Ack
[remote] Packet received: PacketSize=4000;qXfer:memory-map:read-;qXfer:features:read+;qXfer:threads:read+;QStartNoAckMode+;vContSupported+
[remote] packet_ok: Packet qSupported (supported-packets) is supported
// src/server/gdb_server.c
gdb_query_packet // 处理q/Q消息
xml_printf // xml格式的回复消息
gdb_put_packet // 回复消息
vMustReplyEmpty
1 | [remote] Sending packet: $vMustReplyEmpty#3a |
QStartNoAckMode
设置不回复ACK模式1
2
3
4
5
6
7 [remote] Sending packet: $QStartNoAckMode#b0
[remote] Received Ack
[remote] Packet received: OK
// src/server/gdb_server.c
gdb_query_packet // 处理q/Q消息
gdb_put_packet // 回复OK
Hgxxx
1 | [remote] Sending packet: $Hg0#df |
qXfer:features:read
qXfer:features:read:target.xml:<offset,length>命令分页读取xml格式的架构描述文件,详细信息见riscv描述1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 [remote] Sending packet: $qXfer:features:read:target.xml:0,1000#0c
[remote] Packet received: m<?xml version="1.0"?>\n<!DOCTYPE target SYSTEM "gdb-target.dtd">\n<target version="1.0">\n<architecture>riscv:rv32</architecture>\n<feature name="org.gnu.gdb.riscv.cpu">\n<reg name="zero" bitsize="32" regnum="0" save-restore="yes" type="int" group="general"/>\n<reg name="ra" bitsize="32" regnum="1" save-restore="yes" type="int" group="general"/>\n<reg name="sp" bitsize="32" regnum="2" save-restore="yes" type="int" group="general"/>\n<reg name="gp" bitsize="32" regnum="3" save-restore="yes" type="int" group="genera [3585 bytes omitted]
...
[remote] Sending packet: $qXfer:features:read:target.xml:9000,1000#a5
[remote] Packet received: l type="int" group="csr"/>\n<reg name="hpmcounter27h" bitsize="32" regnum="3292" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter28h" bitsize="32" regnum="3293" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter29h" bitsize="32" regnum="3294" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter30h" bitsize="32" regnum="3295" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter31h" bitsize="32" regnum="3296" save-restore="no" type="int" group="csr"/>\n<reg [882 bytes omitted]
// src/server/gdb_server.c
gdb_query_packet // 处理q/Q消息
decode_xfer_read // 解析qXfer命令
gdb_get_target_description_chunk // 架构描述文件分块处理
gdb_generate_target_description // xml格式打印完整的架构描述文件
smp_reg_list_noread // 读取架构完整的寄存器列表
get_reg_features_list // 获取架构寄存器特性列表
xml_printf // 循环打印xml格式的描述文件
gdb_put_packet(connection, xml, strlen(xml)) // 回复架构描述文件xml数据;第一个字符为'm'表示后面有分页;第一个字符为'l'表示最后一页;
qTStatus
1 | [remote] Sending packet: $qTStatus#49 |
?
获取进入调试模式的原因对应的信号量1
2
3
4
5
6
7 [remote] Sending packet: $?#3f
[remote] Packet received: S00
// src/server/gdb_server.c
gdb_last_signal_packet 处理?消息
gdb_last_signal // 获取上次收到gdb的信号量(根据进入调试模式的原因转换)
gdb_put_packet(connection, sig_reply, 3); // 回复对应的信号量消息
qXfer:threads:read
获取线程列表1
2
3
4
5
6
7
8
9 [remote] Sending packet: $qXfer:threads:read::0,1000#92
[remote] Packet received: l<?xml version="1.0"?>\n<threads>\n</threads>\n
// src/server/gdb_server.c
gdb_query_packet // 处理q/Q消息
decode_xfer_read // 解析qXfer命令
gdb_get_thread_list_chunk // 线程列表线程信息分块处理
gdb_generate_thread_list // xml格式打印完整的线程列表信息
gdb_put_packet(connection, xml, strlen(xml)); // 回复线程列表信息xml数据;第一个字符为'm'表示后面有分页;第一个字符为'l'表示最后一页;
Hc-xxx
1 | [remote] Sending packet: $Hc-1#09 |
qC
1 | [remote] Sending packet: $qC#b4 |
qAttached
1 | [remote] Sending packet: $qAttached#8f |
g
获取通用寄存器列表1
2
3
4
5
6
7
8
9 [remote] Sending packet: $g#67
[remote] Packet received: 000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000080
// src/server/gdb_server.c
gdb_get_registers_packet // 处理g消息
target_get_gdb_reg_list // 获取特定架构寄存器列表
gdb_get_reg_value_as_str // 循环遍历所有寄存器,将寄存器的值格式化为字符串
gdb_str_to_target // 格式化寄存器的值,每个字节格式化为十六进制2位字符
gdb_put_packet(connection, reg_packet, reg_packet_size); // 返回寄存器值字符化后的数据
mxxx
m<address>,<length>读取指定地址的内存数据。默认分别读取当前PC和上一次PC对应的指令。1
2
3
4
5
6
7
8
9 [remote] Sending packet: $m80000004,4#59
[remote] Packet received: 93051005
[remote] Sending packet: $m80000000,4#55
[remote] Packet received: 13050005
// src/server/gdb_server.c
gdb_read_memory_packet // 处理m消息
target_read_buffer // 读取特定架构内存数据
gdb_put_packet // 返回内存数据字符化后的数据
附件
GDB通信日志
GDB远程连接日志
执行GDB命令set debug remote 1打开远程调试后,再连接远程目标可以看到通信日志1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68(gdb) target remote :3333
Remote debugging using :3333
[remote] start_remote_1: enter
[remote] Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+;xmlRegisters=i386#77
[remote] Received Ack
[remote] Packet received: PacketSize=4000;qXfer:memory-map:read-;qXfer:features:read+;qXfer:threads:read+;QStartNoAckMode+;vContSupported+
[remote] packet_ok: Packet qSupported (supported-packets) is supported
[remote] Sending packet: $vMustReplyEmpty#3a
[remote] Received Ack
[remote] Packet received:
[remote] Sending packet: $QStartNoAckMode#b0
[remote] Received Ack
[remote] Packet received: OK
[remote] Sending packet: $Hg0#df
[remote] Packet received: OK
[remote] Sending packet: $qXfer:features:read:target.xml:0,1000#0c
[remote] Packet received: m<?xml version="1.0"?>\n<!DOCTYPE target SYSTEM "gdb-target.dtd">\n<target version="1.0">\n<architecture>riscv:rv32</architecture>\n<feature name="org.gnu.gdb.riscv.cpu">\n<reg name="zero" bitsize="32" regnum="0" save-restore="yes" type="int" group="general"/>\n<reg name="ra" bitsize="32" regnum="1" save-restore="yes" type="int" group="general"/>\n<reg name="sp" bitsize="32" regnum="2" save-restore="yes" type="int" group="general"/>\n<reg name="gp" bitsize="32" regnum="3" save-restore="yes" type="int" group="genera [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:1000,1000#9d
[remote] Packet received: m="sstateen0" bitsize="32" regnum="333" save-restore="no" type="int" group="csr"/>\n<reg name="sstateen1" bitsize="32" regnum="334" save-restore="no" type="int" group="csr"/>\n<reg name="sstateen2" bitsize="32" regnum="335" save-restore="no" type="int" group="csr"/>\n<reg name="sstateen3" bitsize="32" regnum="336" save-restore="no" type="int" group="csr"/>\n<reg name="snxti" bitsize="32" regnum="390" save-restore="no" type="int" group="csr"/>\n<reg name="sintstatus" bitsize="32" regnum="391" save-restore="no" ty [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:2000,1000#9e
[remote] Packet received: mno" type="int" group="csr"/>\n<reg name="mhpmevent8" bitsize="32" regnum="873" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent9" bitsize="32" regnum="874" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent10" bitsize="32" regnum="875" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent11" bitsize="32" regnum="876" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent12" bitsize="32" regnum="877" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmeven [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:3000,1000#9f
[remote] Packet received: m type="int" group="csr"/>\n<reg name="pmpcfg6" bitsize="32" regnum="999" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg7" bitsize="32" regnum="1000" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg8" bitsize="32" regnum="1001" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg9" bitsize="32" regnum="1002" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg10" bitsize="32" regnum="1003" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg11" bitsize="32" r [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:4000,1000#a0
[remote] Packet received: m" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr35" bitsize="32" regnum="1044" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr36" bitsize="32" regnum="1045" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr37" bitsize="32" regnum="1046" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr38" bitsize="32" regnum="1047" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr39" bitsize="32" regnum="1048" save-restore="no" type="int" group="csr"/>\n<reg n [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:5000,1000#a1
[remote] Packet received: m0h" bitsize="32" regnum="1629" save-restore="no" type="int" group="csr"/>\n<reg name="hstateen1h" bitsize="32" regnum="1630" save-restore="no" type="int" group="csr"/>\n<reg name="hstateen2h" bitsize="32" regnum="1631" save-restore="no" type="int" group="csr"/>\n<reg name="hstateen3h" bitsize="32" regnum="1632" save-restore="no" type="int" group="csr"/>\n<reg name="htval" bitsize="32" regnum="1668" save-restore="no" type="int" group="csr"/>\n<reg name="hip" bitsize="32" regnum="1669" save-restore="no" type="int [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:6000,1000#a2
[remote] Packet received: m" bitsize="32" regnum="2020" save-restore="no" type="int" group="csr"/>\n<reg name="tinfo" bitsize="32" regnum="2021" save-restore="no" type="int" group="csr"/>\n<reg name="tcontrol" bitsize="32" regnum="2022" save-restore="no" type="int" group="csr"/>\n<reg name="mcontext" bitsize="32" regnum="2025" save-restore="no" type="int" group="csr"/>\n<reg name="mscontext" bitsize="32" regnum="2027" save-restore="no" type="int" group="csr"/>\n<reg name="dcsr" bitsize="32" regnum="2033" save-restore="no" type="int" grou [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:7000,1000#a3
[remote] Packet received: m type="int" group="csr"/>\n<reg name="mhpmcounter5h" bitsize="32" regnum="3014" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter6h" bitsize="32" regnum="3015" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter7h" bitsize="32" regnum="3016" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter8h" bitsize="32" regnum="3017" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter9h" bitsize="32" regnum="3018" save-restore="no" type="int" group="csr"/>\n<reg [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:8000,1000#a4
[remote] Packet received: mestore="no" type="int" group="csr"/>\n<reg name="hpmcounter16" bitsize="32" regnum="3153" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter17" bitsize="32" regnum="3154" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter18" bitsize="32" regnum="3155" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter19" bitsize="32" regnum="3156" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter20" bitsize="32" regnum="3157" save-restore="no" type="int" group="csr"/> [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:9000,1000#a5
[remote] Packet received: l type="int" group="csr"/>\n<reg name="hpmcounter27h" bitsize="32" regnum="3292" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter28h" bitsize="32" regnum="3293" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter29h" bitsize="32" regnum="3294" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter30h" bitsize="32" regnum="3295" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter31h" bitsize="32" regnum="3296" save-restore="no" type="int" group="csr"/>\n<reg [882 bytes omitted]
[remote] Sending packet: $qTStatus#49
[remote] Packet received:
[remote] packet_ok: Packet qTStatus (trace-status) is NOT supported
[remote] Sending packet: $?#3f
[remote] Packet received: S00
[remote] Sending packet: $qXfer:threads:read::0,1000#92
[remote] Packet received: l<?xml version="1.0"?>\n<threads>\n</threads>\n
[remote] Sending packet: $Hc-1#09
[remote] Packet received: OK
[remote] Sending packet: $qC#b4
[remote] Packet received: QC0
[remote] Sending packet: $qAttached#8f
[remote] Packet received: 1
[remote] packet_ok: Packet qAttached (query-attached) is supported
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
[remote] wait: enter
[remote] select_thread_for_ambiguous_stop_reply: enter
[remote] select_thread_for_ambiguous_stop_reply: process_wide_stop = 0
[remote] select_thread_for_ambiguous_stop_reply: first resumed thread is Remote target
[remote] select_thread_for_ambiguous_stop_reply: is this guess ambiguous? = 0
[remote] select_thread_for_ambiguous_stop_reply: exit
[remote] wait: exit
[remote] Sending packet: $g#67
[remote] Packet received: 000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000080
[remote] Sending packet: $qXfer:threads:read::0,1000#92
[remote] Packet received: l<?xml version="1.0"?>\n<threads>\n</threads>\n
[remote] Sending packet: $m80000004,4#59
[remote] Packet received: 93051005
[remote] Sending packet: $m80000000,4#55
[remote] Packet received: 13050005
0x80000000 in ?? ()
[remote] start_remote_1: exit
架构描述文件
riscv描述文件
通信协议日志1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20[remote] Sending packet: $qXfer:features:read:target.xml:0,1000#0c
[remote] Packet received: m<?xml version="1.0"?>\n<!DOCTYPE target SYSTEM "gdb-target.dtd">\n<target version="1.0">\n<architecture>riscv:rv32</architecture>\n<feature name="org.gnu.gdb.riscv.cpu">\n<reg name="zero" bitsize="32" regnum="0" save-restore="yes" type="int" group="general"/>\n<reg name="ra" bitsize="32" regnum="1" save-restore="yes" type="int" group="general"/>\n<reg name="sp" bitsize="32" regnum="2" save-restore="yes" type="int" group="general"/>\n<reg name="gp" bitsize="32" regnum="3" save-restore="yes" type="int" group="genera [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:1000,1000#9d
[remote] Packet received: m="sstateen0" bitsize="32" regnum="333" save-restore="no" type="int" group="csr"/>\n<reg name="sstateen1" bitsize="32" regnum="334" save-restore="no" type="int" group="csr"/>\n<reg name="sstateen2" bitsize="32" regnum="335" save-restore="no" type="int" group="csr"/>\n<reg name="sstateen3" bitsize="32" regnum="336" save-restore="no" type="int" group="csr"/>\n<reg name="snxti" bitsize="32" regnum="390" save-restore="no" type="int" group="csr"/>\n<reg name="sintstatus" bitsize="32" regnum="391" save-restore="no" ty [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:2000,1000#9e
[remote] Packet received: mno" type="int" group="csr"/>\n<reg name="mhpmevent8" bitsize="32" regnum="873" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent9" bitsize="32" regnum="874" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent10" bitsize="32" regnum="875" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent11" bitsize="32" regnum="876" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmevent12" bitsize="32" regnum="877" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmeven [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:3000,1000#9f
[remote] Packet received: m type="int" group="csr"/>\n<reg name="pmpcfg6" bitsize="32" regnum="999" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg7" bitsize="32" regnum="1000" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg8" bitsize="32" regnum="1001" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg9" bitsize="32" regnum="1002" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg10" bitsize="32" regnum="1003" save-restore="no" type="int" group="csr"/>\n<reg name="pmpcfg11" bitsize="32" r [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:4000,1000#a0
[remote] Packet received: m" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr35" bitsize="32" regnum="1044" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr36" bitsize="32" regnum="1045" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr37" bitsize="32" regnum="1046" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr38" bitsize="32" regnum="1047" save-restore="no" type="int" group="csr"/>\n<reg name="pmpaddr39" bitsize="32" regnum="1048" save-restore="no" type="int" group="csr"/>\n<reg n [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:5000,1000#a1
[remote] Packet received: m0h" bitsize="32" regnum="1629" save-restore="no" type="int" group="csr"/>\n<reg name="hstateen1h" bitsize="32" regnum="1630" save-restore="no" type="int" group="csr"/>\n<reg name="hstateen2h" bitsize="32" regnum="1631" save-restore="no" type="int" group="csr"/>\n<reg name="hstateen3h" bitsize="32" regnum="1632" save-restore="no" type="int" group="csr"/>\n<reg name="htval" bitsize="32" regnum="1668" save-restore="no" type="int" group="csr"/>\n<reg name="hip" bitsize="32" regnum="1669" save-restore="no" type="int [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:6000,1000#a2
[remote] Packet received: m" bitsize="32" regnum="2020" save-restore="no" type="int" group="csr"/>\n<reg name="tinfo" bitsize="32" regnum="2021" save-restore="no" type="int" group="csr"/>\n<reg name="tcontrol" bitsize="32" regnum="2022" save-restore="no" type="int" group="csr"/>\n<reg name="mcontext" bitsize="32" regnum="2025" save-restore="no" type="int" group="csr"/>\n<reg name="mscontext" bitsize="32" regnum="2027" save-restore="no" type="int" group="csr"/>\n<reg name="dcsr" bitsize="32" regnum="2033" save-restore="no" type="int" grou [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:7000,1000#a3
[remote] Packet received: m type="int" group="csr"/>\n<reg name="mhpmcounter5h" bitsize="32" regnum="3014" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter6h" bitsize="32" regnum="3015" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter7h" bitsize="32" regnum="3016" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter8h" bitsize="32" regnum="3017" save-restore="no" type="int" group="csr"/>\n<reg name="mhpmcounter9h" bitsize="32" regnum="3018" save-restore="no" type="int" group="csr"/>\n<reg [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:8000,1000#a4
[remote] Packet received: mestore="no" type="int" group="csr"/>\n<reg name="hpmcounter16" bitsize="32" regnum="3153" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter17" bitsize="32" regnum="3154" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter18" bitsize="32" regnum="3155" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter19" bitsize="32" regnum="3156" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter20" bitsize="32" regnum="3157" save-restore="no" type="int" group="csr"/> [3585 bytes omitted]
[remote] Sending packet: $qXfer:features:read:target.xml:9000,1000#a5
[remote] Packet received: l type="int" group="csr"/>\n<reg name="hpmcounter27h" bitsize="32" regnum="3292" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter28h" bitsize="32" regnum="3293" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter29h" bitsize="32" regnum="3294" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter30h" bitsize="32" regnum="3295" save-restore="no" type="int" group="csr"/>\n<reg name="hpmcounter31h" bitsize="32" regnum="3296" save-restore="no" type="int" group="csr"/>\n<reg [882 bytes omitted]
xml格式描述文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<architecture>riscv:rv32</architecture>
<feature name="org.gnu.gdb.riscv.cpu">
<reg name="zero" bitsize="32" regnum="0" save-restore="yes" type="int" group="general"/>
<reg name="ra" bitsize="32" regnum="1" save-restore="yes" type="int" group="general"/>
<reg name="sp" bitsize="32" regnum="2" save-restore="yes" type="int" group="general"/>
<reg name="gp" bitsize="32" regnum="3" save-restore="yes" type="int" group="general"/>
<reg name="tp" bitsize="32" regnum="4" save-restore="yes" type="int" group="general"/>
<reg name="t0" bitsize="32" regnum="5" save-restore="yes" type="int" group="general"/>
<reg name="t1" bitsize="32" regnum="6" save-restore="yes" type="int" group="general"/>
<reg name="t2" bitsize="32" regnum="7" save-restore="yes" type="int" group="general"/>
<reg name="fp" bitsize="32" regnum="8" save-restore="yes" type="int" group="general"/>
<reg name="s1" bitsize="32" regnum="9" save-restore="yes" type="int" group="general"/>
<reg name="a0" bitsize="32" regnum="10" save-restore="yes" type="int" group="general"/>
<reg name="a1" bitsize="32" regnum="11" save-restore="yes" type="int" group="general"/>
<reg name="a2" bitsize="32" regnum="12" save-restore="yes" type="int" group="general"/>
<reg name="a3" bitsize="32" regnum="13" save-restore="yes" type="int" group="general"/>
<reg name="a4" bitsize="32" regnum="14" save-restore="yes" type="int" group="general"/>
<reg name="a5" bitsize="32" regnum="15" save-restore="yes" type="int" group="general"/>
<reg name="a6" bitsize="32" regnum="16" save-restore="yes" type="int" group="general"/>
<reg name="a7" bitsize="32" regnum="17" save-restore="yes" type="int" group="general"/>
<reg name="s2" bitsize="32" regnum="18" save-restore="yes" type="int" group="general"/>
<reg name="s3" bitsize="32" regnum="19" save-restore="yes" type="int" group="general"/>
<reg name="s4" bitsize="32" regnum="20" save-restore="yes" type="int" group="general"/>
<reg name="s5" bitsize="32" regnum="21" save-restore="yes" type="int" group="general"/>
<reg name="s6" bitsize="32" regnum="22" save-restore="yes" type="int" group="general"/>
<reg name="s7" bitsize="32" regnum="23" save-restore="yes" type="int" group="general"/>
<reg name="s8" bitsize="32" regnum="24" save-restore="yes" type="int" group="general"/>
<reg name="s9" bitsize="32" regnum="25" save-restore="yes" type="int" group="general"/>
<reg name="s10" bitsize="32" regnum="26" save-restore="yes" type="int" group="general"/>
<reg name="s11" bitsize="32" regnum="27" save-restore="yes" type="int" group="general"/>
<reg name="t3" bitsize="32" regnum="28" save-restore="yes" type="int" group="general"/>
<reg name="t4" bitsize="32" regnum="29" save-restore="yes" type="int" group="general"/>
<reg name="t5" bitsize="32" regnum="30" save-restore="yes" type="int" group="general"/>
<reg name="t6" bitsize="32" regnum="31" save-restore="yes" type="int" group="general"/>
<reg name="pc" bitsize="32" regnum="32" save-restore="yes" type="int" group="general"/>
</feature>
<feature name="org.gnu.gdb.riscv.csr">
<reg name="utvt" bitsize="32" regnum="72" save-restore="no" type="int" group="csr"/>
<reg name="seed" bitsize="32" regnum="86" save-restore="no" type="int" group="csr"/>
<reg name="jvt" bitsize="32" regnum="88" save-restore="no" type="int" group="csr"/>
<reg name="unxti" bitsize="32" regnum="134" save-restore="no" type="int" group="csr"/>
<reg name="uintstatus" bitsize="32" regnum="135" save-restore="no" type="int" group="csr"/>
<reg name="uscratchcsw" bitsize="32" regnum="137" save-restore="no" type="int" group="csr"/>
<reg name="uscratchcswl" bitsize="32" regnum="138" save-restore="no" type="int" group="csr"/>
<reg name="sedeleg" bitsize="32" regnum="323" save-restore="no" type="int" group="csr"/>
<reg name="sideleg" bitsize="32" regnum="324" save-restore="no" type="int" group="csr"/>
<reg name="stvt" bitsize="32" regnum="328" save-restore="no" type="int" group="csr"/>
<reg name="senvcfg" bitsize="32" regnum="331" save-restore="no" type="int" group="csr"/>
<reg name="sstateen0" bitsize="32" regnum="333" save-restore="no" type="int" group="csr"/>
<reg name="sstateen1" bitsize="32" regnum="334" save-restore="no" type="int" group="csr"/>
<reg name="sstateen2" bitsize="32" regnum="335" save-restore="no" type="int" group="csr"/>
<reg name="sstateen3" bitsize="32" regnum="336" save-restore="no" type="int" group="csr"/>
<reg name="snxti" bitsize="32" regnum="390" save-restore="no" type="int" group="csr"/>
<reg name="sintstatus" bitsize="32" regnum="391" save-restore="no" type="int" group="csr"/>
<reg name="sscratchcsw" bitsize="32" regnum="393" save-restore="no" type="int" group="csr"/>
<reg name="sscratchcswl" bitsize="32" regnum="394" save-restore="no" type="int" group="csr"/>
<reg name="stimecmp" bitsize="32" regnum="398" save-restore="no" type="int" group="csr"/>
<reg name="stimecmph" bitsize="32" regnum="414" save-restore="no" type="int" group="csr"/>
<reg name="vsstatus" bitsize="32" regnum="577" save-restore="no" type="int" group="csr"/>
<reg name="vsie" bitsize="32" regnum="581" save-restore="no" type="int" group="csr"/>
<reg name="vstvec" bitsize="32" regnum="582" save-restore="no" type="int" group="csr"/>
<reg name="vsscratch" bitsize="32" regnum="641" save-restore="no" type="int" group="csr"/>
<reg name="vsepc" bitsize="32" regnum="642" save-restore="no" type="int" group="csr"/>
<reg name="vscause" bitsize="32" regnum="643" save-restore="no" type="int" group="csr"/>
<reg name="vstval" bitsize="32" regnum="644" save-restore="no" type="int" group="csr"/>
<reg name="vsip" bitsize="32" regnum="645" save-restore="no" type="int" group="csr"/>
<reg name="vstimecmp" bitsize="32" regnum="654" save-restore="no" type="int" group="csr"/>
<reg name="vstimecmph" bitsize="32" regnum="670" save-restore="no" type="int" group="csr"/>
<reg name="vsatp" bitsize="32" regnum="705" save-restore="no" type="int" group="csr"/>
<reg name="mstatus" bitsize="32" regnum="833" save-restore="no" type="int" group="csr"/>
<reg name="misa" bitsize="32" regnum="834" save-restore="no" type="int" group="csr"/>
<reg name="mie" bitsize="32" regnum="837" save-restore="no" type="int" group="csr"/>
<reg name="mtvec" bitsize="32" regnum="838" save-restore="no" type="int" group="csr"/>
<reg name="mtvt" bitsize="32" regnum="840" save-restore="no" type="int" group="csr"/>
<reg name="mvien" bitsize="32" regnum="841" save-restore="no" type="int" group="csr"/>
<reg name="mvip" bitsize="32" regnum="842" save-restore="no" type="int" group="csr"/>
<reg name="menvcfg" bitsize="32" regnum="843" save-restore="no" type="int" group="csr"/>
<reg name="mstateen0" bitsize="32" regnum="845" save-restore="no" type="int" group="csr"/>
<reg name="mstateen1" bitsize="32" regnum="846" save-restore="no" type="int" group="csr"/>
<reg name="mstateen2" bitsize="32" regnum="847" save-restore="no" type="int" group="csr"/>
<reg name="mstateen3" bitsize="32" regnum="848" save-restore="no" type="int" group="csr"/>
<reg name="mstatush" bitsize="32" regnum="849" save-restore="no" type="int" group="csr"/>
<reg name="mieh" bitsize="32" regnum="853" save-restore="no" type="int" group="csr"/>
<reg name="menvcfgh" bitsize="32" regnum="859" save-restore="no" type="int" group="csr"/>
<reg name="mstateen0h" bitsize="32" regnum="861" save-restore="no" type="int" group="csr"/>
<reg name="mstateen1h" bitsize="32" regnum="862" save-restore="no" type="int" group="csr"/>
<reg name="mstateen2h" bitsize="32" regnum="863" save-restore="no" type="int" group="csr"/>
<reg name="mstateen3h" bitsize="32" regnum="864" save-restore="no" type="int" group="csr"/>
<reg name="mcountinhibit" bitsize="32" regnum="865" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent3" bitsize="32" regnum="868" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent4" bitsize="32" regnum="869" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent5" bitsize="32" regnum="870" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent6" bitsize="32" regnum="871" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent7" bitsize="32" regnum="872" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent8" bitsize="32" regnum="873" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent9" bitsize="32" regnum="874" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent10" bitsize="32" regnum="875" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent11" bitsize="32" regnum="876" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent12" bitsize="32" regnum="877" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent13" bitsize="32" regnum="878" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent14" bitsize="32" regnum="879" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent15" bitsize="32" regnum="880" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent16" bitsize="32" regnum="881" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent17" bitsize="32" regnum="882" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent18" bitsize="32" regnum="883" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent19" bitsize="32" regnum="884" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent20" bitsize="32" regnum="885" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent21" bitsize="32" regnum="886" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent22" bitsize="32" regnum="887" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent23" bitsize="32" regnum="888" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent24" bitsize="32" regnum="889" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent25" bitsize="32" regnum="890" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent26" bitsize="32" regnum="891" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent27" bitsize="32" regnum="892" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent28" bitsize="32" regnum="893" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent29" bitsize="32" regnum="894" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent30" bitsize="32" regnum="895" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent31" bitsize="32" regnum="896" save-restore="no" type="int" group="csr"/>
<reg name="mscratch" bitsize="32" regnum="897" save-restore="no" type="int" group="csr"/>
<reg name="mepc" bitsize="32" regnum="898" save-restore="no" type="int" group="csr"/>
<reg name="mcause" bitsize="32" regnum="899" save-restore="no" type="int" group="csr"/>
<reg name="mtval" bitsize="32" regnum="900" save-restore="no" type="int" group="csr"/>
<reg name="mip" bitsize="32" regnum="901" save-restore="no" type="int" group="csr"/>
<reg name="mnxti" bitsize="32" regnum="902" save-restore="no" type="int" group="csr"/>
<reg name="mintstatus" bitsize="32" regnum="903" save-restore="no" type="int" group="csr"/>
<reg name="mscratchcsw" bitsize="32" regnum="905" save-restore="no" type="int" group="csr"/>
<reg name="mscratchcswl" bitsize="32" regnum="906" save-restore="no" type="int" group="csr"/>
<reg name="mtinst" bitsize="32" regnum="907" save-restore="no" type="int" group="csr"/>
<reg name="mtval2" bitsize="32" regnum="908" save-restore="no" type="int" group="csr"/>
<reg name="miselect" bitsize="32" regnum="913" save-restore="no" type="int" group="csr"/>
<reg name="mireg" bitsize="32" regnum="914" save-restore="no" type="int" group="csr"/>
<reg name="miph" bitsize="32" regnum="917" save-restore="no" type="int" group="csr"/>
<reg name="mtopei" bitsize="32" regnum="925" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg0" bitsize="32" regnum="993" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg1" bitsize="32" regnum="994" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg2" bitsize="32" regnum="995" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg3" bitsize="32" regnum="996" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg4" bitsize="32" regnum="997" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg5" bitsize="32" regnum="998" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg6" bitsize="32" regnum="999" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg7" bitsize="32" regnum="1000" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg8" bitsize="32" regnum="1001" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg9" bitsize="32" regnum="1002" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg10" bitsize="32" regnum="1003" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg11" bitsize="32" regnum="1004" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg12" bitsize="32" regnum="1005" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg13" bitsize="32" regnum="1006" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg14" bitsize="32" regnum="1007" save-restore="no" type="int" group="csr"/>
<reg name="pmpcfg15" bitsize="32" regnum="1008" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr0" bitsize="32" regnum="1009" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr1" bitsize="32" regnum="1010" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr2" bitsize="32" regnum="1011" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr3" bitsize="32" regnum="1012" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr4" bitsize="32" regnum="1013" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr5" bitsize="32" regnum="1014" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr6" bitsize="32" regnum="1015" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr7" bitsize="32" regnum="1016" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr8" bitsize="32" regnum="1017" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr9" bitsize="32" regnum="1018" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr10" bitsize="32" regnum="1019" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr11" bitsize="32" regnum="1020" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr12" bitsize="32" regnum="1021" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr13" bitsize="32" regnum="1022" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr14" bitsize="32" regnum="1023" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr15" bitsize="32" regnum="1024" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr16" bitsize="32" regnum="1025" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr17" bitsize="32" regnum="1026" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr18" bitsize="32" regnum="1027" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr19" bitsize="32" regnum="1028" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr20" bitsize="32" regnum="1029" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr21" bitsize="32" regnum="1030" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr22" bitsize="32" regnum="1031" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr23" bitsize="32" regnum="1032" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr24" bitsize="32" regnum="1033" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr25" bitsize="32" regnum="1034" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr26" bitsize="32" regnum="1035" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr27" bitsize="32" regnum="1036" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr28" bitsize="32" regnum="1037" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr29" bitsize="32" regnum="1038" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr30" bitsize="32" regnum="1039" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr31" bitsize="32" regnum="1040" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr32" bitsize="32" regnum="1041" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr33" bitsize="32" regnum="1042" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr34" bitsize="32" regnum="1043" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr35" bitsize="32" regnum="1044" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr36" bitsize="32" regnum="1045" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr37" bitsize="32" regnum="1046" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr38" bitsize="32" regnum="1047" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr39" bitsize="32" regnum="1048" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr40" bitsize="32" regnum="1049" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr41" bitsize="32" regnum="1050" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr42" bitsize="32" regnum="1051" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr43" bitsize="32" regnum="1052" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr44" bitsize="32" regnum="1053" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr45" bitsize="32" regnum="1054" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr46" bitsize="32" regnum="1055" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr47" bitsize="32" regnum="1056" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr48" bitsize="32" regnum="1057" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr49" bitsize="32" regnum="1058" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr50" bitsize="32" regnum="1059" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr51" bitsize="32" regnum="1060" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr52" bitsize="32" regnum="1061" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr53" bitsize="32" regnum="1062" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr54" bitsize="32" regnum="1063" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr55" bitsize="32" regnum="1064" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr56" bitsize="32" regnum="1065" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr57" bitsize="32" regnum="1066" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr58" bitsize="32" regnum="1067" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr59" bitsize="32" regnum="1068" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr60" bitsize="32" regnum="1069" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr61" bitsize="32" regnum="1070" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr62" bitsize="32" regnum="1071" save-restore="no" type="int" group="csr"/>
<reg name="pmpaddr63" bitsize="32" regnum="1072" save-restore="no" type="int" group="csr"/>
<reg name="scontext" bitsize="32" regnum="1513" save-restore="no" type="int" group="csr"/>
<reg name="hstatus" bitsize="32" regnum="1601" save-restore="no" type="int" group="csr"/>
<reg name="hedeleg" bitsize="32" regnum="1603" save-restore="no" type="int" group="csr"/>
<reg name="hideleg" bitsize="32" regnum="1604" save-restore="no" type="int" group="csr"/>
<reg name="hie" bitsize="32" regnum="1605" save-restore="no" type="int" group="csr"/>
<reg name="htimedelta" bitsize="32" regnum="1606" save-restore="no" type="int" group="csr"/>
<reg name="hcounteren" bitsize="32" regnum="1607" save-restore="no" type="int" group="csr"/>
<reg name="hgeie" bitsize="32" regnum="1608" save-restore="no" type="int" group="csr"/>
<reg name="henvcfg" bitsize="32" regnum="1611" save-restore="no" type="int" group="csr"/>
<reg name="hstateen0" bitsize="32" regnum="1613" save-restore="no" type="int" group="csr"/>
<reg name="hstateen1" bitsize="32" regnum="1614" save-restore="no" type="int" group="csr"/>
<reg name="hstateen2" bitsize="32" regnum="1615" save-restore="no" type="int" group="csr"/>
<reg name="hstateen3" bitsize="32" regnum="1616" save-restore="no" type="int" group="csr"/>
<reg name="htimedeltah" bitsize="32" regnum="1622" save-restore="no" type="int" group="csr"/>
<reg name="henvcfgh" bitsize="32" regnum="1627" save-restore="no" type="int" group="csr"/>
<reg name="hstateen0h" bitsize="32" regnum="1629" save-restore="no" type="int" group="csr"/>
<reg name="hstateen1h" bitsize="32" regnum="1630" save-restore="no" type="int" group="csr"/>
<reg name="hstateen2h" bitsize="32" regnum="1631" save-restore="no" type="int" group="csr"/>
<reg name="hstateen3h" bitsize="32" regnum="1632" save-restore="no" type="int" group="csr"/>
<reg name="htval" bitsize="32" regnum="1668" save-restore="no" type="int" group="csr"/>
<reg name="hip" bitsize="32" regnum="1669" save-restore="no" type="int" group="csr"/>
<reg name="hvip" bitsize="32" regnum="1670" save-restore="no" type="int" group="csr"/>
<reg name="htinst" bitsize="32" regnum="1675" save-restore="no" type="int" group="csr"/>
<reg name="hgatp" bitsize="32" regnum="1729" save-restore="no" type="int" group="csr"/>
<reg name="hcontext" bitsize="32" regnum="1769" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent3h" bitsize="32" regnum="1892" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent4h" bitsize="32" regnum="1893" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent5h" bitsize="32" regnum="1894" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent6h" bitsize="32" regnum="1895" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent7h" bitsize="32" regnum="1896" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent8h" bitsize="32" regnum="1897" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent9h" bitsize="32" regnum="1898" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent10h" bitsize="32" regnum="1899" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent11h" bitsize="32" regnum="1900" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent12h" bitsize="32" regnum="1901" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent13h" bitsize="32" regnum="1902" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent14h" bitsize="32" regnum="1903" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent15h" bitsize="32" regnum="1904" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent16h" bitsize="32" regnum="1905" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent17h" bitsize="32" regnum="1906" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent18h" bitsize="32" regnum="1907" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent19h" bitsize="32" regnum="1908" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent20h" bitsize="32" regnum="1909" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent21h" bitsize="32" regnum="1910" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent22h" bitsize="32" regnum="1911" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent23h" bitsize="32" regnum="1912" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent24h" bitsize="32" regnum="1913" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent25h" bitsize="32" regnum="1914" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent26h" bitsize="32" regnum="1915" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent27h" bitsize="32" regnum="1916" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent28h" bitsize="32" regnum="1917" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent29h" bitsize="32" regnum="1918" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent30h" bitsize="32" regnum="1919" save-restore="no" type="int" group="csr"/>
<reg name="mhpmevent31h" bitsize="32" regnum="1920" save-restore="no" type="int" group="csr"/>
<reg name="mseccfg" bitsize="32" regnum="1928" save-restore="no" type="int" group="csr"/>
<reg name="mseccfgh" bitsize="32" regnum="1944" save-restore="no" type="int" group="csr"/>
<reg name="tselect" bitsize="32" regnum="2017" save-restore="no" type="int" group="csr"/>
<reg name="tdata1" bitsize="32" regnum="2018" save-restore="no" type="int" group="csr"/>
<reg name="tdata2" bitsize="32" regnum="2019" save-restore="no" type="int" group="csr"/>
<reg name="tdata3" bitsize="32" regnum="2020" save-restore="no" type="int" group="csr"/>
<reg name="tinfo" bitsize="32" regnum="2021" save-restore="no" type="int" group="csr"/>
<reg name="tcontrol" bitsize="32" regnum="2022" save-restore="no" type="int" group="csr"/>
<reg name="mcontext" bitsize="32" regnum="2025" save-restore="no" type="int" group="csr"/>
<reg name="mscontext" bitsize="32" regnum="2027" save-restore="no" type="int" group="csr"/>
<reg name="dcsr" bitsize="32" regnum="2033" save-restore="no" type="int" group="csr"/>
<reg name="dpc" bitsize="32" regnum="2034" save-restore="no" type="int" group="csr"/>
<reg name="dscratch0" bitsize="32" regnum="2035" save-restore="no" type="int" group="csr"/>
<reg name="dscratch1" bitsize="32" regnum="2036" save-restore="no" type="int" group="csr"/>
<reg name="mcycle" bitsize="32" regnum="2881" save-restore="no" type="int" group="csr"/>
<reg name="minstret" bitsize="32" regnum="2883" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter3" bitsize="32" regnum="2884" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter4" bitsize="32" regnum="2885" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter5" bitsize="32" regnum="2886" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter6" bitsize="32" regnum="2887" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter7" bitsize="32" regnum="2888" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter8" bitsize="32" regnum="2889" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter9" bitsize="32" regnum="2890" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter10" bitsize="32" regnum="2891" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter11" bitsize="32" regnum="2892" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter12" bitsize="32" regnum="2893" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter13" bitsize="32" regnum="2894" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter14" bitsize="32" regnum="2895" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter15" bitsize="32" regnum="2896" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter16" bitsize="32" regnum="2897" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter17" bitsize="32" regnum="2898" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter18" bitsize="32" regnum="2899" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter19" bitsize="32" regnum="2900" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter20" bitsize="32" regnum="2901" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter21" bitsize="32" regnum="2902" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter22" bitsize="32" regnum="2903" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter23" bitsize="32" regnum="2904" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter24" bitsize="32" regnum="2905" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter25" bitsize="32" regnum="2906" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter26" bitsize="32" regnum="2907" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter27" bitsize="32" regnum="2908" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter28" bitsize="32" regnum="2909" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter29" bitsize="32" regnum="2910" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter30" bitsize="32" regnum="2911" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter31" bitsize="32" regnum="2912" save-restore="no" type="int" group="csr"/>
<reg name="mcycleh" bitsize="32" regnum="3009" save-restore="no" type="int" group="csr"/>
<reg name="minstreth" bitsize="32" regnum="3011" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter3h" bitsize="32" regnum="3012" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter4h" bitsize="32" regnum="3013" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter5h" bitsize="32" regnum="3014" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter6h" bitsize="32" regnum="3015" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter7h" bitsize="32" regnum="3016" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter8h" bitsize="32" regnum="3017" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter9h" bitsize="32" regnum="3018" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter10h" bitsize="32" regnum="3019" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter11h" bitsize="32" regnum="3020" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter12h" bitsize="32" regnum="3021" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter13h" bitsize="32" regnum="3022" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter14h" bitsize="32" regnum="3023" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter15h" bitsize="32" regnum="3024" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter16h" bitsize="32" regnum="3025" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter17h" bitsize="32" regnum="3026" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter18h" bitsize="32" regnum="3027" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter19h" bitsize="32" regnum="3028" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter20h" bitsize="32" regnum="3029" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter21h" bitsize="32" regnum="3030" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter22h" bitsize="32" regnum="3031" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter23h" bitsize="32" regnum="3032" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter24h" bitsize="32" regnum="3033" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter25h" bitsize="32" regnum="3034" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter26h" bitsize="32" regnum="3035" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter27h" bitsize="32" regnum="3036" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter28h" bitsize="32" regnum="3037" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter29h" bitsize="32" regnum="3038" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter30h" bitsize="32" regnum="3039" save-restore="no" type="int" group="csr"/>
<reg name="mhpmcounter31h" bitsize="32" regnum="3040" save-restore="no" type="int" group="csr"/>
<reg name="cycle" bitsize="32" regnum="3137" save-restore="no" type="int" group="csr"/>
<reg name="time" bitsize="32" regnum="3138" save-restore="no" type="int" group="csr"/>
<reg name="instret" bitsize="32" regnum="3139" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter3" bitsize="32" regnum="3140" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter4" bitsize="32" regnum="3141" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter5" bitsize="32" regnum="3142" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter6" bitsize="32" regnum="3143" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter7" bitsize="32" regnum="3144" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter8" bitsize="32" regnum="3145" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter9" bitsize="32" regnum="3146" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter10" bitsize="32" regnum="3147" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter11" bitsize="32" regnum="3148" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter12" bitsize="32" regnum="3149" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter13" bitsize="32" regnum="3150" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter14" bitsize="32" regnum="3151" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter15" bitsize="32" regnum="3152" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter16" bitsize="32" regnum="3153" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter17" bitsize="32" regnum="3154" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter18" bitsize="32" regnum="3155" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter19" bitsize="32" regnum="3156" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter20" bitsize="32" regnum="3157" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter21" bitsize="32" regnum="3158" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter22" bitsize="32" regnum="3159" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter23" bitsize="32" regnum="3160" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter24" bitsize="32" regnum="3161" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter25" bitsize="32" regnum="3162" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter26" bitsize="32" regnum="3163" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter27" bitsize="32" regnum="3164" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter28" bitsize="32" regnum="3165" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter29" bitsize="32" regnum="3166" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter30" bitsize="32" regnum="3167" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter31" bitsize="32" regnum="3168" save-restore="no" type="int" group="csr"/>
<reg name="cycleh" bitsize="32" regnum="3265" save-restore="no" type="int" group="csr"/>
<reg name="timeh" bitsize="32" regnum="3266" save-restore="no" type="int" group="csr"/>
<reg name="instreth" bitsize="32" regnum="3267" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter3h" bitsize="32" regnum="3268" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter4h" bitsize="32" regnum="3269" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter5h" bitsize="32" regnum="3270" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter6h" bitsize="32" regnum="3271" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter7h" bitsize="32" regnum="3272" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter8h" bitsize="32" regnum="3273" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter9h" bitsize="32" regnum="3274" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter10h" bitsize="32" regnum="3275" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter11h" bitsize="32" regnum="3276" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter12h" bitsize="32" regnum="3277" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter13h" bitsize="32" regnum="3278" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter14h" bitsize="32" regnum="3279" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter15h" bitsize="32" regnum="3280" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter16h" bitsize="32" regnum="3281" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter17h" bitsize="32" regnum="3282" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter18h" bitsize="32" regnum="3283" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter19h" bitsize="32" regnum="3284" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter20h" bitsize="32" regnum="3285" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter21h" bitsize="32" regnum="3286" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter22h" bitsize="32" regnum="3287" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter23h" bitsize="32" regnum="3288" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter24h" bitsize="32" regnum="3289" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter25h" bitsize="32" regnum="3290" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter26h" bitsize="32" regnum="3291" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter27h" bitsize="32" regnum="3292" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter28h" bitsize="32" regnum="3293" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter29h" bitsize="32" regnum="3294" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter30h" bitsize="32" regnum="3295" save-restore="no" type="int" group="csr"/>
<reg name="hpmcounter31h" bitsize="32" regnum="3296" save-restore="no" type="int" group="csr"/>
<reg name="scountovf" bitsize="32" regnum="3553" save-restore="no" type="int" group="csr"/>
<reg name="hgeip" bitsize="32" regnum="3667" save-restore="no" type="int" group="csr"/>
<reg name="mvendorid" bitsize="32" regnum="3922" save-restore="no" type="int" group="csr"/>
<reg name="marchid" bitsize="32" regnum="3923" save-restore="no" type="int" group="csr"/>
<reg name="mimpid" bitsize="32" regnum="3924" save-restore="no" type="int" group="csr"/>
<reg name="mhartid" bitsize="32" regnum="3925" save-restore="no" type="int" group="csr"/>
<reg name="mconfigptr" bitsize="32" regnum="3926" save-restore="no" type="int" group="csr"/>
<reg name="mtopi" bitsize="32" regnum="4081" save-restore="no" type="int" group="csr"/>
</feature>
<feature name="org.gnu.gdb.riscv.virtual">
<reg name="priv" bitsize="8" regnum="4161" save-restore="no" type="int" group="general"/>
</feature>
</target>