diff options
author | Tim Newsome <tim@sifive.com> | 2017-10-12 11:45:52 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2017-10-12 11:45:52 -0700 |
commit | 94e82507134610180843d70c8b244d98de26171a (patch) | |
tree | c28681383afc0e29379cf19b35f6139629df5b67 /src | |
parent | 77802af655fef154a1eff30d59e699c11917ecd2 (diff) | |
download | riscv-openocd-94e82507134610180843d70c8b244d98de26171a.zip riscv-openocd-94e82507134610180843d70c8b244d98de26171a.tar.gz riscv-openocd-94e82507134610180843d70c8b244d98de26171a.tar.bz2 |
WIP; doesn't work.
Change-Id: Ia407e82ccbd2044ad61e0845d285dd5765154476
Diffstat (limited to 'src')
-rw-r--r-- | src/target/riscv/program.c | 71 | ||||
-rw-r--r-- | src/target/riscv/program.h | 16 | ||||
-rw-r--r-- | src/target/riscv/riscv-013.c | 129 | ||||
-rw-r--r-- | src/target/riscv/riscv.c | 9 | ||||
-rw-r--r-- | src/target/riscv/riscv.h | 4 |
5 files changed, 55 insertions, 174 deletions
diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c index d052574..2fc8041 100644 --- a/src/target/riscv/program.c +++ b/src/target/riscv/program.c @@ -100,77 +100,6 @@ int riscv_program_exec(struct riscv_program *p, struct target *t) return ERROR_OK; } -riscv_addr_t riscv_program_alloc_data(struct riscv_program *p, size_t bytes) -{ - riscv_addr_t addr = - riscv_debug_buffer_addr(p->target) - + riscv_debug_buffer_size(p->target) * sizeof(p->debug_buffer[0]) - - p->data_count * sizeof(p->debug_buffer[0]) - - bytes; - while (addr % bytes != 0) addr--; - - riscv_addr_t ptop = - riscv_debug_buffer_addr(p->target) - + p->instruction_count * sizeof(p->debug_buffer[0]); - - if (addr <= ptop) { - LOG_ERROR("unable to allocate %d bytes", (int)bytes); - return RISCV_PROGRAM_ALLOC_FAIL; - } - - p->data_count = - + riscv_debug_buffer_size(p->target) - - (addr - riscv_debug_buffer_addr(p->target)) / sizeof(p->debug_buffer[0]); - return addr; -} - -riscv_addr_t riscv_program_alloc_x(struct riscv_program *p) -{ - return riscv_program_alloc_data(p, p->target_xlen / 8); -} - -riscv_addr_t riscv_program_alloc_d(struct riscv_program *p) -{ - return riscv_program_alloc_data(p, 8); -} - -riscv_addr_t riscv_program_alloc_w(struct riscv_program *p) -{ - return riscv_program_alloc_data(p, 4); -} - -riscv_addr_t riscv_program_alloc_h(struct riscv_program *p) -{ - return riscv_program_alloc_data(p, 2); -} - -riscv_addr_t riscv_program_alloc_b(struct riscv_program *p) -{ - return riscv_program_alloc_data(p, 1); -} - -riscv_insn_t riscv_program_read_ram(struct riscv_program *p, riscv_addr_t addr) -{ - if (addr < riscv_debug_buffer_addr(p->target)) - return -1; - if ((size_t)addr > riscv_debug_buffer_addr(p->target) + (riscv_debug_buffer_size(p->target) * sizeof(p->debug_buffer[0]))) - return -1; - - int off = (addr - riscv_debug_buffer_addr(p->target)) / sizeof(p->debug_buffer[0]); - return p->debug_buffer[off]; -} - -void riscv_program_write_ram(struct riscv_program *p, riscv_addr_t addr, uint64_t d) -{ - if (addr < riscv_debug_buffer_addr(p->target)) - return; - if ((size_t)addr > riscv_debug_buffer_addr(p->target) + (riscv_debug_buffer_size(p->target) * sizeof(p->debug_buffer[0]))) - return; - - int off = (addr - riscv_debug_buffer_addr(p->target)) / sizeof(p->debug_buffer[0]); - p->debug_buffer[off] = d; -} - int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset) { p->writes_memory = 1; diff --git a/src/target/riscv/program.h b/src/target/riscv/program.h index ac1127e..82e9b5e 100644 --- a/src/target/riscv/program.h +++ b/src/target/riscv/program.h @@ -60,22 +60,6 @@ int riscv_program_insert(struct riscv_program *p, riscv_insn_t i); * memory. */ int riscv_program_save_to_dscratch(struct riscv_program *p, enum gdb_regno to_save); -/* Allocates data of various sizes. Either returns the absolute physical - * address or RISCV_PROGRAM_ALLOC_FAIL on failure. */ -riscv_addr_t riscv_program_alloc_data(struct riscv_program *p, size_t bytes); -riscv_addr_t riscv_program_alloc_x(struct riscv_program *p); -riscv_addr_t riscv_program_alloc_d(struct riscv_program *p); -riscv_addr_t riscv_program_alloc_w(struct riscv_program *p); -riscv_addr_t riscv_program_alloc_h(struct riscv_program *p); -riscv_addr_t riscv_program_alloc_b(struct riscv_program *p); -#define RISCV_PROGRAM_ALLOC_FAIL ((riscv_addr_t)(-1)) - -/* Reads a word of memory from this program's internal view of the debug RAM. - * This is what you want to use to get data back from the program after it - * executes. */ -riscv_insn_t riscv_program_read_ram(struct riscv_program *p, riscv_addr_t addr); -void riscv_program_write_ram(struct riscv_program *p, riscv_addr_t a, uint64_t d); - /* Helpers to assembly various instructions. Return 0 on success. These might * assembly into a multi-instruction sequence that overwrites some other * register, but those will be properly saved and restored. */ diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index f8fd7e6..483c523 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -31,13 +31,13 @@ static void riscv013_on_step_or_resume(struct target *target, bool step); static void riscv013_step_or_resume_current_hart(struct target *target, bool step); -static riscv_addr_t riscv013_progbuf_addr(struct target *target); -static riscv_addr_t riscv013_data_size(struct target *target); -static riscv_addr_t riscv013_data_addr(struct target *target); -static void riscv013_set_autoexec(struct target *target, unsigned index, - bool enabled); -static int riscv013_debug_buffer_register(struct target *target, riscv_addr_t addr); -static void riscv013_clear_abstract_error(struct target *target); +//static riscv_addr_t riscv013_progbuf_addr(struct target *target); +//static riscv_addr_t riscv013_data_size(struct target *target); +//static riscv_addr_t riscv013_data_addr(struct target *target); +//static void riscv013_set_autoexec(struct target *target, unsigned index, + //bool enabled); +//static int riscv013_debug_buffer_register(struct target *target, riscv_addr_t addr); +//static void riscv013_clear_abstract_error(struct target *target); /* Implementations of the functions in riscv_info_t. */ static riscv_reg_t riscv013_get_register(struct target *target, int hartid, int regid); @@ -517,6 +517,7 @@ static void dmi_write(struct target *target, uint16_t address, uint64_t value) } } +#if 0 static void increase_ac_busy_delay(struct target *target) { riscv013_info_t *info = get_info(target); @@ -525,6 +526,7 @@ static void increase_ac_busy_delay(struct target *target) info->dtmcontrol_idle, info->dmi_busy_delay, info->ac_busy_delay); } +#endif uint32_t abstract_register_size(unsigned width) { @@ -769,6 +771,8 @@ static int register_write_direct(struct target *target, unsigned number, riscv_program_init(&program, target); + assert(0); +#if 0 riscv_addr_t input = riscv_program_alloc_d(&program); riscv_program_write_ram(&program, input + 4, value >> 32); riscv_program_write_ram(&program, input, value); @@ -794,6 +798,7 @@ static int register_write_direct(struct target *target, unsigned number, } return ERROR_OK; +#endif } /** Actually read registers from the target right now. */ @@ -805,6 +810,22 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t if (result != ERROR_OK) { struct riscv_program program; riscv_program_init(&program, target); + assert(0); + assert(number != GDB_REGNO_S0); + + uint64_t s0; + if (register_read_direct(target, &s0, GDB_REGNO_S0) != ERROR_OK) + return ERROR_FAIL; + + // Write program to move data into s0. + // Execute program. + // Read S0 + if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK) + return ERROR_FAIL; + // Restore S0. + if (register_write_direct(target, GDB_REGNO_S0, &s0) != ERROR_OK) + return ERROR_FAIL; +#if 0 riscv_addr_t output = riscv_program_alloc_d(&program); riscv_program_write_ram(&program, output + 4, 0); riscv_program_write_ram(&program, output, 0); @@ -833,6 +854,7 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t *value = 0; *value |= ((uint64_t)(riscv_program_read_ram(&program, output + 4))) << 32; *value |= riscv_program_read_ram(&program, output); +#endif } LOG_DEBUG("[%d] reg[0x%x] = 0x%" PRIx64, riscv_current_hartid(target), @@ -1080,77 +1102,19 @@ static int examine(struct target *target) r->debug_buffer_size[i] = info->progsize; /* Guess this is a 32-bit system, we're probing it. */ - r->xlen[i] = 32; - - /* First find the low 32 bits of the program buffer. This is - * used to check for alignment. */ - struct riscv_program program32; - riscv_program_init(&program32, target); - riscv_program_csrrw(&program32, GDB_REGNO_S0, GDB_REGNO_S0, GDB_REGNO_DSCRATCH); - riscv_program_insert(&program32, auipc(GDB_REGNO_S0)); - riscv_program_insert(&program32, sw(GDB_REGNO_S0, GDB_REGNO_S0, -4)); - riscv_program_csrrw(&program32, GDB_REGNO_S0, GDB_REGNO_S0, GDB_REGNO_DSCRATCH); - riscv_program_fence(&program32); - riscv_program_exec(&program32, target); - - riscv_addr_t progbuf_addr = dmi_read(target, DMI_PROGBUF0) - 4; - if (get_field(dmi_read(target, DMI_ABSTRACTCS), DMI_ABSTRACTCS_CMDERR) != 0) { - LOG_ERROR("Unable to find the address of the program buffer on hart %d", i); - r->xlen[i] = -1; - continue; - } - r->debug_buffer_addr[i] = progbuf_addr; - - /* Check to see if the core can execute 64 bit instructions. - * In order to make this work we first need to */ - int offset = (progbuf_addr % 8 == 0) ? -4 : 0; - - /* This program uses a temporary register. If the core can not - * execute 64 bit instruction, the original value of temporary - * register (s0) will not be restored due to an exception. - * So we have to save it and restore manually in that case. - * If the core can execute 64 bit instruction, the saved value - * is wrong, because it was read with 32 bit lw instruction, - * but the value of s0 will be restored by the reverse swap - * of s0 and dscratch registers. */ - uint64_t s0 = riscv_get_register(target, GDB_REGNO_S0); - - struct riscv_program program64; - riscv_program_init(&program64, target); - riscv_program_csrrw(&program64, GDB_REGNO_S0, GDB_REGNO_S0, GDB_REGNO_DSCRATCH); - riscv_program_insert(&program64, auipc(GDB_REGNO_S0)); - riscv_program_insert(&program64, sd(GDB_REGNO_S0, GDB_REGNO_S0, offset)); - riscv_program_csrrw(&program64, GDB_REGNO_S0, GDB_REGNO_S0, GDB_REGNO_DSCRATCH); - riscv_program_fence(&program64); - int result = riscv_program_exec(&program64, target); + // >>> r->xlen[i] = 32; + uint64_t value; + int result = register_read_abstract(target, &value, GDB_REGNO_S0, 64); if (result == ERROR_OK) { - r->debug_buffer_addr[i] = - (dmi_read(target, DMI_PROGBUF0 + (8 + offset) / 4) << 32) - + dmi_read(target, DMI_PROGBUF0 + (4 + offset) / 4) - - 4; r->xlen[i] = 64; } else { - riscv_set_register(target, GDB_REGNO_S0, s0); + r->xlen[i] = 32; } /* Display this as early as possible to help people who are using * really slow simulators. */ - LOG_DEBUG(" hart %d: XLEN=%d, program buffer at 0x%" PRIx64, i, - r->xlen[i], r->debug_buffer_addr[i]); - - if (riscv_program_gah(&program64, r->debug_buffer_addr[i])) { - LOG_ERROR("This implementation will not work with hart %d with debug_buffer_addr of 0x%lx", i, - (long)r->debug_buffer_addr[i]); - abort(); - } - - /* Check to see if we can use the data words as an extended - * program buffer or not. */ - if (r->debug_buffer_addr[i] + (4 * r->debug_buffer_size[i]) == riscv013_data_addr(target)) { - r->debug_buffer_size[i] += riscv013_data_size(target); - LOG_DEBUG("extending the debug buffer using data words, total size %d", r->debug_buffer_size[i]); - } + LOG_DEBUG(" hart %d: XLEN=%d", i, r->xlen[i]); } /* Then we check the number of triggers availiable to each hart. */ @@ -1172,8 +1136,7 @@ static int examine(struct target *target) riscv_count_harts(target)); for (int i = 0; i < riscv_count_harts(target); ++i) { if (riscv_hart_enabled(target, i)) { - LOG_INFO(" hart %d: XLEN=%d, program buffer at 0x%" PRIx64 - ", %d triggers", i, r->xlen[i], r->debug_buffer_addr[i], + LOG_INFO(" hart %d: XLEN=%d, %d triggers", i, r->xlen[i], r->trigger_count[i]); } else { LOG_INFO(" hart %d: currently disabled", i); @@ -1296,6 +1259,7 @@ static int deassert_reset(struct target *target) return ERROR_OK; } +#if 0 static void write_to_buf(uint8_t *buffer, uint64_t value, unsigned size) { switch (size) { @@ -1316,6 +1280,7 @@ static void write_to_buf(uint8_t *buffer, uint64_t value, unsigned size) assert(false); } } +#endif /** * Read the requested memory, taking care to execute every read exactly once, @@ -1324,7 +1289,7 @@ static void write_to_buf(uint8_t *buffer, uint64_t value, unsigned size) static int read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) { - RISCV013_INFO(info); + //RISCV013_INFO(info); LOG_DEBUG("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR, count, size, address); @@ -1342,6 +1307,8 @@ static int read_memory(struct target *target, target_addr_t address, struct riscv_program program; riscv_program_init(&program, target); + assert(0); +#if 0 riscv_addr_t r_data = riscv_program_alloc_w(&program); riscv_addr_t r_addr = riscv_program_alloc_x(&program); riscv_program_fence(&program); @@ -1496,6 +1463,7 @@ static int read_memory(struct target *target, target_addr_t address, riscv_addr_t addr = cur_addr - size; write_to_buf(buffer + addr - address, value, size); LOG_DEBUG("M[0x%" TARGET_PRIxADDR "] reads 0x%08x", addr, value); +#endif riscv_set_register(target, GDB_REGNO_S0, s0); riscv_set_register(target, GDB_REGNO_S1, s1); @@ -1505,7 +1473,7 @@ static int read_memory(struct target *target, target_addr_t address, static int write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { - RISCV013_INFO(info); + //RISCV013_INFO(info); LOG_DEBUG("writing %d words of %d bytes to 0x%08lx", count, size, (long)address); @@ -1522,6 +1490,8 @@ static int write_memory(struct target *target, target_addr_t address, struct riscv_program program; riscv_program_init(&program, target); + assert(0); +#if 0 riscv_addr_t r_data = riscv_program_alloc_w(&program); riscv_addr_t r_addr = riscv_program_alloc_x(&program); riscv_program_fence(&program); @@ -1682,6 +1652,7 @@ static int write_memory(struct target *target, target_addr_t address, } riscv013_set_autoexec(target, d_data, 0); +#endif riscv_set_register(target, GDB_REGNO_S0, s0); riscv_set_register(target, GDB_REGNO_S1, s1); return ERROR_OK; @@ -1992,13 +1963,16 @@ static void riscv013_step_or_resume_current_hart(struct target *target, bool ste abort(); } +#if 0 riscv_addr_t riscv013_progbuf_addr(struct target *target) { RISCV013_INFO(info); assert(info->progbuf_addr != -1); return info->progbuf_addr; } +#endif +#if 0 riscv_addr_t riscv013_data_size(struct target *target) { RISCV013_INFO(info); @@ -2008,7 +1982,9 @@ riscv_addr_t riscv013_data_size(struct target *target) } return info->data_size; } +#endif +#if 0 riscv_addr_t riscv013_data_addr(struct target *target) { RISCV013_INFO(info); @@ -2018,7 +1994,9 @@ riscv_addr_t riscv013_data_addr(struct target *target) } return info->data_addr; } +#endif +#if 0 void riscv013_set_autoexec(struct target *target, unsigned index, bool enabled) { RISCV013_INFO(info); @@ -2040,7 +2018,9 @@ void riscv013_set_autoexec(struct target *target, unsigned index, bool enabled) dmi_write(target, DMI_ABSTRACTAUTO, aa); } } +#endif +#if 0 int riscv013_debug_buffer_register(struct target *target, riscv_addr_t addr) { if (addr >= riscv013_data_addr(target)) @@ -2069,3 +2049,4 @@ void riscv013_clear_abstract_error(struct target *target) // Clear the error status. dmi_write(target, DMI_ABSTRACTCS, abstractcs & DMI_ABSTRACTCS_CMDERR); } +#endif diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index a8fc437..80ecfff 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1235,7 +1235,6 @@ void riscv_info_init(struct target *target, riscv_info_t *r) for (size_t h = 0; h < RISCV_MAX_HARTS; ++h) { r->xlen[h] = -1; - r->debug_buffer_addr[h] = -1; for (size_t e = 0; e < RISCV_MAX_REGISTERS; ++e) r->valid_saved_registers[h][e] = false; @@ -1483,14 +1482,6 @@ size_t riscv_debug_buffer_size(struct target *target) return r->debug_buffer_size[riscv_current_hartid(target)]; } -riscv_addr_t riscv_debug_buffer_addr(struct target *target) -{ - RISCV_INFO(r); - riscv_addr_t out = r->debug_buffer_addr[riscv_current_hartid(target)]; - assert((out & 3) == 0); - return out; -} - int riscv_debug_buffer_enter(struct target *target, struct riscv_program *program) { RISCV_INFO(r); diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 1197cbf..192d5c9 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -72,9 +72,6 @@ typedef struct { * target controls, while otherwise only a single hart is controlled. */ int trigger_unique_id[RISCV_MAX_HWBPS]; - /* The address of the debug RAM buffer. */ - riscv_addr_t debug_buffer_addr[RISCV_MAX_HARTS]; - /* The number of entries in the debug buffer. */ int debug_buffer_size[RISCV_MAX_HARTS]; @@ -213,7 +210,6 @@ int riscv_count_triggers_of_hart(struct target *target, int hartid); /* These helper functions let the generic program interface get target-specific * information. */ size_t riscv_debug_buffer_size(struct target *target); -riscv_addr_t riscv_debug_buffer_addr(struct target *target); int riscv_debug_buffer_enter(struct target *target, struct riscv_program *program); int riscv_debug_buffer_leave(struct target *target, struct riscv_program *program); |