16be2ff7dSConrad Meyer /* 26be2ff7dSConrad Meyer * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org> 36be2ff7dSConrad Meyer * All rights reserved. 46be2ff7dSConrad Meyer * 56be2ff7dSConrad Meyer * Redistribution and use in source and binary forms, with or without 66be2ff7dSConrad Meyer * modification, are permitted provided that the following conditions 76be2ff7dSConrad Meyer * are met: 86be2ff7dSConrad Meyer * 1. Redistributions of source code must retain the above copyright 96be2ff7dSConrad Meyer * notice, this list of conditions and the following disclaimer. 106be2ff7dSConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright 116be2ff7dSConrad Meyer * notice, this list of conditions and the following disclaimer in the 126be2ff7dSConrad Meyer * documentation and/or other materials provided with the distribution. 136be2ff7dSConrad Meyer * 146be2ff7dSConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 156be2ff7dSConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 166be2ff7dSConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 176be2ff7dSConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 186be2ff7dSConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 196be2ff7dSConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 206be2ff7dSConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 216be2ff7dSConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 226be2ff7dSConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 236be2ff7dSConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 246be2ff7dSConrad Meyer * SUCH DAMAGE. 256be2ff7dSConrad Meyer * 266be2ff7dSConrad Meyer * $FreeBSD$ 276be2ff7dSConrad Meyer */ 286be2ff7dSConrad Meyer 296be2ff7dSConrad Meyer #include <sys/param.h> 30f89d2072SXin LI #include <sys/gsb_crc32.h> 316be2ff7dSConrad Meyer 326be2ff7dSConrad Meyer #include <stdint.h> 336be2ff7dSConrad Meyer 346be2ff7dSConrad Meyer #include <atf-c.h> 356be2ff7dSConrad Meyer 36*83c20b8aSAlex Richardson #if defined(__amd64__) || defined(__i386__) 37*83c20b8aSAlex Richardson #include <machine/cpufunc.h> 38*83c20b8aSAlex Richardson #include <machine/specialreg.h> 39*83c20b8aSAlex Richardson 40*83c20b8aSAlex Richardson static bool 41*83c20b8aSAlex Richardson have_sse42(void) 42*83c20b8aSAlex Richardson { 43*83c20b8aSAlex Richardson u_int cpu_registers[4]; 44*83c20b8aSAlex Richardson 45*83c20b8aSAlex Richardson do_cpuid(1, cpu_registers); 46*83c20b8aSAlex Richardson 47*83c20b8aSAlex Richardson return ((cpu_registers[2] & CPUID2_SSE42) != 0); 48*83c20b8aSAlex Richardson } 49d7f27102SMichael Tuexen #endif 506be2ff7dSConrad Meyer 51*83c20b8aSAlex Richardson static void 52*83c20b8aSAlex Richardson check_crc32c(uint32_t expected, uint32_t crc32c, const void *buffer, 53*83c20b8aSAlex Richardson size_t length) 54*83c20b8aSAlex Richardson { 55*83c20b8aSAlex Richardson uint32_t act; 56*83c20b8aSAlex Richardson 57*83c20b8aSAlex Richardson #if defined(__amd64__) || defined(__i386__) 58*83c20b8aSAlex Richardson if (have_sse42()) { 59*83c20b8aSAlex Richardson act = sse42_crc32c(crc32c, buffer, length); 60*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act, 61*83c20b8aSAlex Richardson "sse42_crc32c expected 0x%08x, got 0x%08x", expected, act); 62*83c20b8aSAlex Richardson } 63*83c20b8aSAlex Richardson #elif defined(__aarch64__) 64*83c20b8aSAlex Richardson act = armv8_crc32c(crc32c, buffer, length); 65*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act, 66*83c20b8aSAlex Richardson "armv8_crc32c expected 0x%08x, got 0x%08x", expected, act); 67*83c20b8aSAlex Richardson #endif 68*83c20b8aSAlex Richardson act = singletable_crc32c(crc32c, buffer, length); 69*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act, 70*83c20b8aSAlex Richardson "singletable_crc32c expected 0x%08x, got 0x%08x", expected, act); 71*83c20b8aSAlex Richardson act = multitable_crc32c(crc32c, buffer, length); 72*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act, 73*83c20b8aSAlex Richardson "multitable_crc32c expected 0x%08x, got 0x%08x", expected, act); 74*83c20b8aSAlex Richardson } 75*83c20b8aSAlex Richardson 766be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_basic_correctness); 776be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_basic_correctness, tc) 786be2ff7dSConrad Meyer { 796be2ff7dSConrad Meyer const uint64_t inputs[] = { 806be2ff7dSConrad Meyer 0xf408c634b3a9142, 816be2ff7dSConrad Meyer 0x80539e8c7c352e2b, 826be2ff7dSConrad Meyer 0x62e9121db6e4d649, 836be2ff7dSConrad Meyer 0x899345850ed0a286, 846be2ff7dSConrad Meyer 0x2302df11b4a43b15, 856be2ff7dSConrad Meyer 0xe943de7b3d35d70, 866be2ff7dSConrad Meyer 0xdf1ff2bf41abf56b, 876be2ff7dSConrad Meyer 0x9bc138abae315de2, 886be2ff7dSConrad Meyer 0x31cc82e56234f0ff, 896be2ff7dSConrad Meyer 0xce63c0cd6988e847, 906be2ff7dSConrad Meyer 0x3e42f6b78ee352fa, 916be2ff7dSConrad Meyer 0xfa4085436078cfa6, 926be2ff7dSConrad Meyer 0x53349558bf670a4b, 936be2ff7dSConrad Meyer 0x2714e10e7d722c61, 946be2ff7dSConrad Meyer 0xc0d3261addfc6908, 956be2ff7dSConrad Meyer 0xd1567c3181d3a1bf, 966be2ff7dSConrad Meyer }; 976be2ff7dSConrad Meyer const uint32_t results[] = { 986be2ff7dSConrad Meyer 0x2ce33ede, 996be2ff7dSConrad Meyer 0xc49cc573, 1006be2ff7dSConrad Meyer 0xb8683c96, 1016be2ff7dSConrad Meyer 0x6918660d, 1026be2ff7dSConrad Meyer 0xa904e522, 1036be2ff7dSConrad Meyer 0x52dbc42c, 1046be2ff7dSConrad Meyer 0x98863c22, 1056be2ff7dSConrad Meyer 0x894d5d2c, 1066be2ff7dSConrad Meyer 0xb003745d, 1076be2ff7dSConrad Meyer 0xfc496dbd, 1086be2ff7dSConrad Meyer 0x97d2fbb5, 1096be2ff7dSConrad Meyer 0x3c062ef1, 1106be2ff7dSConrad Meyer 0xcc2eff18, 1116be2ff7dSConrad Meyer 0x6a9b09f6, 1126be2ff7dSConrad Meyer 0x420242c1, 1136be2ff7dSConrad Meyer 0xfd562dc3, 1146be2ff7dSConrad Meyer }; 1156be2ff7dSConrad Meyer size_t i; 1166be2ff7dSConrad Meyer 1176be2ff7dSConrad Meyer ATF_REQUIRE(nitems(inputs) == nitems(results)); 1186be2ff7dSConrad Meyer 1196be2ff7dSConrad Meyer for (i = 0; i < nitems(inputs); i++) { 120*83c20b8aSAlex Richardson check_crc32c(results[i], ~0u, &inputs[i], sizeof(inputs[0])); 1216be2ff7dSConrad Meyer } 1226be2ff7dSConrad Meyer } 1236be2ff7dSConrad Meyer 1246be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_alignment); 1256be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_alignment, tc) 1266be2ff7dSConrad Meyer { 1276be2ff7dSConrad Meyer const uint64_t input = 0xf408c634b3a9142; 1286be2ff7dSConrad Meyer const uint32_t result = 0x2ce33ede; 1296be2ff7dSConrad Meyer unsigned char buf[15]; 1306be2ff7dSConrad Meyer size_t i; 1316be2ff7dSConrad Meyer 1326be2ff7dSConrad Meyer for (i = 1; i < 8; i++) { 1336be2ff7dSConrad Meyer memcpy(&buf[i], &input, sizeof(input)); 134*83c20b8aSAlex Richardson check_crc32c(result, ~0u, &buf[i], sizeof(input)); 1356be2ff7dSConrad Meyer } 1366be2ff7dSConrad Meyer } 1376be2ff7dSConrad Meyer 1386be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_trailing_bytes); 1396be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_trailing_bytes, tc) 1406be2ff7dSConrad Meyer { 1416be2ff7dSConrad Meyer const unsigned char input[] = { 1426be2ff7dSConrad Meyer 0x87, 0x54, 0x74, 0xd2, 0xb, 0x9b, 0xdd, 0xf6, 0x68, 0x37, 1436be2ff7dSConrad Meyer 0xd4, 0x4, 0x5e, 0xa9, 0xb3 1446be2ff7dSConrad Meyer }; 1456be2ff7dSConrad Meyer const uint32_t result = 0xec638d62; 1466be2ff7dSConrad Meyer 147*83c20b8aSAlex Richardson check_crc32c(result, ~0u, input, sizeof(input)); 1486be2ff7dSConrad Meyer } 1496be2ff7dSConrad Meyer 1506be2ff7dSConrad Meyer ATF_TP_ADD_TCS(tp) 1516be2ff7dSConrad Meyer { 1526be2ff7dSConrad Meyer 1536be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_basic_correctness); 1546be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_alignment); 1556be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_trailing_bytes); 1566be2ff7dSConrad Meyer return (atf_no_error()); 1576be2ff7dSConrad Meyer } 158