|
|
1.1 root 1: .text
2:
3: .set MOVCMAX,0xffff # largest single movc
4: #
5: # copyin and copyout
6: #
7: _Copyin: .globl _Copyin # <<<massaged for jsb by asm.sed>>>
8: movl 12(sp),r0 # copy length
9: blss ersb
10: movl 4(sp),r1 # copy user address
11: cmpl $NBPG,r0 # probing one page or less ?
12: blss ciloop # no
13: cishort:
14: prober $3,r0,(r1) # bytes accessible ?
15: beql ersb # no
16: docp:
17: pushl _nofault
18: movab ersbp,_nofault
19: cpagain:
20: cmpl 16(sp),$MOVCMAX
21: bgtr cpbig
22: movc3 16(sp),*8(sp),*12(sp)
23: movl (sp)+,_nofault
24: # clrl r0 # movc leaves 0 in r0
25: rsb
26: ersbp:
27: movl (sp)+,_nofault
28: ersb:
29: mnegl $1,r0
30: rsb
31:
32: cpbig:
33: movc3 $MOVCMAX,*8(sp),*12(sp)
34: subl2 $MOVCMAX,16(sp) # new len
35: movl r1,8(sp) # new source, from movc
36: movl r3,12(sp) # new dest, from movc
37: brb cpagain
38: ciloop:
39: prober $3,$NBPG,(r1) # bytes accessible ?
40: beql ersb # no
41: addl2 $NBPG,r1 # incr user address ptr
42: acbl $NBPG+1,$-NBPG,r0,ciloop # reduce count and loop
43: brb cishort
44:
45: _Copyout: .globl _Copyout # <<<massaged for jsb by asm.sed >>>
46: movl 12(sp),r0 # get count
47: blss ersb
48: movl 8(sp),r1 # get user address
49: cmpl $NBPG,r0 # can do in one probew?
50: blss coloop # yes
51: coshort:
52: probew $3,r0,(r1) # bytes accessible?
53: beql ersb # no
54: brw docp
55: coloop:
56: probew $3,$NBPG,(r1) # bytes accessible?
57: beql ersb # no
58: addl2 $NBPG,r1 # increment user address
59: acbl $NBPG+1,$-NBPG,r0,coloop # reduce count and loop
60: brb coshort
61:
62: /*
63: * {fu,su},{byte,word}, all massaged by asm.sed to jsb's
64: */
65: .globl _Fuword
66: _Fuword:
67: prober $3,$4,(r0)
68: beql fserr
69: movl (r0),r0
70: rsb
71: fserr:
72: mnegl $1,r0
73: rsb
74:
75: .globl _Fubyte
76: _Fubyte:
77: prober $3,$1,(r0)
78: beql fserr
79: movzbl (r0),r0
80: rsb
81:
82: .globl _Suword
83: _Suword:
84: probew $3,$4,(r0)
85: beql fserr
86: movl r1,(r0)
87: clrl r0
88: rsb
89:
90: .globl _Subyte
91: _Subyte:
92: probew $3,$1,(r0)
93: beql fserr
94: movb r1,(r0)
95: clrl r0
96: rsb
97:
98: /*
99: * find length of a NUL-terminated string in user space;
100: * check access along the way
101: * returns -1 if access is bad,
102: * otherwise length of string including NUL
103: * NB not the same number strlen returns
104: */
105:
106: .globl _fustrlen
107: _fustrlen: # fustrlen(ustr)
108: .word 0x0000
109: movl 4(ap),r2
110: bsbb Fustrlen
111: ret
112:
113: /*
114: * the real work, split off so can jsb here for speed
115: * address of string in r2
116: */
117:
118: Fustrlen:
119: movl r2,r1
120: bicl3 $~(NBPG-1),r1,r0 # bytes within page
121: subl3 r0,$NBPG,r0 # bytes remaining in page
122: 0:
123: prober $3,r0,(r1)
124: beql fsfault # sic - if error, ret from whoever called us
125: locc $0,r0,(r1)
126: bneq 1f
127: movl $NBPG,r0 # next page
128: brb 0b
129: 1: # r1 contains address of NUL
130: subl3 r2,r1,r0
131: incl r0 # byte count
132: rsb
133:
134: /*
135: * strncpy, but from user space; returns -1 if error
136: * it is an error if the string is too long
137: * fustrncpy(to, from, tolen)
138: */
139: .globl _fustrncpy
140: _fustrncpy:
141: .word 0
142: movl 8(ap),r2
143: bsbb Fustrlen # check access and find length
144: # tstl r0 # Fustrlen does ret if error
145: # blss fsfault
146: cmpl r0,12(ap)
147: bgtr fsfault
148: 0: cmpl r0,$MOVCMAX
149: bgtr 1f # hard case: too big for one movc
150: movc3 r0,*8(ap),*4(ap)
151: # clrl r0 # movc leaves 0 in r0
152: ret
153:
154: 1:
155: subl3 $MOVCMAX,r0,-(sp)
156: movc3 $MOVCMAX,*8(ap),*4(ap)
157: movl r1,8(ap) # movc leaves new source here
158: movl r3,4(ap) # movc leaves new dest here
159: movl (sp)+,r0
160: jbr 0b
161:
162: fsfault:
163: mnegl $1,r0
164: ret
165:
166: /*
167: * Copy 1 relocation unit (NBPG bytes)
168: * from user virtual address to physical address
169: */
170: _copyseg: .globl _copyseg
171: .word 0x0
172: bisl3 $PG_V|PG_KW,8(ap),*_CMAP2
173: mtpr _CADDR2,$TBIS # invalidate entry for copy
174: movc3 $NBPG,*4(ap),*_CADDR2
175: ret
176:
177: /*
178: * zero out physical memory
179: * specified in relocation units (NBPG bytes)
180: */
181: _clearseg: .globl _clearseg
182: .word 0x0
183: bisl3 $PG_V|PG_KW,4(ap),*_CMAP1
184: mtpr _CADDR1,$TBIS
185: movc5 $0,(sp),$0,$NBPG,*_CADDR1
186: ret
187:
188: .comm _CMAP1,4
189: .comm _CADDR1,4
190: .comm _CMAP2,4
191: .comm _CADDR2,4
192:
193: #
194: # get/put one byte in physical memory
195: # the original excuse is I/O ECC correction
196: #
197: # phgetc(addr)
198: # phputc(addr, byte)
199: # both return -1 for error
200: #
201: .comm _CMAP3,4
202: .comm _CADDR3,4
203: _phgetc: .globl _phgetc
204: .word 0
205: bsbb phcomm
206: movzbl (r1),r0
207: brb 2f
208:
209: _phputc: .globl _phputc
210: .word 0
211: bsbb phcomm
212: clrl r0 # return 0 if ok
213: cvtlb 8(ap),(r1)
214: brb 2f
215: 1: mnegl $1,r0 # error
216: 2: movl r3,_nofault
217: mtpr r2,$IPL
218: ret
219:
220: # r2 -> old IPL, new IPL high
221: # r3 -> old nofault, new nofault ours
222: # *CMAP3 -> pte
223: # r1 -> virtual address of the interesting byte
224:
225: phcomm:
226: mfpr $IPL,r2
227: mtpr $HIGH,$IPL
228: divl3 $NBPG,4(ap),r0 # page number
229: bisl3 $PG_V|PG_KW,r0,*_CMAP3
230: bicl3 $~(NBPG-1),4(ap),r1 # offset within page
231: addl2 _CADDR3,r1
232: mtpr r1,$TBIS
233: movl _nofault,r3
234: movab 1b,_nofault
235: rsb
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.