607451a7c2f1d5a0ee9bcc9b5b75ab3fd5b72898
[openocd.git] / src / target / openrisc / or1k_tap_vjtag.c
1 /***************************************************************************
2 * Copyright (C) 2013 by Franck Jullien *
3 * elec4fun@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "or1k_tap.h"
24 #include "or1k.h"
25
26 #include <jtag/jtag.h>
27
28 /* Contains constants relevant to the Altera Virtual JTAG
29 * device, which are not included in the BSDL.
30 * As of this writing, these are constant across every
31 * device which supports virtual JTAG.
32 */
33
34 /* These are commands for the FPGA's IR. */
35 #define ALTERA_CYCLONE_CMD_USER1 0x0E
36 #define ALTERA_CYCLONE_CMD_USER0 0x0C
37
38 /* These defines are for the virtual IR (not the FPGA's)
39 * The virtual TAP was defined in hardware to match the OpenCores native
40 * TAP in both IR size and DEBUG command.
41 */
42 #define ALT_VJTAG_IR_SIZE 4
43 #define ALT_VJTAG_CMD_DEBUG 0x8
44
45 /* SLD node ID. */
46 #define JTAG_TO_AVALON_NODE_ID 0x84
47 #define VJTAG_NODE_ID 0x08
48 #define SIGNAL_TAP_NODE_ID 0x00
49 #define SERIAL_FLASH_LOADER_NODE_ID 0x04
50
51 #define VER(x) ((x >> 27) & 0x1f)
52 #define NB_NODES(x) ((x >> 19) & 0xff)
53 #define ID(x) ((x >> 19) & 0xff)
54 #define MANUF(x) ((x >> 8) & 0x7ff)
55 #define M_WIDTH(x) ((x >> 0) & 0xff)
56 #define INST_ID(x) ((x >> 0) & 0xff)
57
58 /* tap instructions - Mohor JTAG TAP */
59 #define OR1K_TAP_INST_IDCODE 0x2
60 #define OR1K_TAP_INST_DEBUG 0x8
61
62 static const char *id_to_string(unsigned char id)
63 {
64 switch (id) {
65 case VJTAG_NODE_ID:
66 return "Virtual JTAG";
67 case JTAG_TO_AVALON_NODE_ID:
68 return "JTAG to avalon bridge";
69 case SIGNAL_TAP_NODE_ID:
70 return "Signal TAP";
71 case SERIAL_FLASH_LOADER_NODE_ID:
72 return "Serial Flash Loader";
73 }
74 return "unknown";
75 }
76
77 static unsigned char guess_addr_width(unsigned char number_of_nodes)
78 {
79 unsigned char width = 0;
80
81 while (number_of_nodes) {
82 number_of_nodes >>= 1;
83 width++;
84 }
85
86 return width;
87 }
88
89 static int or1k_tap_vjtag_init(struct or1k_jtag *jtag_info)
90 {
91 LOG_DEBUG("Initialising Altera Virtual JTAG TAP");
92
93 /* Put TAP into state where it can talk to the debug interface
94 * by shifting in correct value to IR.
95 */
96
97 /* Ensure TAP is reset - maybe not necessary*/
98 jtag_add_tlr();
99
100 /* You can use a custom JTAG controller to discover transactions
101 * necessary to enumerate all Virtual JTAG megafunction instances
102 * from your design atruntime. All SLD nodes and the virtual JTAG
103 * registers that they contain are targeted by two Instruction Register
104 * values, USER0 and USER1.
105 *
106 * The USER1 instruction targets the virtual IR of either the sld_hub
107 * or a SLD node. That is,when the USER1 instruction is issued to
108 * the device, the subsequent DR scans target a specific virtual
109 * IR chain based on an address field contained within the DR scan.
110 * The table below shows how the virtual IR, the DR target of the
111 * USER1 instruction is interpreted.
112 *
113 * The VIR_VALUE in the table below is the virtual IR value for the
114 * target SLD node. The width of this field is m bits in length,
115 * where m is the length of the largest VIR for all of the SLD nodes
116 * in the design. All SLD nodes with VIR lengths of fewer than m
117 * bits must pad VIR_VALUE with zeros up to a length of m.
118 *
119 * -------------------------------+-------------------------------
120 * m + n - 1 m | m -1 0
121 * -------------------------------+-------------------------------
122 * ADDR [(n – 1)..0] | VIR_VALUE [(m – 1)..0]
123 * -------------------------------+-------------------------------
124 *
125 * The ADDR bits act as address values to signal the active SLD node
126 * that the virtual IR shift targets. ADDR is n bits in length, where
127 * n bits must be long enough to encode all SLD nodes within the design,
128 * as shown below.
129 *
130 * n = CEIL(log2(Number of SLD_nodes +1))
131 *
132 * The SLD hub is always 0 in the address map.
133 *
134 * Discovery and enumeration of the SLD instances within a design
135 * requires interrogation of the sld_hub to determine the dimensions
136 * of the USER1 DR (m and n) and associating each SLD instance, specifically
137 * the Virtual JTAG megafunction instances, with an address value
138 * contained within the ADDR bits of the USER1 DR.
139 *
140 * The SLD hub contains the HUB IP Configuration Register and SLD_NODE_INFO
141 * register for each SLD node in the design. The HUB IP configuration register provides
142 * information needed to determine the dimensions of the USER1 DR chain. The
143 * SLD_NODE_INFO register is used to determine the address mapping for Virtual
144 * JTAG instance in your design. This register set is shifted out by issuing the
145 * HUB_INFO instruction. Both the ADDR bits for the SLD hub and the HUB_INFO
146 * instruction is 0 × 0.
147 * Because m and n are unknown at this point, the DR register
148 * (ADDR bits + VIR_VALUE) must be filled with zeros. Shifting a sequence of 64 zeroes
149 * into the USER1 DR is sufficient to cover the most conservative case for m and n.
150 */
151
152 uint8_t t[4];
153 struct scan_field field;
154 struct jtag_tap *tap = jtag_info->tap;
155
156 /* Select VIR */
157 buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER1);
158 field.num_bits = tap->ir_length;
159 field.out_value = t;
160 field.in_value = NULL;
161 jtag_add_ir_scan(tap, &field, TAP_IDLE);
162
163 /* Select the SLD Hub */
164 field.num_bits = 64;
165 field.out_value = NULL;
166 field.in_value = NULL;
167 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
168
169 /* HUB IP Configuration Register
170 *
171 * When the USER1 and HUB_INFO instruction sequence is issued, the
172 * USER0 instruction must be applied to enable the target register
173 * of the HUB_INFO instruction. The HUB IP configuration register
174 * is shifted out using eight four-bit nibble scans of the DR register.
175 * Each four-bit scan must pass through the UPDATE_DR state before
176 * the next four-bit scan. The 8 scans are assembled into a 32-bit
177 * value with the definitions shown in the table below.
178 *
179 * --------------------------------------------------------------------------------
180 * NIBBLE7 | NIBBLE6 | NIBBLE5 | NIBBLE4 | NIBBLE3 | NIBBLE2 | NIBBLE1 | NIBBLE0
181 * ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----
182 * | | | | | | | | | | | | | | |
183 * ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----
184 * HUB IP version| N | ALTERA_MFG_ID (0x06E) | SUM (m, n)
185 * --------------+-------------------+------------------------+--------------------
186 */
187
188 /* Select VDR */
189 buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER0);
190 field.num_bits = tap->ir_length;
191 field.out_value = t;
192 field.in_value = NULL;
193 jtag_add_ir_scan(tap, &field, TAP_IDLE);
194
195 int retval = jtag_execute_queue();
196 if (retval != ERROR_OK)
197 return retval;
198
199 uint8_t nibble;
200 uint32_t hub_info = 0;
201
202 for (int i = 0; i < 8; i++) {
203 field.num_bits = 4;
204 field.out_value = NULL;
205 field.in_value = &nibble;
206 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
207 retval = jtag_execute_queue();
208 if (retval != ERROR_OK)
209 return retval;
210 hub_info = ((hub_info >> 4) | ((nibble & 0xf) << 28));
211 }
212
213 int nb_nodes = NB_NODES(hub_info);
214 int m_width = M_WIDTH(hub_info);
215
216 LOG_DEBUG("SLD HUB Configuration register");
217 LOG_DEBUG("------------------------------");
218 LOG_DEBUG("m_width = %d", m_width);
219 LOG_DEBUG("manufacturer_id = 0x%02" PRIx32, MANUF(hub_info));
220 LOG_DEBUG("nb_of_node = %d", nb_nodes);
221 LOG_DEBUG("version = %" PRId32, VER(hub_info));
222 LOG_DEBUG("VIR length = %d", guess_addr_width(nb_nodes) + m_width);
223
224 /* Because the number of SLD nodes is now known, the Nodes on the hub can be
225 * enumerated by repeating the 8 four-bit nibble scans, once for each Node,
226 * to yield the SLD_NODE_INFO register of each Node. The DR nibble shifts
227 * are a continuation of the HUB_INFO DR shift used to shift out the Hub IP
228 * Configuration register.
229 *
230 * The order of the Nodes as they are shifted out determines the ADDR
231 * values for the Nodes, beginning with, for the first Node SLD_NODE_INFO
232 * shifted out, up to and including, for the last node on the hub. The
233 * tables below show the SLD_NODE_INFO register and a their functional descriptions.
234 *
235 * --------------+-----------+---------------+----------------
236 * 31 27 | 26 19 | 18 8 | 7 0
237 * --------------+-----------+---------------+----------------
238 * Node Version | NODE ID | NODE MFG_ID | NODE INST ID
239 *
240 */
241
242 int vjtag_node_address = -1;
243 int node_index;
244 uint32_t node_info = 0;
245 for (node_index = 0; node_index < nb_nodes; node_index++) {
246
247 for (int i = 0; i < 8; i++) {
248 field.num_bits = 4;
249 field.out_value = NULL;
250 field.in_value = &nibble;
251 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
252 retval = jtag_execute_queue();
253 if (retval != ERROR_OK)
254 return retval;
255 node_info = ((node_info >> 4) | ((nibble & 0xf) << 28));
256 }
257
258 LOG_DEBUG("Node info register");
259 LOG_DEBUG("--------------------");
260 LOG_DEBUG("instance_id = %" PRId32, ID(node_info));
261 LOG_DEBUG("manufacturer_id = 0x%02" PRIx32, MANUF(node_info));
262 LOG_DEBUG("node_id = %" PRId32 " (%s)", ID(node_info),
263 id_to_string(ID(node_info)));
264 LOG_DEBUG("version = %" PRId32, VER(node_info));
265
266 if (ID(node_info) == VJTAG_NODE_ID)
267 vjtag_node_address = node_index + 1;
268 }
269
270 if (vjtag_node_address < 0) {
271 LOG_ERROR("No VJTAG TAP instance found !");
272 return ERROR_FAIL;
273 }
274
275 /* Select VIR */
276 buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER1);
277 field.num_bits = tap->ir_length;
278 field.out_value = t;
279 field.in_value = NULL;
280 jtag_add_ir_scan(tap, &field, TAP_IDLE);
281
282 /* Send the DEBUG command to the VJTAG IR */
283 int dr_length = guess_addr_width(nb_nodes) + m_width;
284 buf_set_u32(t, 0, dr_length, (vjtag_node_address << m_width) | ALT_VJTAG_CMD_DEBUG);
285 field.num_bits = dr_length;
286 field.out_value = t;
287 field.in_value = NULL;
288 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
289
290 /* Select the VJTAG DR */
291 buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER0);
292 field.num_bits = tap->ir_length;
293 field.out_value = t;
294 field.in_value = NULL;
295 jtag_add_ir_scan(tap, &field, TAP_IDLE);
296
297 return jtag_execute_queue();
298 }
299
300 static struct or1k_tap_ip vjtag_tap = {
301 .name = "vjtag",
302 .init = or1k_tap_vjtag_init,
303 };
304
305 int or1k_tap_vjtag_register(void)
306 {
307 list_add_tail(&vjtag_tap.list, &tap_list);
308 return 0;
309 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)