Remove commented out code.

Also added back the initial check that confirms debug RAM is written
correctly.
__archive__
Tim Newsome 2016-07-25 13:58:21 -07:00
parent a916d204b9
commit 5de81da8f4
1 changed files with 39 additions and 268 deletions

View File

@ -207,38 +207,6 @@ static uint16_t dram_address(unsigned int index)
return 0x40 + index - 0x10;
}
#if 0
static int debug_scan(struct target *target)
{
uint8_t in[DIV_ROUND_UP(DEBUG_LENGTH, 8)];
jtag_add_ir_scan(target->tap, &select_debug, TAP_IDLE);
struct scan_field field;
field.num_bits = DEBUG_LENGTH;
field.out_value = NULL;
field.check_value = NULL;
field.check_mask = NULL;
field.in_value = in;
jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
/* Always return to dbus. */
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
jtag_execute_queue();
LOG_DEBUG(" debug_pc=0x%x", buf_get_u32(in, 0, 32));
LOG_DEBUG(" last_returned_data=0x%x", buf_get_u32(in, 32, 32));
LOG_DEBUG(" last_returned_pc=0x%x", buf_get_u32(in, 64, 32));
LOG_DEBUG(" last_requested_pc=0x%x", buf_get_u32(in, 96, 32));
LOG_DEBUG(" last_committed_instruction=0x%x", buf_get_u32(in, 128, 32));
LOG_DEBUG(" last_committed_pc=0x%x", buf_get_u32(in, 160, 32));
LOG_DEBUG(" last_committed_time=0x%" PRIx64, buf_get_u64(in, 192, 64));
LOG_DEBUG(" 3bits=0x%x", buf_get_u32(in, 256, 3));
return 0;
}
#endif
static void increase_dbus_busy_delay(struct target *target)
{
riscv_info_t *info = (riscv_info_t *) target->arch_info;
@ -451,6 +419,19 @@ static int wait_for_debugint_clear(struct target *target, bool ignore_first)
}
}
static int dram_check32(struct target *target, unsigned int index,
uint32_t expected)
{
uint16_t address = dram_address(index);
uint32_t actual = dbus_read(target, address);
if (expected != actual) {
LOG_ERROR("Wrote 0x%x to Debug RAM at %d, but read back 0x%x",
expected, index, actual);
return ERROR_FAIL;
}
return ERROR_OK;
}
static void cache_set(struct target *target, unsigned int index, uint32_t data)
{
riscv_info_t *info = (riscv_info_t *) target->arch_info;
@ -503,6 +484,27 @@ static void cache_clean(struct target *target)
}
}
static int cache_check(struct target *target)
{
riscv_info_t *info = (riscv_info_t *) target->arch_info;
int error = 0;
for (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) {
if (info->dram_cache[i].valid && !info->dram_cache[i].dirty) {
if (dram_check32(target, i, info->dram_cache[i].data) != ERROR_OK) {
error++;
}
}
}
if (error) {
dump_debug_ram(target);
return ERROR_FAIL;
}
return ERROR_OK;
}
/** Write cache to the target, and optionally run the program. */
static int cache_write(struct target *target, unsigned int address, bool run)
{
@ -642,21 +644,6 @@ uint32_t cache_get32(struct target *target, unsigned int address)
return info->dram_cache[address].data;
}
#if 0
static int dram_check32(struct target *target, unsigned int index,
uint32_t expected)
{
uint16_t address = dram_address(index);
uint32_t actual = dbus_read(target, address, address + 1);
if (expected != actual) {
LOG_ERROR("Wrote 0x%x to Debug RAM at %d, but read back 0x%x",
expected, index, actual);
return ERROR_FAIL;
}
return ERROR_OK;
}
#endif
/* Write instruction that jumps from the specified word in Debug RAM to resume
* in Debug ROM. */
static void dram_write_jump(struct target *target, unsigned int index, bool set_interrupt)
@ -684,29 +671,6 @@ static int wait_for_state(struct target *target, enum target_state state)
}
}
#if 0
static int wait_and_read(struct target *target, uint32_t *data, uint16_t address)
{
time_t start = time(NULL);
// Throw away the results of the first read, since they'll contain the
// result of the read that happened just before debugint was set. (Assuming
// the last scan before calling this function was one that sets debugint.)
dbus_scan(target, NULL, NULL, DBUS_OP_READ, address, 0);
while (1) {
uint64_t dbus_value = dbus_read(target, address);
*data = dbus_value;
if (!get_field(dbus_value, DMCONTROL_INTERRUPT)) {
return ERROR_OK;
}
if (time(NULL) - start > 2) {
LOG_ERROR("Timed out waiting for debug int to clear.");
return ERROR_FAIL;
}
}
}
#endif
static int read_csr(struct target *target, uint32_t *value, uint32_t csr)
{
cache_set(target, 0, csrr(S0, csr));
@ -1019,100 +983,9 @@ static int riscv_step(struct target *target, int current, uint32_t address,
int handle_breakpoints)
{
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
#if 1
return resume(target, current, address, handle_breakpoints, 0, true);
#else
// Hardware single step doesn't exist yet.
riscv_info_t *info = (riscv_info_t *) target->arch_info;
uint32_t next_pc = info->dpc + 4;
// TODO: write better next pc prediction code
if (breakpoint_add(target, next_pc, 4, BKPT_SOFT) != ERROR_OK) {
return ERROR_FAIL;
}
if (resume(target, current, address, handle_breakpoints, 0, false) != ERROR_OK) {
return ERROR_FAIL;
}
while (target->state == TARGET_RUNNING) {
riscv_poll(target);
}
breakpoint_remove(target, next_pc);
return ERROR_OK;
#endif
}
#if 0
static void dram_test(struct target *target)
{
uint32_t shadow[16];
for (int j = 0; j < 100; j++) {
LOG_DEBUG("Round %d", j);
for (int i = 0; i < 16; i++) {
shadow[i] = random();
dram_write32(target, i, shadow[i], false);
}
for (int i = 0; i < 16; i++) {
if (dram_check32(target, i, shadow[i]) != ERROR_OK) {
LOG_ERROR("Mismatch! j=%d i=%d", j, i);
}
}
}
}
#endif
#if 0
static void light_leds(struct target *target)
{
dram_write32(target, 0, lui(S0, 0x70002), false);
dram_write32(target, 1, lui(S1, 0xccccc), false);
dram_write32(target, 2, sw(S1, S0, 0xa0), false);
dram_write32(target, 3, jal(ZERO, 0), true);
}
#endif
#if 0
static void write_constants(struct target *target)
{
dram_write32(target, 0, lui(S0, 0x70002), false);
dram_write32(target, 1, lui(S1, 0xccccc), false);
dram_write32(target, 2, sw(S0, ZERO, DEBUG_RAM_START + 0), false);
dram_write32(target, 3, sw(S1, ZERO, DEBUG_RAM_START + 4), false);
dram_write_jump(target, 4, true);
if (wait_for_debugint_clear(target, true) != ERROR_OK) {
LOG_ERROR("Debug interrupt didn't clear.");
}
uint32_t word0 = dram_read32(target, 0);
uint32_t word1 = dram_read32(target, 1);
if (word0 != 0x70002000) {
LOG_ERROR("Value at word 0 should be 0x%x but is 0x%x",
0x70002000, word0);
}
if (word1 != 0x70002000) {
LOG_ERROR("Value at word 1 should be 0x%x but is 0x%x",
0x70002000, word1);
}
}
#endif
#if 0
static void test_s1(struct target *target)
{
riscv_info_t *info = (riscv_info_t *) target->arch_info;
riscv_halt(target);
riscv_poll(target);
dram_write32(target, info->dramsize - 1, 0xdeadbed, false);
dram_read32(target, info->dramsize - 1);
riscv_step(target, true, 0, 0);
dram_read32(target, info->dramsize - 1);
exit(0);
}
#endif
static int riscv_examine(struct target *target)
{
LOG_DEBUG("riscv_examine()");
@ -1181,23 +1054,15 @@ static int riscv_examine(struct target *target)
cache_set(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4));
cache_set_jump(target, 5);
cache_write(target, 0, true);
cache_invalidate(target);
cache_write(target, 0, false);
#if 0
// TODO
// Check that we can actually read/write dram.
int error = 0;
error += dram_check32(target, 0, xori(S1, ZERO, -1));
error += dram_check32(target, 1, srli(S1, S1, 31));
error += dram_check32(target, 2, sw(S1, ZERO, DEBUG_RAM_START));
error += dram_check32(target, 3, srli(S1, S1, 31));
error += dram_check32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4));
if (error != 5 * ERROR_OK) {
dump_debug_ram(target);
if (cache_check(target) != ERROR_OK) {
return ERROR_FAIL;
}
#endif
cache_write(target, 0, true);
cache_invalidate(target);
uint32_t word0 = cache_get32(target, 0);
uint32_t word1 = cache_get32(target, 1);
@ -1552,7 +1417,6 @@ static int riscv_read_memory(struct target *target, uint32_t address,
cache_set_jump(target, 3);
cache_write(target, 4, false);
#if 1
riscv_info_t *info = (riscv_info_t *) target->arch_info;
const int max_batch_size = 256;
uint8_t *in = malloc(max_batch_size * 8);
@ -1648,39 +1512,8 @@ error:
free(out);
free(field);
return ERROR_FAIL;
#else
for (unsigned int i = 0; i < count; i++) {
dram_write32(target, 4, address + i * size, true);
uint32_t value;
if (wait_and_read(target, &value, 4) != ERROR_OK) {
LOG_ERROR("Debug interrupt didn't clear.");
return ERROR_FAIL;
}
unsigned int offset = i * size;
switch (size) {
case 1:
buffer[offset] = value & 0xff;
break;
case 2:
buffer[offset] = value & 0xff;
buffer[offset + 1] = (value >> 8) & 0xff;
break;
case 4:
buffer[offset] = value & 0xff;
buffer[offset + 1] = (value >> 8) & 0xff;
buffer[offset + 2] = (value >> 16) & 0xff;
buffer[offset + 3] = (value >> 24) & 0xff;
break;
}
}
return ERROR_OK;
#endif
}
#if 1
static int setup_write_memory(struct target *target, uint32_t size)
{
switch (size) {
@ -1838,68 +1671,6 @@ error:
free(field);
return ERROR_FAIL;
}
#else
/** Inefficient implementation that doesn't require conditional writes. */
static int riscv_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
// Write program.
dram_write32(target, 0, lw(S1, ZERO, DEBUG_RAM_START + 16), false);
switch (size) {
case 1:
dram_write32(target, 1, lb(S0, ZERO, DEBUG_RAM_START + 20), false);
dram_write32(target, 2, sb(S0, S1, 0), false);
break;
case 2:
dram_write32(target, 1, lh(S0, ZERO, DEBUG_RAM_START + 20), false);
dram_write32(target, 2, sh(S0, S1, 0), false);
break;
case 4:
dram_write32(target, 1, lw(S0, ZERO, DEBUG_RAM_START + 20), false);
dram_write32(target, 2, sw(S0, S1, 0), false);
break;
default:
LOG_ERROR("Unsupported size: %d", size);
return ERROR_FAIL;
}
dram_write_jump(target, 3, false);
for (uint32_t i = 0; i < count; i++) {
// Write the next value and set interrupt.
uint32_t value;
uint32_t offset = size * i;
switch (size) {
case 1:
value = buffer[offset];
break;
case 2:
value = buffer[offset] |
(buffer[offset+1] << 8);
break;
case 4:
value = buffer[offset] |
((uint32_t) buffer[offset+1] << 8) |
((uint32_t) buffer[offset+2] << 16) |
((uint32_t) buffer[offset+3] << 24);
break;
default:
return ERROR_FAIL;
}
dram_write32(target, 4, address + offset, false);
dram_write32(target, 5, value, true);
if (wait_for_debugint_clear(target, true) != ERROR_OK) {
LOG_ERROR("Debug interrupt didn't clear.");
return ERROR_FAIL;
}
}
return ERROR_OK;
}
#endif
static int riscv_get_gdb_reg_list(struct target *target,
struct reg **reg_list[], int *reg_list_size,