1313006Scem/* 2313006Scem * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org> 3313006Scem * All rights reserved. 4313006Scem * 5313006Scem * Redistribution and use in source and binary forms, with or without 6313006Scem * modification, are permitted provided that the following conditions 7313006Scem * are met: 8313006Scem * 1. Redistributions of source code must retain the above copyright 9313006Scem * notice, this list of conditions and the following disclaimer. 10313006Scem * 2. Redistributions in binary form must reproduce the above copyright 11313006Scem * notice, this list of conditions and the following disclaimer in the 12313006Scem * documentation and/or other materials provided with the distribution. 13313006Scem * 14313006Scem * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15313006Scem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16313006Scem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17313006Scem * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18313006Scem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19313006Scem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20313006Scem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21313006Scem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22313006Scem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23313006Scem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24313006Scem * SUCH DAMAGE. 25313006Scem * 26313006Scem * $FreeBSD: stable/11/tests/sys/kern/libkern_crc32.c 319404 2017-06-01 09:00:38Z tuexen $ 27313006Scem */ 28313006Scem 29313006Scem#include <sys/param.h> 30313006Scem 31313006Scem#include <stdint.h> 32313006Scem 33313006Scem#include <atf-c.h> 34313006Scem 35319404Stuexen#if defined(__amd64__) || defined(__i386__) 36313006Scemextern uint32_t sse42_crc32c(uint32_t, const unsigned char *, unsigned); 37319404Stuexen#elif defined(__aarch64__) 38319404Stuexenextern uint32_t armv8_crc32c(uint32_t, const unsigned char *, unsigned); 39319404Stuexen#else 40319404Stuexen#error These tests are not supported on this platform 41319404Stuexen#endif 42313006Scem 43313006ScemATF_TC_WITHOUT_HEAD(crc32c_basic_correctness); 44313006ScemATF_TC_BODY(crc32c_basic_correctness, tc) 45313006Scem{ 46313006Scem const uint64_t inputs[] = { 47313006Scem 0xf408c634b3a9142, 48313006Scem 0x80539e8c7c352e2b, 49313006Scem 0x62e9121db6e4d649, 50313006Scem 0x899345850ed0a286, 51313006Scem 0x2302df11b4a43b15, 52313006Scem 0xe943de7b3d35d70, 53313006Scem 0xdf1ff2bf41abf56b, 54313006Scem 0x9bc138abae315de2, 55313006Scem 0x31cc82e56234f0ff, 56313006Scem 0xce63c0cd6988e847, 57313006Scem 0x3e42f6b78ee352fa, 58313006Scem 0xfa4085436078cfa6, 59313006Scem 0x53349558bf670a4b, 60313006Scem 0x2714e10e7d722c61, 61313006Scem 0xc0d3261addfc6908, 62313006Scem 0xd1567c3181d3a1bf, 63313006Scem }; 64313006Scem const uint32_t results[] = { 65313006Scem 0x2ce33ede, 66313006Scem 0xc49cc573, 67313006Scem 0xb8683c96, 68313006Scem 0x6918660d, 69313006Scem 0xa904e522, 70313006Scem 0x52dbc42c, 71313006Scem 0x98863c22, 72313006Scem 0x894d5d2c, 73313006Scem 0xb003745d, 74313006Scem 0xfc496dbd, 75313006Scem 0x97d2fbb5, 76313006Scem 0x3c062ef1, 77313006Scem 0xcc2eff18, 78313006Scem 0x6a9b09f6, 79313006Scem 0x420242c1, 80313006Scem 0xfd562dc3, 81313006Scem }; 82313006Scem size_t i; 83313006Scem uint32_t act; 84313006Scem 85313006Scem ATF_REQUIRE(nitems(inputs) == nitems(results)); 86313006Scem 87313006Scem for (i = 0; i < nitems(inputs); i++) { 88319404Stuexen#if defined(__amd64__) || defined(__i386__) 89313006Scem act = sse42_crc32c(~0, (const void *)&inputs[i], 90313006Scem sizeof(inputs[0])); 91319404Stuexen#else 92319404Stuexen act = armv8_crc32c(~0, (const void *)&inputs[i], 93319404Stuexen sizeof(inputs[0])); 94319404Stuexen#endif 95313006Scem ATF_REQUIRE_MSG(act == results[i], 96313006Scem "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)inputs[i], 97313006Scem results[i], act); 98313006Scem } 99313006Scem} 100313006Scem 101313006ScemATF_TC_WITHOUT_HEAD(crc32c_alignment); 102313006ScemATF_TC_BODY(crc32c_alignment, tc) 103313006Scem{ 104313006Scem const uint64_t input = 0xf408c634b3a9142; 105313006Scem const uint32_t result = 0x2ce33ede; 106313006Scem unsigned char buf[15]; 107313006Scem size_t i; 108313006Scem uint32_t act; 109313006Scem 110313006Scem 111313006Scem for (i = 1; i < 8; i++) { 112313006Scem memcpy(&buf[i], &input, sizeof(input)); 113313006Scem 114319404Stuexen#if defined(__amd64__) || defined(__i386__) 115313006Scem act = sse42_crc32c(~0, (const void *)&buf[i], sizeof(input)); 116319404Stuexen#else 117319404Stuexen act = armv8_crc32c(~0, (const void *)&buf[i], sizeof(input)); 118319404Stuexen#endif 119313006Scem ATF_REQUIRE_MSG(act == result, 120313006Scem "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)input, 121313006Scem result, act); 122313006Scem } 123313006Scem} 124313006Scem 125313006ScemATF_TC_WITHOUT_HEAD(crc32c_trailing_bytes); 126313006ScemATF_TC_BODY(crc32c_trailing_bytes, tc) 127313006Scem{ 128313006Scem const unsigned char input[] = { 129313006Scem 0x87, 0x54, 0x74, 0xd2, 0xb, 0x9b, 0xdd, 0xf6, 0x68, 0x37, 130313006Scem 0xd4, 0x4, 0x5e, 0xa9, 0xb3 131313006Scem }; 132313006Scem const uint32_t result = 0xec638d62; 133313006Scem uint32_t act; 134313006Scem 135319404Stuexen#if defined(__amd64__) || defined(__i386__) 136313006Scem act = sse42_crc32c(~0, input, sizeof(input)); 137319404Stuexen#else 138319404Stuexen act = armv8_crc32c(~0, input, sizeof(input)); 139319404Stuexen#endif 140313006Scem ATF_REQUIRE_MSG(act == result, "expected 0x%08x, got 0x%08x", result, 141313006Scem act); 142313006Scem} 143313006Scem 144313006ScemATF_TP_ADD_TCS(tp) 145313006Scem{ 146313006Scem 147313006Scem ATF_TP_ADD_TC(tp, crc32c_basic_correctness); 148313006Scem ATF_TP_ADD_TC(tp, crc32c_alignment); 149313006Scem ATF_TP_ADD_TC(tp, crc32c_trailing_bytes); 150313006Scem return (atf_no_error()); 151313006Scem} 152