Browse Source

Added BSD checksum for ip

Change-Id: I1799d6ea1e925625185c2c22446d421abcc7f2c6
Signed-off-by: Keith Poole <keith.poole@gmail.com>
Keith Poole 8 years ago
parent
commit
bb9f75d910
2 changed files with 159 additions and 66 deletions
  1. 158 66
      sys/src/9/ip/ptclbsum.c
  2. 1 0
      util/GO9PRUN

+ 158 - 66
sys/src/9/ip/ptclbsum.c

@@ -1,81 +1,173 @@
+
+/* $NetBSD: in_cksum.c,v 1.7 1997/09/02 13:18:15 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1988, 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 1996
+ *	Matt Thomas <matt@3am-software.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)in_cksum.c	8.1 (Berkeley) 6/10/93
+ */
+
 /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
+ * Checksum routine for Internet Protocol family headers
+ *    (Portable Alpha version).
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
  */
 
-#include	"u.h"
-#include	"../port/lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"../port/error.h"
-#include	"ip.h"
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
 
-static	short	endian	= 1;
-static	uint8_t*	aendian	= (uint8_t*)&endian;
-#define	LITTLE	*aendian
+#define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
+#define REDUCE32							  \
+    {									  \
+	q_util.q = sum;							  \
+	sum = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3];	  \
+    }
+#define REDUCE16							  \
+    {									  \
+	q_util.q = sum;							  \
+	l_util.l = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \
+	sum = l_util.s[0] + l_util.s[1];				  \
+	ADDCARRY(sum);							  \
+    }
 
-uint16_t
-ptclbsum(uint8_t *addr, int len)
+static const uint32_t in_masks[] = {
+	/*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 */
+};
+
+union l_util {
+	uint16_t s[2];
+	uint32_t l;
+};
+union q_util {
+	uint16_t s[4];
+	uint32_t l[2];
+	uint64_t q;
+};
+
+static uint64_t
+in_cksumdata(const void *buf, int len)
 {
-	uint32_t losum, hisum, mdsum, x;
-	uint32_t t1, t2;
+	const uint32_t *lw = (const uint32_t *) buf;
+	uint64_t sum = 0;
+	uint64_t prefilled;
+	int offset;
+	union q_util q_util;
 
-	losum = 0;
-	hisum = 0;
-	mdsum = 0;
+	if ((3 & (long) lw) == 0 && len == 20) {
+	     sum = (uint64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4];
+	     REDUCE32;
+	     return sum;
+	}
 
-	x = 0;
-	if(PTR2UINT(addr) & 1) {
-		if(len) {
-			hisum += addr[0];
-			len--;
-			addr++;
+	if ((offset = 3 & (long) lw) != 0) {
+		const uint32_t *masks = in_masks + (offset << 2);
+		lw = (uint32_t *) (((long) lw) - offset);
+		sum = *lw++ & masks[len >= 3 ? 3 : len];
+		len -= 4 - offset;
+		if (len <= 0) {
+			REDUCE32;
+			return sum;
 		}
-		x = 1;
 	}
-	while(len >= 16) {
-		t1 = *(uint16_t*)(addr+0);
-		t2 = *(uint16_t*)(addr+2);	mdsum += t1;
-		t1 = *(uint16_t*)(addr+4);	mdsum += t2;
-		t2 = *(uint16_t*)(addr+6);	mdsum += t1;
-		t1 = *(uint16_t*)(addr+8);	mdsum += t2;
-		t2 = *(uint16_t*)(addr+10);	mdsum += t1;
-		t1 = *(uint16_t*)(addr+12);	mdsum += t2;
-		t2 = *(uint16_t*)(addr+14);	mdsum += t1;
-		mdsum += t2;
-		len -= 16;
-		addr += 16;
+#if 0
+	/*
+	 * Force to cache line boundary.
+	 */
+	offset = 32 - (0x1f & (long) lw);
+	if (offset < 32 && len > offset) {
+		len -= offset;
+		if (4 & offset) {
+			sum += (uint64_t) lw[0];
+			lw += 1;
+		}
+		if (8 & offset) {
+			sum += (uint64_t) lw[0] + lw[1];
+			lw += 2;
+		}
+		if (16 & offset) {
+			sum += (uint64_t) lw[0] + lw[1] + lw[2] + lw[3];
+			lw += 4;
+		}
 	}
-	while(len >= 2) {
-		mdsum += *(uint16_t*)addr;
-		len -= 2;
-		addr += 2;
+#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) {
+		uint64_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(x) {
-		if(len)
-			losum += addr[0];
-		if(LITTLE)
-			losum += mdsum;
-		else
-			hisum += mdsum;
+	if (len >= 0) {
+		sum += prefilled + lw[1] + lw[2] + lw[3]
+			+ lw[4] + lw[5] + lw[6] + lw[7];
+		lw += 8;
 	} else {
-		if(len)
-			hisum += addr[0];
-		if(LITTLE)
-			hisum += mdsum;
-		else
-			losum += mdsum;
+		len += 32;
 	}
-
-	losum += hisum >> 8;
-	losum += (hisum & 0xff) << 8;
-	while(hisum = losum>>16)
-		losum = hisum + (losum & 0xffff);
-
-	return losum & 0xffff;
+	while ((len -= 16) >= 0) {
+		sum += (uint64_t) lw[0] + lw[1] + lw[2] + lw[3];
+		lw += 4;
+	}
+	len += 16;
+	while ((len -= 4) >= 0) {
+		sum += (uint64_t) *lw++;
+	}
+	len += 4;
+	if (len > 0)
+		sum += (uint64_t) (in_masks[len] & *lw);
+	REDUCE32;
+	return sum;
+}
+uint16_t ptclbsum(uint8_t * addr, int len)
+{
+	uint64_t sum = in_cksumdata(addr, len);
+	union q_util q_util;
+	union l_util l_util;
+	REDUCE16;
+	return  ((sum & (uint16_t)0x00ffU) << 8) |
+	        ((sum & (uint16_t)0xff00U) >> 8);
 }

+ 1 - 0
util/GO9PRUN

@@ -11,6 +11,7 @@ sudo qemu-system-x86_64 -s -cpu Opteron_G1 -smp 1 -m 2048  \
 -net nic,model=rtl8139 \
 -net user,hostfwd=tcp::5555-:1522 \
 -net dump,file=/tmp/vm0.pcap \
+-redir tcp:9999::9 \
 -redir tcp:17010::17010 \
 -redir tcp:17013::17013 \
 -append "nobootprompt=tcp maxcores=1024 fs=10.0.2.2 auth=10.0.2.2 user=glenda" \