diff options
author | Ivan De Cesaris <ivan.de.cesaris@intel.com> | 2016-01-12 16:30:18 +0100 |
---|---|---|
committer | Andreas Fritiofson <andreas.fritiofson@gmail.com> | 2016-02-13 22:55:41 +0000 |
commit | a4ce9a2c719b1f7536ada1c9fa8f1eb672b04897 (patch) | |
tree | 3e57cd84810f6bb309d29202c40a26af67567cb9 /src | |
parent | 3e07e1cdfac63d5fb93260803d16e79f292dae73 (diff) |
quark: add Intel Quark mcu D2000 support
Add support for the Intel Quark mcu D2000 using the new quark_d2xx
target.
Changes to the lakemont part are needed for the D2000 core and
backwards compatible with the X1000 one.
Change-Id: I6e1ef5a5d116344942f08e413965abd3945235fa
Signed-off-by: Ivan De Cesaris <ivan.de.cesaris@intel.com>
Reviewed-on: http://openocd.zylin.com/3199
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/target/Makefile.am | 1 | ||||
-rw-r--r-- | src/target/lakemont.c | 35 | ||||
-rw-r--r-- | src/target/lakemont.h | 3 | ||||
-rw-r--r-- | src/target/quark_d20xx.c | 112 | ||||
-rw-r--r-- | src/target/quark_x10xx.c | 3 | ||||
-rw-r--r-- | src/target/target.c | 2 | ||||
-rw-r--r-- | src/target/x86_32_common.h | 8 |
7 files changed, 150 insertions, 14 deletions
diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 9f47b1fd..1f4cbba4 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -129,6 +129,7 @@ NDS32_SRC = \ INTEL_IA32_SRC = \ quark_x10xx.c \ + quark_d20xx.c \ lakemont.c \ x86_32_common.c diff --git a/src/target/lakemont.c b/src/target/lakemont.c index 055d9434..151f4abe 100644 --- a/src/target/lakemont.c +++ b/src/target/lakemont.c @@ -1,11 +1,12 @@ /* - * Copyright(c) 2013 Intel Corporation. + * Copyright(c) 2013-2016 Intel Corporation. * * Adrian Burns (adrian.burns@intel.com) * Thomas Faust (thomas.faust@intel.com) * Ivan De Cesaris (ivan.de.cesaris@intel.com) * Julien Carreno (julien.carreno@intel.com) * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com) + * Jessica Gomez (jessica.gomez.hernandez@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -498,6 +499,12 @@ static int halt_prep(struct target *t) if (write_hw_reg(t, DSAR, PM_DSAR, 0) != ERROR_OK) return ERROR_FAIL; LOG_DEBUG("write DSAR 0x%08" PRIx32, PM_DSAR); + if (write_hw_reg(t, CSB, PM_DSB, 0) != ERROR_OK) + return ERROR_FAIL; + LOG_DEBUG("write %s 0x%08" PRIx32, regs[CSB].name, PM_DSB); + if (write_hw_reg(t, CSL, PM_DSL, 0) != ERROR_OK) + return ERROR_FAIL; + LOG_DEBUG("write %s 0x%08" PRIx32, regs[CSL].name, PM_DSL); if (write_hw_reg(t, DR7, PM_DR7, 0) != ERROR_OK) return ERROR_FAIL; LOG_DEBUG("write DR7 0x%08" PRIx32, PM_DR7); @@ -511,8 +518,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; @@ -530,14 +536,14 @@ static int halt_prep(struct target *t) LOG_DEBUG("write CSAR_CPL to 0 0x%08" PRIx32, x86_32->pm_regs[I(CSAR)]); } if (ssar & SSAR_DPL) { - x86_32->pm_regs[I(SSAR)] = ssar & ~CSAR_DPL; + x86_32->pm_regs[I(SSAR)] = ssar & ~SSAR_DPL; if (write_hw_reg(t, SSAR, x86_32->pm_regs[I(SSAR)], 0) != ERROR_OK) return ERROR_FAIL; LOG_DEBUG("write SSAR_CPL to 0 0x%08" PRIx32, x86_32->pm_regs[I(SSAR)]); } - /* if cache's are enabled, disable and flush */ - if (!(cr0 & CR0_CD)) { + /* if cache's are enabled, disable and flush, depending on the core version */ + if (!(x86_32->core_type == LMT3_5) && !(cr0 & CR0_CD)) { LOG_DEBUG("caching enabled CR0 = 0x%08" PRIx32, cr0); if (cr0 & CR0_PG) { x86_32->pm_regs[I(CR0)] = cr0 & ~CR0_PG; @@ -563,6 +569,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) @@ -677,16 +690,16 @@ static int write_hw_reg(struct target *t, int reg, uint32_t regval, uint8_t cach arch_info->op, regval); - scan.out[0] = RDWRPDR; x86_32->flush = 0; /* dont flush scans till we have a batch */ - if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) - return ERROR_FAIL; - if (drscan(t, reg_buf, scan.out, PDR_SIZE) != ERROR_OK) - return ERROR_FAIL; if (submit_reg_pir(t, reg) != ERROR_OK) return ERROR_FAIL; if (submit_instruction_pir(t, SRAMACCESS) != ERROR_OK) return ERROR_FAIL; + scan.out[0] = RDWRPDR; + if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) + return ERROR_FAIL; + if (drscan(t, reg_buf, scan.out, PDR_SIZE) != ERROR_OK) + return ERROR_FAIL; x86_32->flush = 1; if (submit_instruction_pir(t, PDR2SRAM) != ERROR_OK) return ERROR_FAIL; diff --git a/src/target/lakemont.h b/src/target/lakemont.h index 30b34b3f..1075ad31 100644 --- a/src/target/lakemont.h +++ b/src/target/lakemont.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2013 Intel Corporation. + * Copyright(c) 2013-2016 Intel Corporation. * * Adrian Burns (adrian.burns@intel.com) * Thomas Faust (thomas.faust@intel.com) @@ -101,5 +101,6 @@ int lakemont_step(struct target *t, int current, uint32_t address, int handle_breakpoints); int lakemont_reset_assert(struct target *t); int lakemont_reset_deassert(struct target *t); +int lakemont_update_after_probemode_entry(struct target *t); #endif /* LAKEMONT_H */ diff --git a/src/target/quark_d20xx.c b/src/target/quark_d20xx.c new file mode 100644 index 00000000..f7972141 --- /dev/null +++ b/src/target/quark_d20xx.c @@ -0,0 +1,112 @@ +/* + * Copyright(c) 2015-2016 Intel Corporation. + * + * Jessica Gomez (jessica.gomez.hernandez@intel.com) + * Ivan De Cesaris (ivan.de.cesaris@intel.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Contact Information: + * Intel Corporation + */ + +/* + * @file + * Debugger for Intel Quark D20xx + * The CPU TAP (Lakemont TAP) is used for software debug and the CLTAP is + * used for SoC level operations. + * + * Reference document: + * Intel Quark microcontroller D2000 Debug Operations (web search for doc num 333241) + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <helper/log.h> + +#include "target.h" +#include "target_type.h" +#include "breakpoints.h" +#include "lakemont.h" +#include "x86_32_common.h" + +int quark_d20xx_target_create(struct target *t, Jim_Interp *interp) +{ + struct x86_32_common *x86_32 = calloc(1, sizeof(struct x86_32_common)); + if (x86_32 == NULL) { + LOG_ERROR("%s out of memory", __func__); + return ERROR_FAIL; + } + x86_32_common_init_arch_info(t, x86_32); + lakemont_init_arch_info(t, x86_32); + x86_32->core_type = LMT3_5; + return ERROR_OK; +} + +int quark_d20xx_init_target(struct command_context *cmd_ctx, struct target *t) +{ + return lakemont_init_target(cmd_ctx, t); +} + +static int quark_d20xx_reset_deassert(struct target *t) +{ + int retval; + + /* Can't detect if a warm reset happened while halted but we can make the + * openocd and target state consistent here if in probe mode already + */ + if (!check_not_halted(t)) { + retval = lakemont_update_after_probemode_entry(t); + if (retval != ERROR_OK) { + LOG_ERROR("%s core state update fail", __func__); + return retval; + } + /* resume target if reset mode is run */ + if (!t->reset_halt) { + retval = lakemont_resume(t, 1, 0, 0, 0); + if (retval != ERROR_OK) { + LOG_ERROR("%s could not resume target", __func__); + return retval; + } + } + } + + return ERROR_OK; +} + +struct target_type quark_d20xx_target = { + .name = "quark_d20xx", + .target_create = quark_d20xx_target_create, + .init_target = quark_d20xx_init_target, + /* lakemont probemode specific code */ + .poll = lakemont_poll, + .arch_state = lakemont_arch_state, + .halt = lakemont_halt, + .resume = lakemont_resume, + .step = lakemont_step, + .assert_reset = lakemont_reset_assert, + .deassert_reset = quark_d20xx_reset_deassert, + /* common x86 code */ + .commands = x86_32_command_handlers, + .get_gdb_reg_list = x86_32_get_gdb_reg_list, + .read_memory = x86_32_common_read_memory, + .write_memory = x86_32_common_write_memory, + .add_breakpoint = x86_32_common_add_breakpoint, + .remove_breakpoint = x86_32_common_remove_breakpoint, + .add_watchpoint = x86_32_common_add_watchpoint, + .remove_watchpoint = x86_32_common_remove_watchpoint, + .virt2phys = x86_32_common_virt2phys, + .read_phys_memory = x86_32_common_read_phys_mem, + .write_phys_memory = x86_32_common_write_phys_mem, + .mmu = x86_32_common_mmu, +}; diff --git a/src/target/quark_x10xx.c b/src/target/quark_x10xx.c index 9a1ccb65..a3b8a266 100644 --- a/src/target/quark_x10xx.c +++ b/src/target/quark_x10xx.c @@ -1,5 +1,5 @@ /* - * Copyright(c) 2013 Intel Corporation. + * Copyright(c) 2013-2016 Intel Corporation. * * Adrian Burns (adrian.burns@intel.com) * Thomas Faust (thomas.faust@intel.com) @@ -61,6 +61,7 @@ int quark_x10xx_target_create(struct target *t, Jim_Interp *interp) } x86_32_common_init_arch_info(t, x86_32); lakemont_init_arch_info(t, x86_32); + x86_32->core_type = LMT1; return ERROR_OK; } diff --git a/src/target/target.c b/src/target/target.c index 598d7d5a..6df8d8b9 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -104,6 +104,7 @@ extern struct target_type nds32_v3_target; extern struct target_type nds32_v3m_target; extern struct target_type or1k_target; extern struct target_type quark_x10xx_target; +extern struct target_type quark_d20xx_target; static struct target_type *target_types[] = { &arm7tdmi_target, @@ -133,6 +134,7 @@ static struct target_type *target_types[] = { &nds32_v3m_target, &or1k_target, &quark_x10xx_target, + &quark_d20xx_target, NULL, }; diff --git a/src/target/x86_32_common.h b/src/target/x86_32_common.h index af57a5f7..c9cb389b 100644 --- a/src/target/x86_32_common.h +++ b/src/target/x86_32_common.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2013 Intel Corporation. + * Copyright(c) 2013-2016 Intel Corporation. * * Adrian Burns (adrian.burns@intel.com) * Thomas Faust (thomas.faust@intel.com) @@ -196,6 +196,11 @@ enum { WBINVD, }; +enum x86_core_type { + LMT1, + LMT3_5 +}; + struct swbp_mem_patch { uint8_t orig_byte; uint32_t swbp_unique_id; @@ -209,6 +214,7 @@ struct swbp_mem_patch { struct x86_32_common { uint32_t common_magic; void *arch_info; + enum x86_core_type core_type; struct reg_cache *cache; struct jtag_tap *curr_tap; uint32_t stored_pc; |