Annotation of cci/sys/tahoe/in_cksum.c, revision 1.1

1.1     ! root        1: /*     in_cksum.c      6.1     83/07/29        */
        !             2: 
        !             3: #include "../h/types.h"
        !             4: #include "../h/mbuf.h"
        !             5: #include "../netinet/in.h"
        !             6: #include "../netinet/in_systm.h"
        !             7: 
        !             8: #if defined(tahoe)
        !             9: /*
        !            10:  * Checksum routine for Internet Protocol family headers.
        !            11:  *
        !            12:  * This routine is very heavily used in the network
        !            13:  * code and should be modified for each CPU to be as fast as possible.
        !            14:  * 
        !            15:  * This implementation is TAHOE version.
        !            16:  */
        !            17: 
        !            18: #undef ADDCARRY
        !            19: #define ADDCARRY(sum)  {                               \
        !            20:                        if (sum & 0xffff0000) {         \
        !            21:                                sum &= 0xffff;          \
        !            22:                                sum++;                  \
        !            23:                        }                               \
        !            24:                }
        !            25: in_cksum(m, len)
        !            26:        register struct mbuf *m;
        !            27:        register int len;
        !            28: {
        !            29:        union word {
        !            30:                char    c[2];
        !            31:                u_short s;
        !            32:        } u;
        !            33:        register u_short *w;
        !            34:        register int sum = 0;
        !            35:        register int mlen = 0;
        !            36: 
        !            37:        for (;m && len; m = m->m_next) {
        !            38: 
        !            39:                if (m->m_len == 0) {
        !            40:                        continue;
        !            41:                }
        !            42: 
        !            43:                w = mtod(m, u_short *);
        !            44:                if (mlen == -1) {
        !            45:                        /*
        !            46:                         * The first byte of this mbuf is the continuation
        !            47:                         * of a word spanning between this mbuf and the
        !            48:                         * last mbuf.
        !            49:                         */
        !            50: 
        !            51:                        /* u.c[0] is already saved when scanning previous 
        !            52:                         * mbuf.
        !            53:                         */
        !            54:                        u.c[1] = *(u_char *)w;
        !            55:                        sum += u.s;
        !            56:                        ADDCARRY(sum);
        !            57: 
        !            58:                        w = (u_short *)((char *)w + 1);
        !            59:                        mlen = m->m_len - 1;
        !            60:                        len--;
        !            61:                } else
        !            62:                        mlen = m->m_len;
        !            63: 
        !            64:                if (len < mlen)
        !            65:                        mlen = len;
        !            66:                len -= mlen;
        !            67: 
        !            68:                /*
        !            69:                 * add by words.
        !            70:                 */
        !            71:                while ((mlen -= 2) >= 0) {
        !            72:                        
        !            73:                        if ((int)w & 0x1) {
        !            74:                                /* word is not aligned */
        !            75:                                u.c[0] = *(char *)w;
        !            76:                                u.c[1] = *((char *)w+1);
        !            77:                                sum += u.s;
        !            78:                                w++;
        !            79:                        }
        !            80:                        else {
        !            81:                                sum += *w++;
        !            82:                        }
        !            83:                        ADDCARRY(sum);
        !            84:                }
        !            85:                if (mlen == -1) {
        !            86:                        /*
        !            87:                         * This mbuf has odd number of bytes. 
        !            88:                         * There could be a word split betwen
        !            89:                         * this mbuf and the next mbuf.
        !            90:                         * Save the last byte (to prepend to next mbuf).
        !            91:                         */
        !            92:                        u.c[0] = *(u_char *)w;
        !            93:                }
        !            94:        }
        !            95:        if (len)
        !            96:                printf("cksum: out of data\n");
        !            97:        if (mlen == -1) {
        !            98:                /* The last mbuf has odd # of bytes. Follow the
        !            99:                   standard (the odd byte is shifted left by 8 bits) */
        !           100:                u.c[1] = 0;
        !           101:                sum += u.s;
        !           102:                ADDCARRY(sum);
        !           103:        }
        !           104: done:
        !           105:        return (~sum & 0xffff);
        !           106: }
        !           107: #endif
        !           108: 
        !           109: #if defined(vax)
        !           110: 
        !           111: /*
        !           112:  * Checksum routine for Internet Protocol family headers (VAX Version).
        !           113:  *
        !           114:  * This routine is very heavily used in the network
        !           115:  * code and should be modified for each CPU to be as fast as possible.
        !           116:  */
        !           117: 
        !           118: in_cksum(m, len)
        !           119:        register struct mbuf *m;
        !           120:        register int len;
        !           121: {
        !           122:        register u_short *w;            /* on Tahoe, known to be r10 */
        !           123:        register int sum = 0;           /* on Tahoe, known to be r9 */
        !           124:        register int mlen = 0;
        !           125: 
        !           126:        for (;;) {
        !           127:                /*
        !           128:                 * Each trip around loop adds in
        !           129:                 * word from one mbuf segment.
        !           130:                 */
        !           131:                w = mtod(m, u_short *);
        !           132:                if (mlen == -1) {
        !           133:                        /*
        !           134:                         * There is a byte left from the last segment;
        !           135:                         * add it into the checksum.  Don't have to worry
        !           136:                         * about a carry-out here because we make sure
        !           137:                         * that high part of (32 bit) sum is small below.
        !           138:                         */
        !           139:                        sum += *(u_char *)w << 8;
        !           140:                        w = (u_short *)((char *)w + 1);
        !           141:                        mlen = m->m_len - 1;
        !           142:                        len--;
        !           143:                } else
        !           144:                        mlen = m->m_len;
        !           145:                m = m->m_next;
        !           146:                if (len < mlen)
        !           147:                        mlen = len;
        !           148:                len -= mlen;
        !           149:                /*
        !           150:                 * Force to long boundary so we do longword aligned
        !           151:                 * memory operations.  
        !           152:                 */
        !           153:                if (((int)w&0x1) && mlen >= 1) {
        !           154:                        sum += *(u_char *)w++;
        !           155:                        mlen -= 1;
        !           156:                }
        !           157:                if (((int)w&0x2) && mlen >= 2) {
        !           158:                        sum += *w++;
        !           159:                        mlen -= 2;
        !           160:                }
        !           161:                /*
        !           162:                 * Do as much of the checksum as possible 32 bits at at time.
        !           163:                 * In fact, this loop is unrolled to make overhead from
        !           164:                 * branches &c small.
        !           165:                 *
        !           166:                 * We can do a 16 bit ones complement sum 32 bits at a time
        !           167:                 * because the 32 bit register is acting as two 16 bit
        !           168:                 * registers for adding, with carries from the low added
        !           169:                 * into the high (by normal carry-chaining) and carries
        !           170:                 * from the high carried into the low on the next word
        !           171:                 * by use of the adwc instruction.  This lets us run
        !           172:                 * this loop at almost memory speed.
        !           173:                 *
        !           174:                 * Here there is the danger of high order carry out, and
        !           175:                 * we carefully use adwc.
        !           176:                 */
        !           177:                while ((mlen -= 32) >= 0) {
        !           178: #undef ADD
        !           179:                        asm("clrl r0");         /* clears carry */
        !           180: #define ADD            asm("adwc (r10),r9;addl2 $4,r10; ");
        !           181:                        ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
        !           182:                        asm("adwc $0,r9");
        !           183:                }
        !           184:                mlen += 32;
        !           185:                while ((mlen -= 8) >= 0) {
        !           186:                        asm("clrl r0");
        !           187:                        ADD; ADD;
        !           188:                        asm("adwc $0,r9");
        !           189:                }
        !           190:                mlen += 8;
        !           191:                /*
        !           192:                 * Now eliminate the possibility of carry-out's by
        !           193:                 * folding back to a 16 bit number (adding high and
        !           194:                 * low parts together.)  Then mop up trailing words
        !           195:                 * and maybe an odd byte.
        !           196:                 */
        !           197:                { asm("shal $-16,r9,r0; addw2 r0,r9");
        !           198:                  asm("adwc $0,r9; movzwl r9,r9"); }
        !           199:                while ((mlen -= 2) >= 0) {
        !           200:                        asm("movzwl (r10),r0;addl2 $4,r10;  addl2 r0,r9");
        !           201:                }
        !           202:                if (mlen == -1) {
        !           203:                        sum += *(u_char *)w;
        !           204:                }
        !           205:                if (len == 0)
        !           206:                        break;
        !           207:                /*
        !           208:                 * Locate the next block with some data.
        !           209:                 * If there is a word split across a boundary we
        !           210:                 * will wrap to the top with mlen == -1 and
        !           211:                 * then add it in shifted appropriately.
        !           212:                 */
        !           213:                for (;;) {
        !           214:                        if (m == 0) {
        !           215:                                printf("cksum: out of data\n");
        !           216:                                goto done;
        !           217:                        }
        !           218:                        if (m->m_len)
        !           219:                                break;
        !           220:                        m = m->m_next;
        !           221:                }
        !           222:        }
        !           223: done:
        !           224:        /*
        !           225:         * Add together high and low parts of sum
        !           226:         * and carry to get cksum.
        !           227:         * Have to be careful to not drop the last
        !           228:         * carry here.
        !           229:         */
        !           230:        { asm("shal $-16,r9,r0; addw2 r0,r9; adwc $0,r9");
        !           231:          asm("mcoml r9,r9; movzwl r9,r9"); }
        !           232:        return (sum);
        !           233: }
        !           234: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.