Mesa (master): freedreno/afuc: Handle setsecure opcode

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 18 16:27:31 UTC 2020


Module: Mesa
Branch: master
Commit: a2c14ac070b6703d3e395707ab7938aca4fe4fdb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a2c14ac070b6703d3e395707ab7938aca4fe4fdb

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Mon Aug 17 14:26:49 2020 +0200

freedreno/afuc: Handle setsecure opcode

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6368>

---

 src/freedreno/afuc/afuc.h   |  1 +
 src/freedreno/afuc/asm.c    | 11 +++++++++++
 src/freedreno/afuc/disasm.c | 16 ++++++++++++++++
 src/freedreno/afuc/lexer.l  |  1 +
 src/freedreno/afuc/parser.y |  2 ++
 5 files changed, 31 insertions(+)

diff --git a/src/freedreno/afuc/afuc.h b/src/freedreno/afuc/afuc.h
index 4f9e9d21815..a69690a56f2 100644
--- a/src/freedreno/afuc/afuc.h
+++ b/src/freedreno/afuc/afuc.h
@@ -109,6 +109,7 @@ typedef enum {
 	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;
 
 
diff --git a/src/freedreno/afuc/asm.c b/src/freedreno/afuc/asm.c
index 56036be46f6..896a8555cf3 100644
--- a/src/freedreno/afuc/asm.c
+++ b/src/freedreno/afuc/asm.c
@@ -262,6 +262,17 @@ static void emit_instructions(int outfd)
 			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;
diff --git a/src/freedreno/afuc/disasm.c b/src/freedreno/afuc/disasm.c
index d170b152fad..5c86f4327da 100644
--- a/src/freedreno/afuc/disasm.c
+++ b/src/freedreno/afuc/disasm.c
@@ -338,6 +338,10 @@ static void disasm(uint32_t *buf, int sizedwords)
 		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;
 		}
@@ -672,6 +676,18 @@ static void disasm(uint32_t *buf, int sizedwords)
 				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);
diff --git a/src/freedreno/afuc/lexer.l b/src/freedreno/afuc/lexer.l
index f78446011c2..077ae657d3c 100644
--- a/src/freedreno/afuc/lexer.l
+++ b/src/freedreno/afuc/lexer.l
@@ -82,6 +82,7 @@ extern YYSTYPE yylval;
 "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);
 
diff --git a/src/freedreno/afuc/parser.y b/src/freedreno/afuc/parser.y
index 5eb6e6a6a14..7b2eebd410a 100644
--- a/src/freedreno/afuc/parser.y
+++ b/src/freedreno/afuc/parser.y
@@ -157,6 +157,7 @@ label(const char *str)
 %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
 
@@ -245,6 +246,7 @@ branch_instr:      branch_op reg ',' T_BIT ',' T_LABEL_REF     { src1($2); bit($
 
 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); }



More information about the mesa-commit mailing list