Files
Linux_Drivers/fsbl/lib/crc/crc32.c
sam.xiang 4bc998a131 [fsbl] add fsbl for cv181x/cv180x
Change-Id: I6809bc5016d4bc148f62be2ed3f8e928ec111f19
2023-03-10 20:33:00 +08:00

71 lines
1.5 KiB
C

#include <stddef.h>
#include <stdint.h>
#pragma GCC push_options
#pragma GCC target("+nothing+crc")
#if !defined(__ARM_FEATURE_CRC32)
#error "__ARM_FEATURE_CRC32"
#endif
static inline uint32_t __extension__ __attribute__((__always_inline__)) __crc32b(uint32_t __a, uint8_t __b)
{
return __builtin_aarch64_crc32b(__a, __b);
}
static inline uint32_t __extension__ __attribute__((__always_inline__)) __crc32d(uint32_t __a, uint64_t __b)
{
return __builtin_aarch64_crc32x(__a, __b);
}
/**
* crc-32
* Width 32
* Poly 0x04c11db7
* Reflect In True
* XOR In 0xffffffff
* Reflect Out True
* XOR Out 0xffffffff
* Short command pycrc.py --model crc-32
* Extended command pycrc.py --width 32 --poly 0x04c11db7
* --reflect-in True --xor-in 0xffffffff --reflect-out True --xor-out 0xffffffff
* Check 0xcbf43926
*/
uint32_t armv8_crc32_little(unsigned long crc, const unsigned char *buf, size_t len)
{
uint32_t c = (uint32_t)~crc;
while (len && ((uintptr_t)buf & 7)) {
c = __crc32b(c, *buf++);
--len;
}
const uint64_t *buf8 = (const uint64_t *)buf;
while (len >= 64) {
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
len -= 64;
}
while (len >= 8) {
c = __crc32d(c, *buf8++);
len -= 8;
}
buf = (const unsigned char *)buf8;
while (len--) {
c = __crc32b(c, *buf++);
}
return ~c;
}
#pragma GCC pop_options