Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/arm Move the final ip checksum to a common file...



details:   https://anonhg.NetBSD.org/src/rev/17e6c11a08c8
branches:  trunk
changeset: 783408:17e6c11a08c8
user:      matt <matt%NetBSD.org@localhost>
date:      Wed Dec 19 15:05:16 2012 +0000

description:
Move the final ip checksum to a common file to be included.
Add a generic ip checksum calculator for a buffer (ptr/len).

diffstat:

 sys/arch/arm/arm/cpu_in_cksum_buffer.S |  183 +++++++++++++++++++++++++++++++++
 sys/arch/arm/arm/cpu_in_cksum_fold.S   |   60 ++++++++++
 sys/arch/arm/arm/cpu_in_cksum_v4hdr.S  |   34 ++---
 3 files changed, 255 insertions(+), 22 deletions(-)

diffs (truncated from 315 to 300 lines):

diff -r 6b07229cb2ae -r 17e6c11a08c8 sys/arch/arm/arm/cpu_in_cksum_buffer.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/arm/cpu_in_cksum_buffer.S    Wed Dec 19 15:05:16 2012 +0000
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: cpu_in_cksum_buffer.S,v 1.1 2012/12/19 15:05:16 matt Exp $")
+
+/*
+ * Special note:
+ * The use of cmp is avoided so that APSR.C (carry) is never overwritten.
+ */
+
+#ifdef _ARM_ARCH_DWORD_OK
+#define        LOAD_DWORD_INTO_R4(r)   ldrd    r4, [r], #8
+#else
+#define        LOAD_DWORD_INTO_R4(r)   ldr     r4, [r], #4;    ldr     r5, [r], #4
+#endif
+
+/*
+ * uint16_t cpu_in_cksum_buffer(const void *, size_t, uint32_t initial_csum);
+ */
+
+ENTRY(cpu_in_cksum_buffer)
+       mov     ip, r2                  /* initialize accumulator */
+       adds    ip, ip, #0              /* clear carry */
+       push    {r4-r5}                 /* save temporaries */
+       teq     r1, #0                  /* did we get passed a zero length? */
+       beq     .Lfold                  /* fold the checksum */
+       ands    r2, r0, #7              /* test for dword alignment */
+       bne     .Ldword_misaligned      /*   no, fixup non dword aligned */
+
+       add     r2, r1, r0              /* point r2 just past end */
+#ifndef __OPTIMIZE_SIZE__
+       bics    r3, r1, #63             /* at least 64 bytes to do? */
+       bne     4f                      /*   yes, then do them */
+#endif /* __OPTIMIZE_SIZE__ */
+       bics    r3, r1, #7              /* at least 8 bytes to do? */
+       beq     .Lfinal_dword           /*   no, handle the final dword */
+3:
+#ifndef __OPTIMIZE_SIZE__
+       rsb     r3, r3, #64             /* subtract from 64 */
+#ifdef _ARM_ARCH_DWORD_OK
+       add     r3, r3, r1, lsr #1      /* multiply by 1.5 */
+       add     pc, pc, r3              /* and jump! */
+#else
+       add     pc, pc, r3, lsl #1      /* multiply by 2 and jump! */
+#endif
+       nop
+4:     LOAD_DWORD_INTO_R4(r0)          /* 8 dwords left */
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+       LOAD_DWORD_INTO_R4(r0)          /* 7 dwords left */
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+       LOAD_DWORD_INTO_R4(r0)          /* 6 dwords left */
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+       LOAD_DWORD_INTO_R4(r0)          /* 5 dwords left */
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+       LOAD_DWORD_INTO_R4(r0)          /* 4 dwords left */
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+       LOAD_DWORD_INTO_R4(r0)          /* 3 dwords left */
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+       LOAD_DWORD_INTO_R4(r0)          /* 2 dwords left */
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+#endif /* __OPTIMIZE_SIZE__ */
+       LOAD_DWORD_INTO_R4(r0)          /* 1 dword left */
+.Ladd_one_dword:
+       adcs    ip, ip, r4
+       adcs    ip, ip, r5
+       teq     r2, r0                  /* nothing left? */
+       beq     .Lfold                  /*   yep, proceed to hold */
+
+       sub     r1, r2, r0              /* find out much left to do? */
+#ifndef __OPTIMIZE_SIZE__
+       bics    r3, r1, #63             /* at least 64 bytes left? */
+       bne     4b                      /*   yep, do 64 at time */
+#endif
+       bics    r3, r1, #7              /* at least 8 bytes left? */
+       bge     3b                      /*   yep, do them */
+
+.Lfinal_dword:
+       tst     r1, #4                  /* more than one word more left? */
+       moveq   r4, #0                  /*   no, just use zero */
+       ldrne   r4, [r0], #4            /*   yes, load first word */
+       ldr     r5, [r0]                /* load last word */
+.Lfinal_dword_noload:
+       rsb     r1, r1, #4              /* find out many bytes to discard */
+#ifdef __ARMEL__
+       tst     r1, #2                  /* discard at least 2? */
+       movne   r5, r5, lsl #16         /*   yes, discard upper halfword */
+       tst     r1, #1                  /* discard odd? */
+       bicne   r5, r5, #0xff000000     /*   yes, discard odd byte */
+#else
+       tst     r1, #2                  /* discard at least 2? */
+       movne   r5, r5, lsr #16         /*   yes, discard lower halfword */
+       tst     r1, #1                  /* discard odd? */
+       bicne   r5, r5, #0x000000ff     /*   yes, discard odd byte */
+#endif
+       adds    ip, ip, r4              /* add 1st to accumulator */
+       adcs    ip, ip, r5              /* add 2nd to accumulator */
+
+       /*
+        * Fall into fold.
+        */
+
+.Lfold:
+       pop     {r4-r5}                 /* we don't need these anymore */
+       /*
+        * We now have the 33-bit result in <carry>, ip.  Pull in the
+        * standard folding code.
+        */
+#include "cpu_in_cksum_fold.S"
+
+.Ldword_misaligned:
+       bic     r0, r0, #3              /* force word alignment */
+       add     r1, r1, r2              /* add misalignment to length */
+       tst     r2, #4                  /* first  */
+       ldr     r4, [r0], #4            /* load first word */
+       movne   r5, #0                  /* no second word */
+       ldreq   r5, [r0], #4            /* load second word */
+       /*
+        * We are now dword aligned.
+        */
+#ifdef __ARMEL__
+       tst     r2, #2                  /* discard at least 2? */
+       movne   r4, r4, lsr #16         /* yes, discard lower halfword */
+       tst     r2, #1                  /* discard odd? */
+       bicne   r4, r4, #0x0000ff00     /* yes, discard odd byte */
+#else
+       tst     r2, #2                  /* discard at least 2? */
+       movne   r4, r4, lsl #16         /* yes, discard upper halfword */
+       tst     r2, #1                  /* discard odd? */
+       bicne   r4, r4, #0x00ff0000     /* yes, discard odd byte */
+#endif
+       /*
+        * See if we have a least a full dword to process.  If we do, jump
+        * into the main loop as if we just load a single dword.
+        */
+       bics    r3, r1, #7              /* at least one dword? */
+       addne   r2, r1, r0              /*   yes, point r2 just past end */
+       bne     .Ladd_one_dword         /*   yes, accumulate it and loop */
+       /*
+        * Not a full dword so do the final dword processing to find out
+        * bytes to discard.  If we only loaded one word, move it to 2nd
+        * word since that is what final_dword will be discarding from and
+        * clear the 1st word.
+        */
+       tst     r2, #4                  /* one or two words? */
+       movne   r5, r4                  /*   one, move 1st word to 2nd word */
+       movne   r4, #0                  /*        and clear 1st word */
+       b       .Lfinal_dword_noload    /* handle final dword */
+END(cpu_in_cksum_buffer)
diff -r 6b07229cb2ae -r 17e6c11a08c8 sys/arch/arm/arm/cpu_in_cksum_fold.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/arm/cpu_in_cksum_fold.S      Wed Dec 19 15:05:16 2012 +0000
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * This file is intended to be included at the end of a in_cksum routine
+ * to reduce the 33-bit sum in <carry>, ip to a 16-bit return value.
+ */
+
+       /*
+        * Add the final carry bit.  If it overflows, we have a 33-bit value
+        * of 0x1.0000.0000 which we know is just equivalent to 1.  Since we
+        * return a complement of the lower halfword, that's 0xfffe.
+        */
+       adcs    ip, ip, #0              /* add final carry bit */
+       subeq   r0, r1, #1              /* zero?  complement the carry */
+       RETc(eq)                        /*        and return 0xfffe */
+       /*
+        * Now prevent the adding of 0xffff to 0xffff by making sure the upper
+        * halfword isn't 0xffff.  If it is, just complement all 32-bits
+        * which clears the upper halfword and complements the lower halfword.
+        */
+       cmp     ip, r1, lsl #16         /* is the upper halfword 0xffff? */
+       mvneq   r0, ip                  /*   yes, complement */
+       RETc(eq)                        /*        and return */
+       /*
+        * Finally add the lower halfword to the upper halfword.  If we have
+        * a result >= 0x10000, carry will be set.  The maximum result will
+        * be 0x[1]fffe.  So if the carry bit is set, just add 0x10000
+        * (which is equivalent to subtracting 0xffff.0000).
+        */
+       adds    ip, ip, ip, lsl #16
+       addcs   ip, ip, #0x10000
+       eor     r0, r1, ip, lsr #16
+       RET
diff -r 6b07229cb2ae -r 17e6c11a08c8 sys/arch/arm/arm/cpu_in_cksum_v4hdr.S
--- a/sys/arch/arm/arm/cpu_in_cksum_v4hdr.S     Wed Dec 19 15:00:34 2012 +0000
+++ b/sys/arch/arm/arm/cpu_in_cksum_v4hdr.S     Wed Dec 19 15:05:16 2012 +0000
@@ -29,7 +29,7 @@
 
 #include <machine/asm.h>
 
-RCSID("$NetBSD: cpu_in_cksum_v4hdr.S,v 1.2 2012/12/18 14:08:25 matt Exp $")
+RCSID("$NetBSD: cpu_in_cksum_v4hdr.S,v 1.3 2012/12/19 15:05:16 matt Exp $")
 
 ENTRY(cpu_in_cksum_v4hdr)
 #ifdef _ARM_ARCH_DWORD_OK
@@ -43,40 +43,30 @@
        ldr     r3, [r0, #4]            /* load 2nd word */
        ldr     r2, [r0, #8]            /* load 3rd word */
 #endif
-       adds    r3, r3, ip              /* accumulate */
-       adcs    r2, r2, r3              /* accumulate */
+       adds    ip, ip, r3              /* accumulate */
+       adcs    ip, ip, r2              /* accumulate */
 #ifdef _ARM_ARCH_DWORD_OK
        ldrd    r0, [r0]                /* load remaining words */
 #else
        ldr     r1, [r0, #12]           /* load 4th word */
        ldr     r0, [r0, #16]           /* load 5th word */
 #endif
-       adcs    r1, r1, r2              /* accumulate */
-       adcs    r0, r0, r1              /* accumulate */
+       adcs    ip, ip, r1              /* accumulate */
+       adcs    ip, ip, r0              /* accumulate */
        /*
         * We now have a 33-bit (r0 + carry) sum which needs to resolved to a
-        * 16-bit sum.
+        * 16-bit sum.  But first, let's put 0xffff in a register.
         */
-       mov     r1, r0, lsr #16         /* get upper halfword */
-#ifdef _ARM_ARCH_6
-       uxth    r0, r0                  /* clear upper halfword (16bit carry) */
-#else
-       bic     r0, r0, #0x00ff0000     /* clear upper halfword (16bit carry) */
-       bic     r0, r0, #0xff000000     /* clear upper halfword */
-#endif
-       adc     r0, r0, r1              /* add halfwords with leftover carry */
-       /*
-        * At this point, we have a sum with a max of 0x1fffe.
-        * If we have a 17-bit value (>= 0x10000) then subtract 0xffff.
-        */
-       cmp     r0, #0x10000            /* test 16-bit carry */
 #ifdef _ARM_ARCH_7



Home | Main Index | Thread Index | Old Index