@samitouri / QOSamiQemu / commits / e32e36298e

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 }