This is an automated email from Gerrit. Ivan De Cesaris ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/2290
-- gerrit commit cbcb2695ab89b48741674372ee0f70e73617c1b4 Author: Ivan De Cesaris <[email protected]> Date: Mon Sep 8 14:25:31 2014 +0200 quark_x10xx: add soft_reset_halt First enable the reset break by setting the proper bits in the CLTAP and then issue the actual reset by writing 0x6 to port 0xcf9. Remove break/watchpoints after the reset as the memory layout is probably different and just reenabling them won't give the desired effect. Tested on the original Galileo and on the Gen 2. Change-Id: I54a8d127251be0fa48e9f4d8c94d7fbbf57c58be Signed-off-by: Ivan De Cesaris <[email protected]> Signed-off-by: Jessica Gomez <[email protected]> diff --git a/src/target/lakemont.c b/src/target/lakemont.c index 17b0c12..fd8a3e0 100644 --- a/src/target/lakemont.c +++ b/src/target/lakemont.c @@ -6,6 +6,7 @@ * Ivan De Cesaris ([email protected]) * Julien Carreno ([email protected]) * Jeffrey Maxwell ([email protected]) + * Jessica Gomez ([email protected]) * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -510,8 +511,7 @@ static int halt_prep(struct target *t) LOG_DEBUG("EFLAGS = 0x%08" PRIx32 ", VM86 = %d, IF = %d", eflags, eflags & EFLAGS_VM86 ? 1 : 0, eflags & EFLAGS_IF ? 1 : 0); - if (eflags & EFLAGS_VM86 - || eflags & EFLAGS_IF) { + if ((eflags & EFLAGS_VM86) || (eflags & EFLAGS_IF)) { x86_32->pm_regs[I(EFLAGS)] = eflags & ~(EFLAGS_VM86 | EFLAGS_IF); if (write_hw_reg(t, EFLAGS, x86_32->pm_regs[I(EFLAGS)], 0) != ERROR_OK) return ERROR_FAIL; @@ -562,6 +562,13 @@ static int do_halt(struct target *t) t->state = TARGET_DEBUG_RUNNING; if (enter_probemode(t) != ERROR_OK) return ERROR_FAIL; + + return lakemont_update_after_probemode_entry(t); +} + +/* we need to expose the update to be able to complete the reset at SoC level */ +int lakemont_update_after_probemode_entry(struct target *t) +{ if (save_context(t) != ERROR_OK) return ERROR_FAIL; if (halt_prep(t) != ERROR_OK) @@ -1098,7 +1105,6 @@ int lakemont_step(struct target *t, int current, return retval; } -/* TODO - implement resetbreak fully through CLTAP registers */ int lakemont_reset_assert(struct target *t) { LOG_DEBUG("-"); diff --git a/src/target/lakemont.h b/src/target/lakemont.h index e5729ae..d369ecb 100644 --- a/src/target/lakemont.h +++ b/src/target/lakemont.h @@ -6,6 +6,7 @@ * Ivan De Cesaris ([email protected]) * Julien Carreno ([email protected]) * Jeffrey Maxwell ([email protected]) + * Jessica Gomez ([email protected]) * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -91,6 +92,7 @@ struct scan_blk { int lakemont_init_target(struct command_context *cmd_ctx, struct target *t); int lakemont_init_arch_info(struct target *t, struct x86_32_common *x86_32); +int lakemont_update_after_probemode_entry(struct target *t); int lakemont_poll(struct target *t); int lakemont_arch_state(struct target *t); int lakemont_halt(struct target *t); diff --git a/src/target/quark_x10xx.c b/src/target/quark_x10xx.c index 05818b7..0a9229d 100644 --- a/src/target/quark_x10xx.c +++ b/src/target/quark_x10xx.c @@ -6,6 +6,7 @@ * Ivan De Cesaris ([email protected]) * Julien Carreno ([email protected]) * Jeffrey Maxwell ([email protected]) + * Jessica Gomez ([email protected]) * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -37,7 +38,7 @@ * Intel Quark SoC X1000 Debug Operations User Guide (web search for doc num 329866) * Intel Quark SoC X1000 Datasheet (web search for doc num 329676) * - * This file implements any Quark SoC specific features such as resetbreak (TODO) + * This file implements any Quark SoC specific features, such as resetbreak. */ #ifdef HAVE_CONFIG_H @@ -68,11 +69,95 @@ int quark_x10xx_init_target(struct command_context *cmd_ctx, struct target *t) return lakemont_init_target(cmd_ctx, t); } +/* + * issue a system reset using the 0xcf9 I/O port and then break (this is the + * closest we can get to a proper reset break without a connected srst pin). +*/ +static int quark_x10xx_target_reset(struct target *t) +{ + LOG_DEBUG("issuing port 0xcf9 reset"); + struct x86_32_common *x86_32 = target_to_x86_32(t); + int retval = ERROR_OK; + + /* we can't be running when issuing an I/O port write */ + if (t->state == TARGET_RUNNING) { + retval = lakemont_halt(t); + if (retval != ERROR_OK) { + LOG_ERROR("%s could not halt target", __func__); + return retval; + } + } + + /* save current tap so we can restore it later */ + struct jtag_tap *saved_tap = x86_32->curr_tap; + + /* prepare resetbreak setting the proper bits in CLTAPC_CPU_VPREQ */ + x86_32->curr_tap = jtag_tap_by_string("quark_x10xx.cltap"); + if (x86_32->curr_tap == NULL) { + x86_32->curr_tap = saved_tap; + LOG_ERROR("%s could not select quark_x10xx.cltap", __func__); + return ERROR_FAIL; + } + + static struct scan_blk scan; + struct scan_field *fields = &scan.field; + fields->in_value = NULL; + fields->num_bits = 8; + + /* select CLTAPC_CPU_VPREQ instruction*/ + scan.out[0] = 0x51; + fields->out_value = ((uint8_t *)scan.out); + jtag_add_ir_scan(x86_32->curr_tap, fields, TAP_IDLE); + retval = jtag_execute_queue(); + if (retval != ERROR_OK) { + x86_32->curr_tap = saved_tap; + LOG_ERROR("%s irscan failed to execute queue", __func__); + return retval; + } + + /* set enable_preq_on_reset & enable_preq_on_reset2 bits*/ + scan.out[0] = 0x06; + fields->out_value = ((uint8_t *)scan.out); + jtag_add_dr_scan(x86_32->curr_tap, 1, fields, TAP_IDLE); + retval = jtag_execute_queue(); + if (retval != ERROR_OK) { + LOG_ERROR("%s drscan failed to execute queue", __func__); + x86_32->curr_tap = saved_tap; + return retval; + } + + /* restore current tap */ + x86_32->curr_tap = saved_tap; + + /* write 0x6 to I/O port 0xcf9 to cause the reset */ + const uint8_t cf9_reset_val[] = { 0x6 }; + + retval = x86_32_common_write_io(t, (uint32_t)0xcf9, BYTE, cf9_reset_val); + if (retval != ERROR_OK) { + LOG_ERROR("%s could not write to port 0xcf9", __func__); + return retval; + } + + /* entered PM after reset, update the state */ + retval = lakemont_update_after_probemode_entry(t); + if (retval != ERROR_OK) { + LOG_ERROR("%s could not update state after probemode entry", __func__); + return retval; + } + + /* remove breakpoints and watchpoints */ + x86_32_common_reset_breakpoints_watchpoints(t); + + return ERROR_OK; + +} + struct target_type quark_x10xx_target = { .name = "quark_x10xx", /* Quark X1000 SoC */ - .target_create = quark_x10xx_target_create, - .init_target = quark_x10xx_init_target, + .target_create = quark_x10xx_target_create, + .soft_reset_halt = quark_x10xx_target_reset, + .init_target = quark_x10xx_init_target, /* lakemont probemode specific code */ .poll = lakemont_poll, .arch_state = lakemont_arch_state, diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c index 6bcd4af..d2eadf1 100644 --- a/src/target/x86_32_common.c +++ b/src/target/x86_32_common.c @@ -6,6 +6,7 @@ * Ivan De Cesaris ([email protected]) * Julien Carreno ([email protected]) * Jeffrey Maxwell ([email protected]) + * Jessica Gomez ([email protected]) * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -769,7 +770,7 @@ int x86_32_common_write_io(struct target *t, uint32_t addr, LOG_ERROR("%s invalid params buf=%p, addr=0x%08" PRIx32, __func__, buf, addr); return retval; } - /* no do the write */ + /* now do the write */ retval = x86_32->write_hw_reg(t, EDX, addr, 0); if (retval != ERROR_OK) { LOG_ERROR("%s error on EDX write", __func__); @@ -1215,6 +1216,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp) break; default: LOG_ERROR("%s only 'access' or 'write' watchpoints are supported", __func__); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; break; } wp->set = wp_num + 1; @@ -1257,6 +1259,36 @@ 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; diff --git a/src/target/x86_32_common.h b/src/target/x86_32_common.h index 83973b8..bb769f0 100644 --- a/src/target/x86_32_common.h +++ b/src/target/x86_32_common.h @@ -6,6 +6,7 @@ * Ivan De Cesaris ([email protected]) * Julien Carreno ([email protected]) * Jeffrey Maxwell ([email protected]) + * Jessica Gomez ([email protected]) * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -320,5 +321,6 @@ int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp); int x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp); int x86_32_common_add_watchpoint(struct target *t, struct watchpoint *wp); int x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp); +void x86_32_common_reset_breakpoints_watchpoints(struct target *t); #endif /* X86_32_COMMON_H */ -- ------------------------------------------------------------------------------ Want excitement? Manually upgrade your production database. When you want reliability, choose Perforce Perforce version control. Predictably reliable. http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
