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