1*6bbe0590SSundeep Panicker /* 2*6bbe0590SSundeep Panicker * CDDL HEADER START 3*6bbe0590SSundeep Panicker * 4*6bbe0590SSundeep Panicker * The contents of this file are subject to the terms of the 5*6bbe0590SSundeep Panicker * Common Development and Distribution License (the "License"). 6*6bbe0590SSundeep Panicker * You may not use this file except in compliance with the License. 7*6bbe0590SSundeep Panicker * 8*6bbe0590SSundeep Panicker * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*6bbe0590SSundeep Panicker * or http://www.opensolaris.org/os/licensing. 10*6bbe0590SSundeep Panicker * See the License for the specific language governing permissions 11*6bbe0590SSundeep Panicker * and limitations under the License. 12*6bbe0590SSundeep Panicker * 13*6bbe0590SSundeep Panicker * When distributing Covered Code, include this CDDL HEADER in each 14*6bbe0590SSundeep Panicker * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*6bbe0590SSundeep Panicker * If applicable, add the following below this CDDL HEADER, with the 16*6bbe0590SSundeep Panicker * fields enclosed by brackets "[]" replaced with your own identifying 17*6bbe0590SSundeep Panicker * information: Portions Copyright [yyyy] [name of copyright owner] 18*6bbe0590SSundeep Panicker * 19*6bbe0590SSundeep Panicker * CDDL HEADER END 20*6bbe0590SSundeep Panicker */ 21*6bbe0590SSundeep Panicker 22*6bbe0590SSundeep Panicker /* 23*6bbe0590SSundeep Panicker * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*6bbe0590SSundeep Panicker * Use is subject to license terms. 25*6bbe0590SSundeep Panicker */ 26*6bbe0590SSundeep Panicker 27*6bbe0590SSundeep Panicker /* 28*6bbe0590SSundeep Panicker * 29*6bbe0590SSundeep Panicker * Start of crcmodel.c 30*6bbe0590SSundeep Panicker * 31*6bbe0590SSundeep Panicker * 32*6bbe0590SSundeep Panicker * Author : Ross Williams (ross@guest.adelaide.edu.au.). 33*6bbe0590SSundeep Panicker * Date : 3 June 1993. 34*6bbe0590SSundeep Panicker * Status : Public domain. 35*6bbe0590SSundeep Panicker * 36*6bbe0590SSundeep Panicker * Description : This is the implementation (.c) file for the reference 37*6bbe0590SSundeep Panicker * implementation of the Rocksoft^tm Model CRC Algorithm. For more 38*6bbe0590SSundeep Panicker * information on the Rocksoft^tm Model CRC Algorithm, see the document 39*6bbe0590SSundeep Panicker * titled "A Painless Guide to CRC Error Detection Algorithms" by Ross 40*6bbe0590SSundeep Panicker * Williams (ross@guest.adelaide.edu.au.). This document is likely to be in 41*6bbe0590SSundeep Panicker * "ftp.adelaide.edu.au/pub/rocksoft". 42*6bbe0590SSundeep Panicker * 43*6bbe0590SSundeep Panicker * Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. 44*6bbe0590SSundeep Panicker * 45*6bbe0590SSundeep Panicker * 46*6bbe0590SSundeep Panicker * 47*6bbe0590SSundeep Panicker * Implementation Notes 48*6bbe0590SSundeep Panicker * -------------------- 49*6bbe0590SSundeep Panicker * To avoid inconsistencies, the specification of each function is not echoed 50*6bbe0590SSundeep Panicker * here. See the header file for a description of these functions. 51*6bbe0590SSundeep Panicker * This package is light on checking because I want to keep it short and 52*6bbe0590SSundeep Panicker * simple and portable (i.e. it would be too messy to distribute my entire 53*6bbe0590SSundeep Panicker * C culture (e.g. assertions package) with this package. 54*6bbe0590SSundeep Panicker * 55*6bbe0590SSundeep Panicker * 56*6bbe0590SSundeep Panicker */ 57*6bbe0590SSundeep Panicker 58*6bbe0590SSundeep Panicker #include "crcmodel.h" 59*6bbe0590SSundeep Panicker 60*6bbe0590SSundeep Panicker /* The following definitions make the code more readable. */ 61*6bbe0590SSundeep Panicker 62*6bbe0590SSundeep Panicker #define BITMASK(X) (1L << (X)) 63*6bbe0590SSundeep Panicker #define MASK32 0xFFFFFFFFL 64*6bbe0590SSundeep Panicker #define LOCAL static 65*6bbe0590SSundeep Panicker 66*6bbe0590SSundeep Panicker LOCAL uint32_t reflect P_((uint32_t v, int b)); 67*6bbe0590SSundeep Panicker LOCAL uint32_t 68*6bbe0590SSundeep Panicker reflect(v, b) 69*6bbe0590SSundeep Panicker /* Returns the value v with the bottom b [0,32] bits reflected. */ 70*6bbe0590SSundeep Panicker /* Example: reflect(0x3e23L,3) == 0x3e26 */ 71*6bbe0590SSundeep Panicker uint32_t v; 72*6bbe0590SSundeep Panicker int b; 73*6bbe0590SSundeep Panicker { 74*6bbe0590SSundeep Panicker int i; 75*6bbe0590SSundeep Panicker uint32_t t = v; 76*6bbe0590SSundeep Panicker for (i = 0; i < b; i++) { 77*6bbe0590SSundeep Panicker if (t & 1L) 78*6bbe0590SSundeep Panicker v |= BITMASK((b-1)-i); 79*6bbe0590SSundeep Panicker else 80*6bbe0590SSundeep Panicker v &= ~BITMASK((b-1)-i); 81*6bbe0590SSundeep Panicker t >>= 1; 82*6bbe0590SSundeep Panicker } 83*6bbe0590SSundeep Panicker return (v); 84*6bbe0590SSundeep Panicker } 85*6bbe0590SSundeep Panicker 86*6bbe0590SSundeep Panicker LOCAL uint32_t widmask P_((p_cm_t)); 87*6bbe0590SSundeep Panicker LOCAL uint32_t 88*6bbe0590SSundeep Panicker widmask(p_cm) 89*6bbe0590SSundeep Panicker /* Returns a longword whose value is (2^p_cm->cm_width)-1. */ 90*6bbe0590SSundeep Panicker /* The trick is to do this portably (e.g. without doing <<32). */ 91*6bbe0590SSundeep Panicker p_cm_t p_cm; 92*6bbe0590SSundeep Panicker { 93*6bbe0590SSundeep Panicker return ((((1L<<(p_cm->cm_width-1))-1L)<<1)|1L); 94*6bbe0590SSundeep Panicker } 95*6bbe0590SSundeep Panicker 96*6bbe0590SSundeep Panicker void 97*6bbe0590SSundeep Panicker cm_ini(p_cm) 98*6bbe0590SSundeep Panicker p_cm_t p_cm; 99*6bbe0590SSundeep Panicker { 100*6bbe0590SSundeep Panicker p_cm->cm_reg = p_cm->cm_init; 101*6bbe0590SSundeep Panicker } 102*6bbe0590SSundeep Panicker 103*6bbe0590SSundeep Panicker void 104*6bbe0590SSundeep Panicker cm_nxt(p_cm, ch) 105*6bbe0590SSundeep Panicker p_cm_t p_cm; 106*6bbe0590SSundeep Panicker int ch; 107*6bbe0590SSundeep Panicker { 108*6bbe0590SSundeep Panicker int i; 109*6bbe0590SSundeep Panicker uint32_t uch = (uint32_t)ch; 110*6bbe0590SSundeep Panicker uint32_t topbit = BITMASK(p_cm->cm_width-1); 111*6bbe0590SSundeep Panicker 112*6bbe0590SSundeep Panicker if (p_cm->cm_refin) 113*6bbe0590SSundeep Panicker uch = reflect(uch, 8); 114*6bbe0590SSundeep Panicker 115*6bbe0590SSundeep Panicker p_cm->cm_reg ^= (uch << (p_cm->cm_width-8)); 116*6bbe0590SSundeep Panicker for (i = 0; i < 8; i++) { 117*6bbe0590SSundeep Panicker if (p_cm->cm_reg & topbit) 118*6bbe0590SSundeep Panicker p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly; 119*6bbe0590SSundeep Panicker else 120*6bbe0590SSundeep Panicker p_cm->cm_reg <<= 1; 121*6bbe0590SSundeep Panicker 122*6bbe0590SSundeep Panicker p_cm->cm_reg &= widmask(p_cm); 123*6bbe0590SSundeep Panicker } 124*6bbe0590SSundeep Panicker } 125*6bbe0590SSundeep Panicker 126*6bbe0590SSundeep Panicker void 127*6bbe0590SSundeep Panicker cm_blk(p_cm, blk_adr, blk_len) 128*6bbe0590SSundeep Panicker p_cm_t p_cm; 129*6bbe0590SSundeep Panicker p_ubyte_ blk_adr; 130*6bbe0590SSundeep Panicker uint32_t blk_len; 131*6bbe0590SSundeep Panicker { 132*6bbe0590SSundeep Panicker while (blk_len--) 133*6bbe0590SSundeep Panicker cm_nxt(p_cm, *blk_adr++); 134*6bbe0590SSundeep Panicker } 135*6bbe0590SSundeep Panicker 136*6bbe0590SSundeep Panicker uint32_t 137*6bbe0590SSundeep Panicker cm_crc(p_cm) 138*6bbe0590SSundeep Panicker p_cm_t p_cm; 139*6bbe0590SSundeep Panicker { 140*6bbe0590SSundeep Panicker if (p_cm->cm_refot) 141*6bbe0590SSundeep Panicker return (p_cm->cm_xorot ^ reflect(p_cm->cm_reg, p_cm->cm_width)); 142*6bbe0590SSundeep Panicker else 143*6bbe0590SSundeep Panicker return (p_cm->cm_xorot ^ p_cm->cm_reg); 144*6bbe0590SSundeep Panicker } 145*6bbe0590SSundeep Panicker 146*6bbe0590SSundeep Panicker uint32_t 147*6bbe0590SSundeep Panicker cm_tab(p_cm, index) 148*6bbe0590SSundeep Panicker p_cm_t p_cm; 149*6bbe0590SSundeep Panicker int index; 150*6bbe0590SSundeep Panicker { 151*6bbe0590SSundeep Panicker int i; 152*6bbe0590SSundeep Panicker uint32_t r; 153*6bbe0590SSundeep Panicker uint32_t topbit = BITMASK(p_cm->cm_width-1); 154*6bbe0590SSundeep Panicker uint32_t inbyte = (uint32_t)index; 155*6bbe0590SSundeep Panicker 156*6bbe0590SSundeep Panicker if (p_cm->cm_refin) 157*6bbe0590SSundeep Panicker inbyte = reflect(inbyte, 8); 158*6bbe0590SSundeep Panicker 159*6bbe0590SSundeep Panicker r = inbyte << (p_cm->cm_width-8); 160*6bbe0590SSundeep Panicker for (i = 0; i < 8; i++) 161*6bbe0590SSundeep Panicker if (r & topbit) 162*6bbe0590SSundeep Panicker r = (r << 1) ^ p_cm->cm_poly; 163*6bbe0590SSundeep Panicker else 164*6bbe0590SSundeep Panicker r <<= 1; 165*6bbe0590SSundeep Panicker 166*6bbe0590SSundeep Panicker if (p_cm->cm_refin) 167*6bbe0590SSundeep Panicker r = reflect(r, p_cm->cm_width); 168*6bbe0590SSundeep Panicker 169*6bbe0590SSundeep Panicker return (r & widmask(p_cm)); 170*6bbe0590SSundeep Panicker } 171