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