1: /* 2: * Copyright (c) 1988 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)net_copy.s 1.1 (2.10BSD Berkeley) 4/10/88 7: */ 8: 9: #include "DEFS.h" 10: #include "../machine/mch_iopage.h" 11: 12: 13: /* 14: * Fetch and set user byte routines: 15: * fubyte(addr): fetch user data space byte 16: * subyte(addr, byte): set user data space byte 17: * caddr_t addr; 18: * u_char byte; 19: * 20: * The fetch routines return the requested byte or -1 on fault. The set 21: * routines return 0 on success, -1 on failure. 22: */ 23: ENTRY(fubyte) 24: jsr pc,fssetup / r1 = addr, previous mode = user 25: bic $1,r1 / r1 = addr&~1 26: mfpd (r1) / tmp = user data word at (addr&~1) 27: mov (sp)+,r0 28: cmp r1,6(sp) / if (addr&1) 29: beq 1f / tmp >>= 8 30: swab r0 31: 1: 32: bic $!377,r0 / return((u_char)tmp) 33: br fscleanup / restore fault trap and PS, and return 34: 35: ENTRY(subyte) 36: jsr pc,fssetup / r1 = addr, previous mode = user 37: bic $1,r1 / r1 = addr&~1 38: mfpd (r1) / tmp = user data word at (addr&~1) 39: cmp r1,10(sp) / if (addr&1) 40: beq 1f 41: movb 12(sp),1(sp) / *((char *)tmp + 1) = byte 42: br 2f 43: 1: / else 44: movb 12(sp),(sp) / *((char *)tmp) = byte 45: 2: 46: mtpd (r1) / user data word (addr&~1) = tmp 47: clr r0 / return success 48: br fscleanup / restore fault trap and PS, and return 49: 50: 51: /* 52: * Fetch and set user word routines: 53: * fuword(addr): fetch user data space word 54: * suword(addr, word): set user data space word 55: * caddr_t addr; 56: * u_short word; 57: * 58: * The fetch routines return the requested word or -1 on fault. The set 59: * routines return 0 on success, -1 on failure. Addr must be even. The data 60: * space routines are really the corresponding instruction space routines if 61: * NONSEPARATE is defined. 62: */ 63: ENTRY(fuword) 64: jsr pc,fssetup / r1 = addr, previous mode = user 65: mfpd (r1) / r0 = user data word at addr 66: mov (sp)+,r0 67: br fscleanup / restore fault trap and PS, and return 68: 69: ENTRY(suword) 70: jsr pc,fssetup / r1 = addr, previous mode = user 71: mov 10(sp),-(sp) / user data word at addr = word 72: mtpd (r1) 73: clr r0 / resturn success 74: br fscleanup / restore fault trap and PS, and return 75: 76: 77: /* 78: * Common set up code for the [fs]u(byte|word) routines. Sets up fault 79: * trap, sets previous mode to user, and loads addr into r1. Leaves old 80: * values of PS and nofault on stack. 81: */ 82: fssetup: 83: mov (sp)+,r0 / snag return address 84: mov PS,-(sp) / save current PS, 85: bic $30000,PS / set previous mode kernel 86: mfpd *$nofault / grab current value of nofault 87: mov $fsfault,-(sp) / and set new fault trap 88: mtpd *$nofault 89: bis $30000,PS / leave previous mode set to user 90: mov 6(sp),r1 / r1 = addr 91: jmp (r0) / return to f/s routine 92: 93: /* 94: * Common fault trap for fetch/set user byte/word routines. Returns -1 to 95: * indicate fault. Stack contains saved fault trap followed by return 96: * address. 97: */ 98: fsfault: 99: mov $-1,r0 / return failure (-1) 100: /*FALLTHROUGH*/ 101: 102: /* 103: * Common clean up code for the [fs]u(byte|word) routines. 104: */ 105: fscleanup: 106: bic $30000,PS / set previous more to kernel 107: mtpd *$nofault / restore fault trap, 108: mov (sp)+,PS / PS, 109: rts pc / and return 110: 111: 112: /* 113: * copyin(fromaddr, toaddr, length) 114: * caddr_t fromaddr, toaddr; 115: * u_int length; 116: * 117: * Copy length/2 words from user space fromaddr to kernel space address 118: * toaddr. Fromaddr and toaddr must be even. Returns zero on success, 119: * EFAULT on failure. 120: */ 121: ENTRY(copyin) 122: jsr pc,copysetup / r1 = fromaddr, r2 = toaddr, 123: 1: / r0 = length/2 124: mfpd (r1)+ / do 125: mov (sp)+,(r2)+ / *toaddr++ = *fromaddr++ 126: sob r0,1b / while (--length) 127: br copycleanup 128: 129: 130: /* 131: * copyout(fromaddr, toaddr, length) 132: * caddr_t fromaddr, toaddr; 133: * u_int length; 134: * 135: * Copy length/2 words from kernel space fromaddr to user space address 136: * toaddr. Fromaddr and toaddr must be even. Returns zero on success, 137: * EFAULT on failure. 138: */ 139: ENTRY(copyout) 140: jsr pc,copysetup / r1 = fromaddr, r2 = toaddr, 141: 1: / r0 = length/2 142: mov (r1)+,-(sp) / do 143: mtpd (r2)+ / *toaddr++ = *fromaddr++ 144: sob r0,1b / while (--length) 145: br copycleanup 146: 147: 148: /* 149: * Common set up code for the copy(in|out) routines. Performs zero length 150: * check, sets up fault trap, sets previous mode to user, and loads 151: * fromaddr, toaddr and length into the registers r1, r2 and r0 152: * respectively. Leaves old values of r2, PS, and nofault on stack. 153: */ 154: copysetup: 155: mov (sp)+,r0 / snag return address 156: mov r2,-(sp) / reserve r2 for our use, 157: mov PS,-(sp) / save current PS, 158: bic $30000,PS / set previous mode kernel 159: mfpd *$nofault / grab current value of nofault 160: mov r0,-(sp) / push return address back 161: mov $copyfault,-(sp) / and set new fault trap 162: mtpd *$nofault 163: bis $30000,PS / leave previous mode set to user 164: mov 16(sp),r0 / r0 = (unsigned)length/2 165: beq 1f / (exit early if length equals zero) 166: asr r0 167: bic $100000,r0 168: mov 12(sp),r1 / r1 = fromaddr 169: mov 14(sp),r2 / r2 = toaddr 170: rts pc 171: 172: 1: 173: tst (sp)+ / short circuit the copy for zero 174: br copycleanup / length returning "success" ... 175: 176: copyfault: 177: mov $EFAULT,r0 / we faulted out, return EFAULT 178: /*FALLTHROUGH*/ 179: 180: /* 181: * Common clean up code for the copy(in|out) routines. When copy routines 182: * finish successfully r0 has already been decremented to zero which is 183: * exactly what we want to return for success ... Tricky, hhmmm? 184: */ 185: copycleanup: 186: bic $30000,PS / set previous mode to kernel 187: mtpd *$nofault / restore fault trap, 188: mov (sp)+,PS / PS, 189: mov (sp)+,r2 / and reserved registers 190: rts pc 191: 192: 193: /* 194: * Kernel/Network copying routines. 195: * 196: * NOTE: 197: * The cp(to|from)kern functions operate atomically, at high ipl. 198: * This is done mostly out of paranoia. If the cp(to|from)kern 199: * routines start taking up too much time at high IPL, then this 200: * parnoia should probably be reconsidered. 201: * 202: * 203: * WARNING: 204: * All functions assume that the segments in supervisor space 205: * containing the source or target variables are never remapped. 206: */ 207: 208: #ifdef notdef /* not currently used */ 209: /* 210: * void 211: * cptokern(nfrom, kto, len) 212: * caddr_t nfrom; source address in network space 213: * caddr_t kto; destination address in kernel space 214: * int len; number of bytes to copy 215: * 216: * Copy words from the network to the kernel. Len must be even and both 217: * nfrom and kto must begin on an even word boundary. 218: */ 219: ENTRY(cptokern) 220: mov r2,-(sp) 221: mov PS,-(sp) 222: mov $40340,PS / set previous mode to kernel 223: mov 6(sp),r0 / nfrom 224: mov 10(sp),r1 / kto 225: mov 12(sp),r2 / len 226: asr r2 / len/2 227: 1: 228: mov (r0)+,-(sp) 229: mtpd (r1)+ 230: sob r2,1b 231: 232: mov (sp)+,PS 233: mov (sp)+,r2 234: rts pc 235: #endif /* notdef */ 236: 237: /* 238: * void 239: * cpfromkern(kfrom, nto, len) 240: * caddr_t kfrom; source address in kernel space 241: * caddr_t nto; destination address in network space 242: * int len; number of bytes to copy 243: * 244: * Copy words from the kernel to the network. Len must be even and both 245: * kfrom and nto must begin on an even word boundary. 246: */ 247: ENTRY(cpfromkern) 248: mov r2,-(sp) 249: mov PS,-(sp) 250: mov $40340,PS / set previous mode to kernel 251: mov 6(sp),r0 / kfrom 252: mov 10(sp),r1 / nto 253: mov 12(sp),r2 / len 254: asr r2 / len/2 255: 1: 256: mfpd (r0)+ 257: mov (sp)+,(r1)+ 258: sob r2,1b 259: 260: mov (sp)+,PS 261: mov (sp)+,r2 262: rts pc 263: 264: /* 265: * void 266: * mtkd(addr, word) 267: * caddr addr; destination address in kernel space 268: * int word; word to store 269: * 270: * Move To Kernel Data, simplified interface for the network to store 271: * single words in the kernel data space. 272: */ 273: ENTRY(mtkd) 274: mov 2(sp),r0 / get the destination address 275: mov PS,-(sp) / save psw 276: bic $30000,PS / previous kernel 277: mov 6(sp),-(sp) / grab word 278: mtpd (r0) / and store it in kernel space 279: mov (sp)+,PS / restore psw 280: rts pc / return 281: 282: /* 283: * int 284: * mfkd(addr) 285: * caddr_t addr; source address in kernel space 286: * 287: * Move From Kernel Data, simplified interface for the network to get 288: * single words from the kernel data space. 289: */ 290: ENTRY(mfkd) 291: mov 2(sp),r0 / get the address of the data 292: mov PS,-(sp) / save psw 293: bic $30000,PS / previous kernel 294: mfpd (r0) / get the word 295: mov (sp)+,r0 / return value 296: mov (sp)+,PS / restore psw 297: rts pc / return