aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-10-12 11:45:52 -0700
committerTim Newsome <tim@sifive.com>2017-10-12 11:45:52 -0700
commit94e82507134610180843d70c8b244d98de26171a (patch)
treec28681383afc0e29379cf19b35f6139629df5b67 /src
parent77802af655fef154a1eff30d59e699c11917ecd2 (diff)
downloadriscv-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.c71
-rw-r--r--src/target/riscv/program.h16
-rw-r--r--src/target/riscv/riscv-013.c129
-rw-r--r--src/target/riscv/riscv.c9
-rw-r--r--src/target/riscv/riscv.h4
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);