riscv: drop deprecated command 'riscv test_sba_config_reg'

Change-Id: I51c1b1cb3de8cb86ee38280fa3f035f6f7a63dbc
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7272
Reviewed-by: Jan Matyas <matyas@codasip.com>
Reviewed-by: Tim Newsome <tim@sifive.com>
Tested-by: jenkins
This commit is contained in:
Antonio Borneo 2022-10-17 12:34:23 +02:00
parent 27edeb7757
commit f2fc23e16b
3 changed files with 0 additions and 409 deletions

View File

@ -65,12 +65,6 @@ static int read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment);
static int write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
static int riscv013_test_sba_config_reg(struct target *target, target_addr_t legal_address,
uint32_t num_words, target_addr_t illegal_address, bool run_sbbusyerror_test);
static void write_memory_sba_simple(struct target *target, target_addr_t addr, uint32_t *write_data,
uint32_t write_size, uint32_t sbcs);
static void read_memory_sba_simple(struct target *target, target_addr_t addr,
uint32_t *rd_buf, uint32_t read_size, uint32_t sbcs);
/**
* Since almost everything can be accomplish by scanning the dbus register, all
@ -2307,7 +2301,6 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->dmi_read = &dmi_read;
generic_info->dmi_write = &dmi_write;
generic_info->read_memory = read_memory;
generic_info->test_sba_config_reg = &riscv013_test_sba_config_reg;
generic_info->hart_count = &riscv013_hart_count;
generic_info->data_bits = &riscv013_data_bits;
generic_info->print_info = &riscv013_print_info;
@ -4408,360 +4401,6 @@ void riscv013_fill_dmi_nop_u64(struct target *target, char *buf)
buf_set_u64((unsigned char *)buf, DTM_DMI_ADDRESS_OFFSET, info->abits, 0);
}
/* Helper function for riscv013_test_sba_config_reg */
static int get_max_sbaccess(struct target *target)
{
RISCV013_INFO(info);
uint32_t sbaccess128 = get_field(info->sbcs, DM_SBCS_SBACCESS128);
uint32_t sbaccess64 = get_field(info->sbcs, DM_SBCS_SBACCESS64);
uint32_t sbaccess32 = get_field(info->sbcs, DM_SBCS_SBACCESS32);
uint32_t sbaccess16 = get_field(info->sbcs, DM_SBCS_SBACCESS16);
uint32_t sbaccess8 = get_field(info->sbcs, DM_SBCS_SBACCESS8);
if (sbaccess128)
return 4;
else if (sbaccess64)
return 3;
else if (sbaccess32)
return 2;
else if (sbaccess16)
return 1;
else if (sbaccess8)
return 0;
else
return -1;
}
static uint32_t get_num_sbdata_regs(struct target *target)
{
RISCV013_INFO(info);
uint32_t sbaccess128 = get_field(info->sbcs, DM_SBCS_SBACCESS128);
uint32_t sbaccess64 = get_field(info->sbcs, DM_SBCS_SBACCESS64);
uint32_t sbaccess32 = get_field(info->sbcs, DM_SBCS_SBACCESS32);
if (sbaccess128)
return 4;
else if (sbaccess64)
return 2;
else if (sbaccess32)
return 1;
else
return 0;
}
static int riscv013_test_sba_config_reg(struct target *target,
target_addr_t legal_address, uint32_t num_words,
target_addr_t illegal_address, bool run_sbbusyerror_test)
{
LOG_INFO("Testing System Bus Access as defined by RISC-V Debug Spec v0.13");
uint32_t tests_failed = 0;
uint32_t rd_val;
uint32_t sbcs_orig;
int retval = dmi_read(target, &sbcs_orig, DM_SBCS);
if (retval != ERROR_OK)
return retval;
uint32_t sbcs = sbcs_orig;
bool test_passed;
int max_sbaccess = get_max_sbaccess(target);
if (max_sbaccess == -1) {
LOG_ERROR("System Bus Access not supported in this config.");
return ERROR_FAIL;
}
if (get_field(sbcs, DM_SBCS_SBVERSION) != 1) {
LOG_ERROR("System Bus Access unsupported SBVERSION (%d). Only version 1 is supported.",
get_field(sbcs, DM_SBCS_SBVERSION));
return ERROR_FAIL;
}
uint32_t num_sbdata_regs = get_num_sbdata_regs(target);
assert(num_sbdata_regs);
uint32_t rd_buf[num_sbdata_regs];
/* Test 1: Simple write/read test */
test_passed = true;
sbcs = set_field(sbcs_orig, DM_SBCS_SBAUTOINCREMENT, 0);
dmi_write(target, DM_SBCS, sbcs);
uint32_t test_patterns[4] = {0xdeadbeef, 0xfeedbabe, 0x12345678, 0x08675309};
for (uint32_t sbaccess = 0; sbaccess <= (uint32_t)max_sbaccess; sbaccess++) {
sbcs = set_field(sbcs, DM_SBCS_SBACCESS, sbaccess);
dmi_write(target, DM_SBCS, sbcs);
uint32_t compare_mask = (sbaccess == 0) ? 0xff : (sbaccess == 1) ? 0xffff : 0xffffffff;
for (uint32_t i = 0; i < num_words; i++) {
uint32_t addr = legal_address + (i << sbaccess);
uint32_t wr_data[num_sbdata_regs];
for (uint32_t j = 0; j < num_sbdata_regs; j++)
wr_data[j] = test_patterns[j] + i;
write_memory_sba_simple(target, addr, wr_data, num_sbdata_regs, sbcs);
}
for (uint32_t i = 0; i < num_words; i++) {
uint32_t addr = legal_address + (i << sbaccess);
read_memory_sba_simple(target, addr, rd_buf, num_sbdata_regs, sbcs);
for (uint32_t j = 0; j < num_sbdata_regs; j++) {
if (((test_patterns[j]+i)&compare_mask) != (rd_buf[j]&compare_mask)) {
LOG_ERROR("System Bus Access Test 1: Error reading non-autoincremented address %x,"
"expected val = %x, read val = %x", addr, test_patterns[j]+i, rd_buf[j]);
test_passed = false;
tests_failed++;
}
}
}
}
if (test_passed)
LOG_INFO("System Bus Access Test 1: Simple write/read test PASSED.");
/* Test 2: Address autoincrement test */
target_addr_t curr_addr;
target_addr_t prev_addr;
test_passed = true;
sbcs = set_field(sbcs_orig, DM_SBCS_SBAUTOINCREMENT, 1);
dmi_write(target, DM_SBCS, sbcs);
for (uint32_t sbaccess = 0; sbaccess <= (uint32_t)max_sbaccess; sbaccess++) {
sbcs = set_field(sbcs, DM_SBCS_SBACCESS, sbaccess);
dmi_write(target, DM_SBCS, sbcs);
dmi_write(target, DM_SBADDRESS0, legal_address);
read_sbcs_nonbusy(target, &sbcs);
curr_addr = legal_address;
for (uint32_t i = 0; i < num_words; i++) {
prev_addr = curr_addr;
read_sbcs_nonbusy(target, &sbcs);
curr_addr = sb_read_address(target);
if ((curr_addr - prev_addr != (uint32_t)(1 << sbaccess)) && (i != 0)) {
LOG_ERROR("System Bus Access Test 2: Error with address auto-increment, sbaccess = %x.", sbaccess);
test_passed = false;
tests_failed++;
}
dmi_write(target, DM_SBDATA0, i);
}
read_sbcs_nonbusy(target, &sbcs);
dmi_write(target, DM_SBADDRESS0, legal_address);
uint32_t val;
sbcs = set_field(sbcs, DM_SBCS_SBREADONDATA, 1);
dmi_write(target, DM_SBCS, sbcs);
dmi_read(target, &val, DM_SBDATA0); /* Dummy read to trigger first system bus read */
curr_addr = legal_address;
for (uint32_t i = 0; i < num_words; i++) {
prev_addr = curr_addr;
read_sbcs_nonbusy(target, &sbcs);
curr_addr = sb_read_address(target);
if ((curr_addr - prev_addr != (uint32_t)(1 << sbaccess)) && (i != 0)) {
LOG_ERROR("System Bus Access Test 2: Error with address auto-increment, sbaccess = %x", sbaccess);
test_passed = false;
tests_failed++;
}
dmi_read(target, &val, DM_SBDATA0);
read_sbcs_nonbusy(target, &sbcs);
if (i != val) {
LOG_ERROR("System Bus Access Test 2: Error reading auto-incremented address,"
"expected val = %x, read val = %x.", i, val);
test_passed = false;
tests_failed++;
}
}
}
if (test_passed)
LOG_INFO("System Bus Access Test 2: Address auto-increment test PASSED.");
/* Test 3: Read from illegal address */
read_memory_sba_simple(target, illegal_address, rd_buf, 1, sbcs_orig);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 2) {
sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 2);
dmi_write(target, DM_SBCS, sbcs);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 0)
LOG_INFO("System Bus Access Test 3: Illegal address read test PASSED.");
else
LOG_ERROR("System Bus Access Test 3: Illegal address read test FAILED, unable to clear to 0.");
} else {
LOG_ERROR("System Bus Access Test 3: Illegal address read test FAILED, unable to set error code.");
}
/* Test 4: Write to illegal address */
write_memory_sba_simple(target, illegal_address, test_patterns, 1, sbcs_orig);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 2) {
sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 2);
dmi_write(target, DM_SBCS, sbcs);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 0)
LOG_INFO("System Bus Access Test 4: Illegal address write test PASSED.");
else {
LOG_ERROR("System Bus Access Test 4: Illegal address write test FAILED, unable to clear to 0.");
tests_failed++;
}
} else {
LOG_ERROR("System Bus Access Test 4: Illegal address write test FAILED, unable to set error code.");
tests_failed++;
}
/* Test 5: Write with unsupported sbaccess size */
uint32_t sbaccess128 = get_field(sbcs_orig, DM_SBCS_SBACCESS128);
if (sbaccess128) {
LOG_INFO("System Bus Access Test 5: SBCS sbaccess error test PASSED, all sbaccess sizes supported.");
} else {
sbcs = set_field(sbcs_orig, DM_SBCS_SBACCESS, 4);
write_memory_sba_simple(target, legal_address, test_patterns, 1, sbcs);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 4) {
sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 4);
dmi_write(target, DM_SBCS, sbcs);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 0)
LOG_INFO("System Bus Access Test 5: SBCS sbaccess error test PASSED.");
else {
LOG_ERROR("System Bus Access Test 5: SBCS sbaccess error test FAILED, unable to clear to 0.");
tests_failed++;
}
} else {
LOG_ERROR("System Bus Access Test 5: SBCS sbaccess error test FAILED, unable to set error code.");
tests_failed++;
}
}
/* Test 6: Write to misaligned address */
sbcs = set_field(sbcs_orig, DM_SBCS_SBACCESS, 1);
write_memory_sba_simple(target, legal_address+1, test_patterns, 1, sbcs);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 3) {
sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 3);
dmi_write(target, DM_SBCS, sbcs);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBERROR) == 0)
LOG_INFO("System Bus Access Test 6: SBCS address alignment error test PASSED");
else {
LOG_ERROR("System Bus Access Test 6: SBCS address alignment error test FAILED, unable to clear to 0.");
tests_failed++;
}
} else {
LOG_ERROR("System Bus Access Test 6: SBCS address alignment error test FAILED, unable to set error code.");
tests_failed++;
}
/* Test 7: Set sbbusyerror, only run this case in simulation as it is likely
* impossible to hit otherwise */
if (run_sbbusyerror_test) {
sbcs = set_field(sbcs_orig, DM_SBCS_SBREADONADDR, 1);
dmi_write(target, DM_SBCS, sbcs);
for (int i = 0; i < 16; i++)
dmi_write(target, DM_SBDATA0, 0xdeadbeef);
for (int i = 0; i < 16; i++)
dmi_write(target, DM_SBADDRESS0, legal_address);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBBUSYERROR)) {
sbcs = set_field(sbcs_orig, DM_SBCS_SBBUSYERROR, 1);
dmi_write(target, DM_SBCS, sbcs);
dmi_read(target, &rd_val, DM_SBCS);
if (get_field(rd_val, DM_SBCS_SBBUSYERROR) == 0)
LOG_INFO("System Bus Access Test 7: SBCS sbbusyerror test PASSED.");
else {
LOG_ERROR("System Bus Access Test 7: SBCS sbbusyerror test FAILED, unable to clear to 0.");
tests_failed++;
}
} else {
LOG_ERROR("System Bus Access Test 7: SBCS sbbusyerror test FAILED, unable to set error code.");
tests_failed++;
}
}
if (tests_failed == 0) {
LOG_INFO("ALL TESTS PASSED");
return ERROR_OK;
} else {
LOG_ERROR("%d TESTS FAILED", tests_failed);
return ERROR_FAIL;
}
}
static void write_memory_sba_simple(struct target *target, target_addr_t addr,
uint32_t *write_data, uint32_t write_size, uint32_t sbcs)
{
RISCV013_INFO(info);
uint32_t rd_sbcs;
uint32_t masked_addr;
uint32_t sba_size = get_field(info->sbcs, DM_SBCS_SBASIZE);
read_sbcs_nonbusy(target, &rd_sbcs);
uint32_t sbcs_no_readonaddr = set_field(sbcs, DM_SBCS_SBREADONADDR, 0);
dmi_write(target, DM_SBCS, sbcs_no_readonaddr);
for (uint32_t i = 0; i < sba_size/32; i++) {
masked_addr = (addr >> 32*i) & 0xffffffff;
if (i != 3)
dmi_write(target, DM_SBADDRESS0+i, masked_addr);
else
dmi_write(target, DM_SBADDRESS3, masked_addr);
}
/* Write SBDATA registers starting with highest address, since write to
* SBDATA0 triggers write */
for (int i = write_size-1; i >= 0; i--)
dmi_write(target, DM_SBDATA0+i, write_data[i]);
}
static void read_memory_sba_simple(struct target *target, target_addr_t addr,
uint32_t *rd_buf, uint32_t read_size, uint32_t sbcs)
{
RISCV013_INFO(info);
uint32_t rd_sbcs;
uint32_t masked_addr;
uint32_t sba_size = get_field(info->sbcs, DM_SBCS_SBASIZE);
read_sbcs_nonbusy(target, &rd_sbcs);
uint32_t sbcs_readonaddr = set_field(sbcs, DM_SBCS_SBREADONADDR, 1);
dmi_write(target, DM_SBCS, sbcs_readonaddr);
/* Write addresses starting with highest address register */
for (int i = sba_size/32-1; i >= 0; i--) {
masked_addr = (addr >> 32*i) & 0xffffffff;
if (i != 3)
dmi_write(target, DM_SBADDRESS0+i, masked_addr);
else
dmi_write(target, DM_SBADDRESS3, masked_addr);
}
read_sbcs_nonbusy(target, &rd_sbcs);
for (uint32_t i = 0; i < read_size; i++)
dmi_read(target, &(rd_buf[i]), DM_SBDATA0+i);
}
int riscv013_dmi_write_u64_bits(struct target *target)
{
RISCV013_INFO(info);

View File

@ -2711,38 +2711,6 @@ COMMAND_HANDLER(riscv_dmi_write)
}
}
COMMAND_HANDLER(riscv_test_sba_config_reg)
{
LOG_WARNING("Command \"riscv test_sba_config_reg\" is deprecated. "
"It will be removed in a future OpenOCD version.");
if (CMD_ARGC != 4) {
LOG_ERROR("Command takes exactly 4 arguments");
return ERROR_COMMAND_SYNTAX_ERROR;
}
struct target *target = get_current_target(CMD_CTX);
RISCV_INFO(r);
target_addr_t legal_address;
uint32_t num_words;
target_addr_t illegal_address;
bool run_sbbusyerror_test;
COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[0], legal_address);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], num_words);
COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[2], illegal_address);
COMMAND_PARSE_ON_OFF(CMD_ARGV[3], run_sbbusyerror_test);
if (r->test_sba_config_reg) {
return r->test_sba_config_reg(target, legal_address, num_words,
illegal_address, run_sbbusyerror_test);
} else {
LOG_ERROR("test_sba_config_reg is not implemented for this target.");
return ERROR_FAIL;
}
}
COMMAND_HANDLER(riscv_reset_delays)
{
int wait = 0;
@ -2982,19 +2950,6 @@ static const struct command_registration riscv_exec_command_handlers[] = {
.usage = "address value",
.help = "Perform a 32-bit DMI write of value at address."
},
{
.name = "test_sba_config_reg",
.handler = riscv_test_sba_config_reg,
.mode = COMMAND_ANY,
.usage = "legal_address num_words "
"illegal_address run_sbbusyerror_test[on/off]",
.help = "Perform a series of tests on the SBCS register. "
"Inputs are a legal, 128-byte aligned address and a number of words to "
"read/write starting at that address (i.e., address range [legal address, "
"legal_address+word_size*num_words) must be legally readable/writable), "
"an illegal, 128-byte aligned address for error flag/handling cases, "
"and whether sbbusyerror test should be run."
},
{
.name = "reset_delays",
.handler = riscv_reset_delays,

View File

@ -174,9 +174,6 @@ struct riscv_info {
int (*dmi_read)(struct target *target, uint32_t *value, uint32_t address);
int (*dmi_write)(struct target *target, uint32_t address, uint32_t value);
int (*test_sba_config_reg)(struct target *target, target_addr_t legal_address,
uint32_t num_words, target_addr_t illegal_address, bool run_sbbusyerror_test);
int (*sample_memory)(struct target *target,
struct riscv_sample_buf *buf,
riscv_sample_config_t *config,