OPC_CALL = 0x35, /* "function" call */
OPC_WIN = 0x36, /* wait for input (ie. wait for WPTR to advance) */
OPC_PREEMPTLEAVE6 = 0x38, /* try to leave preemption */
+ OPC_SETSECURE = 0x3b, /* switch secure mode on/off */
} afuc_opc;
opc = OPC_PREEMPTLEAVE6;
instr.call.uoff = resolve_label(ai->label);
break;
+ case T_OP_SETSECURE:
+ opc = OPC_SETSECURE;
+ if (resolve_label(ai->label) != i + 3) {
+ fprintf(stderr, "jump label %s is incorrect for setsecure\n", ai->label);
+ exit(1);
+ }
+ if (ai->src1 != 0x2) {
+ fprintf(stderr, "source for setsecure must be $02\n");
+ exit(1);
+ }
+ break;
case T_OP_JUMP:
/* encode jump as: brne $00, b0, #label */
opc = OPC_BRNEB;
case OPC_CALL:
fxn_idx(instr->call.uoff, true);
break;
+ case OPC_SETSECURE:
+ /* this implicitly jumps to pc + 3 if successful */
+ label_idx(i + 3, true);
+ break;
default:
break;
}
printlbl("%s", label_name(instr->call.uoff, true));
}
break;
+ case OPC_SETSECURE:
+ /* Note: This seems to implicitly read the secure/not-secure state
+ * to set from the low bit of $02, and implicitly jumps to pc + 3
+ * (i.e. skipping the next two instructions) if it succeeds. We
+ * print these implicit parameters to make reading the disassembly
+ * easier.
+ */
+ if (instr->pad)
+ printf("[%08x] ; ", instrs[i]);
+ printf("setsecure $02, #");
+ printlbl("%s", label_name(i + 3, true));
+ break;
default:
printerr("[%08x]", instrs[i]);
printf(" ; op%02x ", opc);
"jump" return TOKEN(T_OP_JUMP);
"waitin" return TOKEN(T_OP_WAITIN);
"preemptleave" return TOKEN(T_OP_PREEMPTLEAVE);
+"setsecure" return TOKEN(T_OP_SETSECURE);
"<<" return TOKEN(T_LSHIFT);
"(rep)" return TOKEN(T_REP);
%token <tok> T_OP_JUMP
%token <tok> T_OP_WAITIN
%token <tok> T_OP_PREEMPTLEAVE
+%token <tok> T_OP_SETSECURE
%token <tok> T_LSHIFT
%token <tok> T_REP
other_instr: T_OP_CALL T_LABEL_REF { new_instr($1); label($2); }
| T_OP_PREEMPTLEAVE T_LABEL_REF { new_instr($1); label($2); }
+| T_OP_SETSECURE reg ',' T_LABEL_REF { new_instr($1); src1($2); label($4); }
| T_OP_RET { new_instr($1); }
| T_OP_JUMP T_LABEL_REF { new_instr($1); label($2); }
| T_OP_WAITIN { new_instr($1); }