openocd: src/target: replace the GPL-2.0-or-later license tag
[fw/openocd] / src / target / cortex_m.h
index a5dfbf856aef0aea68f5922373622d3881b13a56..3f0d55c1c24f5160ef3e6505c9413c0f5d4262a5 100644 (file)
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
 /***************************************************************************
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
@@ -7,19 +9,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/>. *
  ***************************************************************************/
 
 #ifndef OPENOCD_TARGET_CORTEX_M_H
@@ -46,6 +35,7 @@
 #define ARM_CPUID_PARTNO_MASK  (0xFFF << ARM_CPUID_PARTNO_POS)
 
 enum cortex_m_partno {
+       CORTEX_M_PARTNO_INVALID,
        CORTEX_M0_PARTNO   = 0xC20,
        CORTEX_M1_PARTNO   = 0xC21,
        CORTEX_M3_PARTNO   = 0xC23,
@@ -238,18 +228,77 @@ struct cortex_m_common {
        const struct cortex_m_part_info *core_info;
        struct armv7m_common armv7m;
 
-       int apsel;
+       bool slow_register_read;        /* A register has not been ready, poll S_REGRDY */
+
+       uint64_t apsel;
 
        /* Whether this target has the erratum that makes C_MASKINTS not apply to
         * already pending interrupts */
        bool maskints_erratum;
 };
 
+static inline bool is_cortex_m_or_hla(const struct cortex_m_common *cortex_m)
+{
+       return cortex_m->common_magic == CORTEX_M_COMMON_MAGIC;
+}
+
+static inline bool is_cortex_m_with_dap_access(const struct cortex_m_common *cortex_m)
+{
+       if (!is_cortex_m_or_hla(cortex_m))
+               return false;
+
+       return !cortex_m->armv7m.is_hla_target;
+}
+
+/**
+ * @returns the pointer to the target specific struct
+ * without matching a magic number.
+ * Use in target specific service routines, where the correct
+ * type of arch_info is certain.
+ */
 static inline struct cortex_m_common *
 target_to_cm(struct target *target)
 {
        return container_of(target->arch_info,
-                       struct cortex_m_common, armv7m);
+                       struct cortex_m_common, armv7m.arm);
+}
+
+/**
+ * @returns the pointer to the target specific struct
+ * or NULL if the magic number does not match.
+ * Use in a flash driver or any place where mismatch of the arch_info
+ * type can happen.
+ */
+static inline struct cortex_m_common *
+target_to_cortex_m_safe(struct target *target)
+{
+       /* Check the parent types first to prevent peeking memory too far
+        * from arch_info pointer */
+       if (!target_to_armv7m_safe(target))
+               return NULL;
+
+       struct cortex_m_common *cortex_m = target_to_cm(target);
+       if (!is_cortex_m_or_hla(cortex_m))
+               return NULL;
+
+       return cortex_m;
+}
+
+/**
+ * @returns cached value of Cortex-M part number
+ * or CORTEX_M_PARTNO_INVALID if the magic number does not match
+ * or core_info is not initialised.
+ */
+static inline enum cortex_m_partno cortex_m_get_partno_safe(struct target *target)
+{
+       struct cortex_m_common *cortex_m = target_to_cortex_m_safe(target);
+       if (!cortex_m)
+               return CORTEX_M_PARTNO_INVALID;
+
+       if (!cortex_m->core_info)
+               return CORTEX_M_PARTNO_INVALID;
+
+       return cortex_m->core_info->partno;
 }
 
 int cortex_m_examine(struct target *target);