2498 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * altera.c4 *5 * altera FPGA driver6 *7 * Copyright (C) Altera Corporation 1998-20018 * Copyright (C) 2010,2011 NetUP Inc.9 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>10 */11 12#include <linux/unaligned.h>13#include <linux/ctype.h>14#include <linux/string.h>15#include <linux/firmware.h>16#include <linux/slab.h>17#include <linux/module.h>18#include <misc/altera.h>19#include "altera-exprt.h"20#include "altera-jtag.h"21 22static int debug = 1;23module_param(debug, int, 0644);24MODULE_PARM_DESC(debug, "enable debugging information");25 26MODULE_DESCRIPTION("altera FPGA kernel module");27MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");28MODULE_LICENSE("GPL");29 30#define dprintk(args...) \31 if (debug) { \32 printk(KERN_DEBUG args); \33 }34 35enum altera_fpga_opcode {36 OP_NOP = 0,37 OP_DUP,38 OP_SWP,39 OP_ADD,40 OP_SUB,41 OP_MULT,42 OP_DIV,43 OP_MOD,44 OP_SHL,45 OP_SHR,46 OP_NOT,47 OP_AND,48 OP_OR,49 OP_XOR,50 OP_INV,51 OP_GT,52 OP_LT,53 OP_RET,54 OP_CMPS,55 OP_PINT,56 OP_PRNT,57 OP_DSS,58 OP_DSSC,59 OP_ISS,60 OP_ISSC,61 OP_DPR = 0x1c,62 OP_DPRL,63 OP_DPO,64 OP_DPOL,65 OP_IPR,66 OP_IPRL,67 OP_IPO,68 OP_IPOL,69 OP_PCHR,70 OP_EXIT,71 OP_EQU,72 OP_POPT,73 OP_ABS = 0x2c,74 OP_BCH0,75 OP_PSH0 = 0x2f,76 OP_PSHL = 0x40,77 OP_PSHV,78 OP_JMP,79 OP_CALL,80 OP_NEXT,81 OP_PSTR,82 OP_SINT = 0x47,83 OP_ST,84 OP_ISTP,85 OP_DSTP,86 OP_SWPN,87 OP_DUPN,88 OP_POPV,89 OP_POPE,90 OP_POPA,91 OP_JMPZ,92 OP_DS,93 OP_IS,94 OP_DPRA,95 OP_DPOA,96 OP_IPRA,97 OP_IPOA,98 OP_EXPT,99 OP_PSHE,100 OP_PSHA,101 OP_DYNA,102 OP_EXPV = 0x5c,103 OP_COPY = 0x80,104 OP_REVA,105 OP_DSC,106 OP_ISC,107 OP_WAIT,108 OP_VS,109 OP_CMPA = 0xc0,110 OP_VSC,111};112 113struct altera_procinfo {114 char *name;115 u8 attrs;116 struct altera_procinfo *next;117};118 119/* This function checks if enough parameters are available on the stack. */120static int altera_check_stack(int stack_ptr, int count, int *status)121{122 if (stack_ptr < count) {123 *status = -EOVERFLOW;124 return 0;125 }126 127 return 1;128}129 130static void altera_export_int(char *key, s32 value)131{132 dprintk("Export: key = \"%s\", value = %d\n", key, value);133}134 135#define HEX_LINE_CHARS 72136#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)137 138static void altera_export_bool_array(char *key, u8 *data, s32 count)139{140 char string[HEX_LINE_CHARS + 1];141 s32 i, offset;142 u32 size, line, lines, linebits, value, j, k;143 144 if (count > HEX_LINE_BITS) {145 dprintk("Export: key = \"%s\", %d bits, value = HEX\n",146 key, count);147 lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;148 149 for (line = 0; line < lines; ++line) {150 if (line < (lines - 1)) {151 linebits = HEX_LINE_BITS;152 size = HEX_LINE_CHARS;153 offset = count - ((line + 1) * HEX_LINE_BITS);154 } else {155 linebits =156 count - ((lines - 1) * HEX_LINE_BITS);157 size = (linebits + 3) / 4;158 offset = 0L;159 }160 161 string[size] = '\0';162 j = size - 1;163 value = 0;164 165 for (k = 0; k < linebits; ++k) {166 i = k + offset;167 if (data[i >> 3] & (1 << (i & 7)))168 value |= (1 << (i & 3));169 if ((i & 3) == 3) {170 sprintf(&string[j], "%1x", value);171 value = 0;172 --j;173 }174 }175 if ((k & 3) > 0)176 sprintf(&string[j], "%1x", value);177 178 dprintk("%s\n", string);179 }180 181 } else {182 size = (count + 3) / 4;183 string[size] = '\0';184 j = size - 1;185 value = 0;186 187 for (i = 0; i < count; ++i) {188 if (data[i >> 3] & (1 << (i & 7)))189 value |= (1 << (i & 3));190 if ((i & 3) == 3) {191 sprintf(&string[j], "%1x", value);192 value = 0;193 --j;194 }195 }196 if ((i & 3) > 0)197 sprintf(&string[j], "%1x", value);198 199 dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n",200 key, count, string);201 }202}203 204static int altera_execute(struct altera_state *astate,205 u8 *p,206 s32 program_size,207 s32 *error_address,208 int *exit_code,209 int *format_version)210{211 struct altera_config *aconf = astate->config;212 char *msg_buff = astate->msg_buff;213 long *stack = astate->stack;214 int status = 0;215 u32 first_word = 0L;216 u32 action_table = 0L;217 u32 proc_table = 0L;218 u32 str_table = 0L;219 u32 sym_table = 0L;220 u32 data_sect = 0L;221 u32 code_sect = 0L;222 u32 debug_sect = 0L;223 u32 action_count = 0L;224 u32 proc_count = 0L;225 u32 sym_count = 0L;226 long *vars = NULL;227 s32 *var_size = NULL;228 char *attrs = NULL;229 u8 *proc_attributes = NULL;230 u32 pc;231 u32 opcode_address;232 u32 args[3];233 u32 opcode;234 u32 name_id;235 u8 charbuf[4];236 long long_tmp;237 u32 variable_id;238 u8 *charptr_tmp;239 u8 *charptr_tmp2;240 long *longptr_tmp;241 int version = 0;242 int delta = 0;243 int stack_ptr = 0;244 u32 arg_count;245 int done = 0;246 int bad_opcode = 0;247 u32 count;248 u32 index;249 u32 index2;250 s32 long_count;251 s32 long_idx;252 s32 long_idx2;253 u32 i;254 u32 j;255 u32 uncomp_size;256 u32 offset;257 u32 value;258 int current_proc = 0;259 int reverse;260 261 char *name;262 263 dprintk("%s\n", __func__);264 265 /* Read header information */266 if (program_size > 52L) {267 first_word = get_unaligned_be32(&p[0]);268 version = (first_word & 1L);269 *format_version = version + 1;270 delta = version * 8;271 272 action_table = get_unaligned_be32(&p[4]);273 proc_table = get_unaligned_be32(&p[8]);274 str_table = get_unaligned_be32(&p[4 + delta]);275 sym_table = get_unaligned_be32(&p[16 + delta]);276 data_sect = get_unaligned_be32(&p[20 + delta]);277 code_sect = get_unaligned_be32(&p[24 + delta]);278 debug_sect = get_unaligned_be32(&p[28 + delta]);279 action_count = get_unaligned_be32(&p[40 + delta]);280 proc_count = get_unaligned_be32(&p[44 + delta]);281 sym_count = get_unaligned_be32(&p[48 + (2 * delta)]);282 }283 284 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {285 done = 1;286 status = -EIO;287 goto exit_done;288 }289 290 if (sym_count <= 0)291 goto exit_done;292 293 vars = kcalloc(sym_count, sizeof(long), GFP_KERNEL);294 295 if (vars == NULL)296 status = -ENOMEM;297 298 if (status == 0) {299 var_size = kcalloc(sym_count, sizeof(s32), GFP_KERNEL);300 301 if (var_size == NULL)302 status = -ENOMEM;303 }304 305 if (status == 0) {306 attrs = kzalloc(sym_count, GFP_KERNEL);307 308 if (attrs == NULL)309 status = -ENOMEM;310 }311 312 if ((status == 0) && (version > 0)) {313 proc_attributes = kzalloc(proc_count, GFP_KERNEL);314 315 if (proc_attributes == NULL)316 status = -ENOMEM;317 }318 319 if (status != 0)320 goto exit_done;321 322 delta = version * 2;323 324 for (i = 0; i < sym_count; ++i) {325 offset = (sym_table + ((11 + delta) * i));326 327 value = get_unaligned_be32(&p[offset + 3 + delta]);328 329 attrs[i] = p[offset];330 331 /*332 * use bit 7 of attribute byte to indicate that333 * this buffer was dynamically allocated334 * and should be freed later335 */336 attrs[i] &= 0x7f;337 338 var_size[i] = get_unaligned_be32(&p[offset + 7 + delta]);339 340 /*341 * Attribute bits:342 * bit 0: 0 = read-only, 1 = read-write343 * bit 1: 0 = not compressed, 1 = compressed344 * bit 2: 0 = not initialized, 1 = initialized345 * bit 3: 0 = scalar, 1 = array346 * bit 4: 0 = Boolean, 1 = integer347 * bit 5: 0 = declared variable,348 * 1 = compiler created temporary variable349 */350 351 if ((attrs[i] & 0x0c) == 0x04)352 /* initialized scalar variable */353 vars[i] = value;354 else if ((attrs[i] & 0x1e) == 0x0e) {355 /* initialized compressed Boolean array */356 uncomp_size = get_unaligned_le32(&p[data_sect + value]);357 358 /* allocate a buffer for the uncompressed data */359 vars[i] = (long)kzalloc(uncomp_size, GFP_KERNEL);360 if (vars[i] == 0L)361 status = -ENOMEM;362 else {363 /* set flag so buffer will be freed later */364 attrs[i] |= 0x80;365 366 /* uncompress the data */367 if (altera_shrink(&p[data_sect + value],368 var_size[i],369 (u8 *)vars[i],370 uncomp_size,371 version) != uncomp_size)372 /* decompression failed */373 status = -EIO;374 else375 var_size[i] = uncomp_size * 8L;376 377 }378 } else if ((attrs[i] & 0x1e) == 0x0c) {379 /* initialized Boolean array */380 vars[i] = value + data_sect + (long)p;381 } else if ((attrs[i] & 0x1c) == 0x1c) {382 /* initialized integer array */383 vars[i] = value + data_sect;384 } else if ((attrs[i] & 0x0c) == 0x08) {385 /* uninitialized array */386 387 /* flag attrs so that memory is freed */388 attrs[i] |= 0x80;389 390 if (var_size[i] > 0) {391 u32 size;392 393 if (attrs[i] & 0x10)394 /* integer array */395 size = (var_size[i] * sizeof(s32));396 else397 /* Boolean array */398 size = ((var_size[i] + 7L) / 8L);399 400 vars[i] = (long)kzalloc(size, GFP_KERNEL);401 402 if (vars[i] == 0) {403 status = -ENOMEM;404 } else {405 /* zero out memory */406 for (j = 0; j < size; ++j)407 ((u8 *)(vars[i]))[j] = 0;408 409 }410 } else411 vars[i] = 0;412 413 } else414 vars[i] = 0;415 416 }417 418exit_done:419 if (status != 0)420 done = 1;421 422 altera_jinit(astate);423 424 pc = code_sect;425 msg_buff[0] = '\0';426 427 /*428 * For JBC version 2, we will execute the procedures corresponding to429 * the selected ACTION430 */431 if (version > 0) {432 if (aconf->action == NULL) {433 status = -EINVAL;434 done = 1;435 } else {436 int action_found = 0;437 for (i = 0; (i < action_count) && !action_found; ++i) {438 name_id = get_unaligned_be32(&p[action_table +439 (12 * i)]);440 441 name = &p[str_table + name_id];442 443 if (strncasecmp(aconf->action, name, strlen(name)) == 0) {444 action_found = 1;445 current_proc =446 get_unaligned_be32(&p[action_table +447 (12 * i) + 8]);448 }449 }450 451 if (!action_found) {452 status = -EINVAL;453 done = 1;454 }455 }456 457 if (status == 0) {458 int first_time = 1;459 i = current_proc;460 while ((i != 0) || first_time) {461 first_time = 0;462 /* check procedure attribute byte */463 proc_attributes[i] =464 (p[proc_table +465 (13 * i) + 8] &466 0x03);467 468 /*469 * BIT0 - OPTIONAL470 * BIT1 - RECOMMENDED471 * BIT6 - FORCED OFF472 * BIT7 - FORCED ON473 */474 475 i = get_unaligned_be32(&p[proc_table +476 (13 * i) + 4]);477 }478 479 /*480 * Set current_proc to the first procedure481 * to be executed482 */483 i = current_proc;484 while ((i != 0) &&485 ((proc_attributes[i] == 1) ||486 ((proc_attributes[i] & 0xc0) == 0x40))) {487 i = get_unaligned_be32(&p[proc_table +488 (13 * i) + 4]);489 }490 491 if ((i != 0) || ((i == 0) && (current_proc == 0) &&492 ((proc_attributes[0] != 1) &&493 ((proc_attributes[0] & 0xc0) != 0x40)))) {494 current_proc = i;495 pc = code_sect +496 get_unaligned_be32(&p[proc_table +497 (13 * i) + 9]);498 if ((pc < code_sect) || (pc >= debug_sect))499 status = -ERANGE;500 } else501 /* there are no procedures to execute! */502 done = 1;503 504 }505 }506 507 msg_buff[0] = '\0';508 509 while (!done) {510 opcode = (p[pc] & 0xff);511 opcode_address = pc;512 ++pc;513 514 if (debug > 1)515 printk("opcode: %02x\n", opcode);516 517 arg_count = (opcode >> 6) & 3;518 for (i = 0; i < arg_count; ++i) {519 args[i] = get_unaligned_be32(&p[pc]);520 pc += 4;521 }522 523 switch (opcode) {524 case OP_NOP:525 break;526 case OP_DUP:527 if (altera_check_stack(stack_ptr, 1, &status)) {528 stack[stack_ptr] = stack[stack_ptr - 1];529 ++stack_ptr;530 }531 break;532 case OP_SWP:533 if (altera_check_stack(stack_ptr, 2, &status))534 swap(stack[stack_ptr - 2], stack[stack_ptr - 1]);535 break;536 case OP_ADD:537 if (altera_check_stack(stack_ptr, 2, &status)) {538 --stack_ptr;539 stack[stack_ptr - 1] += stack[stack_ptr];540 }541 break;542 case OP_SUB:543 if (altera_check_stack(stack_ptr, 2, &status)) {544 --stack_ptr;545 stack[stack_ptr - 1] -= stack[stack_ptr];546 }547 break;548 case OP_MULT:549 if (altera_check_stack(stack_ptr, 2, &status)) {550 --stack_ptr;551 stack[stack_ptr - 1] *= stack[stack_ptr];552 }553 break;554 case OP_DIV:555 if (altera_check_stack(stack_ptr, 2, &status)) {556 --stack_ptr;557 stack[stack_ptr - 1] /= stack[stack_ptr];558 }559 break;560 case OP_MOD:561 if (altera_check_stack(stack_ptr, 2, &status)) {562 --stack_ptr;563 stack[stack_ptr - 1] %= stack[stack_ptr];564 }565 break;566 case OP_SHL:567 if (altera_check_stack(stack_ptr, 2, &status)) {568 --stack_ptr;569 stack[stack_ptr - 1] <<= stack[stack_ptr];570 }571 break;572 case OP_SHR:573 if (altera_check_stack(stack_ptr, 2, &status)) {574 --stack_ptr;575 stack[stack_ptr - 1] >>= stack[stack_ptr];576 }577 break;578 case OP_NOT:579 if (altera_check_stack(stack_ptr, 1, &status))580 stack[stack_ptr - 1] ^= (-1L);581 582 break;583 case OP_AND:584 if (altera_check_stack(stack_ptr, 2, &status)) {585 --stack_ptr;586 stack[stack_ptr - 1] &= stack[stack_ptr];587 }588 break;589 case OP_OR:590 if (altera_check_stack(stack_ptr, 2, &status)) {591 --stack_ptr;592 stack[stack_ptr - 1] |= stack[stack_ptr];593 }594 break;595 case OP_XOR:596 if (altera_check_stack(stack_ptr, 2, &status)) {597 --stack_ptr;598 stack[stack_ptr - 1] ^= stack[stack_ptr];599 }600 break;601 case OP_INV:602 if (!altera_check_stack(stack_ptr, 1, &status))603 break;604 stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;605 break;606 case OP_GT:607 if (!altera_check_stack(stack_ptr, 2, &status))608 break;609 --stack_ptr;610 stack[stack_ptr - 1] =611 (stack[stack_ptr - 1] > stack[stack_ptr]) ?612 1L : 0L;613 614 break;615 case OP_LT:616 if (!altera_check_stack(stack_ptr, 2, &status))617 break;618 --stack_ptr;619 stack[stack_ptr - 1] =620 (stack[stack_ptr - 1] < stack[stack_ptr]) ?621 1L : 0L;622 623 break;624 case OP_RET:625 if ((version > 0) && (stack_ptr == 0)) {626 /*627 * We completed one of the main procedures628 * of an ACTION.629 * Find the next procedure630 * to be executed and jump to it.631 * If there are no more procedures, then EXIT.632 */633 i = get_unaligned_be32(&p[proc_table +634 (13 * current_proc) + 4]);635 while ((i != 0) &&636 ((proc_attributes[i] == 1) ||637 ((proc_attributes[i] & 0xc0) == 0x40)))638 i = get_unaligned_be32(&p[proc_table +639 (13 * i) + 4]);640 641 if (i == 0) {642 /* no procedures to execute! */643 done = 1;644 *exit_code = 0; /* success */645 } else {646 current_proc = i;647 pc = code_sect + get_unaligned_be32(648 &p[proc_table +649 (13 * i) + 9]);650 if ((pc < code_sect) ||651 (pc >= debug_sect))652 status = -ERANGE;653 }654 655 } else656 if (altera_check_stack(stack_ptr, 1, &status)) {657 pc = stack[--stack_ptr] + code_sect;658 if ((pc <= code_sect) ||659 (pc >= debug_sect))660 status = -ERANGE;661 662 }663 664 break;665 case OP_CMPS:666 /*667 * Array short compare668 * ...stack 0 is source 1 value669 * ...stack 1 is source 2 value670 * ...stack 2 is mask value671 * ...stack 3 is count672 */673 if (altera_check_stack(stack_ptr, 4, &status)) {674 s32 a = stack[--stack_ptr];675 s32 b = stack[--stack_ptr];676 long_tmp = stack[--stack_ptr];677 count = stack[stack_ptr - 1];678 679 if ((count < 1) || (count > 32))680 status = -ERANGE;681 else {682 long_tmp &= ((-1L) >> (32 - count));683 684 stack[stack_ptr - 1] =685 ((a & long_tmp) == (b & long_tmp))686 ? 1L : 0L;687 }688 }689 break;690 case OP_PINT:691 /*692 * PRINT add integer693 * ...stack 0 is integer value694 */695 if (!altera_check_stack(stack_ptr, 1, &status))696 break;697 sprintf(&msg_buff[strlen(msg_buff)],698 "%ld", stack[--stack_ptr]);699 break;700 case OP_PRNT:701 /* PRINT finish */702 if (debug)703 printk(msg_buff, "\n");704 705 msg_buff[0] = '\0';706 break;707 case OP_DSS:708 /*709 * DRSCAN short710 * ...stack 0 is scan data711 * ...stack 1 is count712 */713 if (!altera_check_stack(stack_ptr, 2, &status))714 break;715 long_tmp = stack[--stack_ptr];716 count = stack[--stack_ptr];717 put_unaligned_le32(long_tmp, &charbuf[0]);718 status = altera_drscan(astate, count, charbuf, 0);719 break;720 case OP_DSSC:721 /*722 * DRSCAN short with capture723 * ...stack 0 is scan data724 * ...stack 1 is count725 */726 if (!altera_check_stack(stack_ptr, 2, &status))727 break;728 long_tmp = stack[--stack_ptr];729 count = stack[stack_ptr - 1];730 put_unaligned_le32(long_tmp, &charbuf[0]);731 status = altera_swap_dr(astate, count, charbuf,732 0, charbuf, 0);733 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);734 break;735 case OP_ISS:736 /*737 * IRSCAN short738 * ...stack 0 is scan data739 * ...stack 1 is count740 */741 if (!altera_check_stack(stack_ptr, 2, &status))742 break;743 long_tmp = stack[--stack_ptr];744 count = stack[--stack_ptr];745 put_unaligned_le32(long_tmp, &charbuf[0]);746 status = altera_irscan(astate, count, charbuf, 0);747 break;748 case OP_ISSC:749 /*750 * IRSCAN short with capture751 * ...stack 0 is scan data752 * ...stack 1 is count753 */754 if (!altera_check_stack(stack_ptr, 2, &status))755 break;756 long_tmp = stack[--stack_ptr];757 count = stack[stack_ptr - 1];758 put_unaligned_le32(long_tmp, &charbuf[0]);759 status = altera_swap_ir(astate, count, charbuf,760 0, charbuf, 0);761 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);762 break;763 case OP_DPR:764 if (!altera_check_stack(stack_ptr, 1, &status))765 break;766 count = stack[--stack_ptr];767 status = altera_set_dr_pre(&astate->js, count, 0, NULL);768 break;769 case OP_DPRL:770 /*771 * DRPRE with literal data772 * ...stack 0 is count773 * ...stack 1 is literal data774 */775 if (!altera_check_stack(stack_ptr, 2, &status))776 break;777 count = stack[--stack_ptr];778 long_tmp = stack[--stack_ptr];779 put_unaligned_le32(long_tmp, &charbuf[0]);780 status = altera_set_dr_pre(&astate->js, count, 0,781 charbuf);782 break;783 case OP_DPO:784 /*785 * DRPOST786 * ...stack 0 is count787 */788 if (altera_check_stack(stack_ptr, 1, &status)) {789 count = stack[--stack_ptr];790 status = altera_set_dr_post(&astate->js, count,791 0, NULL);792 }793 break;794 case OP_DPOL:795 /*796 * DRPOST with literal data797 * ...stack 0 is count798 * ...stack 1 is literal data799 */800 if (!altera_check_stack(stack_ptr, 2, &status))801 break;802 count = stack[--stack_ptr];803 long_tmp = stack[--stack_ptr];804 put_unaligned_le32(long_tmp, &charbuf[0]);805 status = altera_set_dr_post(&astate->js, count, 0,806 charbuf);807 break;808 case OP_IPR:809 if (altera_check_stack(stack_ptr, 1, &status)) {810 count = stack[--stack_ptr];811 status = altera_set_ir_pre(&astate->js, count,812 0, NULL);813 }814 break;815 case OP_IPRL:816 /*817 * IRPRE with literal data818 * ...stack 0 is count819 * ...stack 1 is literal data820 */821 if (altera_check_stack(stack_ptr, 2, &status)) {822 count = stack[--stack_ptr];823 long_tmp = stack[--stack_ptr];824 put_unaligned_le32(long_tmp, &charbuf[0]);825 status = altera_set_ir_pre(&astate->js, count,826 0, charbuf);827 }828 break;829 case OP_IPO:830 /*831 * IRPOST832 * ...stack 0 is count833 */834 if (altera_check_stack(stack_ptr, 1, &status)) {835 count = stack[--stack_ptr];836 status = altera_set_ir_post(&astate->js, count,837 0, NULL);838 }839 break;840 case OP_IPOL:841 /*842 * IRPOST with literal data843 * ...stack 0 is count844 * ...stack 1 is literal data845 */846 if (!altera_check_stack(stack_ptr, 2, &status))847 break;848 count = stack[--stack_ptr];849 long_tmp = stack[--stack_ptr];850 put_unaligned_le32(long_tmp, &charbuf[0]);851 status = altera_set_ir_post(&astate->js, count, 0,852 charbuf);853 break;854 case OP_PCHR:855 if (altera_check_stack(stack_ptr, 1, &status)) {856 u8 ch;857 count = strlen(msg_buff);858 ch = (char) stack[--stack_ptr];859 if ((ch < 1) || (ch > 127)) {860 /*861 * character code out of range862 * instead of flagging an error,863 * force the value to 127864 */865 ch = 127;866 }867 msg_buff[count] = ch;868 msg_buff[count + 1] = '\0';869 }870 break;871 case OP_EXIT:872 if (altera_check_stack(stack_ptr, 1, &status))873 *exit_code = stack[--stack_ptr];874 875 done = 1;876 break;877 case OP_EQU:878 if (!altera_check_stack(stack_ptr, 2, &status))879 break;880 --stack_ptr;881 stack[stack_ptr - 1] =882 (stack[stack_ptr - 1] == stack[stack_ptr]) ?883 1L : 0L;884 break;885 case OP_POPT:886 if (altera_check_stack(stack_ptr, 1, &status))887 --stack_ptr;888 889 break;890 case OP_ABS:891 if (!altera_check_stack(stack_ptr, 1, &status))892 break;893 if (stack[stack_ptr - 1] < 0)894 stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];895 896 break;897 case OP_BCH0:898 /*899 * Batch operation 0900 * SWP901 * SWPN 7902 * SWP903 * SWPN 6904 * DUPN 8905 * SWPN 2906 * SWP907 * DUPN 6908 * DUPN 6909 */910 911 /* SWP */912 if (altera_check_stack(stack_ptr, 2, &status))913 swap(stack[stack_ptr - 2], stack[stack_ptr - 1]);914 915 /* SWPN 7 */916 index = 7 + 1;917 if (altera_check_stack(stack_ptr, index, &status))918 swap(stack[stack_ptr - index], stack[stack_ptr - 1]);919 920 /* SWP */921 if (altera_check_stack(stack_ptr, 2, &status))922 swap(stack[stack_ptr - 2], stack[stack_ptr - 1]);923 924 /* SWPN 6 */925 index = 6 + 1;926 if (altera_check_stack(stack_ptr, index, &status))927 swap(stack[stack_ptr - index], stack[stack_ptr - 1]);928 929 /* DUPN 8 */930 index = 8 + 1;931 if (altera_check_stack(stack_ptr, index, &status)) {932 stack[stack_ptr] = stack[stack_ptr - index];933 ++stack_ptr;934 }935 936 /* SWPN 2 */937 index = 2 + 1;938 if (altera_check_stack(stack_ptr, index, &status))939 swap(stack[stack_ptr - index], stack[stack_ptr - 1]);940 941 /* SWP */942 if (altera_check_stack(stack_ptr, 2, &status))943 swap(stack[stack_ptr - 2], stack[stack_ptr - 1]);944 945 /* DUPN 6 */946 index = 6 + 1;947 if (altera_check_stack(stack_ptr, index, &status)) {948 stack[stack_ptr] = stack[stack_ptr - index];949 ++stack_ptr;950 }951 952 /* DUPN 6 */953 index = 6 + 1;954 if (altera_check_stack(stack_ptr, index, &status)) {955 stack[stack_ptr] = stack[stack_ptr - index];956 ++stack_ptr;957 }958 break;959 case OP_PSH0:960 stack[stack_ptr++] = 0;961 break;962 case OP_PSHL:963 stack[stack_ptr++] = (s32) args[0];964 break;965 case OP_PSHV:966 stack[stack_ptr++] = vars[args[0]];967 break;968 case OP_JMP:969 pc = args[0] + code_sect;970 if ((pc < code_sect) || (pc >= debug_sect))971 status = -ERANGE;972 break;973 case OP_CALL:974 stack[stack_ptr++] = pc;975 pc = args[0] + code_sect;976 if ((pc < code_sect) || (pc >= debug_sect))977 status = -ERANGE;978 break;979 case OP_NEXT:980 /*981 * Process FOR / NEXT loop982 * ...argument 0 is variable ID983 * ...stack 0 is step value984 * ...stack 1 is end value985 * ...stack 2 is top address986 */987 if (altera_check_stack(stack_ptr, 3, &status)) {988 s32 step = stack[stack_ptr - 1];989 s32 end = stack[stack_ptr - 2];990 s32 top = stack[stack_ptr - 3];991 s32 iterator = vars[args[0]];992 int break_out = 0;993 994 if (step < 0) {995 if (iterator <= end)996 break_out = 1;997 } else if (iterator >= end)998 break_out = 1;999 1000 if (break_out) {1001 stack_ptr -= 3;1002 } else {1003 vars[args[0]] = iterator + step;1004 pc = top + code_sect;1005 if ((pc < code_sect) ||1006 (pc >= debug_sect))1007 status = -ERANGE;1008 }1009 }1010 break;1011 case OP_PSTR:1012 /*1013 * PRINT add string1014 * ...argument 0 is string ID1015 */1016 count = strlen(msg_buff);1017 strscpy(&msg_buff[count],1018 &p[str_table + args[0]],1019 ALTERA_MESSAGE_LENGTH - count);1020 break;1021 case OP_SINT:1022 /*1023 * STATE intermediate state1024 * ...argument 0 is state code1025 */1026 status = altera_goto_jstate(astate, args[0]);1027 break;1028 case OP_ST:1029 /*1030 * STATE final state1031 * ...argument 0 is state code1032 */1033 status = altera_goto_jstate(astate, args[0]);1034 break;1035 case OP_ISTP:1036 /*1037 * IRSTOP state1038 * ...argument 0 is state code1039 */1040 status = altera_set_irstop(&astate->js, args[0]);1041 break;1042 case OP_DSTP:1043 /*1044 * DRSTOP state1045 * ...argument 0 is state code1046 */1047 status = altera_set_drstop(&astate->js, args[0]);1048 break;1049 1050 case OP_SWPN:1051 /*1052 * Exchange top with Nth stack value1053 * ...argument 0 is 0-based stack entry1054 * to swap with top element1055 */1056 index = (args[0]) + 1;1057 if (altera_check_stack(stack_ptr, index, &status))1058 swap(stack[stack_ptr - index], stack[stack_ptr - 1]);1059 break;1060 case OP_DUPN:1061 /*1062 * Duplicate Nth stack value1063 * ...argument 0 is 0-based stack entry to duplicate1064 */1065 index = (args[0]) + 1;1066 if (altera_check_stack(stack_ptr, index, &status)) {1067 stack[stack_ptr] = stack[stack_ptr - index];1068 ++stack_ptr;1069 }1070 break;1071 case OP_POPV:1072 /*1073 * Pop stack into scalar variable1074 * ...argument 0 is variable ID1075 * ...stack 0 is value1076 */1077 if (altera_check_stack(stack_ptr, 1, &status))1078 vars[args[0]] = stack[--stack_ptr];1079 1080 break;1081 case OP_POPE:1082 /*1083 * Pop stack into integer array element1084 * ...argument 0 is variable ID1085 * ...stack 0 is array index1086 * ...stack 1 is value1087 */1088 if (!altera_check_stack(stack_ptr, 2, &status))1089 break;1090 variable_id = args[0];1091 1092 /*1093 * If variable is read-only,1094 * convert to writable array1095 */1096 if ((version > 0) &&1097 ((attrs[variable_id] & 0x9c) == 0x1c)) {1098 /* Allocate a writable buffer for this array */1099 count = var_size[variable_id];1100 long_tmp = vars[variable_id];1101 longptr_tmp = kcalloc(count, sizeof(long),1102 GFP_KERNEL);1103 vars[variable_id] = (long)longptr_tmp;1104 1105 if (vars[variable_id] == 0) {1106 status = -ENOMEM;1107 break;1108 }1109 1110 /* copy previous contents into buffer */1111 for (i = 0; i < count; ++i) {1112 longptr_tmp[i] =1113 get_unaligned_be32(&p[long_tmp]);1114 long_tmp += sizeof(long);1115 }1116 1117 /*1118 * set bit 7 - buffer was1119 * dynamically allocated1120 */1121 attrs[variable_id] |= 0x80;1122 1123 /* clear bit 2 - variable is writable */1124 attrs[variable_id] &= ~0x04;1125 attrs[variable_id] |= 0x01;1126 1127 }1128 1129 /* check that variable is a writable integer array */1130 if ((attrs[variable_id] & 0x1c) != 0x18)1131 status = -ERANGE;1132 else {1133 longptr_tmp = (long *)vars[variable_id];1134 1135 /* pop the array index */1136 index = stack[--stack_ptr];1137 1138 /* pop the value and store it into the array */1139 longptr_tmp[index] = stack[--stack_ptr];1140 }1141 1142 break;1143 case OP_POPA:1144 /*1145 * Pop stack into Boolean array1146 * ...argument 0 is variable ID1147 * ...stack 0 is count1148 * ...stack 1 is array index1149 * ...stack 2 is value1150 */1151 if (!altera_check_stack(stack_ptr, 3, &status))1152 break;1153 variable_id = args[0];1154 1155 /*1156 * If variable is read-only,1157 * convert to writable array1158 */1159 if ((version > 0) &&1160 ((attrs[variable_id] & 0x9c) == 0x0c)) {1161 /* Allocate a writable buffer for this array */1162 long_tmp =1163 (var_size[variable_id] + 7L) >> 3L;1164 charptr_tmp2 = (u8 *)vars[variable_id];1165 charptr_tmp =1166 kzalloc(long_tmp, GFP_KERNEL);1167 vars[variable_id] = (long)charptr_tmp;1168 1169 if (vars[variable_id] == 0) {1170 status = -ENOMEM;1171 break;1172 }1173 1174 /* zero the buffer */1175 for (long_idx = 0L;1176 long_idx < long_tmp;1177 ++long_idx) {1178 charptr_tmp[long_idx] = 0;1179 }1180 1181 /* copy previous contents into buffer */1182 for (long_idx = 0L;1183 long_idx < var_size[variable_id];1184 ++long_idx) {1185 long_idx2 = long_idx;1186 1187 if (charptr_tmp2[long_idx2 >> 3] &1188 (1 << (long_idx2 & 7))) {1189 charptr_tmp[long_idx >> 3] |=1190 (1 << (long_idx & 7));1191 }1192 }1193 1194 /*1195 * set bit 7 - buffer was1196 * dynamically allocated1197 */1198 attrs[variable_id] |= 0x80;1199 1200 /* clear bit 2 - variable is writable */1201 attrs[variable_id] &= ~0x04;1202 attrs[variable_id] |= 0x01;1203 1204 }1205 1206 /*1207 * check that variable is1208 * a writable Boolean array1209 */1210 if ((attrs[variable_id] & 0x1c) != 0x08) {1211 status = -ERANGE;1212 break;1213 }1214 1215 charptr_tmp = (u8 *)vars[variable_id];1216 1217 /* pop the count (number of bits to copy) */1218 long_count = stack[--stack_ptr];1219 1220 /* pop the array index */1221 long_idx = stack[--stack_ptr];1222 1223 reverse = 0;1224 1225 if (version > 0) {1226 /*1227 * stack 0 = array right index1228 * stack 1 = array left index1229 */1230 1231 if (long_idx > long_count) {1232 reverse = 1;1233 long_tmp = long_count;1234 long_count = 1 + long_idx -1235 long_count;1236 long_idx = long_tmp;1237 1238 /* reverse POPA is not supported */1239 status = -ERANGE;1240 break;1241 } else1242 long_count = 1 + long_count -1243 long_idx;1244 1245 }1246 1247 /* pop the data */1248 long_tmp = stack[--stack_ptr];1249 1250 if (long_count < 1) {1251 status = -ERANGE;1252 break;1253 }1254 1255 for (i = 0; i < long_count; ++i) {1256 if (long_tmp & (1L << (s32) i))1257 charptr_tmp[long_idx >> 3L] |=1258 (1L << (long_idx & 7L));1259 else1260 charptr_tmp[long_idx >> 3L] &=1261 ~(1L << (long_idx & 7L));1262 1263 ++long_idx;1264 }1265 1266 break;1267 case OP_JMPZ:1268 /*1269 * Pop stack and branch if zero1270 * ...argument 0 is address1271 * ...stack 0 is condition value1272 */1273 if (altera_check_stack(stack_ptr, 1, &status)) {1274 if (stack[--stack_ptr] == 0) {1275 pc = args[0] + code_sect;1276 if ((pc < code_sect) ||1277 (pc >= debug_sect))1278 status = -ERANGE;1279 }1280 }1281 break;1282 case OP_DS:1283 case OP_IS:1284 /*1285 * DRSCAN1286 * IRSCAN1287 * ...argument 0 is scan data variable ID1288 * ...stack 0 is array index1289 * ...stack 1 is count1290 */1291 if (!altera_check_stack(stack_ptr, 2, &status))1292 break;1293 long_idx = stack[--stack_ptr];1294 long_count = stack[--stack_ptr];1295 reverse = 0;1296 if (version > 0) {1297 /*1298 * stack 0 = array right index1299 * stack 1 = array left index1300 * stack 2 = count1301 */1302 long_tmp = long_count;1303 long_count = stack[--stack_ptr];1304 1305 if (long_idx > long_tmp) {1306 reverse = 1;1307 long_idx = long_tmp;1308 }1309 }1310 1311 charptr_tmp = (u8 *)vars[args[0]];1312 1313 if (reverse) {1314 /*1315 * allocate a buffer1316 * and reverse the data order1317 */1318 charptr_tmp2 = charptr_tmp;1319 charptr_tmp = kzalloc((long_count >> 3) + 1,1320 GFP_KERNEL);1321 if (charptr_tmp == NULL) {1322 status = -ENOMEM;1323 break;1324 }1325 1326 long_tmp = long_idx + long_count - 1;1327 long_idx2 = 0;1328 while (long_idx2 < long_count) {1329 if (charptr_tmp2[long_tmp >> 3] &1330 (1 << (long_tmp & 7)))1331 charptr_tmp[long_idx2 >> 3] |=1332 (1 << (long_idx2 & 7));1333 else1334 charptr_tmp[long_idx2 >> 3] &=1335 ~(1 << (long_idx2 & 7));1336 1337 --long_tmp;1338 ++long_idx2;1339 }1340 }1341 1342 if (opcode == 0x51) /* DS */1343 status = altera_drscan(astate, long_count,1344 charptr_tmp, long_idx);1345 else /* IS */1346 status = altera_irscan(astate, long_count,1347 charptr_tmp, long_idx);1348 1349 if (reverse)1350 kfree(charptr_tmp);1351 1352 break;1353 case OP_DPRA:1354 /*1355 * DRPRE with array data1356 * ...argument 0 is variable ID1357 * ...stack 0 is array index1358 * ...stack 1 is count1359 */1360 if (!altera_check_stack(stack_ptr, 2, &status))1361 break;1362 index = stack[--stack_ptr];1363 count = stack[--stack_ptr];1364 1365 if (version > 0)1366 /*1367 * stack 0 = array right index1368 * stack 1 = array left index1369 */1370 count = 1 + count - index;1371 1372 charptr_tmp = (u8 *)vars[args[0]];1373 status = altera_set_dr_pre(&astate->js, count, index,1374 charptr_tmp);1375 break;1376 case OP_DPOA:1377 /*1378 * DRPOST with array data1379 * ...argument 0 is variable ID1380 * ...stack 0 is array index1381 * ...stack 1 is count1382 */1383 if (!altera_check_stack(stack_ptr, 2, &status))1384 break;1385 index = stack[--stack_ptr];1386 count = stack[--stack_ptr];1387 1388 if (version > 0)1389 /*1390 * stack 0 = array right index1391 * stack 1 = array left index1392 */1393 count = 1 + count - index;1394 1395 charptr_tmp = (u8 *)vars[args[0]];1396 status = altera_set_dr_post(&astate->js, count, index,1397 charptr_tmp);1398 break;1399 case OP_IPRA:1400 /*1401 * IRPRE with array data1402 * ...argument 0 is variable ID1403 * ...stack 0 is array index1404 * ...stack 1 is count1405 */1406 if (!altera_check_stack(stack_ptr, 2, &status))1407 break;1408 index = stack[--stack_ptr];1409 count = stack[--stack_ptr];1410 1411 if (version > 0)1412 /*1413 * stack 0 = array right index1414 * stack 1 = array left index1415 */1416 count = 1 + count - index;1417 1418 charptr_tmp = (u8 *)vars[args[0]];1419 status = altera_set_ir_pre(&astate->js, count, index,1420 charptr_tmp);1421 1422 break;1423 case OP_IPOA:1424 /*1425 * IRPOST with array data1426 * ...argument 0 is variable ID1427 * ...stack 0 is array index1428 * ...stack 1 is count1429 */1430 if (!altera_check_stack(stack_ptr, 2, &status))1431 break;1432 index = stack[--stack_ptr];1433 count = stack[--stack_ptr];1434 1435 if (version > 0)1436 /*1437 * stack 0 = array right index1438 * stack 1 = array left index1439 */1440 count = 1 + count - index;1441 1442 charptr_tmp = (u8 *)vars[args[0]];1443 status = altera_set_ir_post(&astate->js, count, index,1444 charptr_tmp);1445 1446 break;1447 case OP_EXPT:1448 /*1449 * EXPORT1450 * ...argument 0 is string ID1451 * ...stack 0 is integer expression1452 */1453 if (altera_check_stack(stack_ptr, 1, &status)) {1454 name = &p[str_table + args[0]];1455 long_tmp = stack[--stack_ptr];1456 altera_export_int(name, long_tmp);1457 }1458 break;1459 case OP_PSHE:1460 /*1461 * Push integer array element1462 * ...argument 0 is variable ID1463 * ...stack 0 is array index1464 */1465 if (!altera_check_stack(stack_ptr, 1, &status))1466 break;1467 variable_id = args[0];1468 index = stack[stack_ptr - 1];1469 1470 /* check variable type */1471 if ((attrs[variable_id] & 0x1f) == 0x19) {1472 /* writable integer array */1473 longptr_tmp = (long *)vars[variable_id];1474 stack[stack_ptr - 1] = longptr_tmp[index];1475 } else if ((attrs[variable_id] & 0x1f) == 0x1c) {1476 /* read-only integer array */1477 long_tmp = vars[variable_id] +1478 (index * sizeof(long));1479 stack[stack_ptr - 1] =1480 get_unaligned_be32(&p[long_tmp]);1481 } else1482 status = -ERANGE;1483 1484 break;1485 case OP_PSHA:1486 /*1487 * Push Boolean array1488 * ...argument 0 is variable ID1489 * ...stack 0 is count1490 * ...stack 1 is array index1491 */1492 if (!altera_check_stack(stack_ptr, 2, &status))1493 break;1494 variable_id = args[0];1495 1496 /* check that variable is a Boolean array */1497 if ((attrs[variable_id] & 0x18) != 0x08) {1498 status = -ERANGE;1499 break;1500 }1501 1502 charptr_tmp = (u8 *)vars[variable_id];1503 1504 /* pop the count (number of bits to copy) */1505 count = stack[--stack_ptr];1506 1507 /* pop the array index */1508 index = stack[stack_ptr - 1];1509 1510 if (version > 0)1511 /*1512 * stack 0 = array right index1513 * stack 1 = array left index1514 */1515 count = 1 + count - index;1516 1517 if ((count < 1) || (count > 32)) {1518 status = -ERANGE;1519 break;1520 }1521 1522 long_tmp = 0L;1523 1524 for (i = 0; i < count; ++i)1525 if (charptr_tmp[(i + index) >> 3] &1526 (1 << ((i + index) & 7)))1527 long_tmp |= (1L << i);1528 1529 stack[stack_ptr - 1] = long_tmp;1530 1531 break;1532 case OP_DYNA:1533 /*1534 * Dynamically change size of array1535 * ...argument 0 is variable ID1536 * ...stack 0 is new size1537 */1538 if (!altera_check_stack(stack_ptr, 1, &status))1539 break;1540 variable_id = args[0];1541 long_tmp = stack[--stack_ptr];1542 1543 if (long_tmp > var_size[variable_id]) {1544 var_size[variable_id] = long_tmp;1545 1546 if (attrs[variable_id] & 0x10)1547 /* allocate integer array */1548 long_tmp *= sizeof(long);1549 else1550 /* allocate Boolean array */1551 long_tmp = (long_tmp + 7) >> 3;1552 1553 /*1554 * If the buffer was previously allocated,1555 * free it1556 */1557 if (attrs[variable_id] & 0x80) {1558 kfree((void *)vars[variable_id]);1559 vars[variable_id] = 0;1560 }1561 1562 /*1563 * Allocate a new buffer1564 * of the requested size1565 */1566 vars[variable_id] = (long)1567 kzalloc(long_tmp, GFP_KERNEL);1568 1569 if (vars[variable_id] == 0) {1570 status = -ENOMEM;1571 break;1572 }1573 1574 /*1575 * Set the attribute bit to indicate that1576 * this buffer was dynamically allocated and1577 * should be freed later1578 */1579 attrs[variable_id] |= 0x80;1580 1581 /* zero out memory */1582 count = ((var_size[variable_id] + 7L) /1583 8L);1584 charptr_tmp = (u8 *)(vars[variable_id]);1585 for (index = 0; index < count; ++index)1586 charptr_tmp[index] = 0;1587 1588 }1589 1590 break;1591 case OP_EXPV:1592 /*1593 * Export Boolean array1594 * ...argument 0 is string ID1595 * ...stack 0 is variable ID1596 * ...stack 1 is array right index1597 * ...stack 2 is array left index1598 */1599 if (!altera_check_stack(stack_ptr, 3, &status))1600 break;1601 if (version == 0) {1602 /* EXPV is not supported in JBC 1.0 */1603 bad_opcode = 1;1604 break;1605 }1606 name = &p[str_table + args[0]];1607 variable_id = stack[--stack_ptr];1608 long_idx = stack[--stack_ptr];/* right indx */1609 long_idx2 = stack[--stack_ptr];/* left indx */1610 1611 if (long_idx > long_idx2) {1612 /* reverse indices not supported */1613 status = -ERANGE;1614 break;1615 }1616 1617 long_count = 1 + long_idx2 - long_idx;1618 1619 charptr_tmp = (u8 *)vars[variable_id];1620 charptr_tmp2 = NULL;1621 1622 if ((long_idx & 7L) != 0) {1623 s32 k = long_idx;1624 charptr_tmp2 =1625 kzalloc(((long_count + 7L) / 8L),1626 GFP_KERNEL);1627 if (charptr_tmp2 == NULL) {1628 status = -ENOMEM;1629 break;1630 }1631 1632 for (i = 0; i < long_count; ++i) {1633 if (charptr_tmp[k >> 3] &1634 (1 << (k & 7)))1635 charptr_tmp2[i >> 3] |=1636 (1 << (i & 7));1637 else1638 charptr_tmp2[i >> 3] &=1639 ~(1 << (i & 7));1640 1641 ++k;1642 }1643 charptr_tmp = charptr_tmp2;1644 1645 } else if (long_idx != 0)1646 charptr_tmp = &charptr_tmp[long_idx >> 3];1647 1648 altera_export_bool_array(name, charptr_tmp,1649 long_count);1650 1651 /* free allocated buffer */1652 if ((long_idx & 7L) != 0)1653 kfree(charptr_tmp2);1654 1655 break;1656 case OP_COPY: {1657 /*1658 * Array copy1659 * ...argument 0 is dest ID1660 * ...argument 1 is source ID1661 * ...stack 0 is count1662 * ...stack 1 is dest index1663 * ...stack 2 is source index1664 */1665 s32 copy_count;1666 s32 copy_index;1667 s32 copy_index2;1668 s32 destleft;1669 s32 src_count;1670 s32 dest_count;1671 int src_reverse = 0;1672 int dest_reverse = 0;1673 1674 if (!altera_check_stack(stack_ptr, 3, &status))1675 break;1676 1677 copy_count = stack[--stack_ptr];1678 copy_index = stack[--stack_ptr];1679 copy_index2 = stack[--stack_ptr];1680 reverse = 0;1681 1682 if (version > 0) {1683 /*1684 * stack 0 = source right index1685 * stack 1 = source left index1686 * stack 2 = destination right index1687 * stack 3 = destination left index1688 */1689 destleft = stack[--stack_ptr];1690 1691 if (copy_count > copy_index) {1692 src_reverse = 1;1693 reverse = 1;1694 src_count = 1 + copy_count - copy_index;1695 /* copy_index = source start index */1696 } else {1697 src_count = 1 + copy_index - copy_count;1698 /* source start index */1699 copy_index = copy_count;1700 }1701 1702 if (copy_index2 > destleft) {1703 dest_reverse = 1;1704 reverse = !reverse;1705 dest_count = 1 + copy_index2 - destleft;1706 /* destination start index */1707 copy_index2 = destleft;1708 } else1709 dest_count = 1 + destleft - copy_index2;1710 1711 copy_count = (src_count < dest_count) ?1712 src_count : dest_count;1713 1714 if ((src_reverse || dest_reverse) &&1715 (src_count != dest_count))1716 /*1717 * If either the source or destination1718 * is reversed, we can't tolerate1719 * a length mismatch, because we1720 * "left justify" arrays when copying.1721 * This won't work correctly1722 * with reversed arrays.1723 */1724 status = -ERANGE;1725 1726 }1727 1728 count = copy_count;1729 index = copy_index;1730 index2 = copy_index2;1731 1732 /*1733 * If destination is a read-only array,1734 * allocate a buffer and convert it to a writable array1735 */1736 variable_id = args[1];1737 if ((version > 0) &&1738 ((attrs[variable_id] & 0x9c) == 0x0c)) {1739 /* Allocate a writable buffer for this array */1740 long_tmp =1741 (var_size[variable_id] + 7L) >> 3L;1742 charptr_tmp2 = (u8 *)vars[variable_id];1743 charptr_tmp =1744 kzalloc(long_tmp, GFP_KERNEL);1745 vars[variable_id] = (long)charptr_tmp;1746 1747 if (vars[variable_id] == 0) {1748 status = -ENOMEM;1749 break;1750 }1751 1752 /* zero the buffer */1753 for (long_idx = 0L; long_idx < long_tmp;1754 ++long_idx)1755 charptr_tmp[long_idx] = 0;1756 1757 /* copy previous contents into buffer */1758 for (long_idx = 0L;1759 long_idx < var_size[variable_id];1760 ++long_idx) {1761 long_idx2 = long_idx;1762 1763 if (charptr_tmp2[long_idx2 >> 3] &1764 (1 << (long_idx2 & 7)))1765 charptr_tmp[long_idx >> 3] |=1766 (1 << (long_idx & 7));1767 1768 }1769 1770 /*1771 set bit 7 - buffer was dynamically allocated */1772 attrs[variable_id] |= 0x80;1773 1774 /* clear bit 2 - variable is writable */1775 attrs[variable_id] &= ~0x04;1776 attrs[variable_id] |= 0x01;1777 }1778 1779 charptr_tmp = (u8 *)vars[args[1]];1780 charptr_tmp2 = (u8 *)vars[args[0]];1781 1782 /* check if destination is a writable Boolean array */1783 if ((attrs[args[1]] & 0x1c) != 0x08) {1784 status = -ERANGE;1785 break;1786 }1787 1788 if (count < 1) {1789 status = -ERANGE;1790 break;1791 }1792 1793 if (reverse)1794 index2 += (count - 1);1795 1796 for (i = 0; i < count; ++i) {1797 if (charptr_tmp2[index >> 3] &1798 (1 << (index & 7)))1799 charptr_tmp[index2 >> 3] |=1800 (1 << (index2 & 7));1801 else1802 charptr_tmp[index2 >> 3] &=1803 ~(1 << (index2 & 7));1804 1805 ++index;1806 if (reverse)1807 --index2;1808 else1809 ++index2;1810 }1811 1812 break;1813 }1814 case OP_DSC:1815 case OP_ISC: {1816 /*1817 * DRSCAN with capture1818 * IRSCAN with capture1819 * ...argument 0 is scan data variable ID1820 * ...argument 1 is capture variable ID1821 * ...stack 0 is capture index1822 * ...stack 1 is scan data index1823 * ...stack 2 is count1824 */1825 s32 scan_right, scan_left;1826 s32 capture_count = 0;1827 s32 scan_count = 0;1828 s32 capture_index;1829 s32 scan_index;1830 1831 if (!altera_check_stack(stack_ptr, 3, &status))1832 break;1833 1834 capture_index = stack[--stack_ptr];1835 scan_index = stack[--stack_ptr];1836 1837 if (version > 0) {1838 /*1839 * stack 0 = capture right index1840 * stack 1 = capture left index1841 * stack 2 = scan right index1842 * stack 3 = scan left index1843 * stack 4 = count1844 */1845 scan_right = stack[--stack_ptr];1846 scan_left = stack[--stack_ptr];1847 capture_count = 1 + scan_index - capture_index;1848 scan_count = 1 + scan_left - scan_right;1849 scan_index = scan_right;1850 }1851 1852 long_count = stack[--stack_ptr];1853 /*1854 * If capture array is read-only, allocate a buffer1855 * and convert it to a writable array1856 */1857 variable_id = args[1];1858 if ((version > 0) &&1859 ((attrs[variable_id] & 0x9c) == 0x0c)) {1860 /* Allocate a writable buffer for this array */1861 long_tmp =1862 (var_size[variable_id] + 7L) >> 3L;1863 charptr_tmp2 = (u8 *)vars[variable_id];1864 charptr_tmp =1865 kzalloc(long_tmp, GFP_KERNEL);1866 vars[variable_id] = (long)charptr_tmp;1867 1868 if (vars[variable_id] == 0) {1869 status = -ENOMEM;1870 break;1871 }1872 1873 /* zero the buffer */1874 for (long_idx = 0L; long_idx < long_tmp;1875 ++long_idx)1876 charptr_tmp[long_idx] = 0;1877 1878 /* copy previous contents into buffer */1879 for (long_idx = 0L;1880 long_idx < var_size[variable_id];1881 ++long_idx) {1882 long_idx2 = long_idx;1883 1884 if (charptr_tmp2[long_idx2 >> 3] &1885 (1 << (long_idx2 & 7)))1886 charptr_tmp[long_idx >> 3] |=1887 (1 << (long_idx & 7));1888 1889 }1890 1891 /*1892 * set bit 7 - buffer was1893 * dynamically allocated1894 */1895 attrs[variable_id] |= 0x80;1896 1897 /* clear bit 2 - variable is writable */1898 attrs[variable_id] &= ~0x04;1899 attrs[variable_id] |= 0x01;1900 1901 }1902 1903 charptr_tmp = (u8 *)vars[args[0]];1904 charptr_tmp2 = (u8 *)vars[args[1]];1905 1906 if ((version > 0) &&1907 ((long_count > capture_count) ||1908 (long_count > scan_count))) {1909 status = -ERANGE;1910 break;1911 }1912 1913 /*1914 * check that capture array1915 * is a writable Boolean array1916 */1917 if ((attrs[args[1]] & 0x1c) != 0x08) {1918 status = -ERANGE;1919 break;1920 }1921 1922 if (status == 0) {1923 if (opcode == 0x82) /* DSC */1924 status = altera_swap_dr(astate,1925 long_count,1926 charptr_tmp,1927 scan_index,1928 charptr_tmp2,1929 capture_index);1930 else /* ISC */1931 status = altera_swap_ir(astate,1932 long_count,1933 charptr_tmp,1934 scan_index,1935 charptr_tmp2,1936 capture_index);1937 1938 }1939 1940 break;1941 }1942 case OP_WAIT:1943 /*1944 * WAIT1945 * ...argument 0 is wait state1946 * ...argument 1 is end state1947 * ...stack 0 is cycles1948 * ...stack 1 is microseconds1949 */1950 if (!altera_check_stack(stack_ptr, 2, &status))1951 break;1952 long_tmp = stack[--stack_ptr];1953 1954 if (long_tmp != 0L)1955 status = altera_wait_cycles(astate, long_tmp,1956 args[0]);1957 1958 long_tmp = stack[--stack_ptr];1959 1960 if ((status == 0) && (long_tmp != 0L))1961 status = altera_wait_msecs(astate,1962 long_tmp,1963 args[0]);1964 1965 if ((status == 0) && (args[1] != args[0]))1966 status = altera_goto_jstate(astate,1967 args[1]);1968 1969 if (version > 0) {1970 --stack_ptr; /* throw away MAX cycles */1971 --stack_ptr; /* throw away MAX microseconds */1972 }1973 break;1974 case OP_CMPA: {1975 /*1976 * Array compare1977 * ...argument 0 is source 1 ID1978 * ...argument 1 is source 2 ID1979 * ...argument 2 is mask ID1980 * ...stack 0 is source 1 index1981 * ...stack 1 is source 2 index1982 * ...stack 2 is mask index1983 * ...stack 3 is count1984 */1985 s32 a, b;1986 u8 *source1 = (u8 *)vars[args[0]];1987 u8 *source2 = (u8 *)vars[args[1]];1988 u8 *mask = (u8 *)vars[args[2]];1989 u32 index1;1990 u32 index2;1991 u32 mask_index;1992 1993 if (!altera_check_stack(stack_ptr, 4, &status))1994 break;1995 1996 index1 = stack[--stack_ptr];1997 index2 = stack[--stack_ptr];1998 mask_index = stack[--stack_ptr];1999 long_count = stack[--stack_ptr];2000 2001 if (version > 0) {2002 /*2003 * stack 0 = source 1 right index2004 * stack 1 = source 1 left index2005 * stack 2 = source 2 right index2006 * stack 3 = source 2 left index2007 * stack 4 = mask right index2008 * stack 5 = mask left index2009 */2010 s32 mask_right = stack[--stack_ptr];2011 s32 mask_left = stack[--stack_ptr];2012 /* source 1 count */2013 a = 1 + index2 - index1;2014 /* source 2 count */2015 b = 1 + long_count - mask_index;2016 a = (a < b) ? a : b;2017 /* mask count */2018 b = 1 + mask_left - mask_right;2019 a = (a < b) ? a : b;2020 /* source 2 start index */2021 index2 = mask_index;2022 /* mask start index */2023 mask_index = mask_right;2024 long_count = a;2025 }2026 2027 long_tmp = 1L;2028 2029 if (long_count < 1)2030 status = -ERANGE;2031 else {2032 count = long_count;2033 2034 for (i = 0; i < count; ++i) {2035 if (mask[mask_index >> 3] &2036 (1 << (mask_index & 7))) {2037 a = source1[index1 >> 3] &2038 (1 << (index1 & 7))2039 ? 1 : 0;2040 b = source2[index2 >> 3] &2041 (1 << (index2 & 7))2042 ? 1 : 0;2043 2044 if (a != b) /* failure */2045 long_tmp = 0L;2046 }2047 ++index1;2048 ++index2;2049 ++mask_index;2050 }2051 }2052 2053 stack[stack_ptr++] = long_tmp;2054 2055 break;2056 }2057 default:2058 /* Unrecognized opcode -- ERROR! */2059 bad_opcode = 1;2060 break;2061 }2062 2063 if (bad_opcode)2064 status = -ENOSYS;2065 2066 if ((stack_ptr < 0) || (stack_ptr >= ALTERA_STACK_SIZE))2067 status = -EOVERFLOW;2068 2069 if (status != 0) {2070 done = 1;2071 *error_address = (s32)(opcode_address - code_sect);2072 }2073 }2074 2075 altera_free_buffers(astate);2076 2077 /* Free all dynamically allocated arrays */2078 if ((attrs != NULL) && (vars != NULL))2079 for (i = 0; i < sym_count; ++i)2080 if (attrs[i] & 0x80)2081 kfree((void *)vars[i]);2082 2083 kfree(vars);2084 kfree(var_size);2085 kfree(attrs);2086 kfree(proc_attributes);2087 2088 return status;2089}2090 2091static int altera_get_note(u8 *p, s32 program_size, s32 *offset,2092 char *key, char *value, int keylen, int vallen)2093/*2094 * Gets key and value of NOTE fields in the JBC file.2095 * Can be called in two modes: if offset pointer is NULL,2096 * then the function searches for note fields which match2097 * the key string provided. If offset is not NULL, then2098 * the function finds the next note field of any key,2099 * starting at the offset specified by the offset pointer.2100 * Returns 0 for success, else appropriate error code2101 */2102{2103 int status = -ENODATA;2104 u32 note_strings = 0L;2105 u32 note_table = 0L;2106 u32 note_count = 0L;2107 u32 first_word = 0L;2108 int version = 0;2109 int delta = 0;2110 char *key_ptr;2111 char *value_ptr;2112 int i;2113 2114 /* Read header information */2115 if (program_size > 52L) {2116 first_word = get_unaligned_be32(&p[0]);2117 version = (first_word & 1L);2118 delta = version * 8;2119 2120 note_strings = get_unaligned_be32(&p[8 + delta]);2121 note_table = get_unaligned_be32(&p[12 + delta]);2122 note_count = get_unaligned_be32(&p[44 + (2 * delta)]);2123 }2124 2125 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))2126 return -EIO;2127 2128 if (note_count <= 0L)2129 return status;2130 2131 if (offset == NULL) {2132 /*2133 * We will search for the first note with a specific key,2134 * and return only the value2135 */2136 for (i = 0; (i < note_count) &&2137 (status != 0); ++i) {2138 key_ptr = &p[note_strings +2139 get_unaligned_be32(2140 &p[note_table + (8 * i)])];2141 if (key && !strncasecmp(key, key_ptr, strlen(key_ptr))) {2142 status = 0;2143 2144 value_ptr = &p[note_strings +2145 get_unaligned_be32(2146 &p[note_table + (8 * i) + 4])];2147 2148 if (value != NULL)2149 strscpy(value, value_ptr, vallen);2150 2151 }2152 }2153 } else {2154 /*2155 * We will search for the next note, regardless of the key,2156 * and return both the value and the key2157 */2158 2159 i = *offset;2160 2161 if ((i >= 0) && (i < note_count)) {2162 status = 0;2163 2164 if (key != NULL)2165 strscpy(key, &p[note_strings +2166 get_unaligned_be32(2167 &p[note_table + (8 * i)])],2168 keylen);2169 2170 if (value != NULL)2171 strscpy(value, &p[note_strings +2172 get_unaligned_be32(2173 &p[note_table + (8 * i) + 4])],2174 vallen);2175 2176 *offset = i + 1;2177 }2178 }2179 2180 return status;2181}2182 2183static int altera_check_crc(u8 *p, s32 program_size)2184{2185 int status = 0;2186 u16 local_expected = 0,2187 local_actual = 0,2188 shift_reg = 0xffff;2189 int bit, feedback;2190 u8 databyte;2191 u32 i;2192 u32 crc_section = 0L;2193 u32 first_word = 0L;2194 int version = 0;2195 int delta = 0;2196 2197 if (program_size > 52L) {2198 first_word = get_unaligned_be32(&p[0]);2199 version = (first_word & 1L);2200 delta = version * 8;2201 2202 crc_section = get_unaligned_be32(&p[32 + delta]);2203 }2204 2205 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))2206 status = -EIO;2207 2208 if (crc_section >= program_size)2209 status = -EIO;2210 2211 if (status == 0) {2212 local_expected = (u16)get_unaligned_be16(&p[crc_section]);2213 2214 for (i = 0; i < crc_section; ++i) {2215 databyte = p[i];2216 for (bit = 0; bit < 8; bit++) {2217 feedback = (databyte ^ shift_reg) & 0x01;2218 shift_reg >>= 1;2219 if (feedback)2220 shift_reg ^= 0x8408;2221 2222 databyte >>= 1;2223 }2224 }2225 2226 local_actual = (u16)~shift_reg;2227 2228 if (local_expected != local_actual)2229 status = -EILSEQ;2230 2231 }2232 2233 if (debug || status) {2234 switch (status) {2235 case 0:2236 printk(KERN_INFO "%s: CRC matched: %04x\n", __func__,2237 local_actual);2238 break;2239 case -EILSEQ:2240 printk(KERN_ERR "%s: CRC mismatch: expected %04x, "2241 "actual %04x\n", __func__, local_expected,2242 local_actual);2243 break;2244 case -EIO:2245 printk(KERN_ERR "%s: error: format isn't "2246 "recognized.\n", __func__);2247 break;2248 default:2249 printk(KERN_ERR "%s: CRC function returned error "2250 "code %d\n", __func__, status);2251 break;2252 }2253 }2254 2255 return status;2256}2257 2258static int altera_get_file_info(u8 *p,2259 s32 program_size,2260 int *format_version,2261 int *action_count,2262 int *procedure_count)2263{2264 int status = -EIO;2265 u32 first_word = 0;2266 int version = 0;2267 2268 if (program_size <= 52L)2269 return status;2270 2271 first_word = get_unaligned_be32(&p[0]);2272 2273 if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) {2274 status = 0;2275 2276 version = (first_word & 1L);2277 *format_version = version + 1;2278 2279 if (version > 0) {2280 *action_count = get_unaligned_be32(&p[48]);2281 *procedure_count = get_unaligned_be32(&p[52]);2282 }2283 }2284 2285 return status;2286}2287 2288static int altera_get_act_info(u8 *p,2289 s32 program_size,2290 int index,2291 char **name,2292 char **description,2293 struct altera_procinfo **proc_list)2294{2295 int status = -EIO;2296 struct altera_procinfo *procptr = NULL;2297 struct altera_procinfo *tmpptr = NULL;2298 u32 first_word = 0L;2299 u32 action_table = 0L;2300 u32 proc_table = 0L;2301 u32 str_table = 0L;2302 u32 note_strings = 0L;2303 u32 action_count = 0L;2304 u32 proc_count = 0L;2305 u32 act_name_id = 0L;2306 u32 act_desc_id = 0L;2307 u32 act_proc_id = 0L;2308 u32 act_proc_name = 0L;2309 u8 act_proc_attribute = 0;2310 2311 if (program_size <= 52L)2312 return status;2313 /* Read header information */2314 first_word = get_unaligned_be32(&p[0]);2315 2316 if (first_word != 0x4A414D01L)2317 return status;2318 2319 action_table = get_unaligned_be32(&p[4]);2320 proc_table = get_unaligned_be32(&p[8]);2321 str_table = get_unaligned_be32(&p[12]);2322 note_strings = get_unaligned_be32(&p[16]);2323 action_count = get_unaligned_be32(&p[48]);2324 proc_count = get_unaligned_be32(&p[52]);2325 2326 if (index >= action_count)2327 return status;2328 2329 act_name_id = get_unaligned_be32(&p[action_table + (12 * index)]);2330 act_desc_id = get_unaligned_be32(&p[action_table + (12 * index) + 4]);2331 act_proc_id = get_unaligned_be32(&p[action_table + (12 * index) + 8]);2332 2333 *name = &p[str_table + act_name_id];2334 2335 if (act_desc_id < (note_strings - str_table))2336 *description = &p[str_table + act_desc_id];2337 2338 do {2339 act_proc_name = get_unaligned_be32(2340 &p[proc_table + (13 * act_proc_id)]);2341 act_proc_attribute =2342 (p[proc_table + (13 * act_proc_id) + 8] & 0x03);2343 2344 procptr =2345 kzalloc(sizeof(struct altera_procinfo),2346 GFP_KERNEL);2347 2348 if (procptr == NULL)2349 status = -ENOMEM;2350 else {2351 procptr->name = &p[str_table + act_proc_name];2352 procptr->attrs = act_proc_attribute;2353 procptr->next = NULL;2354 2355 /* add record to end of linked list */2356 if (*proc_list == NULL)2357 *proc_list = procptr;2358 else {2359 tmpptr = *proc_list;2360 while (tmpptr->next != NULL)2361 tmpptr = tmpptr->next;2362 tmpptr->next = procptr;2363 }2364 }2365 2366 act_proc_id = get_unaligned_be32(2367 &p[proc_table + (13 * act_proc_id) + 4]);2368 } while ((act_proc_id != 0) && (act_proc_id < proc_count));2369 2370 return status;2371}2372 2373int altera_init(struct altera_config *config, const struct firmware *fw)2374{2375 struct altera_state *astate = NULL;2376 struct altera_procinfo *proc_list = NULL;2377 struct altera_procinfo *procptr = NULL;2378 char *key = NULL;2379 char *value = NULL;2380 char *action_name = NULL;2381 char *description = NULL;2382 int exec_result = 0;2383 int exit_code = 0;2384 int format_version = 0;2385 int action_count = 0;2386 int procedure_count = 0;2387 int index = 0;2388 s32 offset = 0L;2389 s32 error_address = 0L;2390 int retval = 0;2391 2392 key = kzalloc(33, GFP_KERNEL);2393 if (!key) {2394 retval = -ENOMEM;2395 goto out;2396 }2397 value = kzalloc(257, GFP_KERNEL);2398 if (!value) {2399 retval = -ENOMEM;2400 goto free_key;2401 }2402 astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL);2403 if (!astate) {2404 retval = -ENOMEM;2405 goto free_value;2406 }2407 2408 astate->config = config;2409 if (!astate->config->jtag_io) {2410 if (!IS_ENABLED(CONFIG_HAS_IOPORT)) {2411 retval = -ENODEV;2412 goto free_state;2413 }2414 dprintk("%s: using byteblaster!\n", __func__);2415 astate->config->jtag_io = netup_jtag_io_lpt;2416 }2417 2418 altera_check_crc((u8 *)fw->data, fw->size);2419 2420 if (debug) {2421 altera_get_file_info((u8 *)fw->data, fw->size, &format_version,2422 &action_count, &procedure_count);2423 printk(KERN_INFO "%s: File format is %s ByteCode format\n",2424 __func__, (format_version == 2) ? "Jam STAPL" :2425 "pre-standardized Jam 1.1");2426 while (altera_get_note((u8 *)fw->data, fw->size,2427 &offset, key, value, 32, 256) == 0)2428 printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",2429 __func__, key, value);2430 }2431 2432 if (debug && (format_version == 2) && (action_count > 0)) {2433 printk(KERN_INFO "%s: Actions available:\n", __func__);2434 for (index = 0; index < action_count; ++index) {2435 altera_get_act_info((u8 *)fw->data, fw->size,2436 index, &action_name,2437 &description,2438 &proc_list);2439 2440 if (description == NULL)2441 printk(KERN_INFO "%s: %s\n",2442 __func__,2443 action_name);2444 else2445 printk(KERN_INFO "%s: %s \"%s\"\n",2446 __func__,2447 action_name,2448 description);2449 2450 procptr = proc_list;2451 while (procptr != NULL) {2452 if (procptr->attrs != 0)2453 printk(KERN_INFO "%s: %s (%s)\n",2454 __func__,2455 procptr->name,2456 (procptr->attrs == 1) ?2457 "optional" : "recommended");2458 2459 proc_list = procptr->next;2460 kfree(procptr);2461 procptr = proc_list;2462 }2463 }2464 2465 printk(KERN_INFO "\n");2466 }2467 2468 exec_result = altera_execute(astate, (u8 *)fw->data, fw->size,2469 &error_address, &exit_code, &format_version);2470 2471 if (exit_code)2472 exec_result = -EREMOTEIO;2473 2474 if ((format_version == 2) && (exec_result == -EINVAL)) {2475 if (astate->config->action == NULL)2476 printk(KERN_ERR "%s: error: no action specified for "2477 "Jam STAPL file.\nprogram terminated.\n",2478 __func__);2479 else2480 printk(KERN_ERR "%s: error: action \"%s\""2481 " is not supported "2482 "for this Jam STAPL file.\n"2483 "Program terminated.\n", __func__,2484 astate->config->action);2485 2486 } else if (exec_result)2487 printk(KERN_ERR "%s: error %d\n", __func__, exec_result);2488free_state:2489 kfree(astate);2490free_value:2491 kfree(value);2492free_key:2493 kfree(key);2494out:2495 return retval;2496}2497EXPORT_SYMBOL(altera_init);2498