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