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