2d06a0e98f5aaf8ce19702af626c195f11e1bbee
[fw/openocd] / src / pld / virtex2.c
1 /***************************************************************************
2  *   Copyright (C) 2006 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
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, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "virtex2.h"
25 #include "xilinx_bit.h"
26 #include "pld.h"
27
28
29 static int virtex2_set_instr(struct jtag_tap *tap, uint32_t new_instr)
30 {
31         if (tap == NULL)
32                 return ERROR_FAIL;
33
34         if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
35         {
36                 scan_field_t field;
37
38                 field.tap = tap;
39                 field.num_bits = tap->ir_length;
40                 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
41                 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
42                 field.in_value = NULL;
43
44                 jtag_add_ir_scan(1, &field, jtag_set_end_state(TAP_IDLE));
45
46                 free(field.out_value);
47         }
48
49         return ERROR_OK;
50 }
51
52 static int virtex2_send_32(struct pld_device_s *pld_device,
53                 int num_words, uint32_t *words)
54 {
55         virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
56         scan_field_t scan_field;
57         uint8_t *values;
58         int i;
59
60         values = malloc(num_words * 4);
61
62         scan_field.tap = virtex2_info->tap;
63         scan_field.num_bits = num_words * 32;
64         scan_field.out_value = values;
65         scan_field.in_value = NULL;
66
67         for (i = 0; i < num_words; i++)
68                 buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
69
70         virtex2_set_instr(virtex2_info->tap, 0x5); /* CFG_IN */
71
72         jtag_add_dr_scan(1, &scan_field, jtag_set_end_state(TAP_DRPAUSE));
73
74         free(values);
75
76         return ERROR_OK;
77 }
78
79 static __inline__ void virtexflip32(jtag_callback_data_t arg)
80 {
81   uint8_t *in = (uint8_t *)arg;
82         *((uint32_t *)in) = flip_u32(le_to_h_u32(in), 32);
83 }
84
85 static int virtex2_receive_32(struct pld_device_s *pld_device,
86                 int num_words, uint32_t *words)
87 {
88         virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
89         scan_field_t scan_field;
90
91         scan_field.tap = virtex2_info->tap;
92         scan_field.num_bits = 32;
93         scan_field.out_value = NULL;
94         scan_field.in_value = NULL;
95
96         virtex2_set_instr(virtex2_info->tap, 0x4); /* CFG_OUT */
97
98         while (num_words--)
99         {
100                 scan_field.in_value = (uint8_t *)words;
101
102                 jtag_add_dr_scan(1, &scan_field, jtag_set_end_state(TAP_DRPAUSE));
103
104                 jtag_add_callback(virtexflip32, (jtag_callback_data_t)words);
105
106                 words++;;
107         }
108
109         return ERROR_OK;
110 }
111
112 static int virtex2_read_stat(struct pld_device_s *pld_device, uint32_t *status)
113 {
114         uint32_t data[5];
115
116         jtag_add_tlr();
117
118         data[0] = 0xaa995566; /* synch word */
119         data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */
120         data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */
121         data[3] = 0x20000000; /* NOOP */
122         data[4] = 0x20000000; /* NOOP */
123         virtex2_send_32(pld_device, 5, data);
124
125         virtex2_receive_32(pld_device, 1, status);
126
127         jtag_execute_queue();
128
129         LOG_DEBUG("status: 0x%8.8" PRIx32 "", *status);
130
131         return ERROR_OK;
132 }
133
134 static int virtex2_load(struct pld_device_s *pld_device, const char *filename)
135 {
136         virtex2_pld_device_t *virtex2_info = pld_device->driver_priv;
137         xilinx_bit_file_t bit_file;
138         int retval;
139         unsigned int i;
140         scan_field_t field;
141
142         field.tap = virtex2_info->tap;
143         field.in_value = NULL;
144
145         if ((retval = xilinx_read_bit_file(&bit_file, filename)) != ERROR_OK)
146                 return retval;
147
148         jtag_set_end_state(TAP_IDLE);
149         virtex2_set_instr(virtex2_info->tap, 0xb); /* JPROG_B */
150         jtag_execute_queue();
151         jtag_add_sleep(1000);
152
153         virtex2_set_instr(virtex2_info->tap, 0x5); /* CFG_IN */
154         jtag_execute_queue();
155
156         for (i = 0; i < bit_file.length; i++)
157                 bit_file.data[i] = flip_u32(bit_file.data[i], 8);
158
159         field.num_bits = bit_file.length * 8;
160         field.out_value = bit_file.data;
161
162         jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_DRPAUSE));
163         jtag_execute_queue();
164
165         jtag_add_tlr();
166
167         jtag_set_end_state(TAP_IDLE);
168         virtex2_set_instr(virtex2_info->tap, 0xc); /* JSTART */
169         jtag_add_runtest(13, jtag_set_end_state(TAP_IDLE));
170         virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */
171         virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */
172         virtex2_set_instr(virtex2_info->tap, 0xc); /* JSTART */
173         jtag_add_runtest(13, jtag_set_end_state(TAP_IDLE));
174         virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */
175         jtag_execute_queue();
176
177         return ERROR_OK;
178 }
179
180 COMMAND_HANDLER(virtex2_handle_read_stat_command)
181 {
182         pld_device_t *device;
183         virtex2_pld_device_t *virtex2_info;
184         uint32_t status;
185
186         if (argc < 1)
187         {
188                 command_print(cmd_ctx, "usage: virtex2 read_stat <num>");
189                 return ERROR_OK;
190         }
191
192         unsigned dev_id;
193         COMMAND_PARSE_NUMBER(uint, args[0], dev_id);
194         device = get_pld_device_by_num(dev_id);
195         if (!device)
196         {
197                 command_print(cmd_ctx, "pld device '#%s' is out of bounds", args[0]);
198                 return ERROR_OK;
199         }
200
201         virtex2_info = device->driver_priv;
202
203         virtex2_read_stat(device, &status);
204
205         command_print(cmd_ctx, "virtex2 status register: 0x%8.8" PRIx32 "", status);
206
207         return ERROR_OK;
208 }
209
210 PLD_DEVICE_COMMAND_HANDLER(virtex2_pld_device_command)
211 {
212         struct jtag_tap *tap;
213
214         virtex2_pld_device_t *virtex2_info;
215
216         if (argc < 2)
217         {
218                 LOG_WARNING("incomplete pld device 'virtex2' configuration");
219                 return ERROR_PLD_DEVICE_INVALID;
220         }
221
222         tap = jtag_tap_by_string(args[1]);
223         if (tap == NULL) {
224                 command_print(cmd_ctx, "Tap: %s does not exist", args[1]);
225                 return ERROR_OK;
226         }
227
228         virtex2_info = malloc(sizeof(virtex2_pld_device_t));
229         virtex2_info->tap = tap;
230
231         pld->driver_priv = virtex2_info;
232
233         return ERROR_OK;
234 }
235
236 static int virtex2_register_commands(struct command_context_s *cmd_ctx)
237 {
238         command_t *virtex2_cmd = register_command(cmd_ctx, NULL, "virtex2",
239                         NULL, COMMAND_ANY, "virtex2 specific commands");
240
241         register_command(cmd_ctx, virtex2_cmd, "read_stat",
242                         &virtex2_handle_read_stat_command, COMMAND_EXEC,
243                         "read Virtex-II status register");
244
245         return ERROR_OK;
246 }
247
248 pld_driver_t virtex2_pld = {
249                 .name = "virtex2",
250                 .register_commands = &virtex2_register_commands,
251                 .pld_device_command = &virtex2_pld_device_command,
252                 .load = &virtex2_load,
253         };