From b411d805477bd67856403c73bad41534bcf2aa31 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 20 May 2019 17:25:18 +0200 Subject: [PATCH] Support single-core, align access with mmu off, plus fixes --- src/target/adi_v5_stlink.c | 12 -------- src/target/cortex_a.c | 43 ++++++++++++++++++++++++++--- src/target/cortex_m.c | 8 +++--- tcl/target/stm32mp15x.cfg | 56 ++++++++++++++++++++++++++++---------- 4 files changed, 84 insertions(+), 35 deletions(-) diff --git a/src/target/adi_v5_stlink.c b/src/target/adi_v5_stlink.c index 9e7ab0f64..fd4a4e28a 100644 --- a/src/target/adi_v5_stlink.c +++ b/src/target/adi_v5_stlink.c @@ -120,18 +120,6 @@ static int stlink_connect(struct adiv5_dap *dap) LOG_INFO("stlink_connect(%sconnect)", dap->do_reconnect ? "re" : ""); - /* Check if we should reset srst already when connecting, but not if reconnecting. */ - if (!dap->do_reconnect) { - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { - if (jtag_reset_config & RESET_SRST_NO_GATING) - adapter_assert_reset(); - else - LOG_WARNING("\'srst_nogate\' reset_config option is required"); - } - } - dap->do_reconnect = false; dap_invalidate_cache(dap); diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 499dacc9b..9f6f3d5d2 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1220,6 +1220,8 @@ static int cortex_a_step(struct target *target, int current, target_addr_t addre retval = cortex_a_poll(target); if (retval != ERROR_OK) return retval; + if (target->state == TARGET_HALTED) + break; if (timeval_ms() > then + 1000) { LOG_ERROR("timeout waiting for target halt"); return ERROR_FAIL; @@ -2017,7 +2019,8 @@ static int cortex_a_write_cpu_memory_slow(struct target *target, { /* Writes count objects of size size from *buffer. Old value of DSCR must * be in *dscr; updated to new value. This is slow because it works for - * non-word-sized objects and (maybe) unaligned accesses. If size == 4 and + * non-word-sized objects. Avoid unaligned accesses as they do not work + * on memory address space without "Normal" attribute. If size == 4 and * the address is aligned, cortex_a_write_cpu_memory_fast should be * preferred. * Preconditions: @@ -2174,7 +2177,22 @@ static int cortex_a_write_cpu_memory(struct target *target, /* We are doing a word-aligned transfer, so use fast mode. */ retval = cortex_a_write_cpu_memory_fast(target, count, buffer, &dscr); } else { - /* Use slow path. */ + /* Use slow path. Adjust size for aligned accesses */ + switch (address % 4) { + case 1: + case 3: + count *= size; + size = 1; + break; + case 2: + if (size == 4) { + count *= 2; + size = 2; + } + case 0: + default: + break; + } retval = cortex_a_write_cpu_memory_slow(target, size, count, buffer, &dscr); } @@ -2260,7 +2278,8 @@ static int cortex_a_read_cpu_memory_slow(struct target *target, { /* Reads count objects of size size into *buffer. Old value of DSCR must be * in *dscr; updated to new value. This is slow because it works for - * non-word-sized objects and (maybe) unaligned accesses. If size == 4 and + * non-word-sized objects. Avoid unaligned accesses as they do not work + * on memory address space without "Normal" attribute. If size == 4 and * the address is aligned, cortex_a_read_cpu_memory_fast should be * preferred. * Preconditions: @@ -2476,7 +2495,23 @@ static int cortex_a_read_cpu_memory(struct target *target, /* We are doing a word-aligned transfer, so use fast mode. */ retval = cortex_a_read_cpu_memory_fast(target, count, buffer, &dscr); } else { - /* Use slow path. */ + /* Use slow path. Adjust size for aligned accesses */ + switch (address % 4) { + case 1: + case 3: + count *= size; + size = 1; + break; + case 2: + if (size == 4) { + count *= 2; + size = 2; + } + break; + case 0: + default: + break; + } retval = cortex_a_read_cpu_memory_slow(target, size, count, buffer, &dscr); } diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 79975aa89..9b962192f 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -532,21 +532,21 @@ static int cortex_m_poll(struct target *target) if (cortex_m->dcb_dhcsr & S_HALT) { target->state = TARGET_HALTED; - if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) { + if (prev_target_state != TARGET_HALTED) { retval = cortex_m_debug_entry(target); if (retval != ERROR_OK) return retval; + } + if (prev_target_state == TARGET_RUNNING || prev_target_state == TARGET_RESET) { if (arm_semihosting(target, &retval) != 0) return retval; target_call_event_callbacks(target, TARGET_EVENT_HALTED); } + if (prev_target_state == TARGET_DEBUG_RUNNING) { LOG_DEBUG(" "); - retval = cortex_m_debug_entry(target); - if (retval != ERROR_OK) - return retval; target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); } diff --git a/tcl/target/stm32mp15x.cfg b/tcl/target/stm32mp15x.cfg index 992975f87..f95070c3c 100644 --- a/tcl/target/stm32mp15x.cfg +++ b/tcl/target/stm32mp15x.cfg @@ -54,8 +54,10 @@ proc cti_prepare_restart_all {} { global _CHIPNAME cti_prepare_restart cti0 - cti_prepare_restart cti1 - if { [$_CHIPNAME.cpu2 curstate] ne "examine deferred" } { + if { [$_CHIPNAME.cpu1 was_examined] } { + cti_prepare_restart cti1 + } + if { [$_CHIPNAME.cpu2 was_examined] } { cti_prepare_restart cti2 } } @@ -71,22 +73,22 @@ proc cti_prepare_restart {cti} { proc cti_start {} { global _CHIPNAME - # Configure both Cortex-A CTIs to halt each other + # Configure CTIs to halt the other cores # TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0 $_CHIPNAME.cti0 write INEN0 0x1 - $_CHIPNAME.cti1 write INEN0 0x1 $_CHIPNAME.cti0 write OUTEN0 0x1 - $_CHIPNAME.cti1 write OUTEN0 0x1 - - $_CHIPNAME.cpu0 configure -event halted { cti_prepare_restart_all } - $_CHIPNAME.cpu1 configure -event halted { cti_prepare_restart_all } - - # enable CTIs + $_CHIPNAME.cpu0 configure -event halted { cti_prepare_restart_all } $_CHIPNAME.cti0 enable on - $_CHIPNAME.cti1 enable on + + if { [$_CHIPNAME.cpu1 was_examined] } { + $_CHIPNAME.cti1 write INEN0 0x1 + $_CHIPNAME.cti1 write OUTEN0 0x1 + $_CHIPNAME.cpu1 configure -event halted { cti_prepare_restart_all } + $_CHIPNAME.cti1 enable on + } # Cortex-M4 CTI configuration (enable CM4.CTI and join same CTM channels) - if { [$_CHIPNAME.cpu2 curstate] ne "examine deferred" } { + if { [$_CHIPNAME.cpu2 was_examined] } { $_CHIPNAME.cti2 write INEN0 0x1 $_CHIPNAME.cti2 write OUTEN0 0x1 $_CHIPNAME.cpu2 configure -event halted { cti_prepare_restart_all } @@ -98,8 +100,9 @@ proc cti_stop {} { global _CHIPNAME $_CHIPNAME.cti0 enable off - $_CHIPNAME.cti1 enable off - + if { [$_CHIPNAME.cpu1 was_examined] } { + $_CHIPNAME.cti1 enable off + } if { [$_CHIPNAME.cpu2 curstate] ne "examine deferred" } { $_CHIPNAME.cti2 enable off } @@ -111,7 +114,7 @@ cti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 1 -ctibase 0xE00D9000 cti create $_CHIPNAME.cti2 -dap $_CHIPNAME.dap -ap-num 2 -ctibase 0xE0043000 target create $_CHIPNAME.cpu0 cortex_a -dap $_CHIPNAME.dap -coreid 0 -dbgbase 0xE00D0000 -target create $_CHIPNAME.cpu1 cortex_a -dap $_CHIPNAME.dap -coreid 1 -dbgbase 0xE00D2000 +target create $_CHIPNAME.cpu1 cortex_a -dap $_CHIPNAME.dap -coreid 1 -dbgbase 0xE00D2000 -defer-examine target create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0 target create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1 @@ -228,6 +231,29 @@ adapter_khz $_CLOCK_FREQ adapter_nsrst_assert_width 200 adapter_nsrst_delay 200 +$_CHIPNAME.ap1 configure -event examine-end { + global _CHIPNAME + + # only on dual-cores chips, examine the second core + $_CHIPNAME.ap1 mem2array cpu1_prsr 32 0xE00D2314 1 + if {$cpu1_prsr(0) & 1} { + $_CHIPNAME.cpu1 invoke-event examine-start + set err [catch "$_CHIPNAME.cpu1 arp_examine"] + if { $err } { + $_CHIPNAME.cpu1 invoke-event examine-fail + } else { + $_CHIPNAME.cpu1 invoke-event examine-end + } + } +} + +$_CHIPNAME.cpu1 configure -event examine-end { + global _CHIPNAME + + if {[$_CHIPNAME.cpu1 was_examined] && [$_CHIPNAME.cpu0 curstate] eq "halted"} { + halt + } +} set clients_num 0 proc clients_inc {} { -- 2.21.0