Allow riscv_semihosting without 16 bit access to memory with instructions (#544)
* Allow riscv_semihosting without 16 bit access to memory with instrustions Signed-off-by: Samuel Obuch <sobuch@codasip.com> * rename *_by_any_size to riscv_*_by_any_size
This commit is contained in:
parent
fb477376da
commit
bc1d689e6d
|
@ -778,7 +778,7 @@ static int read_by_given_size(struct target *target, target_addr_t address,
|
||||||
* Write one memory item using any memory access size that will work.
|
* Write one memory item using any memory access size that will work.
|
||||||
* Utilize read-modify-write, if needed.
|
* Utilize read-modify-write, if needed.
|
||||||
* */
|
* */
|
||||||
static int write_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
|
int riscv_write_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
assert(size == 1 || size == 2 || size == 4 || size == 8);
|
assert(size == 1 || size == 2 || size == 4 || size == 8);
|
||||||
|
|
||||||
|
@ -810,7 +810,7 @@ static int write_by_any_size(struct target *target, target_addr_t address, uint3
|
||||||
* Read one memory item using any memory access size that will work.
|
* Read one memory item using any memory access size that will work.
|
||||||
* Read larger section of memory and pick out the required portion, if needed.
|
* Read larger section of memory and pick out the required portion, if needed.
|
||||||
* */
|
* */
|
||||||
static int read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
|
int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
assert(size == 1 || size == 2 || size == 4 || size == 8);
|
assert(size == 1 || size == 2 || size == 4 || size == 8);
|
||||||
|
|
||||||
|
@ -855,7 +855,7 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the original instruction. */
|
/* Read the original instruction. */
|
||||||
if (read_by_any_size(
|
if (riscv_read_by_any_size(
|
||||||
target, breakpoint->address, breakpoint->length, breakpoint->orig_instr) != ERROR_OK) {
|
target, breakpoint->address, breakpoint->length, breakpoint->orig_instr) != ERROR_OK) {
|
||||||
LOG_ERROR("Failed to read original instruction at 0x%" TARGET_PRIxADDR,
|
LOG_ERROR("Failed to read original instruction at 0x%" TARGET_PRIxADDR,
|
||||||
breakpoint->address);
|
breakpoint->address);
|
||||||
|
@ -865,7 +865,7 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
|
||||||
uint8_t buff[4] = { 0 };
|
uint8_t buff[4] = { 0 };
|
||||||
buf_set_u32(buff, 0, breakpoint->length * CHAR_BIT, breakpoint->length == 4 ? ebreak() : ebreak_c());
|
buf_set_u32(buff, 0, breakpoint->length * CHAR_BIT, breakpoint->length == 4 ? ebreak() : ebreak_c());
|
||||||
/* Write the ebreak instruction. */
|
/* Write the ebreak instruction. */
|
||||||
if (write_by_any_size(target, breakpoint->address, breakpoint->length, buff) != ERROR_OK) {
|
if (riscv_write_by_any_size(target, breakpoint->address, breakpoint->length, buff) != ERROR_OK) {
|
||||||
LOG_ERROR("Failed to write %d-byte breakpoint instruction at 0x%"
|
LOG_ERROR("Failed to write %d-byte breakpoint instruction at 0x%"
|
||||||
TARGET_PRIxADDR, breakpoint->length, breakpoint->address);
|
TARGET_PRIxADDR, breakpoint->length, breakpoint->address);
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
@ -937,7 +937,7 @@ int riscv_remove_breakpoint(struct target *target,
|
||||||
{
|
{
|
||||||
if (breakpoint->type == BKPT_SOFT) {
|
if (breakpoint->type == BKPT_SOFT) {
|
||||||
/* Write the original instruction. */
|
/* Write the original instruction. */
|
||||||
if (write_by_any_size(
|
if (riscv_write_by_any_size(
|
||||||
target, breakpoint->address, breakpoint->length, breakpoint->orig_instr) != ERROR_OK) {
|
target, breakpoint->address, breakpoint->length, breakpoint->orig_instr) != ERROR_OK) {
|
||||||
LOG_ERROR("Failed to restore instruction for %d-byte breakpoint at "
|
LOG_ERROR("Failed to restore instruction for %d-byte breakpoint at "
|
||||||
"0x%" TARGET_PRIxADDR, breakpoint->length, breakpoint->address);
|
"0x%" TARGET_PRIxADDR, breakpoint->length, breakpoint->address);
|
||||||
|
|
|
@ -414,4 +414,7 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval);
|
||||||
void riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field,
|
void riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field,
|
||||||
riscv_bscan_tunneled_scan_context_t *ctxt);
|
riscv_bscan_tunneled_scan_context_t *ctxt);
|
||||||
|
|
||||||
|
int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);
|
||||||
|
int riscv_write_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,12 +85,15 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval)
|
||||||
if (result != ERROR_OK)
|
if (result != ERROR_OK)
|
||||||
return SEMI_ERROR;
|
return SEMI_ERROR;
|
||||||
|
|
||||||
uint8_t tmp[12];
|
uint8_t tmp_buf[12];
|
||||||
|
|
||||||
/* Read the current instruction, including the bracketing */
|
/* Read three uncompressed instructions: The previous, the current one (pointed to by PC) and the next one */
|
||||||
*retval = target_read_memory(target, pc - 4, 2, 6, tmp);
|
for (int i = 0; i < 3; i++) {
|
||||||
if (*retval != ERROR_OK)
|
/* Instruction memories may not support arbitrary read size. Use any size that will work. */
|
||||||
return SEMI_ERROR;
|
*retval = riscv_read_by_any_size(target, (pc - 4) + 4 * i, 4, tmp_buf + 4 * i);
|
||||||
|
if (*retval != ERROR_OK)
|
||||||
|
return SEMI_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The instructions that trigger a semihosting call,
|
* The instructions that trigger a semihosting call,
|
||||||
|
@ -100,9 +103,9 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval)
|
||||||
* 00100073 ebreak
|
* 00100073 ebreak
|
||||||
* 40705013 srai zero,zero,0x7
|
* 40705013 srai zero,zero,0x7
|
||||||
*/
|
*/
|
||||||
uint32_t pre = target_buffer_get_u32(target, tmp);
|
uint32_t pre = target_buffer_get_u32(target, tmp_buf);
|
||||||
uint32_t ebreak = target_buffer_get_u32(target, tmp + 4);
|
uint32_t ebreak = target_buffer_get_u32(target, tmp_buf + 4);
|
||||||
uint32_t post = target_buffer_get_u32(target, tmp + 8);
|
uint32_t post = target_buffer_get_u32(target, tmp_buf + 8);
|
||||||
LOG_DEBUG("check %08x %08x %08x from 0x%" PRIx64 "-4", pre, ebreak, post, pc);
|
LOG_DEBUG("check %08x %08x %08x from 0x%" PRIx64 "-4", pre, ebreak, post, pc);
|
||||||
|
|
||||||
if (pre != 0x01f01013 || ebreak != 0x00100073 || post != 0x40705013) {
|
if (pre != 0x01f01013 || ebreak != 0x00100073 || post != 0x40705013) {
|
||||||
|
|
Loading…
Reference in New Issue