-
Victor Kotlyar authoredVictor Kotlyar authored
CRC.hpp 4.57 KiB
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdint.h>
namespace cta {
/**
* Set of CRC functions.
*/
/**
* Compute by software Reed Solomon CRC for the given block.
*
* @param crcInit The initial crc (0 for fresh) (i.e., seed).
* @param cnt The number of data bytes to compute CRC for.
* @param start The starting address of the data bytes (e.g., data buffer).
* @return The computed CRC in big endian (MSB is first byte).
*/
uint32_t crcRS_sw (const uint32_t crcInit, const uint32_t cnt,
const void *const start);
/**
* Compute by software CRC32C (iSCSI) for the given block.
*
* @param crcInit The initial crc (0xFFFFFFFF for fresh) (i.e., seed).
* @param cnt The number of data bytes to compute CRC for.
* @param start The starting address of the data bytes (e.g., data buffer).
* @return The computed CRC in big endian (MSB is first byte).
*/
uint32_t crc32c_sw (const uint32_t crcInit, const uint32_t cnt,
const void *const start);
/**
* Compute by hardware CRC32C (iSCSI) for the given block.
*
* CRC32 Generator Polynomial:
* 0x11EDC6F41
* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+
* x^10+x^9+x^8+x^6+x^0
*
* @param crcInit The initial crc (0xFFFFFFFF for fresh) (i.e., seed).
* @param cnt The number of data bytes to compute CRC for.
* @param start The starting address of the data bytes (e.g., data buffer).
* @return The computed CRC in big endian (MSB is first byte).
*/
uint32_t crc32c_hw (const uint32_t crcInit, const uint32_t cnt,
const void *const start);
/**
* Check for SSE 4.2. SSE 4.2 was first supported in Nehalem processors
* introduced in November, 2008. This does not check for the existence of the
* cpuid instruction itself, which was introduced on the 486SL in 1992, so this
* will fail on earlier x86 processors. cpuid works on all Pentium and later
* processors.
*/
#define SSE42(have) \
do { \
uint32_t eax, ecx; \
eax = 1; \
__asm__("cpuid" \
: "=c"(ecx) \
: "a"(eax) \
: "%ebx", "%edx"); \
(have) = (ecx >> 20) & 1; \
} while (0)
/**
* Compute the CRC32C (iSCSI). If the crc32 processor's instruction is
* available than use the hardware version. Otherwise use the software version.
*
* @param crcInit The initial crc (0xFFFFFFFF for fresh) (i.e., seed).
* @param cnt The number of data bytes to compute CRC for.
* @param start The starting address of the data bytes (e.g., data buffer).
* @return The computed CRC in big endian (MSB is first byte).
*/
uint32_t crc32c(const uint32_t crcInit, const uint32_t cnt,
const void *const start);
/**
* Compute the CRC32C (iSCSI) and append it to the memory block.
* If the crc32 processor's instruction is available
* use the hardware version. Otherwise use the software version.
*
* @param crcInit The initial crc (0xFFFFFFFF for fresh) (i.e., seed).
* @param cnt The number of data bytes in the memory block.
* @param start The starting address of the data bytes (e.g., data buffer).
* The memory block must be big enough to save additional
* 4 bytes at the end.
* @return The length of the memory block with crc32c added.
*/
uint32_t addCrc32cToMemoryBlock(const uint32_t crcInit,
const uint32_t cnt, uint8_t *start);
/**
* Compute the CRC32C (iSCSI) and check it for the memory block with CRC32C
* addition. If the crc32 processor's instruction is available
* use the hardware version. Otherwise use the software version.
*
* @param crcInit The initial crc (0xFFFFFFFF for fresh) (i.e., seed).
* @param cnt The number of data bytes in the memory block.
* @param start The starting address of the data bytes (e.g., data buffer).
* @return True if CRC32C is correct and False otherwise.
*/
bool verifyCrc32cForMemoryBlockWithCrc32c(
const uint32_t crcInit, const uint32_t cnt, const uint8_t *start);
} // namespace cta