Extend the Octeon linux-user smoke test with AES key and key-length DMTC2/DMFC2 readback checks, QMAC/QMACS fixed-point accumulator checks, and an RDHWR $31 monotonicity check.
The COP2 readback cases exercise the explicit COP2 decodetree entries and direct TCG register-transfer paths introduced by the decode split. The QMAC and CvmCount cases keep the fixed-point accumulator and RDHWR paths covered by the same Octeon smoke binary. Reviewed-by: Richard Henderson <[email protected]> Signed-off-by: James Hilliard <[email protected]> --- Changes v8 -> v9: - Combine the v8 COP2 selector readback and QMAC/CvmCount test patches. - Fix the commit message to refer to RDHWR $31. Changes v7 -> v8: - Split AES COP2 selector readback coverage out of the COP2 crypto core patch. Changes v5 -> v6: - Add QMAC/QMACS and CvmCount smoke coverage. --- tests/tcg/mips/user/isa/octeon/octeon-insns.c | 128 ++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/tests/tcg/mips/user/isa/octeon/octeon-insns.c b/tests/tcg/mips/user/isa/octeon/octeon-insns.c index 9153e37e9e..1dbdd9f52a 100644 --- a/tests/tcg/mips/user/isa/octeon/octeon-insns.c +++ b/tests/tcg/mips/user/isa/octeon/octeon-insns.c @@ -129,6 +129,59 @@ static uint64_t octeon_vmm0(uint64_t mpl0, uint64_t p0, return rd; } +static uint64_t octeon_qmac_lo(uint64_t rs, uint64_t rt, uint64_t lo) +{ + uint64_t rd; + + asm volatile( + "move $8, %[rs]\n\t" + "move $9, %[rt]\n\t" + "mtlo %[lo]\n\t" + "mthi $0\n\t" + ".word 0x710904d2\n\t" /* qmac.03 $8, $9 */ + "mflo %[rd]\n\t" + : [rd] "=r" (rd) + : [rs] "r" (rs), [rt] "r" (rt), [lo] "r" (lo) + : "$8", "$9"); + + return rd; +} + +static uint64_t octeon_qmacs_state(uint64_t rs, uint64_t rt, uint64_t lo) +{ + uint64_t hi, rd; + + asm volatile( + "move $8, %[rs]\n\t" + "move $9, %[rt]\n\t" + "mtlo %[lo]\n\t" + "mthi $0\n\t" + ".word 0x71090012\n\t" /* qmacs.00 $8, $9 */ + "mfhi %[hi]\n\t" + "mflo %[rd]\n\t" + : [hi] "=r" (hi), [rd] "=r" (rd) + : [rs] "r" (rs), [rt] "r" (rt), [lo] "r" (lo) + : "$8", "$9"); + + return ((hi & 1) << 32) | (rd & 0xffffffff); +} + +static uint64_t octeon_rdhwr31_non_decreasing(void) +{ + uint64_t first, second; + + asm volatile( + ".word 0x7c08f83b\n\t" /* rdhwr $8, $31 */ + ".word 0x7c09f83b\n\t" /* rdhwr $9, $31 */ + "move %[first], $8\n\t" + "move %[second], $9\n\t" + : [first] "=r" (first), [second] "=r" (second) + : + : "$8", "$9"); + + return second >= first; +} + static uint64_t octeon_vmm0_zeroes_mpl1(void) { uint64_t rd; @@ -186,6 +239,70 @@ static uint64_t octeon_mtp0_zeroes_p1(void) return rd; } +static uint64_t octeon_cop2_key0_readback(uint64_t value) +{ + uint64_t rd; + + asm volatile( + "move $8, %[value]\n\t" + ".word 0x48a80104\n\t" /* dmtc2 $8, AES_KEY0 selector */ + ".word 0x482a0104\n\t" /* dmfc2 $10, AES_KEY0 selector */ + "move %[rd], $10\n\t" + : [rd] "=r" (rd) + : [value] "r" (value) + : "$8", "$10"); + + return rd; +} + +static uint64_t octeon_cop2_key2_readback(uint64_t value) +{ + uint64_t rd; + + asm volatile( + "move $8, %[value]\n\t" + ".word 0x48a80106\n\t" /* dmtc2 $8, AES_KEY2 selector */ + ".word 0x482a0106\n\t" /* dmfc2 $10, AES_KEY2 selector */ + "move %[rd], $10\n\t" + : [rd] "=r" (rd) + : [value] "r" (value) + : "$8", "$10"); + + return rd; +} + +static uint64_t octeon_cop2_key3_readback(uint64_t value) +{ + uint64_t rd; + + asm volatile( + "move $8, %[value]\n\t" + ".word 0x48a80107\n\t" /* dmtc2 $8, AES_KEY3 selector */ + ".word 0x482a0107\n\t" /* dmfc2 $10, AES_KEY3 selector */ + "move %[rd], $10\n\t" + : [rd] "=r" (rd) + : [value] "r" (value) + : "$8", "$10"); + + return rd; +} + +static uint64_t octeon_cop2_keylength_readback(uint64_t value) +{ + uint64_t rd; + + asm volatile( + "move $8, %[value]\n\t" + ".word 0x48a80110\n\t" /* dmtc2 $8, AES_KEYLENGTH selector */ + ".word 0x482a0110\n\t" /* dmfc2 $10, AES_KEYLENGTH selector */ + "move %[rd], $10\n\t" + : [rd] "=r" (rd) + : [value] "r" (value) + : "$8", "$10"); + + return rd; +} + int main(void) { assert(octeon_baddu(0x123, 0x0f0) == 0x13); @@ -195,10 +312,21 @@ int main(void) assert(octeon_seq(0xabc, 0xdef) == 0); assert(octeon_sne(0xabc, 0xabc) == 0); assert(octeon_sne(0xabc, 0xdef) == 1); + assert(octeon_qmac_lo(0x0003000000000000ULL, 2, 1) == 13); + assert(octeon_qmacs_state(1, 1, 0x7ffffffe) == 0x17fffffffULL); + assert(octeon_qmacs_state(0x8000, 0x8000, 0) == 0x17fffffffULL); + assert(octeon_rdhwr31_non_decreasing()); assert(octeon_vmulu(5, 7, 11) == 46); assert(octeon_vmm0(5, 13, 7, 11) == 59); assert(octeon_vmm0_zeroes_mpl1() == 0); assert(octeon_mtp0_zeroes_p1() == 0); + assert(octeon_cop2_key0_readback(0x1122334455667788ULL) == + 0x1122334455667788ULL); + assert(octeon_cop2_key2_readback(0x8877665544332211ULL) == + 0x8877665544332211ULL); + assert(octeon_cop2_key3_readback(0x0102030405060708ULL) == + 0x0102030405060708ULL); + assert(octeon_cop2_keylength_readback(0xa5) == 0xa5); return 0; } -- 2.54.0
