Conform to OpenOCD style guide.

Change-Id: I2b23ac79639ed40e9d59db5c52ea2196df0349bc
fence_i_fix_for_release
Tim Newsome 2017-12-22 14:35:38 -08:00
parent 19d9e3e32a
commit d942bce996
16 changed files with 848 additions and 735 deletions

View File

@ -28,7 +28,7 @@ matrix:
- os: linux
env:
- BUILD=i686-linux-gnu
- BUILD=i686-linux-gnu
- CFLAGS=-m32
- EXECUTABLE=openocd
compiler: clang
@ -38,7 +38,7 @@ matrix:
- gcc-multilib
- os: linux
env:
env:
- BUILD=i686-w64-mingw
- CONFIGURE_ARGS="--build=i686-unknown-linux-gnu --host=i686-w64-mingw32"
- EXECUTABLE=openocd.exe

View File

@ -1,7 +1,7 @@
/***************************************************************************
* Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com> *
* Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *
* *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
@ -18,7 +18,7 @@
/* The Freedom E SPI controller is a SPI bus controller
* specifically designed for SPI Flash Memories on Freedom E platforms.
*
*
* Two working modes are available:
* - SW mode: the SPI is controlled by SW. Any custom commands can be sent
* on the bus. Writes are only possible in this mode.
@ -127,7 +127,7 @@
int __a; \
uint32_t __v; \
\
__a = target_read_u32(target, ctrl_base + (a), &__v); \
__a = target_read_u32(target, ctrl_base + (a), &__v); \
if (__a != ERROR_OK) { \
LOG_ERROR("FESPI_READ_REG error"); \
return __a; \
@ -139,7 +139,7 @@
{ \
int __r; \
\
__r = target_write_u32(target, ctrl_base + (a), (v)); \
__r = target_write_u32(target, ctrl_base + (a), (v)); \
if (__r != ERROR_OK) { \
LOG_ERROR("FESPI_WRITE_REG error"); \
return __r; \
@ -163,7 +163,7 @@ struct fespi_target {
uint32_t ctrl_base;
};
//TODO !!! What is the right naming convention here?
/* TODO !!! What is the right naming convention here? */
static const struct fespi_target target_devices[] = {
/* name, tap_idcode, ctrl_base */
{ "Freedom E300 SPI Flash", 0x10e31913 , 0x10014000 },
@ -189,16 +189,17 @@ FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command)
fespi_info->probed = 0;
fespi_info->ctrl_base = 0;
if (CMD_ARGC >= 7) {
int temp;
COMMAND_PARSE_NUMBER(int, CMD_ARGV[6], temp);
fespi_info->ctrl_base = (uint32_t) temp;
LOG_DEBUG("ASSUMING FESPI device at ctrl_base = 0x%x", fespi_info->ctrl_base);
int temp;
COMMAND_PARSE_NUMBER(int, CMD_ARGV[6], temp);
fespi_info->ctrl_base = (uint32_t) temp;
LOG_DEBUG("ASSUMING FESPI device at ctrl_base = 0x%x", fespi_info->ctrl_base);
}
return ERROR_OK;
}
static int fespi_set_dir (struct flash_bank * bank, bool dir) {
static int fespi_set_dir(struct flash_bank *bank, bool dir)
{
struct target *target = bank->target;
struct fespi_flash_bank *fespi_info = bank->driver_priv;
uint32_t ctrl_base = fespi_info->ctrl_base;
@ -211,7 +212,8 @@ static int fespi_set_dir (struct flash_bank * bank, bool dir) {
}
static int fespi_txwm_wait(struct flash_bank *bank) {
static int fespi_txwm_wait(struct flash_bank *bank)
{
struct target *target = bank->target;
struct fespi_flash_bank *fespi_info = bank->driver_priv;
uint32_t ctrl_base = fespi_info->ctrl_base;
@ -219,9 +221,8 @@ static int fespi_txwm_wait(struct flash_bank *bank) {
int64_t start = timeval_ms();
while (1) {
if (FESPI_READ_REG(FESPI_REG_IP) & FESPI_IP_TXWM) {
if (FESPI_READ_REG(FESPI_REG_IP) & FESPI_IP_TXWM)
break;
}
int64_t now = timeval_ms();
if (now - start > 1000) {
LOG_ERROR("ip.txwm didn't get set.");
@ -233,7 +234,8 @@ static int fespi_txwm_wait(struct flash_bank *bank) {
}
static int fespi_tx(struct flash_bank *bank, uint8_t in){
static int fespi_tx(struct flash_bank *bank, uint8_t in)
{
struct target *target = bank->target;
struct fespi_flash_bank *fespi_info = bank->driver_priv;
uint32_t ctrl_base = fespi_info->ctrl_base;
@ -241,9 +243,8 @@ static int fespi_tx(struct flash_bank *bank, uint8_t in){
int64_t start = timeval_ms();
while (1) {
if ((int32_t) FESPI_READ_REG(FESPI_REG_TXFIFO) >= 0) {
if ((int32_t) FESPI_READ_REG(FESPI_REG_TXFIFO) >= 0)
break;
}
int64_t now = timeval_ms();
if (now - start > 1000) {
LOG_ERROR("txfifo stayed negative.");
@ -276,14 +277,14 @@ static int fespi_rx(struct flash_bank *bank, uint8_t *out)
}
}
if (out) {
if (out)
*out = value & 0xff;
}
return ERROR_OK;
}
//TODO!!! Why don't we need to call this after writing?
static int fespi_wip (struct flash_bank * bank, int timeout)
/* TODO!!! Why don't we need to call this after writing? */
static int fespi_wip(struct flash_bank *bank, int timeout)
{
struct target *target = bank->target;
struct fespi_flash_bank *fespi_info = bank->driver_priv;
@ -326,26 +327,34 @@ static int fespi_erase_sector(struct flash_bank *bank, int sector)
int retval;
retval = fespi_tx(bank, SPIFLASH_WRITE_ENABLE);
if (retval != ERROR_OK) {return retval;}
if (retval != ERROR_OK)
return retval;
retval = fespi_txwm_wait(bank);
if (retval != ERROR_OK) {return retval;}
if (retval != ERROR_OK)
return retval;
FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_HOLD);
retval = fespi_tx(bank, fespi_info->dev->erase_cmd);
if (retval != ERROR_OK) {return retval;}
if (retval != ERROR_OK)
return retval;
sector = bank->sectors[sector].offset;
retval = fespi_tx(bank, sector >> 16);
if (retval != ERROR_OK) {return retval;}
if (retval != ERROR_OK)
return retval;
retval = fespi_tx(bank, sector >> 8);
if (retval != ERROR_OK) {return retval;}
if (retval != ERROR_OK)
return retval;
retval = fespi_tx(bank, sector);
if (retval != ERROR_OK) {return retval;}
if (retval != ERROR_OK)
return retval;
retval = fespi_txwm_wait(bank);
if (retval != ERROR_OK) {return retval;}
if (retval != ERROR_OK)
return retval;
FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_AUTO);
retval = fespi_wip(bank, FESPI_MAX_TIMEOUT);
if (retval != ERROR_OK){return retval;}
if (retval != ERROR_OK)
return retval;
return ERROR_OK;
}
@ -384,9 +393,9 @@ static int fespi_erase(struct flash_bank *bank, int first, int last)
FESPI_WRITE_REG(FESPI_REG_TXCTRL, FESPI_TXWM(1));
retval = fespi_txwm_wait(bank);
if (retval != ERROR_OK){
LOG_ERROR("WM Didn't go high before attempting.");
return retval;
if (retval != ERROR_OK) {
LOG_ERROR("WM Didn't go high before attempting.");
return retval;
}
/* Disable Hardware accesses*/
@ -394,7 +403,7 @@ static int fespi_erase(struct flash_bank *bank, int first, int last)
/* poll WIP */
retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);
if (retval != ERROR_OK)
if (retval != ERROR_OK)
return retval;
for (sector = first; sector <= last; sector++) {
@ -427,7 +436,7 @@ static int slow_fespi_write_buffer(struct flash_bank *bank,
uint32_t ctrl_base = fespi_info->ctrl_base;
uint32_t ii;
//TODO!!! assert that len < page size
/* TODO!!! assert that len < page size */
fespi_tx(bank, SPIFLASH_WRITE_ENABLE);
fespi_txwm_wait(bank);
@ -440,9 +449,8 @@ static int slow_fespi_write_buffer(struct flash_bank *bank,
fespi_tx(bank, offset >> 8);
fespi_tx(bank, offset);
for (ii = 0; ii < len; ii++) {
for (ii = 0; ii < len; ii++)
fespi_tx(bank, buffer[ii]);
}
fespi_txwm_wait(bank);
@ -487,67 +495,67 @@ static int slow_fespi_write_buffer(struct flash_bank *bank,
.global _start
_start:
command_table:
j main // 0
ebreak // 4
j tx // 8
j txwm_wait // 12
j write_reg // 16
j main // 0
ebreak // 4
j tx // 8
j txwm_wait // 12
j write_reg // 16
j wip_wait // 20
j set_dir // 24
j set_dir // 24
// Execute the program.
main:
lbu t0, 0(a1)
addi a1, a1, 1
la t1, command_table
add t0, t0, t1
jr t0
lbu t0, 0(a1)
addi a1, a1, 1
la t1, command_table
add t0, t0, t1
jr t0
// Read 1 byte the contains the number of bytes to transmit. Then read those
// bytes from the program and transmit them one by one.
tx:
lbu t1, 0(a1) // read number of bytes to transmit
addi a1, a1, 1
lbu t1, 0(a1) // read number of bytes to transmit
addi a1, a1, 1
1: lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
bltz t0, 1b
lbu t0, 0(a1) // Load byte to write
sw t0, FESPI_REG_TXFIFO(a0)
addi a1, a1, 1
addi t1, t1, -1
bgtz t1, 1b
j main
bltz t0, 1b
lbu t0, 0(a1) // Load byte to write
sw t0, FESPI_REG_TXFIFO(a0)
addi a1, a1, 1
addi t1, t1, -1
bgtz t1, 1b
j main
// Wait until TXWM is set.
txwm_wait:
1: lw t0, FESPI_REG_IP(a0)
andi t0, t0, FESPI_IP_TXWM
beqz t0, 1b
j main
andi t0, t0, FESPI_IP_TXWM
beqz t0, 1b
j main
// Read 1 byte that contains the offset of the register to write, and 1 byte
// that contains the data to write.
write_reg:
lbu t0, 0(a1) // read register to write
add t0, t0, a0
lbu t1, 1(a1) // read value to write
addi a1, a1, 2
sw t1, 0(t0)
j main
lbu t0, 0(a1) // read register to write
add t0, t0, a0
lbu t1, 1(a1) // read value to write
addi a1, a1, 2
sw t1, 0(t0)
j main
wip_wait:
li a2, SPIFLASH_READ_STATUS
jal txrx_byte
jal txrx_byte
// discard first result
1: li a2, 0
jal txrx_byte
jal txrx_byte
andi t0, a2, SPIFLASH_BSY_BIT
bnez t0, 1b
j main
txrx_byte: // transmit the byte in a2, receive a bit into a2
lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
bltz t0, txrx_byte
sw a2, FESPI_REG_TXFIFO(a0)
bltz t0, txrx_byte
sw a2, FESPI_REG_TXFIFO(a0)
1: lw a2, FESPI_REG_RXFIFO(a0)
bltz a2, 1b
ret
@ -556,8 +564,8 @@ set_dir:
lw t0, FESPI_REG_FMT(a0)
li t1, ~(FESPI_FMT_DIR(0xFFFFFFFF))
and t0, t0, t1
lbu t1, 0(a1) // read value to OR in
addi a1, a1, 1
lbu t1, 0(a1) // read value to OR in
addi a1, a1, 1
or t0, t0, t1
sw t0, FESPI_REG_FMT(a0)
j main
@ -565,24 +573,24 @@ set_dir:
// ALGO_END
*/
static const uint8_t algorithm_bin[] = {
0x6f, 0x00, 0xc0, 0x01, 0x73, 0x00, 0x10, 0x00, 0x6f, 0x00, 0xc0, 0x02,
0x6f, 0x00, 0x00, 0x05, 0x6f, 0x00, 0xc0, 0x05, 0x6f, 0x00, 0x00, 0x07,
0x6f, 0x00, 0x00, 0x0a, 0x83, 0xc2, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00,
0x17, 0x03, 0x00, 0x00, 0x13, 0x03, 0xc3, 0xfd, 0xb3, 0x82, 0x62, 0x00,
0x67, 0x80, 0x02, 0x00, 0x03, 0xc3, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00,
0x83, 0x22, 0x85, 0x04, 0xe3, 0xce, 0x02, 0xfe, 0x83, 0xc2, 0x05, 0x00,
0x23, 0x24, 0x55, 0x04, 0x93, 0x85, 0x15, 0x00, 0x13, 0x03, 0xf3, 0xff,
0xe3, 0x44, 0x60, 0xfe, 0x6f, 0xf0, 0x5f, 0xfc, 0x83, 0x22, 0x45, 0x07,
0x93, 0xf2, 0x12, 0x00, 0xe3, 0x8c, 0x02, 0xfe, 0x6f, 0xf0, 0x5f, 0xfb,
0x83, 0xc2, 0x05, 0x00, 0xb3, 0x82, 0xa2, 0x00, 0x03, 0xc3, 0x15, 0x00,
0x93, 0x85, 0x25, 0x00, 0x23, 0xa0, 0x62, 0x00, 0x6f, 0xf0, 0xdf, 0xf9,
0x13, 0x06, 0x50, 0x00, 0xef, 0x00, 0x80, 0x01, 0x13, 0x06, 0x00, 0x00,
0xef, 0x00, 0x00, 0x01, 0x93, 0x72, 0x16, 0x00, 0xe3, 0x9a, 0x02, 0xfe,
0x6f, 0xf0, 0x1f, 0xf8, 0x83, 0x22, 0x85, 0x04, 0xe3, 0xce, 0x02, 0xfe,
0x23, 0x24, 0xc5, 0x04, 0x03, 0x26, 0xc5, 0x04, 0xe3, 0x4e, 0x06, 0xfe,
0x67, 0x80, 0x00, 0x00, 0x83, 0x22, 0x05, 0x04, 0x13, 0x03, 0x70, 0xff,
0xb3, 0xf2, 0x62, 0x00, 0x03, 0xc3, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00,
0xb3, 0xe2, 0x62, 0x00, 0x23, 0x20, 0x55, 0x04, 0x6f, 0xf0, 0x9f, 0xf4
0x6f, 0x00, 0xc0, 0x01, 0x73, 0x00, 0x10, 0x00, 0x6f, 0x00, 0xc0, 0x02,
0x6f, 0x00, 0x00, 0x05, 0x6f, 0x00, 0xc0, 0x05, 0x6f, 0x00, 0x00, 0x07,
0x6f, 0x00, 0x00, 0x0a, 0x83, 0xc2, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00,
0x17, 0x03, 0x00, 0x00, 0x13, 0x03, 0xc3, 0xfd, 0xb3, 0x82, 0x62, 0x00,
0x67, 0x80, 0x02, 0x00, 0x03, 0xc3, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00,
0x83, 0x22, 0x85, 0x04, 0xe3, 0xce, 0x02, 0xfe, 0x83, 0xc2, 0x05, 0x00,
0x23, 0x24, 0x55, 0x04, 0x93, 0x85, 0x15, 0x00, 0x13, 0x03, 0xf3, 0xff,
0xe3, 0x44, 0x60, 0xfe, 0x6f, 0xf0, 0x5f, 0xfc, 0x83, 0x22, 0x45, 0x07,
0x93, 0xf2, 0x12, 0x00, 0xe3, 0x8c, 0x02, 0xfe, 0x6f, 0xf0, 0x5f, 0xfb,
0x83, 0xc2, 0x05, 0x00, 0xb3, 0x82, 0xa2, 0x00, 0x03, 0xc3, 0x15, 0x00,
0x93, 0x85, 0x25, 0x00, 0x23, 0xa0, 0x62, 0x00, 0x6f, 0xf0, 0xdf, 0xf9,
0x13, 0x06, 0x50, 0x00, 0xef, 0x00, 0x80, 0x01, 0x13, 0x06, 0x00, 0x00,
0xef, 0x00, 0x00, 0x01, 0x93, 0x72, 0x16, 0x00, 0xe3, 0x9a, 0x02, 0xfe,
0x6f, 0xf0, 0x1f, 0xf8, 0x83, 0x22, 0x85, 0x04, 0xe3, 0xce, 0x02, 0xfe,
0x23, 0x24, 0xc5, 0x04, 0x03, 0x26, 0xc5, 0x04, 0xe3, 0x4e, 0x06, 0xfe,
0x67, 0x80, 0x00, 0x00, 0x83, 0x22, 0x05, 0x04, 0x13, 0x03, 0x70, 0xff,
0xb3, 0xf2, 0x62, 0x00, 0x03, 0xc3, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00,
0xb3, 0xe2, 0x62, 0x00, 0x23, 0x20, 0x55, 0x04, 0x6f, 0xf0, 0x9f, 0xf4
};
#define STEP_EXIT 4
#define STEP_TX 8
@ -625,7 +633,7 @@ static int as_empty(struct algorithm_steps *as)
return 1;
}
// Return size of compiled program.
/* Return size of compiled program. */
static unsigned as_compile(struct algorithm_steps *as, uint8_t *target,
unsigned target_size)
{
@ -684,9 +692,8 @@ static unsigned as_compile(struct algorithm_steps *as, uint8_t *target,
LOG_DEBUG("%d-byte program:", offset);
for (unsigned i = 0; i < offset;) {
char buf[80];
for (unsigned x = 0; i < offset && x < 16; x++, i++) {
for (unsigned x = 0; i < offset && x < 16; x++, i++)
sprintf(buf + x*3, "%02x ", target[i]);
}
LOG_DEBUG("%s", buf);
}
@ -771,7 +778,7 @@ static int steps_add_buffer_write(struct algorithm_steps *as,
as_add_txwm_wait(as);
as_add_write_reg(as, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO);
// fespi_wip()
/* fespi_wip() */
as_add_set_dir(as, FESPI_DIR_RX);
as_add_write_reg(as, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD);
as_add_wip_wait(as);
@ -908,11 +915,10 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
cur_count = 4 - (offset & 3);
if (cur_count > count)
cur_count = count;
if (algorithm_wa) {
if (algorithm_wa)
retval = steps_add_buffer_write(as, buffer, offset, cur_count);
} else {
else
retval = slow_fespi_write_buffer(bank, buffer, offset, cur_count);
}
if (retval != ERROR_OK)
goto err;
offset += cur_count;
@ -929,11 +935,10 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
else
cur_count = count & ~3;
if (algorithm_wa) {
if (algorithm_wa)
retval = steps_add_buffer_write(as, buffer, offset, cur_count);
} else {
else
retval = slow_fespi_write_buffer(bank, buffer, offset, cur_count);
}
if (retval != ERROR_OK)
goto err;
@ -945,18 +950,16 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
/* buffer tail */
if (count > 0) {
if (algorithm_wa) {
if (algorithm_wa)
retval = steps_add_buffer_write(as, buffer, offset, count);
} else {
else
retval = slow_fespi_write_buffer(bank, buffer, offset, count);
}
if (retval != ERROR_OK)
goto err;
}
if (algorithm_wa) {
if (algorithm_wa)
retval = steps_execute(as, bank, algorithm_wa, data_wa);
}
err:
if (algorithm_wa) {
@ -1043,27 +1046,27 @@ static int fespi_probe(struct flash_bank *bank)
fespi_info->probed = 0;
if (fespi_info->ctrl_base == 0) {
for (target_device = target_devices ; target_device->name ; ++target_device)
if (target_device->tap_idcode == target->tap->idcode)
break;
for (target_device = target_devices ; target_device->name ; ++target_device)
if (target_device->tap_idcode == target->tap->idcode)
break;
if (!target_device->name) {
LOG_ERROR("Device ID 0x%" PRIx32 " is not known as FESPI capable",
target->tap->idcode);
return ERROR_FAIL;
}
if (!target_device->name) {
LOG_ERROR("Device ID 0x%" PRIx32 " is not known as FESPI capable",
target->tap->idcode);
return ERROR_FAIL;
}
fespi_info->ctrl_base = target_device->ctrl_base;
fespi_info->ctrl_base = target_device->ctrl_base;
LOG_DEBUG("Valid FESPI on device %s at address 0x%" PRIx32,
target_device->name, bank->base);
LOG_DEBUG("Valid FESPI on device %s at address 0x%" PRIx32,
target_device->name, bank->base);
} else {
LOG_DEBUG("Assuming FESPI as specified at address 0x%x with ctrl at 0x%x",
fespi_info->ctrl_base,
bank->base);
}
ctrl_base = fespi_info->ctrl_base;
ctrl_base = fespi_info->ctrl_base;
/* read and decode flash ID; returns in SW mode */
FESPI_WRITE_REG(FESPI_REG_TXCTRL, FESPI_TXWM(1));

View File

@ -76,10 +76,8 @@ static void remote_bitbang_fill_buf(void)
contiguous_available_space);
if (count > 0) {
remote_bitbang_end += count;
// TODO: check for overflow.
if (remote_bitbang_end == sizeof(remote_bitbang_buf)) {
if (remote_bitbang_end == sizeof(remote_bitbang_buf))
remote_bitbang_end = 0;
}
} else if (count == 0) {
return;
} else if (count < 0) {
@ -171,7 +169,7 @@ static int remote_bitbang_read_sample(void)
{
if (remote_bitbang_start != remote_bitbang_end) {
int c = remote_bitbang_buf[remote_bitbang_start];
remote_bitbang_start =
remote_bitbang_start =
(remote_bitbang_start + 1) % sizeof(remote_bitbang_buf);
return char_to_int(c);
}

View File

@ -79,7 +79,7 @@ static int riscv_gdb_thread_packet(struct connection *connection, const char *pa
if (strncmp(packet, "qfThreadInfo", 12) == 0) {
riscv_update_threads(target->rtos);
r->qs_thread_info_offset = 1;
char m[16];
snprintf(m, 16, "m%08x", (int)rtos->thread_details[0].threadid);
gdb_put_packet(connection, m, strlen(m));
@ -305,8 +305,7 @@ static int riscv_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
return JIM_OK;
}
const struct rtos_type riscv_rtos =
{
const struct rtos_type riscv_rtos = {
.name = "riscv",
.detect_rtos = riscv_detect_rtos,
.create = riscv_create_rtos,

View File

@ -1286,10 +1286,10 @@ static int gdb_get_register_packet(struct connection *connection,
}
if (!reg_list[reg_num]->valid) {
retval = reg_list[reg_num]->type->get(reg_list[reg_num]);
retval = reg_list[reg_num]->type->get(reg_list[reg_num]);
if (retval != ERROR_OK) {
LOG_DEBUG("Couldn't get register %s.", reg_list[reg_num]->name);
free (reg_list);
free(reg_list);
return gdb_error(connection, retval);
}
}
@ -1347,7 +1347,7 @@ static int gdb_set_register_packet(struct connection *connection,
gdb_target_to_reg(target, separator + 1, chars, bin_buf);
retval = reg_list[reg_num]->type->set(reg_list[reg_num], bin_buf);
if (retval != ERROR_OK){
if (retval != ERROR_OK) {
LOG_DEBUG("Couldn't set register %s.", reg_list[reg_num]->name);
free(bin_buf);
free(reg_list);

View File

@ -17,7 +17,7 @@ static uint32_t load(const struct target *target, unsigned int rd,
return ld(rd, base, offset);
}
assert(0);
return 0; // Silence -Werror=return-type
return 0; /* Silence -Werror=return-type */
}
static uint32_t store(const struct target *target, unsigned int src,
@ -32,7 +32,7 @@ static uint32_t store(const struct target *target, unsigned int src,
return sd(src, base, offset);
}
assert(0);
return 0; // Silence -Werror=return-type
return 0; /* Silence -Werror=return-type */
}
#endif

View File

@ -138,8 +138,8 @@ void riscv_batch_add_nop(struct riscv_batch *batch)
void dump_field(const struct scan_field *field)
{
static const char *op_string[] = {"-", "r", "w", "?"};
static const char *status_string[] = {"+", "?", "F", "b"};
static const char * const op_string[] = {"-", "r", "w", "?"};
static const char * const status_string[] = {"+", "?", "F", "b"};
if (debug_level < LOG_LVL_DEBUG)
return;

View File

@ -295,7 +295,7 @@
*
* Other values are reserved for future use.
*/
#define CSR_TDATA1_TYPE_OFFSET XLEN-4
#define CSR_TDATA1_TYPE_OFFSET (XLEN-4)
#define CSR_TDATA1_TYPE_LENGTH 4
#define CSR_TDATA1_TYPE (0xfULL << CSR_TDATA1_TYPE_OFFSET)
/*
@ -307,14 +307,14 @@
*
* This bit is only writable from Debug Mode.
*/
#define CSR_TDATA1_DMODE_OFFSET XLEN-5
#define CSR_TDATA1_DMODE_OFFSET (XLEN-5)
#define CSR_TDATA1_DMODE_LENGTH 1
#define CSR_TDATA1_DMODE (0x1ULL << CSR_TDATA1_DMODE_OFFSET)
/*
* Trigger-specific data.
*/
#define CSR_TDATA1_DATA_OFFSET 0
#define CSR_TDATA1_DATA_LENGTH XLEN - 5
#define CSR_TDATA1_DATA_LENGTH (XLEN - 5)
#define CSR_TDATA1_DATA (((1L<<XLEN - 5)-1) << CSR_TDATA1_DATA_OFFSET)
#define CSR_TDATA2 0x7a2
#define CSR_TDATA2_DATA_OFFSET 0
@ -325,10 +325,10 @@
#define CSR_TDATA3_DATA_LENGTH XLEN
#define CSR_TDATA3_DATA (((1L<<XLEN)-1) << CSR_TDATA3_DATA_OFFSET)
#define CSR_MCONTROL 0x7a1
#define CSR_MCONTROL_TYPE_OFFSET XLEN-4
#define CSR_MCONTROL_TYPE_OFFSET (XLEN-4)
#define CSR_MCONTROL_TYPE_LENGTH 4
#define CSR_MCONTROL_TYPE (0xfULL << CSR_MCONTROL_TYPE_OFFSET)
#define CSR_MCONTROL_DMODE_OFFSET XLEN-5
#define CSR_MCONTROL_DMODE_OFFSET (XLEN-5)
#define CSR_MCONTROL_DMODE_LENGTH 1
#define CSR_MCONTROL_DMODE (0x1ULL << CSR_MCONTROL_DMODE_OFFSET)
/*
@ -339,7 +339,7 @@
* corresponds to the maximum NAPOT range, which is $2^{63}$ bytes in
* size.
*/
#define CSR_MCONTROL_MASKMAX_OFFSET XLEN-11
#define CSR_MCONTROL_MASKMAX_OFFSET (XLEN-11)
#define CSR_MCONTROL_MASKMAX_LENGTH 6
#define CSR_MCONTROL_MASKMAX (0x3fULL << CSR_MCONTROL_MASKMAX_OFFSET)
/*
@ -478,10 +478,10 @@
#define CSR_MCONTROL_LOAD_LENGTH 1
#define CSR_MCONTROL_LOAD (0x1ULL << CSR_MCONTROL_LOAD_OFFSET)
#define CSR_ICOUNT 0x7a1
#define CSR_ICOUNT_TYPE_OFFSET XLEN-4
#define CSR_ICOUNT_TYPE_OFFSET (XLEN-4)
#define CSR_ICOUNT_TYPE_LENGTH 4
#define CSR_ICOUNT_TYPE (0xfULL << CSR_ICOUNT_TYPE_OFFSET)
#define CSR_ICOUNT_DMODE_OFFSET XLEN-5
#define CSR_ICOUNT_DMODE_OFFSET (XLEN-5)
#define CSR_ICOUNT_DMODE_LENGTH 1
#define CSR_ICOUNT_DMODE (0x1ULL << CSR_ICOUNT_DMODE_OFFSET)
/*

View File

@ -1,8 +1,8 @@
#ifndef TARGET__RISCV__GDB_REGS_H
#define TARGET__RISCV__GDB_REGS_H
// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
// its source tree. We must interpret the numbers the same here.
/* gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
* its source tree. We must interpret the numbers the same here. */
enum gdb_regno {
GDB_REGNO_ZERO = 0, /* Read-only register, always 0. */
GDB_REGNO_RA = 1, /* Return Address. */

View File

@ -5,16 +5,19 @@
#define S0 8
#define S1 9
static uint32_t bits(uint32_t value, unsigned int hi, unsigned int lo) {
static uint32_t bits(uint32_t value, unsigned int hi, unsigned int lo)
{
return (value >> lo) & ((1 << (hi+1-lo)) - 1);
}
static uint32_t bit(uint32_t value, unsigned int b) {
static uint32_t bit(uint32_t value, unsigned int b)
{
return (value >> b) & 1;
}
static uint32_t jal(unsigned int rd, uint32_t imm) __attribute__ ((unused));
static uint32_t jal(unsigned int rd, uint32_t imm) {
static uint32_t jal(unsigned int rd, uint32_t imm)
{
return (bit(imm, 20) << 31) |
(bits(imm, 10, 1) << 21) |
(bit(imm, 11) << 20) |
@ -24,7 +27,8 @@ static uint32_t jal(unsigned int rd, uint32_t imm) {
}
static uint32_t csrsi(unsigned int csr, uint16_t imm) __attribute__ ((unused));
static uint32_t csrsi(unsigned int csr, uint16_t imm) {
static uint32_t csrsi(unsigned int csr, uint16_t imm)
{
return (csr << 20) |
(bits(imm, 4, 0) << 15) |
MATCH_CSRRSI;
@ -107,7 +111,8 @@ static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset)
}
static uint32_t csrw(unsigned int source, unsigned int csr) __attribute__ ((unused));
static uint32_t csrw(unsigned int source, unsigned int csr) {
static uint32_t csrw(unsigned int source, unsigned int csr)
{
return (csr << 20) | (source << 15) | MATCH_CSRRW;
}
@ -121,17 +126,20 @@ static uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm)
}
static uint32_t csrr(unsigned int rd, unsigned int csr) __attribute__ ((unused));
static uint32_t csrr(unsigned int rd, unsigned int csr) {
static uint32_t csrr(unsigned int rd, unsigned int csr)
{
return (csr << 20) | (rd << 7) | MATCH_CSRRS;
}
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) {
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr)
{
return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRS;
}
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) {
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr)
{
return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRW;
}
@ -206,9 +214,15 @@ static uint32_t fmv_d_x(unsigned dest, unsigned src)
}
static uint32_t ebreak(void) __attribute__ ((unused));
static uint32_t ebreak(void) { return MATCH_EBREAK; }
static uint32_t ebreak(void)
{
return MATCH_EBREAK;
}
static uint32_t ebreak_c(void) __attribute__ ((unused));
static uint32_t ebreak_c(void) { return MATCH_C_EBREAK; }
static uint32_t ebreak_c(void)
{
return MATCH_C_EBREAK;
}
static uint32_t fence_i(void) __attribute__ ((unused));
static uint32_t fence_i(void)
@ -226,7 +240,8 @@ static uint32_t lui(unsigned int dest, uint32_t imm)
/*
static uint32_t csrci(unsigned int csr, uint16_t imm) __attribute__ ((unused));
static uint32_t csrci(unsigned int csr, uint16_t imm) {
static uint32_t csrci(unsigned int csr, uint16_t imm)
{
return (csr << 20) |
(bits(imm, 4, 0) << 15) |
MATCH_CSRRCI;

View File

@ -18,11 +18,10 @@ int riscv_program_init(struct riscv_program *p, struct target *target)
p->target = target;
p->instruction_count = 0;
p->target_xlen = riscv_xlen(target);
for (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i) {
for (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i)
p->writes_xreg[i] = 0;
}
for(size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)
for (size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)
p->debug_buffer[i] = -1;
return ERROR_OK;
@ -54,7 +53,7 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
if (riscv_program_ebreak(p) != ERROR_OK) {
LOG_ERROR("Unable to write ebreak");
for(size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
LOG_ERROR("ram[%02x]: DASM(0x%08lx) [0x%08lx]", (int)i, (long)p->debug_buffer[i], (long)p->debug_buffer[i]);
abort();
return ERROR_FAIL;

File diff suppressed because it is too large Load Diff

View File

@ -150,20 +150,20 @@ typedef struct {
/* We only need the address so that we know the alignment of the buffer. */
riscv_addr_t progbuf_address;
// Number of run-test/idle cycles the target requests we do after each dbus
// access.
/* Number of run-test/idle cycles the target requests we do after each dbus
* access. */
unsigned int dtmcontrol_idle;
// This value is incremented every time a dbus access comes back as "busy".
// It's used to determine how many run-test/idle cycles to feed the target
// in between accesses.
/* This value is incremented every time a dbus access comes back as "busy".
* It's used to determine how many run-test/idle cycles to feed the target
* in between accesses. */
unsigned int dmi_busy_delay;
// This value is increased every time we tried to execute two commands
// consecutively, and the second one failed because the previous hadn't
// completed yet. It's used to add extra run-test/idle cycles after
// starting a command, so we don't have to waste time checking for busy to
// go low.
/* This value is increased every time we tried to execute two commands
* consecutively, and the second one failed because the previous hadn't
* completed yet. It's used to add extra run-test/idle cycles after
* starting a command, so we don't have to waste time checking for busy to
* go low. */
unsigned int ac_busy_delay;
bool need_strict_step;
@ -173,12 +173,12 @@ typedef struct {
bool abstract_read_fpr_supported;
bool abstract_write_fpr_supported;
// When a function returns some error due to a failure indicated by the
// target in cmderr, the caller can look here to see what that error was.
// (Compare with errno.)
/* When a function returns some error due to a failure indicated by the
* target in cmderr, the caller can look here to see what that error was.
* (Compare with errno.) */
uint8_t cmderr;
// Some fields from hartinfo.
/* Some fields from hartinfo. */
uint8_t datasize;
uint8_t dataaccess;
int16_t dataaddr;
@ -232,7 +232,7 @@ static void decode_dmi(char *text, unsigned address, unsigned data)
if (i > 0)
*(text++) = ' ';
if (mask & (mask >> 1)) {
// If the field is more than 1 bit wide.
/* If the field is more than 1 bit wide. */
sprintf(text, "%s=%d", description[i].name, value);
} else {
strcpy(text, description[i].name);
@ -245,8 +245,8 @@ static void decode_dmi(char *text, unsigned address, unsigned data)
static void dump_field(const struct scan_field *field)
{
static const char *op_string[] = {"-", "r", "w", "?"};
static const char *status_string[] = {"+", "?", "F", "b"};
static const char * const op_string[] = {"-", "r", "w", "?"};
static const char * const status_string[] = {"+", "?", "F", "b"};
if (debug_level < LOG_LVL_DEBUG)
return;
@ -371,9 +371,8 @@ static dmi_status_t dmi_scan(struct target *target, uint16_t *address_in,
if (exec)
idle_count += info->ac_busy_delay;
if (idle_count) {
if (idle_count)
jtag_add_runtest(idle_count, TAP_IDLE);
}
int retval = jtag_execute_queue();
if (retval != ERROR_OK) {
@ -381,13 +380,11 @@ static dmi_status_t dmi_scan(struct target *target, uint16_t *address_in,
return DMI_STATUS_FAILED;
}
if (data_in) {
if (data_in)
*data_in = buf_get_u64(in, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);
}
if (address_in) {
if (address_in)
*address_in = buf_get_u32(in, DTM_DMI_ADDRESS_OFFSET, info->abits);
}
dump_field(&field);
@ -403,9 +400,9 @@ static uint64_t dmi_read(struct target *target, uint16_t address)
unsigned i = 0;
// This first loop ensures that the read request was actually sent
// to the target. Note that if for some reason this stays busy,
// it is actually due to the previous dmi_read or dmi_write.
/* This first loop ensures that the read request was actually sent
* to the target. Note that if for some reason this stays busy,
* it is actually due to the previous dmi_read or dmi_write. */
for (i = 0; i < 256; i++) {
status = dmi_scan(target, NULL, NULL, DMI_OP_READ, address, 0,
false);
@ -424,9 +421,9 @@ static uint64_t dmi_read(struct target *target, uint16_t address)
abort();
}
// This second loop ensures that we got the read
// data back. Note that NOP can result in a 'busy' result as well, but
// that would be noticed on the next DMI access we do.
/* This second loop ensures that we got the read
* data back. Note that NOP can result in a 'busy' result as well, but
* that would be noticed on the next DMI access we do. */
uint64_t value;
for (i = 0; i < 256; i++) {
status = dmi_scan(target, &address_in, &value, DMI_OP_NOP, address, 0,
@ -456,7 +453,7 @@ static void dmi_write(struct target *target, uint16_t address, uint64_t value)
dmi_status_t status = DMI_STATUS_BUSY;
unsigned i = 0;
// The first loop ensures that we successfully sent the write request.
/* The first loop ensures that we successfully sent the write request. */
for (i = 0; i < 256; i++) {
status = dmi_scan(target, NULL, NULL, DMI_OP_WRITE, address, value,
address == DMI_COMMAND);
@ -476,8 +473,9 @@ static void dmi_write(struct target *target, uint16_t address, uint64_t value)
abort();
}
// The second loop isn't strictly necessary, but would ensure that
// the write is complete/ has no non-busy errors before returning from this function.
/* The second loop isn't strictly necessary, but would ensure that the
* write is complete/ has no non-busy errors before returning from this
* function. */
for (i = 0; i < 256; i++) {
status = dmi_scan(target, NULL, NULL, DMI_OP_NOP, address, 0,
false);
@ -529,9 +527,8 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
while (1) {
*abstractcs = dmi_read(target, DMI_ABSTRACTCS);
if (get_field(*abstractcs, DMI_ABSTRACTCS_BUSY) == 0) {
if (get_field(*abstractcs, DMI_ABSTRACTCS_BUSY) == 0)
return ERROR_OK;
}
if (time(NULL) - start > riscv_command_timeout_sec) {
info->cmderr = get_field(*abstractcs, DMI_ABSTRACTCS_CMDERR);
@ -551,9 +548,9 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
}
LOG_ERROR("Timed out after %ds waiting for busy to go low (abstractcs=0x%x). "
"Increase the timeout with riscv set_command_timeout_sec.",
riscv_command_timeout_sec,
*abstractcs);
"Increase the timeout with riscv set_command_timeout_sec.",
riscv_command_timeout_sec,
*abstractcs);
return ERROR_FAIL;
}
}
@ -574,7 +571,7 @@ static int execute_abstract_command(struct target *target, uint32_t command)
info->cmderr = get_field(cs, DMI_ABSTRACTCS_CMDERR);
if (info->cmderr != 0) {
LOG_DEBUG("command 0x%x failed; abstractcs=0x%x", command, cs);
// Clear the error.
/* Clear the error. */
dmi_write(target, DMI_ABSTRACTCS, set_field(0, DMI_ABSTRACTCS_CMDERR,
info->cmderr));
return ERROR_FAIL;
@ -704,9 +701,8 @@ static int register_write_abstract(struct target *target, uint32_t number,
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);
if (write_abstract_arg(target, 0, value) != ERROR_OK) {
if (write_abstract_arg(target, 0, value) != ERROR_OK)
return ERROR_FAIL;
}
int result = execute_abstract_command(target, command);
if (result != ERROR_OK) {
@ -732,7 +728,7 @@ static int examine_progbuf(struct target *target)
if (info->progbuf_writable != YNM_MAYBE)
return ERROR_OK;
// Figure out if progbuf is writable.
/* Figure out if progbuf is writable. */
if (info->progbufsize < 1) {
info->progbuf_writable = YNM_NO;
@ -761,8 +757,8 @@ static int examine_progbuf(struct target *target)
return ERROR_FAIL;
if (result != ERROR_OK) {
// This program might have failed if the program buffer is not
// writable.
/* This program might have failed if the program buffer is not
* writable. */
info->progbuf_writable = YNM_NO;
return ERROR_OK;
}
@ -789,11 +785,11 @@ typedef enum {
} memory_space_t;
typedef struct {
// How can the debugger access this memory?
/* How can the debugger access this memory? */
memory_space_t memory_space;
// Memory address to access the scratch memory from the hart.
/* Memory address to access the scratch memory from the hart. */
riscv_addr_t hart_address;
// Memory address to access the scratch memory from the debugger.
/* Memory address to access the scratch memory from the debugger. */
riscv_addr_t debug_address;
} scratch_mem_t;
@ -812,12 +808,11 @@ static int scratch_find(struct target *target,
alignment *= 2;
if (info->dataaccess == 1) {
// Sign extend dataaddr.
/* Sign extend dataaddr. */
scratch->hart_address = info->dataaddr;
if (info->dataaddr & (1<<11)) {
if (info->dataaddr & (1<<11))
scratch->hart_address |= 0xfffffffffffff000ULL;
}
// Align.
/* Align. */
scratch->hart_address = (scratch->hart_address + alignment - 1) & ~(alignment - 1);
if ((size_bytes + scratch->hart_address - info->dataaddr + 3) / 4 >=
@ -831,8 +826,8 @@ static int scratch_find(struct target *target,
if (examine_progbuf(target) != ERROR_OK)
return ERROR_FAIL;
// Allow for ebreak at the end of the program.
unsigned program_size = (program->instruction_count + 1 ) * 4;
/* Allow for ebreak at the end of the program. */
unsigned program_size = (program->instruction_count + 1) * 4;
scratch->hart_address = (info->progbuf_address + program_size + alignment - 1) &
~(alignment - 1);
if ((size_bytes + scratch->hart_address - info->progbuf_address + 3) / 4 >=
@ -961,11 +956,10 @@ static int register_write_direct(struct target *target, unsigned number,
return ERROR_FAIL;
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
if (riscv_supports_extension(target, 'D')) {
if (riscv_supports_extension(target, 'D'))
riscv_program_insert(&program, fmv_d_x(number - GDB_REGNO_FPR0, S0));
} else {
else
riscv_program_insert(&program, fmv_w_x(number - GDB_REGNO_FPR0, S0));
}
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
riscv_program_csrw(&program, S0, number);
} else {
@ -976,7 +970,7 @@ static int register_write_direct(struct target *target, unsigned number,
int exec_out = riscv_program_exec(&program, target);
// Restore S0.
/* Restore S0. */
if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)
return ERROR_FAIL;
@ -1004,10 +998,10 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
if (register_read_direct(target, &s0, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL;
// Write program to move data into s0.
/* Write program to move data into s0. */
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
// TODO: Possibly set F in mstatus.
/* TODO: Possibly set F in mstatus. */
if (riscv_supports_extension(target, 'D') && riscv_xlen(target) < 64) {
/* There are no instructions to move all the bits from a
* register, so we need to use some scratch RAM. */
@ -1033,19 +1027,19 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
abort();
}
// Execute program.
/* Execute program. */
result = riscv_program_exec(&program, target);
if (use_scratch) {
if (scratch_read64(target, &scratch, value) != ERROR_OK)
return ERROR_FAIL;
} else {
// Read S0
/* Read S0 */
if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL;
}
// Restore S0.
/* Restore S0. */
if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)
return ERROR_FAIL;
}
@ -1094,11 +1088,11 @@ static int init_target(struct command_context *cmd_ctx,
info->dmi_busy_delay = 0;
info->ac_busy_delay = 0;
// Assume all these abstract commands are supported until we learn
// otherwise.
// TODO: The spec allows eg. one CSR to be able to be accessed abstractly
// while another one isn't. We don't track that this closely here, but in
// the future we probably should.
/* Assume all these abstract commands are supported until we learn
* otherwise.
* TODO: The spec allows eg. one CSR to be able to be accessed abstractly
* while another one isn't. We don't track that this closely here, but in
* the future we probably should. */
info->abstract_read_csr_supported = true;
info->abstract_write_csr_supported = true;
info->abstract_read_fpr_supported = true;
@ -1117,7 +1111,7 @@ static void deinit_target(struct target *target)
static int examine(struct target *target)
{
// Don't need to select dbus, since the first thing we do is read dtmcontrol.
/* Don't need to select dbus, since the first thing we do is read dtmcontrol. */
uint32_t dtmcontrol = dtmcontrol_scan(target, 0);
LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol);
@ -1147,7 +1141,7 @@ static int examine(struct target *target)
return ERROR_FAIL;
}
// Reset the Debug Module.
/* Reset the Debug Module. */
dmi_write(target, DMI_DMCONTROL, 0);
dmi_write(target, DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE);
uint32_t dmcontrol = dmi_read(target, DMI_DMCONTROL);
@ -1184,7 +1178,7 @@ static int examine(struct target *target)
return ERROR_FAIL;
}
// Check that abstract data registers are accessible.
/* Check that abstract data registers are accessible. */
uint32_t abstractcs = dmi_read(target, DMI_ABSTRACTCS);
info->datacount = get_field(abstractcs, DMI_ABSTRACTCS_DATACOUNT);
info->progbufsize = get_field(abstractcs, DMI_ABSTRACTCS_PROGBUFSIZE);
@ -1193,8 +1187,8 @@ static int examine(struct target *target)
RISCV_INFO(r);
r->impebreak = get_field(dmstatus, DMI_DMSTATUS_IMPEBREAK);
// Don't call any riscv_* functions until after we've counted the number of
// cores and initialized registers.
/* Don't call any riscv_* functions until after we've counted the number of
* cores and initialized registers. */
for (int i = 0; i < RISCV_MAX_HARTS; ++i) {
if (!riscv_rtos_enabled(target) && i != target->coreid)
continue;
@ -1203,29 +1197,26 @@ static int examine(struct target *target)
riscv013_select_current_hart(target);
uint32_t s = dmi_read(target, DMI_DMSTATUS);
if (get_field(s, DMI_DMSTATUS_ANYNONEXISTENT)) {
if (get_field(s, DMI_DMSTATUS_ANYNONEXISTENT))
break;
}
r->hart_count = i + 1;
if (!riscv_is_halted(target)) {
if (!riscv_is_halted(target))
riscv013_halt_current_hart(target);
}
/* Without knowing anything else we can at least mess with the
* program buffer. */
r->debug_buffer_size[i] = info->progbufsize;
int result = register_read_abstract(target, NULL, GDB_REGNO_S0, 64);
if (result == ERROR_OK) {
if (result == ERROR_OK)
r->xlen[i] = 64;
} else {
else
r->xlen[i] = 32;
}
register_read_direct(target, &r->misa, GDB_REGNO_MISA);
// Now init registers based on what we discovered.
/* Now init registers based on what we discovered. */
if (riscv_init_registers(target) != ERROR_OK)
return ERROR_FAIL;
@ -1241,19 +1232,18 @@ static int examine(struct target *target)
riscv_enumerate_triggers(target);
/* Resumes all the harts, so the debugger can later pause them. */
// TODO: Only do this if the harts were halted to start with.
/* TODO: Only do this if the harts were halted to start with. */
riscv_resume_all_harts(target);
target->state = TARGET_RUNNING;
target_set_examined(target);
if (target->rtos) {
if (target->rtos)
riscv_update_threads(target->rtos);
}
// Some regression suites rely on seeing 'Examined RISC-V core' to know
// when they can connect with gdb/telnet.
// We will need to update those suites if we want to change that text.
/* Some regression suites rely on seeing 'Examined RISC-V core' to know
* when they can connect with gdb/telnet.
* We will need to update those suites if we want to change that text. */
LOG_INFO("Examined RISC-V core; found %d harts",
riscv_count_harts(target));
for (int i = 0; i < riscv_count_harts(target); ++i) {
@ -1276,12 +1266,12 @@ static int assert_reset(struct target *target)
uint32_t control_base = set_field(0, DMI_DMCONTROL_DMACTIVE, 1);
if (target->rtos) {
// There's only one target, and OpenOCD thinks each hart is a thread.
// We must reset them all.
/* There's only one target, and OpenOCD thinks each hart is a thread.
* We must reset them all. */
// TODO: Try to use hasel in dmcontrol
/* TODO: Try to use hasel in dmcontrol */
// Set haltreq/resumereq for each hart.
/* Set haltreq/resumereq for each hart. */
uint32_t control = control_base;
for (int i = 0; i < riscv_count_harts(target); ++i) {
if (!riscv_hart_enabled(target, i))
@ -1292,12 +1282,12 @@ static int assert_reset(struct target *target)
target->reset_halt ? 1 : 0);
dmi_write(target, DMI_DMCONTROL, control);
}
// Assert ndmreset
/* Assert ndmreset */
control = set_field(control, DMI_DMCONTROL_NDMRESET, 1);
dmi_write(target, DMI_DMCONTROL, control);
} else {
// Reset just this hart.
/* Reset just this hart. */
uint32_t control = set_field(control_base, DMI_DMCONTROL_HARTSEL,
r->current_hartid);
control = set_field(control, DMI_DMCONTROL_HALTREQ,
@ -1305,11 +1295,11 @@ static int assert_reset(struct target *target)
control = set_field(control, DMI_DMCONTROL_HARTRESET, 1);
dmi_write(target, DMI_DMCONTROL, control);
// Read back to check if hartreset is supported.
/* Read back to check if hartreset is supported. */
uint32_t rb = dmi_read(target, DMI_DMCONTROL);
if (!get_field(rb, DMI_DMCONTROL_HARTRESET)) {
// Use ndmreset instead. That will reset the entire device, but
// that's probably what OpenOCD wants anyway.
/* Use ndmreset instead. That will reset the entire device, but
* that's probably what OpenOCD wants anyway. */
control = set_field(control, DMI_DMCONTROL_HARTRESET, 0);
control = set_field(control, DMI_DMCONTROL_NDMRESET, 1);
dmi_write(target, DMI_DMCONTROL, control);
@ -1329,7 +1319,7 @@ static int deassert_reset(struct target *target)
LOG_DEBUG("%d", r->current_hartid);
// Clear the reset, but make sure haltreq is still set
/* Clear the reset, but make sure haltreq is still set */
uint32_t control = 0;
control = set_field(control, DMI_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0);
control = set_field(control, DMI_DMCONTROL_HARTSEL, r->current_hartid);
@ -1405,7 +1395,8 @@ static void write_to_buf(uint8_t *buffer, uint64_t value, unsigned size)
}
}
static int execute_fence(struct target *target) {
static int execute_fence(struct target *target)
{
struct riscv_program program;
riscv_program_init(&program, target);
riscv_program_fence(&program);
@ -1441,7 +1432,7 @@ static int read_memory(struct target *target, target_addr_t address,
if (execute_fence(target) != ERROR_OK)
return ERROR_FAIL;
// Write the program (load, increment)
/* Write the program (load, increment) */
struct riscv_program program;
riscv_program_init(&program, target);
switch (size) {
@ -1464,7 +1455,7 @@ static int read_memory(struct target *target, target_addr_t address,
return ERROR_FAIL;
riscv_program_write(&program);
// Write address to S0, and execute buffer.
/* Write address to S0, and execute buffer. */
if (register_write_direct(target, GDB_REGNO_S0, address) != ERROR_OK)
return ERROR_FAIL;
uint32_t command = access_register_command(GDB_REGNO_S1, riscv_xlen(target),
@ -1473,27 +1464,27 @@ static int read_memory(struct target *target, target_addr_t address,
if (execute_abstract_command(target, command) != ERROR_OK)
return ERROR_FAIL;
// First read has just triggered. Result is in s1.
/* First read has just triggered. Result is in s1. */
dmi_write(target, DMI_ABSTRACTAUTO,
1 << DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET);
// read_addr is the next address that the hart will read from, which is the
// value in s0.
/* read_addr is the next address that the hart will read from, which is the
* value in s0. */
riscv_addr_t read_addr = address + size;
// The next address that we need to receive data for.
/* The next address that we need to receive data for. */
riscv_addr_t receive_addr = address;
riscv_addr_t fin_addr = address + (count * size);
unsigned skip = 1;
while (read_addr < fin_addr) {
LOG_DEBUG("read_addr=0x%" PRIx64 ", receive_addr=0x%" PRIx64
", fin_addr=0x%" PRIx64, read_addr, receive_addr, fin_addr);
// The pipeline looks like this:
// memory -> s1 -> dm_data0 -> debugger
// It advances every time the debugger reads dmdata0.
// So at any time the debugger has just read mem[s0 - 3*size],
// dm_data0 contains mem[s0 - 2*size]
// s1 contains mem[s0-size]
/* The pipeline looks like this:
* memory -> s1 -> dm_data0 -> debugger
* It advances every time the debugger reads dmdata0.
* So at any time the debugger has just read mem[s0 - 3*size],
* dm_data0 contains mem[s0 - 2*size]
* s1 contains mem[s0-size] */
LOG_DEBUG("creating burst to read from 0x%" TARGET_PRIxADDR
" up to 0x%" TARGET_PRIxADDR, read_addr, fin_addr);
@ -1512,8 +1503,8 @@ static int read_memory(struct target *target, target_addr_t address,
riscv_batch_run(batch);
// Wait for the target to finish performing the last abstract command,
// and update our copy of cmderr.
/* Wait for the target to finish performing the last abstract command,
* and update our copy of cmderr. */
uint32_t abstractcs = dmi_read(target, DMI_ABSTRACTCS);
while (get_field(abstractcs, DMI_ABSTRACTCS_BUSY))
abstractcs = dmi_read(target, DMI_ABSTRACTCS);
@ -1538,7 +1529,7 @@ static int read_memory(struct target *target, target_addr_t address,
+#include <unistd.h>
+
#include <cassert>
#include "debug_module.h"
@@ -398,6 +400,15 @@ bool debug_module_t::perform_abstract_command()
// Since the next instruction is what we will use, just use nother NOP
@ -1562,17 +1553,17 @@ static int read_memory(struct target *target, target_addr_t address,
dmi_write(target, DMI_ABSTRACTAUTO, 0);
// This is definitely a good version of the value that we
// attempted to read when we discovered that the target was
// busy.
/* This is definitely a good version of the value that we
* attempted to read when we discovered that the target was
* busy. */
dmi_data0 = dmi_read(target, DMI_DATA0);
// Clobbers DMI_DATA0.
/* Clobbers DMI_DATA0. */
if (register_read_direct(target, &next_read_addr, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL;
// Restore the command, and execute it.
// Now DMI_DATA0 contains the next value just as it would if no
// error had occurred.
/* Restore the command, and execute it.
* Now DMI_DATA0 contains the next value just as it would if no
* error had occurred. */
dmi_write(target, DMI_COMMAND, command);
dmi_write(target, DMI_ABSTRACTAUTO,
@ -1588,11 +1579,10 @@ static int read_memory(struct target *target, target_addr_t address,
return ERROR_FAIL;
}
// Now read whatever we got out of the batch.
/* Now read whatever we got out of the batch. */
for (size_t i = 0; i < reads; i++) {
if (read_addr >= next_read_addr) {
if (read_addr >= next_read_addr)
break;
}
read_addr += size;
@ -1625,14 +1615,14 @@ static int read_memory(struct target *target, target_addr_t address,
dmi_write(target, DMI_ABSTRACTAUTO, 0);
if (count > 1) {
// Read the penultimate word.
/* Read the penultimate word. */
uint64_t value = dmi_read(target, DMI_DATA0);
write_to_buf(buffer + receive_addr - address, value, size);
LOG_DEBUG("M[0x%" TARGET_PRIxADDR "] reads 0x%" PRIx64, receive_addr, value);
receive_addr += size;
}
// Read the last word.
/* Read the last word. */
uint64_t value;
if (register_read_direct(target, &value, GDB_REGNO_S1) != ERROR_OK)
return ERROR_FAIL;
@ -1664,7 +1654,7 @@ static int write_memory(struct target *target, target_addr_t address,
if (register_read_direct(target, &s1, GDB_REGNO_S1) != ERROR_OK)
return ERROR_FAIL;
// Write the program (store, increment)
/* Write the program (store, increment) */
struct riscv_program program;
riscv_program_init(&program, target);
@ -1736,12 +1726,12 @@ static int write_memory(struct target *target, target_addr_t address,
address + offset) != ERROR_OK)
return ERROR_FAIL;
// Write value.
/* Write value. */
dmi_write(target, DMI_DATA0, value);
// Write and execute command that moves value into S1 and
// executes program buffer.
uint32_t command = access_register_command(GDB_REGNO_S1, 32,
/* Write and execute command that moves value into S1 and
* executes program buffer. */
uint32_t command = access_register_command(GDB_REGNO_S1, 32,
AC_ACCESS_REGISTER_POSTEXEC |
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);
@ -1749,7 +1739,7 @@ static int write_memory(struct target *target, target_addr_t address,
if (result != ERROR_OK)
return result;
// Turn on autoexec
/* Turn on autoexec */
dmi_write(target, DMI_ABSTRACTAUTO,
1 << DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET);
@ -1764,9 +1754,9 @@ static int write_memory(struct target *target, target_addr_t address,
riscv_batch_run(batch);
riscv_batch_free(batch);
// Note that if the scan resulted in a Busy DMI response, it
// is this read to abstractcs that will cause the dmi_busy_delay
// to be incremented if necessary.
/* Note that if the scan resulted in a Busy DMI response, it
* is this read to abstractcs that will cause the dmi_busy_delay
* to be incremented if necessary. */
uint32_t abstractcs = dmi_read(target, DMI_ABSTRACTCS);
while (get_field(abstractcs, DMI_ABSTRACTCS_BUSY))
@ -1815,8 +1805,7 @@ static int arch_state(struct target *target)
return ERROR_OK;
}
struct target_type riscv013_target =
{
struct target_type riscv013_target = {
.name = "riscv",
.init_target = init_target,
@ -2102,7 +2091,7 @@ static void riscv013_step_or_resume_current_hart(struct target *target, bool ste
void riscv013_clear_abstract_error(struct target *target)
{
// Wait for busy to go away.
/* Wait for busy to go away. */
time_t start = time(NULL);
uint32_t abstractcs = dmi_read(target, DMI_ABSTRACTCS);
while (get_field(abstractcs, DMI_ABSTRACTCS_BUSY)) {
@ -2117,6 +2106,6 @@ void riscv013_clear_abstract_error(struct target *target)
break;
}
}
// Clear the error status.
/* Clear the error status. */
dmi_write(target, DMI_ABSTRACTCS, abstractcs & DMI_ABSTRACTCS_CMDERR);
}

View File

@ -65,7 +65,7 @@
#define DIM(x) (sizeof(x)/sizeof(*x))
// Constants for legacy SiFive hardware breakpoints.
/* Constants for legacy SiFive hardware breakpoints. */
#define CSR_BPCONTROL_X (1<<0)
#define CSR_BPCONTROL_W (1<<1)
#define CSR_BPCONTROL_R (1<<2)
@ -185,8 +185,8 @@ int riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC;
/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;
bool riscv_use_scratch_ram = false;
uint64_t riscv_scratch_ram_address = 0;
bool riscv_use_scratch_ram;
uint64_t riscv_scratch_ram_address;
/* In addition to the ones in the standard spec, we'll also expose additional
* CSRs in this list.
@ -284,7 +284,7 @@ static void trigger_from_breakpoint(struct trigger *trigger,
trigger->read = false;
trigger->write = false;
trigger->execute = true;
// unique_id is unique across both breakpoints and watchpoints.
/* unique_id is unique across both breakpoints and watchpoints. */
trigger->unique_id = breakpoint->unique_id;
}
@ -304,7 +304,7 @@ static int maybe_add_trigger_t1(struct target *target, unsigned hartid,
const uint32_t bpcontrol_bpaction = 0xff << 11;
if (tdata1 & (bpcontrol_r | bpcontrol_w | bpcontrol_x)) {
// Trigger is already in use, presumably by user code.
/* Trigger is already in use, presumably by user code. */
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
@ -315,8 +315,8 @@ static int maybe_add_trigger_t1(struct target *target, unsigned hartid,
tdata1 = set_field(tdata1, bpcontrol_s, !!(r->misa & (1 << ('S' - 'A'))));
tdata1 = set_field(tdata1, bpcontrol_h, !!(r->misa & (1 << ('H' - 'A'))));
tdata1 |= bpcontrol_m;
tdata1 = set_field(tdata1, bpcontrol_bpmatch, 0); // exact match
tdata1 = set_field(tdata1, bpcontrol_bpaction, 0); // cause bp exception
tdata1 = set_field(tdata1, bpcontrol_bpmatch, 0); /* exact match */
tdata1 = set_field(tdata1, bpcontrol_bpaction, 0); /* cause bp exception */
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TDATA1, tdata1);
@ -342,13 +342,13 @@ static int maybe_add_trigger_t2(struct target *target, unsigned hartid,
{
RISCV_INFO(r);
// tselect is already set
/* tselect is already set */
if (tdata1 & (MCONTROL_EXECUTE | MCONTROL_STORE | MCONTROL_LOAD)) {
// Trigger is already in use, presumably by user code.
/* Trigger is already in use, presumably by user code. */
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
// address/data match trigger
/* address/data match trigger */
tdata1 |= MCONTROL_DMODE(riscv_xlen(target));
tdata1 = set_field(tdata1, MCONTROL_ACTION,
MCONTROL_ACTION_DEBUG_MODE);
@ -390,12 +390,12 @@ static int add_trigger(struct target *target, struct trigger *trigger)
{
RISCV_INFO(r);
// In RTOS mode, we need to set the same trigger in the same slot on every
// hart, to keep up the illusion that each hart is a thread running on the
// same core.
/* In RTOS mode, we need to set the same trigger in the same slot on every
* hart, to keep up the illusion that each hart is a thread running on the
* same core. */
// Otherwise, we just set the trigger on the one hart this target deals
// with.
/* Otherwise, we just set the trigger on the one hart this target deals
* with. */
riscv_reg_t tselect[RISCV_MAX_HARTS];
@ -412,9 +412,8 @@ static int add_trigger(struct target *target, struct trigger *trigger)
unsigned int i;
for (i = 0; i < r->trigger_count[first_hart]; i++) {
if (r->trigger_unique_id[i] != -1) {
if (r->trigger_unique_id[i] != -1)
continue;
}
riscv_set_register_on_hart(target, first_hart, GDB_REGNO_TSELECT, i);
@ -425,9 +424,8 @@ static int add_trigger(struct target *target, struct trigger *trigger)
for (int hartid = first_hart; hartid < riscv_count_harts(target); ++hartid) {
if (!riscv_hart_enabled(target, hartid))
continue;
if (hartid > first_hart) {
if (hartid > first_hart)
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TSELECT, i);
}
switch (type) {
case 1:
result = maybe_add_trigger_t1(target, hartid, trigger, tdata1);
@ -440,14 +438,12 @@ static int add_trigger(struct target *target, struct trigger *trigger)
continue;
}
if (result != ERROR_OK) {
if (result != ERROR_OK)
continue;
}
}
if (result != ERROR_OK) {
if (result != ERROR_OK)
continue;
}
LOG_DEBUG("Using trigger %d (type %d) for bp %d", i, type,
trigger->unique_id);
@ -481,11 +477,10 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
}
int retval;
if (breakpoint->length == 4) {
if (breakpoint->length == 4)
retval = target_write_u32(target, breakpoint->address, ebreak());
} else {
else
retval = target_write_u16(target, breakpoint->address, ebreak_c());
}
if (retval != ERROR_OK) {
LOG_ERROR("Failed to write %d-byte breakpoint instruction at 0x%"
TARGET_PRIxADDR, breakpoint->length, breakpoint->address);
@ -496,9 +491,8 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
struct trigger trigger;
trigger_from_breakpoint(&trigger, breakpoint);
int result = add_trigger(target, &trigger);
if (result != ERROR_OK) {
if (result != ERROR_OK)
return result;
}
} else {
LOG_INFO("OpenOCD only supports hardware and software breakpoints.");
@ -527,9 +521,8 @@ static int remove_trigger(struct target *target, struct trigger *trigger)
unsigned int i;
for (i = 0; i < r->trigger_count[first_hart]; i++) {
if (r->trigger_unique_id[i] == trigger->unique_id) {
if (r->trigger_unique_id[i] == trigger->unique_id)
break;
}
}
if (i >= r->trigger_count[first_hart]) {
LOG_ERROR("Couldn't find the hardware resources used by hardware "
@ -565,9 +558,8 @@ int riscv_remove_breakpoint(struct target *target,
struct trigger trigger;
trigger_from_breakpoint(&trigger, breakpoint);
int result = remove_trigger(target, &trigger);
if (result != ERROR_OK) {
if (result != ERROR_OK)
return result;
}
} else {
LOG_INFO("OpenOCD only supports hardware and software breakpoints.");
@ -589,7 +581,7 @@ static void trigger_from_watchpoint(struct trigger *trigger,
trigger->read = (watchpoint->rw == WPT_READ || watchpoint->rw == WPT_ACCESS);
trigger->write = (watchpoint->rw == WPT_WRITE || watchpoint->rw == WPT_ACCESS);
trigger->execute = false;
// unique_id is unique across both breakpoints and watchpoints.
/* unique_id is unique across both breakpoints and watchpoints. */
trigger->unique_id = watchpoint->unique_id;
}
@ -599,9 +591,8 @@ int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
trigger_from_watchpoint(&trigger, watchpoint);
int result = add_trigger(target, &trigger);
if (result != ERROR_OK) {
if (result != ERROR_OK)
return result;
}
watchpoint->set = true;
return ERROR_OK;
@ -614,9 +605,8 @@ int riscv_remove_watchpoint(struct target *target,
trigger_from_watchpoint(&trigger, watchpoint);
int result = remove_trigger(target, &trigger);
if (result != ERROR_OK) {
if (result != ERROR_OK)
return result;
}
watchpoint->set = false;
return ERROR_OK;
@ -651,7 +641,7 @@ static int riscv_examine(struct target *target)
return ERROR_OK;
}
// Don't need to select dbus, since the first thing we do is read dtmcontrol.
/* Don't need to select dbus, since the first thing we do is read dtmcontrol. */
riscv_info_t *info = (riscv_info_t *) target->arch_info;
uint32_t dtmcontrol = dtmcontrol_scan(target, 0);
@ -775,9 +765,8 @@ static int riscv_get_gdb_reg_list(struct target *target,
}
*reg_list = calloc(*reg_list_size, sizeof(struct reg *));
if (!*reg_list) {
if (!*reg_list)
return ERROR_FAIL;
}
for (int i = 0; i < *reg_list_size; i++) {
assert(!target->reg_cache->reg_list[i].valid ||
@ -794,7 +783,7 @@ static int riscv_arch_state(struct target *target)
return tt->arch_state(target);
}
// Algorithm must end with a software breakpoint instruction.
/* Algorithm must end with a software breakpoint instruction. */
static int riscv_run_algorithm(struct target *target, int num_mem_params,
struct mem_param *mem_params, int num_reg_params,
struct reg_param *reg_params, target_addr_t entry_point,
@ -812,11 +801,10 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
return ERROR_TARGET_NOT_HALTED;
}
/// Save registers
/* Save registers */
struct reg *reg_pc = register_get_by_name(target->reg_cache, "pc", 1);
if (!reg_pc || reg_pc->type->get(reg_pc) != ERROR_OK) {
if (!reg_pc || reg_pc->type->get(reg_pc) != ERROR_OK)
return ERROR_FAIL;
}
uint64_t saved_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size);
uint64_t saved_regs[32];
@ -839,17 +827,15 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
return ERROR_FAIL;
}
if (r->type->get(r) != ERROR_OK) {
if (r->type->get(r) != ERROR_OK)
return ERROR_FAIL;
}
saved_regs[r->number] = buf_get_u64(r->value, 0, r->size);
if (r->type->set(r, reg_params[i].value) != ERROR_OK) {
if (r->type->set(r, reg_params[i].value) != ERROR_OK)
return ERROR_FAIL;
}
}
// Disable Interrupts before attempting to run the algorithm.
/* Disable Interrupts before attempting to run the algorithm. */
uint64_t current_mstatus;
uint8_t mstatus_bytes[8];
@ -869,11 +855,10 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
reg_mstatus->type->set(reg_mstatus, mstatus_bytes);
/// Run algorithm
/* Run algorithm */
LOG_DEBUG("resume at 0x%" TARGET_PRIxADDR, entry_point);
if (oldriscv_resume(target, 0, entry_point, 0, 0) != ERROR_OK) {
if (oldriscv_resume(target, 0, entry_point, 0, 0) != ERROR_OK)
return ERROR_FAIL;
}
int64_t start = timeval_ms();
while (target->state != TARGET_HALTED) {
@ -889,14 +874,12 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
}
int result = old_or_new_riscv_poll(target);
if (result != ERROR_OK) {
if (result != ERROR_OK)
return result;
}
}
if (reg_pc->type->get(reg_pc) != ERROR_OK) {
if (reg_pc->type->get(reg_pc) != ERROR_OK)
return ERROR_FAIL;
}
uint64_t final_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size);
if (final_pc != exit_point) {
LOG_ERROR("PC ended up at 0x%" PRIx64 " instead of 0x%"
@ -904,37 +887,35 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
return ERROR_FAIL;
}
// Restore Interrupts
/* Restore Interrupts */
LOG_DEBUG("Restoring Interrupts");
buf_set_u64(mstatus_bytes, 0, info->xlen[0], current_mstatus);
reg_mstatus->type->set(reg_mstatus, mstatus_bytes);
/// Restore registers
/* Restore registers */
uint8_t buf[8];
buf_set_u64(buf, 0, info->xlen[0], saved_pc);
if (reg_pc->type->set(reg_pc, buf) != ERROR_OK) {
if (reg_pc->type->set(reg_pc, buf) != ERROR_OK)
return ERROR_FAIL;
}
for (int i = 0; i < num_reg_params; i++) {
LOG_DEBUG("restore %s", reg_params[i].reg_name);
struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, 0);
buf_set_u64(buf, 0, info->xlen[0], saved_regs[r->number]);
if (r->type->set(r, buf) != ERROR_OK) {
if (r->type->set(r, buf) != ERROR_OK)
return ERROR_FAIL;
}
}
return ERROR_OK;
}
/* Should run code on the target to perform CRC of
/* Should run code on the target to perform CRC of
memory. Not yet implemented.
*/
static int riscv_checksum_memory(struct target *target,
target_addr_t address, uint32_t count,
uint32_t* checksum)
uint32_t *checksum)
{
*checksum = 0xFFFFFFFF;
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
@ -945,10 +926,10 @@ block holds all-ones (because this is generally called on
NOR flash which is 1 when "blank")
Not yet implemented.
*/
int riscv_blank_check_memory(struct target * target,
int riscv_blank_check_memory(struct target *target,
target_addr_t address,
uint32_t count,
uint32_t * blank,
uint32_t *blank,
uint8_t erased_value)
{
*blank = 0;
@ -1031,7 +1012,7 @@ int riscv_openocd_poll(struct target *target)
target->debug_reason = DBG_REASON_SINGLESTEP;
break;
}
if (riscv_rtos_enabled(target)) {
target->rtos->current_threadid = triggered_hart + 1;
target->rtos->current_thread = triggered_hart + 1;
@ -1075,9 +1056,8 @@ int riscv_openocd_resume(
) {
LOG_DEBUG("resuming all harts");
if (!current) {
if (!current)
riscv_set_register(target, GDB_REGNO_PC, address);
}
int out = riscv_resume_all_harts(target);
if (out != ERROR_OK) {
@ -1099,9 +1079,8 @@ int riscv_openocd_step(
) {
LOG_DEBUG("stepping rtos hart");
if (!current) {
if (!current)
riscv_set_register(target, GDB_REGNO_PC, address);
}
int out = riscv_step_rtos_hart(target);
if (out != ERROR_OK) {
@ -1126,7 +1105,7 @@ COMMAND_HANDLER(riscv_set_command_timeout_sec)
return ERROR_COMMAND_SYNTAX_ERROR;
}
int timeout = atoi(CMD_ARGV[0]);
if (timeout <= 0){
if (timeout <= 0) {
LOG_ERROR("%s is not a valid integer argument for command.", CMD_ARGV[0]);
return ERROR_FAIL;
}
@ -1143,7 +1122,7 @@ COMMAND_HANDLER(riscv_set_reset_timeout_sec)
return ERROR_COMMAND_SYNTAX_ERROR;
}
int timeout = atoi(CMD_ARGV[0]);
if (timeout <= 0){
if (timeout <= 0) {
LOG_ERROR("%s is not a valid integer argument for command.", CMD_ARGV[0]);
return ERROR_FAIL;
}
@ -1204,7 +1183,7 @@ COMMAND_HANDLER(riscv_set_expose_csrs)
for (unsigned i = 0; i == 0 || CMD_ARGV[0][i-1]; i++) {
char c = CMD_ARGV[0][i];
if (isspace(c)) {
// Ignore whitespace.
/* Ignore whitespace. */
continue;
}
@ -1303,8 +1282,7 @@ const struct command_registration riscv_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
struct target_type riscv_target =
{
struct target_type riscv_target = {
.name = "riscv",
.init_target = riscv_init_target,
@ -1443,13 +1421,12 @@ bool riscv_supports_extension(struct target *target, char letter)
{
RISCV_INFO(r);
unsigned num;
if (letter >= 'a' && letter <= 'z') {
if (letter >= 'a' && letter <= 'z')
num = letter - 'a';
} else if (letter >= 'A' && letter <= 'Z') {
else if (letter >= 'A' && letter <= 'Z')
num = letter - 'A';
} else {
else
return false;
}
return r->misa & (1 << num);
}
@ -1533,9 +1510,11 @@ void riscv_set_rtos_hartid(struct target *target, int hartid)
int riscv_count_harts(struct target *target)
{
if (target == NULL) return 1;
if (target == NULL)
return 1;
RISCV_INFO(r);
if (r == NULL) return 1;
if (r == NULL)
return 1;
return r->hart_count;
}
@ -1546,7 +1525,7 @@ bool riscv_has_register(struct target *target, int hartid, int regid)
void riscv_set_register(struct target *target, enum gdb_regno r, riscv_reg_t v)
{
// TODO: propagate errors
/* TODO: propagate errors */
return riscv_set_register_on_hart(target, riscv_current_hartid(target), r, v);
}
@ -1697,8 +1676,8 @@ int riscv_enumerate_triggers(struct target *target)
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TSELECT, t);
uint64_t tselect_rb = riscv_get_register_on_hart(target, hartid,
GDB_REGNO_TSELECT);
// Mask off the top bit, which is used as tdrmode in old
// implementations.
/* Mask off the top bit, which is used as tdrmode in old
* implementations. */
tselect_rb &= ~(1ULL << (riscv_xlen(target)-1));
if (tselect_rb != t)
break;
@ -1707,14 +1686,13 @@ int riscv_enumerate_triggers(struct target *target)
int type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target)));
switch (type) {
case 1:
// On these older cores we don't support software using
// triggers.
/* On these older cores we don't support software using
* triggers. */
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TDATA1, 0);
break;
case 2:
if (tdata1 & MCONTROL_DMODE(riscv_xlen(target))) {
if (tdata1 & MCONTROL_DMODE(riscv_xlen(target)))
riscv_set_register_on_hart(target, hartid, GDB_REGNO_TDATA1, 0);
}
break;
}
}
@ -1765,15 +1743,14 @@ const char *gdb_regno_name(enum gdb_regno regno)
case GDB_REGNO_PRIV:
return "priv";
default:
if (regno <= GDB_REGNO_XPR31) {
if (regno <= GDB_REGNO_XPR31)
sprintf(buf, "x%d", regno - GDB_REGNO_ZERO);
} else if (regno >= GDB_REGNO_CSR0 && regno <= GDB_REGNO_CSR4095) {
else if (regno >= GDB_REGNO_CSR0 && regno <= GDB_REGNO_CSR4095)
sprintf(buf, "csr%d", regno - GDB_REGNO_CSR0);
} else if (regno >= GDB_REGNO_FPR0 && regno <= GDB_REGNO_FPR31) {
else if (regno >= GDB_REGNO_FPR0 && regno <= GDB_REGNO_FPR31)
sprintf(buf, "f%d", regno - GDB_REGNO_FPR0);
} else {
else
sprintf(buf, "gdb_regno_%d", regno);
}
return buf;
}
}
@ -1864,15 +1841,15 @@ int riscv_init_registers(struct target *target)
#include "encoding.h"
#undef DECLARE_CSR
};
// encoding.h does not contain the registers in sorted order.
/* encoding.h does not contain the registers in sorted order. */
qsort(csr_info, DIM(csr_info), sizeof(*csr_info), cmp_csr_info);
unsigned csr_info_index = 0;
// When gdb request register N, gdb_get_register_packet() assumes that this
// is register at index N in reg_list. So if there are certain registers
// that don't exist, we need to leave holes in the list (or renumber, but
// it would be nice not to have yet another set of numbers to translate
// between).
/* When gdb request register N, gdb_get_register_packet() assumes that this
* is register at index N in reg_list. So if there are certain registers
* that don't exist, we need to leave holes in the list (or renumber, but
* it would be nice not to have yet another set of numbers to translate
* between). */
for (uint32_t number = 0; number < GDB_REGNO_COUNT; number++) {
struct reg *r = &target->reg_cache->reg_list[number];
r->caller_save = true;
@ -1883,43 +1860,107 @@ int riscv_init_registers(struct target *target)
r->arch_info = target;
r->number = number;
r->size = riscv_xlen(target);
// r->size is set in riscv_invalidate_register_cache, maybe because the
// target is in theory allowed to change XLEN on us. But I expect a lot
// of other things to break in that case as well.
/* r->size is set in riscv_invalidate_register_cache, maybe because the
* target is in theory allowed to change XLEN on us. But I expect a lot
* of other things to break in that case as well. */
if (number <= GDB_REGNO_XPR31) {
switch (number) {
case GDB_REGNO_ZERO: r->name = "zero"; break;
case GDB_REGNO_RA: r->name = "ra"; break;
case GDB_REGNO_SP: r->name = "sp"; break;
case GDB_REGNO_GP: r->name = "gp"; break;
case GDB_REGNO_TP: r->name = "tp"; break;
case GDB_REGNO_T0: r->name = "t0"; break;
case GDB_REGNO_T1: r->name = "t1"; break;
case GDB_REGNO_T2: r->name = "t2"; break;
case GDB_REGNO_FP: r->name = "fp"; break;
case GDB_REGNO_S1: r->name = "s1"; break;
case GDB_REGNO_A0: r->name = "a0"; break;
case GDB_REGNO_A1: r->name = "a1"; break;
case GDB_REGNO_A2: r->name = "a2"; break;
case GDB_REGNO_A3: r->name = "a3"; break;
case GDB_REGNO_A4: r->name = "a4"; break;
case GDB_REGNO_A5: r->name = "a5"; break;
case GDB_REGNO_A6: r->name = "a6"; break;
case GDB_REGNO_A7: r->name = "a7"; break;
case GDB_REGNO_S2: r->name = "s2"; break;
case GDB_REGNO_S3: r->name = "s3"; break;
case GDB_REGNO_S4: r->name = "s4"; break;
case GDB_REGNO_S5: r->name = "s5"; break;
case GDB_REGNO_S6: r->name = "s6"; break;
case GDB_REGNO_S7: r->name = "s7"; break;
case GDB_REGNO_S8: r->name = "s8"; break;
case GDB_REGNO_S9: r->name = "s9"; break;
case GDB_REGNO_S10: r->name = "s10"; break;
case GDB_REGNO_S11: r->name = "s11"; break;
case GDB_REGNO_T3: r->name = "t3"; break;
case GDB_REGNO_T4: r->name = "t4"; break;
case GDB_REGNO_T5: r->name = "t5"; break;
case GDB_REGNO_T6: r->name = "t6"; break;
case GDB_REGNO_ZERO:
r->name = "zero";
break;
case GDB_REGNO_RA:
r->name = "ra";
break;
case GDB_REGNO_SP:
r->name = "sp";
break;
case GDB_REGNO_GP:
r->name = "gp";
break;
case GDB_REGNO_TP:
r->name = "tp";
break;
case GDB_REGNO_T0:
r->name = "t0";
break;
case GDB_REGNO_T1:
r->name = "t1";
break;
case GDB_REGNO_T2:
r->name = "t2";
break;
case GDB_REGNO_FP:
r->name = "fp";
break;
case GDB_REGNO_S1:
r->name = "s1";
break;
case GDB_REGNO_A0:
r->name = "a0";
break;
case GDB_REGNO_A1:
r->name = "a1";
break;
case GDB_REGNO_A2:
r->name = "a2";
break;
case GDB_REGNO_A3:
r->name = "a3";
break;
case GDB_REGNO_A4:
r->name = "a4";
break;
case GDB_REGNO_A5:
r->name = "a5";
break;
case GDB_REGNO_A6:
r->name = "a6";
break;
case GDB_REGNO_A7:
r->name = "a7";
break;
case GDB_REGNO_S2:
r->name = "s2";
break;
case GDB_REGNO_S3:
r->name = "s3";
break;
case GDB_REGNO_S4:
r->name = "s4";
break;
case GDB_REGNO_S5:
r->name = "s5";
break;
case GDB_REGNO_S6:
r->name = "s6";
break;
case GDB_REGNO_S7:
r->name = "s7";
break;
case GDB_REGNO_S8:
r->name = "s8";
break;
case GDB_REGNO_S9:
r->name = "s9";
break;
case GDB_REGNO_S10:
r->name = "s10";
break;
case GDB_REGNO_S11:
r->name = "s11";
break;
case GDB_REGNO_T3:
r->name = "t3";
break;
case GDB_REGNO_T4:
r->name = "t4";
break;
case GDB_REGNO_T5:
r->name = "t5";
break;
case GDB_REGNO_T6:
r->name = "t6";
break;
}
r->group = "general";
r->feature = &feature_cpu;
@ -1938,38 +1979,102 @@ int riscv_init_registers(struct target *target)
r->exist = false;
}
switch (number) {
case GDB_REGNO_FT0: r->name = "ft0"; break;
case GDB_REGNO_FT1: r->name = "ft1"; break;
case GDB_REGNO_FT2: r->name = "ft2"; break;
case GDB_REGNO_FT3: r->name = "ft3"; break;
case GDB_REGNO_FT4: r->name = "ft4"; break;
case GDB_REGNO_FT5: r->name = "ft5"; break;
case GDB_REGNO_FT6: r->name = "ft6"; break;
case GDB_REGNO_FT7: r->name = "ft7"; break;
case GDB_REGNO_FS0: r->name = "fs0"; break;
case GDB_REGNO_FS1: r->name = "fs1"; break;
case GDB_REGNO_FA0: r->name = "fa0"; break;
case GDB_REGNO_FA1: r->name = "fa1"; break;
case GDB_REGNO_FA2: r->name = "fa2"; break;
case GDB_REGNO_FA3: r->name = "fa3"; break;
case GDB_REGNO_FA4: r->name = "fa4"; break;
case GDB_REGNO_FA5: r->name = "fa5"; break;
case GDB_REGNO_FA6: r->name = "fa6"; break;
case GDB_REGNO_FA7: r->name = "fa7"; break;
case GDB_REGNO_FS2: r->name = "fs2"; break;
case GDB_REGNO_FS3: r->name = "fs3"; break;
case GDB_REGNO_FS4: r->name = "fs4"; break;
case GDB_REGNO_FS5: r->name = "fs5"; break;
case GDB_REGNO_FS6: r->name = "fs6"; break;
case GDB_REGNO_FS7: r->name = "fs7"; break;
case GDB_REGNO_FS8: r->name = "fs8"; break;
case GDB_REGNO_FS9: r->name = "fs9"; break;
case GDB_REGNO_FS10: r->name = "fs10"; break;
case GDB_REGNO_FS11: r->name = "fs11"; break;
case GDB_REGNO_FT8: r->name = "ft8"; break;
case GDB_REGNO_FT9: r->name = "ft9"; break;
case GDB_REGNO_FT10: r->name = "ft10"; break;
case GDB_REGNO_FT11: r->name = "ft11"; break;
case GDB_REGNO_FT0:
r->name = "ft0";
break;
case GDB_REGNO_FT1:
r->name = "ft1";
break;
case GDB_REGNO_FT2:
r->name = "ft2";
break;
case GDB_REGNO_FT3:
r->name = "ft3";
break;
case GDB_REGNO_FT4:
r->name = "ft4";
break;
case GDB_REGNO_FT5:
r->name = "ft5";
break;
case GDB_REGNO_FT6:
r->name = "ft6";
break;
case GDB_REGNO_FT7:
r->name = "ft7";
break;
case GDB_REGNO_FS0:
r->name = "fs0";
break;
case GDB_REGNO_FS1:
r->name = "fs1";
break;
case GDB_REGNO_FA0:
r->name = "fa0";
break;
case GDB_REGNO_FA1:
r->name = "fa1";
break;
case GDB_REGNO_FA2:
r->name = "fa2";
break;
case GDB_REGNO_FA3:
r->name = "fa3";
break;
case GDB_REGNO_FA4:
r->name = "fa4";
break;
case GDB_REGNO_FA5:
r->name = "fa5";
break;
case GDB_REGNO_FA6:
r->name = "fa6";
break;
case GDB_REGNO_FA7:
r->name = "fa7";
break;
case GDB_REGNO_FS2:
r->name = "fs2";
break;
case GDB_REGNO_FS3:
r->name = "fs3";
break;
case GDB_REGNO_FS4:
r->name = "fs4";
break;
case GDB_REGNO_FS5:
r->name = "fs5";
break;
case GDB_REGNO_FS6:
r->name = "fs6";
break;
case GDB_REGNO_FS7:
r->name = "fs7";
break;
case GDB_REGNO_FS8:
r->name = "fs8";
break;
case GDB_REGNO_FS9:
r->name = "fs9";
break;
case GDB_REGNO_FS10:
r->name = "fs10";
break;
case GDB_REGNO_FS11:
r->name = "fs11";
break;
case GDB_REGNO_FT8:
r->name = "ft8";
break;
case GDB_REGNO_FT9:
r->name = "ft9";
break;
case GDB_REGNO_FT10:
r->name = "ft10";
break;
case GDB_REGNO_FT11:
r->name = "ft11";
break;
}
r->group = "float";
r->feature = &feature_fpu;
@ -1986,11 +2091,11 @@ int riscv_init_registers(struct target *target)
r->name = csr_info[csr_info_index].name;
} else {
sprintf(reg_name, "csr%d", csr_number);
// Assume unnamed registers don't exist, unless we have some
// configuration that tells us otherwise. That's important
// because eg. Eclipse crashes if a target has too many
// registers, and apparently has no way of only showing a
// subset of registers in any case.
/* Assume unnamed registers don't exist, unless we have some
* configuration that tells us otherwise. That's important
* because eg. Eclipse crashes if a target has too many
* registers, and apparently has no way of only showing a
* subset of registers in any case. */
r->exist = false;
}
@ -2032,9 +2137,8 @@ int riscv_init_registers(struct target *target)
r->feature = &feature_virtual;
r->size = 8;
}
if (reg_name[0]) {
if (reg_name[0])
r->name = reg_name;
}
reg_name += strlen(reg_name) + 1;
assert(reg_name < info->reg_names + GDB_REGNO_COUNT * max_reg_name_len);
r->value = &info->reg_cache_values[number];

View File

@ -141,7 +141,7 @@ int riscv_openocd_resume(
struct target *target,
int current,
target_addr_t address,
int handle_breakpoints,
int handle_breakpoints,
int debug_execution
);

View File

@ -2830,8 +2830,8 @@ COMMAND_HANDLER(handle_reg_command)
retval = reg->type->set(reg, buf);
if (retval != ERROR_OK) {
LOG_DEBUG("Couldn't set register %s.", reg->name);
free (buf);
LOG_DEBUG("Couldn't set register %s.", reg->name);
free(buf);
return retval;
}