1 /***************************************************************************
2 * Copyright (C) 2009 by David Brownell *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
23 #include "replacements.h"
26 #include "arm_disassembler.h"
29 #include "binarybuffer.h"
37 char* armv7a_core_reg_list[] =
39 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
40 "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
41 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
46 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
47 "r13_mon", "lr_mon", "spsr_mon"
50 char* armv7a_state_strings[] =
52 "ARM", "Thumb", "Jazelle", "ThumbEE"
55 struct armv7a_core_reg armv7a_core_reg_list_arch_info[] =
57 {0, ARMV4_5_MODE_ANY, NULL, NULL},
58 {1, ARMV4_5_MODE_ANY, NULL, NULL},
59 {2, ARMV4_5_MODE_ANY, NULL, NULL},
60 {3, ARMV4_5_MODE_ANY, NULL, NULL},
61 {4, ARMV4_5_MODE_ANY, NULL, NULL},
62 {5, ARMV4_5_MODE_ANY, NULL, NULL},
63 {6, ARMV4_5_MODE_ANY, NULL, NULL},
64 {7, ARMV4_5_MODE_ANY, NULL, NULL},
65 {8, ARMV4_5_MODE_ANY, NULL, NULL},
66 {9, ARMV4_5_MODE_ANY, NULL, NULL},
67 {10, ARMV4_5_MODE_ANY, NULL, NULL},
68 {11, ARMV4_5_MODE_ANY, NULL, NULL},
69 {12, ARMV4_5_MODE_ANY, NULL, NULL},
70 {13, ARMV4_5_MODE_USR, NULL, NULL},
71 {14, ARMV4_5_MODE_USR, NULL, NULL},
72 {15, ARMV4_5_MODE_ANY, NULL, NULL},
74 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
75 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
76 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
77 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
78 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
79 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
80 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
82 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
83 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
85 {13, ARMV4_5_MODE_SVC, NULL, NULL},
86 {14, ARMV4_5_MODE_SVC, NULL, NULL},
88 {13, ARMV4_5_MODE_ABT, NULL, NULL},
89 {14, ARMV4_5_MODE_ABT, NULL, NULL},
91 {13, ARMV4_5_MODE_UND, NULL, NULL},
92 {14, ARMV4_5_MODE_UND, NULL, NULL},
94 {16, ARMV4_5_MODE_ANY, NULL, NULL},
95 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
96 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
97 {16, ARMV4_5_MODE_SVC, NULL, NULL},
98 {16, ARMV4_5_MODE_ABT, NULL, NULL},
99 {16, ARMV4_5_MODE_UND, NULL, NULL},
101 {13, ARMV7A_MODE_MON, NULL, NULL},
102 {14, ARMV7A_MODE_MON, NULL, NULL},
103 {16, ARMV7A_MODE_MON, NULL, NULL}
106 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
107 int armv7a_core_reg_map[8][17] =
110 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
113 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
116 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
119 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
122 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
125 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
128 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
131 /* TODO Fix the register mapping for mon, we need r13_mon,
132 * r14_mon and spsr_mon
134 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
138 void armv7a_show_fault_registers(struct target *target)
140 uint32_t dfsr, ifsr, dfar, ifar;
141 struct armv7a_common *armv7a = target_to_armv7a(target);
143 armv7a->read_cp15(target, 0, 0, 5, 0, &dfsr);
144 armv7a->read_cp15(target, 0, 1, 5, 0, &ifsr);
145 armv7a->read_cp15(target, 0, 0, 6, 0, &dfar);
146 armv7a->read_cp15(target, 0, 2, 6, 0, &ifar);
148 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
149 ", DFAR: %8.8" PRIx32, dfsr, dfar);
150 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
151 ", IFAR: %8.8" PRIx32, ifsr, ifar);
155 int armv7a_arch_state(struct target *target)
157 static const char *state[] =
159 "disabled", "enabled"
162 struct armv7a_common *armv7a = target_to_armv7a(target);
163 struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
165 if (armv7a->common_magic != ARMV7_COMMON_MAGIC)
167 LOG_ERROR("BUG: called for a non-ARMv7A target");
168 return ERROR_INVALID_ARGUMENTS;
171 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
172 "%s: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
173 "MMU: %s, D-Cache: %s, I-Cache: %s",
174 armv7a_state_strings[armv7a->core_state],
175 Jim_Nvp_value2name_simple(nvp_target_debug_reason,
176 target->debug_reason)->name,
177 arm_mode_name(armv4_5->core_mode),
178 armv7a_core_reg_list[armv7a_core_reg_map[
179 armv7a_mode_to_number(armv4_5->core_mode)][16]],
180 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
181 armv4_5->core_mode, 16).value, 0, 32),
182 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
183 state[armv7a->armv4_5_mmu.mmu_enabled],
184 state[armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
185 state[armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
187 if (armv4_5->core_mode == ARMV7A_MODE_ABT)
188 armv7a_show_fault_registers(target);
194 COMMAND_HANDLER(handle_dap_baseaddr_command)
196 struct target *target = get_current_target(CMD_CTX);
197 struct armv7a_common *armv7a = target_to_armv7a(target);
198 struct swjdp_common *swjdp = &armv7a->swjdp_info;
200 return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp);
203 COMMAND_HANDLER(handle_dap_memaccess_command)
205 struct target *target = get_current_target(CMD_CTX);
206 struct armv7a_common *armv7a = target_to_armv7a(target);
207 struct swjdp_common *swjdp = &armv7a->swjdp_info;
209 return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp);
212 COMMAND_HANDLER(handle_dap_apsel_command)
214 struct target *target = get_current_target(CMD_CTX);
215 struct armv7a_common *armv7a = target_to_armv7a(target);
216 struct swjdp_common *swjdp = &armv7a->swjdp_info;
218 return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp);
221 COMMAND_HANDLER(handle_dap_apid_command)
223 struct target *target = get_current_target(CMD_CTX);
224 struct armv7a_common *armv7a = target_to_armv7a(target);
225 struct swjdp_common *swjdp = &armv7a->swjdp_info;
227 return CALL_COMMAND_HANDLER(dap_apid_command, swjdp);
230 COMMAND_HANDLER(handle_dap_info_command)
232 struct target *target = get_current_target(CMD_CTX);
233 struct armv7a_common *armv7a = target_to_armv7a(target);
234 struct swjdp_common *swjdp = &armv7a->swjdp_info;
239 apsel = swjdp->apsel;
242 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
245 return ERROR_COMMAND_SYNTAX_ERROR;
248 return dap_info_command(CMD_CTX, swjdp, apsel);
251 int armv7a_register_commands(struct command_context *cmd_ctx)
253 struct command *arm_adi_v5_dap_cmd;
255 arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap",
257 "cortex dap specific commands");
259 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info",
260 handle_dap_info_command, COMMAND_EXEC,
261 "dap info for ap [num], "
262 "default currently selected AP");
263 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel",
264 handle_dap_apsel_command, COMMAND_EXEC,
265 "select a different AP [num] (default 0)");
266 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid",
267 handle_dap_apid_command, COMMAND_EXEC,
268 "return id reg from AP [num], "
269 "default currently selected AP");
270 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "baseaddr",
271 handle_dap_baseaddr_command, COMMAND_EXEC,
272 "return debug base address from AP [num], "
273 "default currently selected AP");
274 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "memaccess",
275 handle_dap_memaccess_command, COMMAND_EXEC,
276 "set/get number of extra tck for mem-ap memory "
277 "bus access [0-255]");