Skip to content

Commit 6d4ad00

Browse files
committed
target/riscv: write SB address using batch
Reduces the number of JTAG queue flushes. Change-Id: Id103f5da1a3ea3177447046711e0e62a22c98c75 Signed-off-by: Evgeniy Naydanov <[email protected]>
1 parent 2f29b80 commit 6d4ad00

File tree

1 file changed

+37
-38
lines changed

1 file changed

+37
-38
lines changed

src/target/riscv/riscv-013.c

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -731,17 +731,6 @@ static uint32_t riscv013_get_dmi_address(const struct target *target, uint32_t a
731731
return address + base;
732732
}
733733

734-
static int dm_op(struct target *target, uint32_t *data_in,
735-
bool *dmi_busy_encountered, int op, uint32_t address,
736-
uint32_t data_out, bool exec, bool ensure_success)
737-
{
738-
dm013_info_t *dm = get_dm(target);
739-
if (!dm)
740-
return ERROR_FAIL;
741-
return dmi_op(target, data_in, dmi_busy_encountered, op, address + dm->base,
742-
data_out, exec, ensure_success);
743-
}
744-
745734
static int dm_read(struct target *target, uint32_t *value, uint32_t address)
746735
{
747736
dm013_info_t *dm = get_dm(target);
@@ -2716,21 +2705,42 @@ static uint32_t sb_sbaccess(unsigned int size_bytes)
27162705
return 0;
27172706
}
27182707

2719-
static int sb_write_address(struct target *target, target_addr_t address,
2720-
bool ensure_success)
2708+
static unsigned int get_sbaadress_reg_count(const struct target *target)
27212709
{
27222710
RISCV013_INFO(info);
2723-
unsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);
2711+
const unsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);
2712+
return DIV_ROUND_UP(sbasize, 32);
2713+
}
2714+
2715+
static void batch_fill_sb_write_address(const struct target *target,
2716+
struct riscv_batch *batch, target_addr_t address,
2717+
enum riscv_scan_delay_class sbaddr0_delay)
2718+
{
27242719
/* There currently is no support for >64-bit addresses in OpenOCD. */
2725-
if (sbasize > 96)
2726-
dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS3, 0, false, false);
2727-
if (sbasize > 64)
2728-
dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS2, 0, false, false);
2729-
if (sbasize > 32)
2730-
dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS1,
2731-
(uint32_t)(address >> 32), false, false);
2732-
return dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS0,
2733-
(uint32_t)address, false, ensure_success);
2720+
assert(sizeof(target_addr_t) == sizeof(uint64_t));
2721+
const uint32_t addresses[] = {DM_SBADDRESS0, DM_SBADDRESS1, DM_SBADDRESS2, DM_SBADDRESS3};
2722+
const uint32_t values[] = {(uint32_t)address, (uint32_t)(address >> 32), 0, 0};
2723+
const unsigned int reg_count = get_sbaadress_reg_count(target);
2724+
assert(reg_count > 0);
2725+
assert(reg_count <= ARRAY_SIZE(addresses));
2726+
assert(ARRAY_SIZE(addresses) == ARRAY_SIZE(values));
2727+
2728+
for (unsigned int i = reg_count - 1; i > 0; --i)
2729+
riscv_batch_add_dm_write(batch, addresses[i], values[i], /* read back */ true,
2730+
RISCV_DELAY_BASE);
2731+
riscv_batch_add_dm_write(batch, addresses[0], values[0], /* read back */ true,
2732+
sbaddr0_delay);
2733+
}
2734+
2735+
static int sb_write_address(struct target *target, target_addr_t address,
2736+
enum riscv_scan_delay_class sbaddr0_delay)
2737+
{
2738+
struct riscv_batch *batch = riscv_batch_alloc(target,
2739+
get_sbaadress_reg_count(target));
2740+
batch_fill_sb_write_address(target, batch, address, sbaddr0_delay);
2741+
const int res = batch_run_timeout(target, batch);
2742+
riscv_batch_free(batch);
2743+
return res;
27342744
}
27352745

27362746
static int batch_run(struct target *target, struct riscv_batch *batch)
@@ -3555,21 +3565,9 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
35553565
return ERROR_FAIL;
35563566

35573567
/* This address write will trigger the first read. */
3558-
if (sb_write_address(target, next_address, true) != ERROR_OK)
3568+
if (sb_write_address(target, next_address, RISCV_DELAY_SYSBUS_READ) != ERROR_OK)
35593569
return ERROR_FAIL;
35603570

3561-
unsigned int bus_master_read_delay = riscv_scan_get_delay(&info->learned_delays,
3562-
RISCV_DELAY_SYSBUS_READ);
3563-
if (bus_master_read_delay) {
3564-
LOG_TARGET_DEBUG(target, "Waiting %d cycles for bus master read delay",
3565-
bus_master_read_delay);
3566-
jtag_add_runtest(bus_master_read_delay, TAP_IDLE);
3567-
if (jtag_execute_queue() != ERROR_OK) {
3568-
LOG_TARGET_ERROR(target, "Failed to scan idle sequence");
3569-
return ERROR_FAIL;
3570-
}
3571-
}
3572-
35733571
/* First read has been started. Optimistically assume that it has
35743572
* completed. */
35753573

@@ -4681,9 +4679,10 @@ static int write_memory_bus_v1(struct target *target, target_addr_t address,
46814679
target_addr_t next_address = address;
46824680
target_addr_t end_address = address + count * size;
46834681

4684-
int result;
4682+
int result = sb_write_address(target, next_address, RISCV_DELAY_BASE);
4683+
if (result != ERROR_OK)
4684+
return result;
46854685

4686-
sb_write_address(target, next_address, true);
46874686
while (next_address < end_address) {
46884687
LOG_TARGET_DEBUG(target, "Transferring burst starting at address 0x%" TARGET_PRIxADDR,
46894688
next_address);

0 commit comments

Comments
 (0)