X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fx86_32_common.c;h=b85e451194e141554227416ff38a927caf0edd70;hb=762ddcb74948852b0dfb25fcbca0965b09249a2f;hp=34f92eaca81d2deff7f1ef833854757f6c47aa9a;hpb=47b8cf84202bf792cf66fbfa01169e9592236b8a;p=openocd.git diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c index 34f92eaca8..b85e451194 100644 --- a/src/target/x86_32_common.c +++ b/src/target/x86_32_common.c @@ -209,15 +209,16 @@ static int read_phys_mem(struct target *t, uint32_t phys_address, LOG_ERROR("%s invalid read size", __func__); break; } + if (retval != ERROR_OK) + break; } /* restore CR0.PG bit if needed (regardless of retval) */ if (pg_disabled) { - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { + int retval2 = x86_32->enable_paging(t); + if (retval2 != ERROR_OK) { LOG_ERROR("%s could not enable paging", __func__); - return retval; + return retval2; } - pg_disabled = true; } /* TODO: After reading memory from target, we must replace * software breakpoints with the original instructions again. @@ -364,6 +365,9 @@ static int read_mem(struct target *t, uint32_t size, break; } + if (retval != ERROR_OK) + return retval; + /* read_hw_reg() will write to 4 bytes (uint32_t) * Watch out, the buffer passed into read_mem() might be 1 or 2 bytes. */ @@ -436,6 +440,10 @@ static int write_mem(struct target *t, uint32_t size, LOG_ERROR("%s invalid write mem size", __func__); return ERROR_FAIL; } + + if (retval != ERROR_OK) + return retval; + retval = x86_32->transaction_status(t); if (retval != ERROR_OK) { LOG_ERROR("%s error on mem write", __func__); @@ -606,7 +614,6 @@ int x86_32_common_read_memory(struct target *t, target_addr_t addr, && x86_32_common_read_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) { LOG_ERROR("%s failed to read memory from physical address " TARGET_ADDR_FMT, __func__, physaddr); - retval = ERROR_FAIL; } /* restore PG bit if it was cleared prior (regardless of retval) */ retval = x86_32->enable_paging(t); @@ -662,7 +669,6 @@ int x86_32_common_write_memory(struct target *t, target_addr_t addr, && x86_32_common_write_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) { LOG_ERROR("%s failed to write memory to physical address " TARGET_ADDR_FMT, __func__, physaddr); - retval = ERROR_FAIL; } /* restore PG bit if it was cleared prior (regardless of retval) */ retval = x86_32->enable_paging(t); @@ -733,15 +739,19 @@ int x86_32_common_read_io(struct target *t, uint32_t addr, LOG_ERROR("%s invalid read io size", __func__); return ERROR_FAIL; } + /* restore CR0.PG bit if needed */ if (pg_disabled) { - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { + int retval2 = x86_32->enable_paging(t); + if (retval2 != ERROR_OK) { LOG_ERROR("%s could not enable paging", __func__); - return retval; + return retval2; } - pg_disabled = false; } + + if (retval != ERROR_OK) + return retval; + uint32_t regval = 0; retval = x86_32->read_hw_reg(t, EAX, ®val, 0); if (retval != ERROR_OK) { @@ -818,15 +828,19 @@ int x86_32_common_write_io(struct target *t, uint32_t addr, LOG_ERROR("%s invalid write io size", __func__); return ERROR_FAIL; } + /* restore CR0.PG bit if needed */ if (pg_disabled) { - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { + int retval2 = x86_32->enable_paging(t); + if (retval2 != ERROR_OK) { LOG_ERROR("%s could not enable paging", __func__); - return retval; + return retval2; } - pg_disabled = false; } + + if (retval != ERROR_OK) + return retval; + retval = x86_32->transaction_status(t); if (retval != ERROR_OK) { LOG_ERROR("%s error on io write", __func__); @@ -925,14 +939,14 @@ static int set_debug_regs(struct target *t, uint32_t address, * when we exit PM */ buf_set_u32(x86_32->cache->reg_list[bp_num+DR0].value, 0, 32, address); - x86_32->cache->reg_list[bp_num+DR0].dirty = 1; - x86_32->cache->reg_list[bp_num+DR0].valid = 1; + x86_32->cache->reg_list[bp_num+DR0].dirty = true; + x86_32->cache->reg_list[bp_num+DR0].valid = true; buf_set_u32(x86_32->cache->reg_list[DR6].value, 0, 32, PM_DR6); - x86_32->cache->reg_list[DR6].dirty = 1; - x86_32->cache->reg_list[DR6].valid = 1; + x86_32->cache->reg_list[DR6].dirty = true; + x86_32->cache->reg_list[DR6].valid = true; buf_set_u32(x86_32->cache->reg_list[DR7].value, 0, 32, dr7); - x86_32->cache->reg_list[DR7].dirty = 1; - x86_32->cache->reg_list[DR7].valid = 1; + x86_32->cache->reg_list[DR7].dirty = true; + x86_32->cache->reg_list[DR7].valid = true; return ERROR_OK; } @@ -956,14 +970,14 @@ static int unset_debug_regs(struct target *t, uint8_t bp_num) * when we exit PM */ buf_set_u32(x86_32->cache->reg_list[bp_num+DR0].value, 0, 32, 0); - x86_32->cache->reg_list[bp_num+DR0].dirty = 1; - x86_32->cache->reg_list[bp_num+DR0].valid = 1; + x86_32->cache->reg_list[bp_num+DR0].dirty = true; + x86_32->cache->reg_list[bp_num+DR0].valid = true; buf_set_u32(x86_32->cache->reg_list[DR6].value, 0, 32, PM_DR6); - x86_32->cache->reg_list[DR6].dirty = 1; - x86_32->cache->reg_list[DR6].valid = 1; + x86_32->cache->reg_list[DR6].dirty = true; + x86_32->cache->reg_list[DR6].valid = true; buf_set_u32(x86_32->cache->reg_list[DR7].value, 0, 32, dr7); - x86_32->cache->reg_list[DR7].dirty = 1; - x86_32->cache->reg_list[DR7].valid = 1; + x86_32->cache->reg_list[DR7].dirty = true; + x86_32->cache->reg_list[DR7].valid = true; return ERROR_OK; } @@ -1141,7 +1155,6 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp) } } else { LOG_ERROR("%s core doesn't support SW breakpoints", __func__); - error = ERROR_FAIL; return ERROR_FAIL; } } @@ -1260,6 +1273,38 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp) return ERROR_OK; } +/* after reset breakpoints and watchpoints in memory are not valid anymore and + * debug registers are cleared. + * we can't afford to remove sw breakpoints using the default methods as the + * memory doesn't have the same layout yet and an access might crash the target, + * so we just clear the openocd breakpoints structures. + */ +void x86_32_common_reset_breakpoints_watchpoints(struct target *t) +{ + struct x86_32_common *x86_32 = target_to_x86_32(t); + struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list; + struct breakpoint *next_b; + struct watchpoint *next_w; + + while (t->breakpoints) { + next_b = t->breakpoints->next; + free(t->breakpoints->orig_instr); + free(t->breakpoints); + t->breakpoints = next_b; + } + + while (t->watchpoints) { + next_w = t->watchpoints->next; + free(t->watchpoints); + t->watchpoints = next_w; + } + + for (int i = 0; i < x86_32->num_hw_bpoints; i++) { + debug_reg_list[i].used = 0; + debug_reg_list[i].bp_value = 0; + } +} + static int read_hw_reg_to_cache(struct target *t, int num) { uint32_t reg_value; @@ -1295,7 +1340,7 @@ static int write_hw_reg_from_cache(struct target *t, int num) } /* x86 32 commands */ -static void handle_iod_output(struct command_context *cmd_ctx, +static void handle_iod_output(struct command_invocation *cmd, struct target *target, uint32_t address, unsigned size, unsigned count, const uint8_t *buffer) { @@ -1347,7 +1392,7 @@ static void handle_iod_output(struct command_context *cmd_ctx, value_fmt, value); if ((i % line_modulo == line_modulo - 1) || (i == count - 1)) { - command_print(cmd_ctx, "%s", output); + command_print(cmd, "%s", output); output_len = 0; } } @@ -1384,7 +1429,7 @@ COMMAND_HANDLER(handle_iod_command) struct target *target = get_current_target(CMD_CTX); int retval = x86_32_common_read_io(target, address, size, buffer); if (ERROR_OK == retval) - handle_iod_output(CMD_CTX, target, address, size, count, buffer); + handle_iod_output(CMD, target, address, size, count, buffer); free(buffer); return retval; }