openocd: fix SPDX tag format for files .c
[fw/openocd] / src / target / cortex_m.c
index 344cfcf61735fa05d1b4e3cda89f7c59068a008e..23d9065e2a7e09ccb36fa8b56e7e66260cbc8719 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
@@ -8,19 +10,6 @@
  *   Copyright (C) 2008 by Spencer Oliver                                  *
  *   spen@spen-soft.co.uk                                                  *
  *                                                                         *
- *   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.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
- *                                                                         *
  *                                                                         *
  *   Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0)              *
  *                                                                         *
@@ -114,6 +103,12 @@ static const struct cortex_m_part_info cortex_m_parts[] = {
                .arch = ARM_ARCH_V8M,
                .flags = CORTEX_M_F_HAS_FPV5,
        },
+       {
+               .partno = STAR_MC1_PARTNO,
+               .name = "STAR-MC1",
+               .arch = ARM_ARCH_V8M,
+               .flags = CORTEX_M_F_HAS_FPV5,
+       },
 };
 
 /* forward declarations */
@@ -663,6 +658,11 @@ static int cortex_m_endreset_event(struct target *target)
 
        register_cache_invalidate(armv7m->arm.core_cache);
 
+       /* TODO: invalidate also working areas (needed in the case of detected reset).
+        * Doing so will require flash drivers to test if working area
+        * is still valid in all target algo calling loops.
+        */
+
        /* make sure we have latest dhcsr flags */
        retval = cortex_m_read_dhcsr_atomic_sticky(target);
        if (retval != ERROR_OK)
@@ -775,7 +775,7 @@ static int cortex_m_examine_exception_reason(struct target *target)
 
 static int cortex_m_debug_entry(struct target *target)
 {
-       uint32_t xPSR;
+       uint32_t xpsr;
        int retval;
        struct cortex_m_common *cortex_m = target_to_cm(target);
        struct armv7m_common *armv7m = &cortex_m->armv7m;
@@ -826,11 +826,11 @@ static int cortex_m_debug_entry(struct target *target)
                return retval;
 
        r = arm->cpsr;
-       xPSR = buf_get_u32(r->value, 0, 32);
+       xpsr = buf_get_u32(r->value, 0, 32);
 
        /* Are we in an exception handler */
-       if (xPSR & 0x1FF) {
-               armv7m->exception_number = (xPSR & 0x1FF);
+       if (xpsr & 0x1FF) {
+               armv7m->exception_number = (xpsr & 0x1FF);
 
                arm->core_mode = ARM_MODE_HANDLER;
                arm->map = armv7m_msp_reg_map;
@@ -879,6 +879,16 @@ static int cortex_m_poll(struct target *target)
        struct cortex_m_common *cortex_m = target_to_cm(target);
        struct armv7m_common *armv7m = &cortex_m->armv7m;
 
+       /* Check if debug_ap is available to prevent segmentation fault.
+        * If the re-examination after an error does not find a MEM-AP
+        * (e.g. the target stopped communicating), debug_ap pointer
+        * can suddenly become NULL.
+        */
+       if (!armv7m->debug_ap) {
+               target->state = TARGET_UNKNOWN;
+               return ERROR_TARGET_NOT_EXAMINED;
+       }
+
        /* Read from Debug Halting Control and Status Register */
        retval = cortex_m_read_dhcsr_atomic_sticky(target);
        if (retval != ERROR_OK) {
@@ -1904,7 +1914,7 @@ int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpo
        return ERROR_OK;
 }
 
-int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
+static int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
 {
        if (target->debug_reason != DBG_REASON_WATCHPOINT)
                return ERROR_FAIL;
@@ -1984,6 +1994,10 @@ static int cortex_m_init_target(struct command_context *cmd_ctx,
 void cortex_m_deinit_target(struct target *target)
 {
        struct cortex_m_common *cortex_m = target_to_cm(target);
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+
+       if (!armv7m->is_hla_target && armv7m->debug_ap)
+               dap_put_ap(armv7m->debug_ap);
 
        free(cortex_m->fp_comparator_list);
 
@@ -2262,10 +2276,10 @@ static void cortex_m_dwt_free(struct target *target)
 static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
                struct adiv5_ap **debug_ap)
 {
-       if (dap_find_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
+       if (dap_find_get_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
                return ERROR_OK;
 
-       return dap_find_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
+       return dap_find_get_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
 }
 
 int cortex_m_examine(struct target *target)
@@ -2279,6 +2293,11 @@ int cortex_m_examine(struct target *target)
        /* hla_target shares the examine handler but does not support
         * all its calls */
        if (!armv7m->is_hla_target) {
+               if (armv7m->debug_ap) {
+                       dap_put_ap(armv7m->debug_ap);
+                       armv7m->debug_ap = NULL;
+               }
+
                if (cortex_m->apsel == DP_APSEL_INVALID) {
                        /* Search for the MEM-AP */
                        retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
@@ -2287,7 +2306,11 @@ int cortex_m_examine(struct target *target)
                                return retval;
                        }
                } else {
-                       armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel);
+                       armv7m->debug_ap = dap_get_ap(swjdp, cortex_m->apsel);
+                       if (!armv7m->debug_ap) {
+                               LOG_ERROR("Cannot get AP");
+                               return ERROR_FAIL;
+                       }
                }
 
                armv7m->debug_ap->memaccess_tck = 8;
@@ -2384,6 +2407,20 @@ int cortex_m_examine(struct target *target)
                retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr);
                if (retval != ERROR_OK)
                        return retval;
+
+               /*  Don't cumulate sticky S_RESET_ST at the very first read of DHCSR
+                *  as S_RESET_ST may indicate a reset that happened long time ago
+                *  (most probably the power-on reset before OpenOCD was started).
+                *  As we are just initializing the debug system we do not need
+                *  to call cortex_m_endreset_event() in the following poll.
+                */
+               if (!cortex_m->dcb_dhcsr_sticky_is_recent) {
+                       cortex_m->dcb_dhcsr_sticky_is_recent = true;
+                       if (cortex_m->dcb_dhcsr & S_RESET_ST) {
+                               LOG_TARGET_DEBUG(target, "reset happened some time ago, ignore");
+                               cortex_m->dcb_dhcsr &= ~S_RESET_ST;
+                       }
+               }
                cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr);
 
                if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {