]> git.gag.com Git - fw/openocd/blob - src/target/arm966e.c
b3d8e158553a1c5b3d69e369798adc05c20dd33c
[fw/openocd] / src / target / arm966e.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2008 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
22  ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "arm966e.h"
28 #include "target_type.h"
29
30
31 #if 0
32 #define _DEBUG_INSTRUCTION_EXECUTION_
33 #endif
34
35 int arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e, struct jtag_tap *tap)
36 {
37         struct arm9tdmi_common *arm9tdmi = &arm966e->arm9tdmi_common;
38         struct arm7_9_common *arm7_9 = &arm9tdmi->arm7_9_common;
39
40         arm9tdmi_init_arch_info(target, arm9tdmi, tap);
41
42         arm966e->common_magic = ARM966E_COMMON_MAGIC;
43
44         /* The ARM966E-S implements the ARMv5TE architecture which
45          * has the BKPT instruction, so we don't have to use a watchpoint comparator
46          */
47         arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
48         arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
49
50         return ERROR_OK;
51 }
52
53 static int arm966e_target_create(struct target *target, Jim_Interp *interp)
54 {
55         struct arm966e_common *arm966e = calloc(1,sizeof(struct arm966e_common));
56
57         return arm966e_init_arch_info(target, arm966e, target->tap);
58 }
59
60 static int arm966e_verify_pointer(struct command_context *cmd_ctx,
61                 struct arm966e_common *arm966e)
62 {
63         if (arm966e->common_magic != ARM966E_COMMON_MAGIC) {
64                 command_print(cmd_ctx, "target is not an ARM966");
65                 return ERROR_TARGET_INVALID;
66         }
67         return ERROR_OK;
68 }
69
70 static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *value)
71 {
72         int retval = ERROR_OK;
73         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
74         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
75         struct scan_field fields[3];
76         uint8_t reg_addr_buf = reg_addr & 0x3f;
77         uint8_t nr_w_buf = 0;
78
79         jtag_set_end_state(TAP_IDLE);
80         if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
81         {
82                 return retval;
83         }
84         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
85
86         fields[0].tap = jtag_info->tap;
87         fields[0].num_bits = 32;
88         fields[0].out_value = NULL;
89         fields[0].in_value = NULL;
90
91         fields[1].tap = jtag_info->tap;
92         fields[1].num_bits = 6;
93         fields[1].out_value = &reg_addr_buf;
94         fields[1].in_value = NULL;
95
96         fields[2].tap = jtag_info->tap;
97         fields[2].num_bits = 1;
98         fields[2].out_value = &nr_w_buf;
99         fields[2].in_value = NULL;
100
101         jtag_add_dr_scan(3, fields, jtag_get_end_state());
102
103         fields[1].in_value = (uint8_t *)value;
104
105         jtag_add_dr_scan(3, fields, jtag_get_end_state());
106
107         jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
108
109
110 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
111         if ((retval = jtag_execute_queue()) != ERROR_OK)
112         {
113                 return retval;
114         }
115         LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
116 #endif
117
118         return ERROR_OK;
119 }
120
121 // EXPORTED to str9x (flash)
122 int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)
123 {
124         int retval = ERROR_OK;
125         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
126         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
127         struct scan_field fields[3];
128         uint8_t reg_addr_buf = reg_addr & 0x3f;
129         uint8_t nr_w_buf = 1;
130         uint8_t value_buf[4];
131
132         buf_set_u32(value_buf, 0, 32, value);
133
134         jtag_set_end_state(TAP_IDLE);
135         if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
136         {
137                 return retval;
138         }
139         arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
140
141         fields[0].tap = jtag_info->tap;
142         fields[0].num_bits = 32;
143         fields[0].out_value = value_buf;
144         fields[0].in_value = NULL;
145
146         fields[1].tap = jtag_info->tap;
147         fields[1].num_bits = 6;
148         fields[1].out_value = &reg_addr_buf;
149         fields[1].in_value = NULL;
150
151         fields[2].tap = jtag_info->tap;
152         fields[2].num_bits = 1;
153         fields[2].out_value = &nr_w_buf;
154         fields[2].in_value = NULL;
155
156         jtag_add_dr_scan(3, fields, jtag_get_end_state());
157
158 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
159         LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
160 #endif
161
162         return ERROR_OK;
163 }
164
165 COMMAND_HANDLER(arm966e_handle_cp15_command)
166 {
167         int retval;
168         struct target *target = get_current_target(cmd_ctx);
169         struct arm966e_common *arm966e = target_to_arm966(target);
170
171         retval = arm966e_verify_pointer(cmd_ctx, arm966e);
172         if (retval != ERROR_OK)
173                 return retval;
174
175         if (target->state != TARGET_HALTED)
176         {
177                 command_print(cmd_ctx, "target must be stopped for \"%s\" command", CMD_NAME);
178                 return ERROR_OK;
179         }
180
181         /* one or more argument, access a single register (write if second argument is given */
182         if (argc >= 1)
183         {
184                 uint32_t address;
185                 COMMAND_PARSE_NUMBER(u32, args[0], address);
186
187                 if (argc == 1)
188                 {
189                         uint32_t value;
190                         if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
191                         {
192                                 command_print(cmd_ctx,
193                                                 "couldn't access reg %" PRIi32,
194                                                 address);
195                                 return ERROR_OK;
196                         }
197                         if ((retval = jtag_execute_queue()) != ERROR_OK)
198                         {
199                                 return retval;
200                         }
201
202                         command_print(cmd_ctx, "%" PRIi32 ": %8.8" PRIx32,
203                                         address, value);
204                 }
205                 else if (argc == 2)
206                 {
207                         uint32_t value;
208                         COMMAND_PARSE_NUMBER(u32, args[1], value);
209                         if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
210                         {
211                                 command_print(cmd_ctx,
212                                                 "couldn't access reg %" PRIi32,
213                                                 address);
214                                 return ERROR_OK;
215                         }
216                         command_print(cmd_ctx, "%" PRIi32 ": %8.8" PRIx32,
217                                         address, value);
218                 }
219         }
220
221         return ERROR_OK;
222 }
223
224 /** Registers commands used to access coprocessor resources. */
225 int arm966e_register_commands(struct command_context *cmd_ctx)
226 {
227         int retval;
228         struct command *arm966e_cmd;
229
230         retval = arm9tdmi_register_commands(cmd_ctx);
231         arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e",
232                         NULL, COMMAND_ANY,
233                         "arm966e specific commands");
234         register_command(cmd_ctx, arm966e_cmd, "cp15",
235                         arm966e_handle_cp15_command, COMMAND_EXEC,
236                         "display/modify cp15 register <num> [value]");
237
238         return retval;
239 }
240
241 /** Holds methods for ARM966 targets. */
242 struct target_type arm966e_target =
243 {
244         .name = "arm966e",
245
246         .poll = arm7_9_poll,
247         .arch_state = armv4_5_arch_state,
248
249         .target_request_data = arm7_9_target_request_data,
250
251         .halt = arm7_9_halt,
252         .resume = arm7_9_resume,
253         .step = arm7_9_step,
254
255         .assert_reset = arm7_9_assert_reset,
256         .deassert_reset = arm7_9_deassert_reset,
257         .soft_reset_halt = arm7_9_soft_reset_halt,
258
259         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
260
261         .read_memory = arm7_9_read_memory,
262         .write_memory = arm7_9_write_memory,
263         .bulk_write_memory = arm7_9_bulk_write_memory,
264         .checksum_memory = arm7_9_checksum_memory,
265         .blank_check_memory = arm7_9_blank_check_memory,
266
267         .run_algorithm = armv4_5_run_algorithm,
268
269         .add_breakpoint = arm7_9_add_breakpoint,
270         .remove_breakpoint = arm7_9_remove_breakpoint,
271         .add_watchpoint = arm7_9_add_watchpoint,
272         .remove_watchpoint = arm7_9_remove_watchpoint,
273
274         .register_commands = arm966e_register_commands,
275         .target_create = arm966e_target_create,
276         .init_target = arm9tdmi_init_target,
277         .examine = arm7_9_examine,
278 };