+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2016 by Matthias Welwarsky *
* matthias.welwarsky@sysgo.com *
* *
* Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com *
- * *
- * 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/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
/* V7 method VA TO PA */
int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va,
- uint32_t *val, int meminfo)
+ target_addr_t *val, int meminfo)
{
int retval = ERROR_FAIL;
struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm_dpm *dpm = armv7a->arm.dpm;
- uint32_t virt = va & ~0xfff;
- uint32_t NOS, NS, INNER, OUTER;
+ uint32_t virt = va & ~0xfff, value;
+ uint32_t NOS, NS, INNER, OUTER, SS;
*val = 0xdeadbeef;
retval = dpm->prepare(dpm);
if (retval != ERROR_OK)
goto done;
retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 0, 0, 7, 4, 0),
- val);
+ &value);
if (retval != ERROR_OK)
goto done;
- /* decode memory attribute */
- NOS = (*val >> 10) & 1; /* Not Outer shareable */
- NS = (*val >> 9) & 1; /* Non secure */
- INNER = (*val >> 4) & 0x7;
- OUTER = (*val >> 2) & 0x3;
- *val = (*val & ~0xfff) + (va & 0xfff);
+ /* decode memory attribute */
+ SS = (value >> 1) & 1;
+ NOS = (value >> 10) & 1; /* Not Outer shareable */
+ NS = (value >> 9) & 1; /* Non secure */
+ INNER = (value >> 4) & 0x7;
+ OUTER = (value >> 2) & 0x3;
+
+ if (SS) {
+ /* PAR[31:24] contains PA[31:24] */
+ *val = value & 0xff000000;
+ /* PAR [23:16] contains PA[39:32] */
+ *val |= (target_addr_t)(value & 0x00ff0000) << 16;
+ /* PA[23:12] is the same as VA[23:12] */
+ *val |= (va & 0xffffff);
+ } else {
+ *val = (value & ~0xfff) + (va & 0xfff);
+ }
if (meminfo) {
- LOG_INFO("%" PRIx32 " : %" PRIx32 " %s outer shareable %s secured",
+ LOG_INFO("%" PRIx32 " : %" TARGET_PRIxADDR " %s outer shareable %s secured %s super section",
va, *val,
NOS == 1 ? "not" : " ",
- NS == 1 ? "not" : "");
+ NS == 1 ? "not" : "",
+ SS == 0 ? "not" : "");
switch (OUTER) {
case 0:
LOG_INFO("outer: Non-Cacheable");
LOG_USER("Page Directory at (phys): %8.8" TARGET_PRIxADDR, ttb);
first_lvl_ptbl = malloc(sizeof(uint32_t)*(max_pt_idx+1));
- if (first_lvl_ptbl == NULL)
+ if (!first_lvl_ptbl)
return ERROR_FAIL;
/*
uint32_t first_lvl_descriptor = target_buffer_get_u32(target,
(uint8_t *)&first_lvl_ptbl[pt_idx]);
- LOG_DEBUG("L1 desc[%8.8"PRIx32"]: %8.8"PRIx32, pt_idx << 20, first_lvl_descriptor);
+ LOG_DEBUG("L1 desc[%8.8x]: %8.8"PRIx32, pt_idx << 20, first_lvl_descriptor);
/* skip empty entries in the first level table */
if ((first_lvl_descriptor & 3) == 0) {