Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);