Commit eb0ecd5a authored by Will Newton's avatar Will Newton Committed by Peter Maydell
Browse files

target-arm: Add support for AArch32 ARMv8 CRC32 instructions



Add support for AArch32 CRC32 and CRC32C instructions added in ARMv8
and add a CPU feature flag to enable these instructions.

The CRC32-C implementation used is the built-in qemu implementation
and The CRC-32 implementation is from zlib. This requires adding zlib
to LIBS to ensure it is linked for the linux-user binary.

Signed-off-by: default avatarWill Newton <will.newton@linaro.org>
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Message-id: 1393411566-24104-3-git-send-email-will.newton@linaro.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 0956ff5a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1657,7 +1657,7 @@ EOF
            "Make sure to have the zlib libs and headers installed."
    fi
fi
libs_softmmu="$libs_softmmu -lz"
LIBS="$LIBS -lz"

##########################################
# libseccomp check
+1 −0
Original line number Diff line number Diff line
@@ -924,6 +924,7 @@ static void arm_any_initfn(Object *obj)
    set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
    set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
    set_feature(&cpu->env, ARM_FEATURE_V7MP);
    set_feature(&cpu->env, ARM_FEATURE_CRC);
#ifdef TARGET_AARCH64
    set_feature(&cpu->env, ARM_FEATURE_AARCH64);
#endif
+1 −0
Original line number Diff line number Diff line
@@ -626,6 +626,7 @@ enum arm_features {
    ARM_FEATURE_AARCH64, /* supports 64 bit mode */
    ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */
    ARM_FEATURE_CBAR, /* has cp15 CBAR */
    ARM_FEATURE_CRC, /* ARMv8 CRC instructions */
};

static inline int arm_feature(CPUARMState *env, int feature)
+39 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "qemu/bitops.h"
#include "qemu/crc32c.h"
#include <zlib.h> /* For crc32 */

#ifndef CONFIG_USER_ONLY
static inline int get_phys_addr(CPUARMState *env, uint32_t address,
@@ -4703,3 +4705,40 @@ int arm_rmode_to_sf(int rmode)
    }
    return rmode;
}

static void crc_init_buffer(uint8_t *buf, uint32_t val, uint32_t bytes)
{
    memset(buf, 0, 4);

    if (bytes == 1) {
        buf[0] = val & 0xff;
    } else if (bytes == 2) {
        buf[0] = val & 0xff;
        buf[1] = (val >> 8) & 0xff;
    } else {
        buf[0] = val & 0xff;
        buf[1] = (val >> 8) & 0xff;
        buf[2] = (val >> 16) & 0xff;
        buf[3] = (val >> 24) & 0xff;
    }
}

uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
{
    uint8_t buf[4];

    crc_init_buffer(buf, val, bytes);

    /* zlib crc32 converts the accumulator and output to one's complement.  */
    return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
}

uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
{
    uint8_t buf[4];

    crc_init_buffer(buf, val, bytes);

    /* Linux crc32c converts the output to one's complement.  */
    return crc32c(acc, buf, bytes) ^ 0xffffffff;
}
+3 −0
Original line number Diff line number Diff line
@@ -499,6 +499,9 @@ DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
DEF_HELPER_4(crypto_aese, void, env, i32, i32, i32)
DEF_HELPER_4(crypto_aesmc, void, env, i32, i32, i32)

DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)

#ifdef TARGET_AARCH64
#include "helper-a64.h"
#endif
Loading