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

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)