From d4528c355d28480ceb546f9dcee00f28a01bc5c2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 14 Oct 2019 13:02:11 +0200 Subject: [PATCH] Add support for stlink traces and silicon rev.2.1, fix CSW --- src/jtag/drivers/stlink_usb.c | 39 +++++++++++++++++-------------- src/target/armv8.c | 3 ++- tcl/target/stm32mp15x.cfg | 17 ++++++++++---- tcl/target/stm32mp15x_stpmic1.cfg | 5 ++-- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index b27d04318..a4944e7bd 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -2937,7 +2937,7 @@ int stlink_dap_dap_write(unsigned short dap_port, unsigned short addr, uint32_t * * This workaround leverage the CSW caching operated by ST-Link. At every * memory R/W, ST-Link computes the new CSW value based on word size. If it - * match the previous CSW value than it has wrote in CSW register, ST-Link + * match the previous CSW value that it has wrote in CSW register, ST-Link * will not write in CSW register again. * * Here we track the word size used in the last memory R/W. If it does not @@ -2956,18 +2956,6 @@ static int stlink_dap_set_csw(struct adiv5_ap *ap, uint32_t size, bool addrinc) ap_num = ap->ap_num; struct stlink_usb_handle_s *h = stlink_dap_handle; - if ((h->version.stlink == 2 && h->version.jtag >= 32) || (h->version.stlink == 3 && h->version.jtag >= 2)) { - csw = ap->csw_default; - if (csw != (ap->csw_value & ~(CSW_SIZE_MASK | CSW_ADDRINC_MASK))) { - retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw); - if (retval != ERROR_OK) { - ap->csw_value = 0; - return retval; - } - ap->csw_value = csw; - } - return ERROR_OK; - } switch (size) { case 2: @@ -2991,12 +2979,14 @@ static int stlink_dap_set_csw(struct adiv5_ap *ap, uint32_t size, bool addrinc) } csw |= ap->csw_default; - if (ap_csw_size_cached[ap_num] != size) { - ap_csw_size_cached[ap_num] = size; + if ((h->version.stlink == 2 && h->version.jtag < 32) || (h->version.stlink == 3 && h->version.jtag < 2)) { + if (ap_csw_size_cached[ap_num] != size) { + ap_csw_size_cached[ap_num] = size; - /* The mem read below will change CSW */ - ap->csw_value = 0; - stlink_usb_read_ap_mem(stlink_dap_handle, ap_num, 0x00000000, size, 1, dummy); + /* The mem read below will change CSW */ + ap->csw_value = 0; + stlink_usb_read_ap_mem(stlink_dap_handle, ap_num, 0x00000000, size, 1, dummy); + } } if (ap->csw_value != csw) { @@ -3324,6 +3314,17 @@ static int stlink_dap_quit(void) return stlink_usb_close(stlink_dap_handle); } +static int stlink_dap_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, + uint32_t port_size, unsigned int *trace_freq) +{ + return stlink_config_trace(stlink_dap_handle, enabled, pin_protocol, port_size, trace_freq); +} + +static int stlink_dap_trace_read(uint8_t *buf, size_t *size) +{ + return stlink_usb_trace_read(stlink_dap_handle, buf, size); +} + COMMAND_HANDLER(stlink_dap_serial_command) { LOG_DEBUG("stlink_dap_serial_command"); @@ -3416,4 +3417,6 @@ struct jtag_interface stlink_dap_interface = { .khz = stlink_dap_khz, .init = stlink_dap_init, .quit = stlink_dap_quit, + .config_trace = stlink_dap_config_trace, + .poll_trace = stlink_dap_trace_read, }; diff --git a/src/target/armv8.c b/src/target/armv8.c index 39ce7e129..c3e3460fc 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1670,7 +1670,8 @@ const struct command_registration armv8_command_handlers[] = { const char *armv8_get_gdb_arch(struct target *target) { - return "aarch64"; + struct arm *arm = target_to_arm(target); + return arm->core_state == ARM_STATE_AARCH64 ? "aarch64" : "arm"; } int armv8_get_gdb_reg_list(struct target *target, diff --git a/tcl/target/stm32mp15x.cfg b/tcl/target/stm32mp15x.cfg index f95070c3c..ec9f279f4 100644 --- a/tcl/target/stm32mp15x.cfg +++ b/tcl/target/stm32mp15x.cfg @@ -159,7 +159,8 @@ proc pre_reset_halt_cpu0 {} { global workaround_revision_0x2000 catch { unset workaround_revision_0x2000 } - if { ([eval chip_revision] == 0x2000) && ![info exists ENG_MODE] && ([string compare "$arp_reset_mode" "run"] != 0) } { + set chip_rev [expr [chip_revision] & 0xfffe] + if { ($chip_rev == 0x2000) && ![info exists ENG_MODE] && ([string compare "$arp_reset_mode" "run"] != 0) } { set workaround_revision_0x2000 1 set_debugflag_in_backup_reg } @@ -200,9 +201,14 @@ proc delayed_reset_halt_cpu0 { } { targets $_CHIPNAME.cpu0 arp_reset_default_handler post $_CHIPNAME.cpu0 - set rom_halt_pc 0x000079ac - if { [eval chip_revision] == 0x1000 } { - set rom_halt_pc 0x0000688c + switch [chip_revision] { + 0x1000 + { set rom_halt_pc 0x0000688c } + 0x2000 + { set rom_halt_pc 0x000079ac } + 0x2001 - + default + { set rom_halt_pc 0x00000000 } } poll on @@ -362,7 +368,8 @@ axi_secure_access rename init __init proc init {} { __init - if { [eval chip_revision] == 0x2000 } { + set chip_rev [expr [chip_revision] & 0xfffe] + if { $chip_rev == 0x2000 } { # srst pulse causes a reset of the debug port reset_config srst_pulls_trst } diff --git a/tcl/target/stm32mp15x_stpmic1.cfg b/tcl/target/stm32mp15x_stpmic1.cfg index 16cf9b0ae..ac57ba171 100644 --- a/tcl/target/stm32mp15x_stpmic1.cfg +++ b/tcl/target/stm32mp15x_stpmic1.cfg @@ -2,7 +2,7 @@ source [find target/stm32mp15x.cfg] -$_CHIPNAME.cpu0 configure -event reset-halt { catch { if { [eval chip_revision] != 0x2000 } { pmic_init } } } +$_CHIPNAME.cpu0 configure -event reset-halt { catch { set chip_rev [expr [chip_revision] & 0xfffe]; if { $chip_rev != 0x2000 } { pmic_init } } } # Wait for expression to be true with a timeout of 200ms proc wait_state {condition} { @@ -63,7 +63,8 @@ proc pmic_init {} { rename init _init proc init {} { _init - if { [eval chip_revision] != 0x2000 } { + set chip_rev [expr [chip_revision] & 0xfffe] + if { $chip_rev != 0x2000 } { # Use debug flag to signal to SPL and TF-A that we are in a debug # session. This will force them (at next reboot) to program the PMIC # for keeping powered-on the debug unit during reset. -- 2.25.0