1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * from tahoe: in_cksum.c 1.2 86/01/05 34 * from: @(#)in_cksum.c 1.3 (Berkeley) 1/19/91 35 * from: Id: in_cksum.c,v 1.8 1995/12/03 18:35:19 bde Exp 36 * $FreeBSD$ 37 */ 38 39 #ifndef _MACHINE_IN_CKSUM_H_ 40 #define _MACHINE_IN_CKSUM_H_ 1 41 42 #include <sys/cdefs.h> 43 44 #ifdef _KERNEL 45 u_short in_cksum(struct mbuf *m, int len); 46 u_short in_addword(u_short sum, u_short b); 47 u_short in_cksum_skip(struct mbuf *m, int len, int skip); 48 u_int do_cksum(const void *, int); 49 static __inline u_int 50 in_cksum_hdr(const struct ip *ip) 51 { 52 u_int sum = 0; 53 u_int tmp1, tmp2, tmp3, tmp4; 54 55 if (((vm_offset_t)ip & 0x03) == 0) 56 __asm __volatile ( 57 "adds %0, %0, %1\n" 58 "adcs %0, %0, %2\n" 59 "adcs %0, %0, %3\n" 60 "adcs %0, %0, %4\n" 61 "adcs %0, %0, %5\n" 62 "adc %0, %0, #0\n" 63 : "+r" (sum) 64 : "r" (((const u_int32_t *)ip)[0]), 65 "r" (((const u_int32_t *)ip)[1]), 66 "r" (((const u_int32_t *)ip)[2]), 67 "r" (((const u_int32_t *)ip)[3]), 68 "r" (((const u_int32_t *)ip)[4]) 69 ); 70 else 71 __asm __volatile ( 72 "and %1, %5, #3\n" 73 "cmp %1, #0x02\n" 74 "ldrb %2, [%5], #0x01\n" 75 "ldrgeb %3, [%5], #0x01\n" 76 "movlt %3, #0\n" 77 "ldrgtb %4, [%5], #0x01\n" 78 "movle %4, #0x00\n" 79 #ifdef __ARMEB__ 80 "orreq %0, %3, %2, lsl #8\n" 81 "orreq %0, %0, %4, lsl #24\n" 82 "orrne %0, %0, %3, lsl #8\n" 83 "orrne %0, %0, %4, lsl #16\n" 84 #else 85 "orreq %0, %2, %3, lsl #8\n" 86 "orreq %0, %0, %4, lsl #16\n" 87 "orrne %0, %3, %2, lsl #8\n" 88 "orrne %0, %0, %4, lsl #24\n" 89 #endif 90 "ldmia %5, {%2, %3, %4}\n" 91 "adcs %0, %0, %2\n" 92 "adcs %0, %0, %3\n" 93 "adcs %0, %0, %4\n" 94 "ldrb %2, [%5]\n" 95 "cmp %1, #0x02\n" 96 "ldrgeb %3, [%5, #0x01]\n" 97 "movlt %3, #0x00\n" 98 "ldrgtb %4, [%5, #0x02]\n" 99 "movle %4, #0x00\n" 100 "tst %5, #0x01\n" 101 #ifdef __ARMEB__ 102 "orreq %2, %3, %2, lsl #8\n" 103 "orreq %2, %2, %4, lsl #24\n" 104 "orrne %2, %2, %3, lsl #8\n" 105 "orrne %2, %2, %4, lsl #16\n" 106 #else 107 "orreq %2, %2, %3, lsl #8\n" 108 "orreq %2, %2, %4, lsl #16\n" 109 "orrne %2, %3, %2, lsl #8\n" 110 "orrne %2, %2, %4, lsl #24\n" 111 #endif 112 "adds %0, %0, %2\n" 113 "adc %0, %0, #0\n" 114 : "+r" (sum), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), 115 "=r" (tmp4) 116 : "r" (ip)); 117 118 sum = (sum & 0xffff) + (sum >> 16); 119 if (sum > 0xffff) 120 sum -= 0xffff; 121 return (~sum & 0xffff); 122 } 123 124 static __inline u_short 125 in_pseudo(u_int sum, u_int b, u_int c) 126 { 127 __asm __volatile("adds %0, %0, %1\n" 128 "adcs %0, %0, %2\n" 129 "adc %0, %0, #0\n" 130 : "+r" (sum) 131 : "r" (b), "r" (c)); 132 sum = (sum & 0xffff) + (sum >> 16); 133 if (sum > 0xffff) 134 sum -= 0xffff; 135 return (sum); 136 } 137 138 #endif /* _KERNEL */ 139 #endif /* _MACHINE_IN_CKSUM_H_ */ 140