diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-10-09 22:52:54 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-10-10 09:08:23 +0200 |
commit | e599318e912d8836c59d8b5202e3e31a6b8dcae9 (patch) | |
tree | 1172b8b830a1c3236e45c834c2b80e01325ea144 /freebsd/sys/arm/arm/in_cksum.c | |
parent | Move files to match FreeBSD layout (diff) | |
download | rtems-libbsd-e599318e912d8836c59d8b5202e3e31a6b8dcae9.tar.bz2 |
Update files to match FreeBSD layout
Add compatibility with Newlib header files. Some FreeBSD header files
are mapped by the translation script:
o rtems/bsd/sys/_types.h
o rtems/bsd/sys/errno.h
o rtems/bsd/sys/lock.h
o rtems/bsd/sys/param.h
o rtems/bsd/sys/resource.h
o rtems/bsd/sys/time.h
o rtems/bsd/sys/timespec.h
o rtems/bsd/sys/types.h
o rtems/bsd/sys/unistd.h
It is now possible to include <sys/socket.h> directly for example.
Generate one Makefile which builds everything including tests.
Diffstat (limited to 'freebsd/sys/arm/arm/in_cksum.c')
-rw-r--r-- | freebsd/sys/arm/arm/in_cksum.c | 163 |
1 files changed, 132 insertions, 31 deletions
diff --git a/freebsd/sys/arm/arm/in_cksum.c b/freebsd/sys/arm/arm/in_cksum.c index db98915d..c6f7b568 100644 --- a/freebsd/sys/arm/arm/in_cksum.c +++ b/freebsd/sys/arm/arm/in_cksum.c @@ -1,6 +1,4 @@ -#include <freebsd/machine/rtems-bsd-config.h> - -/* $NetBSD: in_cksum.c,v 1.7 1997/09/02 13:18:15 thorpej Exp $ */ +#include <machine/rtems-bsd-config.h> /*- * Copyright (c) 1988, 1992, 1993 @@ -39,16 +37,16 @@ * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 */ -#include <freebsd/sys/cdefs.h> /* RCS ID & Copyright macro defns */ +#include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <freebsd/sys/param.h> -#include <freebsd/sys/mbuf.h> -#include <freebsd/sys/systm.h> -#include <freebsd/netinet/in_systm.h> -#include <freebsd/netinet/in.h> -#include <freebsd/netinet/ip.h> -#include <freebsd/machine/in_cksum.h> +#include <rtems/bsd/sys/param.h> +#include <sys/mbuf.h> +#include <sys/systm.h> +#include <netinet/in_systm.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <machine/in_cksum.h> /* * Checksum routine for Internet Protocol family headers @@ -72,6 +70,22 @@ __FBSDID("$FreeBSD$"); ADDCARRY(sum); \ } +static const u_int32_t in_masks[] = { +#if _BYTE_ORDER == _LITTLE_ENDIAN + /*0 bytes*/ /*1 byte*/ /*2 bytes*/ /*3 bytes*/ + 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF, /* offset 0 */ + 0x00000000, 0x0000FF00, 0x00FFFF00, 0xFFFFFF00, /* offset 1 */ + 0x00000000, 0x00FF0000, 0xFFFF0000, 0xFFFF0000, /* offset 2 */ + 0x00000000, 0xFF000000, 0xFF000000, 0xFF000000, /* offset 3 */ +#else + /*0 bytes*/ /*1 byte*/ /*2 bytes*/ /*3 bytes*/ + 0x00000000, 0xFF000000, 0xFFFF0000, 0xFFFFFF00, /* offset 0 */ + 0x00000000, 0x00FF0000, 0x00FFFF00, 0x00FFFFFF, /* offset 1 */ + 0x00000000, 0x0000FF00, 0x0000FFFF, 0x0000FFFF, /* offset 2 */ + 0x00000000, 0x000000FF, 0x000000FF, 0x000000FF, /* offset 3 */ +#endif +}; + union l_util { u_int16_t s[2]; u_int32_t l; @@ -82,6 +96,87 @@ union q_util { u_int64_t q; }; +static u_int64_t +in_cksumdata(const void *buf, int len) +{ + const u_int32_t *lw = (const u_int32_t *) buf; + u_int64_t sum = 0; + u_int64_t prefilled; + int offset; + union q_util q_util; + + if ((3 & (long) lw) == 0 && len == 20) { + sum = (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4]; + REDUCE32; + return sum; + } + + if ((offset = 3 & (long) lw) != 0) { + const u_int32_t *masks = in_masks + (offset << 2); + lw = (u_int32_t *) (((long) lw) - offset); + sum = *lw++ & masks[len >= 3 ? 3 : len]; + len -= 4 - offset; + if (len <= 0) { + REDUCE32; + return sum; + } + } +#if 0 + /* + * Force to cache line boundary. + */ + offset = 32 - (0x1f & (long) lw); + if (offset < 32 && len > offset) { + len -= offset; + if (4 & offset) { + sum += (u_int64_t) lw[0]; + lw += 1; + } + if (8 & offset) { + sum += (u_int64_t) lw[0] + lw[1]; + lw += 2; + } + if (16 & offset) { + sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3]; + lw += 4; + } + } +#endif + /* + * access prefilling to start load of next cache line. + * then add current cache line + * save result of prefilling for loop iteration. + */ + prefilled = lw[0]; + while ((len -= 32) >= 4) { + u_int64_t prefilling = lw[8]; + sum += prefilled + lw[1] + lw[2] + lw[3] + + lw[4] + lw[5] + lw[6] + lw[7]; + lw += 8; + prefilled = prefilling; + } + if (len >= 0) { + sum += prefilled + lw[1] + lw[2] + lw[3] + + lw[4] + lw[5] + lw[6] + lw[7]; + lw += 8; + } else { + len += 32; + } + while ((len -= 16) >= 0) { + sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3]; + lw += 4; + } + len += 16; + while ((len -= 4) >= 0) { + sum += (u_int64_t) *lw++; + } + len += 4; + if (len > 0) + sum += (u_int64_t) (in_masks[len] & *lw); + REDUCE32; + return sum; +} + u_short in_addword(u_short a, u_short b) { @@ -91,14 +186,20 @@ in_addword(u_short a, u_short b) return (sum); } -static -uint64_t _do_cksum(void *addr, int len) +u_short +#ifdef __rtems__ +/* Prototype does not match in FreeBSD code */ +in_pseudo(u_int a, u_int b, u_int c) +#else +in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c) +#endif { - uint64_t sum; + u_int64_t sum; union q_util q_util; + union l_util l_util; - sum = do_cksum(addr, len); - REDUCE32; + sum = (u_int64_t) a + b + c; + REDUCE16; return (sum); } @@ -112,16 +213,16 @@ in_cksum_skip(struct mbuf *m, int len, int skip) union q_util q_util; union l_util l_util; - len -= skip; - for (; skip && m; m = m->m_next) { - if (m->m_len > skip) { - mlen = m->m_len - skip; + len -= skip; + for (; skip && m; m = m->m_next) { + if (m->m_len > skip) { + mlen = m->m_len - skip; addr = mtod(m, caddr_t) + skip; - goto skip_start; - } else { - skip -= m->m_len; - } - } + goto skip_start; + } else { + skip -= m->m_len; + } + } for (; m && len; m = m->m_next) { if (m->m_len == 0) @@ -132,10 +233,10 @@ skip_start: if (len < mlen) mlen = len; - if ((clen ^ (int) addr) & 1) - sum += _do_cksum(addr, mlen) << 8; + if ((clen ^ (uintptr_t) addr) & 1) + sum += in_cksumdata(addr, mlen) << 8; else - sum += _do_cksum(addr, mlen); + sum += in_cksumdata(addr, mlen); clen += mlen; len -= mlen; @@ -146,9 +247,9 @@ skip_start: u_int in_cksum_hdr(const struct ip *ip) { - u_int64_t sum = do_cksum(ip, sizeof(struct ip)); + u_int64_t sum = in_cksumdata(ip, sizeof(struct ip)); union q_util q_util; - union l_util l_util; + union l_util l_util; REDUCE16; return (~sum & 0xffff); -} +} |