aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorIgor M. Liplianin <liplianin@me.by>2011-01-25 15:00:00 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:16 -0400
commitfa766c9be58bd872784b081074a7d15a3ce61c5f (patch)
treee78ca5f181b914770769e7c6ce1e16d9383b6ddd /drivers/staging
parentf72cfd859b0e436d9f680790cb665ad1390187ae (diff)
[media] Altera FPGA firmware download module
It uses STAPL files and programs Altera FPGA through JTAG. Interface to JTAG must be provided from main device module, for example through cx23885 GPIO. Signed-off-by: Igor M. Liplianin <liplianin@netup.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/altera-stapl/Kconfig8
-rw-r--r--drivers/staging/altera-stapl/Makefile3
-rw-r--r--drivers/staging/altera-stapl/altera-comp.c142
-rw-r--r--drivers/staging/altera-stapl/altera-exprt.h33
-rw-r--r--drivers/staging/altera-stapl/altera-jtag.c1020
-rw-r--r--drivers/staging/altera-stapl/altera-jtag.h113
-rw-r--r--drivers/staging/altera-stapl/altera-lpt.c70
-rw-r--r--drivers/staging/altera-stapl/altera.c2527
10 files changed, 3919 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index a2742d8102c1..74a8b272154f 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -175,5 +175,7 @@ source "drivers/staging/cptm1217/Kconfig"
175 175
176source "drivers/staging/ste_rmi4/Kconfig" 176source "drivers/staging/ste_rmi4/Kconfig"
177 177
178source "drivers/staging/altera-stapl/Kconfig"
179
178endif # !STAGING_EXCLUDE_BUILD 180endif # !STAGING_EXCLUDE_BUILD
179endif # STAGING 181endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 4ddd3ce780e0..9f50ec90f9d8 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -66,5 +66,6 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/
66obj-$(CONFIG_FT1000) += ft1000/ 66obj-$(CONFIG_FT1000) += ft1000/
67obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ 67obj-$(CONFIG_SND_INTEL_SST) += intel_sst/
68obj-$(CONFIG_SPEAKUP) += speakup/ 68obj-$(CONFIG_SPEAKUP) += speakup/
69obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
69obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ 70obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
70obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ 71obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
diff --git a/drivers/staging/altera-stapl/Kconfig b/drivers/staging/altera-stapl/Kconfig
new file mode 100644
index 000000000000..7f01d8e93992
--- /dev/null
+++ b/drivers/staging/altera-stapl/Kconfig
@@ -0,0 +1,8 @@
1comment "Altera FPGA firmware download module"
2
3config ALTERA_STAPL
4 tristate "Altera FPGA firmware download module"
5 depends on I2C
6 default n
7 help
8 An Altera FPGA module. Say Y when you want to support this tool.
diff --git a/drivers/staging/altera-stapl/Makefile b/drivers/staging/altera-stapl/Makefile
new file mode 100644
index 000000000000..055f61ee781a
--- /dev/null
+++ b/drivers/staging/altera-stapl/Makefile
@@ -0,0 +1,3 @@
1altera-stapl-objs = altera-lpt.o altera-jtag.o altera-comp.o altera.o
2
3obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o
diff --git a/drivers/staging/altera-stapl/altera-comp.c b/drivers/staging/altera-stapl/altera-comp.c
new file mode 100644
index 000000000000..49b103bedaaf
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-comp.c
@@ -0,0 +1,142 @@
1/*
2 * altera-comp.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include "altera-exprt.h"
28
29#define SHORT_BITS 16
30#define CHAR_BITS 8
31#define DATA_BLOB_LENGTH 3
32#define MATCH_DATA_LENGTH 8192
33#define ALTERA_REQUEST_SIZE 1024
34#define ALTERA_BUFFER_SIZE (MATCH_DATA_LENGTH + ALTERA_REQUEST_SIZE)
35
36static u32 altera_bits_req(u32 n)
37{
38 u32 result = SHORT_BITS;
39
40 if (n == 0)
41 result = 1;
42 else {
43 /* Look for the highest non-zero bit position */
44 while ((n & (1 << (SHORT_BITS - 1))) == 0) {
45 n <<= 1;
46 --result;
47 }
48 }
49
50 return result;
51}
52
53static u32 altera_read_packed(u8 *buffer, u32 bits, u32 *bits_avail,
54 u32 *in_index)
55{
56 u32 result = 0;
57 u32 shift = 0;
58 u32 databyte = 0;
59
60 while (bits > 0) {
61 databyte = buffer[*in_index];
62 result |= (((databyte >> (CHAR_BITS - *bits_avail))
63 & (0xff >> (CHAR_BITS - *bits_avail))) << shift);
64
65 if (bits <= *bits_avail) {
66 result &= (0xffff >> (SHORT_BITS - (bits + shift)));
67 *bits_avail -= bits;
68 bits = 0;
69 } else {
70 ++(*in_index);
71 shift += *bits_avail;
72 bits -= *bits_avail;
73 *bits_avail = CHAR_BITS;
74 }
75 }
76
77 return result;
78}
79
80u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version)
81{
82 u32 i, j, data_length = 0L;
83 u32 offset, length;
84 u32 match_data_length = MATCH_DATA_LENGTH;
85 u32 bits_avail = CHAR_BITS;
86 u32 in_index = 0L;
87
88 if (version > 0)
89 --match_data_length;
90
91 for (i = 0; i < out_length; ++i)
92 out[i] = 0;
93
94 /* Read number of bytes in data. */
95 for (i = 0; i < sizeof(in_length); ++i) {
96 data_length = data_length | (
97 altera_read_packed(in,
98 CHAR_BITS,
99 &bits_avail,
100 &in_index) << (i * CHAR_BITS));
101 }
102
103 if (data_length > out_length) {
104 data_length = 0L;
105 return data_length;
106 }
107
108 i = 0;
109 while (i < data_length) {
110 /* A 0 bit indicates literal data. */
111 if (altera_read_packed(in, 1, &bits_avail,
112 &in_index) == 0) {
113 for (j = 0; j < DATA_BLOB_LENGTH; ++j) {
114 if (i < data_length) {
115 out[i] = (u8)altera_read_packed(in,
116 CHAR_BITS,
117 &bits_avail,
118 &in_index);
119 i++;
120 }
121 }
122 } else {
123 /* A 1 bit indicates offset/length to follow. */
124 offset = altera_read_packed(in, altera_bits_req((s16)
125 (i > match_data_length ?
126 match_data_length : i)),
127 &bits_avail,
128 &in_index);
129 length = altera_read_packed(in, CHAR_BITS,
130 &bits_avail,
131 &in_index);
132 for (j = 0; j < length; ++j) {
133 if (i < data_length) {
134 out[i] = out[i - offset];
135 i++;
136 }
137 }
138 }
139 }
140
141 return data_length;
142}
diff --git a/drivers/staging/altera-stapl/altera-exprt.h b/drivers/staging/altera-stapl/altera-exprt.h
new file mode 100644
index 000000000000..39c38d84a670
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-exprt.h
@@ -0,0 +1,33 @@
1/*
2 * altera-exprt.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef ALTERA_EXPRT_H
27#define ALTERA_EXPRT_H
28
29
30u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version);
31int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo);
32
33#endif /* ALTERA_EXPRT_H */
diff --git a/drivers/staging/altera-stapl/altera-jtag.c b/drivers/staging/altera-stapl/altera-jtag.c
new file mode 100644
index 000000000000..6b633b179a7e
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-jtag.c
@@ -0,0 +1,1020 @@
1/*
2 * altera-jtag.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/firmware.h>
27#include <linux/slab.h>
28#include <staging/altera.h>
29#include "altera-exprt.h"
30#include "altera-jtag.h"
31
32#define alt_jtag_io(a, b, c)\
33 astate->config->jtag_io(astate->config->dev, a, b, c);
34
35#define alt_malloc(a) kzalloc(a, GFP_KERNEL);
36
37/*
38 * This structure shows, for each JTAG state, which state is reached after
39 * a single TCK clock cycle with TMS high or TMS low, respectively. This
40 * describes all possible state transitions in the JTAG state machine.
41 */
42struct altera_jtag_machine {
43 enum altera_jtag_state tms_high;
44 enum altera_jtag_state tms_low;
45};
46
47static const struct altera_jtag_machine altera_transitions[] = {
48 /* RESET */ { RESET, IDLE },
49 /* IDLE */ { DRSELECT, IDLE },
50 /* DRSELECT */ { IRSELECT, DRCAPTURE },
51 /* DRCAPTURE */ { DREXIT1, DRSHIFT },
52 /* DRSHIFT */ { DREXIT1, DRSHIFT },
53 /* DREXIT1 */ { DRUPDATE, DRPAUSE },
54 /* DRPAUSE */ { DREXIT2, DRPAUSE },
55 /* DREXIT2 */ { DRUPDATE, DRSHIFT },
56 /* DRUPDATE */ { DRSELECT, IDLE },
57 /* IRSELECT */ { RESET, IRCAPTURE },
58 /* IRCAPTURE */ { IREXIT1, IRSHIFT },
59 /* IRSHIFT */ { IREXIT1, IRSHIFT },
60 /* IREXIT1 */ { IRUPDATE, IRPAUSE },
61 /* IRPAUSE */ { IREXIT2, IRPAUSE },
62 /* IREXIT2 */ { IRUPDATE, IRSHIFT },
63 /* IRUPDATE */ { DRSELECT, IDLE }
64};
65
66/*
67 * This table contains the TMS value to be used to take the NEXT STEP on
68 * the path to the desired state. The array index is the current state,
69 * and the bit position is the desired endstate. To find out which state
70 * is used as the intermediate state, look up the TMS value in the
71 * altera_transitions[] table.
72 */
73static const u16 altera_jtag_path_map[16] = {
74 /* RST RTI SDRS CDR SDR E1DR PDR E2DR */
75 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
76 /* UDR SIRS CIR SIR E1IR PIR E2IR UIR */
77 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
78};
79
80/* Flag bits for alt_jtag_io() function */
81#define TMS_HIGH 1
82#define TMS_LOW 0
83#define TDI_HIGH 1
84#define TDI_LOW 0
85#define READ_TDO 1
86#define IGNORE_TDO 0
87
88int altera_jinit(struct altera_state *astate)
89{
90 struct altera_jtag *js = &astate->js;
91
92 /* initial JTAG state is unknown */
93 js->jtag_state = ILLEGAL_JTAG_STATE;
94
95 /* initialize to default state */
96 js->drstop_state = IDLE;
97 js->irstop_state = IDLE;
98 js->dr_pre = 0;
99 js->dr_post = 0;
100 js->ir_pre = 0;
101 js->ir_post = 0;
102 js->dr_length = 0;
103 js->ir_length = 0;
104
105 js->dr_pre_data = NULL;
106 js->dr_post_data = NULL;
107 js->ir_pre_data = NULL;
108 js->ir_post_data = NULL;
109 js->dr_buffer = NULL;
110 js->ir_buffer = NULL;
111
112 return 0;
113}
114
115int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
116{
117 js->drstop_state = state;
118
119 return 0;
120}
121
122int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
123{
124 js->irstop_state = state;
125
126 return 0;
127}
128
129int altera_set_dr_pre(struct altera_jtag *js,
130 u32 count, u32 start_index,
131 u8 *preamble_data)
132{
133 int status = 0;
134 u32 i;
135 u32 j;
136
137 if (count > js->dr_pre) {
138 kfree(js->dr_pre_data);
139 js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
140 if (js->dr_pre_data == NULL)
141 status = -ENOMEM;
142 else
143 js->dr_pre = count;
144 } else
145 js->dr_pre = count;
146
147 if (status == 0) {
148 for (i = 0; i < count; ++i) {
149 j = i + start_index;
150
151 if (preamble_data == NULL)
152 js->dr_pre_data[i >> 3] |= (1 << (i & 7));
153 else {
154 if (preamble_data[j >> 3] & (1 << (j & 7)))
155 js->dr_pre_data[i >> 3] |=
156 (1 << (i & 7));
157 else
158 js->dr_pre_data[i >> 3] &=
159 ~(u32)(1 << (i & 7));
160
161 }
162 }
163 }
164
165 return status;
166}
167
168int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
169 u8 *preamble_data)
170{
171 int status = 0;
172 u32 i;
173 u32 j;
174
175 if (count > js->ir_pre) {
176 kfree(js->ir_pre_data);
177 js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
178 if (js->ir_pre_data == NULL)
179 status = -ENOMEM;
180 else
181 js->ir_pre = count;
182
183 } else
184 js->ir_pre = count;
185
186 if (status == 0) {
187 for (i = 0; i < count; ++i) {
188 j = i + start_index;
189 if (preamble_data == NULL)
190 js->ir_pre_data[i >> 3] |= (1 << (i & 7));
191 else {
192 if (preamble_data[j >> 3] & (1 << (j & 7)))
193 js->ir_pre_data[i >> 3] |=
194 (1 << (i & 7));
195 else
196 js->ir_pre_data[i >> 3] &=
197 ~(u32)(1 << (i & 7));
198
199 }
200 }
201 }
202
203 return status;
204}
205
206int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
207 u8 *postamble_data)
208{
209 int status = 0;
210 u32 i;
211 u32 j;
212
213 if (count > js->dr_post) {
214 kfree(js->dr_post_data);
215 js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
216
217 if (js->dr_post_data == NULL)
218 status = -ENOMEM;
219 else
220 js->dr_post = count;
221
222 } else
223 js->dr_post = count;
224
225 if (status == 0) {
226 for (i = 0; i < count; ++i) {
227 j = i + start_index;
228
229 if (postamble_data == NULL)
230 js->dr_post_data[i >> 3] |= (1 << (i & 7));
231 else {
232 if (postamble_data[j >> 3] & (1 << (j & 7)))
233 js->dr_post_data[i >> 3] |=
234 (1 << (i & 7));
235 else
236 js->dr_post_data[i >> 3] &=
237 ~(u32)(1 << (i & 7));
238
239 }
240 }
241 }
242
243 return status;
244}
245
246int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
247 u8 *postamble_data)
248{
249 int status = 0;
250 u32 i;
251 u32 j;
252
253 if (count > js->ir_post) {
254 kfree(js->ir_post_data);
255 js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
256 if (js->ir_post_data == NULL)
257 status = -ENOMEM;
258 else
259 js->ir_post = count;
260
261 } else
262 js->ir_post = count;
263
264 if (status != 0)
265 return status;
266
267 for (i = 0; i < count; ++i) {
268 j = i + start_index;
269
270 if (postamble_data == NULL)
271 js->ir_post_data[i >> 3] |= (1 << (i & 7));
272 else {
273 if (postamble_data[j >> 3] & (1 << (j & 7)))
274 js->ir_post_data[i >> 3] |= (1 << (i & 7));
275 else
276 js->ir_post_data[i >> 3] &=
277 ~(u32)(1 << (i & 7));
278
279 }
280 }
281
282 return status;
283}
284
285static void altera_jreset_idle(struct altera_state *astate)
286{
287 struct altera_jtag *js = &astate->js;
288 int i;
289 /* Go to Test Logic Reset (no matter what the starting state may be) */
290 for (i = 0; i < 5; ++i)
291 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
292
293 /* Now step to Run Test / Idle */
294 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
295 js->jtag_state = IDLE;
296}
297
298int altera_goto_jstate(struct altera_state *astate,
299 enum altera_jtag_state state)
300{
301 struct altera_jtag *js = &astate->js;
302 int tms;
303 int count = 0;
304 int status = 0;
305
306 if (js->jtag_state == ILLEGAL_JTAG_STATE)
307 /* initialize JTAG chain to known state */
308 altera_jreset_idle(astate);
309
310 if (js->jtag_state == state) {
311 /*
312 * We are already in the desired state.
313 * If it is a stable state, loop here.
314 * Otherwise do nothing (no clock cycles).
315 */
316 if ((state == IDLE) || (state == DRSHIFT) ||
317 (state == DRPAUSE) || (state == IRSHIFT) ||
318 (state == IRPAUSE)) {
319 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
320 } else if (state == RESET)
321 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
322
323 } else {
324 while ((js->jtag_state != state) && (count < 9)) {
325 /* Get TMS value to take a step toward desired state */
326 tms = (altera_jtag_path_map[js->jtag_state] &
327 (1 << state))
328 ? TMS_HIGH : TMS_LOW;
329
330 /* Take a step */
331 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
332
333 if (tms)
334 js->jtag_state =
335 altera_transitions[js->jtag_state].tms_high;
336 else
337 js->jtag_state =
338 altera_transitions[js->jtag_state].tms_low;
339
340 ++count;
341 }
342 }
343
344 if (js->jtag_state != state)
345 status = -EREMOTEIO;
346
347 return status;
348}
349
350int altera_wait_cycles(struct altera_state *astate,
351 s32 cycles,
352 enum altera_jtag_state wait_state)
353{
354 struct altera_jtag *js = &astate->js;
355 int tms;
356 s32 count;
357 int status = 0;
358
359 if (js->jtag_state != wait_state)
360 status = altera_goto_jstate(astate, wait_state);
361
362 if (status == 0) {
363 /*
364 * Set TMS high to loop in RESET state
365 * Set TMS low to loop in any other stable state
366 */
367 tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
368
369 for (count = 0L; count < cycles; count++)
370 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
371
372 }
373
374 return status;
375}
376
377int altera_wait_msecs(struct altera_state *astate,
378 s32 microseconds, enum altera_jtag_state wait_state)
379/*
380 * Causes JTAG hardware to sit in the specified stable
381 * state for the specified duration of real time. If
382 * no JTAG operations have been performed yet, then only
383 * a delay is performed. This permits the WAIT USECS
384 * statement to be used in VECTOR programs without causing
385 * any JTAG operations.
386 * Returns 0 for success, else appropriate error code.
387 */
388{
389 struct altera_jtag *js = &astate->js;
390 int status = 0;
391
392 if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
393 (js->jtag_state != wait_state))
394 status = altera_goto_jstate(astate, wait_state);
395
396 if (status == 0)
397 /* Wait for specified time interval */
398 udelay(microseconds);
399
400 return status;
401}
402
403static void altera_concatenate_data(u8 *buffer,
404 u8 *preamble_data,
405 u32 preamble_count,
406 u8 *target_data,
407 u32 start_index,
408 u32 target_count,
409 u8 *postamble_data,
410 u32 postamble_count)
411/*
412 * Copies preamble data, target data, and postamble data
413 * into one buffer for IR or DR scans.
414 */
415{
416 u32 i, j, k;
417
418 for (i = 0L; i < preamble_count; ++i) {
419 if (preamble_data[i >> 3L] & (1L << (i & 7L)))
420 buffer[i >> 3L] |= (1L << (i & 7L));
421 else
422 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
423
424 }
425
426 j = start_index;
427 k = preamble_count + target_count;
428 for (; i < k; ++i, ++j) {
429 if (target_data[j >> 3L] & (1L << (j & 7L)))
430 buffer[i >> 3L] |= (1L << (i & 7L));
431 else
432 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
433
434 }
435
436 j = 0L;
437 k = preamble_count + target_count + postamble_count;
438 for (; i < k; ++i, ++j) {
439 if (postamble_data[j >> 3L] & (1L << (j & 7L)))
440 buffer[i >> 3L] |= (1L << (i & 7L));
441 else
442 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
443
444 }
445}
446
447static int alt_jtag_drscan(struct altera_state *astate,
448 int start_state,
449 int count,
450 u8 *tdi,
451 u8 *tdo)
452{
453 int i = 0;
454 int tdo_bit = 0;
455 int status = 1;
456
457 /* First go to DRSHIFT state */
458 switch (start_state) {
459 case 0: /* IDLE */
460 alt_jtag_io(1, 0, 0); /* DRSELECT */
461 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
462 alt_jtag_io(0, 0, 0); /* DRSHIFT */
463 break;
464
465 case 1: /* DRPAUSE */
466 alt_jtag_io(1, 0, 0); /* DREXIT2 */
467 alt_jtag_io(1, 0, 0); /* DRUPDATE */
468 alt_jtag_io(1, 0, 0); /* DRSELECT */
469 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
470 alt_jtag_io(0, 0, 0); /* DRSHIFT */
471 break;
472
473 case 2: /* IRPAUSE */
474 alt_jtag_io(1, 0, 0); /* IREXIT2 */
475 alt_jtag_io(1, 0, 0); /* IRUPDATE */
476 alt_jtag_io(1, 0, 0); /* DRSELECT */
477 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
478 alt_jtag_io(0, 0, 0); /* DRSHIFT */
479 break;
480
481 default:
482 status = 0;
483 }
484
485 if (status) {
486 /* loop in the SHIFT-DR state */
487 for (i = 0; i < count; i++) {
488 tdo_bit = alt_jtag_io(
489 (i == count - 1),
490 tdi[i >> 3] & (1 << (i & 7)),
491 (tdo != NULL));
492
493 if (tdo != NULL) {
494 if (tdo_bit)
495 tdo[i >> 3] |= (1 << (i & 7));
496 else
497 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
498
499 }
500 }
501
502 alt_jtag_io(0, 0, 0); /* DRPAUSE */
503 }
504
505 return status;
506}
507
508static int alt_jtag_irscan(struct altera_state *astate,
509 int start_state,
510 int count,
511 u8 *tdi,
512 u8 *tdo)
513{
514 int i = 0;
515 int tdo_bit = 0;
516 int status = 1;
517
518 /* First go to IRSHIFT state */
519 switch (start_state) {
520 case 0: /* IDLE */
521 alt_jtag_io(1, 0, 0); /* DRSELECT */
522 alt_jtag_io(1, 0, 0); /* IRSELECT */
523 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
524 alt_jtag_io(0, 0, 0); /* IRSHIFT */
525 break;
526
527 case 1: /* DRPAUSE */
528 alt_jtag_io(1, 0, 0); /* DREXIT2 */
529 alt_jtag_io(1, 0, 0); /* DRUPDATE */
530 alt_jtag_io(1, 0, 0); /* DRSELECT */
531 alt_jtag_io(1, 0, 0); /* IRSELECT */
532 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
533 alt_jtag_io(0, 0, 0); /* IRSHIFT */
534 break;
535
536 case 2: /* IRPAUSE */
537 alt_jtag_io(1, 0, 0); /* IREXIT2 */
538 alt_jtag_io(1, 0, 0); /* IRUPDATE */
539 alt_jtag_io(1, 0, 0); /* DRSELECT */
540 alt_jtag_io(1, 0, 0); /* IRSELECT */
541 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
542 alt_jtag_io(0, 0, 0); /* IRSHIFT */
543 break;
544
545 default:
546 status = 0;
547 }
548
549 if (status) {
550 /* loop in the SHIFT-IR state */
551 for (i = 0; i < count; i++) {
552 tdo_bit = alt_jtag_io(
553 (i == count - 1),
554 tdi[i >> 3] & (1 << (i & 7)),
555 (tdo != NULL));
556 if (tdo != NULL) {
557 if (tdo_bit)
558 tdo[i >> 3] |= (1 << (i & 7));
559 else
560 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
561
562 }
563 }
564
565 alt_jtag_io(0, 0, 0); /* IRPAUSE */
566 }
567
568 return status;
569}
570
571static void altera_extract_target_data(u8 *buffer,
572 u8 *target_data,
573 u32 start_index,
574 u32 preamble_count,
575 u32 target_count)
576/*
577 * Copies target data from scan buffer, filtering out
578 * preamble and postamble data.
579 */
580{
581 u32 i;
582 u32 j;
583 u32 k;
584
585 j = preamble_count;
586 k = start_index + target_count;
587 for (i = start_index; i < k; ++i, ++j) {
588 if (buffer[j >> 3] & (1 << (j & 7)))
589 target_data[i >> 3] |= (1 << (i & 7));
590 else
591 target_data[i >> 3] &= ~(u32)(1 << (i & 7));
592
593 }
594}
595
596int altera_irscan(struct altera_state *astate,
597 u32 count,
598 u8 *tdi_data,
599 u32 start_index)
600/* Shifts data into instruction register */
601{
602 struct altera_jtag *js = &astate->js;
603 int start_code = 0;
604 u32 alloc_chars = 0;
605 u32 shift_count = js->ir_pre + count + js->ir_post;
606 int status = 0;
607 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
608
609 switch (js->jtag_state) {
610 case ILLEGAL_JTAG_STATE:
611 case RESET:
612 case IDLE:
613 start_code = 0;
614 start_state = IDLE;
615 break;
616
617 case DRSELECT:
618 case DRCAPTURE:
619 case DRSHIFT:
620 case DREXIT1:
621 case DRPAUSE:
622 case DREXIT2:
623 case DRUPDATE:
624 start_code = 1;
625 start_state = DRPAUSE;
626 break;
627
628 case IRSELECT:
629 case IRCAPTURE:
630 case IRSHIFT:
631 case IREXIT1:
632 case IRPAUSE:
633 case IREXIT2:
634 case IRUPDATE:
635 start_code = 2;
636 start_state = IRPAUSE;
637 break;
638
639 default:
640 status = -EREMOTEIO;
641 break;
642 }
643
644 if (status == 0)
645 if (js->jtag_state != start_state)
646 status = altera_goto_jstate(astate, start_state);
647
648 if (status == 0) {
649 if (shift_count > js->ir_length) {
650 alloc_chars = (shift_count + 7) >> 3;
651 kfree(js->ir_buffer);
652 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
653 if (js->ir_buffer == NULL)
654 status = -ENOMEM;
655 else
656 js->ir_length = alloc_chars * 8;
657
658 }
659 }
660
661 if (status == 0) {
662 /*
663 * Copy preamble data, IR data,
664 * and postamble data into a buffer
665 */
666 altera_concatenate_data(js->ir_buffer,
667 js->ir_pre_data,
668 js->ir_pre,
669 tdi_data,
670 start_index,
671 count,
672 js->ir_post_data,
673 js->ir_post);
674 /* Do the IRSCAN */
675 alt_jtag_irscan(astate,
676 start_code,
677 shift_count,
678 js->ir_buffer,
679 NULL);
680
681 /* alt_jtag_irscan() always ends in IRPAUSE state */
682 js->jtag_state = IRPAUSE;
683 }
684
685 if (status == 0)
686 if (js->irstop_state != IRPAUSE)
687 status = altera_goto_jstate(astate, js->irstop_state);
688
689
690 return status;
691}
692
693int altera_swap_ir(struct altera_state *astate,
694 u32 count,
695 u8 *in_data,
696 u32 in_index,
697 u8 *out_data,
698 u32 out_index)
699/* Shifts data into instruction register, capturing output data */
700{
701 struct altera_jtag *js = &astate->js;
702 int start_code = 0;
703 u32 alloc_chars = 0;
704 u32 shift_count = js->ir_pre + count + js->ir_post;
705 int status = 0;
706 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
707
708 switch (js->jtag_state) {
709 case ILLEGAL_JTAG_STATE:
710 case RESET:
711 case IDLE:
712 start_code = 0;
713 start_state = IDLE;
714 break;
715
716 case DRSELECT:
717 case DRCAPTURE:
718 case DRSHIFT:
719 case DREXIT1:
720 case DRPAUSE:
721 case DREXIT2:
722 case DRUPDATE:
723 start_code = 1;
724 start_state = DRPAUSE;
725 break;
726
727 case IRSELECT:
728 case IRCAPTURE:
729 case IRSHIFT:
730 case IREXIT1:
731 case IRPAUSE:
732 case IREXIT2:
733 case IRUPDATE:
734 start_code = 2;
735 start_state = IRPAUSE;
736 break;
737
738 default:
739 status = -EREMOTEIO;
740 break;
741 }
742
743 if (status == 0)
744 if (js->jtag_state != start_state)
745 status = altera_goto_jstate(astate, start_state);
746
747 if (status == 0) {
748 if (shift_count > js->ir_length) {
749 alloc_chars = (shift_count + 7) >> 3;
750 kfree(js->ir_buffer);
751 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
752 if (js->ir_buffer == NULL)
753 status = -ENOMEM;
754 else
755 js->ir_length = alloc_chars * 8;
756
757 }
758 }
759
760 if (status == 0) {
761 /*
762 * Copy preamble data, IR data,
763 * and postamble data into a buffer
764 */
765 altera_concatenate_data(js->ir_buffer,
766 js->ir_pre_data,
767 js->ir_pre,
768 in_data,
769 in_index,
770 count,
771 js->ir_post_data,
772 js->ir_post);
773
774 /* Do the IRSCAN */
775 alt_jtag_irscan(astate,
776 start_code,
777 shift_count,
778 js->ir_buffer,
779 js->ir_buffer);
780
781 /* alt_jtag_irscan() always ends in IRPAUSE state */
782 js->jtag_state = IRPAUSE;
783 }
784
785 if (status == 0)
786 if (js->irstop_state != IRPAUSE)
787 status = altera_goto_jstate(astate, js->irstop_state);
788
789
790 if (status == 0)
791 /* Now extract the returned data from the buffer */
792 altera_extract_target_data(js->ir_buffer,
793 out_data, out_index,
794 js->ir_pre, count);
795
796 return status;
797}
798
799int altera_drscan(struct altera_state *astate,
800 u32 count,
801 u8 *tdi_data,
802 u32 start_index)
803/* Shifts data into data register (ignoring output data) */
804{
805 struct altera_jtag *js = &astate->js;
806 int start_code = 0;
807 u32 alloc_chars = 0;
808 u32 shift_count = js->dr_pre + count + js->dr_post;
809 int status = 0;
810 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
811
812 switch (js->jtag_state) {
813 case ILLEGAL_JTAG_STATE:
814 case RESET:
815 case IDLE:
816 start_code = 0;
817 start_state = IDLE;
818 break;
819
820 case DRSELECT:
821 case DRCAPTURE:
822 case DRSHIFT:
823 case DREXIT1:
824 case DRPAUSE:
825 case DREXIT2:
826 case DRUPDATE:
827 start_code = 1;
828 start_state = DRPAUSE;
829 break;
830
831 case IRSELECT:
832 case IRCAPTURE:
833 case IRSHIFT:
834 case IREXIT1:
835 case IRPAUSE:
836 case IREXIT2:
837 case IRUPDATE:
838 start_code = 2;
839 start_state = IRPAUSE;
840 break;
841
842 default:
843 status = -EREMOTEIO;
844 break;
845 }
846
847 if (status == 0)
848 if (js->jtag_state != start_state)
849 status = altera_goto_jstate(astate, start_state);
850
851 if (status == 0) {
852 if (shift_count > js->dr_length) {
853 alloc_chars = (shift_count + 7) >> 3;
854 kfree(js->dr_buffer);
855 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
856 if (js->dr_buffer == NULL)
857 status = -ENOMEM;
858 else
859 js->dr_length = alloc_chars * 8;
860
861 }
862 }
863
864 if (status == 0) {
865 /*
866 * Copy preamble data, DR data,
867 * and postamble data into a buffer
868 */
869 altera_concatenate_data(js->dr_buffer,
870 js->dr_pre_data,
871 js->dr_pre,
872 tdi_data,
873 start_index,
874 count,
875 js->dr_post_data,
876 js->dr_post);
877 /* Do the DRSCAN */
878 alt_jtag_drscan(astate, start_code, shift_count,
879 js->dr_buffer, NULL);
880 /* alt_jtag_drscan() always ends in DRPAUSE state */
881 js->jtag_state = DRPAUSE;
882 }
883
884 if (status == 0)
885 if (js->drstop_state != DRPAUSE)
886 status = altera_goto_jstate(astate, js->drstop_state);
887
888 return status;
889}
890
891int altera_swap_dr(struct altera_state *astate, u32 count,
892 u8 *in_data, u32 in_index,
893 u8 *out_data, u32 out_index)
894/* Shifts data into data register, capturing output data */
895{
896 struct altera_jtag *js = &astate->js;
897 int start_code = 0;
898 u32 alloc_chars = 0;
899 u32 shift_count = js->dr_pre + count + js->dr_post;
900 int status = 0;
901 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
902
903 switch (js->jtag_state) {
904 case ILLEGAL_JTAG_STATE:
905 case RESET:
906 case IDLE:
907 start_code = 0;
908 start_state = IDLE;
909 break;
910
911 case DRSELECT:
912 case DRCAPTURE:
913 case DRSHIFT:
914 case DREXIT1:
915 case DRPAUSE:
916 case DREXIT2:
917 case DRUPDATE:
918 start_code = 1;
919 start_state = DRPAUSE;
920 break;
921
922 case IRSELECT:
923 case IRCAPTURE:
924 case IRSHIFT:
925 case IREXIT1:
926 case IRPAUSE:
927 case IREXIT2:
928 case IRUPDATE:
929 start_code = 2;
930 start_state = IRPAUSE;
931 break;
932
933 default:
934 status = -EREMOTEIO;
935 break;
936 }
937
938 if (status == 0)
939 if (js->jtag_state != start_state)
940 status = altera_goto_jstate(astate, start_state);
941
942 if (status == 0) {
943 if (shift_count > js->dr_length) {
944 alloc_chars = (shift_count + 7) >> 3;
945 kfree(js->dr_buffer);
946 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
947
948 if (js->dr_buffer == NULL)
949 status = -ENOMEM;
950 else
951 js->dr_length = alloc_chars * 8;
952
953 }
954 }
955
956 if (status == 0) {
957 /*
958 * Copy preamble data, DR data,
959 * and postamble data into a buffer
960 */
961 altera_concatenate_data(js->dr_buffer,
962 js->dr_pre_data,
963 js->dr_pre,
964 in_data,
965 in_index,
966 count,
967 js->dr_post_data,
968 js->dr_post);
969
970 /* Do the DRSCAN */
971 alt_jtag_drscan(astate,
972 start_code,
973 shift_count,
974 js->dr_buffer,
975 js->dr_buffer);
976
977 /* alt_jtag_drscan() always ends in DRPAUSE state */
978 js->jtag_state = DRPAUSE;
979 }
980
981 if (status == 0)
982 if (js->drstop_state != DRPAUSE)
983 status = altera_goto_jstate(astate, js->drstop_state);
984
985 if (status == 0)
986 /* Now extract the returned data from the buffer */
987 altera_extract_target_data(js->dr_buffer,
988 out_data,
989 out_index,
990 js->dr_pre,
991 count);
992
993 return status;
994}
995
996void altera_free_buffers(struct altera_state *astate)
997{
998 struct altera_jtag *js = &astate->js;
999 /* If the JTAG interface was used, reset it to TLR */
1000 if (js->jtag_state != ILLEGAL_JTAG_STATE)
1001 altera_jreset_idle(astate);
1002
1003 kfree(js->dr_pre_data);
1004 js->dr_pre_data = NULL;
1005
1006 kfree(js->dr_post_data);
1007 js->dr_post_data = NULL;
1008
1009 kfree(js->dr_buffer);
1010 js->dr_buffer = NULL;
1011
1012 kfree(js->ir_pre_data);
1013 js->ir_pre_data = NULL;
1014
1015 kfree(js->ir_post_data);
1016 js->ir_post_data = NULL;
1017
1018 kfree(js->ir_buffer);
1019 js->ir_buffer = NULL;
1020}
diff --git a/drivers/staging/altera-stapl/altera-jtag.h b/drivers/staging/altera-stapl/altera-jtag.h
new file mode 100644
index 000000000000..2f97e36a2fbc
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-jtag.h
@@ -0,0 +1,113 @@
1/*
2 * altera-jtag.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef ALTERA_JTAG_H
27#define ALTERA_JTAG_H
28
29/* Function Prototypes */
30enum altera_jtag_state {
31 ILLEGAL_JTAG_STATE = -1,
32 RESET = 0,
33 IDLE = 1,
34 DRSELECT = 2,
35 DRCAPTURE = 3,
36 DRSHIFT = 4,
37 DREXIT1 = 5,
38 DRPAUSE = 6,
39 DREXIT2 = 7,
40 DRUPDATE = 8,
41 IRSELECT = 9,
42 IRCAPTURE = 10,
43 IRSHIFT = 11,
44 IREXIT1 = 12,
45 IRPAUSE = 13,
46 IREXIT2 = 14,
47 IRUPDATE = 15
48
49};
50
51struct altera_jtag {
52 /* Global variable to store the current JTAG state */
53 enum altera_jtag_state jtag_state;
54
55 /* Store current stop-state for DR and IR scan commands */
56 enum altera_jtag_state drstop_state;
57 enum altera_jtag_state irstop_state;
58
59 /* Store current padding values */
60 u32 dr_pre;
61 u32 dr_post;
62 u32 ir_pre;
63 u32 ir_post;
64 u32 dr_length;
65 u32 ir_length;
66 u8 *dr_pre_data;
67 u8 *dr_post_data;
68 u8 *ir_pre_data;
69 u8 *ir_post_data;
70 u8 *dr_buffer;
71 u8 *ir_buffer;
72};
73
74#define ALTERA_STACK_SIZE 128
75#define ALTERA_MESSAGE_LENGTH 1024
76
77struct altera_state {
78 struct altera_config *config;
79 struct altera_jtag js;
80 char msg_buff[ALTERA_MESSAGE_LENGTH + 1];
81 long stack[ALTERA_STACK_SIZE];
82};
83
84int altera_jinit(struct altera_state *astate);
85int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state);
86int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state);
87int altera_set_dr_pre(struct altera_jtag *js, u32 count, u32 start_index,
88 u8 *preamble_data);
89int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
90 u8 *preamble_data);
91int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
92 u8 *postamble_data);
93int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
94 u8 *postamble_data);
95int altera_goto_jstate(struct altera_state *astate,
96 enum altera_jtag_state state);
97int altera_wait_cycles(struct altera_state *astate, s32 cycles,
98 enum altera_jtag_state wait_state);
99int altera_wait_msecs(struct altera_state *astate, s32 microseconds,
100 enum altera_jtag_state wait_state);
101int altera_irscan(struct altera_state *astate, u32 count,
102 u8 *tdi_data, u32 start_index);
103int altera_swap_ir(struct altera_state *astate,
104 u32 count, u8 *in_data,
105 u32 in_index, u8 *out_data,
106 u32 out_index);
107int altera_drscan(struct altera_state *astate, u32 count,
108 u8 *tdi_data, u32 start_index);
109int altera_swap_dr(struct altera_state *astate, u32 count,
110 u8 *in_data, u32 in_index,
111 u8 *out_data, u32 out_index);
112void altera_free_buffers(struct altera_state *astate);
113#endif /* ALTERA_JTAG_H */
diff --git a/drivers/staging/altera-stapl/altera-lpt.c b/drivers/staging/altera-stapl/altera-lpt.c
new file mode 100644
index 000000000000..91456a03612d
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-lpt.c
@@ -0,0 +1,70 @@
1/*
2 * altera-lpt.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Abylay Ospan <aospan@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/io.h>
27#include <linux/kernel.h>
28#include "altera-exprt.h"
29
30static int lpt_hardware_initialized;
31
32static void byteblaster_write(int port, int data)
33{
34 outb((u8)data, (u16)(port + 0x378));
35};
36
37static int byteblaster_read(int port)
38{
39 int data = 0;
40 data = inb((u16)(port + 0x378));
41 return data & 0xff;
42};
43
44int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo)
45{
46 int data = 0;
47 int tdo = 0;
48 int initial_lpt_ctrl = 0;
49
50 if (!lpt_hardware_initialized) {
51 initial_lpt_ctrl = byteblaster_read(2);
52 byteblaster_write(2, (initial_lpt_ctrl | 0x02) & 0xdf);
53 lpt_hardware_initialized = 1;
54 }
55
56 data = ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0));
57
58 byteblaster_write(0, data);
59
60 if (read_tdo) {
61 tdo = byteblaster_read(1);
62 tdo = ((tdo & 0x80) ? 0 : 1);
63 }
64
65 byteblaster_write(0, data | 0x01);
66
67 byteblaster_write(0, data);
68
69 return tdo;
70}
diff --git a/drivers/staging/altera-stapl/altera.c b/drivers/staging/altera-stapl/altera.c
new file mode 100644
index 000000000000..05aad351b120
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera.c
@@ -0,0 +1,2527 @@
1/*
2 * altera.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <asm/unaligned.h>
27#include <linux/ctype.h>
28#include <linux/string.h>
29#include <linux/firmware.h>
30#include <linux/slab.h>
31#include <staging/altera.h>
32#include "altera-exprt.h"
33#include "altera-jtag.h"
34
35static int debug = 1;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debugging information");
38
39MODULE_DESCRIPTION("altera FPGA kernel module");
40MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");
41MODULE_LICENSE("GPL");
42
43#define dprintk(args...) \
44 if (debug) { \
45 printk(KERN_DEBUG args); \
46 }
47
48enum altera_fpga_opcode {
49 OP_NOP = 0,
50 OP_DUP,
51 OP_SWP,
52 OP_ADD,
53 OP_SUB,
54 OP_MULT,
55 OP_DIV,
56 OP_MOD,
57 OP_SHL,
58 OP_SHR,
59 OP_NOT,
60 OP_AND,
61 OP_OR,
62 OP_XOR,
63 OP_INV,
64 OP_GT,
65 OP_LT,
66 OP_RET,
67 OP_CMPS,
68 OP_PINT,
69 OP_PRNT,
70 OP_DSS,
71 OP_DSSC,
72 OP_ISS,
73 OP_ISSC,
74 OP_DPR = 0x1c,
75 OP_DPRL,
76 OP_DPO,
77 OP_DPOL,
78 OP_IPR,
79 OP_IPRL,
80 OP_IPO,
81 OP_IPOL,
82 OP_PCHR,
83 OP_EXIT,
84 OP_EQU,
85 OP_POPT,
86 OP_ABS = 0x2c,
87 OP_BCH0,
88 OP_PSH0 = 0x2f,
89 OP_PSHL = 0x40,
90 OP_PSHV,
91 OP_JMP,
92 OP_CALL,
93 OP_NEXT,
94 OP_PSTR,
95 OP_SINT = 0x47,
96 OP_ST,
97 OP_ISTP,
98 OP_DSTP,
99 OP_SWPN,
100 OP_DUPN,
101 OP_POPV,
102 OP_POPE,
103 OP_POPA,
104 OP_JMPZ,
105 OP_DS,
106 OP_IS,
107 OP_DPRA,
108 OP_DPOA,
109 OP_IPRA,
110 OP_IPOA,
111 OP_EXPT,
112 OP_PSHE,
113 OP_PSHA,
114 OP_DYNA,
115 OP_EXPV = 0x5c,
116 OP_COPY = 0x80,
117 OP_REVA,
118 OP_DSC,
119 OP_ISC,
120 OP_WAIT,
121 OP_VS,
122 OP_CMPA = 0xc0,
123 OP_VSC,
124};
125
126struct altera_procinfo {
127 char *name;
128 u8 attrs;
129 struct altera_procinfo *next;
130};
131
132/* This function checks if enough parameters are available on the stack. */
133static int altera_check_stack(int stack_ptr, int count, int *status)
134{
135 if (stack_ptr < count) {
136 *status = -EOVERFLOW;
137 return 0;
138 }
139
140 return 1;
141}
142
143static void altera_export_int(char *key, s32 value)
144{
145 dprintk("Export: key = \"%s\", value = %d\n", key, value);
146}
147
148#define HEX_LINE_CHARS 72
149#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
150
151static void altera_export_bool_array(char *key, u8 *data, s32 count)
152{
153 char string[HEX_LINE_CHARS + 1];
154 s32 i, offset;
155 u32 size, line, lines, linebits, value, j, k;
156
157 if (count > HEX_LINE_BITS) {
158 dprintk("Export: key = \"%s\", %d bits, value = HEX\n",
159 key, count);
160 lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;
161
162 for (line = 0; line < lines; ++line) {
163 if (line < (lines - 1)) {
164 linebits = HEX_LINE_BITS;
165 size = HEX_LINE_CHARS;
166 offset = count - ((line + 1) * HEX_LINE_BITS);
167 } else {
168 linebits =
169 count - ((lines - 1) * HEX_LINE_BITS);
170 size = (linebits + 3) / 4;
171 offset = 0L;
172 }
173
174 string[size] = '\0';
175 j = size - 1;
176 value = 0;
177
178 for (k = 0; k < linebits; ++k) {
179 i = k + offset;
180 if (data[i >> 3] & (1 << (i & 7)))
181 value |= (1 << (i & 3));
182 if ((i & 3) == 3) {
183 sprintf(&string[j], "%1x", value);
184 value = 0;
185 --j;
186 }
187 }
188 if ((k & 3) > 0)
189 sprintf(&string[j], "%1x", value);
190
191 dprintk("%s\n", string);
192 }
193
194 } else {
195 size = (count + 3) / 4;
196 string[size] = '\0';
197 j = size - 1;
198 value = 0;
199
200 for (i = 0; i < count; ++i) {
201 if (data[i >> 3] & (1 << (i & 7)))
202 value |= (1 << (i & 3));
203 if ((i & 3) == 3) {
204 sprintf(&string[j], "%1x", value);
205 value = 0;
206 --j;
207 }
208 }
209 if ((i & 3) > 0)
210 sprintf(&string[j], "%1x", value);
211
212 dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n",
213 key, count, string);
214 }
215}
216
217static int altera_execute(struct altera_state *astate,
218 u8 *p,
219 s32 program_size,
220 s32 *error_address,
221 int *exit_code,
222 int *format_version)
223{
224 struct altera_config *aconf = astate->config;
225 char *msg_buff = astate->msg_buff;
226 long *stack = astate->stack;
227 int status = 0;
228 u32 first_word = 0L;
229 u32 action_table = 0L;
230 u32 proc_table = 0L;
231 u32 str_table = 0L;
232 u32 sym_table = 0L;
233 u32 data_sect = 0L;
234 u32 code_sect = 0L;
235 u32 debug_sect = 0L;
236 u32 action_count = 0L;
237 u32 proc_count = 0L;
238 u32 sym_count = 0L;
239 long *vars = NULL;
240 s32 *var_size = NULL;
241 char *attrs = NULL;
242 u8 *proc_attributes = NULL;
243 u32 pc;
244 u32 opcode_address;
245 u32 args[3];
246 u32 opcode;
247 u32 name_id;
248 u8 charbuf[4];
249 long long_tmp;
250 u32 variable_id;
251 u8 *charptr_tmp;
252 u8 *charptr_tmp2;
253 long *longptr_tmp;
254 int version = 0;
255 int delta = 0;
256 int stack_ptr = 0;
257 u32 arg_count;
258 int done = 0;
259 int bad_opcode = 0;
260 u32 count;
261 u32 index;
262 u32 index2;
263 s32 long_count;
264 s32 long_idx;
265 s32 long_idx2;
266 u32 i;
267 u32 j;
268 u32 uncomp_size;
269 u32 offset;
270 u32 value;
271 int current_proc = 0;
272 int reverse;
273
274 char *name;
275
276 dprintk("%s\n", __func__);
277
278 /* Read header information */
279 if (program_size > 52L) {
280 first_word = get_unaligned_be32(&p[0]);
281 version = (first_word & 1L);
282 *format_version = version + 1;
283 delta = version * 8;
284
285 action_table = get_unaligned_be32(&p[4]);
286 proc_table = get_unaligned_be32(&p[8]);
287 str_table = get_unaligned_be32(&p[4 + delta]);
288 sym_table = get_unaligned_be32(&p[16 + delta]);
289 data_sect = get_unaligned_be32(&p[20 + delta]);
290 code_sect = get_unaligned_be32(&p[24 + delta]);
291 debug_sect = get_unaligned_be32(&p[28 + delta]);
292 action_count = get_unaligned_be32(&p[40 + delta]);
293 proc_count = get_unaligned_be32(&p[44 + delta]);
294 sym_count = get_unaligned_be32(&p[48 + (2 * delta)]);
295 }
296
297 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {
298 done = 1;
299 status = -EIO;
300 goto exit_done;
301 }
302
303 if (sym_count <= 0)
304 goto exit_done;
305
306 vars = kzalloc(sym_count * sizeof(long), GFP_KERNEL);
307
308 if (vars == NULL)
309 status = -ENOMEM;
310
311 if (status == 0) {
312 var_size = kzalloc(sym_count * sizeof(s32), GFP_KERNEL);
313
314 if (var_size == NULL)
315 status = -ENOMEM;
316 }
317
318 if (status == 0) {
319 attrs = kzalloc(sym_count, GFP_KERNEL);
320
321 if (attrs == NULL)
322 status = -ENOMEM;
323 }
324
325 if ((status == 0) && (version > 0)) {
326 proc_attributes = kzalloc(proc_count, GFP_KERNEL);
327
328 if (proc_attributes == NULL)
329 status = -ENOMEM;
330 }
331
332 if (status != 0)
333 goto exit_done;
334
335 delta = version * 2;
336
337 for (i = 0; i < sym_count; ++i) {
338 offset = (sym_table + ((11 + delta) * i));
339
340 value = get_unaligned_be32(&p[offset + 3 + delta]);
341
342 attrs[i] = p[offset];
343
344 /*
345 * use bit 7 of attribute byte to indicate that
346 * this buffer was dynamically allocated
347 * and should be freed later
348 */
349 attrs[i] &= 0x7f;
350
351 var_size[i] = get_unaligned_be32(&p[offset + 7 + delta]);
352
353 /*
354 * Attribute bits:
355 * bit 0: 0 = read-only, 1 = read-write
356 * bit 1: 0 = not compressed, 1 = compressed
357 * bit 2: 0 = not initialized, 1 = initialized
358 * bit 3: 0 = scalar, 1 = array
359 * bit 4: 0 = Boolean, 1 = integer
360 * bit 5: 0 = declared variable,
361 * 1 = compiler created temporary variable
362 */
363
364 if ((attrs[i] & 0x0c) == 0x04)
365 /* initialized scalar variable */
366 vars[i] = value;
367 else if ((attrs[i] & 0x1e) == 0x0e) {
368 /* initialized compressed Boolean array */
369 uncomp_size = get_unaligned_le32(&p[data_sect + value]);
370
371 /* allocate a buffer for the uncompressed data */
372 vars[i] = (long)kzalloc(uncomp_size, GFP_KERNEL);
373 if (vars[i] == 0L)
374 status = -ENOMEM;
375 else {
376 /* set flag so buffer will be freed later */
377 attrs[i] |= 0x80;
378
379 /* uncompress the data */
380 if (altera_shrink(&p[data_sect + value],
381 var_size[i],
382 (u8 *)vars[i],
383 uncomp_size,
384 version) != uncomp_size)
385 /* decompression failed */
386 status = -EIO;
387 else
388 var_size[i] = uncomp_size * 8L;
389
390 }
391 } else if ((attrs[i] & 0x1e) == 0x0c) {
392 /* initialized Boolean array */
393 vars[i] = value + data_sect + (long)p;
394 } else if ((attrs[i] & 0x1c) == 0x1c) {
395 /* initialized integer array */
396 vars[i] = value + data_sect;
397 } else if ((attrs[i] & 0x0c) == 0x08) {
398 /* uninitialized array */
399
400 /* flag attrs so that memory is freed */
401 attrs[i] |= 0x80;
402
403 if (var_size[i] > 0) {
404 u32 size;
405
406 if (attrs[i] & 0x10)
407 /* integer array */
408 size = (var_size[i] * sizeof(s32));
409 else
410 /* Boolean array */
411 size = ((var_size[i] + 7L) / 8L);
412
413 vars[i] = (long)kzalloc(size, GFP_KERNEL);
414
415 if (vars[i] == 0) {
416 status = -ENOMEM;
417 } else {
418 /* zero out memory */
419 for (j = 0; j < size; ++j)
420 ((u8 *)(vars[i]))[j] = 0;
421
422 }
423 } else
424 vars[i] = 0;
425
426 } else
427 vars[i] = 0;
428
429 }
430
431exit_done:
432 if (status != 0)
433 done = 1;
434
435 altera_jinit(astate);
436
437 pc = code_sect;
438 msg_buff[0] = '\0';
439
440 /*
441 * For JBC version 2, we will execute the procedures corresponding to
442 * the selected ACTION
443 */
444 if (version > 0) {
445 if (aconf->action == NULL) {
446 status = -EINVAL;
447 done = 1;
448 } else {
449 int action_found = 0;
450 for (i = 0; (i < action_count) && !action_found; ++i) {
451 name_id = get_unaligned_be32(&p[action_table +
452 (12 * i)]);
453
454 name = &p[str_table + name_id];
455
456 if (strnicmp(aconf->action, name, strlen(name)) == 0) {
457 action_found = 1;
458 current_proc =
459 get_unaligned_be32(&p[action_table +
460 (12 * i) + 8]);
461 }
462 }
463
464 if (!action_found) {
465 status = -EINVAL;
466 done = 1;
467 }
468 }
469
470 if (status == 0) {
471 int first_time = 1;
472 i = current_proc;
473 while ((i != 0) || first_time) {
474 first_time = 0;
475 /* check procedure attribute byte */
476 proc_attributes[i] =
477 (p[proc_table +
478 (13 * i) + 8] &
479 0x03);
480
481 /*
482 * BIT0 - OPTIONAL
483 * BIT1 - RECOMMENDED
484 * BIT6 - FORCED OFF
485 * BIT7 - FORCED ON
486 */
487
488 i = get_unaligned_be32(&p[proc_table +
489 (13 * i) + 4]);
490 }
491
492 /*
493 * Set current_proc to the first procedure
494 * to be executed
495 */
496 i = current_proc;
497 while ((i != 0) &&
498 ((proc_attributes[i] == 1) ||
499 ((proc_attributes[i] & 0xc0) == 0x40))) {
500 i = get_unaligned_be32(&p[proc_table +
501 (13 * i) + 4]);
502 }
503
504 if ((i != 0) || ((i == 0) && (current_proc == 0) &&
505 ((proc_attributes[0] != 1) &&
506 ((proc_attributes[0] & 0xc0) != 0x40)))) {
507 current_proc = i;
508 pc = code_sect +
509 get_unaligned_be32(&p[proc_table +
510 (13 * i) + 9]);
511 if ((pc < code_sect) || (pc >= debug_sect))
512 status = -ERANGE;
513 } else
514 /* there are no procedures to execute! */
515 done = 1;
516
517 }
518 }
519
520 msg_buff[0] = '\0';
521
522 while (!done) {
523 opcode = (p[pc] & 0xff);
524 opcode_address = pc;
525 ++pc;
526
527 if (debug > 1)
528 printk("opcode: %02x\n", opcode);
529
530 arg_count = (opcode >> 6) & 3;
531 for (i = 0; i < arg_count; ++i) {
532 args[i] = get_unaligned_be32(&p[pc]);
533 pc += 4;
534 }
535
536 switch (opcode) {
537 case OP_NOP:
538 break;
539 case OP_DUP:
540 if (altera_check_stack(stack_ptr, 1, &status)) {
541 stack[stack_ptr] = stack[stack_ptr - 1];
542 ++stack_ptr;
543 }
544 break;
545 case OP_SWP:
546 if (altera_check_stack(stack_ptr, 2, &status)) {
547 long_tmp = stack[stack_ptr - 2];
548 stack[stack_ptr - 2] = stack[stack_ptr - 1];
549 stack[stack_ptr - 1] = long_tmp;
550 }
551 break;
552 case OP_ADD:
553 if (altera_check_stack(stack_ptr, 2, &status)) {
554 --stack_ptr;
555 stack[stack_ptr - 1] += stack[stack_ptr];
556 }
557 break;
558 case OP_SUB:
559 if (altera_check_stack(stack_ptr, 2, &status)) {
560 --stack_ptr;
561 stack[stack_ptr - 1] -= stack[stack_ptr];
562 }
563 break;
564 case OP_MULT:
565 if (altera_check_stack(stack_ptr, 2, &status)) {
566 --stack_ptr;
567 stack[stack_ptr - 1] *= stack[stack_ptr];
568 }
569 break;
570 case OP_DIV:
571 if (altera_check_stack(stack_ptr, 2, &status)) {
572 --stack_ptr;
573 stack[stack_ptr - 1] /= stack[stack_ptr];
574 }
575 break;
576 case OP_MOD:
577 if (altera_check_stack(stack_ptr, 2, &status)) {
578 --stack_ptr;
579 stack[stack_ptr - 1] %= stack[stack_ptr];
580 }
581 break;
582 case OP_SHL:
583 if (altera_check_stack(stack_ptr, 2, &status)) {
584 --stack_ptr;
585 stack[stack_ptr - 1] <<= stack[stack_ptr];
586 }
587 break;
588 case OP_SHR:
589 if (altera_check_stack(stack_ptr, 2, &status)) {
590 --stack_ptr;
591 stack[stack_ptr - 1] >>= stack[stack_ptr];
592 }
593 break;
594 case OP_NOT:
595 if (altera_check_stack(stack_ptr, 1, &status))
596 stack[stack_ptr - 1] ^= (-1L);
597
598 break;
599 case OP_AND:
600 if (altera_check_stack(stack_ptr, 2, &status)) {
601 --stack_ptr;
602 stack[stack_ptr - 1] &= stack[stack_ptr];
603 }
604 break;
605 case OP_OR:
606 if (altera_check_stack(stack_ptr, 2, &status)) {
607 --stack_ptr;
608 stack[stack_ptr - 1] |= stack[stack_ptr];
609 }
610 break;
611 case OP_XOR:
612 if (altera_check_stack(stack_ptr, 2, &status)) {
613 --stack_ptr;
614 stack[stack_ptr - 1] ^= stack[stack_ptr];
615 }
616 break;
617 case OP_INV:
618 if (!altera_check_stack(stack_ptr, 1, &status))
619 break;
620 stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;
621 break;
622 case OP_GT:
623 if (!altera_check_stack(stack_ptr, 2, &status))
624 break;
625 --stack_ptr;
626 stack[stack_ptr - 1] =
627 (stack[stack_ptr - 1] > stack[stack_ptr]) ?
628 1L : 0L;
629
630 break;
631 case OP_LT:
632 if (!altera_check_stack(stack_ptr, 2, &status))
633 break;
634 --stack_ptr;
635 stack[stack_ptr - 1] =
636 (stack[stack_ptr - 1] < stack[stack_ptr]) ?
637 1L : 0L;
638
639 break;
640 case OP_RET:
641 if ((version > 0) && (stack_ptr == 0)) {
642 /*
643 * We completed one of the main procedures
644 * of an ACTION.
645 * Find the next procedure
646 * to be executed and jump to it.
647 * If there are no more procedures, then EXIT.
648 */
649 i = get_unaligned_be32(&p[proc_table +
650 (13 * current_proc) + 4]);
651 while ((i != 0) &&
652 ((proc_attributes[i] == 1) ||
653 ((proc_attributes[i] & 0xc0) == 0x40)))
654 i = get_unaligned_be32(&p[proc_table +
655 (13 * i) + 4]);
656
657 if (i == 0) {
658 /* no procedures to execute! */
659 done = 1;
660 *exit_code = 0; /* success */
661 } else {
662 current_proc = i;
663 pc = code_sect + get_unaligned_be32(
664 &p[proc_table +
665 (13 * i) + 9]);
666 if ((pc < code_sect) ||
667 (pc >= debug_sect))
668 status = -ERANGE;
669 }
670
671 } else
672 if (altera_check_stack(stack_ptr, 1, &status)) {
673 pc = stack[--stack_ptr] + code_sect;
674 if ((pc <= code_sect) ||
675 (pc >= debug_sect))
676 status = -ERANGE;
677
678 }
679
680 break;
681 case OP_CMPS:
682 /*
683 * Array short compare
684 * ...stack 0 is source 1 value
685 * ...stack 1 is source 2 value
686 * ...stack 2 is mask value
687 * ...stack 3 is count
688 */
689 if (altera_check_stack(stack_ptr, 4, &status)) {
690 s32 a = stack[--stack_ptr];
691 s32 b = stack[--stack_ptr];
692 long_tmp = stack[--stack_ptr];
693 count = stack[stack_ptr - 1];
694
695 if ((count < 1) || (count > 32))
696 status = -ERANGE;
697 else {
698 long_tmp &= ((-1L) >> (32 - count));
699
700 stack[stack_ptr - 1] =
701 ((a & long_tmp) == (b & long_tmp))
702 ? 1L : 0L;
703 }
704 }
705 break;
706 case OP_PINT:
707 /*
708 * PRINT add integer
709 * ...stack 0 is integer value
710 */
711 if (!altera_check_stack(stack_ptr, 1, &status))
712 break;
713 sprintf(&msg_buff[strlen(msg_buff)],
714 "%ld", stack[--stack_ptr]);
715 break;
716 case OP_PRNT:
717 /* PRINT finish */
718 if (debug)
719 printk(msg_buff, "\n");
720
721 msg_buff[0] = '\0';
722 break;
723 case OP_DSS:
724 /*
725 * DRSCAN short
726 * ...stack 0 is scan data
727 * ...stack 1 is count
728 */
729 if (!altera_check_stack(stack_ptr, 2, &status))
730 break;
731 long_tmp = stack[--stack_ptr];
732 count = stack[--stack_ptr];
733 put_unaligned_le32(long_tmp, &charbuf[0]);
734 status = altera_drscan(astate, count, charbuf, 0);
735 break;
736 case OP_DSSC:
737 /*
738 * DRSCAN short with capture
739 * ...stack 0 is scan data
740 * ...stack 1 is count
741 */
742 if (!altera_check_stack(stack_ptr, 2, &status))
743 break;
744 long_tmp = stack[--stack_ptr];
745 count = stack[stack_ptr - 1];
746 put_unaligned_le32(long_tmp, &charbuf[0]);
747 status = altera_swap_dr(astate, count, charbuf,
748 0, charbuf, 0);
749 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
750 break;
751 case OP_ISS:
752 /*
753 * IRSCAN short
754 * ...stack 0 is scan data
755 * ...stack 1 is count
756 */
757 if (!altera_check_stack(stack_ptr, 2, &status))
758 break;
759 long_tmp = stack[--stack_ptr];
760 count = stack[--stack_ptr];
761 put_unaligned_le32(long_tmp, &charbuf[0]);
762 status = altera_irscan(astate, count, charbuf, 0);
763 break;
764 case OP_ISSC:
765 /*
766 * IRSCAN short with capture
767 * ...stack 0 is scan data
768 * ...stack 1 is count
769 */
770 if (!altera_check_stack(stack_ptr, 2, &status))
771 break;
772 long_tmp = stack[--stack_ptr];
773 count = stack[stack_ptr - 1];
774 put_unaligned_le32(long_tmp, &charbuf[0]);
775 status = altera_swap_ir(astate, count, charbuf,
776 0, charbuf, 0);
777 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
778 break;
779 case OP_DPR:
780 if (!altera_check_stack(stack_ptr, 1, &status))
781 break;
782 count = stack[--stack_ptr];
783 status = altera_set_dr_pre(&astate->js, count, 0, NULL);
784 break;
785 case OP_DPRL:
786 /*
787 * DRPRE with literal data
788 * ...stack 0 is count
789 * ...stack 1 is literal data
790 */
791 if (!altera_check_stack(stack_ptr, 2, &status))
792 break;
793 count = stack[--stack_ptr];
794 long_tmp = stack[--stack_ptr];
795 put_unaligned_le32(long_tmp, &charbuf[0]);
796 status = altera_set_dr_pre(&astate->js, count, 0,
797 charbuf);
798 break;
799 case OP_DPO:
800 /*
801 * DRPOST
802 * ...stack 0 is count
803 */
804 if (altera_check_stack(stack_ptr, 1, &status)) {
805 count = stack[--stack_ptr];
806 status = altera_set_dr_post(&astate->js, count,
807 0, NULL);
808 }
809 break;
810 case OP_DPOL:
811 /*
812 * DRPOST with literal data
813 * ...stack 0 is count
814 * ...stack 1 is literal data
815 */
816 if (!altera_check_stack(stack_ptr, 2, &status))
817 break;
818 count = stack[--stack_ptr];
819 long_tmp = stack[--stack_ptr];
820 put_unaligned_le32(long_tmp, &charbuf[0]);
821 status = altera_set_dr_post(&astate->js, count, 0,
822 charbuf);
823 break;
824 case OP_IPR:
825 if (altera_check_stack(stack_ptr, 1, &status)) {
826 count = stack[--stack_ptr];
827 status = altera_set_ir_pre(&astate->js, count,
828 0, NULL);
829 }
830 break;
831 case OP_IPRL:
832 /*
833 * IRPRE with literal data
834 * ...stack 0 is count
835 * ...stack 1 is literal data
836 */
837 if (altera_check_stack(stack_ptr, 2, &status)) {
838 count = stack[--stack_ptr];
839 long_tmp = stack[--stack_ptr];
840 put_unaligned_le32(long_tmp, &charbuf[0]);
841 status = altera_set_ir_pre(&astate->js, count,
842 0, charbuf);
843 }
844 break;
845 case OP_IPO:
846 /*
847 * IRPOST
848 * ...stack 0 is count
849 */
850 if (altera_check_stack(stack_ptr, 1, &status)) {
851 count = stack[--stack_ptr];
852 status = altera_set_ir_post(&astate->js, count,
853 0, NULL);
854 }
855 break;
856 case OP_IPOL:
857 /*
858 * IRPOST with literal data
859 * ...stack 0 is count
860 * ...stack 1 is literal data
861 */
862 if (!altera_check_stack(stack_ptr, 2, &status))
863 break;
864 count = stack[--stack_ptr];
865 long_tmp = stack[--stack_ptr];
866 put_unaligned_le32(long_tmp, &charbuf[0]);
867 status = altera_set_ir_post(&astate->js, count, 0,
868 charbuf);
869 break;
870 case OP_PCHR:
871 if (altera_check_stack(stack_ptr, 1, &status)) {
872 u8 ch;
873 count = strlen(msg_buff);
874 ch = (char) stack[--stack_ptr];
875 if ((ch < 1) || (ch > 127)) {
876 /*
877 * character code out of range
878 * instead of flagging an error,
879 * force the value to 127
880 */
881 ch = 127;
882 }
883 msg_buff[count] = ch;
884 msg_buff[count + 1] = '\0';
885 }
886 break;
887 case OP_EXIT:
888 if (altera_check_stack(stack_ptr, 1, &status))
889 *exit_code = stack[--stack_ptr];
890
891 done = 1;
892 break;
893 case OP_EQU:
894 if (!altera_check_stack(stack_ptr, 2, &status))
895 break;
896 --stack_ptr;
897 stack[stack_ptr - 1] =
898 (stack[stack_ptr - 1] == stack[stack_ptr]) ?
899 1L : 0L;
900 break;
901 case OP_POPT:
902 if (altera_check_stack(stack_ptr, 1, &status))
903 --stack_ptr;
904
905 break;
906 case OP_ABS:
907 if (!altera_check_stack(stack_ptr, 1, &status))
908 break;
909 if (stack[stack_ptr - 1] < 0)
910 stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
911
912 break;
913 case OP_BCH0:
914 /*
915 * Batch operation 0
916 * SWP
917 * SWPN 7
918 * SWP
919 * SWPN 6
920 * DUPN 8
921 * SWPN 2
922 * SWP
923 * DUPN 6
924 * DUPN 6
925 */
926
927 /* SWP */
928 if (altera_check_stack(stack_ptr, 2, &status)) {
929 long_tmp = stack[stack_ptr - 2];
930 stack[stack_ptr - 2] = stack[stack_ptr - 1];
931 stack[stack_ptr - 1] = long_tmp;
932 }
933
934 /* SWPN 7 */
935 index = 7 + 1;
936 if (altera_check_stack(stack_ptr, index, &status)) {
937 long_tmp = stack[stack_ptr - index];
938 stack[stack_ptr - index] = stack[stack_ptr - 1];
939 stack[stack_ptr - 1] = long_tmp;
940 }
941
942 /* SWP */
943 if (altera_check_stack(stack_ptr, 2, &status)) {
944 long_tmp = stack[stack_ptr - 2];
945 stack[stack_ptr - 2] = stack[stack_ptr - 1];
946 stack[stack_ptr - 1] = long_tmp;
947 }
948
949 /* SWPN 6 */
950 index = 6 + 1;
951 if (altera_check_stack(stack_ptr, index, &status)) {
952 long_tmp = stack[stack_ptr - index];
953 stack[stack_ptr - index] = stack[stack_ptr - 1];
954 stack[stack_ptr - 1] = long_tmp;
955 }
956
957 /* DUPN 8 */
958 index = 8 + 1;
959 if (altera_check_stack(stack_ptr, index, &status)) {
960 stack[stack_ptr] = stack[stack_ptr - index];
961 ++stack_ptr;
962 }
963
964 /* SWPN 2 */
965 index = 2 + 1;
966 if (altera_check_stack(stack_ptr, index, &status)) {
967 long_tmp = stack[stack_ptr - index];
968 stack[stack_ptr - index] = stack[stack_ptr - 1];
969 stack[stack_ptr - 1] = long_tmp;
970 }
971
972 /* SWP */
973 if (altera_check_stack(stack_ptr, 2, &status)) {
974 long_tmp = stack[stack_ptr - 2];
975 stack[stack_ptr - 2] = stack[stack_ptr - 1];
976 stack[stack_ptr - 1] = long_tmp;
977 }
978
979 /* DUPN 6 */
980 index = 6 + 1;
981 if (altera_check_stack(stack_ptr, index, &status)) {
982 stack[stack_ptr] = stack[stack_ptr - index];
983 ++stack_ptr;
984 }
985
986 /* DUPN 6 */
987 index = 6 + 1;
988 if (altera_check_stack(stack_ptr, index, &status)) {
989 stack[stack_ptr] = stack[stack_ptr - index];
990 ++stack_ptr;
991 }
992 break;
993 case OP_PSH0:
994 stack[stack_ptr++] = 0;
995 break;
996 case OP_PSHL:
997 stack[stack_ptr++] = (s32) args[0];
998 break;
999 case OP_PSHV:
1000 stack[stack_ptr++] = vars[args[0]];
1001 break;
1002 case OP_JMP:
1003 pc = args[0] + code_sect;
1004 if ((pc < code_sect) || (pc >= debug_sect))
1005 status = -ERANGE;
1006 break;
1007 case OP_CALL:
1008 stack[stack_ptr++] = pc;
1009 pc = args[0] + code_sect;
1010 if ((pc < code_sect) || (pc >= debug_sect))
1011 status = -ERANGE;
1012 break;
1013 case OP_NEXT:
1014 /*
1015 * Process FOR / NEXT loop
1016 * ...argument 0 is variable ID
1017 * ...stack 0 is step value
1018 * ...stack 1 is end value
1019 * ...stack 2 is top address
1020 */
1021 if (altera_check_stack(stack_ptr, 3, &status)) {
1022 s32 step = stack[stack_ptr - 1];
1023 s32 end = stack[stack_ptr - 2];
1024 s32 top = stack[stack_ptr - 3];
1025 s32 iterator = vars[args[0]];
1026 int break_out = 0;
1027
1028 if (step < 0) {
1029 if (iterator <= end)
1030 break_out = 1;
1031 } else if (iterator >= end)
1032 break_out = 1;
1033
1034 if (break_out) {
1035 stack_ptr -= 3;
1036 } else {
1037 vars[args[0]] = iterator + step;
1038 pc = top + code_sect;
1039 if ((pc < code_sect) ||
1040 (pc >= debug_sect))
1041 status = -ERANGE;
1042 }
1043 }
1044 break;
1045 case OP_PSTR:
1046 /*
1047 * PRINT add string
1048 * ...argument 0 is string ID
1049 */
1050 count = strlen(msg_buff);
1051 strlcpy(&msg_buff[count],
1052 &p[str_table + args[0]],
1053 ALTERA_MESSAGE_LENGTH - count);
1054 break;
1055 case OP_SINT:
1056 /*
1057 * STATE intermediate state
1058 * ...argument 0 is state code
1059 */
1060 status = altera_goto_jstate(astate, args[0]);
1061 break;
1062 case OP_ST:
1063 /*
1064 * STATE final state
1065 * ...argument 0 is state code
1066 */
1067 status = altera_goto_jstate(astate, args[0]);
1068 break;
1069 case OP_ISTP:
1070 /*
1071 * IRSTOP state
1072 * ...argument 0 is state code
1073 */
1074 status = altera_set_irstop(&astate->js, args[0]);
1075 break;
1076 case OP_DSTP:
1077 /*
1078 * DRSTOP state
1079 * ...argument 0 is state code
1080 */
1081 status = altera_set_drstop(&astate->js, args[0]);
1082 break;
1083
1084 case OP_SWPN:
1085 /*
1086 * Exchange top with Nth stack value
1087 * ...argument 0 is 0-based stack entry
1088 * to swap with top element
1089 */
1090 index = (args[0]) + 1;
1091 if (altera_check_stack(stack_ptr, index, &status)) {
1092 long_tmp = stack[stack_ptr - index];
1093 stack[stack_ptr - index] = stack[stack_ptr - 1];
1094 stack[stack_ptr - 1] = long_tmp;
1095 }
1096 break;
1097 case OP_DUPN:
1098 /*
1099 * Duplicate Nth stack value
1100 * ...argument 0 is 0-based stack entry to duplicate
1101 */
1102 index = (args[0]) + 1;
1103 if (altera_check_stack(stack_ptr, index, &status)) {
1104 stack[stack_ptr] = stack[stack_ptr - index];
1105 ++stack_ptr;
1106 }
1107 break;
1108 case OP_POPV:
1109 /*
1110 * Pop stack into scalar variable
1111 * ...argument 0 is variable ID
1112 * ...stack 0 is value
1113 */
1114 if (altera_check_stack(stack_ptr, 1, &status))
1115 vars[args[0]] = stack[--stack_ptr];
1116
1117 break;
1118 case OP_POPE:
1119 /*
1120 * Pop stack into integer array element
1121 * ...argument 0 is variable ID
1122 * ...stack 0 is array index
1123 * ...stack 1 is value
1124 */
1125 if (!altera_check_stack(stack_ptr, 2, &status))
1126 break;
1127 variable_id = args[0];
1128
1129 /*
1130 * If variable is read-only,
1131 * convert to writable array
1132 */
1133 if ((version > 0) &&
1134 ((attrs[variable_id] & 0x9c) == 0x1c)) {
1135 /* Allocate a writable buffer for this array */
1136 count = var_size[variable_id];
1137 long_tmp = vars[variable_id];
1138 longptr_tmp = kzalloc(count * sizeof(long),
1139 GFP_KERNEL);
1140 vars[variable_id] = (long)longptr_tmp;
1141
1142 if (vars[variable_id] == 0) {
1143 status = -ENOMEM;
1144 break;
1145 }
1146
1147 /* copy previous contents into buffer */
1148 for (i = 0; i < count; ++i) {
1149 longptr_tmp[i] =
1150 get_unaligned_be32(&p[long_tmp]);
1151 long_tmp += sizeof(long);
1152 }
1153
1154 /*
1155 * set bit 7 - buffer was
1156 * dynamically allocated
1157 */
1158 attrs[variable_id] |= 0x80;
1159
1160 /* clear bit 2 - variable is writable */
1161 attrs[variable_id] &= ~0x04;
1162 attrs[variable_id] |= 0x01;
1163
1164 }
1165
1166 /* check that variable is a writable integer array */
1167 if ((attrs[variable_id] & 0x1c) != 0x18)
1168 status = -ERANGE;
1169 else {
1170 longptr_tmp = (long *)vars[variable_id];
1171
1172 /* pop the array index */
1173 index = stack[--stack_ptr];
1174
1175 /* pop the value and store it into the array */
1176 longptr_tmp[index] = stack[--stack_ptr];
1177 }
1178
1179 break;
1180 case OP_POPA:
1181 /*
1182 * Pop stack into Boolean array
1183 * ...argument 0 is variable ID
1184 * ...stack 0 is count
1185 * ...stack 1 is array index
1186 * ...stack 2 is value
1187 */
1188 if (!altera_check_stack(stack_ptr, 3, &status))
1189 break;
1190 variable_id = args[0];
1191
1192 /*
1193 * If variable is read-only,
1194 * convert to writable array
1195 */
1196 if ((version > 0) &&
1197 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1198 /* Allocate a writable buffer for this array */
1199 long_tmp =
1200 (var_size[variable_id] + 7L) >> 3L;
1201 charptr_tmp2 = (u8 *)vars[variable_id];
1202 charptr_tmp =
1203 kzalloc(long_tmp, GFP_KERNEL);
1204 vars[variable_id] = (long)charptr_tmp;
1205
1206 if (vars[variable_id] == 0) {
1207 status = -ENOMEM;
1208 break;
1209 }
1210
1211 /* zero the buffer */
1212 for (long_idx = 0L;
1213 long_idx < long_tmp;
1214 ++long_idx) {
1215 charptr_tmp[long_idx] = 0;
1216 }
1217
1218 /* copy previous contents into buffer */
1219 for (long_idx = 0L;
1220 long_idx < var_size[variable_id];
1221 ++long_idx) {
1222 long_idx2 = long_idx;
1223
1224 if (charptr_tmp2[long_idx2 >> 3] &
1225 (1 << (long_idx2 & 7))) {
1226 charptr_tmp[long_idx >> 3] |=
1227 (1 << (long_idx & 7));
1228 }
1229 }
1230
1231 /*
1232 * set bit 7 - buffer was
1233 * dynamically allocated
1234 */
1235 attrs[variable_id] |= 0x80;
1236
1237 /* clear bit 2 - variable is writable */
1238 attrs[variable_id] &= ~0x04;
1239 attrs[variable_id] |= 0x01;
1240
1241 }
1242
1243 /*
1244 * check that variable is
1245 * a writable Boolean array
1246 */
1247 if ((attrs[variable_id] & 0x1c) != 0x08) {
1248 status = -ERANGE;
1249 break;
1250 }
1251
1252 charptr_tmp = (u8 *)vars[variable_id];
1253
1254 /* pop the count (number of bits to copy) */
1255 long_count = stack[--stack_ptr];
1256
1257 /* pop the array index */
1258 long_idx = stack[--stack_ptr];
1259
1260 reverse = 0;
1261
1262 if (version > 0) {
1263 /*
1264 * stack 0 = array right index
1265 * stack 1 = array left index
1266 */
1267
1268 if (long_idx > long_count) {
1269 reverse = 1;
1270 long_tmp = long_count;
1271 long_count = 1 + long_idx -
1272 long_count;
1273 long_idx = long_tmp;
1274
1275 /* reverse POPA is not supported */
1276 status = -ERANGE;
1277 break;
1278 } else
1279 long_count = 1 + long_count -
1280 long_idx;
1281
1282 }
1283
1284 /* pop the data */
1285 long_tmp = stack[--stack_ptr];
1286
1287 if (long_count < 1) {
1288 status = -ERANGE;
1289 break;
1290 }
1291
1292 for (i = 0; i < long_count; ++i) {
1293 if (long_tmp & (1L << (s32) i))
1294 charptr_tmp[long_idx >> 3L] |=
1295 (1L << (long_idx & 7L));
1296 else
1297 charptr_tmp[long_idx >> 3L] &=
1298 ~(1L << (long_idx & 7L));
1299
1300 ++long_idx;
1301 }
1302
1303 break;
1304 case OP_JMPZ:
1305 /*
1306 * Pop stack and branch if zero
1307 * ...argument 0 is address
1308 * ...stack 0 is condition value
1309 */
1310 if (altera_check_stack(stack_ptr, 1, &status)) {
1311 if (stack[--stack_ptr] == 0) {
1312 pc = args[0] + code_sect;
1313 if ((pc < code_sect) ||
1314 (pc >= debug_sect))
1315 status = -ERANGE;
1316 }
1317 }
1318 break;
1319 case OP_DS:
1320 case OP_IS:
1321 /*
1322 * DRSCAN
1323 * IRSCAN
1324 * ...argument 0 is scan data variable ID
1325 * ...stack 0 is array index
1326 * ...stack 1 is count
1327 */
1328 if (!altera_check_stack(stack_ptr, 2, &status))
1329 break;
1330 long_idx = stack[--stack_ptr];
1331 long_count = stack[--stack_ptr];
1332 reverse = 0;
1333 if (version > 0) {
1334 /*
1335 * stack 0 = array right index
1336 * stack 1 = array left index
1337 * stack 2 = count
1338 */
1339 long_tmp = long_count;
1340 long_count = stack[--stack_ptr];
1341
1342 if (long_idx > long_tmp) {
1343 reverse = 1;
1344 long_idx = long_tmp;
1345 }
1346 }
1347
1348 charptr_tmp = (u8 *)vars[args[0]];
1349
1350 if (reverse) {
1351 /*
1352 * allocate a buffer
1353 * and reverse the data order
1354 */
1355 charptr_tmp2 = charptr_tmp;
1356 charptr_tmp = kzalloc((long_count >> 3) + 1,
1357 GFP_KERNEL);
1358 if (charptr_tmp == NULL) {
1359 status = -ENOMEM;
1360 break;
1361 }
1362
1363 long_tmp = long_idx + long_count - 1;
1364 long_idx2 = 0;
1365 while (long_idx2 < long_count) {
1366 if (charptr_tmp2[long_tmp >> 3] &
1367 (1 << (long_tmp & 7)))
1368 charptr_tmp[long_idx2 >> 3] |=
1369 (1 << (long_idx2 & 7));
1370 else
1371 charptr_tmp[long_idx2 >> 3] &=
1372 ~(1 << (long_idx2 & 7));
1373
1374 --long_tmp;
1375 ++long_idx2;
1376 }
1377 }
1378
1379 if (opcode == 0x51) /* DS */
1380 status = altera_drscan(astate, long_count,
1381 charptr_tmp, long_idx);
1382 else /* IS */
1383 status = altera_irscan(astate, long_count,
1384 charptr_tmp, long_idx);
1385
1386 if (reverse)
1387 kfree(charptr_tmp);
1388
1389 break;
1390 case OP_DPRA:
1391 /*
1392 * DRPRE with array data
1393 * ...argument 0 is variable ID
1394 * ...stack 0 is array index
1395 * ...stack 1 is count
1396 */
1397 if (!altera_check_stack(stack_ptr, 2, &status))
1398 break;
1399 index = stack[--stack_ptr];
1400 count = stack[--stack_ptr];
1401
1402 if (version > 0)
1403 /*
1404 * stack 0 = array right index
1405 * stack 1 = array left index
1406 */
1407 count = 1 + count - index;
1408
1409 charptr_tmp = (u8 *)vars[args[0]];
1410 status = altera_set_dr_pre(&astate->js, count, index,
1411 charptr_tmp);
1412 break;
1413 case OP_DPOA:
1414 /*
1415 * DRPOST with array data
1416 * ...argument 0 is variable ID
1417 * ...stack 0 is array index
1418 * ...stack 1 is count
1419 */
1420 if (!altera_check_stack(stack_ptr, 2, &status))
1421 break;
1422 index = stack[--stack_ptr];
1423 count = stack[--stack_ptr];
1424
1425 if (version > 0)
1426 /*
1427 * stack 0 = array right index
1428 * stack 1 = array left index
1429 */
1430 count = 1 + count - index;
1431
1432 charptr_tmp = (u8 *)vars[args[0]];
1433 status = altera_set_dr_post(&astate->js, count, index,
1434 charptr_tmp);
1435 break;
1436 case OP_IPRA:
1437 /*
1438 * IRPRE with array data
1439 * ...argument 0 is variable ID
1440 * ...stack 0 is array index
1441 * ...stack 1 is count
1442 */
1443 if (!altera_check_stack(stack_ptr, 2, &status))
1444 break;
1445 index = stack[--stack_ptr];
1446 count = stack[--stack_ptr];
1447
1448 if (version > 0)
1449 /*
1450 * stack 0 = array right index
1451 * stack 1 = array left index
1452 */
1453 count = 1 + count - index;
1454
1455 charptr_tmp = (u8 *)vars[args[0]];
1456 status = altera_set_ir_pre(&astate->js, count, index,
1457 charptr_tmp);
1458
1459 break;
1460 case OP_IPOA:
1461 /*
1462 * IRPOST with array data
1463 * ...argument 0 is variable ID
1464 * ...stack 0 is array index
1465 * ...stack 1 is count
1466 */
1467 if (!altera_check_stack(stack_ptr, 2, &status))
1468 break;
1469 index = stack[--stack_ptr];
1470 count = stack[--stack_ptr];
1471
1472 if (version > 0)
1473 /*
1474 * stack 0 = array right index
1475 * stack 1 = array left index
1476 */
1477 count = 1 + count - index;
1478
1479 charptr_tmp = (u8 *)vars[args[0]];
1480 status = altera_set_ir_post(&astate->js, count, index,
1481 charptr_tmp);
1482
1483 break;
1484 case OP_EXPT:
1485 /*
1486 * EXPORT
1487 * ...argument 0 is string ID
1488 * ...stack 0 is integer expression
1489 */
1490 if (altera_check_stack(stack_ptr, 1, &status)) {
1491 name = &p[str_table + args[0]];
1492 long_tmp = stack[--stack_ptr];
1493 altera_export_int(name, long_tmp);
1494 }
1495 break;
1496 case OP_PSHE:
1497 /*
1498 * Push integer array element
1499 * ...argument 0 is variable ID
1500 * ...stack 0 is array index
1501 */
1502 if (!altera_check_stack(stack_ptr, 1, &status))
1503 break;
1504 variable_id = args[0];
1505 index = stack[stack_ptr - 1];
1506
1507 /* check variable type */
1508 if ((attrs[variable_id] & 0x1f) == 0x19) {
1509 /* writable integer array */
1510 longptr_tmp = (long *)vars[variable_id];
1511 stack[stack_ptr - 1] = longptr_tmp[index];
1512 } else if ((attrs[variable_id] & 0x1f) == 0x1c) {
1513 /* read-only integer array */
1514 long_tmp = vars[variable_id] +
1515 (index * sizeof(long));
1516 stack[stack_ptr - 1] =
1517 get_unaligned_be32(&p[long_tmp]);
1518 } else
1519 status = -ERANGE;
1520
1521 break;
1522 case OP_PSHA:
1523 /*
1524 * Push Boolean array
1525 * ...argument 0 is variable ID
1526 * ...stack 0 is count
1527 * ...stack 1 is array index
1528 */
1529 if (!altera_check_stack(stack_ptr, 2, &status))
1530 break;
1531 variable_id = args[0];
1532
1533 /* check that variable is a Boolean array */
1534 if ((attrs[variable_id] & 0x18) != 0x08) {
1535 status = -ERANGE;
1536 break;
1537 }
1538
1539 charptr_tmp = (u8 *)vars[variable_id];
1540
1541 /* pop the count (number of bits to copy) */
1542 count = stack[--stack_ptr];
1543
1544 /* pop the array index */
1545 index = stack[stack_ptr - 1];
1546
1547 if (version > 0)
1548 /*
1549 * stack 0 = array right index
1550 * stack 1 = array left index
1551 */
1552 count = 1 + count - index;
1553
1554 if ((count < 1) || (count > 32)) {
1555 status = -ERANGE;
1556 break;
1557 }
1558
1559 long_tmp = 0L;
1560
1561 for (i = 0; i < count; ++i)
1562 if (charptr_tmp[(i + index) >> 3] &
1563 (1 << ((i + index) & 7)))
1564 long_tmp |= (1L << i);
1565
1566 stack[stack_ptr - 1] = long_tmp;
1567
1568 break;
1569 case OP_DYNA:
1570 /*
1571 * Dynamically change size of array
1572 * ...argument 0 is variable ID
1573 * ...stack 0 is new size
1574 */
1575 if (!altera_check_stack(stack_ptr, 1, &status))
1576 break;
1577 variable_id = args[0];
1578 long_tmp = stack[--stack_ptr];
1579
1580 if (long_tmp > var_size[variable_id]) {
1581 var_size[variable_id] = long_tmp;
1582
1583 if (attrs[variable_id] & 0x10)
1584 /* allocate integer array */
1585 long_tmp *= sizeof(long);
1586 else
1587 /* allocate Boolean array */
1588 long_tmp = (long_tmp + 7) >> 3;
1589
1590 /*
1591 * If the buffer was previously allocated,
1592 * free it
1593 */
1594 if (attrs[variable_id] & 0x80) {
1595 kfree((void *)vars[variable_id]);
1596 vars[variable_id] = 0;
1597 }
1598
1599 /*
1600 * Allocate a new buffer
1601 * of the requested size
1602 */
1603 vars[variable_id] = (long)
1604 kzalloc(long_tmp, GFP_KERNEL);
1605
1606 if (vars[variable_id] == 0) {
1607 status = -ENOMEM;
1608 break;
1609 }
1610
1611 /*
1612 * Set the attribute bit to indicate that
1613 * this buffer was dynamically allocated and
1614 * should be freed later
1615 */
1616 attrs[variable_id] |= 0x80;
1617
1618 /* zero out memory */
1619 count = ((var_size[variable_id] + 7L) /
1620 8L);
1621 charptr_tmp = (u8 *)(vars[variable_id]);
1622 for (index = 0; index < count; ++index)
1623 charptr_tmp[index] = 0;
1624
1625 }
1626
1627 break;
1628 case OP_EXPV:
1629 /*
1630 * Export Boolean array
1631 * ...argument 0 is string ID
1632 * ...stack 0 is variable ID
1633 * ...stack 1 is array right index
1634 * ...stack 2 is array left index
1635 */
1636 if (!altera_check_stack(stack_ptr, 3, &status))
1637 break;
1638 if (version == 0) {
1639 /* EXPV is not supported in JBC 1.0 */
1640 bad_opcode = 1;
1641 break;
1642 }
1643 name = &p[str_table + args[0]];
1644 variable_id = stack[--stack_ptr];
1645 long_idx = stack[--stack_ptr];/* right indx */
1646 long_idx2 = stack[--stack_ptr];/* left indx */
1647
1648 if (long_idx > long_idx2) {
1649 /* reverse indices not supported */
1650 status = -ERANGE;
1651 break;
1652 }
1653
1654 long_count = 1 + long_idx2 - long_idx;
1655
1656 charptr_tmp = (u8 *)vars[variable_id];
1657 charptr_tmp2 = NULL;
1658
1659 if ((long_idx & 7L) != 0) {
1660 s32 k = long_idx;
1661 charptr_tmp2 =
1662 kzalloc(((long_count + 7L) / 8L),
1663 GFP_KERNEL);
1664 if (charptr_tmp2 == NULL) {
1665 status = -ENOMEM;
1666 break;
1667 }
1668
1669 for (i = 0; i < long_count; ++i) {
1670 if (charptr_tmp[k >> 3] &
1671 (1 << (k & 7)))
1672 charptr_tmp2[i >> 3] |=
1673 (1 << (i & 7));
1674 else
1675 charptr_tmp2[i >> 3] &=
1676 ~(1 << (i & 7));
1677
1678 ++k;
1679 }
1680 charptr_tmp = charptr_tmp2;
1681
1682 } else if (long_idx != 0)
1683 charptr_tmp = &charptr_tmp[long_idx >> 3];
1684
1685 altera_export_bool_array(name, charptr_tmp,
1686 long_count);
1687
1688 /* free allocated buffer */
1689 if ((long_idx & 7L) != 0)
1690 kfree(charptr_tmp2);
1691
1692 break;
1693 case OP_COPY: {
1694 /*
1695 * Array copy
1696 * ...argument 0 is dest ID
1697 * ...argument 1 is source ID
1698 * ...stack 0 is count
1699 * ...stack 1 is dest index
1700 * ...stack 2 is source index
1701 */
1702 s32 copy_count;
1703 s32 copy_index;
1704 s32 copy_index2;
1705 s32 destleft;
1706 s32 src_count;
1707 s32 dest_count;
1708 int src_reverse = 0;
1709 int dest_reverse = 0;
1710
1711 if (!altera_check_stack(stack_ptr, 3, &status))
1712 break;
1713
1714 copy_count = stack[--stack_ptr];
1715 copy_index = stack[--stack_ptr];
1716 copy_index2 = stack[--stack_ptr];
1717 reverse = 0;
1718
1719 if (version > 0) {
1720 /*
1721 * stack 0 = source right index
1722 * stack 1 = source left index
1723 * stack 2 = destination right index
1724 * stack 3 = destination left index
1725 */
1726 destleft = stack[--stack_ptr];
1727
1728 if (copy_count > copy_index) {
1729 src_reverse = 1;
1730 reverse = 1;
1731 src_count = 1 + copy_count - copy_index;
1732 /* copy_index = source start index */
1733 } else {
1734 src_count = 1 + copy_index - copy_count;
1735 /* source start index */
1736 copy_index = copy_count;
1737 }
1738
1739 if (copy_index2 > destleft) {
1740 dest_reverse = 1;
1741 reverse = !reverse;
1742 dest_count = 1 + copy_index2 - destleft;
1743 /* destination start index */
1744 copy_index2 = destleft;
1745 } else
1746 dest_count = 1 + destleft - copy_index2;
1747
1748 copy_count = (src_count < dest_count) ?
1749 src_count : dest_count;
1750
1751 if ((src_reverse || dest_reverse) &&
1752 (src_count != dest_count))
1753 /*
1754 * If either the source or destination
1755 * is reversed, we can't tolerate
1756 * a length mismatch, because we
1757 * "left justify" arrays when copying.
1758 * This won't work correctly
1759 * with reversed arrays.
1760 */
1761 status = -ERANGE;
1762
1763 }
1764
1765 count = copy_count;
1766 index = copy_index;
1767 index2 = copy_index2;
1768
1769 /*
1770 * If destination is a read-only array,
1771 * allocate a buffer and convert it to a writable array
1772 */
1773 variable_id = args[1];
1774 if ((version > 0) &&
1775 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1776 /* Allocate a writable buffer for this array */
1777 long_tmp =
1778 (var_size[variable_id] + 7L) >> 3L;
1779 charptr_tmp2 = (u8 *)vars[variable_id];
1780 charptr_tmp =
1781 kzalloc(long_tmp, GFP_KERNEL);
1782 vars[variable_id] = (long)charptr_tmp;
1783
1784 if (vars[variable_id] == 0) {
1785 status = -ENOMEM;
1786 break;
1787 }
1788
1789 /* zero the buffer */
1790 for (long_idx = 0L; long_idx < long_tmp;
1791 ++long_idx)
1792 charptr_tmp[long_idx] = 0;
1793
1794 /* copy previous contents into buffer */
1795 for (long_idx = 0L;
1796 long_idx < var_size[variable_id];
1797 ++long_idx) {
1798 long_idx2 = long_idx;
1799
1800 if (charptr_tmp2[long_idx2 >> 3] &
1801 (1 << (long_idx2 & 7)))
1802 charptr_tmp[long_idx >> 3] |=
1803 (1 << (long_idx & 7));
1804
1805 }
1806
1807 /*
1808 set bit 7 - buffer was dynamically allocated */
1809 attrs[variable_id] |= 0x80;
1810
1811 /* clear bit 2 - variable is writable */
1812 attrs[variable_id] &= ~0x04;
1813 attrs[variable_id] |= 0x01;
1814 }
1815
1816 charptr_tmp = (u8 *)vars[args[1]];
1817 charptr_tmp2 = (u8 *)vars[args[0]];
1818
1819 /* check if destination is a writable Boolean array */
1820 if ((attrs[args[1]] & 0x1c) != 0x08) {
1821 status = -ERANGE;
1822 break;
1823 }
1824
1825 if (count < 1) {
1826 status = -ERANGE;
1827 break;
1828 }
1829
1830 if (reverse)
1831 index2 += (count - 1);
1832
1833 for (i = 0; i < count; ++i) {
1834 if (charptr_tmp2[index >> 3] &
1835 (1 << (index & 7)))
1836 charptr_tmp[index2 >> 3] |=
1837 (1 << (index2 & 7));
1838 else
1839 charptr_tmp[index2 >> 3] &=
1840 ~(1 << (index2 & 7));
1841
1842 ++index;
1843 if (reverse)
1844 --index2;
1845 else
1846 ++index2;
1847 }
1848
1849 break;
1850 }
1851 case OP_DSC:
1852 case OP_ISC: {
1853 /*
1854 * DRSCAN with capture
1855 * IRSCAN with capture
1856 * ...argument 0 is scan data variable ID
1857 * ...argument 1 is capture variable ID
1858 * ...stack 0 is capture index
1859 * ...stack 1 is scan data index
1860 * ...stack 2 is count
1861 */
1862 s32 scan_right, scan_left;
1863 s32 capture_count = 0;
1864 s32 scan_count = 0;
1865 s32 capture_index;
1866 s32 scan_index;
1867
1868 if (!altera_check_stack(stack_ptr, 3, &status))
1869 break;
1870
1871 capture_index = stack[--stack_ptr];
1872 scan_index = stack[--stack_ptr];
1873
1874 if (version > 0) {
1875 /*
1876 * stack 0 = capture right index
1877 * stack 1 = capture left index
1878 * stack 2 = scan right index
1879 * stack 3 = scan left index
1880 * stack 4 = count
1881 */
1882 scan_right = stack[--stack_ptr];
1883 scan_left = stack[--stack_ptr];
1884 capture_count = 1 + scan_index - capture_index;
1885 scan_count = 1 + scan_left - scan_right;
1886 scan_index = scan_right;
1887 }
1888
1889 long_count = stack[--stack_ptr];
1890 /*
1891 * If capture array is read-only, allocate a buffer
1892 * and convert it to a writable array
1893 */
1894 variable_id = args[1];
1895 if ((version > 0) &&
1896 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1897 /* Allocate a writable buffer for this array */
1898 long_tmp =
1899 (var_size[variable_id] + 7L) >> 3L;
1900 charptr_tmp2 = (u8 *)vars[variable_id];
1901 charptr_tmp =
1902 kzalloc(long_tmp, GFP_KERNEL);
1903 vars[variable_id] = (long)charptr_tmp;
1904
1905 if (vars[variable_id] == 0) {
1906 status = -ENOMEM;
1907 break;
1908 }
1909
1910 /* zero the buffer */
1911 for (long_idx = 0L; long_idx < long_tmp;
1912 ++long_idx)
1913 charptr_tmp[long_idx] = 0;
1914
1915 /* copy previous contents into buffer */
1916 for (long_idx = 0L;
1917 long_idx < var_size[variable_id];
1918 ++long_idx) {
1919 long_idx2 = long_idx;
1920
1921 if (charptr_tmp2[long_idx2 >> 3] &
1922 (1 << (long_idx2 & 7)))
1923 charptr_tmp[long_idx >> 3] |=
1924 (1 << (long_idx & 7));
1925
1926 }
1927
1928 /*
1929 * set bit 7 - buffer was
1930 * dynamically allocated
1931 */
1932 attrs[variable_id] |= 0x80;
1933
1934 /* clear bit 2 - variable is writable */
1935 attrs[variable_id] &= ~0x04;
1936 attrs[variable_id] |= 0x01;
1937
1938 }
1939
1940 charptr_tmp = (u8 *)vars[args[0]];
1941 charptr_tmp2 = (u8 *)vars[args[1]];
1942
1943 if ((version > 0) &&
1944 ((long_count > capture_count) ||
1945 (long_count > scan_count))) {
1946 status = -ERANGE;
1947 break;
1948 }
1949
1950 /*
1951 * check that capture array
1952 * is a writable Boolean array
1953 */
1954 if ((attrs[args[1]] & 0x1c) != 0x08) {
1955 status = -ERANGE;
1956 break;
1957 }
1958
1959 if (status == 0) {
1960 if (opcode == 0x82) /* DSC */
1961 status = altera_swap_dr(astate,
1962 long_count,
1963 charptr_tmp,
1964 scan_index,
1965 charptr_tmp2,
1966 capture_index);
1967 else /* ISC */
1968 status = altera_swap_ir(astate,
1969 long_count,
1970 charptr_tmp,
1971 scan_index,
1972 charptr_tmp2,
1973 capture_index);
1974
1975 }
1976
1977 break;
1978 }
1979 case OP_WAIT:
1980 /*
1981 * WAIT
1982 * ...argument 0 is wait state
1983 * ...argument 1 is end state
1984 * ...stack 0 is cycles
1985 * ...stack 1 is microseconds
1986 */
1987 if (!altera_check_stack(stack_ptr, 2, &status))
1988 break;
1989 long_tmp = stack[--stack_ptr];
1990
1991 if (long_tmp != 0L)
1992 status = altera_wait_cycles(astate, long_tmp,
1993 args[0]);
1994
1995 long_tmp = stack[--stack_ptr];
1996
1997 if ((status == 0) && (long_tmp != 0L))
1998 status = altera_wait_msecs(astate,
1999 long_tmp,
2000 args[0]);
2001
2002 if ((status == 0) && (args[1] != args[0]))
2003 status = altera_goto_jstate(astate,
2004 args[1]);
2005
2006 if (version > 0) {
2007 --stack_ptr; /* throw away MAX cycles */
2008 --stack_ptr; /* throw away MAX microseconds */
2009 }
2010 break;
2011 case OP_CMPA: {
2012 /*
2013 * Array compare
2014 * ...argument 0 is source 1 ID
2015 * ...argument 1 is source 2 ID
2016 * ...argument 2 is mask ID
2017 * ...stack 0 is source 1 index
2018 * ...stack 1 is source 2 index
2019 * ...stack 2 is mask index
2020 * ...stack 3 is count
2021 */
2022 s32 a, b;
2023 u8 *source1 = (u8 *)vars[args[0]];
2024 u8 *source2 = (u8 *)vars[args[1]];
2025 u8 *mask = (u8 *)vars[args[2]];
2026 u32 index1;
2027 u32 index2;
2028 u32 mask_index;
2029
2030 if (!altera_check_stack(stack_ptr, 4, &status))
2031 break;
2032
2033 index1 = stack[--stack_ptr];
2034 index2 = stack[--stack_ptr];
2035 mask_index = stack[--stack_ptr];
2036 long_count = stack[--stack_ptr];
2037
2038 if (version > 0) {
2039 /*
2040 * stack 0 = source 1 right index
2041 * stack 1 = source 1 left index
2042 * stack 2 = source 2 right index
2043 * stack 3 = source 2 left index
2044 * stack 4 = mask right index
2045 * stack 5 = mask left index
2046 */
2047 s32 mask_right = stack[--stack_ptr];
2048 s32 mask_left = stack[--stack_ptr];
2049 /* source 1 count */
2050 a = 1 + index2 - index1;
2051 /* source 2 count */
2052 b = 1 + long_count - mask_index;
2053 a = (a < b) ? a : b;
2054 /* mask count */
2055 b = 1 + mask_left - mask_right;
2056 a = (a < b) ? a : b;
2057 /* source 2 start index */
2058 index2 = mask_index;
2059 /* mask start index */
2060 mask_index = mask_right;
2061 long_count = a;
2062 }
2063
2064 long_tmp = 1L;
2065
2066 if (long_count < 1)
2067 status = -ERANGE;
2068 else {
2069 count = long_count;
2070
2071 for (i = 0; i < count; ++i) {
2072 if (mask[mask_index >> 3] &
2073 (1 << (mask_index & 7))) {
2074 a = source1[index1 >> 3] &
2075 (1 << (index1 & 7))
2076 ? 1 : 0;
2077 b = source2[index2 >> 3] &
2078 (1 << (index2 & 7))
2079 ? 1 : 0;
2080
2081 if (a != b) /* failure */
2082 long_tmp = 0L;
2083 }
2084 ++index1;
2085 ++index2;
2086 ++mask_index;
2087 }
2088 }
2089
2090 stack[stack_ptr++] = long_tmp;
2091
2092 break;
2093 }
2094 default:
2095 /* Unrecognized opcode -- ERROR! */
2096 bad_opcode = 1;
2097 break;
2098 }
2099
2100 if (bad_opcode)
2101 status = -ENOSYS;
2102
2103 if ((stack_ptr < 0) || (stack_ptr >= ALTERA_STACK_SIZE))
2104 status = -EOVERFLOW;
2105
2106 if (status != 0) {
2107 done = 1;
2108 *error_address = (s32)(opcode_address - code_sect);
2109 }
2110 }
2111
2112 altera_free_buffers(astate);
2113
2114 /* Free all dynamically allocated arrays */
2115 if ((attrs != NULL) && (vars != NULL))
2116 for (i = 0; i < sym_count; ++i)
2117 if (attrs[i] & 0x80)
2118 kfree((void *)vars[i]);
2119
2120 kfree(vars);
2121 kfree(var_size);
2122 kfree(attrs);
2123 kfree(proc_attributes);
2124
2125 return status;
2126}
2127
2128static int altera_get_note(u8 *p, s32 program_size,
2129 s32 *offset, char *key, char *value, int length)
2130/*
2131 * Gets key and value of NOTE fields in the JBC file.
2132 * Can be called in two modes: if offset pointer is NULL,
2133 * then the function searches for note fields which match
2134 * the key string provided. If offset is not NULL, then
2135 * the function finds the next note field of any key,
2136 * starting at the offset specified by the offset pointer.
2137 * Returns 0 for success, else appropriate error code
2138 */
2139{
2140 int status = -ENODATA;
2141 u32 note_strings = 0L;
2142 u32 note_table = 0L;
2143 u32 note_count = 0L;
2144 u32 first_word = 0L;
2145 int version = 0;
2146 int delta = 0;
2147 char *key_ptr;
2148 char *value_ptr;
2149 int i;
2150
2151 /* Read header information */
2152 if (program_size > 52L) {
2153 first_word = get_unaligned_be32(&p[0]);
2154 version = (first_word & 1L);
2155 delta = version * 8;
2156
2157 note_strings = get_unaligned_be32(&p[8 + delta]);
2158 note_table = get_unaligned_be32(&p[12 + delta]);
2159 note_count = get_unaligned_be32(&p[44 + (2 * delta)]);
2160 }
2161
2162 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2163 return -EIO;
2164
2165 if (note_count <= 0L)
2166 return status;
2167
2168 if (offset == NULL) {
2169 /*
2170 * We will search for the first note with a specific key,
2171 * and return only the value
2172 */
2173 for (i = 0; (i < note_count) &&
2174 (status != 0); ++i) {
2175 key_ptr = &p[note_strings +
2176 get_unaligned_be32(
2177 &p[note_table + (8 * i)])];
2178 if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) &&
2179 (key != NULL)) {
2180 status = 0;
2181
2182 value_ptr = &p[note_strings +
2183 get_unaligned_be32(
2184 &p[note_table + (8 * i) + 4])];
2185
2186 if (value != NULL)
2187 strlcpy(value, value_ptr, length);
2188
2189 }
2190 }
2191 } else {
2192 /*
2193 * We will search for the next note, regardless of the key,
2194 * and return both the value and the key
2195 */
2196
2197 i = *offset;
2198
2199 if ((i >= 0) && (i < note_count)) {
2200 status = 0;
2201
2202 if (key != NULL)
2203 strlcpy(key, &p[note_strings +
2204 get_unaligned_be32(
2205 &p[note_table + (8 * i)])],
2206 length);
2207
2208 if (value != NULL)
2209 strlcpy(value, &p[note_strings +
2210 get_unaligned_be32(
2211 &p[note_table + (8 * i) + 4])],
2212 length);
2213
2214 *offset = i + 1;
2215 }
2216 }
2217
2218 return status;
2219}
2220
2221static int altera_check_crc(u8 *p, s32 program_size)
2222{
2223 int status = 0;
2224 u16 local_expected = 0,
2225 local_actual = 0,
2226 shift_reg = 0xffff;
2227 int bit, feedback;
2228 u8 databyte;
2229 u32 i;
2230 u32 crc_section = 0L;
2231 u32 first_word = 0L;
2232 int version = 0;
2233 int delta = 0;
2234
2235 if (program_size > 52L) {
2236 first_word = get_unaligned_be32(&p[0]);
2237 version = (first_word & 1L);
2238 delta = version * 8;
2239
2240 crc_section = get_unaligned_be32(&p[32 + delta]);
2241 }
2242
2243 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2244 status = -EIO;
2245
2246 if (crc_section >= program_size)
2247 status = -EIO;
2248
2249 if (status == 0) {
2250 local_expected = (u16)get_unaligned_be16(&p[crc_section]);
2251
2252 for (i = 0; i < crc_section; ++i) {
2253 databyte = p[i];
2254 for (bit = 0; bit < 8; bit++) {
2255 feedback = (databyte ^ shift_reg) & 0x01;
2256 shift_reg >>= 1;
2257 if (feedback)
2258 shift_reg ^= 0x8408;
2259
2260 databyte >>= 1;
2261 }
2262 }
2263
2264 local_actual = (u16)~shift_reg;
2265
2266 if (local_expected != local_actual)
2267 status = -EILSEQ;
2268
2269 }
2270
2271 if (debug || status) {
2272 switch (status) {
2273 case 0:
2274 printk(KERN_INFO "%s: CRC matched: %04x\n", __func__,
2275 local_actual);
2276 break;
2277 case -EILSEQ:
2278 printk(KERN_ERR "%s: CRC mismatch: expected %04x, "
2279 "actual %04x\n", __func__, local_expected,
2280 local_actual);
2281 break;
2282 case -ENODATA:
2283 printk(KERN_ERR "%s: expected CRC not found, "
2284 "actual CRC = %04x\n", __func__,
2285 local_actual);
2286 break;
2287 case -EIO:
2288 printk(KERN_ERR "%s: error: format isn't "
2289 "recognized.\n", __func__);
2290 break;
2291 default:
2292 printk(KERN_ERR "%s: CRC function returned error "
2293 "code %d\n", __func__, status);
2294 break;
2295 }
2296 }
2297
2298 return status;
2299}
2300
2301static int altera_get_file_info(u8 *p,
2302 s32 program_size,
2303 int *format_version,
2304 int *action_count,
2305 int *procedure_count)
2306{
2307 int status = -EIO;
2308 u32 first_word = 0;
2309 int version = 0;
2310
2311 if (program_size <= 52L)
2312 return status;
2313
2314 first_word = get_unaligned_be32(&p[0]);
2315
2316 if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) {
2317 status = 0;
2318
2319 version = (first_word & 1L);
2320 *format_version = version + 1;
2321
2322 if (version > 0) {
2323 *action_count = get_unaligned_be32(&p[48]);
2324 *procedure_count = get_unaligned_be32(&p[52]);
2325 }
2326 }
2327
2328 return status;
2329}
2330
2331static int altera_get_act_info(u8 *p,
2332 s32 program_size,
2333 int index,
2334 char **name,
2335 char **description,
2336 struct altera_procinfo **proc_list)
2337{
2338 int status = -EIO;
2339 struct altera_procinfo *procptr = NULL;
2340 struct altera_procinfo *tmpptr = NULL;
2341 u32 first_word = 0L;
2342 u32 action_table = 0L;
2343 u32 proc_table = 0L;
2344 u32 str_table = 0L;
2345 u32 note_strings = 0L;
2346 u32 action_count = 0L;
2347 u32 proc_count = 0L;
2348 u32 act_name_id = 0L;
2349 u32 act_desc_id = 0L;
2350 u32 act_proc_id = 0L;
2351 u32 act_proc_name = 0L;
2352 u8 act_proc_attribute = 0;
2353
2354 if (program_size <= 52L)
2355 return status;
2356 /* Read header information */
2357 first_word = get_unaligned_be32(&p[0]);
2358
2359 if (first_word != 0x4A414D01L)
2360 return status;
2361
2362 action_table = get_unaligned_be32(&p[4]);
2363 proc_table = get_unaligned_be32(&p[8]);
2364 str_table = get_unaligned_be32(&p[12]);
2365 note_strings = get_unaligned_be32(&p[16]);
2366 action_count = get_unaligned_be32(&p[48]);
2367 proc_count = get_unaligned_be32(&p[52]);
2368
2369 if (index >= action_count)
2370 return status;
2371
2372 act_name_id = get_unaligned_be32(&p[action_table + (12 * index)]);
2373 act_desc_id = get_unaligned_be32(&p[action_table + (12 * index) + 4]);
2374 act_proc_id = get_unaligned_be32(&p[action_table + (12 * index) + 8]);
2375
2376 *name = &p[str_table + act_name_id];
2377
2378 if (act_desc_id < (note_strings - str_table))
2379 *description = &p[str_table + act_desc_id];
2380
2381 do {
2382 act_proc_name = get_unaligned_be32(
2383 &p[proc_table + (13 * act_proc_id)]);
2384 act_proc_attribute =
2385 (p[proc_table + (13 * act_proc_id) + 8] & 0x03);
2386
2387 procptr = (struct altera_procinfo *)
2388 kzalloc(sizeof(struct altera_procinfo),
2389 GFP_KERNEL);
2390
2391 if (procptr == NULL)
2392 status = -ENOMEM;
2393 else {
2394 procptr->name = &p[str_table + act_proc_name];
2395 procptr->attrs = act_proc_attribute;
2396 procptr->next = NULL;
2397
2398 /* add record to end of linked list */
2399 if (*proc_list == NULL)
2400 *proc_list = procptr;
2401 else {
2402 tmpptr = *proc_list;
2403 while (tmpptr->next != NULL)
2404 tmpptr = tmpptr->next;
2405 tmpptr->next = procptr;
2406 }
2407 }
2408
2409 act_proc_id = get_unaligned_be32(
2410 &p[proc_table + (13 * act_proc_id) + 4]);
2411 } while ((act_proc_id != 0) && (act_proc_id < proc_count));
2412
2413 return status;
2414}
2415
2416int altera_init(struct altera_config *config, const struct firmware *fw)
2417{
2418 struct altera_state *astate = NULL;
2419 struct altera_procinfo *proc_list = NULL;
2420 struct altera_procinfo *procptr = NULL;
2421 char *key = NULL;
2422 char *value = NULL;
2423 char *action_name = NULL;
2424 char *description = NULL;
2425 int exec_result = 0;
2426 int exit_code = 0;
2427 int format_version = 0;
2428 int action_count = 0;
2429 int procedure_count = 0;
2430 int index = 0;
2431 s32 offset = 0L;
2432 s32 error_address = 0L;
2433
2434 key = kzalloc(33 * sizeof(char), GFP_KERNEL);
2435 if (!key)
2436 return -ENOMEM;
2437 value = kzalloc(257 * sizeof(char), GFP_KERNEL);
2438 if (!value)
2439 return -ENOMEM;
2440 astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL);
2441 if (!astate)
2442 return -ENOMEM;
2443
2444 astate->config = config;
2445 if (!astate->config->jtag_io) {
2446 dprintk(KERN_INFO "%s: using byteblaster!\n", __func__);
2447 astate->config->jtag_io = netup_jtag_io_lpt;
2448 }
2449
2450 altera_check_crc((u8 *)fw->data, fw->size);
2451
2452 if (debug) {
2453 altera_get_file_info((u8 *)fw->data, fw->size, &format_version,
2454 &action_count, &procedure_count);
2455 printk(KERN_INFO "%s: File format is %s ByteCode format\n",
2456 __func__, (format_version == 2) ? "Jam STAPL" :
2457 "pre-standardized Jam 1.1");
2458 while (altera_get_note((u8 *)fw->data, fw->size,
2459 &offset, key, value, 256) == 0)
2460 printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
2461 __func__, key, value);
2462 }
2463
2464 if (debug && (format_version == 2) && (action_count > 0)) {
2465 printk(KERN_INFO "%s: Actions available:\n", __func__);
2466 for (index = 0; index < action_count; ++index) {
2467 altera_get_act_info((u8 *)fw->data, fw->size,
2468 index, &action_name,
2469 &description,
2470 &proc_list);
2471
2472 if (description == NULL)
2473 printk(KERN_INFO "%s: %s\n",
2474 __func__,
2475 action_name);
2476 else
2477 printk(KERN_INFO "%s: %s \"%s\"\n",
2478 __func__,
2479 action_name,
2480 description);
2481
2482 procptr = proc_list;
2483 while (procptr != NULL) {
2484 if (procptr->attrs != 0)
2485 printk(KERN_INFO "%s: %s (%s)\n",
2486 __func__,
2487 procptr->name,
2488 (procptr->attrs == 1) ?
2489 "optional" : "recommended");
2490
2491 proc_list = procptr->next;
2492 kfree(procptr);
2493 procptr = proc_list;
2494 }
2495 }
2496
2497 printk(KERN_INFO "\n");
2498 }
2499
2500 exec_result = altera_execute(astate, (u8 *)fw->data, fw->size,
2501 &error_address, &exit_code, &format_version);
2502
2503 if (exit_code)
2504 exec_result = -EREMOTEIO;
2505
2506 if ((format_version == 2) && (exec_result == -EINVAL)) {
2507 if (astate->config->action == NULL)
2508 printk(KERN_ERR "%s: error: no action specified for "
2509 "Jam STAPL file.\nprogram terminated.\n",
2510 __func__);
2511 else
2512 printk(KERN_ERR "%s: error: action \"%s\""
2513 " is not supported "
2514 "for this Jam STAPL file.\n"
2515 "Program terminated.\n", __func__,
2516 astate->config->action);
2517
2518 } else if (exec_result)
2519 printk(KERN_ERR "%s: error %d\n", __func__, exec_result);
2520
2521 kfree(key);
2522 kfree(value);
2523 kfree(astate);
2524
2525 return 0;
2526}
2527EXPORT_SYMBOL(altera_init);