Annotation of cci/sys/tahoe/in_cksum.c, revision 1.1.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.