From Michael Bruck
[fw/openocd] / src / target / arm_jtag.c
1 /***************************************************************************\r
2  *   Copyright (C) 2005 by Dominic Rath                                    *\r
3  *   Dominic.Rath@gmx.de                                                   *\r
4  *                                                                         *\r
5  *   This program is free software; you can redistribute it and/or modify  *\r
6  *   it under the terms of the GNU General Public License as published by  *\r
7  *   the Free Software Foundation; either version 2 of the License, or     *\r
8  *   (at your option) any later version.                                   *\r
9  *                                                                         *\r
10  *   This program is distributed in the hope that it will be useful,       *\r
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
13  *   GNU General Public License for more details.                          *\r
14  *                                                                         *\r
15  *   You should have received a copy of the GNU General Public License     *\r
16  *   along with this program; if not, write to the                         *\r
17  *   Free Software Foundation, Inc.,                                       *\r
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
19  ***************************************************************************/\r
20 #ifdef HAVE_CONFIG_H\r
21 #include "config.h"\r
22 #endif\r
23 \r
24 #include "arm_jtag.h"\r
25 \r
26 #include "binarybuffer.h"\r
27 #include "log.h"\r
28 #include "jtag.h"\r
29 \r
30 #include <stdlib.h>\r
31 \r
32 #if 0\r
33 #define _ARM_JTAG_SCAN_N_CHECK_\r
34 #endif\r
35 \r
36 int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr,  in_handler_t handler)\r
37 {\r
38         jtag_device_t *device = jtag_get_device(jtag_info->chain_pos);\r
39         \r
40         if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)\r
41         {\r
42                 scan_field_t field;\r
43         \r
44                 field.device = jtag_info->chain_pos;\r
45                 field.num_bits = device->ir_length;\r
46                 field.out_value = calloc(CEIL(field.num_bits, 8), 1);\r
47                 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);\r
48                 field.out_mask = NULL;\r
49                 field.in_value = NULL;\r
50                 field.in_check_value = NULL;\r
51                 field.in_check_mask = NULL;\r
52                 field.in_handler = handler;\r
53                 field.in_handler_priv = NULL;\r
54                 jtag_add_ir_scan(1, &field, -1);\r
55                 \r
56                 \r
57                 free(field.out_value);\r
58         }\r
59         \r
60         return ERROR_OK;\r
61 }\r
62 \r
63 int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)\r
64 {\r
65         if(jtag_info->cur_scan_chain != new_scan_chain)\r
66         {\r
67 #ifdef _ARM_JTAG_SCAN_N_CHECK_\r
68                 u8 scan_n_check_value = 1 << (jtag_info->scann_size - 1);\r
69 #endif\r
70                 scan_field_t field;\r
71                 \r
72                 field.device = jtag_info->chain_pos;\r
73                 field.num_bits = jtag_info->scann_size;\r
74                 field.out_value = calloc(CEIL(field.num_bits, 8), 1);\r
75                 buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);\r
76                 field.out_mask = NULL;\r
77                 field.in_value = NULL;\r
78 #ifdef _ARM_JTAG_SCAN_N_CHECK_\r
79                 jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL);\r
80 #else\r
81                 field.in_handler = NULL;\r
82                 field.in_handler_priv = NULL;\r
83 #endif \r
84                 \r
85                 \r
86                 arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);\r
87                 jtag_add_dr_scan(1, &field, -1);\r
88                 \r
89                 jtag_info->cur_scan_chain = new_scan_chain;\r
90                 \r
91                 free(field.out_value);\r
92         }\r
93         \r
94         return ERROR_OK;\r
95 }\r
96 \r
97 int arm_jtag_reset_callback(enum jtag_event event, void *priv)\r
98 {\r
99         arm_jtag_t *jtag_info = priv;\r
100         \r
101         if (event == JTAG_TRST_ASSERTED)\r
102         {\r
103                 jtag_info->cur_scan_chain = 0;\r
104         }\r
105         \r
106         return ERROR_OK;\r
107 }\r
108 \r
109 int arm_jtag_setup_connection(arm_jtag_t *jtag_info)\r
110 {\r
111         jtag_info->scann_instr = 0x2;\r
112         jtag_info->cur_scan_chain = 0;\r
113         jtag_info->intest_instr = 0xc;\r
114 \r
115         jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);\r
116         \r
117         return ERROR_OK;\r
118 }\r
119 \r
120 /* read JTAG buffer into host-endian u32, flipping bit-order */\r
121 int arm_jtag_buf_to_u32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)\r
122 {\r
123         u32 *dest = priv;\r
124         *dest = flip_u32(le_to_h_u32(in_buf), 32);\r
125         return ERROR_OK;\r
126 }\r
127 \r
128 /* read JTAG buffer into little-endian u32, flipping bit-order */\r
129 int arm_jtag_buf_to_le32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)\r
130 {\r
131         h_u32_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));\r
132         return ERROR_OK;\r
133 }\r
134 \r
135 /* read JTAG buffer into little-endian u16, flipping bit-order */\r
136 int arm_jtag_buf_to_le16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)\r
137 {\r
138         h_u16_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);\r
139         return ERROR_OK;\r
140 }\r
141 \r
142 /* read JTAG buffer into big-endian u32, flipping bit-order */\r
143 int arm_jtag_buf_to_be32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)\r
144 {\r
145         h_u32_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));\r
146         return ERROR_OK;\r
147 }\r
148 \r
149 /* read JTAG buffer into big-endian u16, flipping bit-order */\r
150 int arm_jtag_buf_to_be16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)\r
151 {\r
152         h_u16_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);\r
153         return ERROR_OK;\r
154 }\r
155 \r
156 /* read JTAG buffer into u8, flipping bit-order */\r
157 int arm_jtag_buf_to_8_flip(u8 *in_buf, void *priv, struct scan_field_s *field)\r
158 {\r
159         u8 *dest = priv;\r
160         *dest = flip_u32(le_to_h_u32(in_buf), 32) & 0xff;\r
161         return ERROR_OK;\r
162 }\r
163 \r
164 /* not-flipping variants */\r
165 /* read JTAG buffer into host-endian u32 */\r
166 int arm_jtag_buf_to_u32(u8 *in_buf, void *priv, struct scan_field_s *field)\r
167 {\r
168         u32 *dest = priv;\r
169         *dest = le_to_h_u32(in_buf);\r
170         return ERROR_OK;\r
171 }\r
172 \r
173 /* read JTAG buffer into little-endian u32 */\r
174 int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field)\r
175 {\r
176         h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf));\r
177         return ERROR_OK;\r
178 }\r
179 \r
180 /* read JTAG buffer into little-endian u16 */\r
181 int arm_jtag_buf_to_le16(u8 *in_buf, void *priv, struct scan_field_s *field)\r
182 {\r
183         h_u16_to_le(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);\r
184         return ERROR_OK;\r
185 }\r
186 \r
187 /* read JTAG buffer into big-endian u32 */\r
188 int arm_jtag_buf_to_be32(u8 *in_buf, void *priv, struct scan_field_s *field)\r
189 {\r
190         h_u32_to_be(((u8*)priv), le_to_h_u32(in_buf));\r
191         return ERROR_OK;\r
192 }\r
193 \r
194 /* read JTAG buffer into big-endian u16 */\r
195 int arm_jtag_buf_to_be16(u8 *in_buf, void *priv, struct scan_field_s *field)\r
196 {\r
197         h_u16_to_be(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);\r
198         return ERROR_OK;\r
199 }\r
200 \r
201 /* read JTAG buffer into u8 */\r
202 int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)\r
203 {\r
204         u8 *dest = priv;\r
205         *dest = le_to_h_u32(in_buf) & 0xff;\r
206         return ERROR_OK;\r
207 }\r