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

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)