diff --git a/src/helper/log.h b/src/helper/log.h index d60587f72..43f67512c 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -151,6 +151,7 @@ extern int debug_level; #define ERROR_WAIT (-5) /* ERROR_TIMEOUT is already taken by winerror.h. */ #define ERROR_TIMEOUT_REACHED (-6) +#define ERROR_NOT_IMPLEMENTED (-7) #endif /* OPENOCD_HELPER_LOG_H */ diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index 61dd3388f..d36336927 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -39,6 +39,10 @@ static int hwthread_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[] static int hwthread_smp_init(struct target *target); int hwthread_set_reg(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value); bool hwthread_needs_fake_step(struct target *target, int64_t thread_id); +int hwthread_read_buffer(struct rtos *rtos, target_addr_t address, + uint32_t size, uint8_t *buffer); +int hwthread_write_buffer(struct rtos *rtos, target_addr_t address, + uint32_t size, const uint8_t *buffer); #define HW_THREAD_NAME_STR_SIZE (32) @@ -59,7 +63,9 @@ const struct rtos_type hwthread_rtos = { .get_symbol_list_to_lookup = hwthread_get_symbol_list_to_lookup, .smp_init = hwthread_smp_init, .set_reg = hwthread_set_reg, - .needs_fake_step = hwthread_needs_fake_step + .needs_fake_step = hwthread_needs_fake_step, + .read_buffer = hwthread_read_buffer, + .write_buffer = hwthread_write_buffer, }; struct hwthread_params { @@ -393,3 +399,33 @@ bool hwthread_needs_fake_step(struct target *target, int64_t thread_id) { return false; } + +int hwthread_read_buffer(struct rtos *rtos, target_addr_t address, + uint32_t size, uint8_t *buffer) +{ + if (rtos == NULL) + return ERROR_FAIL; + + struct target *target = rtos->target; + + struct target *curr = find_thread(target, rtos->current_thread); + if (curr == NULL) + return ERROR_FAIL; + + return target_read_buffer(curr, address, size, buffer); +} + +int hwthread_write_buffer(struct rtos *rtos, target_addr_t address, + uint32_t size, const uint8_t *buffer) +{ + if (rtos == NULL) + return ERROR_FAIL; + + struct target *target = rtos->target; + + struct target *curr = find_thread(target, rtos->current_thread); + if (curr == NULL) + return ERROR_FAIL; + + return target_write_buffer(curr, address, size, buffer); +} diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index b402f2d80..6b7c9e2ce 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -680,3 +680,19 @@ bool rtos_needs_fake_step(struct target *target, int64_t thread_id) return target->rtos->type->needs_fake_step(target, thread_id); return target->rtos->current_thread != thread_id; } + +int rtos_read_buffer(struct target *target, target_addr_t address, + uint32_t size, uint8_t *buffer) +{ + if (target->rtos->type->read_buffer) + return target->rtos->type->read_buffer(target->rtos, address, size, buffer); + return ERROR_NOT_IMPLEMENTED; +} + +int rtos_write_buffer(struct target *target, target_addr_t address, + uint32_t size, const uint8_t *buffer) +{ + if (target->rtos->type->write_buffer) + return target->rtos->type->write_buffer(target->rtos, address, size, buffer); + return ERROR_NOT_IMPLEMENTED; +} diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h index d0c20509e..ee9d4d4a5 100644 --- a/src/rtos/rtos.h +++ b/src/rtos/rtos.h @@ -90,6 +90,13 @@ struct rtos_type { * target running a multi-threading OS. If an RTOS can do this, override * needs_fake_step(). */ bool (*needs_fake_step)(struct target *target, int64_t thread_id); + /* Implement these if different threads in the RTOS can see memory + * differently (for instance because address translation might be different + * for each thread). */ + int (*read_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, + uint8_t *buffer); + int (*write_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, + const uint8_t *buffer); }; struct stack_register_offset { @@ -136,5 +143,9 @@ int rtos_smp_init(struct target *target); /* function for handling symbol access */ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size); bool rtos_needs_fake_step(struct target *target, int64_t thread_id); +int rtos_read_buffer(struct target *target, target_addr_t address, + uint32_t size, uint8_t *buffer); +int rtos_write_buffer(struct target *target, target_addr_t address, + uint32_t size, const uint8_t *buffer); #endif /* OPENOCD_RTOS_RTOS_H */ diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index d4ad72dad..755463c42 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1425,7 +1425,7 @@ static int gdb_read_memory_packet(struct connection *connection, uint8_t *buffer; char *hex_buffer; - int retval = ERROR_OK; + int retval; /* skip command character */ packet++; @@ -1449,7 +1449,11 @@ static int gdb_read_memory_packet(struct connection *connection, LOG_DEBUG("addr: 0x%16.16" PRIx64 ", len: 0x%8.8" PRIx32 "", addr, len); - retval = target_read_buffer(target, addr, len, buffer); + retval = ERROR_NOT_IMPLEMENTED; + if (target->rtos != NULL) + retval = rtos_read_buffer(target, addr, len, buffer); + if (retval == ERROR_NOT_IMPLEMENTED) + retval = target_read_buffer(target, addr, len, buffer); if ((retval != ERROR_OK) && !gdb_report_data_abort) { /* TODO : Here we have to lie and send back all zero's lest stack traces won't work. @@ -1520,7 +1524,11 @@ static int gdb_write_memory_packet(struct connection *connection, if (unhexify(buffer, separator, len) != len) LOG_ERROR("unable to decode memory packet"); - retval = target_write_buffer(target, addr, len, buffer); + retval = ERROR_NOT_IMPLEMENTED; + if (target->rtos != NULL) + retval = rtos_write_buffer(target, addr, len, buffer); + if (retval == ERROR_NOT_IMPLEMENTED) + retval = target_write_buffer(target, addr, len, buffer); if (retval == ERROR_OK) gdb_put_packet(connection, "OK", 2); @@ -1589,7 +1597,12 @@ static int gdb_write_memory_binary_packet(struct connection *connection, if (len) { LOG_DEBUG("addr: 0x%" PRIx64 ", len: 0x%8.8" PRIx32 "", addr, len); - retval = target_write_buffer(target, addr, len, (uint8_t *)separator); + retval = ERROR_NOT_IMPLEMENTED; + if (target->rtos != NULL) + retval = rtos_write_buffer(target, addr, len, (uint8_t *)separator); + if (retval == ERROR_NOT_IMPLEMENTED) + retval = target_write_buffer(target, addr, len, (uint8_t *)separator); + if (retval != ERROR_OK) gdb_connection->mem_write_error = true; }