X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farmv7a.c;h=db72afd2128dced727c0789226d038c75b93a0a3;hb=efe6991e804b0ad807b926c51108c92c3c627f83;hp=e274785226e7aa099be7fdf522df1bdb8de83cd2;hpb=3a292a1f34586b265b92e4662652683645e14201;p=openocd.git
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index e274785226..db72afd212 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -14,9 +14,7 @@
* 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. *
+ * along with this program. If not, see . *
***************************************************************************/
#ifdef HAVE_CONFIG_H
@@ -172,19 +170,12 @@ static int armv7a_read_ttbcr(struct target *target)
armv7a->armv7a_mmu.ttbr_mask[0],
armv7a->armv7a_mmu.ttbr_mask[1]);
- /* FIXME: default is hard coded LINUX border */
- armv7a->armv7a_mmu.os_border = 0xc0000000;
- if (ttbcr_n != 0) {
- LOG_INFO("SVC access above %" PRIx32,
- armv7a->armv7a_mmu.ttbr_range[0] + 1);
- armv7a->armv7a_mmu.os_border = armv7a->armv7a_mmu.ttbr_range[0] + 1;
- }
done:
dpm->finish(dpm);
return retval;
}
-/* method adapted to cortex A : reused arm v4 v5 method*/
+/* method adapted to Cortex-A : reused ARM v4 v5 method */
int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val)
{
uint32_t first_lvl_descriptor = 0x0;
@@ -364,7 +355,7 @@ int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va,
break;
case 7:
LOG_INFO("inner: Write-Back, no Write-Allocate");
-
+ break;
default:
LOG_INFO("inner: %" PRIx32 " ???", INNER);
}
@@ -376,31 +367,6 @@ done:
return retval;
}
-static int armv7a_handle_inner_cache_info_command(struct command_context *cmd_ctx,
- struct armv7a_cache_common *armv7a_cache)
-{
- if (armv7a_cache->ctype == -1) {
- command_print(cmd_ctx, "cache not yet identified");
- return ERROR_OK;
- }
-
- command_print(cmd_ctx,
- "D-Cache: linelen %" PRIi32 ", associativity %" PRIi32 ", nsets %" PRIi32 ", cachesize %" PRId32 " KBytes",
- armv7a_cache->d_u_size.linelen,
- armv7a_cache->d_u_size.associativity,
- armv7a_cache->d_u_size.nsets,
- armv7a_cache->d_u_size.cachesize);
-
- command_print(cmd_ctx,
- "I-Cache: linelen %" PRIi32 ", associativity %" PRIi32 ", nsets %" PRIi32 ", cachesize %" PRId32 " KBytes",
- armv7a_cache->i_size.linelen,
- armv7a_cache->i_size.associativity,
- armv7a_cache->i_size.nsets,
- armv7a_cache->i_size.cachesize);
-
- return ERROR_OK;
-}
-
/* FIXME: remove it */
static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way)
{
@@ -457,13 +423,43 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)
(armv7a_cache->outer_cache);
- if (armv7a_cache->ctype == -1) {
+ int cl;
+
+ if (armv7a_cache->info == -1) {
command_print(cmd_ctx, "cache not yet identified");
return ERROR_OK;
}
- if (armv7a_cache->display_cache_info)
- armv7a_cache->display_cache_info(cmd_ctx, armv7a_cache);
+ for (cl = 0; cl < armv7a_cache->loc; cl++) {
+ struct armv7a_arch_cache *arch = &(armv7a_cache->arch[cl]);
+
+ if (arch->ctype & 1) {
+ command_print(cmd_ctx,
+ "L%d I-Cache: linelen %" PRIi32
+ ", associativity %" PRIi32
+ ", nsets %" PRIi32
+ ", cachesize %" PRId32 " KBytes",
+ cl+1,
+ arch->i_size.linelen,
+ arch->i_size.associativity,
+ arch->i_size.nsets,
+ arch->i_size.cachesize);
+ }
+
+ if (arch->ctype >= 2) {
+ command_print(cmd_ctx,
+ "L%d D-Cache: linelen %" PRIi32
+ ", associativity %" PRIi32
+ ", nsets %" PRIi32
+ ", cachesize %" PRId32 " KBytes",
+ cl+1,
+ arch->d_u_size.linelen,
+ arch->d_u_size.associativity,
+ arch->d_u_size.nsets,
+ arch->d_u_size.cachesize);
+ }
+ }
+
if (l2x_cache != NULL)
command_print(cmd_ctx, "Outer unified cache Base Address 0x%" PRIx32 ", %" PRId32 " ways",
l2x_cache->base, l2x_cache->way);
@@ -517,17 +513,61 @@ done:
}
+static int get_cache_info(struct arm_dpm *dpm, int cl, int ct, uint32_t *cache_reg)
+{
+ int retval = ERROR_OK;
+
+ /* select cache level */
+ retval = dpm->instr_write_data_r0(dpm,
+ ARMV4_5_MCR(15, 2, 0, 0, 0, 0),
+ (cl << 1) | (ct == 1 ? 1 : 0));
+ if (retval != ERROR_OK)
+ goto done;
+
+ retval = dpm->instr_read_data_r0(dpm,
+ ARMV4_5_MRC(15, 1, 0, 0, 0, 0),
+ cache_reg);
+ done:
+ return retval;
+}
+
+static struct armv7a_cachesize decode_cache_reg(uint32_t cache_reg)
+{
+ struct armv7a_cachesize size;
+ int i = 0;
+
+ size.linelen = 16 << (cache_reg & 0x7);
+ size.associativity = ((cache_reg >> 3) & 0x3ff) + 1;
+ size.nsets = ((cache_reg >> 13) & 0x7fff) + 1;
+ size.cachesize = size.linelen * size.associativity * size.nsets / 1024;
+
+ /* compute info for set way operation on cache */
+ size.index_shift = (cache_reg & 0x7) + 4;
+ size.index = (cache_reg >> 13) & 0x7fff;
+ size.way = ((cache_reg >> 3) & 0x3ff);
+
+ while (((size.way << i) & 0x80000000) == 0)
+ i++;
+ size.way_shift = i;
+
+ return size;
+}
+
int armv7a_identify_cache(struct target *target)
{
/* read cache descriptor */
int retval = ERROR_FAIL;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm_dpm *dpm = armv7a->arm.dpm;
- uint32_t cache_selected, clidr, ctr;
- uint32_t cache_i_reg, cache_d_reg;
- struct armv7a_cache_common *cache = &(armv7a->armv7a_mmu.armv7a_cache);
+ uint32_t csselr, clidr, ctr;
+ uint32_t cache_reg;
+ int cl, ctype;
+ struct armv7a_cache_common *cache =
+ &(armv7a->armv7a_mmu.armv7a_cache);
+
if (!armv7a->is_armv7r)
armv7a_read_ttbcr(target);
+
retval = dpm->prepare(dpm);
if (retval != ERROR_OK)
goto done;
@@ -552,129 +592,86 @@ int armv7a_identify_cache(struct target *target)
&clidr);
if (retval != ERROR_OK)
goto done;
- clidr = (clidr & 0x7000000) >> 23;
- LOG_INFO("number of cache level %" PRIx32, (uint32_t)(clidr / 2));
- if ((clidr / 2) > 1) {
- /* FIXME not supported present in cortex A8 and later */
- /* in cortex A7, A15 */
- LOG_ERROR("cache l2 present :not supported");
- }
- /* retrieve selected cache
+
+ cache->loc = (clidr & 0x7000000) >> 24;
+ LOG_DEBUG("Number of cache levels to PoC %" PRId32, cache->loc);
+
+ /* retrieve selected cache for later restore
* MRC p15, 2,, c0, c0, 0; Read CSSELR */
retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
- &cache_selected);
+ &csselr);
if (retval != ERROR_OK)
goto done;
- retval = armv7a->arm.mrc(target, 15,
- 2, 0, /* op1, op2 */
- 0, 0, /* CRn, CRm */
- &cache_selected);
- if (retval != ERROR_OK)
- goto done;
- /* select instruction cache
- * MCR p15, 2,, c0, c0, 0; Write CSSELR
- * [0] : 1 instruction cache selection , 0 data cache selection */
- retval = dpm->instr_write_data_r0(dpm,
- ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
- 1);
- if (retval != ERROR_OK)
- goto done;
-
- /* read CCSIDR
- * MRC P15,1,