ARPAVAX:UNKNOWN:dove@mit-cipg@mit-mc (09/12/82)
From: dove at mit-cipg at mit-mc I changed rdwri.c and the machine code handling to allow iomove to be efficient with odd addresses and byte counts. This was necessary because the local network software frequently used them. ----rdwri.c /* * Move n bytes at byte location * &bp->b_un.b_addr[o] to/from (flag) the * user/kernel (u.segflg) area starting at u.base. * Update all the arguments by the number * of bytes moved. * * if #bytes>#bytes_per_word, xfer bytes until user address is an even * word boundary. Then call copyin/copyout to transfer the remaining * full words. Finally, use cpass/passc to transfer remaining bytes. * All this assumes that copyin/copyiin/copyout/copyiout support * even #byte xfers from odd kernel addresses to even user addresses. * THIS IS NOT TRUE OF MOST UNIX KERNELS; SO WATCH OUT! */ iomove(cp, nbytes, flag) register caddr_t cp; int nbytes; { register t; register unsigned n=nbytes; if(n==0) return; while(((int)u.u_base&(NBPW-1))!=0 && n>0) { /* align to user wd bdry */ if(flag==B_WRITE) { if((t=cpass())<0) return; *cp++ = t; n--; } else { if(passc(*cp++)<0) return; n--; } } if (n==0) return; nbytes = n; if(u.u_segflg!=1 && /* user space xfer */ n>(NBPW-1)) /* >1 full word */ { n &= ~(NBPW-1); /* #bytes of full wds */ if(flag==B_WRITE) if(u.u_segflg==0) t = copyin(u.u_base, (caddr_t)cp, n); else t = copyiin(u.u_base, (caddr_t)cp, n); else if(u.u_segflg==0) t = copyout((caddr_t)cp, u.u_base, n); else t = copyiout((caddr_t)cp, u.u_base, n); if(t) { u.u_error = EFAULT; return; } u.u_base += n; cp += n; /* in case there is more to come */ u.u_offset += n; u.u_count -= n; n = nbytes-n; /* remaining bytes */ if(n==0) return; } if(flag==B_WRITE) { do{ if((t=cpass())<0) return; *cp++ = t; }while(--n); } else { do{ if(passc(*cp++)<0) return; }while(--n); } } ----- mch.c / 9/12/82 dove / changed to allow odd kernel buffer address. Use byte moves onto stack / .globl _copyin, _copyout .globl _copyiin, _copyiout _copyin: #ifndef NONSEPARATE jsr pc,copsu 1: mfpd (r0)+ movb (sp),(r1)+ movb 1(sp),(r1)+ tst (sp)+ sob r2,1b br 2f #endif _copyiin: jsr pc,copsu 1: mfpi (r0)+ movb (sp),(r1)+ movb 1(sp),(r1)+ tst (sp)+ sob r2,1b br 2f _copyout: #ifndef NONSEPARATE jsr pc,copsu 1: tst -(sp) movb (r0)+,(sp) movb (r0)+,1(sp) mtpd (r1)+ sob r2,1b br 2f #endif _copyiout: jsr pc,copsu 1: tst -(sp) movb (r0)+,(sp) movb (r0)+,1(sp) mtpi (r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sp)+,r2 clr r0 rts pc copsu: mov (sp)+,r0 mov r2,-(sp) mov nofault,-(sp) mov r0,-(sp) mov 10(sp),r0 mov 12(sp),r1 mov 14(sp),r2 asr r2 mov $1f,nofault rts pc 1: mov (sp)+,nofault mov (sp)+,r2 mov $-1,r0 rts pc