target/mips: decode Octeon COP2 register selectors
Add explicit decodetree entries and translator bindings for Octeon DMFC2/DMTC2 selectors that are simple COP2 register transfers. Emit direct TCG loads and stores for register moves. Use signed 32-bit loads for 32-bit DMFC2 readback and mask narrow writable fields such as AESKEYLEN and CRCLEN on DMTC2. Keep operation selectors with side effects in later functional decode patches. Signed-off-by: James Hilliard <james.hilliard1@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-ID: <20260608-mips-octeon-missing-insns-v2-v16-14-daef7a0d8b04@gmail.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
James Hilliard committed
Jun 8, 2026 at 12:59 UTC
e32e36298e2645bf7c18efd9a031827681235030
3 files changed
+379
target/mips/tcg/octeon.decode
+80
@@ -97,3 +97,83 @@ LBUX 011111 ..... ..... ..... 00110 001010 @lx
97
LWUX 011111 ..... ..... ..... 10000 001010 @lx
98
LBX 011111 ..... ..... ..... 10110 001010 @lx
99
LDX 011111 ..... ..... ..... 01000 001010 @lx
100
+
101
+# Selector-driven DMFC2/DMTC2 interfaces for Octeon COP2 engines.
102
+&cp2 rt
103
+{
104
+ [
105
+ CVM_MF_HSH_IV0 010010 00001 rt:5 0000 0000 0100 1000 &cp2
106
+ CVM_MF_HSH_IV1 010010 00001 rt:5 0000 0000 0100 1001 &cp2
107
+ CVM_MF_HSH_IV2 010010 00001 rt:5 0000 0000 0100 1010 &cp2
108
+ CVM_MF_HSH_IV3 010010 00001 rt:5 0000 0000 0100 1011 &cp2
109
+ CVM_MF_HSH_DAT0 010010 00001 rt:5 0000 0000 0100 0000 &cp2
110
+ CVM_MF_HSH_DAT1 010010 00001 rt:5 0000 0000 0100 0001 &cp2
111
+ CVM_MF_HSH_DAT2 010010 00001 rt:5 0000 0000 0100 0010 &cp2
112
+ CVM_MF_HSH_DAT3 010010 00001 rt:5 0000 0000 0100 0011 &cp2
113
+ CVM_MF_HSH_DAT4 010010 00001 rt:5 0000 0000 0100 0100 &cp2
114
+ CVM_MF_HSH_DAT5 010010 00001 rt:5 0000 0000 0100 0101 &cp2
115
+ CVM_MF_HSH_DAT6 010010 00001 rt:5 0000 0000 0100 0110 &cp2
116
+ CVM_MF_3DES_KEY0 010010 00001 rt:5 0000 0000 1000 0000 &cp2
117
+ CVM_MF_3DES_KEY1 010010 00001 rt:5 0000 0000 1000 0001 &cp2
118
+ CVM_MF_3DES_KEY2 010010 00001 rt:5 0000 0000 1000 0010 &cp2
119
+ CVM_MF_3DES_IV 010010 00001 rt:5 0000 0000 1000 0100 &cp2
120
+ CVM_MF_3DES_RESULT 010010 00001 rt:5 0000 0000 1000 1000 &cp2
121
+ CVM_MF_KAS_RESULT 010010 00001 rt:5 0000 0000 1001 1000 &cp2
122
+ CVM_MF_AES_RESINP0 010010 00001 rt:5 0000 0001 0000 0000 &cp2
123
+ CVM_MF_AES_RESINP1 010010 00001 rt:5 0000 0001 0000 0001 &cp2
124
+ CVM_MF_AES_IV0 010010 00001 rt:5 0000 0001 0000 0010 &cp2
125
+ CVM_MF_AES_IV1 010010 00001 rt:5 0000 0001 0000 0011 &cp2
126
+ CVM_MF_AES_KEY0 010010 00001 rt:5 0000 0001 0000 0100 &cp2
127
+ CVM_MF_AES_KEY1 010010 00001 rt:5 0000 0001 0000 0101 &cp2
128
+ CVM_MF_AES_KEY2 010010 00001 rt:5 0000 0001 0000 0110 &cp2
129
+ CVM_MF_AES_KEY3 010010 00001 rt:5 0000 0001 0000 0111 &cp2
130
+ CVM_MF_AES_KEYLENGTH 010010 00001 rt:5 0000 0001 0001 0000 &cp2
131
+ CVM_MF_AES_INP0 010010 00001 rt:5 0000 0001 0001 0001 &cp2
132
+ CVM_MF_CRC_POLYNOMIAL 010010 00001 rt:5 0000 0010 0000 0000 &cp2
133
+ CVM_MF_CRC_IV 010010 00001 rt:5 0000 0010 0000 0001 &cp2
134
+ CVM_MF_CRC_LEN 010010 00001 rt:5 0000 0010 0000 0010 &cp2
135
+ CVM_MF_GFM_MUL0 010010 00001 rt:5 0000 0010 0101 1000 &cp2
136
+ CVM_MF_GFM_MUL1 010010 00001 rt:5 0000 0010 0101 1001 &cp2
137
+ CVM_MF_GFM_RESINP0 010010 00001 rt:5 0000 0010 0101 1010 &cp2
138
+ CVM_MF_GFM_RESINP1 010010 00001 rt:5 0000 0010 0101 1011 &cp2
139
+ CVM_MF_GFM_POLY 010010 00001 rt:5 0000 0010 0101 1110 &cp2
140
+ CVM_MT_HSH_DAT0 010010 00101 rt:5 0000 0000 0100 0000 &cp2
141
+ CVM_MT_HSH_DAT1 010010 00101 rt:5 0000 0000 0100 0001 &cp2
142
+ CVM_MT_HSH_DAT2 010010 00101 rt:5 0000 0000 0100 0010 &cp2
143
+ CVM_MT_HSH_DAT3 010010 00101 rt:5 0000 0000 0100 0011 &cp2
144
+ CVM_MT_HSH_DAT4 010010 00101 rt:5 0000 0000 0100 0100 &cp2
145
+ CVM_MT_HSH_DAT5 010010 00101 rt:5 0000 0000 0100 0101 &cp2
146
+ CVM_MT_HSH_DAT6 010010 00101 rt:5 0000 0000 0100 0110 &cp2
147
+ CVM_MT_HSH_IV0 010010 00101 rt:5 0000 0000 0100 1000 &cp2
148
+ CVM_MT_HSH_IV1 010010 00101 rt:5 0000 0000 0100 1001 &cp2
149
+ CVM_MT_HSH_IV2 010010 00101 rt:5 0000 0000 0100 1010 &cp2
150
+ CVM_MT_HSH_IV3 010010 00101 rt:5 0000 0000 0100 1011 &cp2
151
+ CVM_MT_3DES_KEY0 010010 00101 rt:5 0000 0000 1000 0000 &cp2
152
+ CVM_MT_3DES_KEY1 010010 00101 rt:5 0000 0000 1000 0001 &cp2
153
+ CVM_MT_3DES_KEY2 010010 00101 rt:5 0000 0000 1000 0010 &cp2
154
+ CVM_MT_3DES_IV 010010 00101 rt:5 0000 0000 1000 0100 &cp2
155
+ CVM_MT_3DES_RESULT 010010 00101 rt:5 0000 0000 1001 1000 &cp2
156
+ CVM_MT_AES_RESINP0 010010 00101 rt:5 0000 0001 0000 0000 &cp2
157
+ CVM_MT_AES_RESINP1 010010 00101 rt:5 0000 0001 0000 0001 &cp2
158
+ CVM_MT_AES_IV0 010010 00101 rt:5 0000 0001 0000 0010 &cp2
159
+ CVM_MT_AES_IV1 010010 00101 rt:5 0000 0001 0000 0011 &cp2
160
+ CVM_MT_AES_KEY0 010010 00101 rt:5 0000 0001 0000 0100 &cp2
161
+ CVM_MT_AES_KEY1 010010 00101 rt:5 0000 0001 0000 0101 &cp2
162
+ CVM_MT_AES_KEY2 010010 00101 rt:5 0000 0001 0000 0110 &cp2
163
+ CVM_MT_AES_KEY3 010010 00101 rt:5 0000 0001 0000 0111 &cp2
164
+ CVM_MT_AES_ENC_CBC0 010010 00101 rt:5 0000 0001 0000 1000 &cp2
165
+ CVM_MT_AES_ENC0 010010 00101 rt:5 0000 0001 0000 1010 &cp2
166
+ CVM_MT_AES_DEC_CBC0 010010 00101 rt:5 0000 0001 0000 1100 &cp2
167
+ CVM_MT_AES_DEC0 010010 00101 rt:5 0000 0001 0000 1110 &cp2
168
+ CVM_MT_AES_KEYLENGTH 010010 00101 rt:5 0000 0001 0001 0000 &cp2
169
+ CVM_MT_CRC_IV 010010 00101 rt:5 0000 0010 0000 0001 &cp2
170
+ CVM_MT_GFM_MUL0 010010 00101 rt:5 0000 0010 0101 1000 &cp2
171
+ CVM_MT_GFM_MUL1 010010 00101 rt:5 0000 0010 0101 1001 &cp2
172
+ CVM_MT_GFM_RESINP0 010010 00101 rt:5 0000 0010 0101 1010 &cp2
173
+ CVM_MT_GFM_RESINP1 010010 00101 rt:5 0000 0010 0101 1011 &cp2
174
+ CVM_MT_GFM_POLY 010010 00101 rt:5 0000 0010 0101 1110 &cp2
175
+ CVM_MT_CRC_LEN 010010 00101 rt:5 0001 0010 0000 0010 &cp2
176
+ CVM_MT_CRC_POLYNOMIAL 010010 00101 rt:5 0100 0010 0000 0000 &cp2
177
+ ]
178
+ CP2_Undef 010010 ----- ----- ---- ---- ---- ----
179
+}
target/mips/tcg/octeon_translate.c
+210
@@ -13,6 +13,216 @@
13
/* Include the auto-generated decoder. */
14
#include "decode-octeon.c.inc"
15
16
+#define OCTEON_CRYPTO_OFFSET(FIELD) \
17
+ offsetof(CPUMIPSState, octeon_crypto.FIELD)
18
+
19
+#define CP2_MF_I64(NAME, FIELD) \
20
+ TRANS(NAME, trans_octeon_cp2_mf_i64, OCTEON_CRYPTO_OFFSET(FIELD))
21
+#define CP2_MF_S32(NAME, FIELD) \
22
+ TRANS(NAME, trans_octeon_cp2_mf_s32, OCTEON_CRYPTO_OFFSET(FIELD))
23
+#define CP2_MF_U16(NAME, FIELD) \
24
+ TRANS(NAME, trans_octeon_cp2_mf_u16, OCTEON_CRYPTO_OFFSET(FIELD))
25
+#define CP2_MF_U8(NAME, FIELD) \
26
+ TRANS(NAME, trans_octeon_cp2_mf_u8, OCTEON_CRYPTO_OFFSET(FIELD))
27
+#define CP2_MF_HSH_PAIR(NAME, FIELD, INDEX) \
28
+ TRANS(NAME, trans_octeon_cp2_mf_hsh_pair, \
29
+ OCTEON_CRYPTO_OFFSET(FIELD[2 * (INDEX)]), \
30
+ OCTEON_CRYPTO_OFFSET(FIELD[2 * (INDEX) + 1]))
31
+#define CP2_MT_I64(NAME, FIELD) \
32
+ TRANS(NAME, trans_octeon_cp2_mt_i64, OCTEON_CRYPTO_OFFSET(FIELD))
33
+#define CP2_MT_U32(NAME, FIELD) \
34
+ TRANS(NAME, trans_octeon_cp2_mt_u32, OCTEON_CRYPTO_OFFSET(FIELD))
35
+#define CP2_MT_U16(NAME, FIELD) \
36
+ TRANS(NAME, trans_octeon_cp2_mt_u16, OCTEON_CRYPTO_OFFSET(FIELD))
37
+#define CP2_MT_U8_MASKED(NAME, FIELD, MASK) \
38
+ TRANS(NAME, trans_octeon_cp2_mt_u8_masked, \
39
+ OCTEON_CRYPTO_OFFSET(FIELD), MASK)
40
+#define CP2_MT_HSH_PAIR(NAME, FIELD, INDEX) \
41
+ TRANS(NAME, trans_octeon_cp2_mt_hsh_pair, \
42
+ OCTEON_CRYPTO_OFFSET(FIELD[2 * (INDEX)]), \
43
+ OCTEON_CRYPTO_OFFSET(FIELD[2 * (INDEX) + 1]))
44
+
45
+#define OCTEON_LO32_OFFSET (HOST_BIG_ENDIAN ? 4 : 0)
46
+
47
+static bool trans_CP2_Undef(DisasContext *ctx, arg_CP2_Undef *a)
48
+{
49
+ generate_exception_err(ctx, EXCP_CpU, 2);
50
+ return true;
51
+}
52
+
53
+static bool trans_octeon_cp2_mf_i64(DisasContext *ctx, arg_cp2 *a, int offset)
54
+{
55
+ TCGv_i64 value = tcg_temp_new_i64();
56
+
57
+ tcg_gen_ld_i64(value, tcg_env, offset);
58
+ gen_store_gpr(value, a->rt);
59
+ return true;
60
+}
61
+
62
+static bool trans_octeon_cp2_mf_s32(DisasContext *ctx, arg_cp2 *a, int offset)
63
+{
64
+ TCGv_i64 value = tcg_temp_new_i64();
65
+
66
+ tcg_gen_ld32s_i64(value, tcg_env, offset);
67
+ gen_store_gpr(value, a->rt);
68
+ return true;
69
+}
70
+
71
+static bool trans_octeon_cp2_mf_u16(DisasContext *ctx, arg_cp2 *a, int offset)
72
+{
73
+ TCGv_i64 value = tcg_temp_new_i64();
74
+
75
+ tcg_gen_ld16u_i64(value, tcg_env, offset);
76
+ gen_store_gpr(value, a->rt);
77
+ return true;
78
+}
79
+
80
+static bool trans_octeon_cp2_mf_u8(DisasContext *ctx, arg_cp2 *a, int offset)
81
+{
82
+ TCGv_i64 value = tcg_temp_new_i64();
83
+
84
+ tcg_gen_ld8u_i64(value, tcg_env, offset);
85
+ gen_store_gpr(value, a->rt);
86
+ return true;
87
+}
88
+
89
+static bool trans_octeon_cp2_mf_hsh_pair(DisasContext *ctx, arg_cp2 *a,
90
+ int hi_offset, int lo_offset)
91
+{
92
+ TCGv_i64 hi = tcg_temp_new_i64();
93
+ TCGv_i64 lo = tcg_temp_new_i64();
94
+
95
+ tcg_gen_ld_i64(hi, tcg_env, hi_offset);
96
+ tcg_gen_ld_i64(lo, tcg_env, lo_offset);
97
+ tcg_gen_concat32_i64(lo, lo, hi);
98
+ gen_store_gpr(lo, a->rt);
99
+ return true;
100
+}
101
+
102
+static bool trans_octeon_cp2_mt_i64(DisasContext *ctx, arg_cp2 *a, int offset)
103
+{
104
+ TCGv_i64 value = tcg_temp_new_i64();
105
+
106
+ gen_load_gpr(value, a->rt);
107
+ tcg_gen_st_i64(value, tcg_env, offset);
108
+ return true;
109
+}
110
+
111
+static bool trans_octeon_cp2_mt_u32(DisasContext *ctx, arg_cp2 *a, int offset)
112
+{
113
+ TCGv_i64 value = tcg_temp_new_i64();
114
+
115
+ gen_load_gpr(value, a->rt);
116
+ tcg_gen_st32_i64(value, tcg_env, offset);
117
+ return true;
118
+}
119
+
120
+static bool trans_octeon_cp2_mt_u16(DisasContext *ctx, arg_cp2 *a, int offset)
121
+{
122
+ TCGv_i64 value = tcg_temp_new_i64();
123
+
124
+ gen_load_gpr(value, a->rt);
125
+ tcg_gen_st16_i64(value, tcg_env, offset);
126
+ return true;
127
+}
128
+
129
+static bool trans_octeon_cp2_mt_u8_masked(DisasContext *ctx, arg_cp2 *a,
130
+ int offset, uint8_t mask)
131
+{
132
+ TCGv_i64 value = tcg_temp_new_i64();
133
+
134
+ gen_load_gpr(value, a->rt);
135
+ tcg_gen_andi_i64(value, value, mask);
136
+ tcg_gen_st8_i64(value, tcg_env, offset);
137
+ return true;
138
+}
139
+
140
+static bool trans_octeon_cp2_mt_hsh_pair(DisasContext *ctx, arg_cp2 *a,
141
+ int hi_offset, int lo_offset)
142
+{
143
+ TCGv_i64 value = tcg_temp_new_i64();
144
+
145
+ gen_load_gpr(value, a->rt);
146
+ tcg_gen_st32_i64(value, tcg_env, lo_offset + OCTEON_LO32_OFFSET);
147
+ tcg_gen_shri_i64(value, value, 32);
148
+ tcg_gen_st32_i64(value, tcg_env, hi_offset + OCTEON_LO32_OFFSET);
149
+ return true;
150
+}
151
+
152
+CP2_MF_HSH_PAIR(CVM_MF_HSH_DAT0, hsh_dat, 0);
153
+CP2_MF_HSH_PAIR(CVM_MF_HSH_DAT1, hsh_dat, 1);
154
+CP2_MF_HSH_PAIR(CVM_MF_HSH_DAT2, hsh_dat, 2);
155
+CP2_MF_HSH_PAIR(CVM_MF_HSH_DAT3, hsh_dat, 3);
156
+CP2_MF_HSH_PAIR(CVM_MF_HSH_DAT4, hsh_dat, 4);
157
+CP2_MF_HSH_PAIR(CVM_MF_HSH_DAT5, hsh_dat, 5);
158
+CP2_MF_HSH_PAIR(CVM_MF_HSH_DAT6, hsh_dat, 6);
159
+CP2_MF_HSH_PAIR(CVM_MF_HSH_IV0, hsh_iv, 0);
160
+CP2_MF_HSH_PAIR(CVM_MF_HSH_IV1, hsh_iv, 1);
161
+CP2_MF_HSH_PAIR(CVM_MF_HSH_IV2, hsh_iv, 2);
162
+CP2_MF_HSH_PAIR(CVM_MF_HSH_IV3, hsh_iv, 3);
163
+CP2_MF_I64(CVM_MF_3DES_KEY0, des3_key[0]);
164
+CP2_MF_I64(CVM_MF_3DES_KEY1, des3_key[1]);
165
+CP2_MF_I64(CVM_MF_3DES_KEY2, des3_key[2]);
166
+CP2_MF_I64(CVM_MF_3DES_IV, des3_iv);
167
+CP2_MF_I64(CVM_MF_3DES_RESULT, des3_result);
168
+CP2_MF_I64(CVM_MF_KAS_RESULT, des3_result);
169
+CP2_MF_I64(CVM_MF_AES_RESINP0, aes_resinp[0]);
170
+CP2_MF_I64(CVM_MF_AES_RESINP1, aes_resinp[1]);
171
+CP2_MF_I64(CVM_MF_AES_IV0, aes_iv[0]);
172
+CP2_MF_I64(CVM_MF_AES_IV1, aes_iv[1]);
173
+CP2_MF_I64(CVM_MF_AES_KEY0, aes_key[0]);
174
+CP2_MF_I64(CVM_MF_AES_KEY1, aes_key[1]);
175
+CP2_MF_I64(CVM_MF_AES_KEY2, aes_key[2]);
176
+CP2_MF_I64(CVM_MF_AES_KEY3, aes_key[3]);
177
+CP2_MF_U8(CVM_MF_AES_KEYLENGTH, aes_keylen);
178
+CP2_MF_I64(CVM_MF_AES_INP0, aes_resinp[0]);
179
+CP2_MF_S32(CVM_MF_CRC_POLYNOMIAL, crc_poly);
180
+CP2_MF_S32(CVM_MF_CRC_IV, crc_iv);
181
+CP2_MF_U8(CVM_MF_CRC_LEN, crc_len);
182
+CP2_MF_I64(CVM_MF_GFM_MUL0, gfm_mul[0]);
183
+CP2_MF_I64(CVM_MF_GFM_MUL1, gfm_mul[1]);
184
+CP2_MF_I64(CVM_MF_GFM_RESINP0, gfm_resinp[0]);
185
+CP2_MF_I64(CVM_MF_GFM_RESINP1, gfm_resinp[1]);
186
+CP2_MF_U16(CVM_MF_GFM_POLY, gfm_poly);
187
+
188
+CP2_MT_HSH_PAIR(CVM_MT_HSH_DAT0, hsh_dat, 0);
189
+CP2_MT_HSH_PAIR(CVM_MT_HSH_DAT1, hsh_dat, 1);
190
+CP2_MT_HSH_PAIR(CVM_MT_HSH_DAT2, hsh_dat, 2);
191
+CP2_MT_HSH_PAIR(CVM_MT_HSH_DAT3, hsh_dat, 3);
192
+CP2_MT_HSH_PAIR(CVM_MT_HSH_DAT4, hsh_dat, 4);
193
+CP2_MT_HSH_PAIR(CVM_MT_HSH_DAT5, hsh_dat, 5);
194
+CP2_MT_HSH_PAIR(CVM_MT_HSH_DAT6, hsh_dat, 6);
195
+CP2_MT_HSH_PAIR(CVM_MT_HSH_IV0, hsh_iv, 0);
196
+CP2_MT_HSH_PAIR(CVM_MT_HSH_IV1, hsh_iv, 1);
197
+CP2_MT_HSH_PAIR(CVM_MT_HSH_IV2, hsh_iv, 2);
198
+CP2_MT_HSH_PAIR(CVM_MT_HSH_IV3, hsh_iv, 3);
199
+CP2_MT_I64(CVM_MT_3DES_KEY0, des3_key[0]);
200
+CP2_MT_I64(CVM_MT_3DES_KEY1, des3_key[1]);
201
+CP2_MT_I64(CVM_MT_3DES_KEY2, des3_key[2]);
202
+CP2_MT_I64(CVM_MT_3DES_IV, des3_iv);
203
+CP2_MT_I64(CVM_MT_3DES_RESULT, des3_result);
204
+CP2_MT_I64(CVM_MT_AES_RESINP0, aes_resinp[0]);
205
+CP2_MT_I64(CVM_MT_AES_RESINP1, aes_resinp[1]);
206
+CP2_MT_I64(CVM_MT_AES_IV0, aes_iv[0]);
207
+CP2_MT_I64(CVM_MT_AES_IV1, aes_iv[1]);
208
+CP2_MT_I64(CVM_MT_AES_KEY0, aes_key[0]);
209
+CP2_MT_I64(CVM_MT_AES_KEY1, aes_key[1]);
210
+CP2_MT_I64(CVM_MT_AES_KEY2, aes_key[2]);
211
+CP2_MT_I64(CVM_MT_AES_KEY3, aes_key[3]);
212
+CP2_MT_I64(CVM_MT_AES_ENC_CBC0, aes_resinp[0]);
213
+CP2_MT_I64(CVM_MT_AES_ENC0, aes_resinp[0]);
214
+CP2_MT_I64(CVM_MT_AES_DEC_CBC0, aes_resinp[0]);
215
+CP2_MT_I64(CVM_MT_AES_DEC0, aes_resinp[0]);
216
+CP2_MT_U8_MASKED(CVM_MT_AES_KEYLENGTH, aes_keylen, 3);
217
+CP2_MT_U32(CVM_MT_CRC_IV, crc_iv);
218
+CP2_MT_I64(CVM_MT_GFM_MUL0, gfm_mul[0]);
219
+CP2_MT_I64(CVM_MT_GFM_MUL1, gfm_mul[1]);
220
+CP2_MT_I64(CVM_MT_GFM_RESINP0, gfm_resinp[0]);
221
+CP2_MT_I64(CVM_MT_GFM_RESINP1, gfm_resinp[1]);
222
+CP2_MT_U16(CVM_MT_GFM_POLY, gfm_poly);
223
+CP2_MT_U8_MASKED(CVM_MT_CRC_LEN, crc_len, 0xf);
224
+CP2_MT_U32(CVM_MT_CRC_POLYNOMIAL, crc_poly);
225
+
226
static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a)
227
{
228
TCGv_i64 p;
tests/tcg/mips/user/isa/octeon/octeon-insns.c
+89
@@ -186,6 +186,86 @@ static uint64_t octeon_mtp0_zeroes_p1(void)
186
return rd;
187
}
188
189
+static uint64_t octeon_cop2_key0_readback(uint64_t value)
190
+{
191
+ uint64_t rd;
192
+
193
+ asm volatile(
194
+ "move $8, %[value]\n\t"
195
+ ".word 0x48a80104\n\t" /* dmtc2 $8, AES_KEY0 selector */
196
+ ".word 0x482a0104\n\t" /* dmfc2 $10, AES_KEY0 selector */
197
+ "move %[rd], $10\n\t"
198
+ : [rd] "=r" (rd)
199
+ : [value] "r" (value)
200
+ : "$8", "$10");
201
+
202
+ return rd;
203
+}
204
+
205
+static uint64_t octeon_cop2_key2_readback(uint64_t value)
206
+{
207
+ uint64_t rd;
208
+
209
+ asm volatile(
210
+ "move $8, %[value]\n\t"
211
+ ".word 0x48a80106\n\t" /* dmtc2 $8, AES_KEY2 selector */
212
+ ".word 0x482a0106\n\t" /* dmfc2 $10, AES_KEY2 selector */
213
+ "move %[rd], $10\n\t"
214
+ : [rd] "=r" (rd)
215
+ : [value] "r" (value)
216
+ : "$8", "$10");
217
+
218
+ return rd;
219
+}
220
+
221
+static uint64_t octeon_cop2_key3_readback(uint64_t value)
222
+{
223
+ uint64_t rd;
224
+
225
+ asm volatile(
226
+ "move $8, %[value]\n\t"
227
+ ".word 0x48a80107\n\t" /* dmtc2 $8, AES_KEY3 selector */
228
+ ".word 0x482a0107\n\t" /* dmfc2 $10, AES_KEY3 selector */
229
+ "move %[rd], $10\n\t"
230
+ : [rd] "=r" (rd)
231
+ : [value] "r" (value)
232
+ : "$8", "$10");
233
+
234
+ return rd;
235
+}
236
+
237
+static uint64_t octeon_cop2_keylength_readback(uint64_t value)
238
+{
239
+ uint64_t rd;
240
+
241
+ asm volatile(
242
+ "move $8, %[value]\n\t"
243
+ ".word 0x48a80110\n\t" /* dmtc2 $8, AES_KEYLENGTH selector */
244
+ ".word 0x482a0110\n\t" /* dmfc2 $10, AES_KEYLENGTH selector */
245
+ "move %[rd], $10\n\t"
246
+ : [rd] "=r" (rd)
247
+ : [value] "r" (value)
248
+ : "$8", "$10");
249
+
250
+ return rd;
251
+}
252
+
253
+static uint64_t octeon_cop2_hsh_dat0_readback(uint64_t value)
254
+{
255
+ uint64_t rd;
256
+
257
+ asm volatile(
258
+ "move $8, %[value]\n\t"
259
+ ".word 0x48a80040\n\t" /* dmtc2 $8, HSH_DAT0 selector */
260
+ ".word 0x482a0040\n\t" /* dmfc2 $10, HSH_DAT0 selector */
261
+ "move %[rd], $10\n\t"
262
+ : [rd] "=r" (rd)
263
+ : [value] "r" (value)
264
+ : "$8", "$10");
265
+
266
+ return rd;
267
+}
268
+
269
int main(void)
270
{
271
assert(octeon_baddu(0x123, 0x0f0) == 0x13);
@@ -199,6 +279,15 @@ int main(void)
279
assert(octeon_vmm0(5, 13, 7, 11) == 59);
280
assert(octeon_vmm0_zeroes_mpl1() == 0);
281
assert(octeon_mtp0_zeroes_p1() == 0);
282
+ assert(octeon_cop2_key0_readback(0x1122334455667788ULL) ==
283
+ 0x1122334455667788ULL);
284
+ assert(octeon_cop2_key2_readback(0x8877665544332211ULL) ==
285
+ 0x8877665544332211ULL);
286
+ assert(octeon_cop2_key3_readback(0x0102030405060708ULL) ==
287
+ 0x0102030405060708ULL);
288
+ assert(octeon_cop2_keylength_readback(0xa5) == 1);
289
+ assert(octeon_cop2_hsh_dat0_readback(0x0102030405060708ULL) ==
290
+ 0x0102030405060708ULL);
291
292
return 0;
293
}