|
From: openocd-gerrit <ope...@us...> - 2025-10-11 15:57:20
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 04da6e2c624658d2c2c5c81f49be2e396bd30490 (commit)
from 2abf8daa80d31dc78877943ad580af7a6fbbbe3f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 04da6e2c624658d2c2c5c81f49be2e396bd30490
Author: Antonio Borneo <bor...@gm...>
Date: Tue Aug 5 12:06:22 2025 +0200
target: cortex-m: add support for armv8m caches
Cores like Cortex-M7, Cortex-M55 and Cortex-M85 can have either
D-Cache and/or I-Cache.
Using SW breakpoints in RAM requires handling these caches.
Detect the presence of cache at examine.
Detect cache state (enable/disable) at debug entry.
Take care of caches synchronization through the PoC (usually the
SRAM) while setting and removing SW breakpoints.
Add command 'cache_info' to check cache presence and size.
Change-Id: Ice637c215fe3042c8fff57edefbab1b86515ef4b
Signed-off-by: Antonio Borneo <bor...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9077
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 7f7c8892f..6301077fc 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -11120,6 +11120,10 @@ Enable or disable trace output for all ITM stimulus ports.
@subsection Cortex-M specific commands
@cindex Cortex-M
+@deffn {Command} {cortex_m cache_info}
+Report information about the type and size of the cache, if present.
+@end deffn
+
@deffn {Command} {cortex_m maskisr} (@option{auto}|@option{on}|@option{off}|@option{steponly})
Control masking (disabling) interrupts during target step/resume.
diff --git a/src/target/Makefile.am b/src/target/Makefile.am
index 1a7686418..0b5a85704 100644
--- a/src/target/Makefile.am
+++ b/src/target/Makefile.am
@@ -75,6 +75,7 @@ ARMV6_SRC = \
ARMV7_SRC = \
%D%/armv7m.c \
+ %D%/armv7m_cache.c \
%D%/armv7m_trace.c \
%D%/cortex_m.c \
%D%/armv7a.c \
@@ -183,6 +184,7 @@ ARC_SRC = \
%D%/armv4_5_cache.h \
%D%/armv7a.h \
%D%/armv7m.h \
+ %D%/armv7m_cache.h \
%D%/armv7m_trace.h \
%D%/armv8.h \
%D%/armv8_dpm.h \
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 86c45f7f2..942e22584 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -15,6 +15,7 @@
#define OPENOCD_TARGET_ARMV7M_H
#include "arm.h"
+#include "armv7m_cache.h"
#include "armv7m_trace.h"
struct adiv5_ap;
@@ -239,6 +240,8 @@ struct armv7m_common {
/* hla_target uses a high level adapter that does not support all functions */
bool is_hla_target;
+ struct armv7m_cache_common armv7m_cache;
+
struct armv7m_trace_config trace_config;
/* Direct processor core register read and writes */
diff --git a/src/target/armv7m_cache.c b/src/target/armv7m_cache.c
new file mode 100644
index 000000000..cb57c0e25
--- /dev/null
+++ b/src/target/armv7m_cache.c
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Copyright (C) 2025 by STMicroelectronics
+ * Copyright (C) 2025 by Antonio Borneo <bor...@gm...>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdint.h>
+
+#include <helper/align.h>
+#include <helper/bitfield.h>
+#include <helper/bits.h>
+#include <helper/command.h>
+#include <helper/log.h>
+#include <helper/types.h>
+#include <target/arm_adi_v5.h>
+#include <target/armv7m_cache.h>
+#include <target/cortex_m.h>
+
+static int get_cache_info(struct adiv5_ap *ap, unsigned int cl,
+ unsigned int ind, uint32_t *ccsidr)
+{
+ uint32_t csselr = FIELD_PREP(CSSELR_LEVEL_MASK, cl)
+ | FIELD_PREP(CSSELR_IND_MASK, ind);
+
+ int retval = mem_ap_write_u32(ap, CSSELR, csselr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return mem_ap_read_u32(ap, CCSIDR, ccsidr);
+}
+
+static int get_d_u_cache_info(struct adiv5_ap *ap, unsigned int cl,
+ uint32_t *ccsidr)
+{
+ return get_cache_info(ap, cl, CSSELR_IND_DATA_OR_UNIFIED_CACHE, ccsidr);
+}
+
+static int get_i_cache_info(struct adiv5_ap *ap, unsigned int cl,
+ uint32_t *ccsidr)
+{
+ return get_cache_info(ap, cl, CSSELR_IND_INSTRUCTION_CACHE, ccsidr);
+}
+
+static struct armv7m_cache_size decode_ccsidr(uint32_t ccsidr)
+{
+ struct armv7m_cache_size size;
+
+ size.line_len = 16 << FIELD_GET(CCSIDR_LINESIZE_MASK, ccsidr);
+ size.associativity = FIELD_GET(CCSIDR_ASSOCIATIVITY_MASK, ccsidr) + 1;
+ size.num_sets = FIELD_GET(CCSIDR_NUMSETS_MASK, ccsidr) + 1;
+ size.cache_size = size.line_len * size.associativity * size.num_sets / 1024;
+
+ // compute info for set way operation on cache
+ size.index_shift = FIELD_GET(CCSIDR_LINESIZE_MASK, ccsidr) + 2;
+ size.index = FIELD_GET(CCSIDR_NUMSETS_MASK, ccsidr);
+ size.way = FIELD_GET(CCSIDR_ASSOCIATIVITY_MASK, ccsidr);
+
+ unsigned int i = 0;
+ while (((size.way << i) & 0x80000000) == 0)
+ i++;
+ size.way_shift = i;
+
+ return size;
+}
+
+int armv7m_identify_cache(struct target *target)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
+
+ uint32_t clidr;
+ int retval = mem_ap_read_u32(armv7m->debug_ap, CLIDR, &clidr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ uint32_t ctr;
+ retval = mem_ap_read_u32(armv7m->debug_ap, CTR, &ctr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ // retrieve selected cache for later restore
+ uint32_t csselr;
+ retval = mem_ap_read_atomic_u32(armv7m->debug_ap, CSSELR, &csselr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (clidr == 0) {
+ LOG_TARGET_DEBUG(target, "No cache detected");
+ return ERROR_OK;
+ }
+
+ if (FIELD_GET(CTR_FORMAT_MASK, ctr) != CTR_FORMAT_PROVIDED) {
+ LOG_ERROR("Wrong value in CTR register");
+ return ERROR_FAIL;
+ }
+
+ cache->i_min_line_len = 4UL << FIELD_GET(CTR_IMINLINE_MASK, ctr);
+ cache->d_min_line_len = 4UL << FIELD_GET(CTR_DMINLINE_MASK, ctr);
+ LOG_TARGET_DEBUG(target,
+ "ctr=0x%" PRIx32 " ctr.i_min_line_len=%" PRIu32 " ctr.d_min_line_len=%" PRIu32,
+ ctr, cache->i_min_line_len, cache->d_min_line_len);
+
+ cache->loc = FIELD_GET(CLIDR_LOC_MASK, clidr);
+ LOG_TARGET_DEBUG(target,
+ "clidr=0x%" PRIx32 " Number of cache levels to PoC=%" PRIu32,
+ clidr, cache->loc);
+
+ // retrieve all available inner caches
+ uint32_t d_u_ccsidr[8], i_ccsidr[8];
+ for (unsigned int cl = 0; cl < cache->loc; cl++) {
+ unsigned int ctype = FIELD_GET(CLIDR_CTYPE_MASK(cl + 1), clidr);
+
+ // skip reserved values
+ if (ctype > CLIDR_CTYPE_UNIFIED_CACHE)
+ continue;
+
+ cache->arch[cl].ctype = ctype;
+
+ // separate d or unified d/i cache at this level ?
+ if (ctype & (CLIDR_CTYPE_UNIFIED_CACHE | CLIDR_CTYPE_D_CACHE)) {
+ // retrieve d-cache info
+ retval = get_d_u_cache_info(armv7m->debug_ap, cl, &d_u_ccsidr[cl]);
+ if (retval != ERROR_OK)
+ break;
+ }
+
+ if (ctype & CLIDR_CTYPE_I_CACHE) {
+ // retrieve i-cache info
+ retval = get_i_cache_info(armv7m->debug_ap, cl, &i_ccsidr[cl]);
+ if (retval != ERROR_OK)
+ break;
+ }
+ }
+
+ // restore selected cache
+ int retval1 = mem_ap_write_atomic_u32(armv7m->debug_ap, CSSELR, csselr);
+
+ if (retval != ERROR_OK)
+ return retval;
+ if (retval1 != ERROR_OK)
+ return retval1;
+
+ for (unsigned int cl = 0; cl < cache->loc; cl++) {
+ unsigned int ctype = cache->arch[cl].ctype;
+
+ // separate d or unified d/i cache at this level ?
+ if (ctype & (CLIDR_CTYPE_UNIFIED_CACHE | CLIDR_CTYPE_D_CACHE)) {
+ cache->has_d_u_cache = true;
+ cache->arch[cl].d_u_size = decode_ccsidr(d_u_ccsidr[cl]);
+
+ LOG_TARGET_DEBUG(target,
+ "data/unified cache index %" PRIu32 " << %" PRIu32 ", way %" PRIu32 " << %" PRIu32,
+ cache->arch[cl].d_u_size.index,
+ cache->arch[cl].d_u_size.index_shift,
+ cache->arch[cl].d_u_size.way,
+ cache->arch[cl].d_u_size.way_shift);
+
+ LOG_TARGET_DEBUG(target,
+ "cache line %" PRIu32 " bytes %" PRIu32 " KBytes asso %" PRIu32 " ways",
+ cache->arch[cl].d_u_size.line_len,
+ cache->arch[cl].d_u_size.cache_size,
+ cache->arch[cl].d_u_size.associativity);
+ }
+
+ if (ctype & CLIDR_CTYPE_I_CACHE) {
+ cache->has_i_cache = true;
+ cache->arch[cl].i_size = decode_ccsidr(i_ccsidr[cl]);
+
+ LOG_TARGET_DEBUG(target,
+ "instruction cache index %" PRIu32 " << %" PRIu32 ", way %" PRIu32 " << %" PRIu32,
+ cache->arch[cl].i_size.index,
+ cache->arch[cl].i_size.index_shift,
+ cache->arch[cl].i_size.way,
+ cache->arch[cl].i_size.way_shift);
+
+ LOG_TARGET_DEBUG(target,
+ "cache line %" PRIu32 " bytes %" PRIu32 " KBytes asso %" PRIu32 " ways",
+ cache->arch[cl].i_size.line_len,
+ cache->arch[cl].i_size.cache_size,
+ cache->arch[cl].i_size.associativity);
+ }
+ }
+
+ cache->info_valid = true;
+
+ return ERROR_OK;
+}
+
+int armv7m_d_cache_flush(struct target *target, uint32_t address,
+ unsigned int length)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
+
+ if (!cache->info_valid || !cache->has_d_u_cache)
+ return ERROR_OK;
+
+ uint32_t line_len = cache->d_min_line_len;
+ uint32_t addr_line = ALIGN_DOWN(address, line_len);
+ uint32_t addr_end = address + length;
+
+ while (addr_line < addr_end) {
+ int retval = mem_ap_write_u32(armv7m->debug_ap, DCCIMVAC, addr_line);
+ if (retval != ERROR_OK)
+ return retval;
+ addr_line += line_len;
+ keep_alive();
+ }
+
+ return dap_run(armv7m->debug_ap->dap);
+}
+
+int armv7m_i_cache_inval(struct target *target, uint32_t address,
+ unsigned int length)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
+
+ if (!cache->info_valid || !cache->has_i_cache)
+ return ERROR_OK;
+
+ uint32_t line_len = cache->i_min_line_len;
+ uint32_t addr_line = ALIGN_DOWN(address, line_len);
+ uint32_t addr_end = address + length;
+
+ while (addr_line < addr_end) {
+ int retval = mem_ap_write_u32(armv7m->debug_ap, ICIMVAU, addr_line);
+ if (retval != ERROR_OK)
+ return retval;
+ addr_line += line_len;
+ keep_alive();
+ }
+
+ return dap_run(armv7m->debug_ap->dap);
+}
+
+int armv7m_handle_cache_info_command(struct command_invocation *cmd,
+ struct target *target)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct armv7m_cache_common *cache = &armv7m->armv7m_cache;
+
+ if (!target_was_examined(target)) {
+ command_print(cmd, "Target not examined yet");
+ return ERROR_FAIL;
+ }
+
+ if (!cache->info_valid) {
+ command_print(cmd, "No cache detected");
+ return ERROR_OK;
+ }
+
+ for (unsigned int cl = 0; cl < cache->loc; cl++) {
+ struct armv7m_arch_cache *arch = &cache->arch[cl];
+
+ if (arch->ctype & CLIDR_CTYPE_I_CACHE)
+ command_print(cmd,
+ "L%d I-Cache: line length %" PRIu32 ", associativity %" PRIu32
+ ", num sets %" PRIu32 ", cache size %" PRIu32 " KBytes",
+ cl + 1,
+ arch->i_size.line_len,
+ arch->i_size.associativity,
+ arch->i_size.num_sets,
+ arch->i_size.cache_size);
+
+ if (arch->ctype & (CLIDR_CTYPE_UNIFIED_CACHE | CLIDR_CTYPE_D_CACHE))
+ command_print(cmd,
+ "L%d %c-Cache: line length %" PRIu32 ", associativity %" PRIu32
+ ", num sets %" PRIu32 ", cache size %" PRIu32 " KBytes",
+ cl + 1,
+ (arch->ctype & CLIDR_CTYPE_D_CACHE) ? 'D' : 'U',
+ arch->d_u_size.line_len,
+ arch->d_u_size.associativity,
+ arch->d_u_size.num_sets,
+ arch->d_u_size.cache_size);
+ }
+
+ return ERROR_OK;
+}
diff --git a/src/target/armv7m_cache.h b/src/target/armv7m_cache.h
new file mode 100644
index 000000000..576bff8d6
--- /dev/null
+++ b/src/target/armv7m_cache.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * Copyright (C) 2025 by STMicroelectronics
+ * Copyright (C) 2025 by Antonio Borneo <bor...@gm...>
+ */
+
+#ifndef OPENOCD_TARGET_ARMV7M_CACHE_H
+#define OPENOCD_TARGET_ARMV7M_CACHE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <helper/types.h>
+
+struct target;
+
+struct armv7m_cache_size {
+ // cache dimensioning
+ uint32_t line_len;
+ uint32_t associativity;
+ uint32_t num_sets;
+ uint32_t cache_size;
+ // info for set way operation on cache
+ uint32_t index;
+ uint32_t index_shift;
+ uint32_t way;
+ uint32_t way_shift;
+};
+
+// information about one architecture cache at any level
+struct armv7m_arch_cache {
+ unsigned int ctype; // cache type, CLIDR encoding
+ struct armv7m_cache_size d_u_size; // data cache
+ struct armv7m_cache_size i_size; // instruction cache
+};
+
+// common cache information
+struct armv7m_cache_common {
+ bool info_valid;
+ bool has_i_cache;
+ bool has_d_u_cache;
+ unsigned int loc; // level of coherency
+ uint32_t d_min_line_len; // minimum d-cache line_len
+ uint32_t i_min_line_len; // minimum i-cache line_len
+ struct armv7m_arch_cache arch[6]; // cache info, L1 - L7
+};
+
+int armv7m_identify_cache(struct target *target);
+int armv7m_d_cache_flush(struct target *target, uint32_t address,
+ unsigned int length);
+int armv7m_i_cache_inval(struct target *target, uint32_t address,
+ unsigned int length);
+int armv7m_handle_cache_info_command(struct command_invocation *cmd,
+ struct target *target);
+
+#endif /* OPENOCD_TARGET_ARMV7M_CACHE_H */
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 047a1d38e..bfcbbc289 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -21,6 +21,7 @@
#include "jtag/interface.h"
#include "breakpoints.h"
#include "cortex_m.h"
+#include "armv7m_cache.h"
#include "target_request.h"
#include "target_type.h"
#include "arm_adi_v5.h"
@@ -30,6 +31,7 @@
#include "arm_semihosting.h"
#include "smp.h"
#include <helper/nvp.h>
+#include <helper/string_choices.h>
#include <helper/time_support.h>
#include <rtt/rtt.h>
@@ -873,6 +875,14 @@ static int cortex_m_debug_entry(struct target *target)
return retval;
}
+ // read caches state
+ uint32_t ccr = 0;
+ if (armv7m->armv7m_cache.info_valid) {
+ retval = mem_ap_read_u32(armv7m->debug_ap, CCR, &ccr);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
/* Load all registers to arm.core_cache */
if (!cortex_m->slow_register_read) {
retval = cortex_m_fast_read_all_regs(target);
@@ -926,6 +936,11 @@ static int cortex_m_debug_entry(struct target *target)
secure_state ? "Secure" : "Non-Secure",
target_state_name(target));
+ if (armv7m->armv7m_cache.info_valid)
+ LOG_TARGET_DEBUG(target, "D-Cache %s, I-Cache %s",
+ str_enabled_disabled(ccr & CCR_DC_MASK),
+ str_enabled_disabled(ccr & CCR_IC_MASK));
+
/* Errata 3092511 workaround
* Cortex-M7 can halt in an incorrect address when breakpoint
* and exception occurs simultaneously */
@@ -1938,12 +1953,25 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
breakpoint->orig_instr);
if (retval != ERROR_OK)
return retval;
+ // make sure data cache is cleaned & invalidated down to PoC
+ retval = armv7m_d_cache_flush(target, breakpoint->address, breakpoint->length);
+ if (retval != ERROR_OK)
+ return retval;
+
retval = target_write_memory(target,
breakpoint->address & 0xFFFFFFFE,
breakpoint->length, 1,
code);
if (retval != ERROR_OK)
return retval;
+ // update i-cache at breakpoint location
+ retval = armv7m_d_cache_flush(target, breakpoint->address, breakpoint->length);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = armv7m_i_cache_inval(target, breakpoint->address, breakpoint->length);
+ if (retval != ERROR_OK)
+ return retval;
+
breakpoint->is_set = true;
}
@@ -1986,12 +2014,25 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
target_write_u32(target, comparator_list[fp_num].fpcr_address,
comparator_list[fp_num].fpcr_value);
} else {
+ // make sure data cache is cleaned & invalidated down to PoC
+ retval = armv7m_d_cache_flush(target, breakpoint->address, breakpoint->length);
+ if (retval != ERROR_OK)
+ return retval;
+
/* restore original instruction (kept in target endianness) */
retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE,
breakpoint->length, 1,
breakpoint->orig_instr);
if (retval != ERROR_OK)
return retval;
+
+ // update i-cache at breakpoint location
+ retval = armv7m_d_cache_flush(target, breakpoint->address, breakpoint->length);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = armv7m_i_cache_inval(target, breakpoint->address, breakpoint->length);
+ if (retval != ERROR_OK)
+ return retval;
}
breakpoint->is_set = false;
@@ -2906,6 +2947,12 @@ int cortex_m_examine(struct target *target)
LOG_TARGET_INFO(target, "target has %d breakpoints, %d watchpoints",
cortex_m->fp_num_code,
cortex_m->dwt_num_comp);
+
+ retval = armv7m_identify_cache(target);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Cannot detect cache");
+ return retval;
+ }
}
return ERROR_OK;
@@ -3238,6 +3285,16 @@ COMMAND_HANDLER(handle_cortex_m_reset_config_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_cortex_m_cache_info_command)
+{
+ if (CMD_ARGC)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct target *target = get_current_target(CMD_CTX);
+
+ return armv7m_handle_cache_info_command(CMD, target);
+}
+
static const struct command_registration cortex_m_exec_command_handlers[] = {
{
.name = "maskisr",
@@ -3260,6 +3317,13 @@ static const struct command_registration cortex_m_exec_command_handlers[] = {
.help = "configure software reset handling",
.usage = "['sysresetreq'|'vectreset']",
},
+ {
+ .name = "cache_info",
+ .handler = handle_cortex_m_cache_info_command,
+ .mode = COMMAND_EXEC,
+ .help = "display information about target caches",
+ .usage = "",
+ },
{
.chain = smp_command_handlers,
},
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index 82b2c1ecd..e0a4e8552 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -15,6 +15,7 @@
#define OPENOCD_TARGET_CORTEX_M_H
#include "armv7m.h"
+#include "helper/bitfield.h"
#include "helper/bits.h"
#define CORTEX_M_COMMON_MAGIC 0x1A451A45U
@@ -114,6 +115,45 @@ struct cortex_m_part_info {
#define FPU_FPCAR 0xE000EF38
#define FPU_FPDSCR 0xE000EF3C
+// Cache
+#define CCR 0xE000ED14
+#define CLIDR 0xE000ED78
+#define CTR 0xE000ED7C
+#define CCSIDR 0xE000ED80
+#define CSSELR 0xE000ED84
+#define ICIMVAU 0xE000EF58
+#define DCCIMVAC 0xE000EF70
+
+#define CCR_IC_MASK BIT(17)
+#define CCR_DC_MASK BIT(16)
+
+#define CLIDR_ICB_MASK GENMASK(31, 30)
+#define CLIDR_LOUU_MASK GENMASK(29, 27)
+#define CLIDR_LOC_MASK GENMASK(26, 24)
+#define CLIDR_LOUIS_MASK GENMASK(23, 21)
+#define CLIDR_CTYPE_MASK(i) (GENMASK(2, 0) << (3 * (i) - 3))
+
+#define CLIDR_CTYPE_I_CACHE BIT(0)
+#define CLIDR_CTYPE_D_CACHE BIT(1)
+#define CLIDR_CTYPE_UNIFIED_CACHE BIT(2)
+
+#define CTR_FORMAT_MASK GENMASK(31, 29)
+#define CTR_CWG_MASK GENMASK(27, 24)
+#define CTR_ERG_MASK GENMASK(23, 20)
+#define CTR_DMINLINE_MASK GENMASK(19, 16)
+#define CTR_IMINLINE_MASK GENMASK(3, 0)
+
+#define CTR_FORMAT_PROVIDED 0x04
+
+#define CCSIDR_NUMSETS_MASK GENMASK(27, 13)
+#define CCSIDR_ASSOCIATIVITY_MASK GENMASK(12, 3)
+#define CCSIDR_LINESIZE_MASK GENMASK(2, 0)
+
+#define CSSELR_LEVEL_MASK GENMASK(3, 1)
+#define CSSELR_IND_MASK BIT(0)
+#define CSSELR_IND_DATA_OR_UNIFIED_CACHE 0
+#define CSSELR_IND_INSTRUCTION_CACHE 1
+
#define TPIU_SSPSR 0xE0040000
#define TPIU_CSPSR 0xE0040004
#define TPIU_ACPR 0xE0040010
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 4 +
src/target/Makefile.am | 2 +
src/target/armv7m.h | 3 +
src/target/armv7m_cache.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++
src/target/armv7m_cache.h | 57 ++++++++++
src/target/cortex_m.c | 64 +++++++++++
src/target/cortex_m.h | 40 +++++++
7 files changed, 454 insertions(+)
create mode 100644 src/target/armv7m_cache.c
create mode 100644 src/target/armv7m_cache.h
hooks/post-receive
--
Main OpenOCD repository
|