1 /***************************************************************************
2 * Copyright (C) 2013 by Franck Jullien *
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. *
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. *
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 ***************************************************************************/
26 #include <jtag/jtag.h>
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.
34 /* These are commands for the FPGA's IR. */
35 #define ALTERA_CYCLONE_CMD_USER1 0x0E
36 #define ALTERA_CYCLONE_CMD_USER0 0x0C
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.
42 #define ALT_VJTAG_IR_SIZE 4
43 #define ALT_VJTAG_CMD_DEBUG 0x8
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
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)
58 /* tap instructions - Mohor JTAG TAP */
59 #define OR1K_TAP_INST_IDCODE 0x2
60 #define OR1K_TAP_INST_DEBUG 0x8
62 static const char *id_to_string(unsigned char id
)
66 return "Virtual JTAG";
67 case JTAG_TO_AVALON_NODE_ID
:
68 return "JTAG to avalon bridge";
69 case SIGNAL_TAP_NODE_ID
:
71 case SERIAL_FLASH_LOADER_NODE_ID
:
72 return "Serial Flash Loader";
77 static unsigned char guess_addr_width(unsigned char number_of_nodes
)
79 unsigned char width
= 0;
81 while (number_of_nodes
) {
82 number_of_nodes
>>= 1;
89 static int or1k_tap_vjtag_init(struct or1k_jtag
*jtag_info
)
91 LOG_DEBUG("Initialising Altera Virtual JTAG TAP");
93 /* Put TAP into state where it can talk to the debug interface
94 * by shifting in correct value to IR.
97 /* Ensure TAP is reset - maybe not necessary*/
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.
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.
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.
119 * -------------------------------+-------------------------------
120 * m + n - 1 m | m -1 0
121 * -------------------------------+-------------------------------
122 * ADDR [(n – 1)..0] | VIR_VALUE [(m – 1)..0]
123 * -------------------------------+-------------------------------
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,
130 * n = CEIL(log2(Number of SLD_nodes +1))
132 * The SLD hub is always 0 in the address map.
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.
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.
153 struct scan_field field
;
154 struct jtag_tap
*tap
= jtag_info
->tap
;
157 buf_set_u32(t
, 0, tap
->ir_length
, ALTERA_CYCLONE_CMD_USER1
);
158 field
.num_bits
= tap
->ir_length
;
160 field
.in_value
= NULL
;
161 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
163 /* Select the SLD Hub */
165 field
.out_value
= NULL
;
166 field
.in_value
= NULL
;
167 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
169 /* HUB IP Configuration Register
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.
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 * --------------+-------------------+------------------------+--------------------
189 buf_set_u32(t
, 0, tap
->ir_length
, ALTERA_CYCLONE_CMD_USER0
);
190 field
.num_bits
= tap
->ir_length
;
192 field
.in_value
= NULL
;
193 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
195 int retval
= jtag_execute_queue();
196 if (retval
!= ERROR_OK
)
200 uint32_t hub_info
= 0;
202 for (int i
= 0; i
< 8; i
++) {
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
)
210 hub_info
= ((hub_info
>> 4) | ((nibble
& 0xf) << 28));
213 int nb_nodes
= NB_NODES(hub_info
);
214 int m_width
= M_WIDTH(hub_info
);
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
);
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.
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.
235 * --------------+-----------+---------------+----------------
236 * 31 27 | 26 19 | 18 8 | 7 0
237 * --------------+-----------+---------------+----------------
238 * Node Version | NODE ID | NODE MFG_ID | NODE INST ID
242 int vjtag_node_address
= -1;
244 uint32_t node_info
= 0;
245 for (node_index
= 0; node_index
< nb_nodes
; node_index
++) {
247 for (int i
= 0; i
< 8; i
++) {
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
)
255 node_info
= ((node_info
>> 4) | ((nibble
& 0xf) << 28));
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
));
266 if (ID(node_info
) == VJTAG_NODE_ID
)
267 vjtag_node_address
= node_index
+ 1;
270 if (vjtag_node_address
< 0) {
271 LOG_ERROR("No VJTAG TAP instance found !");
276 buf_set_u32(t
, 0, tap
->ir_length
, ALTERA_CYCLONE_CMD_USER1
);
277 field
.num_bits
= tap
->ir_length
;
279 field
.in_value
= NULL
;
280 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
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
;
287 field
.in_value
= NULL
;
288 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
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
;
294 field
.in_value
= NULL
;
295 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
297 return jtag_execute_queue();
300 static struct or1k_tap_ip vjtag_tap
= {
302 .init
= or1k_tap_vjtag_init
,
305 int or1k_tap_vjtag_register(void)
307 list_add_tail(&vjtag_tap
.list
, &tap_list
);
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)