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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-sh64/] [checksum.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1276 phoenix
#ifndef __ASM_SH64_CHECKSUM_H
2
#define __ASM_SH64_CHECKSUM_H
3
 
4
/*
5
 * This file is subject to the terms and conditions of the GNU General Public
6
 * License.  See the file "COPYING" in the main directory of this archive
7
 * for more details.
8
 *
9
 * include/asm-sh64/checksum.h
10
 *
11
 * Copyright (C) 2000, 2001  Paolo Alberelli
12
 *
13
 */
14
 
15
#include <asm/registers.h>
16
 
17
/*
18
 * computes the checksum of a memory block at buff, length len,
19
 * and adds in "sum" (32-bit)
20
 *
21
 * returns a 32-bit number suitable for feeding into itself
22
 * or csum_tcpudp_magic
23
 *
24
 * this function must be called with even lengths, except
25
 * for the last fragment, which may be odd
26
 *
27
 * it's best to have buff aligned on a 32-bit boundary
28
 */
29
asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
30
//x
31
 
32
/*
33
 *      Note: when you get a NULL pointer exception here this means someone
34
 *      passed in an incorrect kernel address to one of these functions.
35
 *
36
 *      If you use these functions directly please don't forget the
37
 *      verify_area().
38
 */
39
 
40
 
41
#ifdef DJM_USE_ASM_CHECKSUM
42
 
43
/*
44
 * the same as csum_partial, but copies from src while it
45
 * checksums, and handles user-space pointer exceptions correctly, when needed.
46
 *
47
 * here even more important to align src and dst on a 32-bit (or even
48
 * better 64-bit) boundary
49
 */
50
 
51
asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
52
                                                   int *src_err_ptr, int *dst_err_ptr);
53
extern __inline__
54
unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
55
                                        int len, int sum)
56
{
57
        return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
58
}
59
#else
60
// Pre SIM:
61
//#define csum_partial_copy_nocheck csum_partial_copy
62
// Post SIM:
63
unsigned int
64
csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum);
65
#endif
66
 
67
#ifdef DJM_USE_ASM_CHECKSUM
68
 
69
extern __inline__
70
unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
71
                                                int len, unsigned int sum, int *err_ptr)
72
{
73
        return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
74
}
75
#else 
76
unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
77
                                           int len, int sum, int *err_ptr);
78
//x
79
#endif
80
 
81
 
82
/*
83
 * These are the old (and unsafe) way of doing checksums, a warning message will be
84
 * printed if they are used and an exeption occurs.
85
 *
86
 * these functions should go away after some time.
87
 */
88
 
89
#define csum_partial_copy_fromuser csum_partial_copy
90
//x
91
unsigned int csum_partial_copy( const char *src, char *dst, int len, unsigned int sum);
92
//x
93
 
94
/*
95
 *      Fold a partial checksum
96
 */
97
 
98
#ifdef DJM_USE_ASM_CHECKSUM
99
static __inline__ unsigned int csum_fold(unsigned int sum)
100
{
101
        unsigned long long __dummy;
102
        __asm__("mshflo.w       r63, %0, %0\n\t"
103
                "mshflo.w       %0, r63, %1\n\t"
104
                "mshfhi.w       %0, r63, %0\n\t"
105
                "add            %0, %1, %0\n\t"
106
                "shlli          %0, 16, %1\n\t"
107
                "add            %0, %1, %0\n\t"
108
                "sub            r63, %0, %0\n\t"
109
                "shlri          %0, 48, %0"
110
                : "=r" (sum), "=&r" (__dummy)
111
                : "0" (sum));
112
        return sum;
113
}
114
#else
115
 
116
static inline unsigned short csum_fold(unsigned int sum)
117
//x
118
{
119
        sum = (sum & 0xffff) + (sum >> 16);
120
        sum = (sum & 0xffff) + (sum >> 16);
121
        return ~(sum);
122
}
123
#endif
124
 
125
 
126
 
127
 
128
#ifdef DJM_USE_ASM_CHECKSUM
129
/*
130
 *      This is a version of ip_compute_csum() optimized for IP headers,
131
 *      which always checksum on 4 octet boundaries.
132
 *
133
 *      i386 version by Jorge Cwik <jorge@laser.satlink.net>, adapted
134
 *      for linux by * Arnt Gulbrandsen.
135
 */
136
static __inline__ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
137
{
138
        unsigned long long sum, __dummy0, __dummy1;
139
 
140
        __asm__ __volatile__(
141
                "or     r63, r63, %0\n\t"       /* Clear upper part */
142
                "or     r63, r63, %3\n\t"       /* Clear upper part */
143
                "gettr  " __t0 ", %4\n\t"               /* t0 saving */
144
 
145
                /* Less waste using .UW than removing sign extension */
146
                "shlli  %2, 1, %2\n\t"          /* Longs -> Shorts */
147
                "addi   %2, -2, %2\n\t"         /* Last Short to start from */
148
                "ldx.uw %1, %2, %0\n\t"         /* Get last */
149
                "addi   %2, -2, %2\n\t"         /* Do it reverse */
150
                "_pta   4, " __t0 "\n\t"
151
 
152
                "ldx.uw %1, %2, %3\n\t"
153
                "add    %0, %3, %0\n\t"         /* Do the sum */
154
                "shlri  %0, 16, %3\n\t"
155
                "add    %0, %3, %0\n\t"         /* Fold it now */
156
                "shlli  %3, 16, %3\n\t"
157
                "sub    %0, %3, %0\n\t"         /* Remove carry, if any */
158
                "addi   %2, -2, %2\n\t"         /* Do it reverse */
159
                "bnei   %2, -2, " __t0 "\n\t"
160
 
161
                "shlli  %0, 48, %0\n\t"         /* Not sure this is required */
162
                "sub    r63, %0, %0\n\t"        /* Not */
163
                "shlri  %0, 48, %0\n\t"         /* Not sure this is required */
164
                "ptabs  %4, " __t0 "\n\t"
165
 
166
        : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (__dummy0), "=r" (__dummy1)
167
        : "1" (iph), "2" (ihl));
168
 
169
        return (unsigned short) sum;
170
}
171
#else
172
unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
173
//x
174
#endif
175
 
176
 
177
#ifdef DJM_USE_ASM_CHECKSUM
178
 
179
static __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
180
                                                   unsigned long daddr,
181
                                                   unsigned short len,
182
                                                   unsigned short proto,
183
                                                   unsigned int sum)
184
{
185
#ifdef __LITTLE_ENDIAN__
186
        unsigned long len_proto = (ntohs(len)<<16)+proto*256;
187
#else
188
        unsigned long len_proto = (proto<<16)+len;
189
#endif
190
        __asm__("add    %0, %1, %0\n\t"
191
                "add    %0, %2, %0\n\t"
192
                "add    %0, %3, %0\n\t"
193
                "shlri  %0, 32, %1\n\t"
194
                "add    %0, %1, %0\n\t"         /* Fold it to a long */
195
                "shlli  %1, 32, %1\n\t"
196
                "sub    %0, %1, %0\n\t"         /* Remove carry, if any */
197
                : "=r" (sum), "=r" (len_proto)
198
                : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum));
199
 
200
        return sum;
201
}
202
#else
203
unsigned long csum_tcpudp_nofold(unsigned long saddr,
204
                                                   unsigned long daddr,
205
                                                   unsigned short len,
206
                                                   unsigned short proto,
207
                                 unsigned int sum) ;
208
//x
209
#endif
210
 
211
/*
212
 * computes the checksum of the TCP/UDP pseudo-header
213
 * returns a 16-bit checksum, already complemented
214
 */
215
static __inline__ unsigned short int csum_tcpudp_magic(unsigned long saddr,
216
                                                       unsigned long daddr,
217
                                                       unsigned short len,
218
                                                       unsigned short proto,
219
                                                       unsigned int sum)
220
//x
221
{
222
  unsigned short int x;
223
  //printk("csum_tcpudp_magic saddr %08x daddr %08x len %04x proto %04x sum %08x\n",
224
  //     saddr,daddr,len,proto,sum);
225
  x = csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
226
  //printk("csum_tcpudp_magic returning %04x\n", x);
227
  return x;
228
}
229
 
230
/*
231
 * this routine is used for miscellaneous IP-like checksums, mainly
232
 * in icmp.c
233
 */
234
 
235
static __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len)
236
//x
237
{
238
    return csum_fold (csum_partial(buff, len, 0));
239
}
240
 
241
 
242
#ifdef DJM_USE_ASM_CHECKSUM
243
#define _HAVE_ARCH_IPV6_CSUM
244
static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
245
                                                     struct in6_addr *daddr,
246
                                                     __u32 len,
247
                                                     unsigned short proto,
248
                                                     unsigned int sum)
249
{
250
        unsigned int __dummy;
251
 
252
        __asm__("ld.l   %2, 0, %1\n\t"
253
                "add    %0, %1, %0\n\t"
254
                "ld.l   %2, 4, %1\n\t"
255
                "add    %0, %1, %0\n\t"
256
                "ld.l   %2, 8, %1\n\t"
257
                "add    %0, %1, %0\n\t"
258
                "ld.l   %2, 12, %1\n\t"
259
                "add    %0, %1, %0\n\t"
260
                "ld.l   %3, 0, %1\n\t"
261
                "add    %0, %1, %0\n\t"
262
                "ld.l   %3, 4, %1\n\t"
263
                "add    %0, %1, %0\n\t"
264
                "ld.l   %3, 8, %1\n\t"
265
                "add    %0, %1, %0\n\t"
266
                "ld.l   %3, 12, %1\n\t"
267
                "add    %0, %1, %0\n\t"
268
                "add    %0, %4, %0\n\t"
269
                "add    %0, %5, %0\n\t"
270
                "shlri  %0, 32, %1\n\t"
271
                "add    %0, %1, %0\n\t"         /* Fold it to a long */
272
                "shlli  %1, 32, %1\n\t"
273
                "sub    %0, %1, %0\n\t"         /* Remove carry, if any */
274
                : "=r" (sum), "=&r" (__dummy)
275
                : "r" (saddr), "r" (daddr),
276
                  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
277
 
278
        return csum_fold(sum);
279
}
280
#endif
281
 
282
 
283
#ifdef DJM_USE_ASM_CHECKSUM
284
/*
285
 *      Copy and checksum to user
286
 */
287
 
288
 
289
#define HAVE_CSUM_COPY_USER
290
static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
291
                                    int len, int sum, int *err_ptr)
292
{
293
        if (access_ok(VERIFY_WRITE, dst, len))
294
                return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
295
 
296
        if (len)
297
                *err_ptr = -EFAULT;
298
 
299
        return -1; /* invalid checksum */
300
}
301
 
302
#endif
303
 
304
 
305
#endif /* __ASM_SH64_CHECKSUM_H */
306
 
307
 
308
 
309
 
310
 
311
 
312
 
313
 
314
 
315
 
316
 
317
 
318
 
319
 
320
 
321
 

powered by: WebSVN 2.1.0

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