/* This function checks if enough parameters are available on the stack. */ staticint altera_check_stack(int stack_ptr, int count, int *status)
{ if (stack_ptr < count) {
*status = -EOVERFLOW; return 0;
}
/* allocate a buffer for the uncompressed data */
vars[i] = (long)kzalloc(uncomp_size, GFP_KERNEL); if (vars[i] == 0L)
status = -ENOMEM; else { /* set flag so buffer will be freed later */
attrs[i] |= 0x80;
/* uncompress the data */ if (altera_shrink(&p[data_sect + value],
var_size[i],
(u8 *)vars[i],
uncomp_size,
version) != uncomp_size) /* decompression failed */
status = -EIO; else
var_size[i] = uncomp_size * 8L;
if (vars[i] == 0) {
status = -ENOMEM;
} else { /* zero out memory */ for (j = 0; j < size; ++j)
((u8 *)(vars[i]))[j] = 0;
}
} else
vars[i] = 0;
} else
vars[i] = 0;
}
exit_done: if (status != 0)
done = 1;
altera_jinit(astate);
pc = code_sect;
msg_buff[0] = '\0';
/* * For JBC version 2, we will execute the procedures corresponding to * the selected ACTION
*/ if (version > 0) { if (aconf->action == NULL) {
status = -EINVAL;
done = 1;
} else { int action_found = 0; for (i = 0; (i < action_count) && !action_found; ++i) {
name_id = get_unaligned_be32(&p[action_table +
(12 * i)]);
if (!action_found) {
status = -EINVAL;
done = 1;
}
}
if (status == 0) { int first_time = 1;
i = current_proc; while ((i != 0) || first_time) {
first_time = 0; /* check procedure attribute byte */
proc_attributes[i] =
(p[proc_table +
(13 * i) + 8] &
0x03);
/* * BIT0 - OPTIONAL * BIT1 - RECOMMENDED * BIT6 - FORCED OFF * BIT7 - FORCED ON
*/
i = get_unaligned_be32(&p[proc_table +
(13 * i) + 4]);
}
/* * Set current_proc to the first procedure * to be executed
*/
i = current_proc; while ((i != 0) &&
((proc_attributes[i] == 1) ||
((proc_attributes[i] & 0xc0) == 0x40))) {
i = get_unaligned_be32(&p[proc_table +
(13 * i) + 4]);
}
if ((i != 0) || ((i == 0) && (current_proc == 0) &&
((proc_attributes[0] != 1) &&
((proc_attributes[0] & 0xc0) != 0x40)))) {
current_proc = i;
pc = code_sect +
get_unaligned_be32(&p[proc_table +
(13 * i) + 9]); if ((pc < code_sect) || (pc >= debug_sect))
status = -ERANGE;
} else /* there are no procedures to execute! */
done = 1;
break; case OP_RET: if ((version > 0) && (stack_ptr == 0)) { /* * We completed one of the main procedures * of an ACTION. * Find the next procedure * to be executed and jump to it. * If there are no more procedures, then EXIT.
*/
i = get_unaligned_be32(&p[proc_table +
(13 * current_proc) + 4]); while ((i != 0) &&
((proc_attributes[i] == 1) ||
((proc_attributes[i] & 0xc0) == 0x40)))
i = get_unaligned_be32(&p[proc_table +
(13 * i) + 4]);
if (i == 0) { /* no procedures to execute! */
done = 1;
*exit_code = 0; /* success */
} else {
current_proc = i;
pc = code_sect + get_unaligned_be32(
&p[proc_table +
(13 * i) + 9]); if ((pc < code_sect) ||
(pc >= debug_sect))
status = -ERANGE;
}
} else if (altera_check_stack(stack_ptr, 1, &status)) {
pc = stack[--stack_ptr] + code_sect; if ((pc <= code_sect) ||
(pc >= debug_sect))
status = -ERANGE;
}
break; case OP_CMPS: /* * Array short compare * ...stack 0 is source 1 value * ...stack 1 is source 2 value * ...stack 2 is mask value * ...stack 3 is count
*/ if (altera_check_stack(stack_ptr, 4, &status)) {
s32 a = stack[--stack_ptr];
s32 b = stack[--stack_ptr];
long_tmp = stack[--stack_ptr];
count = stack[stack_ptr - 1];
if ((count < 1) || (count > 32))
status = -ERANGE; else {
long_tmp &= ((-1L) >> (32 - count));
stack[stack_ptr - 1] =
((a & long_tmp) == (b & long_tmp))
? 1L : 0L;
}
} break; case OP_PINT: /* * PRINT add integer * ...stack 0 is integer value
*/ if (!altera_check_stack(stack_ptr, 1, &status)) break;
sprintf(&msg_buff[strlen(msg_buff)], "%ld", stack[--stack_ptr]); break; case OP_PRNT: /* PRINT finish */ if (debug)
printk(msg_buff, "\n");
msg_buff[0] = '\0'; break; case OP_DSS: /* * DRSCAN short * ...stack 0 is scan data * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
long_tmp = stack[--stack_ptr];
count = stack[--stack_ptr];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_drscan(astate, count, charbuf, 0); break; case OP_DSSC: /* * DRSCAN short with capture * ...stack 0 is scan data * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
long_tmp = stack[--stack_ptr];
count = stack[stack_ptr - 1];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_swap_dr(astate, count, charbuf,
0, charbuf, 0);
stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]); break; case OP_ISS: /* * IRSCAN short * ...stack 0 is scan data * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
long_tmp = stack[--stack_ptr];
count = stack[--stack_ptr];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_irscan(astate, count, charbuf, 0); break; case OP_ISSC: /* * IRSCAN short with capture * ...stack 0 is scan data * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
long_tmp = stack[--stack_ptr];
count = stack[stack_ptr - 1];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_swap_ir(astate, count, charbuf,
0, charbuf, 0);
stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]); break; case OP_DPR: if (!altera_check_stack(stack_ptr, 1, &status)) break;
count = stack[--stack_ptr];
status = altera_set_dr_pre(&astate->js, count, 0, NULL); break; case OP_DPRL: /* * DRPRE with literal data * ...stack 0 is count * ...stack 1 is literal data
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
count = stack[--stack_ptr];
long_tmp = stack[--stack_ptr];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_set_dr_pre(&astate->js, count, 0,
charbuf); break; case OP_DPO: /* * DRPOST * ...stack 0 is count
*/ if (altera_check_stack(stack_ptr, 1, &status)) {
count = stack[--stack_ptr];
status = altera_set_dr_post(&astate->js, count,
0, NULL);
} break; case OP_DPOL: /* * DRPOST with literal data * ...stack 0 is count * ...stack 1 is literal data
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
count = stack[--stack_ptr];
long_tmp = stack[--stack_ptr];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_set_dr_post(&astate->js, count, 0,
charbuf); break; case OP_IPR: if (altera_check_stack(stack_ptr, 1, &status)) {
count = stack[--stack_ptr];
status = altera_set_ir_pre(&astate->js, count,
0, NULL);
} break; case OP_IPRL: /* * IRPRE with literal data * ...stack 0 is count * ...stack 1 is literal data
*/ if (altera_check_stack(stack_ptr, 2, &status)) {
count = stack[--stack_ptr];
long_tmp = stack[--stack_ptr];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_set_ir_pre(&astate->js, count,
0, charbuf);
} break; case OP_IPO: /* * IRPOST * ...stack 0 is count
*/ if (altera_check_stack(stack_ptr, 1, &status)) {
count = stack[--stack_ptr];
status = altera_set_ir_post(&astate->js, count,
0, NULL);
} break; case OP_IPOL: /* * IRPOST with literal data * ...stack 0 is count * ...stack 1 is literal data
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
count = stack[--stack_ptr];
long_tmp = stack[--stack_ptr];
put_unaligned_le32(long_tmp, &charbuf[0]);
status = altera_set_ir_post(&astate->js, count, 0,
charbuf); break; case OP_PCHR: if (altera_check_stack(stack_ptr, 1, &status)) {
u8 ch;
count = strlen(msg_buff);
ch = (char) stack[--stack_ptr]; if ((ch < 1) || (ch > 127)) { /* * character code out of range * instead of flagging an error, * force the value to 127
*/
ch = 127;
}
msg_buff[count] = ch;
msg_buff[count + 1] = '\0';
} break; case OP_EXIT: if (altera_check_stack(stack_ptr, 1, &status))
*exit_code = stack[--stack_ptr];
done = 1; break; case OP_EQU: if (!altera_check_stack(stack_ptr, 2, &status)) break;
--stack_ptr;
stack[stack_ptr - 1] =
(stack[stack_ptr - 1] == stack[stack_ptr]) ?
1L : 0L; break; case OP_POPT: if (altera_check_stack(stack_ptr, 1, &status))
--stack_ptr;
break; case OP_ABS: if (!altera_check_stack(stack_ptr, 1, &status)) break; if (stack[stack_ptr - 1] < 0)
stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
/* DUPN 6 */
index = 6 + 1; if (altera_check_stack(stack_ptr, index, &status)) {
stack[stack_ptr] = stack[stack_ptr - index];
++stack_ptr;
} break; case OP_PSH0:
stack[stack_ptr++] = 0; break; case OP_PSHL:
stack[stack_ptr++] = (s32) args[0]; break; case OP_PSHV:
stack[stack_ptr++] = vars[args[0]]; break; case OP_JMP:
pc = args[0] + code_sect; if ((pc < code_sect) || (pc >= debug_sect))
status = -ERANGE; break; case OP_CALL:
stack[stack_ptr++] = pc;
pc = args[0] + code_sect; if ((pc < code_sect) || (pc >= debug_sect))
status = -ERANGE; break; case OP_NEXT: /* * Process FOR / NEXT loop * ...argument 0 is variable ID * ...stack 0 is step value * ...stack 1 is end value * ...stack 2 is top address
*/ if (altera_check_stack(stack_ptr, 3, &status)) {
s32 step = stack[stack_ptr - 1];
s32 end = stack[stack_ptr - 2];
s32 top = stack[stack_ptr - 3];
s32 iterator = vars[args[0]]; int break_out = 0;
if (step < 0) { if (iterator <= end)
break_out = 1;
} elseif (iterator >= end)
break_out = 1;
if (break_out) {
stack_ptr -= 3;
} else {
vars[args[0]] = iterator + step;
pc = top + code_sect; if ((pc < code_sect) ||
(pc >= debug_sect))
status = -ERANGE;
}
} break; case OP_PSTR: /* * PRINT add string * ...argument 0 is string ID
*/
count = strlen(msg_buff);
strscpy(&msg_buff[count],
&p[str_table + args[0]],
ALTERA_MESSAGE_LENGTH - count); break; case OP_SINT: /* * STATE intermediate state * ...argument 0 is state code
*/
status = altera_goto_jstate(astate, args[0]); break; case OP_ST: /* * STATE final state * ...argument 0 is state code
*/
status = altera_goto_jstate(astate, args[0]); break; case OP_ISTP: /* * IRSTOP state * ...argument 0 is state code
*/
status = altera_set_irstop(&astate->js, args[0]); break; case OP_DSTP: /* * DRSTOP state * ...argument 0 is state code
*/
status = altera_set_drstop(&astate->js, args[0]); break;
case OP_SWPN: /* * Exchange top with Nth stack value * ...argument 0 is 0-based stack entry * to swap with top element
*/
index = (args[0]) + 1; if (altera_check_stack(stack_ptr, index, &status))
swap(stack[stack_ptr - index], stack[stack_ptr - 1]); break; case OP_DUPN: /* * Duplicate Nth stack value * ...argument 0 is 0-based stack entry to duplicate
*/
index = (args[0]) + 1; if (altera_check_stack(stack_ptr, index, &status)) {
stack[stack_ptr] = stack[stack_ptr - index];
++stack_ptr;
} break; case OP_POPV: /* * Pop stack into scalar variable * ...argument 0 is variable ID * ...stack 0 is value
*/ if (altera_check_stack(stack_ptr, 1, &status))
vars[args[0]] = stack[--stack_ptr];
break; case OP_POPE: /* * Pop stack into integer array element * ...argument 0 is variable ID * ...stack 0 is array index * ...stack 1 is value
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
variable_id = args[0];
/* * If variable is read-only, * convert to writable array
*/ if ((version > 0) &&
((attrs[variable_id] & 0x9c) == 0x1c)) { /* Allocate a writable buffer for this array */
count = var_size[variable_id];
long_tmp = vars[variable_id];
longptr_tmp = kcalloc(count, sizeof(long),
GFP_KERNEL);
vars[variable_id] = (long)longptr_tmp;
if (vars[variable_id] == 0) {
status = -ENOMEM; break;
}
/* copy previous contents into buffer */ for (i = 0; i < count; ++i) {
longptr_tmp[i] =
get_unaligned_be32(&p[long_tmp]);
long_tmp += sizeof(long);
}
/* * set bit 7 - buffer was * dynamically allocated
*/
attrs[variable_id] |= 0x80;
/* clear bit 2 - variable is writable */
attrs[variable_id] &= ~0x04;
attrs[variable_id] |= 0x01;
}
/* check that variable is a writable integer array */ if ((attrs[variable_id] & 0x1c) != 0x18)
status = -ERANGE; else {
longptr_tmp = (long *)vars[variable_id];
/* pop the array index */
index = stack[--stack_ptr];
/* pop the value and store it into the array */
longptr_tmp[index] = stack[--stack_ptr];
}
break; case OP_POPA: /* * Pop stack into Boolean array * ...argument 0 is variable ID * ...stack 0 is count * ...stack 1 is array index * ...stack 2 is value
*/ if (!altera_check_stack(stack_ptr, 3, &status)) break;
variable_id = args[0];
/* * If variable is read-only, * convert to writable array
*/ if ((version > 0) &&
((attrs[variable_id] & 0x9c) == 0x0c)) { /* Allocate a writable buffer for this array */
long_tmp =
(var_size[variable_id] + 7L) >> 3L;
charptr_tmp2 = (u8 *)vars[variable_id];
charptr_tmp =
kzalloc(long_tmp, GFP_KERNEL);
vars[variable_id] = (long)charptr_tmp;
if (vars[variable_id] == 0) {
status = -ENOMEM; break;
}
/* zero the buffer */ for (long_idx = 0L;
long_idx < long_tmp;
++long_idx) {
charptr_tmp[long_idx] = 0;
}
/* copy previous contents into buffer */ for (long_idx = 0L;
long_idx < var_size[variable_id];
++long_idx) {
long_idx2 = long_idx;
/* reverse POPA is not supported */
status = -ERANGE; break;
} else
long_count = 1 + long_count -
long_idx;
}
/* pop the data */
long_tmp = stack[--stack_ptr];
if (long_count < 1) {
status = -ERANGE; break;
}
for (i = 0; i < long_count; ++i) { if (long_tmp & (1L << (s32) i))
charptr_tmp[long_idx >> 3L] |=
(1L << (long_idx & 7L)); else
charptr_tmp[long_idx >> 3L] &=
~(1L << (long_idx & 7L));
++long_idx;
}
break; case OP_JMPZ: /* * Pop stack and branch if zero * ...argument 0 is address * ...stack 0 is condition value
*/ if (altera_check_stack(stack_ptr, 1, &status)) { if (stack[--stack_ptr] == 0) {
pc = args[0] + code_sect; if ((pc < code_sect) ||
(pc >= debug_sect))
status = -ERANGE;
}
} break; case OP_DS: case OP_IS: /* * DRSCAN * IRSCAN * ...argument 0 is scan data variable ID * ...stack 0 is array index * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
long_idx = stack[--stack_ptr];
long_count = stack[--stack_ptr];
reverse = 0; if (version > 0) { /* * stack 0 = array right index * stack 1 = array left index * stack 2 = count
*/
long_tmp = long_count;
long_count = stack[--stack_ptr];
if (reverse) { /* * allocate a buffer * and reverse the data order
*/
charptr_tmp2 = charptr_tmp;
charptr_tmp = kzalloc((long_count >> 3) + 1,
GFP_KERNEL); if (charptr_tmp == NULL) {
status = -ENOMEM; break;
}
if (opcode == 0x51) /* DS */
status = altera_drscan(astate, long_count,
charptr_tmp, long_idx); else/* IS */
status = altera_irscan(astate, long_count,
charptr_tmp, long_idx);
if (reverse)
kfree(charptr_tmp);
break; case OP_DPRA: /* * DRPRE with array data * ...argument 0 is variable ID * ...stack 0 is array index * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
index = stack[--stack_ptr];
count = stack[--stack_ptr];
if (version > 0) /* * stack 0 = array right index * stack 1 = array left index
*/
count = 1 + count - index;
charptr_tmp = (u8 *)vars[args[0]];
status = altera_set_dr_pre(&astate->js, count, index,
charptr_tmp); break; case OP_DPOA: /* * DRPOST with array data * ...argument 0 is variable ID * ...stack 0 is array index * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
index = stack[--stack_ptr];
count = stack[--stack_ptr];
if (version > 0) /* * stack 0 = array right index * stack 1 = array left index
*/
count = 1 + count - index;
charptr_tmp = (u8 *)vars[args[0]];
status = altera_set_dr_post(&astate->js, count, index,
charptr_tmp); break; case OP_IPRA: /* * IRPRE with array data * ...argument 0 is variable ID * ...stack 0 is array index * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
index = stack[--stack_ptr];
count = stack[--stack_ptr];
if (version > 0) /* * stack 0 = array right index * stack 1 = array left index
*/
count = 1 + count - index;
charptr_tmp = (u8 *)vars[args[0]];
status = altera_set_ir_pre(&astate->js, count, index,
charptr_tmp);
break; case OP_IPOA: /* * IRPOST with array data * ...argument 0 is variable ID * ...stack 0 is array index * ...stack 1 is count
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
index = stack[--stack_ptr];
count = stack[--stack_ptr];
if (version > 0) /* * stack 0 = array right index * stack 1 = array left index
*/
count = 1 + count - index;
charptr_tmp = (u8 *)vars[args[0]];
status = altera_set_ir_post(&astate->js, count, index,
charptr_tmp);
break; case OP_EXPT: /* * EXPORT * ...argument 0 is string ID * ...stack 0 is integer expression
*/ if (altera_check_stack(stack_ptr, 1, &status)) {
name = &p[str_table + args[0]];
long_tmp = stack[--stack_ptr];
altera_export_int(name, long_tmp);
} break; case OP_PSHE: /* * Push integer array element * ...argument 0 is variable ID * ...stack 0 is array index
*/ if (!altera_check_stack(stack_ptr, 1, &status)) break;
variable_id = args[0];
index = stack[stack_ptr - 1];
break; case OP_PSHA: /* * Push Boolean array * ...argument 0 is variable ID * ...stack 0 is count * ...stack 1 is array index
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
variable_id = args[0];
/* check that variable is a Boolean array */ if ((attrs[variable_id] & 0x18) != 0x08) {
status = -ERANGE; break;
}
charptr_tmp = (u8 *)vars[variable_id];
/* pop the count (number of bits to copy) */
count = stack[--stack_ptr];
/* pop the array index */
index = stack[stack_ptr - 1];
if (version > 0) /* * stack 0 = array right index * stack 1 = array left index
*/
count = 1 + count - index;
if ((count < 1) || (count > 32)) {
status = -ERANGE; break;
}
long_tmp = 0L;
for (i = 0; i < count; ++i) if (charptr_tmp[(i + index) >> 3] &
(1 << ((i + index) & 7)))
long_tmp |= (1L << i);
stack[stack_ptr - 1] = long_tmp;
break; case OP_DYNA: /* * Dynamically change size of array * ...argument 0 is variable ID * ...stack 0 is new size
*/ if (!altera_check_stack(stack_ptr, 1, &status)) break;
variable_id = args[0];
long_tmp = stack[--stack_ptr];
if (long_tmp > var_size[variable_id]) {
var_size[variable_id] = long_tmp;
/* * If the buffer was previously allocated, * free it
*/ if (attrs[variable_id] & 0x80) {
kfree((void *)vars[variable_id]);
vars[variable_id] = 0;
}
/* * Allocate a new buffer * of the requested size
*/
vars[variable_id] = (long)
kzalloc(long_tmp, GFP_KERNEL);
if (vars[variable_id] == 0) {
status = -ENOMEM; break;
}
/* * Set the attribute bit to indicate that * this buffer was dynamically allocated and * should be freed later
*/
attrs[variable_id] |= 0x80;
/* zero out memory */
count = ((var_size[variable_id] + 7L) /
8L);
charptr_tmp = (u8 *)(vars[variable_id]); for (index = 0; index < count; ++index)
charptr_tmp[index] = 0;
}
break; case OP_EXPV: /* * Export Boolean array * ...argument 0 is string ID * ...stack 0 is variable ID * ...stack 1 is array right index * ...stack 2 is array left index
*/ if (!altera_check_stack(stack_ptr, 3, &status)) break; if (version == 0) { /* EXPV is not supported in JBC 1.0 */
bad_opcode = 1; break;
}
name = &p[str_table + args[0]];
variable_id = stack[--stack_ptr];
long_idx = stack[--stack_ptr];/* right indx */
long_idx2 = stack[--stack_ptr];/* left indx */
if (long_idx > long_idx2) { /* reverse indices not supported */
status = -ERANGE; break;
}
break; case OP_COPY: { /* * Array copy * ...argument 0 is dest ID * ...argument 1 is source ID * ...stack 0 is count * ...stack 1 is dest index * ...stack 2 is source index
*/
s32 copy_count;
s32 copy_index;
s32 copy_index2;
s32 destleft;
s32 src_count;
s32 dest_count; int src_reverse = 0; int dest_reverse = 0;
if (!altera_check_stack(stack_ptr, 3, &status)) break;
if (version > 0) { /* * stack 0 = source right index * stack 1 = source left index * stack 2 = destination right index * stack 3 = destination left index
*/
destleft = stack[--stack_ptr];
if ((src_reverse || dest_reverse) &&
(src_count != dest_count)) /* * If either the source or destination * is reversed, we can't tolerate * a length mismatch, because we * "left justify" arrays when copying. * This won't work correctly * with reversed arrays.
*/
status = -ERANGE;
}
count = copy_count;
index = copy_index;
index2 = copy_index2;
/* * If destination is a read-only array, * allocate a buffer and convert it to a writable array
*/
variable_id = args[1]; if ((version > 0) &&
((attrs[variable_id] & 0x9c) == 0x0c)) { /* Allocate a writable buffer for this array */
long_tmp =
(var_size[variable_id] + 7L) >> 3L;
charptr_tmp2 = (u8 *)vars[variable_id];
charptr_tmp =
kzalloc(long_tmp, GFP_KERNEL);
vars[variable_id] = (long)charptr_tmp;
if (vars[variable_id] == 0) {
status = -ENOMEM; break;
}
/* zero the buffer */ for (long_idx = 0L; long_idx < long_tmp;
++long_idx)
charptr_tmp[long_idx] = 0;
/* copy previous contents into buffer */ for (long_idx = 0L;
long_idx < var_size[variable_id];
++long_idx) {
long_idx2 = long_idx;
/* check if destination is a writable Boolean array */ if ((attrs[args[1]] & 0x1c) != 0x08) {
status = -ERANGE; break;
}
if (count < 1) {
status = -ERANGE; break;
}
if (reverse)
index2 += (count - 1);
for (i = 0; i < count; ++i) { if (charptr_tmp2[index >> 3] &
(1 << (index & 7)))
charptr_tmp[index2 >> 3] |=
(1 << (index2 & 7)); else
charptr_tmp[index2 >> 3] &=
~(1 << (index2 & 7));
++index; if (reverse)
--index2; else
++index2;
}
break;
} case OP_DSC: case OP_ISC: { /* * DRSCAN with capture * IRSCAN with capture * ...argument 0 is scan data variable ID * ...argument 1 is capture variable ID * ...stack 0 is capture index * ...stack 1 is scan data index * ...stack 2 is count
*/
s32 scan_right, scan_left;
s32 capture_count = 0;
s32 scan_count = 0;
s32 capture_index;
s32 scan_index;
if (!altera_check_stack(stack_ptr, 3, &status)) break;
if ((version > 0) &&
((long_count > capture_count) ||
(long_count > scan_count))) {
status = -ERANGE; break;
}
/* * check that capture array * is a writable Boolean array
*/ if ((attrs[args[1]] & 0x1c) != 0x08) {
status = -ERANGE; break;
}
if (status == 0) { if (opcode == 0x82) /* DSC */
status = altera_swap_dr(astate,
long_count,
charptr_tmp,
scan_index,
charptr_tmp2,
capture_index); else/* ISC */
status = altera_swap_ir(astate,
long_count,
charptr_tmp,
scan_index,
charptr_tmp2,
capture_index);
}
break;
} case OP_WAIT: /* * WAIT * ...argument 0 is wait state * ...argument 1 is end state * ...stack 0 is cycles * ...stack 1 is microseconds
*/ if (!altera_check_stack(stack_ptr, 2, &status)) break;
long_tmp = stack[--stack_ptr];
if (long_tmp != 0L)
status = altera_wait_cycles(astate, long_tmp,
args[0]);
long_tmp = stack[--stack_ptr];
if ((status == 0) && (long_tmp != 0L))
status = altera_wait_msecs(astate,
long_tmp,
args[0]);
if ((status == 0) && (args[1] != args[0]))
status = altera_goto_jstate(astate,
args[1]);
if (version > 0) {
--stack_ptr; /* throw away MAX cycles */
--stack_ptr; /* throw away MAX microseconds */
} break; case OP_CMPA: { /* * Array compare * ...argument 0 is source 1 ID * ...argument 1 is source 2 ID * ...argument 2 is mask ID * ...stack 0 is source 1 index * ...stack 1 is source 2 index * ...stack 2 is mask index * ...stack 3 is count
*/
s32 a, b;
u8 *source1 = (u8 *)vars[args[0]];
u8 *source2 = (u8 *)vars[args[1]];
u8 *mask = (u8 *)vars[args[2]];
u32 index1;
u32 index2;
u32 mask_index;
if (!altera_check_stack(stack_ptr, 4, &status)) break;
/* Free all dynamically allocated arrays */ if ((attrs != NULL) && (vars != NULL)) for (i = 0; i < sym_count; ++i) if (attrs[i] & 0x80)
kfree((void *)vars[i]);
staticint altera_get_note(u8 *p, s32 program_size, s32 *offset, char *key, char *value, int keylen, int vallen) /* * Gets key and value of NOTE fields in the JBC file. * Can be called in two modes: if offset pointer is NULL, * then the function searches for note fields which match * the key string provided. If offset is not NULL, then * the function finds the next note field of any key, * starting at the offset specified by the offset pointer. * Returns 0 for success, else appropriate error code
*/
{ int status = -ENODATA;
u32 note_strings = 0L;
u32 note_table = 0L;
u32 note_count = 0L;
u32 first_word = 0L; int version = 0; int delta = 0; char *key_ptr; char *value_ptr; int i;
/* Read header information */ if (program_size > 52L) {
first_word = get_unaligned_be32(&p[0]);
version = (first_word & 1L);
delta = version * 8;
if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) return -EIO;
if (note_count <= 0L) return status;
if (offset == NULL) { /* * We will search for the first note with a specific key, * and return only the value
*/ for (i = 0; (i < note_count) &&
(status != 0); ++i) {
key_ptr = &p[note_strings +
get_unaligned_be32(
&p[note_table + (8 * i)])]; if (key && !strncasecmp(key, key_ptr, strlen(key_ptr))) {
status = 0;
if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
status = -EIO;
if (crc_section >= program_size)
status = -EIO;
if (status == 0) {
local_expected = (u16)get_unaligned_be16(&p[crc_section]);
for (i = 0; i < crc_section; ++i) {
databyte = p[i]; for (bit = 0; bit < 8; bit++) {
feedback = (databyte ^ shift_reg) & 0x01;
shift_reg >>= 1; if (feedback)
shift_reg ^= 0x8408;
databyte >>= 1;
}
}
local_actual = (u16)~shift_reg;
if (local_expected != local_actual)
status = -EILSEQ;
}
if (debug || status) { switch (status) { case 0:
printk(KERN_INFO "%s: CRC matched: %04x\n", __func__,
local_actual); break; case -EILSEQ:
printk(KERN_ERR "%s: CRC mismatch: expected %04x, " "actual %04x\n", __func__, local_expected,
local_actual); break; case -EIO:
printk(KERN_ERR "%s: error: format isn't " "recognized.\n", __func__); break; default:
printk(KERN_ERR "%s: CRC function returned error " "code %d\n", __func__, status); break;
}
}
return status;
}
staticint altera_get_file_info(u8 *p,
s32 program_size, int *format_version, int *action_count, int *procedure_count)
{ int status = -EIO;
u32 first_word = 0; int version = 0;
if (program_size <= 52L) return status;
first_word = get_unaligned_be32(&p[0]);
if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) {
status = 0;
version = (first_word & 1L);
*format_version = version + 1;
if (procptr == NULL)
status = -ENOMEM; else {
procptr->name = &p[str_table + act_proc_name];
procptr->attrs = act_proc_attribute;
procptr->next = NULL;
/* add record to end of linked list */ if (*proc_list == NULL)
*proc_list = procptr; else {
tmpptr = *proc_list; while (tmpptr->next != NULL)
tmpptr = tmpptr->next;
tmpptr->next = procptr;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.