24 #define SCTLR_BIT_AFE (1 << 29)
33 uint32_t virt = va & ~0xfff, value;
34 uint32_t NOS, NS, INNER, OUTER,
SS;
53 SS = (value >> 1) & 1;
54 NOS = (value >> 10) & 1;
55 NS = (value >> 9) & 1;
56 INNER = (value >> 4) & 0x7;
57 OUTER = (value >> 2) & 0x3;
61 *val = value & 0xff000000;
65 *val |= (va & 0xffffff);
67 *val = (value & ~0xfff) + (va & 0xfff);
72 NOS == 1 ?
"not" :
" ",
74 SS == 0 ?
"not" :
"");
80 LOG_INFO(
"outer: Write-Back, Write-Allocate");
83 LOG_INFO(
"outer: Write-Through, No Write-Allocate");
86 LOG_INFO(
"outer: Write-Back, no Write-Allocate");
100 LOG_INFO(
"inner: Write-Back, Write-Allocate");
106 LOG_INFO(
"inner: Write-Back, no Write-Allocate");
109 LOG_INFO(
"inner: %" PRIx32
" ???", INNER);
121 static char bits_string[64];
127 bool priv = !(ap10 & 2);
128 len = snprintf(bits_string,
sizeof(bits_string),
"%s%s%s access%s: %s%s",
129 s_bit ?
"S " :
"", c_bit ?
"C " :
"", b_bit ?
"B " :
"",
130 priv ?
"(priv)" :
"", acc_r ?
"R" :
"N", acc_w ?
"W " :
"O ");
132 bool priv_acc_w = !ap2;
133 bool priv_acc_r =
true;
134 bool unpriv_acc_w = priv_acc_w;
135 bool unpriv_acc_r = priv_acc_r;
139 priv_acc_r = priv_acc_w =
false;
140 unpriv_acc_r = unpriv_acc_w =
false;
143 unpriv_acc_r = unpriv_acc_w =
false;
146 unpriv_acc_w =
false;
152 len = snprintf(bits_string,
sizeof(bits_string),
"%s%s%s access(priv): %s%s access(unpriv): %s%s",
153 s_bit ?
"S " :
"", c_bit ?
"C " :
"", b_bit ?
"B " :
"", priv_acc_r ?
"R" :
"N", priv_acc_w ?
"W" :
"O",
154 unpriv_acc_r ?
"R" :
"N", unpriv_acc_w ?
"W" :
"O");
157 if (len >=
sizeof(bits_string))
165 bool c_bit = !!(l2_desc & (1 << 3));
166 bool b_bit = !!(l2_desc & (1 << 2));
167 bool s_bit = !!(l2_desc & (1 << 10));
168 bool ap2 = !!(l2_desc & (1 << 9));
169 int ap10 = (l2_desc >> 4) & 3;
176 bool c_bit = !!(l1_desc & (1 << 3));
177 bool b_bit = !!(l1_desc & (1 << 2));
178 bool s_bit = !!(l1_desc & (1 << 16));
179 bool ap2 = !!(l1_desc & (1 << 15));
180 int ap10 = (l1_desc >> 10) & 3;
192 uint32_t *first_lvl_ptbl;
197 int max_pt_idx = 4095;
212 if (max_pt_idx < 1 || max_pt_idx > 4096)
223 if (ttbidx < 0 || ttbidx > 1)
229 int ttbcr_n = mmu->
ttbcr & 0x7;
230 max_pt_idx = 0x0fff >> ttbcr_n;
236 first_lvl_ptbl = malloc(
sizeof(uint32_t)*(max_pt_idx+1));
248 LOG_ERROR(
"Failed to read first-level page table!");
254 for (pt_idx = 0; pt_idx <= max_pt_idx;) {
256 (uint8_t *)&first_lvl_ptbl[pt_idx]);
258 LOG_DEBUG(
"L1 desc[%8.8x]: %8.8"PRIx32, pt_idx << 20, first_lvl_descriptor);
261 if ((first_lvl_descriptor & 3) == 0) {
264 if ((first_lvl_descriptor & 0x40002) == 2) {
266 uint32_t va_range = 1024*1024-1;
267 uint32_t va_start = pt_idx << 20;
268 uint32_t va_end = va_start + va_range;
270 uint32_t pa_start = (first_lvl_descriptor & 0xfff00000);
271 uint32_t pa_end = pa_start + va_range;
273 LOG_USER(
"SECT: VA[%8.8"PRIx32
" -- %8.8"PRIx32
"]: PA[%8.8"PRIx32
" -- %8.8"PRIx32
"] %s",
277 if ((first_lvl_descriptor & 0x40002) == 0x40002) {
279 uint32_t va_range = 16*1024*1024-1;
280 uint32_t va_start = pt_idx << 20;
281 uint32_t va_end = va_start + va_range;
283 uint32_t pa_start = (first_lvl_descriptor & 0xff000000);
284 uint32_t pa_end = pa_start + va_range;
286 LOG_USER(
"SSCT: VA[%8.8"PRIx32
" -- %8.8"PRIx32
"]: PA[%8.8"PRIx32
" -- %8.8"PRIx32
"] %s",
292 target_addr_t second_lvl_ptbl = first_lvl_descriptor & 0xfffffc00;
293 uint32_t second_lvl_descriptor;
300 4, 256, (uint8_t *)pt2);
302 LOG_ERROR(
"Failed to read second-level page table!");
306 for (pt2_idx = 0; pt2_idx < 256; ) {
308 (uint8_t *)&pt2[pt2_idx]);
310 if ((second_lvl_descriptor & 3) == 0) {
314 if ((second_lvl_descriptor & 3) == 1) {
316 uint32_t va_range = 64*1024-1;
317 uint32_t va_start = (pt_idx << 20) + (pt2_idx << 12);
318 uint32_t va_end = va_start + va_range;
320 uint32_t pa_start = (second_lvl_descriptor & 0xffff0000);
321 uint32_t pa_end = pa_start + va_range;
323 LOG_USER(
"LPGE: VA[%8.8"PRIx32
" -- %8.8"PRIx32
"]: PA[%8.8"PRIx32
" -- %8.8"PRIx32
"] %s",
329 uint32_t va_range = 4*1024-1;
330 uint32_t va_start = (pt_idx << 20) + (pt2_idx << 12);
331 uint32_t va_end = va_start + va_range;
333 uint32_t pa_start = (second_lvl_descriptor & 0xfffff000);
334 uint32_t pa_end = pa_start + va_range;
336 LOG_USER(
"SPGE: VA[%8.8"PRIx32
" -- %8.8"PRIx32
"]: PA[%8.8"PRIx32
" -- %8.8"PRIx32
"] %s",
347 free(first_lvl_ptbl);
354 .handler = armv7a_mmu_dump_table,
356 .help =
"dump translation table 0, 1 or from <address>",
357 .usage =
"(0|1|addr <address> [num_entries])",
366 .help =
"mmu command group",
Holds the interface to ARM cores.
Macros used to generate various ARM or Thumb opcodes.
#define ARMV4_5_MRC(cp, op1, rd, crn, crm, op2)
#define ARMV4_5_MCR(cp, op1, rd, crn, crm, op2)
static struct armv7a_common * target_to_armv7a(struct target *target)
COMMAND_HANDLER(armv7a_mmu_dump_table)
const struct command_registration armv7a_mmu_command_handlers[]
static const char * l1_desc_bits_to_string(uint32_t l1_desc, bool afe)
int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va, target_addr_t *val, int meminfo)
static const struct command_registration armv7a_mmu_group_handlers[]
static const char * desc_bits_to_string(bool c_bit, bool b_bit, bool s_bit, bool ap2, int ap10, bool afe)
static const char * l2_desc_bits_to_string(uint32_t l2_desc, bool afe)
Support functions to access arbitrary bits in a byte array.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_COMMAND_ARGUMENT_INVALID
static struct cortex_a_common * target_to_cortex_a(struct target *target)
static struct esp_usb_jtag * priv
#define LOG_USER(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
This wraps an implementation of DPM primitives.
int(* instr_write_data_r0)(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
Runs one instruction, writing data to R0 before execution.
int(* finish)(struct arm_dpm *dpm)
Invoke after a series of instruction operations.
int(* prepare)(struct arm_dpm *dpm)
Invoke before a series of instruction operations.
int(* instr_read_data_r0)(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
Runs one instruction, reading data from r0 after execution.
struct arm_dpm * dpm
Handle for the debug module, if one is present.
int(* flush_all_data_cache)(struct target *target)
struct armv7a_mmu_common armv7a_mmu
struct armv7a_cache_common armv7a_cache
int(* read_physical_memory)(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
uint32_t cp15_control_reg
struct target * get_current_target(struct command_context *cmd_ctx)
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)