jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / cortex_m.h
index 4452b98b2c2fd97380cf2677a26fc0dd8ce68d98..a585b786b90ca1b7d1ca5f58701967b09cb763ba 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,46 +9,93 @@
  *                                                                         *
  *   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, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
  ***************************************************************************/
 
-#ifndef CORTEX_M3_H
-#define CORTEX_M3_H
+#ifndef OPENOCD_TARGET_CORTEX_M_H
+#define OPENOCD_TARGET_CORTEX_M_H
 
 #include "armv7m.h"
+#include "helper/bits.h"
 
-#define CORTEX_M3_COMMON_MAGIC 0x1A451A45
+#define CORTEX_M_COMMON_MAGIC 0x1A451A45U
 
 #define SYSTEM_CONTROL_BASE 0x400FE000
 
+#define ITM_TER0       0xE0000E00
+#define ITM_TPR                0xE0000E40
+#define ITM_TCR                0xE0000E80
+#define ITM_TCR_ITMENA_BIT     BIT(0)
+#define ITM_TCR_BUSY_BIT       BIT(23)
+#define ITM_LAR                0xE0000FB0
+#define ITM_LAR_KEY    0xC5ACCE55
+
 #define CPUID          0xE000ED00
+
+#define ARM_CPUID_IMPLEMENTOR_POS      24
+#define ARM_CPUID_IMPLEMENTOR_MASK     (0xFF << ARM_CPUID_IMPLEMENTOR_POS)
+#define ARM_CPUID_PARTNO_POS           4
+#define ARM_CPUID_PARTNO_MASK          (0xFFF << ARM_CPUID_PARTNO_POS)
+
+#define ARM_MAKE_CPUID(impl, partno)   ((((impl) << ARM_CPUID_IMPLEMENTOR_POS) & ARM_CPUID_IMPLEMENTOR_MASK) | \
+       (((partno) << ARM_CPUID_PARTNO_POS)  & ARM_CPUID_PARTNO_MASK))
+
+/** Known Arm Cortex masked CPU Ids
+ * This includes the implementor and part number, but _not_ the revision or
+ * patch fields.
+ */
+enum cortex_m_impl_part {
+       CORTEX_M_PARTNO_INVALID,
+       STAR_MC1_PARTNO      = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0x132), /* FIXME - confirm implementor! */
+       CORTEX_M0_PARTNO     = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC20),
+       CORTEX_M1_PARTNO     = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC21),
+       CORTEX_M3_PARTNO     = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC23),
+       CORTEX_M4_PARTNO     = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC24),
+       CORTEX_M7_PARTNO     = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC27),
+       CORTEX_M0P_PARTNO    = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC60),
+       CORTEX_M23_PARTNO    = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD20),
+       CORTEX_M33_PARTNO    = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD21),
+       CORTEX_M35P_PARTNO   = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD31),
+       CORTEX_M55_PARTNO    = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD22),
+       CORTEX_M85_PARTNO    = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD23),
+       INFINEON_SLX2_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_INFINEON, 0xDB0),
+       REALTEK_M200_PARTNO  = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd20),
+       REALTEK_M300_PARTNO  = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd22),
+};
+
+/* Relevant Cortex-M flags, used in struct cortex_m_part_info.flags */
+#define CORTEX_M_F_HAS_FPV4               BIT(0)
+#define CORTEX_M_F_HAS_FPV5               BIT(1)
+#define CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K  BIT(2)
+
+struct cortex_m_part_info {
+       enum cortex_m_impl_part impl_part;
+       const char *name;
+       enum arm_arch arch;
+       uint32_t flags;
+};
+
 /* Debug Control Block */
 #define DCB_DHCSR      0xE000EDF0
 #define DCB_DCRSR      0xE000EDF4
 #define DCB_DCRDR      0xE000EDF8
 #define DCB_DEMCR      0xE000EDFC
+#define DCB_DSCSR      0xE000EE08
+
+#define DAUTHSTATUS    0xE000EFB8
+#define DAUTHSTATUS_SID_MASK   0x00000030
 
-#define DCRSR_WnR      (1 << 16)
+#define DCRSR_WNR      BIT(16)
 
 #define DWT_CTRL       0xE0001000
 #define DWT_CYCCNT     0xE0001004
+#define DWT_PCSR       0xE000101C
 #define DWT_COMP0      0xE0001020
 #define DWT_MASK0      0xE0001024
 #define DWT_FUNCTION0  0xE0001028
+#define DWT_DEVARCH            0xE0001FBC
+
+#define DWT_DEVARCH_ARMV8M_V2_0        0x101A02
+#define DWT_DEVARCH_ARMV8M_V2_1        0x111A02
 
 #define FP_CTRL                0xE0002000
 #define FP_REMAP       0xE0002004
 #define FPU_FPCAR      0xE000EF38
 #define FPU_FPDSCR     0xE000EF3C
 
+#define TPIU_SSPSR     0xE0040000
+#define TPIU_CSPSR     0xE0040004
+#define TPIU_ACPR      0xE0040010
+#define TPIU_SPPR      0xE00400F0
+#define TPIU_FFSR      0xE0040300
+#define TPIU_FFCR      0xE0040304
+#define TPIU_FSCR      0xE0040308
+
+/* Maximum SWO prescaler value. */
+#define TPIU_ACPR_MAX_SWOSCALER        0x1fff
+
 /* DCB_DHCSR bit and field definitions */
-#define DBGKEY         (0xA05F << 16)
-#define C_DEBUGEN      (1 << 0)
-#define C_HALT         (1 << 1)
-#define C_STEP         (1 << 2)
-#define C_MASKINTS     (1 << 3)
-#define S_REGRDY       (1 << 16)
-#define S_HALT         (1 << 17)
-#define S_SLEEP                (1 << 18)
-#define S_LOCKUP       (1 << 19)
-#define S_RETIRE_ST    (1 << 24)
-#define S_RESET_ST     (1 << 25)
+#define DBGKEY         (0xA05Ful << 16)
+#define C_DEBUGEN      BIT(0)
+#define C_HALT         BIT(1)
+#define C_STEP         BIT(2)
+#define C_MASKINTS     BIT(3)
+#define S_REGRDY       BIT(16)
+#define S_HALT         BIT(17)
+#define S_SLEEP                BIT(18)
+#define S_LOCKUP       BIT(19)
+#define S_RETIRE_ST    BIT(24)
+#define S_RESET_ST     BIT(25)
 
 /* DCB_DEMCR bit and field definitions */
-#define TRCENA                 (1 << 24)
-#define VC_HARDERR             (1 << 10)
-#define VC_INTERR              (1 << 9)
-#define VC_BUSERR              (1 << 8)
-#define VC_STATERR             (1 << 7)
-#define VC_CHKERR              (1 << 6)
-#define VC_NOCPERR             (1 << 5)
-#define VC_MMERR               (1 << 4)
-#define VC_CORERESET   (1 << 0)
+#define TRCENA                 BIT(24)
+#define VC_HARDERR             BIT(10)
+#define VC_INTERR              BIT(9)
+#define VC_BUSERR              BIT(8)
+#define VC_STATERR             BIT(7)
+#define VC_CHKERR              BIT(6)
+#define VC_NOCPERR             BIT(5)
+#define VC_MMERR               BIT(4)
+#define VC_CORERESET   BIT(0)
+
+/* DCB_DSCSR bit and field definitions */
+#define DSCSR_CDS              BIT(16)
 
+/* NVIC registers */
 #define NVIC_ICTR              0xE000E004
 #define NVIC_ISE0              0xE000E100
 #define NVIC_ICSR              0xE000ED04
 #define NVIC_AIRCR             0xE000ED0C
 #define NVIC_SHCSR             0xE000ED24
 #define NVIC_CFSR              0xE000ED28
-#define NVIC_MMFSRb            0xE000ED28
-#define NVIC_BFSRb             0xE000ED29
-#define NVIC_USFSRh            0xE000ED2A
+#define NVIC_MMFSRB            0xE000ED28
+#define NVIC_BFSRB             0xE000ED29
+#define NVIC_USFSRH            0xE000ED2A
 #define NVIC_HFSR              0xE000ED2C
 #define NVIC_DFSR              0xE000ED30
 #define NVIC_MMFAR             0xE000ED34
 #define NVIC_BFAR              0xE000ED38
+#define NVIC_SFSR              0xE000EDE4
+#define NVIC_SFAR              0xE000EDE8
 
 /* NVIC_AIRCR bits */
-#define AIRCR_VECTKEY          (0x5FA << 16)
-#define AIRCR_SYSRESETREQ      (1 << 2)
-#define AIRCR_VECTCLRACTIVE    (1 << 1)
-#define AIRCR_VECTRESET                (1 << 0)
+#define AIRCR_VECTKEY          (0x5FAul << 16)
+#define AIRCR_SYSRESETREQ      BIT(2)
+#define AIRCR_VECTCLRACTIVE    BIT(1)
+#define AIRCR_VECTRESET                BIT(0)
 /* NVIC_SHCSR bits */
-#define SHCSR_BUSFAULTENA      (1 << 17)
+#define SHCSR_BUSFAULTENA      BIT(17)
 /* NVIC_DFSR bits */
 #define DFSR_HALTED                    1
 #define DFSR_BKPT                      2
 #define DFSR_DWTTRAP           4
 #define DFSR_VCATCH                    8
+#define DFSR_EXTERNAL          16
 
 #define FPCR_CODE 0
 #define FPCR_LITERAL 1
-#define FPCR_REPLACE_REMAP  (0 << 30)
-#define FPCR_REPLACE_BKPT_LOW  (1 << 30)
-#define FPCR_REPLACE_BKPT_HIGH  (2 << 30)
-#define FPCR_REPLACE_BKPT_BOTH  (3 << 30)
+#define FPCR_REPLACE_REMAP  (0ul << 30)
+#define FPCR_REPLACE_BKPT_LOW  (1ul << 30)
+#define FPCR_REPLACE_BKPT_HIGH  (2ul << 30)
+#define FPCR_REPLACE_BKPT_BOTH  (3ul << 30)
 
-struct cortex_m3_fp_comparator {
-       int used;
+struct cortex_m_fp_comparator {
+       bool used;
        int type;
        uint32_t fpcr_value;
        uint32_t fpcr_address;
 };
 
-struct cortex_m3_dwt_comparator {
-       int used;
+struct cortex_m_dwt_comparator {
+       bool used;
        uint32_t comp;
        uint32_t mask;
        uint32_t function;
        uint32_t dwt_comparator_address;
 };
 
-enum cortex_m3_soft_reset_config {
-       CORTEX_M3_RESET_SYSRESETREQ,
-       CORTEX_M3_RESET_VECTRESET,
+enum cortex_m_soft_reset_config {
+       CORTEX_M_RESET_SYSRESETREQ,
+       CORTEX_M_RESET_VECTRESET,
 };
 
-enum cortex_m3_isrmasking_mode {
-       CORTEX_M3_ISRMASK_AUTO,
-       CORTEX_M3_ISRMASK_OFF,
-       CORTEX_M3_ISRMASK_ON,
+enum cortex_m_isrmasking_mode {
+       CORTEX_M_ISRMASK_AUTO,
+       CORTEX_M_ISRMASK_OFF,
+       CORTEX_M_ISRMASK_ON,
+       CORTEX_M_ISRMASK_STEPONLY,
 };
 
-struct cortex_m3_common {
-       int common_magic;
-       struct arm_jtag jtag_info;
+struct cortex_m_common {
+       unsigned int common_magic;
+
+       struct armv7m_common armv7m;
 
        /* Context information */
        uint32_t dcb_dhcsr;
+       uint32_t dcb_dhcsr_cumulated_sticky;
+       /* DCB DHCSR has been at least once read, so the sticky bits have been reset */
+       bool dcb_dhcsr_sticky_is_recent;
        uint32_t nvic_dfsr;  /* Debug Fault Status Register - shows reason for debug halt */
        uint32_t nvic_icsr;  /* Interrupt Control State Register - shows active and pending IRQ */
 
        /* Flash Patch and Breakpoint (FPB) */
-       int fp_num_lit;
-       int fp_num_code;
-       int fp_code_available;
-       int fpb_enabled;
-       int auto_bp_type;
-       struct cortex_m3_fp_comparator *fp_comparator_list;
+       unsigned int fp_num_lit;
+       unsigned int fp_num_code;
+       int fp_rev;
+       bool fpb_enabled;
+       struct cortex_m_fp_comparator *fp_comparator_list;
 
        /* Data Watchpoint and Trace (DWT) */
-       int dwt_num_comp;
-       int dwt_comp_available;
-       struct cortex_m3_dwt_comparator *dwt_comparator_list;
+       unsigned int dwt_num_comp;
+       unsigned int dwt_comp_available;
+       uint32_t dwt_devarch;
+       struct cortex_m_dwt_comparator *dwt_comparator_list;
        struct reg_cache *dwt_cache;
 
-       enum cortex_m3_soft_reset_config soft_reset_config;
+       enum cortex_m_soft_reset_config soft_reset_config;
+       bool vectreset_supported;
+       enum cortex_m_isrmasking_mode isrmasking_mode;
 
-       enum cortex_m3_isrmasking_mode isrmasking_mode;
+       const struct cortex_m_part_info *core_info;
 
-       struct armv7m_common armv7m;
+       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 struct cortex_m3_common *
-target_to_cm3(struct target *target)
+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_m3_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 the cpuid, masked for implementation and part.
+ * or CORTEX_M_PARTNO_INVALID if the magic number does not match
+ * or core_info is not initialised.
+ */
+static inline enum cortex_m_impl_part cortex_m_get_impl_part(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->impl_part;
 }
 
-int cortex_m3_examine(struct target *target);
-int cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint);
-int cortex_m3_unset_breakpoint(struct target *target, struct breakpoint *breakpoint);
-int cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoint);
-int cortex_m3_remove_breakpoint(struct target *target, struct breakpoint *breakpoint);
-int cortex_m3_set_watchpoint(struct target *target, struct watchpoint *watchpoint);
-int cortex_m3_unset_watchpoint(struct target *target, struct watchpoint *watchpoint);
-int cortex_m3_add_watchpoint(struct target *target, struct watchpoint *watchpoint);
-int cortex_m3_remove_watchpoint(struct target *target, struct watchpoint *watchpoint);
-void cortex_m3_enable_breakpoints(struct target *target);
-void cortex_m3_enable_watchpoints(struct target *target);
-void cortex_m3_dwt_setup(struct cortex_m3_common *cm3, struct target *target);
-
-#endif /* CORTEX_M3_H */
+int cortex_m_examine(struct target *target);
+int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint);
+int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint);
+int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint);
+int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint);
+int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint);
+int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpoint);
+void cortex_m_enable_breakpoints(struct target *target);
+void cortex_m_enable_watchpoints(struct target *target);
+void cortex_m_deinit_target(struct target *target);
+int cortex_m_profiling(struct target *target, uint32_t *samples,
+       uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
+
+#endif /* OPENOCD_TARGET_CORTEX_M_H */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)