Decode the Octeon COP2 DMFC2/DMTC2 selectors that map directly to architectural COP2 state. These selectors only move values between guest GPRs and Octeon COP2 registers, so emit direct TCG loads and stores instead of routing through a generic selector helper.
Add the common CP2 translator plumbing with the direct register-transfer selectors. Use signed 32-bit DMFC2 readback for the CRC registers to match MIPS register-move semantics, and keep AESRESINP as a single architectural register bank for direct transfers. Signed-off-by: James Hilliard <[email protected]> --- target/mips/helper.h | 1 + target/mips/tcg/octeon.decode | 79 ++++++++++++++ target/mips/tcg/octeon_translate.c | 210 +++++++++++++++++++++++++++++++++++++ 3 files changed, 290 insertions(+) diff --git a/target/mips/helper.h b/target/mips/helper.h index 68a99cfc11..42766ed0d2 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -147,6 +147,7 @@ DEF_HELPER_2(octeon_cp2_mt_llm_write_addr1, void, env, i64) DEF_HELPER_2(octeon_cp2_mt_llm_read64_addr1, void, env, i64) DEF_HELPER_2(octeon_cp2_mt_llm_write64_addr1, void, env, i64) + /* microMIPS functions */ DEF_HELPER_4(lwm, void, env, tl, tl, i32) DEF_HELPER_4(swm, void, env, tl, tl, i32) diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode index 1e44c588dd..01fdbfec7a 100644 --- a/target/mips/tcg/octeon.decode +++ b/target/mips/tcg/octeon.decode @@ -97,3 +97,82 @@ LBUX 011111 ..... ..... ..... 00110 001010 @lx LWUX 011111 ..... ..... ..... 10000 001010 @lx LBX 011111 ..... ..... ..... 10110 001010 @lx LDX 011111 ..... ..... ..... 01000 001010 @lx + +# Selector-driven DMFC2/DMTC2 interfaces for Octeon COP2 engines. +&cp2 rt +{ + [ + CVM_MF_HSH_IV0 010010 00001 rt:5 0000 0000 0100 1000 &cp2 + CVM_MF_HSH_IV1 010010 00001 rt:5 0000 0000 0100 1001 &cp2 + CVM_MF_HSH_IV2 010010 00001 rt:5 0000 0000 0100 1010 &cp2 + CVM_MF_HSH_IV3 010010 00001 rt:5 0000 0000 0100 1011 &cp2 + CVM_MF_GFM_MUL_REFLECT0 010010 00001 rt:5 0000 0000 0101 1000 &cp2 + CVM_MF_GFM_MUL_REFLECT1 010010 00001 rt:5 0000 0000 0101 1001 &cp2 + CVM_MF_GFM_RESINP_REFLECT0 010010 00001 rt:5 0000 0000 0101 1010 &cp2 + CVM_MF_GFM_RESINP_REFLECT1 010010 00001 rt:5 0000 0000 0101 1011 &cp2 + CVM_MF_3DES_KEY0 010010 00001 rt:5 0000 0000 1000 0000 &cp2 + CVM_MF_3DES_KEY1 010010 00001 rt:5 0000 0000 1000 0001 &cp2 + CVM_MF_3DES_KEY2 010010 00001 rt:5 0000 0000 1000 0010 &cp2 + CVM_MF_3DES_IV 010010 00001 rt:5 0000 0000 1000 0100 &cp2 + CVM_MF_3DES_RESULT 010010 00001 rt:5 0000 0000 1000 1000 &cp2 + CVM_MF_3DES_RESULT_MT 010010 00001 rt:5 0000 0000 1001 1000 &cp2 + CVM_MF_AES_RESINP0 010010 00001 rt:5 0000 0001 0000 0000 &cp2 + CVM_MF_AES_RESINP1 010010 00001 rt:5 0000 0001 0000 0001 &cp2 + CVM_MF_AES_IV0 010010 00001 rt:5 0000 0001 0000 0010 &cp2 + CVM_MF_AES_IV1 010010 00001 rt:5 0000 0001 0000 0011 &cp2 + CVM_MF_AES_KEY0 010010 00001 rt:5 0000 0001 0000 0100 &cp2 + CVM_MF_AES_KEY1 010010 00001 rt:5 0000 0001 0000 0101 &cp2 + CVM_MF_AES_KEY2 010010 00001 rt:5 0000 0001 0000 0110 &cp2 + CVM_MF_AES_KEY3 010010 00001 rt:5 0000 0001 0000 0111 &cp2 + CVM_MF_AES_KEYLENGTH 010010 00001 rt:5 0000 0001 0001 0000 &cp2 + CVM_MF_AES_INP0 010010 00001 rt:5 0000 0001 0001 0001 &cp2 + CVM_MF_CRC_POLYNOMIAL 010010 00001 rt:5 0000 0010 0000 0000 &cp2 + CVM_MF_CRC_IV 010010 00001 rt:5 0000 0010 0000 0001 &cp2 + CVM_MF_CRC_LEN 010010 00001 rt:5 0000 0010 0000 0010 &cp2 + CVM_MF_GFM_MUL0 010010 00001 rt:5 0000 0010 0101 1000 &cp2 + CVM_MF_GFM_MUL1 010010 00001 rt:5 0000 0010 0101 1001 &cp2 + CVM_MF_GFM_RESINP0 010010 00001 rt:5 0000 0010 0101 1010 &cp2 + CVM_MF_GFM_RESINP1 010010 00001 rt:5 0000 0010 0101 1011 &cp2 + CVM_MF_GFM_POLY 010010 00001 rt:5 0000 0010 0101 1110 &cp2 + CVM_MT_HSH_DAT0 010010 00101 rt:5 0000 0000 0100 0000 &cp2 + CVM_MT_HSH_DAT1 010010 00101 rt:5 0000 0000 0100 0001 &cp2 + CVM_MT_HSH_DAT2 010010 00101 rt:5 0000 0000 0100 0010 &cp2 + CVM_MT_HSH_DAT3 010010 00101 rt:5 0000 0000 0100 0011 &cp2 + CVM_MT_HSH_DAT4 010010 00101 rt:5 0000 0000 0100 0100 &cp2 + CVM_MT_HSH_DAT5 010010 00101 rt:5 0000 0000 0100 0101 &cp2 + CVM_MT_HSH_DAT6 010010 00101 rt:5 0000 0000 0100 0110 &cp2 + CVM_MT_HSH_IV0 010010 00101 rt:5 0000 0000 0100 1000 &cp2 + CVM_MT_HSH_IV1 010010 00101 rt:5 0000 0000 0100 1001 &cp2 + CVM_MT_HSH_IV2 010010 00101 rt:5 0000 0000 0100 1010 &cp2 + CVM_MT_HSH_IV3 010010 00101 rt:5 0000 0000 0100 1011 &cp2 + CVM_MT_GFM_MUL_REFLECT0 010010 00101 rt:5 0000 0000 0101 1000 &cp2 + CVM_MT_GFM_MUL_REFLECT1 010010 00101 rt:5 0000 0000 0101 1001 &cp2 + CVM_MT_3DES_KEY0 010010 00101 rt:5 0000 0000 1000 0000 &cp2 + CVM_MT_3DES_KEY1 010010 00101 rt:5 0000 0000 1000 0001 &cp2 + CVM_MT_3DES_KEY2 010010 00101 rt:5 0000 0000 1000 0010 &cp2 + CVM_MT_3DES_IV 010010 00101 rt:5 0000 0000 1000 0100 &cp2 + CVM_MT_3DES_RESULT 010010 00101 rt:5 0000 0000 1001 1000 &cp2 + CVM_MT_AES_RESINP0 010010 00101 rt:5 0000 0001 0000 0000 &cp2 + CVM_MT_AES_RESINP1 010010 00101 rt:5 0000 0001 0000 0001 &cp2 + CVM_MT_AES_IV0 010010 00101 rt:5 0000 0001 0000 0010 &cp2 + CVM_MT_AES_IV1 010010 00101 rt:5 0000 0001 0000 0011 &cp2 + CVM_MT_AES_KEY0 010010 00101 rt:5 0000 0001 0000 0100 &cp2 + CVM_MT_AES_KEY1 010010 00101 rt:5 0000 0001 0000 0101 &cp2 + CVM_MT_AES_KEY2 010010 00101 rt:5 0000 0001 0000 0110 &cp2 + CVM_MT_AES_KEY3 010010 00101 rt:5 0000 0001 0000 0111 &cp2 + CVM_MT_AES_ENC_CBC0 010010 00101 rt:5 0000 0001 0000 1000 &cp2 + CVM_MT_AES_ENC0 010010 00101 rt:5 0000 0001 0000 1010 &cp2 + CVM_MT_AES_DEC_CBC0 010010 00101 rt:5 0000 0001 0000 1100 &cp2 + CVM_MT_AES_DEC0 010010 00101 rt:5 0000 0001 0000 1110 &cp2 + CVM_MT_AES_KEYLENGTH 010010 00101 rt:5 0000 0001 0001 0000 &cp2 + CVM_MT_CRC_IV 010010 00101 rt:5 0000 0010 0000 0001 &cp2 + CVM_MT_GFM_MUL0 010010 00101 rt:5 0000 0010 0101 1000 &cp2 + CVM_MT_GFM_MUL1 010010 00101 rt:5 0000 0010 0101 1001 &cp2 + CVM_MT_GFM_RESINP0 010010 00101 rt:5 0000 0010 0101 1010 &cp2 + CVM_MT_GFM_RESINP1 010010 00101 rt:5 0000 0010 0101 1011 &cp2 + CVM_MT_GFM_POLY 010010 00101 rt:5 0000 0010 0101 1110 &cp2 + CVM_MT_CRC_WRITE_LEN 010010 00101 rt:5 0001 0010 0000 0010 &cp2 + CVM_MT_CRC_WRITE_POLYNOMIAL 010010 00101 rt:5 0100 0010 0000 0000 &cp2 + CVM_MT_CRC_WRITE_POLYNOMIAL_REFLECT 010010 00101 rt:5 0100 0010 0001 0000 &cp2 + ] +} diff --git a/target/mips/tcg/octeon_translate.c b/target/mips/tcg/octeon_translate.c index 55cefe0903..7a670053c6 100644 --- a/target/mips/tcg/octeon_translate.c +++ b/target/mips/tcg/octeon_translate.c @@ -13,6 +13,216 @@ /* Include the auto-generated decoder. */ #include "decode-octeon.c.inc" +#define OCTEON_CRYPTO_OFFSET(FIELD) \ + offsetof(CPUMIPSState, octeon_crypto.FIELD) + +#define CP2_MF_I64(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mf_i64, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MF_S32(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mf_s32, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MF_U16(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mf_u16, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MF_U8(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mf_u8, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MF_HELPER(NAME, SUFFIX) \ + TRANS(NAME, trans_octeon_cp2_mf_helper, \ + gen_helper_octeon_cp2_mf_ ## SUFFIX) +#define CP2_MT_I64(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mt_i64, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MT_U32(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mt_u32, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MT_U16(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mt_u16, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MT_U8(NAME, FIELD) \ + TRANS(NAME, trans_octeon_cp2_mt_u8, OCTEON_CRYPTO_OFFSET(FIELD)) +#define CP2_MT_HELPER(NAME, SUFFIX) \ + TRANS(NAME, trans_octeon_cp2_mt_helper, \ + gen_helper_octeon_cp2_mt_ ## SUFFIX) + +static bool trans_CP2_Undef(DisasContext *ctx, arg_CP2_Undef *a) +{ + generate_exception_err(ctx, EXCP_CpU, 2); + return true; +} + +static bool trans_octeon_cp2_mf_i64(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + tcg_gen_ld_i64(value, tcg_env, offset); + gen_store_gpr(value, a->rt); + return true; +} + +static bool trans_octeon_cp2_mf_s32(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + tcg_gen_ld32s_i64(value, tcg_env, offset); + gen_store_gpr(value, a->rt); + return true; +} + +static bool trans_octeon_cp2_mf_u16(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + tcg_gen_ld16u_i64(value, tcg_env, offset); + gen_store_gpr(value, a->rt); + return true; +} + +static bool trans_octeon_cp2_mf_u8(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + tcg_gen_ld8u_i64(value, tcg_env, offset); + gen_store_gpr(value, a->rt); + return true; +} + +static bool trans_octeon_cp2_mf_helper(DisasContext *ctx, arg_cp2 *a, + void (*gen_helper)(TCGv_i64, TCGv_env)) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + gen_helper(value, tcg_env); + gen_store_gpr(value, a->rt); + return true; +} + +static bool trans_octeon_cp2_mt_i64(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + gen_load_gpr(value, a->rt); + tcg_gen_st_i64(value, tcg_env, offset); + return true; +} + +static bool trans_octeon_cp2_mt_u32(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + gen_load_gpr(value, a->rt); + tcg_gen_st32_i64(value, tcg_env, offset); + return true; +} + +static bool trans_octeon_cp2_mt_u16(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + gen_load_gpr(value, a->rt); + tcg_gen_st16_i64(value, tcg_env, offset); + return true; +} + +static bool trans_octeon_cp2_mt_u8(DisasContext *ctx, arg_cp2 *a, int offset) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + gen_load_gpr(value, a->rt); + tcg_gen_st8_i64(value, tcg_env, offset); + return true; +} + +static bool trans_octeon_cp2_mt_resinp(DisasContext *ctx, arg_cp2 *a, + unsigned int index) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + gen_load_gpr(value, a->rt); + tcg_gen_st_i64(value, tcg_env, + OCTEON_CRYPTO_OFFSET(aes_resinp[index])); + return true; +} + +static bool trans_octeon_cp2_mt_helper(DisasContext *ctx, arg_cp2 *a, + void (*gen_helper)(TCGv_env, TCGv_i64)) +{ + TCGv_i64 value = tcg_temp_new_i64(); + + gen_load_gpr(value, a->rt); + gen_helper(tcg_env, value); + return true; +} + +CP2_MF_I64(CVM_MF_HSH_IV0, hsh_iv[0]); +CP2_MF_I64(CVM_MF_HSH_IV1, hsh_iv[1]); +CP2_MF_I64(CVM_MF_HSH_IV2, hsh_iv[2]); +CP2_MF_I64(CVM_MF_HSH_IV3, hsh_iv[3]); +CP2_MF_I64(CVM_MF_GFM_MUL_REFLECT0, gfm_reflect_mul[0]); +CP2_MF_I64(CVM_MF_GFM_MUL_REFLECT1, gfm_reflect_mul[1]); +CP2_MF_I64(CVM_MF_GFM_RESINP_REFLECT0, gfm_reflect_resinp[0]); +CP2_MF_I64(CVM_MF_GFM_RESINP_REFLECT1, gfm_reflect_resinp[1]); +CP2_MF_I64(CVM_MF_3DES_KEY0, des3_key[0]); +CP2_MF_I64(CVM_MF_3DES_KEY1, des3_key[1]); +CP2_MF_I64(CVM_MF_3DES_KEY2, des3_key[2]); +CP2_MF_I64(CVM_MF_3DES_IV, des3_iv); +CP2_MF_I64(CVM_MF_3DES_RESULT, des3_result); +CP2_MF_I64(CVM_MF_3DES_RESULT_MT, des3_result); +CP2_MF_I64(CVM_MF_AES_RESINP0, aes_resinp[0]); +CP2_MF_I64(CVM_MF_AES_RESINP1, aes_resinp[1]); +CP2_MF_I64(CVM_MF_AES_IV0, aes_iv[0]); +CP2_MF_I64(CVM_MF_AES_IV1, aes_iv[1]); +CP2_MF_I64(CVM_MF_AES_KEY0, aes_key[0]); +CP2_MF_I64(CVM_MF_AES_KEY1, aes_key[1]); +CP2_MF_I64(CVM_MF_AES_KEY2, aes_key[2]); +CP2_MF_I64(CVM_MF_AES_KEY3, aes_key[3]); +CP2_MF_U8(CVM_MF_AES_KEYLENGTH, aes_keylen); +CP2_MF_I64(CVM_MF_AES_INP0, aes_resinp[0]); +CP2_MF_S32(CVM_MF_CRC_POLYNOMIAL, crc_poly); +CP2_MF_S32(CVM_MF_CRC_IV, crc_iv); +CP2_MF_U8(CVM_MF_CRC_LEN, crc_len); +CP2_MF_I64(CVM_MF_GFM_MUL0, gfm_mul[0]); +CP2_MF_I64(CVM_MF_GFM_MUL1, gfm_mul[1]); +CP2_MF_I64(CVM_MF_GFM_RESINP0, gfm_resinp[0]); +CP2_MF_I64(CVM_MF_GFM_RESINP1, gfm_resinp[1]); +CP2_MF_U16(CVM_MF_GFM_POLY, gfm_poly); + + +CP2_MT_I64(CVM_MT_HSH_DAT0, hsh_dat[0]); +CP2_MT_I64(CVM_MT_HSH_DAT1, hsh_dat[1]); +CP2_MT_I64(CVM_MT_HSH_DAT2, hsh_dat[2]); +CP2_MT_I64(CVM_MT_HSH_DAT3, hsh_dat[3]); +CP2_MT_I64(CVM_MT_HSH_DAT4, hsh_dat[4]); +CP2_MT_I64(CVM_MT_HSH_DAT5, hsh_dat[5]); +CP2_MT_I64(CVM_MT_HSH_DAT6, hsh_dat[6]); +CP2_MT_I64(CVM_MT_HSH_IV0, hsh_iv[0]); +CP2_MT_I64(CVM_MT_HSH_IV1, hsh_iv[1]); +CP2_MT_I64(CVM_MT_HSH_IV2, hsh_iv[2]); +CP2_MT_I64(CVM_MT_HSH_IV3, hsh_iv[3]); +CP2_MT_I64(CVM_MT_GFM_MUL_REFLECT0, gfm_reflect_mul[0]); +CP2_MT_I64(CVM_MT_GFM_MUL_REFLECT1, gfm_reflect_mul[1]); +CP2_MT_I64(CVM_MT_3DES_KEY0, des3_key[0]); +CP2_MT_I64(CVM_MT_3DES_KEY1, des3_key[1]); +CP2_MT_I64(CVM_MT_3DES_KEY2, des3_key[2]); +CP2_MT_I64(CVM_MT_3DES_IV, des3_iv); +CP2_MT_I64(CVM_MT_3DES_RESULT, des3_result); +TRANS(CVM_MT_AES_RESINP0, trans_octeon_cp2_mt_resinp, 0); +TRANS(CVM_MT_AES_RESINP1, trans_octeon_cp2_mt_resinp, 1); +CP2_MT_I64(CVM_MT_AES_IV0, aes_iv[0]); +CP2_MT_I64(CVM_MT_AES_IV1, aes_iv[1]); +CP2_MT_I64(CVM_MT_AES_KEY0, aes_key[0]); +CP2_MT_I64(CVM_MT_AES_KEY1, aes_key[1]); +CP2_MT_I64(CVM_MT_AES_KEY2, aes_key[2]); +CP2_MT_I64(CVM_MT_AES_KEY3, aes_key[3]); +CP2_MT_I64(CVM_MT_AES_ENC_CBC0, aes_resinp[0]); +CP2_MT_I64(CVM_MT_AES_ENC0, aes_resinp[0]); +CP2_MT_I64(CVM_MT_AES_DEC_CBC0, aes_resinp[0]); +CP2_MT_I64(CVM_MT_AES_DEC0, aes_resinp[0]); +CP2_MT_U8(CVM_MT_AES_KEYLENGTH, aes_keylen); +CP2_MT_U32(CVM_MT_CRC_IV, crc_iv); +CP2_MT_I64(CVM_MT_GFM_MUL0, gfm_mul[0]); +CP2_MT_I64(CVM_MT_GFM_MUL1, gfm_mul[1]); +CP2_MT_I64(CVM_MT_GFM_RESINP0, gfm_resinp[0]); +CP2_MT_I64(CVM_MT_GFM_RESINP1, gfm_resinp[1]); +CP2_MT_U16(CVM_MT_GFM_POLY, gfm_poly); +CP2_MT_U8(CVM_MT_CRC_WRITE_LEN, crc_len); +CP2_MT_U32(CVM_MT_CRC_WRITE_POLYNOMIAL, crc_poly); +CP2_MT_U32(CVM_MT_CRC_WRITE_POLYNOMIAL_REFLECT, crc_poly); + static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a) { TCGv_i64 p; -- 2.54.0
