ARM: rename ARMV4_5_MODE_* as ARM_MODE_*
[fw/openocd] / src / target / armv7a.c
1 /***************************************************************************
2  *    Copyright (C) 2009 by David Brownell                                 *
3  *                                                                         *
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.                                   *
8  *                                                                         *
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.                          *
13  *                                                                         *
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  ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <helper/replacements.h>
24
25 #include "armv7a.h"
26 #include "arm_disassembler.h"
27
28 #include "register.h"
29 #include <helper/binarybuffer.h>
30 #include <helper/command.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36
37 static void armv7a_show_fault_registers(struct target *target)
38 {
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;
42         int retval;
43
44         retval = dpm->prepare(dpm);
45         if (retval != ERROR_OK)
46                 return;
47
48         /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
49
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),
53                         &dfsr);
54         if (retval != ERROR_OK)
55                 goto done;
56
57         retval = dpm->instr_read_data_r0(dpm,
58                         ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
59                         &ifsr);
60         if (retval != ERROR_OK)
61                 goto done;
62
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),
66                         &dfar);
67         if (retval != ERROR_OK)
68                 goto done;
69
70         retval = dpm->instr_read_data_r0(dpm,
71                         ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
72                         &ifar);
73         if (retval != ERROR_OK)
74                 goto done;
75
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);
80
81 done:
82         /* (void) */ dpm->finish(dpm);
83 }
84
85 int armv7a_arch_state(struct target *target)
86 {
87         static const char *state[] =
88         {
89                 "disabled", "enabled"
90         };
91
92         struct armv7a_common *armv7a = target_to_armv7a(target);
93         struct arm *armv4_5 = &armv7a->armv4_5_common;
94
95         if (armv7a->common_magic != ARMV7_COMMON_MAGIC)
96         {
97                 LOG_ERROR("BUG: called for a non-ARMv7A target");
98                 return ERROR_INVALID_ARGUMENTS;
99         }
100
101         armv4_5_arch_state(target);
102
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]);
107
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);
113
114         return ERROR_OK;
115 }
116
117
118 COMMAND_HANDLER(handle_dap_baseaddr_command)
119 {
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;
123
124         return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp);
125 }
126
127 COMMAND_HANDLER(handle_dap_memaccess_command)
128 {
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;
132
133         return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp);
134 }
135
136 COMMAND_HANDLER(handle_dap_apsel_command)
137 {
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;
141
142         return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp);
143 }
144
145 COMMAND_HANDLER(handle_dap_apid_command)
146 {
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;
150
151         return CALL_COMMAND_HANDLER(dap_apid_command, swjdp);
152 }
153
154 COMMAND_HANDLER(handle_dap_info_command)
155 {
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;
159         uint32_t apsel;
160
161         switch (CMD_ARGC) {
162         case 0:
163                 apsel = swjdp->apsel;
164                 break;
165         case 1:
166                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
167                 break;
168         default:
169                 return ERROR_COMMAND_SYNTAX_ERROR;
170         }
171
172         return dap_info_command(CMD_CTX, swjdp, apsel);
173 }
174
175 static const struct command_registration armv7a_exec_command_handlers[] = {
176         {
177                 .name = "info",
178                 .handler = &handle_dap_info_command,
179                 .mode = COMMAND_EXEC,
180                 .help = "dap info for ap [num], "
181                         "default currently selected AP",
182         },
183         {
184                 .name = "apsel",
185                 .handler = &handle_dap_apsel_command,
186                 .mode = COMMAND_EXEC,
187                 .help = "select a different AP [num] (default 0)",
188         },
189         {
190                 .name = "apid",
191                 .handler = &handle_dap_apid_command,
192                 .mode = COMMAND_EXEC,
193                 .help = "return id reg from AP [num], "
194                         "default currently selected AP",
195         },
196         {
197                 .name = "baseaddr",
198                 .handler = &handle_dap_baseaddr_command,
199                 .mode = COMMAND_EXEC,
200                 .help = "return debug base address from AP [num], "
201                         "default currently selected AP",
202         },
203         {
204                 .name = "memaccess",
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]",
209         },
210         COMMAND_REGISTRATION_DONE
211 };
212 const struct command_registration armv7a_command_handlers[] = {
213         {
214                 .name = "dap",
215                 .mode = COMMAND_ANY,
216                 .help = "Cortex DAP command group",
217                 .chain = armv7a_exec_command_handlers,
218         },
219         COMMAND_REGISTRATION_DONE
220 };
221