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
276be2ff7dSConrad Meyer #include <sys/param.h>
28f89d2072SXin LI #include <sys/gsb_crc32.h>
296be2ff7dSConrad Meyer
306be2ff7dSConrad Meyer #include <stdint.h>
316be2ff7dSConrad Meyer
326be2ff7dSConrad Meyer #include <atf-c.h>
336be2ff7dSConrad Meyer
34*83c20b8aSAlex Richardson #if defined(__amd64__) || defined(__i386__)
35*83c20b8aSAlex Richardson #include <machine/cpufunc.h>
36*83c20b8aSAlex Richardson #include <machine/specialreg.h>
37*83c20b8aSAlex Richardson
38*83c20b8aSAlex Richardson static bool
have_sse42(void)39*83c20b8aSAlex Richardson have_sse42(void)
40*83c20b8aSAlex Richardson {
41*83c20b8aSAlex Richardson u_int cpu_registers[4];
42*83c20b8aSAlex Richardson
43*83c20b8aSAlex Richardson do_cpuid(1, cpu_registers);
44*83c20b8aSAlex Richardson
45*83c20b8aSAlex Richardson return ((cpu_registers[2] & CPUID2_SSE42) != 0);
46*83c20b8aSAlex Richardson }
47d7f27102SMichael Tuexen #endif
486be2ff7dSConrad Meyer
49*83c20b8aSAlex Richardson static void
check_crc32c(uint32_t expected,uint32_t crc32c,const void * buffer,size_t length)50*83c20b8aSAlex Richardson check_crc32c(uint32_t expected, uint32_t crc32c, const void *buffer,
51*83c20b8aSAlex Richardson size_t length)
52*83c20b8aSAlex Richardson {
53*83c20b8aSAlex Richardson uint32_t act;
54*83c20b8aSAlex Richardson
55*83c20b8aSAlex Richardson #if defined(__amd64__) || defined(__i386__)
56*83c20b8aSAlex Richardson if (have_sse42()) {
57*83c20b8aSAlex Richardson act = sse42_crc32c(crc32c, buffer, length);
58*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act,
59*83c20b8aSAlex Richardson "sse42_crc32c expected 0x%08x, got 0x%08x", expected, act);
60*83c20b8aSAlex Richardson }
61*83c20b8aSAlex Richardson #elif defined(__aarch64__)
62*83c20b8aSAlex Richardson act = armv8_crc32c(crc32c, buffer, length);
63*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act,
64*83c20b8aSAlex Richardson "armv8_crc32c expected 0x%08x, got 0x%08x", expected, act);
65*83c20b8aSAlex Richardson #endif
66*83c20b8aSAlex Richardson act = singletable_crc32c(crc32c, buffer, length);
67*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act,
68*83c20b8aSAlex Richardson "singletable_crc32c expected 0x%08x, got 0x%08x", expected, act);
69*83c20b8aSAlex Richardson act = multitable_crc32c(crc32c, buffer, length);
70*83c20b8aSAlex Richardson ATF_CHECK_EQ_MSG(expected, act,
71*83c20b8aSAlex Richardson "multitable_crc32c expected 0x%08x, got 0x%08x", expected, act);
72*83c20b8aSAlex Richardson }
73*83c20b8aSAlex Richardson
746be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_basic_correctness);
ATF_TC_BODY(crc32c_basic_correctness,tc)756be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_basic_correctness, tc)
766be2ff7dSConrad Meyer {
776be2ff7dSConrad Meyer const uint64_t inputs[] = {
786be2ff7dSConrad Meyer 0xf408c634b3a9142,
796be2ff7dSConrad Meyer 0x80539e8c7c352e2b,
806be2ff7dSConrad Meyer 0x62e9121db6e4d649,
816be2ff7dSConrad Meyer 0x899345850ed0a286,
826be2ff7dSConrad Meyer 0x2302df11b4a43b15,
836be2ff7dSConrad Meyer 0xe943de7b3d35d70,
846be2ff7dSConrad Meyer 0xdf1ff2bf41abf56b,
856be2ff7dSConrad Meyer 0x9bc138abae315de2,
866be2ff7dSConrad Meyer 0x31cc82e56234f0ff,
876be2ff7dSConrad Meyer 0xce63c0cd6988e847,
886be2ff7dSConrad Meyer 0x3e42f6b78ee352fa,
896be2ff7dSConrad Meyer 0xfa4085436078cfa6,
906be2ff7dSConrad Meyer 0x53349558bf670a4b,
916be2ff7dSConrad Meyer 0x2714e10e7d722c61,
926be2ff7dSConrad Meyer 0xc0d3261addfc6908,
936be2ff7dSConrad Meyer 0xd1567c3181d3a1bf,
946be2ff7dSConrad Meyer };
956be2ff7dSConrad Meyer const uint32_t results[] = {
966be2ff7dSConrad Meyer 0x2ce33ede,
976be2ff7dSConrad Meyer 0xc49cc573,
986be2ff7dSConrad Meyer 0xb8683c96,
996be2ff7dSConrad Meyer 0x6918660d,
1006be2ff7dSConrad Meyer 0xa904e522,
1016be2ff7dSConrad Meyer 0x52dbc42c,
1026be2ff7dSConrad Meyer 0x98863c22,
1036be2ff7dSConrad Meyer 0x894d5d2c,
1046be2ff7dSConrad Meyer 0xb003745d,
1056be2ff7dSConrad Meyer 0xfc496dbd,
1066be2ff7dSConrad Meyer 0x97d2fbb5,
1076be2ff7dSConrad Meyer 0x3c062ef1,
1086be2ff7dSConrad Meyer 0xcc2eff18,
1096be2ff7dSConrad Meyer 0x6a9b09f6,
1106be2ff7dSConrad Meyer 0x420242c1,
1116be2ff7dSConrad Meyer 0xfd562dc3,
1126be2ff7dSConrad Meyer };
1136be2ff7dSConrad Meyer size_t i;
1146be2ff7dSConrad Meyer
1156be2ff7dSConrad Meyer ATF_REQUIRE(nitems(inputs) == nitems(results));
1166be2ff7dSConrad Meyer
1176be2ff7dSConrad Meyer for (i = 0; i < nitems(inputs); i++) {
118*83c20b8aSAlex Richardson check_crc32c(results[i], ~0u, &inputs[i], sizeof(inputs[0]));
1196be2ff7dSConrad Meyer }
1206be2ff7dSConrad Meyer }
1216be2ff7dSConrad Meyer
1226be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_alignment);
ATF_TC_BODY(crc32c_alignment,tc)1236be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_alignment, tc)
1246be2ff7dSConrad Meyer {
1256be2ff7dSConrad Meyer const uint64_t input = 0xf408c634b3a9142;
1266be2ff7dSConrad Meyer const uint32_t result = 0x2ce33ede;
1276be2ff7dSConrad Meyer unsigned char buf[15];
1286be2ff7dSConrad Meyer size_t i;
1296be2ff7dSConrad Meyer
1306be2ff7dSConrad Meyer for (i = 1; i < 8; i++) {
1316be2ff7dSConrad Meyer memcpy(&buf[i], &input, sizeof(input));
132*83c20b8aSAlex Richardson check_crc32c(result, ~0u, &buf[i], sizeof(input));
1336be2ff7dSConrad Meyer }
1346be2ff7dSConrad Meyer }
1356be2ff7dSConrad Meyer
1366be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_trailing_bytes);
ATF_TC_BODY(crc32c_trailing_bytes,tc)1376be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_trailing_bytes, tc)
1386be2ff7dSConrad Meyer {
1396be2ff7dSConrad Meyer const unsigned char input[] = {
1406be2ff7dSConrad Meyer 0x87, 0x54, 0x74, 0xd2, 0xb, 0x9b, 0xdd, 0xf6, 0x68, 0x37,
1416be2ff7dSConrad Meyer 0xd4, 0x4, 0x5e, 0xa9, 0xb3
1426be2ff7dSConrad Meyer };
1436be2ff7dSConrad Meyer const uint32_t result = 0xec638d62;
1446be2ff7dSConrad Meyer
145*83c20b8aSAlex Richardson check_crc32c(result, ~0u, input, sizeof(input));
1466be2ff7dSConrad Meyer }
1476be2ff7dSConrad Meyer
ATF_TP_ADD_TCS(tp)1486be2ff7dSConrad Meyer ATF_TP_ADD_TCS(tp)
1496be2ff7dSConrad Meyer {
1506be2ff7dSConrad Meyer
1516be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_basic_correctness);
1526be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_alignment);
1536be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_trailing_bytes);
1546be2ff7dSConrad Meyer return (atf_no_error());
1556be2ff7dSConrad Meyer }
156