OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [netinet/] [in_cksum_m68k.c] - Blame information for rev 389

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 * Copyright (c) 1988, 1992, 1993
3
 *      The Regents of the University of California.  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
 *      @(#)in_cksum.c  8.1 (Berkeley) 6/10/93
34
 * $Id: in_cksum_m68k.c,v 1.2 2001-09-27 12:01:55 chris Exp $
35
 */
36
 
37
#include <sys/param.h>
38
#include <sys/mbuf.h>
39
 
40
#if (defined (__mcf5200__))
41
# define IS_COLDFIRE 1
42
#else
43
# define IS_COLDFIRE 0
44
#endif
45
 
46
#define REDUCE { sum = (sum & 0xFFFF) + (sum >> 16); if (sum > 0xFFFF) sum -= 0xFFFF; }
47
 
48
/*
49
 * Motorola 68k version of Internet Protocol Checksum routine
50
 * W. Eric Norum
51
 * Saskatchewan Accelerator Laboratory
52
 * August, 1998
53
 */
54
int
55
in_cksum(m, len)
56
        struct mbuf *m;
57
        int len;
58
{
59
        unsigned short *w;
60
        unsigned long sum = 0;
61
        int mlen = 0;
62
        int byte_swapped = 0;
63
        union {
64
                char    c[2];
65
                u_short s;
66
        } s_util;
67
 
68
        for ( ; m && len ; m = m->m_next) {
69
                if (m->m_len == 0)
70
                        continue;
71
                w = mtod(m, u_short *);
72
                if (mlen == -1) {
73
                        /*
74
                         * The first byte of this mbuf is the continuation
75
                         * of a word spanning between this mbuf and the
76
                         * last mbuf.
77
                         *
78
                         * s_util.c[0] is already saved when scanning previous
79
                         * mbuf.
80
                         */
81
                        s_util.c[1] = *(char *)w;
82
                        sum += s_util.s;
83
                        w = (u_short *)((char *)w + 1);
84
                        mlen = m->m_len - 1;
85
                        len--;
86
                } else
87
                        mlen = m->m_len;
88
                if (len < mlen)
89
                        mlen = len;
90
                len -= mlen;
91
 
92
                /*
93
                 * Force to longword boundary.
94
                 */
95
                if (3 & (int)w) {
96
                        REDUCE;
97
                        if ((1 & (int) w) && (mlen > 0)) {
98
                                sum <<= 8;
99
                                s_util.c[0] = *(u_char *)w;
100
                                w = (u_short *)((char *)w + 1);
101
                                mlen--;
102
                                byte_swapped = 1;
103
                        }
104
                        if ((2 & (int) w) && (mlen >= 2)) {
105
                                sum += *w++;
106
                                mlen -= 2;
107
                        }
108
                }
109
 
110
                /*
111
                 * Sum all the longwords in the buffer.
112
                 * See RFC 1071 -- Computing the Internet Checksum.
113
                 * It should work for all 68k family members.
114
                 */
115
                {
116
                unsigned long tcnt = mlen, t1;
117
                __asm__ volatile (
118
                "movel   %2,%3\n\t"
119
                "lsrl    #6,%2       | count/64 = # loop traversals\n\t"
120
                "andl    #0x3c,%3    | Then find fractions of a chunk\n\t"
121
                "negl    %3\n\t      | Each long uses 4 instruction bytes\n\t"
122
#if IS_COLDFIRE
123
                "addql   #1,%2       | Clear X (extended carry flag)\n\t"
124
                "subql   #1,%2       | \n\t"
125
#else
126
                "andi    #0xf,%%cc   | Clear X (extended carry flag)\n\t"
127
#endif
128
                "jmp     %%pc@(lcsum2_lbl-.-2:b,%3)  | Jump into loop\n"
129
                "lcsum1_lbl:         | Begin inner loop...\n\t"
130
                "movel   %1@+,%3     |  0: Fetch 32-bit word\n\t"
131
                "addxl   %3,%0       |    Add word + previous carry\n\t"
132
                "movel   %1@+,%3     |  1: Fetch 32-bit word\n\t"
133
                "addxl   %3,%0       |    Add word + previous carry\n\t"
134
                "movel   %1@+,%3     |  2: Fetch 32-bit word\n\t"
135
                "addxl   %3,%0       |    Add word + previous carry\n\t"
136
                "movel   %1@+,%3     |  3: Fetch 32-bit word\n\t"
137
                "addxl   %3,%0       |    Add word + previous carry\n\t"
138
                "movel   %1@+,%3     |  4: Fetch 32-bit word\n\t"
139
                "addxl   %3,%0       |    Add word + previous carry\n\t"
140
                "movel   %1@+,%3     |  5: Fetch 32-bit word\n\t"
141
                "addxl   %3,%0       |    Add word + previous carry\n\t"
142
                "movel   %1@+,%3     |  6: Fetch 32-bit word\n\t"
143
                "addxl   %3,%0       |    Add word + previous carry\n\t"
144
                "movel   %1@+,%3     |  7: Fetch 32-bit word\n\t"
145
                "addxl   %3,%0       |    Add word + previous carry\n\t"
146
                "movel   %1@+,%3     |  8: Fetch 32-bit word\n\t"
147
                "addxl   %3,%0       |    Add word + previous carry\n\t"
148
                "movel   %1@+,%3     |  9: Fetch 32-bit word\n\t"
149
                "addxl   %3,%0       |    Add word + previous carry\n\t"
150
                "movel   %1@+,%3     |  A: Fetch 32-bit word\n\t"
151
                "addxl   %3,%0       |    Add word + previous carry\n\t"
152
                "movel   %1@+,%3     |  B: Fetch 32-bit word\n\t"
153
                "addxl   %3,%0       |    Add word + previous carry\n\t"
154
                "movel   %1@+,%3     |  C: Fetch 32-bit word\n\t"
155
                "addxl   %3,%0       |    Add word + previous carry\n\t"
156
                "movel   %1@+,%3     |  D: Fetch 32-bit word\n\t"
157
                "addxl   %3,%0       |    Add word + previous carry\n\t"
158
                "movel   %1@+,%3     |  E: Fetch 32-bit word\n\t"
159
                "addxl   %3,%0       |    Add word + previous carry\n\t"
160
                "movel   %1@+,%3     |  F: Fetch 32-bit word\n\t"
161
                "addxl   %3,%0       |    Add word + previous carry\n"
162
                "lcsum2_lbl:         |  End of unrolled loop\n\t"
163
#if IS_COLDFIRE
164
                "moveq   #0,%3       | Add in last carry\n\t"
165
                "addxl   %3,%0       |\n\t"
166
                "subql   #1,%2       | Update loop count\n\t"
167
                "bplb    lcsum1_lbl  | Loop (with X clear) if not done\n\t"
168
                "movel   #0xffff,%2  | Get word mask\n\t"
169
                "movel   %0,%3       | Fold 32 bit sum to 16 bits\n\t"
170
                "swap    %3          |\n\t"
171
                "andl    %2,%0       | Mask to 16-bit sum\n\t"
172
                "andl    %2,%3       | Mask to 16-bit sum\n\t"
173
                "addl    %3,%0       |\n\t"
174
                "movel   %0,%3       | Add in last carry\n\t"
175
                "swap    %3          |\n\t"
176
                "addl    %3,%0       |\n\t"
177
                "andl    %2,%0       | Mask to 16-bit sum\n\t"
178
#else
179
                "dbf     %2,lcsum1_lbl | (NB- dbf doesn't affect X)\n\t"
180
                "movel   %0,%3       | Fold 32 bit sum to 16 bits\n\t"
181
                "swap    %3          | (NB- swap doesn't affect X)\n\t"
182
                "addxw   %3,%0       |\n\t"
183
                "moveq   #0,%3       | Add in last carry\n\t"
184
                "addxw   %3,%0       |\n\t"
185
                "andl    #0xffff,%0  | Mask to 16-bit sum\n"
186
#endif
187
                        :
188
                        "=d" (sum), "=a" (w), "=d" (tcnt) , "=d" (t1) :
189
                        "0" (sum), "1" (w), "2" (tcnt) :
190
                        "cc", "memory");
191
                }
192
                mlen &= 3;
193
 
194
                /*
195
                 * Soak up the last 1, 2 or 3 bytes
196
                 */
197
                while ((mlen -= 2) >= 0)
198
                        sum += *w++;
199
                if (byte_swapped) {
200
                        REDUCE;
201
                        sum <<= 8;
202
                        byte_swapped = 0;
203
                        if (mlen == -1) {
204
                                s_util.c[1] = *(char *)w;
205
                                sum += s_util.s;
206
                                mlen = 0;
207
                        } else
208
                                mlen = -1;
209
                } else if (mlen == -1)
210
                        s_util.c[0] = *(char *)w;
211
        }
212
        if (len)
213
                sum = 0xDEAD;
214
        if (mlen == -1) {
215
                /* The last mbuf has odd # of bytes. Follow the
216
                   standard (the odd byte may be shifted left by 8 bits
217
                   or not as determined by endian-ness of the machine) */
218
                s_util.c[1] = 0;
219
                sum += s_util.s;
220
        }
221
        REDUCE;
222
        return (~sum & 0xffff);
223
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.