1: /*
   2:  * Copyright (c) 1987 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:  *	@(#)mch_click.s	1.4 (2.11BSD GTE) 1995/11/22
   7:  */
   8: 
   9: #include "DEFS.h"
  10: #include "../machine/mch_iopage.h"
  11: 
  12: 
  13: /*
  14:  * copy(src, dst, count)
  15:  *	memaddr	src, dst;
  16:  *	int	count;
  17:  *
  18:  * Copy count clicks from src to dst.  Uses KDSA5 and 6 to copy with mov
  19:  * instructions.  Interrupt routines must restore segmentation registers
  20:  * if needed; see seg.h.
  21:  */
  22: ENTRY(copy)
  23:         jsr     r5, csv
  24: #ifdef INET
  25:         mov     PS,-(sp)                / have to lock out interrupts...
  26:         bit     $0340,(sp)              / Are we currently at spl0?
  27:         bne     1f
  28:         SPLNET                          / No, lock out network interrupts.
  29: 1:
  30: #endif
  31:         mov     KDSA5,-(sp)             / saveseg5(sp)
  32:         mov     KDSD5,-(sp)
  33:         mov     10(r5),r3               / r3 = count
  34:         beq     3f                      / (exit early if zero)
  35:         mov     4(r5),KDSA5             / seg5 = (src, 1 click read only)
  36:         mov     $RO,KDSD5
  37:         mov     sp,r4                   / save current sp
  38:         mov     $eintstk,sp             /   and switch to intstk
  39:         mov     KDSA6,_kdsa6            / save u area address, mark as mapped
  40:         mov     6(r5),KDSA6             /   out and seg6 = (dst, 1 click read/
  41:         mov     $RW,KDSD6               /   write)
  42: 1:
  43:         mov     $5*8192.,r0             / r0 = SEG5 { src }
  44:         mov     $6*8192.,r1             / r1 = SEG6 { dst }
  45:         mov     $8.,r2                  / copy one click (8*8)
  46: 2:
  47:         mov     (r0)+,(r1)+
  48:         mov     (r0)+,(r1)+
  49:         mov     (r0)+,(r1)+
  50:         mov     (r0)+,(r1)+
  51:         sob     r2,2b
  52: 
  53:         inc     KDSA5                   / next click
  54:         inc     KDSA6
  55:         sob     r3,1b
  56: 
  57:         mov     _kdsa6,KDSA6            / restore u area mapping
  58:         mov     $USIZE-1\<8|RW, KDSD6
  59:         clr     _kdsa6
  60:         mov     r4,sp                   / back to normal stack
  61: 3:
  62:         mov     (sp)+,KDSD5             / restorseg5(sp)
  63:         mov     (sp)+,KDSA5
  64: #ifdef INET
  65:         mov     (sp)+,PS                / back to normal priority
  66: #endif
  67:         jmp     cret
  68: 
  69: /*
  70:  * Clear count clicks at dst.  Uses KDSA5.  Interrupt routines must restore
  71:  * segmentation registers if needed; see seg.h.
  72:  *
  73:  * clear(dst, count)
  74:  * 	memaddr dst;
  75:  * 	u_int count;
  76:  */
  77: ENTRY(clear)
  78:         jsr     r5, csv
  79:         mov     KDSA5,-(sp)             / saveseg5(sp)
  80:         mov     KDSD5,-(sp)
  81:         mov     4(r5),KDSA5             / point KDSA5 at source
  82:         mov     $RW,KDSD5               / 64 bytes, read-write
  83:         mov     6(r5),r3                / count
  84:         beq     3f
  85: 1:
  86:         mov     $5*8192.,r0             / point r0 at KDSA5 map
  87:         mov     $8.,r2                  / clear one click (8*8)
  88: 2:
  89:         clr     (r0)+
  90:         clr     (r0)+
  91:         clr     (r0)+
  92:         clr     (r0)+
  93:         sob     r2,2b
  94: 
  95:         inc     KDSA5                   / next click
  96:         sob     r3,1b
  97: 3:
  98:         mov     (sp)+,KDSD5             / restore seg5
  99:         mov     (sp)+,KDSA5             / restore seg5
 100:         jmp     cret
 101: 
 102: /*
 103:  * copyv(fromaddr, toaddr, count)
 104:  *	virtual_addr	fromaddr,
 105:  *			toaddr;
 106:  *	u_int		count;
 107:  *
 108:  * typedef struct {
 109:  *	memaddr	click;
 110:  *	u_int	offset;
 111:  * } virtual_addr;
 112:  *
 113:  * Copy two arbitrary pieces of PDP11 virtual memory from one location
 114:  * to another.  Up to 8K bytes can be copied at one time.
 115:  *
 116:  * A PDP11 virtual address is a two word value; a 16 bit "click" that
 117:  * defines the start in physical memory of an 8KB segment and an offset.
 118:  */
 119: ENTRY(copyv)
 120:         mov     10.(sp),r0              / exit early if count == 0 or >= 8K
 121:         beq     4f
 122:         cmp     r0,$8192.
 123:         bhis    4f
 124:         mov     r2,-(sp)                / need a register for the stack switch
 125:         /*
 126: 	 * Note: the switched stack is only for use of a fatal kernel trap
 127: 	 * occurring during the copy; otherwise we might conflict with the
 128: 	 * other copy routines.
 129: 	 */
 130:         mov     sp,r2                   / switch stacks
 131:         cmp     sp,$eintstk             / are we already in the intstk?
 132:         blo     1f
 133:         mov     $eintstk,sp             / No, point sp to intstk
 134: 1:
 135:         mov     PS,-(sp)                / save current PS
 136:         bit     $0340,(sp)              / are we currently at SPL?
 137:         bne     2f
 138:         SPLNET                          / nope, lock out the network
 139: 2:
 140:         mov     KDSA5,-(sp)             / save seg5
 141:         mov     KDSD5,-(sp)
 142:         mov     _kdsa6,-(sp)            / save the current saved kdsa6
 143:         bne     3f                      / was it set to anything?
 144:         mov     KDSA6,_kdsa6            / nope, set it to the current kdsa6
 145: 3:
 146:         mov     KDSA6,-(sp)             / save user area
 147:         mov     KDSD6,-(sp)
 148:         mov     r2,r0                   / set up bcopy arguments on new stack
 149:         add     $14.,r0                 /   and grab click addresses ...
 150:         mov     -(r0),-(sp)             / copy count
 151:         mov     -(r0),-(sp)             / copy and translate toaddr.offset
 152:         add     $6*8192.,(sp)
 153:         mov     -(r0),r1                / pick up and save toaddr.click
 154:         mov     -(r0),-(sp)             / copy and translate fromaddr.offset
 155:         add     $5*8192.,(sp)
 156: 
 157:         mov     -(r0),KDSA5             / use fromaddr.click to remap seg5
 158:         mov     $128.-1\<8.|RO,KDSD5    /   for 8K read-only
 159:         mov     r1,KDSA6                / use toaddr.click to remap seg6
 160:         mov     $128.-1\<8.|RW,KDSD6    /   for 8K read/write
 161:         jsr     pc,_bcopy               / finally, do the copy
 162:         add     $6.,sp                  / toss the arguments to bcopy
 163:         mov     (sp)+,KDSD6             / restore user area
 164:         mov     (sp)+,KDSA6
 165:         mov     (sp)+,_kdsa6            / restore old _kdsa6 value
 166:         mov     (sp)+,KDSD5             / restore seg5
 167:         mov     (sp)+,KDSA5
 168:         mov     (sp)+,PS                / unlock interrupts
 169:         mov     r2,sp                   / restore stack pointer and retrieve
 170:         mov     (sp)+,r2                /   old register value
 171: 4:
 172:         clr     r0                      / clear r0 and r1 (why?)
 173:         rts     pc                      /   and return
 174: 
 175: /*
 176:  * fmove(par, pdr, from, to, length)
 177:  *	u_short	par, pdr;
 178:  *	caddr_t	from, to;
 179:  *	u_short	length;
 180:  *
 181:  * Map the par/pdr into segment 6 and perform a bcopy(from, to, length).
 182:  * Returns zero on success, EFAULT on failure.  See uiofmove for more
 183:  * information.
 184:  *
 185:  * As written, fmove may only be called from the high kernel and is *not*
 186:  * re-entrant: it doesn't save the previous fault trap, uses the intstk and
 187:  * kdsa6 without checking to see if they're already in use (see the fault
 188:  * handler at 2f below) and assumes that a user structure is currently mapped
 189:  * in (see the restore of KDSD6 below).
 190:  */
 191: ENTRY(fmove)
 192:         mov     r2,-(sp)                / need a few registers for the
 193:         mov     r3,-(sp)                /  copy and stack switch
 194:         mov     r4,-(sp)
 195:         mov     sp,r4                   / switch stacks (SEG6 is out)
 196:         mov     $eintstk,sp
 197:         mov     r4,r0                   / grab parameters
 198:         add     $8.,r0
 199:         mov     (r0)+,-(sp)             / push par and pdr onto new stack
 200:         mov     (r0)+,-(sp)
 201:         mov     (r0)+,r1                / r1 = from
 202:         mov     (r0)+,r2                / r2 = to
 203:         mov     (r0),r0                 / r0 = length
 204:         mov     KDSA6,_kdsa6            / save current segment 6 mapping
 205:         mov     (sp)+,KDSD6             /   passed par/pdr
 206:         mov     (sp)+,KDSA6             /   and map segment 6 with the
 207:         mov     $8f,nofault             / catch any faults during the copy,
 208: 
 209:         /*
 210: 	 * The following code has been lifted almost intact from "bcopy".
 211: 	 * The biggest reason is for error recovery in the case of a user
 212: 	 * memory fault.
 213: 	 */
 214:         tst     r0              / if (length == 0)
 215:         beq     7f              /	return
 216:         cmp     r0,$10.         / if (length > 10)
 217:         bhi     2f              /	try words
 218: 1:
 219:         movb    (r1)+,(r2)+     / do  *dst++ = *src++
 220:         sob     r0,1b           / while (--length)
 221:         br      7f
 222: 2:
 223:         bit     $1,r1           / if (src&1 != dst&1)
 224:         beq     3f              /	do bytes
 225:         bit     $1,r2
 226:         beq     1b              / (src odd, dst even - do bytes)
 227:         movb    (r1)+,(r2)+     / copy leading odd byte
 228:         dec     r0
 229:         br      4f
 230: 3:
 231:         bit     $1,r2
 232:         bne     1b              / (src even, dst odd - do bytes)
 233: 4:
 234:         mov     r0,r3           / save trailing byte indicator
 235:         clc
 236:         ror     r0              / length >>= 1 (unsigned)
 237:         asr     r0              / if (length >>= 1, wasodd(length))
 238:         bcc     5f              /	handle leading non multiple of four
 239:         mov     (r1)+,(r2)+
 240: 5:
 241:         asr     r0              / if (length >>= 1, wasodd(length))
 242:         bcc     6f              /	handle leading non multiple of eight
 243:         mov     (r1)+,(r2)+
 244:         mov     (r1)+,(r2)+
 245: 6:
 246:         mov     (r1)+,(r2)+     / do
 247:         mov     (r1)+,(r2)+     /	move eight bytes
 248:         mov     (r1)+,(r2)+
 249:         mov     (r1)+,(r2)+
 250:         sob     r0,6b           / while (--length)
 251:         asr     r3              / if (odd trailing byte)
 252:         bcc     7f
 253:         movb    (r1)+,(r2)+     /	copy it
 254:         /*
 255: 	 * End of stolen bcopy code.
 256: 	 */
 257: 
 258: 7:
 259:         clr     nofault                 / clear the fault trap and return
 260:                                         /   status (zero from successful copy)
 261:         mov     _kdsa6,KDSA6            / restore the previous segment 6
 262:         mov     $USIZE-1\<8|RW, KDSD6   /   mapping (user structure)
 263:         clr     _kdsa6                  /   (segment 6 not mapped out any more)
 264:         mov     r4,sp                   / restore previous stack pointer
 265:         mov     (sp)+,r4                /   and saved registers
 266:         mov     (sp)+,r3
 267:         mov     (sp)+,r2
 268:         rts     pc                      / and return
 269: 8:
 270:         mov     $EFAULT,r0              / copy failed, return EFAULT
 271:         br      7b

Defined functions

_clear defined in line 77; used 7 times
_copy defined in line 22; used 7 times
_copyv defined in line 119; used 4 times
_fmove defined in line 191; used 4 times
Last modified: 1995-11-23
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 694
Valid CSS Valid XHTML 1.0 Strict