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>
36 #include "arm_opcodes.h"
39 static void armv7a_show_fault_registers(struct target
*target
)
41 uint32_t dfsr
, ifsr
, dfar
, ifar
;
42 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
43 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
46 retval
= dpm
->prepare(dpm
);
47 if (retval
!= ERROR_OK
)
50 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
52 /* c5/c0 - {data, instruction} fault status registers */
53 retval
= dpm
->instr_read_data_r0(dpm
,
54 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
56 if (retval
!= ERROR_OK
)
59 retval
= dpm
->instr_read_data_r0(dpm
,
60 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
62 if (retval
!= ERROR_OK
)
65 /* c6/c0 - {data, instruction} fault address registers */
66 retval
= dpm
->instr_read_data_r0(dpm
,
67 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
69 if (retval
!= ERROR_OK
)
72 retval
= dpm
->instr_read_data_r0(dpm
,
73 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
75 if (retval
!= ERROR_OK
)
78 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
79 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
80 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
81 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
84 /* (void) */ dpm
->finish(dpm
);
87 int armv7a_arch_state(struct target
*target
)
89 static const char *state
[] =
94 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
95 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
97 if (armv7a
->common_magic
!= ARMV7_COMMON_MAGIC
)
99 LOG_ERROR("BUG: called for a non-ARMv7A target");
100 return ERROR_INVALID_ARGUMENTS
;
103 arm_arch_state(target
);
105 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
106 state
[armv7a
->armv4_5_mmu
.mmu_enabled
],
107 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
108 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
]);
110 if (armv4_5
->core_mode
== ARM_MODE_ABT
)
111 armv7a_show_fault_registers(target
);
112 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
113 LOG_USER("Watchpoint triggered at PC %#08x",
114 (unsigned) armv7a
->dpm
.wp_pc
);
120 COMMAND_HANDLER(handle_dap_baseaddr_command
)
122 struct target
*target
= get_current_target(CMD_CTX
);
123 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
124 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
126 return CALL_COMMAND_HANDLER(dap_baseaddr_command
, swjdp
);
129 COMMAND_HANDLER(handle_dap_memaccess_command
)
131 struct target
*target
= get_current_target(CMD_CTX
);
132 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
133 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
135 return CALL_COMMAND_HANDLER(dap_memaccess_command
, swjdp
);
138 COMMAND_HANDLER(handle_dap_apsel_command
)
140 struct target
*target
= get_current_target(CMD_CTX
);
141 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
142 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
144 return CALL_COMMAND_HANDLER(dap_apsel_command
, swjdp
);
147 COMMAND_HANDLER(handle_dap_apid_command
)
149 struct target
*target
= get_current_target(CMD_CTX
);
150 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
151 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
153 return CALL_COMMAND_HANDLER(dap_apid_command
, swjdp
);
156 COMMAND_HANDLER(handle_dap_info_command
)
158 struct target
*target
= get_current_target(CMD_CTX
);
159 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
160 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
165 apsel
= swjdp
->apsel
;
168 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], apsel
);
171 return ERROR_COMMAND_SYNTAX_ERROR
;
174 return dap_info_command(CMD_CTX
, swjdp
, apsel
);
177 /* FIXME this table should be part of generic DAP support, and
178 * be shared by the ARMv7-A/R and ARMv7-M support ...
180 static const struct command_registration armv7a_exec_command_handlers
[] = {
183 .handler
= handle_dap_info_command
,
184 .mode
= COMMAND_EXEC
,
185 .help
= "display ROM table for MEM-AP "
186 "(default currently selected AP)",
191 .handler
= handle_dap_apsel_command
,
192 .mode
= COMMAND_EXEC
,
193 .help
= "Set the currently selected AP (default 0) "
194 "and display the result",
199 .handler
= handle_dap_apid_command
,
200 .mode
= COMMAND_EXEC
,
201 .help
= "return ID register from AP "
202 "(default currently selected AP)",
207 .handler
= handle_dap_baseaddr_command
,
208 .mode
= COMMAND_EXEC
,
209 .help
= "return debug base address from MEM-AP "
210 "(default currently selected AP)",
215 .handler
= handle_dap_memaccess_command
,
216 .mode
= COMMAND_EXEC
,
217 .help
= "set/get number of extra tck for MEM-AP memory "
218 "bus access [0-255]",
221 COMMAND_REGISTRATION_DONE
223 const struct command_registration armv7a_command_handlers
[] = {
227 .help
= "Cortex DAP command group",
228 .chain
= armv7a_exec_command_handlers
,
230 COMMAND_REGISTRATION_DONE