Add the common state needed by Octeon's selector-driven COP2 crypto
interfaces. This includes the selector constants and storage for the base
hash, AES, CRC, GFM, 3DES, KASUMI, and SNOW3G engines, plus the shared
selector-window mode used by overlapping hardware register banks.

Describe the shared HSH/SHA512, SHA3, SNOW3G, and ZUC selector window up
front so later engine patches only add their own selectors and state
instead of rewriting common comments.

Migrate the state in an Octeon-only subsection so non-Octeon CPU models do
not grow migration data. Later patches wire helpers and explicit selector
decode on top of this state.

Signed-off-by: James Hilliard <[email protected]>
---
Changes v7 -> v8:
  - Split COP2 crypto state and migration coverage out of the combined
    COP2 crypto core patch.
---
 target/mips/cpu.h            | 165 +++++++++++++++++++++++++++++++++++++++++++
 target/mips/system/machine.c |  37 ++++++++++
 2 files changed, 202 insertions(+)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 346713705a..1c552b8134 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -537,6 +537,169 @@ struct TCState {
 };
 
 struct MIPSITUState;
+typedef enum MIPSOcteonSharedMode {
+    OCTEON_SHARED_MODE_NONE = 0,
+    OCTEON_SHARED_MODE_SHA512,
+    OCTEON_SHARED_MODE_SNOW3G,
+} MIPSOcteonSharedMode;
+
+typedef enum MIPSOcteonCop2Sel {
+    OCTEON_COP2_SEL_HSH_DAT0 = 0x0040,
+    OCTEON_COP2_SEL_HSH_DAT1,
+    OCTEON_COP2_SEL_HSH_DAT2,
+    OCTEON_COP2_SEL_HSH_DAT3,
+    OCTEON_COP2_SEL_HSH_DAT4,
+    OCTEON_COP2_SEL_HSH_DAT5,
+    OCTEON_COP2_SEL_HSH_DAT6,
+    OCTEON_COP2_SEL_HSH_IV0 = 0x0048,
+    OCTEON_COP2_SEL_HSH_IV1,
+    OCTEON_COP2_SEL_HSH_IV2,
+    OCTEON_COP2_SEL_HSH_IV3,
+    OCTEON_COP2_SEL_SHA3_DAT24 = 0x0050,
+    OCTEON_COP2_SEL_SHA3_DAT15_MT = 0x0051,
+    OCTEON_COP2_SEL_HSH_STARTSHA_COMPAT = 0x0057,
+    OCTEON_COP2_SEL_GFM_MUL_REFLECT0 = 0x0058,
+    OCTEON_COP2_SEL_GFM_MUL_REFLECT1,
+    OCTEON_COP2_SEL_GFM_RESINP_REFLECT0 = 0x005a,
+    OCTEON_COP2_SEL_GFM_RESINP_REFLECT1,
+    OCTEON_COP2_SEL_GFM_XOR0_REFLECT = 0x005c,
+    OCTEON_COP2_SEL_3DES_KEY0 = 0x0080,
+    OCTEON_COP2_SEL_3DES_KEY1,
+    OCTEON_COP2_SEL_3DES_KEY2,
+    OCTEON_COP2_SEL_3DES_IV = 0x0084,
+    OCTEON_COP2_SEL_3DES_RESULT_MF = 0x0088,
+    OCTEON_COP2_SEL_3DES_RESULT_MT = 0x0098,
+    OCTEON_COP2_SEL_3DES_ENC_CBC = 0x4088,
+    /*
+     * Octeon reuses the 3DES key/result bank for KASUMI and only adds
+     * KASUMI-specific operation selectors.
+     */
+    OCTEON_COP2_SEL_KAS_ENC_CBC = 0x4089,
+    OCTEON_COP2_SEL_3DES_ENC = 0x408a,
+    OCTEON_COP2_SEL_KAS_ENC = 0x408b,
+    OCTEON_COP2_SEL_3DES_DEC_CBC = 0x408c,
+    OCTEON_COP2_SEL_3DES_DEC = 0x408e,
+    OCTEON_COP2_SEL_AES_RESINP0 = 0x0100,
+    OCTEON_COP2_SEL_AES_RESINP1,
+    OCTEON_COP2_SEL_AES_IV0,
+    OCTEON_COP2_SEL_AES_IV1,
+    OCTEON_COP2_SEL_AES_KEY0,
+    OCTEON_COP2_SEL_AES_KEY1,
+    OCTEON_COP2_SEL_AES_KEY2,
+    OCTEON_COP2_SEL_AES_KEY3,
+    OCTEON_COP2_SEL_AES_ENC_CBC0 = 0x0108,
+    OCTEON_COP2_SEL_AES_ENC0 = 0x010a,
+    OCTEON_COP2_SEL_AES_DEC_CBC0 = 0x010c,
+    OCTEON_COP2_SEL_AES_DEC0 = 0x010e,
+    OCTEON_COP2_SEL_AES_KEYLENGTH = 0x0110,
+    OCTEON_COP2_SEL_AES_INP0 = 0x0111,
+    OCTEON_COP2_SEL_CRC_POLYNOMIAL = 0x0200,
+    OCTEON_COP2_SEL_CRC_IV = 0x0201,
+    OCTEON_COP2_SEL_CRC_LEN = 0x0202,
+    OCTEON_COP2_SEL_CRC_IV_REFLECT = 0x0203,
+    OCTEON_COP2_SEL_CRC_WRITE_BYTE = 0x0204,
+    OCTEON_COP2_SEL_CRC_WRITE_HALF = 0x0205,
+    OCTEON_COP2_SEL_CRC_WRITE_WORD = 0x0206,
+    OCTEON_COP2_SEL_CRC_WRITE_POLYNOMIAL = 0x4200,
+    OCTEON_COP2_SEL_CRC_WRITE_LEN = 0x1202,
+    OCTEON_COP2_SEL_CRC_WRITE_IV_REFLECT = 0x0211,
+    OCTEON_COP2_SEL_CRC_WRITE_BYTE_REFLECT = 0x0214,
+    OCTEON_COP2_SEL_CRC_WRITE_HALF_REFLECT = 0x0215,
+    OCTEON_COP2_SEL_CRC_WRITE_WORD_REFLECT = 0x0216,
+    OCTEON_COP2_SEL_CRC_WRITE_DWORD = 0x1207,
+    OCTEON_COP2_SEL_CRC_WRITE_VAR = 0x1208,
+    OCTEON_COP2_SEL_CRC_WRITE_POLYNOMIAL_REFLECT = 0x4210,
+    OCTEON_COP2_SEL_CRC_WRITE_DWORD_REFLECT = 0x1217,
+    OCTEON_COP2_SEL_CRC_WRITE_VAR_REFLECT = 0x1218,
+    /*
+     * Octeon shares 0x0240..0x0257 across the HSH/SHA512, SHA3, SNOW3G,
+     * and ZUC selector windows.
+     */
+    OCTEON_COP2_SEL_HSH_DATW0 = 0x0240,
+    OCTEON_COP2_SEL_HSH_DATW1,
+    OCTEON_COP2_SEL_HSH_DATW2,
+    OCTEON_COP2_SEL_HSH_DATW3,
+    OCTEON_COP2_SEL_HSH_DATW4,
+    OCTEON_COP2_SEL_HSH_DATW5,
+    OCTEON_COP2_SEL_HSH_DATW6,
+    OCTEON_COP2_SEL_HSH_DATW7,
+    OCTEON_COP2_SEL_HSH_DATW8,
+    OCTEON_COP2_SEL_HSH_DATW9,
+    OCTEON_COP2_SEL_HSH_DATW10,
+    OCTEON_COP2_SEL_HSH_DATW11,
+    OCTEON_COP2_SEL_HSH_DATW12,
+    OCTEON_COP2_SEL_HSH_DATW13,
+    OCTEON_COP2_SEL_HSH_DATW14,
+    OCTEON_COP2_SEL_HSH_DATW15,
+    OCTEON_COP2_SEL_HSH_IVW0 = 0x0250,
+    OCTEON_COP2_SEL_HSH_IVW1,
+    OCTEON_COP2_SEL_HSH_IVW2,
+    OCTEON_COP2_SEL_HSH_IVW3,
+    OCTEON_COP2_SEL_HSH_IVW4,
+    OCTEON_COP2_SEL_HSH_IVW5,
+    OCTEON_COP2_SEL_HSH_IVW6,
+    OCTEON_COP2_SEL_HSH_IVW7,
+    OCTEON_COP2_SEL_SNOW3G_LFSR0 = 0x0240,
+    OCTEON_COP2_SEL_SNOW3G_LFSR1,
+    OCTEON_COP2_SEL_SNOW3G_LFSR2,
+    OCTEON_COP2_SEL_SNOW3G_LFSR3,
+    OCTEON_COP2_SEL_SNOW3G_LFSR4,
+    OCTEON_COP2_SEL_SNOW3G_LFSR5,
+    OCTEON_COP2_SEL_SNOW3G_LFSR6,
+    OCTEON_COP2_SEL_SNOW3G_LFSR7,
+    OCTEON_COP2_SEL_SNOW3G_RESULT = 0x0250,
+    OCTEON_COP2_SEL_SNOW3G_FSM0,
+    OCTEON_COP2_SEL_SNOW3G_FSM1,
+    OCTEON_COP2_SEL_SNOW3G_FSM2,
+    OCTEON_COP2_SEL_GFM_MUL0 = 0x0258,
+    OCTEON_COP2_SEL_GFM_MUL1,
+    OCTEON_COP2_SEL_GFM_RESINP0,
+    OCTEON_COP2_SEL_GFM_RESINP1,
+    OCTEON_COP2_SEL_GFM_XOR0,
+    OCTEON_COP2_SEL_GFM_POLY = 0x025e,
+    OCTEON_COP2_SEL_AES_ENC_CBC1 = 0x3109,
+    OCTEON_COP2_SEL_AES_ENC1 = 0x310b,
+    OCTEON_COP2_SEL_AES_DEC_CBC1 = 0x310d,
+    OCTEON_COP2_SEL_AES_DEC1 = 0x310f,
+    OCTEON_COP2_SEL_HSH_STARTMD5 = 0x4047,
+    OCTEON_COP2_SEL_SNOW3G_START = 0x404d,
+    OCTEON_COP2_SEL_SNOW3G_MORE = 0x404e,
+    OCTEON_COP2_SEL_HSH_STARTSHA256 = 0x404f,
+    OCTEON_COP2_SEL_GFM_XORMUL1_REFLECT = 0x405d,
+    OCTEON_COP2_SEL_HSH_STARTSHA = 0x4057,
+    OCTEON_COP2_SEL_HSH_STARTSHA512 = 0x424f,
+    OCTEON_COP2_SEL_GFM_XORMUL1 = 0x425d,
+} MIPSOcteonCop2Sel;
+
+typedef struct MIPSOcteonCryptoState {
+    uint64_t des3_key[3];
+    uint64_t des3_iv;
+    uint64_t des3_result;
+    uint64_t hsh_iv[4];
+    uint64_t hsh_dat[8];
+    uint64_t hsh_ivw[8];
+    uint64_t hsh_datw[16];
+    uint64_t aes_iv[2];
+    uint64_t aes_key[4];
+    uint64_t aes_result[2];
+    uint64_t aes_input[2];
+    uint64_t gfm_mul[2];
+    uint64_t gfm_resinp[2];
+    uint64_t gfm_xor0;
+    uint64_t gfm_reflect_mul[2];
+    uint64_t gfm_reflect_resinp[2];
+    uint64_t gfm_reflect_xor0;
+    uint16_t gfm_poly;
+    uint8_t aes_keylen;
+    uint32_t shared_mode;
+    uint32_t crc_poly;
+    uint32_t crc_iv;
+    uint32_t crc_len;
+    uint32_t snow3g_fsm[3];
+    uint32_t snow3g_lfsr[16];
+    uint64_t snow3g_result;
+} MIPSOcteonCryptoState;
+
 typedef struct CPUArchState {
     TCState active_tc;
     CPUMIPSFPUContext active_fpu;
@@ -558,6 +721,8 @@ typedef struct CPUArchState {
 #define MSAIR_ProcID    8
 #define MSAIR_Rev       0
 
+    MIPSOcteonCryptoState octeon_crypto;
+
 /*
  * CP0 Register 0
  */
diff --git a/target/mips/system/machine.c b/target/mips/system/machine.c
index f988b3695b..ebfa0a9eb0 100644
--- a/target/mips/system/machine.c
+++ b/target/mips/system/machine.c
@@ -279,6 +279,42 @@ static const VMStateDescription 
mips_vmstate_octeon_multiplier = {
     }
 };
 
+static const VMStateDescription mips_vmstate_octeon_crypto = {
+    .name = "cpu/octeon_crypto",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = mips_octeon_needed,
+    .fields = (const VMStateField[]) {
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.des3_key, MIPSCPU, 3),
+        VMSTATE_UINT64(env.octeon_crypto.des3_iv, MIPSCPU),
+        VMSTATE_UINT64(env.octeon_crypto.des3_result, MIPSCPU),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.hsh_iv, MIPSCPU, 4),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.hsh_dat, MIPSCPU, 8),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.hsh_ivw, MIPSCPU, 8),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.hsh_datw, MIPSCPU, 16),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.aes_iv, MIPSCPU, 2),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.aes_key, MIPSCPU, 4),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.aes_result, MIPSCPU, 2),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.aes_input, MIPSCPU, 2),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.gfm_mul, MIPSCPU, 2),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.gfm_resinp, MIPSCPU, 2),
+        VMSTATE_UINT64(env.octeon_crypto.gfm_xor0, MIPSCPU),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.gfm_reflect_mul, MIPSCPU, 2),
+        VMSTATE_UINT64_ARRAY(env.octeon_crypto.gfm_reflect_resinp, MIPSCPU, 2),
+        VMSTATE_UINT64(env.octeon_crypto.gfm_reflect_xor0, MIPSCPU),
+        VMSTATE_UINT16(env.octeon_crypto.gfm_poly, MIPSCPU),
+        VMSTATE_UINT8(env.octeon_crypto.aes_keylen, MIPSCPU),
+        VMSTATE_UINT32(env.octeon_crypto.shared_mode, MIPSCPU),
+        VMSTATE_UINT32(env.octeon_crypto.crc_poly, MIPSCPU),
+        VMSTATE_UINT32(env.octeon_crypto.crc_iv, MIPSCPU),
+        VMSTATE_UINT32(env.octeon_crypto.crc_len, MIPSCPU),
+        VMSTATE_UINT32_ARRAY(env.octeon_crypto.snow3g_fsm, MIPSCPU, 3),
+        VMSTATE_UINT32_ARRAY(env.octeon_crypto.snow3g_lfsr, MIPSCPU, 16),
+        VMSTATE_UINT64(env.octeon_crypto.snow3g_result, MIPSCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_mips_cpu = {
     .name = "cpu",
     .version_id = 21,
@@ -396,6 +432,7 @@ const VMStateDescription vmstate_mips_cpu = {
     .subsections = (const VMStateDescription * const []) {
         &mips_vmstate_timer,
         &mips_vmstate_octeon_multiplier,
+        &mips_vmstate_octeon_crypto,
         NULL
     }
 };

-- 
2.54.0


Reply via email to