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 <helper/replacements.h>
26 #include "arm_disassembler.h"
29 #include <helper/binarybuffer.h>
30 #include <helper/command.h>
37 static void armv7a_show_fault_registers(struct target
*target
)
39 uint32_t dfsr
, ifsr
, dfar
, ifar
;
40 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
41 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
44 retval
= dpm
->prepare(dpm
);
45 if (retval
!= ERROR_OK
)
48 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
50 /* c5/c0 - {data, instruction} fault status registers */
51 retval
= dpm
->instr_read_data_r0(dpm
,
52 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
54 if (retval
!= ERROR_OK
)
57 retval
= dpm
->instr_read_data_r0(dpm
,
58 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
60 if (retval
!= ERROR_OK
)
63 /* c6/c0 - {data, instruction} fault address registers */
64 retval
= dpm
->instr_read_data_r0(dpm
,
65 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
67 if (retval
!= ERROR_OK
)
70 retval
= dpm
->instr_read_data_r0(dpm
,
71 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
73 if (retval
!= ERROR_OK
)
76 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
77 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
78 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
79 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
82 /* (void) */ dpm
->finish(dpm
);
85 int armv7a_arch_state(struct target
*target
)
87 static const char *state
[] =
92 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
93 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
95 if (armv7a
->common_magic
!= ARMV7_COMMON_MAGIC
)
97 LOG_ERROR("BUG: called for a non-ARMv7A target");
98 return ERROR_INVALID_ARGUMENTS
;
101 armv4_5_arch_state(target
);
103 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
104 state
[armv7a
->armv4_5_mmu
.mmu_enabled
],
105 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
106 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
]);
108 if (armv4_5
->core_mode
== ARM_MODE_ABT
)
109 armv7a_show_fault_registers(target
);
110 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
111 LOG_USER("Watchpoint triggered at PC %#08x",
112 (unsigned) armv7a
->dpm
.wp_pc
);
118 COMMAND_HANDLER(handle_dap_baseaddr_command
)
120 struct target
*target
= get_current_target(CMD_CTX
);
121 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
122 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
124 return CALL_COMMAND_HANDLER(dap_baseaddr_command
, swjdp
);
127 COMMAND_HANDLER(handle_dap_memaccess_command
)
129 struct target
*target
= get_current_target(CMD_CTX
);
130 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
131 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
133 return CALL_COMMAND_HANDLER(dap_memaccess_command
, swjdp
);
136 COMMAND_HANDLER(handle_dap_apsel_command
)
138 struct target
*target
= get_current_target(CMD_CTX
);
139 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
140 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
142 return CALL_COMMAND_HANDLER(dap_apsel_command
, swjdp
);
145 COMMAND_HANDLER(handle_dap_apid_command
)
147 struct target
*target
= get_current_target(CMD_CTX
);
148 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
149 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
151 return CALL_COMMAND_HANDLER(dap_apid_command
, swjdp
);
154 COMMAND_HANDLER(handle_dap_info_command
)
156 struct target
*target
= get_current_target(CMD_CTX
);
157 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
158 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
163 apsel
= swjdp
->apsel
;
166 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], apsel
);
169 return ERROR_COMMAND_SYNTAX_ERROR
;
172 return dap_info_command(CMD_CTX
, swjdp
, apsel
);
175 static const struct command_registration armv7a_exec_command_handlers
[] = {
178 .handler
= &handle_dap_info_command
,
179 .mode
= COMMAND_EXEC
,
180 .help
= "dap info for ap [num], "
181 "default currently selected AP",
185 .handler
= &handle_dap_apsel_command
,
186 .mode
= COMMAND_EXEC
,
187 .help
= "select a different AP [num] (default 0)",
191 .handler
= &handle_dap_apid_command
,
192 .mode
= COMMAND_EXEC
,
193 .help
= "return id reg from AP [num], "
194 "default currently selected AP",
198 .handler
= &handle_dap_baseaddr_command
,
199 .mode
= COMMAND_EXEC
,
200 .help
= "return debug base address from AP [num], "
201 "default currently selected AP",
205 .handler
= &handle_dap_memaccess_command
,
206 .mode
= COMMAND_EXEC
,
207 .help
= "set/get number of extra tck for mem-ap memory "
208 "bus access [0-255]",
210 COMMAND_REGISTRATION_DONE
212 const struct command_registration armv7a_command_handlers
[] = {
216 .help
= "Cortex DAP command group",
217 .chain
= armv7a_exec_command_handlers
,
219 COMMAND_REGISTRATION_DONE