unbreak arm11. TAP_INVALID is used to communicate inband that a special state should...
[openocd.git] / src / target / cortex_a8.c
blob025eb45f8f42ce11c1323418a543d14b270c9fa4
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2006 by Magnus Lundin *
6 * lundin@mlu.mine.nu *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * Copyright (C) 2009 by Dirk Behme *
12 * dirk.behme@gmail.com - copy from cortex_m3 *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 * *
29 * Cortex-A8(tm) TRM, ARM DDI 0344H *
30 * *
31 ***************************************************************************/
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
36 #include "cortex_a8.h"
37 #include "target_request.h"
38 #include "target_type.h"
41 /* cli handling */
42 int cortex_a8_register_commands(struct command_context_s *cmd_ctx);
44 /* forward declarations */
45 int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp);
47 target_type_t cortexa8_target =
49 .name = "cortex_a8",
51 .poll = NULL,
52 .arch_state = armv7m_arch_state,
54 .target_request_data = NULL,
56 .halt = NULL,
57 .resume = NULL,
58 .step = NULL,
60 .assert_reset = NULL,
61 .deassert_reset = NULL,
62 .soft_reset_halt = NULL,
64 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
66 .read_memory = cortex_a8_read_memory,
67 .write_memory = cortex_a8_write_memory,
68 .bulk_write_memory = NULL,
69 .checksum_memory = NULL,
70 .blank_check_memory = NULL,
72 .run_algorithm = armv7m_run_algorithm,
74 .add_breakpoint = NULL,
75 .remove_breakpoint = NULL,
76 .add_watchpoint = NULL,
77 .remove_watchpoint = NULL,
79 .register_commands = cortex_a8_register_commands,
80 .target_create = cortex_a8_target_create,
81 .init_target = NULL,
82 .examine = NULL,
83 .quit = NULL
86 int cortex_a8_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
88 u16 dcrdr;
90 mem_ap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
91 *ctrl = (u8)dcrdr;
92 *value = (u8)(dcrdr >> 8);
94 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
96 /* write ack back to software dcc register
97 * signify we have read data */
98 if (dcrdr & (1 << 0))
100 dcrdr = 0;
101 mem_ap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
104 return ERROR_OK;
107 int cortex_a8_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
109 /* get pointers to arch-specific information */
110 armv7m_common_t *armv7m = target->arch_info;
111 swjdp_common_t *swjdp = &armv7m->swjdp_info;
112 int retval;
114 /* sanitize arguments */
115 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
116 return ERROR_INVALID_ARGUMENTS;
118 /* cortex_a8 handles unaligned memory access */
120 switch (size)
122 case 4:
123 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
124 break;
125 case 2:
126 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
127 break;
128 case 1:
129 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
130 break;
131 default:
132 LOG_ERROR("BUG: we shouldn't get here");
133 exit(-1);
136 return retval;
139 int cortex_a8_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
141 /* get pointers to arch-specific information */
142 armv7m_common_t *armv7m = target->arch_info;
143 swjdp_common_t *swjdp = &armv7m->swjdp_info;
144 int retval;
146 /* sanitize arguments */
147 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
148 return ERROR_INVALID_ARGUMENTS;
150 switch (size)
152 case 4:
153 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
154 break;
155 case 2:
156 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
157 break;
158 case 1:
159 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
160 break;
161 default:
162 LOG_ERROR("BUG: we shouldn't get here");
163 exit(-1);
166 return retval;
169 int cortex_a8_handle_target_request(void *priv)
171 target_t *target = priv;
172 if (!target_was_examined(target))
173 return ERROR_OK;
174 armv7m_common_t *armv7m = target->arch_info;
175 swjdp_common_t *swjdp = &armv7m->swjdp_info;
177 if (!target->dbg_msg_enabled)
178 return ERROR_OK;
180 if (target->state == TARGET_RUNNING)
182 u8 data;
183 u8 ctrl;
185 cortex_a8_dcc_read(swjdp, &data, &ctrl);
187 /* check if we have data */
188 if (ctrl & (1 << 0))
190 u32 request;
192 /* we assume target is quick enough */
193 request = data;
194 cortex_a8_dcc_read(swjdp, &data, &ctrl);
195 request |= (data << 8);
196 cortex_a8_dcc_read(swjdp, &data, &ctrl);
197 request |= (data << 16);
198 cortex_a8_dcc_read(swjdp, &data, &ctrl);
199 request |= (data << 24);
200 target_request(target, request);
204 return ERROR_OK;
207 int cortex_a8_init_arch_info(target_t *target, cortex_a8_common_t *cortex_a8, jtag_tap_t *tap)
209 armv7m_common_t *armv7m;
210 armv7m = &cortex_a8->armv7m;
212 /* prepare JTAG information for the new target */
213 cortex_a8->jtag_info.tap = tap;
214 cortex_a8->jtag_info.scann_size = 4;
216 armv7m->swjdp_info.dp_select_value = -1;
217 armv7m->swjdp_info.ap_csw_value = -1;
218 armv7m->swjdp_info.ap_tar_value = -1;
219 armv7m->swjdp_info.jtag_info = &cortex_a8->jtag_info;
221 /* initialize arch-specific breakpoint handling */
223 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
224 cortex_a8->arch_info = NULL;
226 /* register arch-specific functions */
227 armv7m->examine_debug_reason = NULL;
229 armv7m->pre_debug_entry = NULL;
230 armv7m->post_debug_entry = NULL;
232 armv7m->pre_restore_context = NULL;
233 armv7m->post_restore_context = NULL;
235 armv7m_init_arch_info(target, armv7m);
236 armv7m->arch_info = cortex_a8;
237 armv7m->load_core_reg_u32 = NULL;
238 armv7m->store_core_reg_u32 = NULL;
240 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
242 return ERROR_OK;
245 int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp)
247 cortex_a8_common_t *cortex_a8 = calloc(1,sizeof(cortex_a8_common_t));
249 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
251 return ERROR_OK;
254 int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
256 int retval;
258 retval = armv7m_register_commands(cmd_ctx);
260 register_command(cmd_ctx, NULL, "cortex_a8", NULL, COMMAND_ANY, "cortex_a8 specific commands");
262 return retval;