Annotation of sys/arch/mips64/mips64/lcore_access.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: lcore_access.S,v 1.10 2007/05/20 14:34:23 miod Exp $ */
2:
3: /*
4: * Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25: * SUCH DAMAGE.
26: *
27: */
28: #include <sys/errno.h>
29: #include <sys/syscall.h>
30:
31: #include <machine/param.h>
32: #include <machine/psl.h>
33: #include <machine/asm.h>
34: #include <machine/cpu.h>
35: #include <machine/regnum.h>
36: #include <machine/cpustate.h>
37: #include <machine/trap.h>
38:
39: #include "assym.h"
40:
41: .set mips3
42:
43: .set noreorder # Noreorder is default style!
44:
45: /*
46: * Primitives
47: */
48:
49: /*
50: * This table is indexed by u.u_pcb.pcb_onfault in trap().
51: * The reason for using this table rather than storing an address in
52: * u.u_pcb.pcb_onfault is simply to make the code faster.
53: * This table must match with definitions in trap.h.
54: */
55: .globl onfault_table
56: .data
57: .align 3
58: onfault_table:
59: PTR_VAL 0 # invalid index number
60: PTR_VAL _copyerr
61: PTR_VAL _copyerr
62: #if defined(DDB) || defined(DEBUG)
63: PTR_VAL kt_ddberr
64: #else
65: PTR_VAL 0
66: #endif
67: .text
68:
69: /*
70: * This code is copied the user's stack for returning from signal handlers
71: * (see sendsig() and sigreturn()). We have to compute the address
72: * of the sigcontext struct for the sigreturn call.
73: */
74: .globl sigcode
75: sigcode:
76: PTR_ADDU a0, sp, 4*REGSZ # address of sigcontext
77: LI v0, SYS_sigreturn # sigreturn(scp)
78: syscall
79: break 0 # just in case sigreturn fails
80: .globl esigcode
81: esigcode:
82:
83: /* Mips o32 ABI sigcode. 32 bit pointers. */
84: .globl sigcode_o32
85: sigcode_o32:
86: addu a0, sp, 16 # address of sigcontext
87: li v0, SYS_sigreturn # sigreturn(scp)
88: syscall
89: break 0 # just in case sigreturn fails
90: .globl esigcode_o32
91: esigcode_o32:
92:
93: /*
94: * Copy a null terminated string within the kernel address space.
95: * Maxlength may be null if count not wanted.
96: * copystr(fromaddr, toaddr, maxlength, &lencopied)
97: * caddr_t fromaddr;
98: * caddr_t toaddr;
99: * u_int maxlength;
100: * u_long *lencopied;
101: */
102: LEAF(copystr, 0)
103: move t2, a2 # Save the number of bytes
104: 1:
105: lbu t0, 0(a0)
106: PTR_SUBU a2, a2, 1
107: beq t0, zero, 2f
108: sb t0, 0(a1)
109: PTR_ADDU a0, a0, 1
110: bne a2, zero, 1b
111: PTR_ADDU a1, a1, 1
112: 2:
113: beq a3, zero, 3f
114: PTR_SUBU a2, t2, a2 # compute length copied
115: REG_S a2, 0(a3)
116: 3:
117: j ra
118: move v0, zero
119: END(copystr)
120:
121: #ifndef __LP64__
122: /*
123: * Read 64 bits from bus in non LP64 mode.
124: * XXX ints should be disabled!
125: */
126: LEAF(lp32_read8, 0)
127: #if defined(__MIPSEB__)
128: ld v1, 0(a0)
129: jr ra
130: dsrl v0, v1, 32
131: #else
132: ld v0, 0(a0)
133: jr ra
134: dsrl v1, v0, 32
135: #endif
136: END(lp32_read8)
137:
138: /*
139: * Write 64 bits to bus in non LP64 mode.
140: * XXX ints should be disabled!
141: */
142: LEAF(lp32_write8, 0)
143: #if defined(__MIPSEB__)
144: dsll a2, 32
145: dsll a3, 32
146: dsrl a3, 32
147: or a2, a3
148: #else
149: dsll a3, 32
150: dsll a2, 32
151: dsrl a2, 32
152: or a3, a2
153: #endif
154: jr ra
155: sd a2, 0(a0)
156: END(lp32_write8)
157: #endif
158:
159: /*
160: * fillw(pat, addr, count)
161: */
162: LEAF(fillw, 0)
163: 1:
164: PTR_ADDU a2, a2, -1
165: sh a0, 0(a1)
166: bne a2,zero, 1b
167: PTR_ADDU a1, a1, 2
168:
169: jr ra
170: nop
171: END(fillw)
172:
173: /*
174: * Optimized memory zero code.
175: * mem_zero_page(addr);
176: */
177: LEAF(mem_zero_page, 0)
178: LI v0, NBPG
179: 1:
180: PTR_SUBU v0, 8
181: sd zero, 0(a0)
182: bne zero, v0, 1b
183: PTR_ADDU a0, 8
184: jr ra
185: nop
186: END(mem_zero_page)
187:
188: /*
189: * Block I/O routines mainly used by I/O drivers.
190: *
191: * Args as: a0 = port
192: * a1 = memory address
193: * a2 = count
194: */
195: LEAF(insb, 0)
196: beq a2, zero, 2f
197: PTR_ADDU a2, a1
198: 1:
199: lbu v0, 0(a0)
200: PTR_ADDU a1, 1
201: bne a1, a2, 1b
202: sb v0, -1(a1)
203: 2:
204: jr ra
205: nop
206: END(insb)
207:
208: LEAF(insw, 0)
209: beq a2, zero, 2f
210: PTR_ADDU a2, a2
211: PTR_ADDU a2, a1
212: 1:
213: lhu v0, 0(a0)
214: PTR_ADDU a1, 2
215: bne a1, a2, 1b
216: sh v0, -2(a1)
217: 2:
218: jr ra
219: nop
220: END(insw)
221:
222: LEAF(insl, 0)
223: beq a2, zero, 2f
224: PTR_SLL a2, 2
225: PTR_ADDU a2, a1
226: 1:
227: lw v0, 0(a0)
228: PTR_ADDU a1, 4
229: bne a1, a2, 1b
230: sw v0, -4(a1)
231: 2:
232: jr ra
233: nop
234: END(insl)
235:
236: LEAF(outsb, 0)
237: beq a2, zero, 2f
238: PTR_ADDU a2, a1
239: 1:
240: lbu v0, 0(a1)
241: PTR_ADDU a1, 1
242: bne a1, a2, 1b
243: sb v0, 0(a0)
244: 2:
245: jr ra
246: nop
247: END(outsb)
248:
249: LEAF(outsw, 0)
250: beq a2, zero, 2f
251: PTR_ADDU a2, a2
252: LI v0, 1
253: and v0, a1
254: bne v0, zero, 3f # arghh, unaligned.
255: PTR_ADDU a2, a1
256: 1:
257: lhu v0, 0(a1)
258: PTR_ADDU a1, 2
259: bne a1, a2, 1b
260: sh v0, 0(a0)
261: 2:
262: jr ra
263: nop
264: 3:
265: LWHI v0, 0(a1)
266: LWLO v0, 3(a1)
267: PTR_ADDU a1, 2
268: bne a1, a2, 3b
269: sh v0, 0(a0)
270:
271: jr ra
272: nop
273: END(outsw)
274:
275: LEAF(outsl, 0)
276: beq a2, zero, 2f
277: PTR_SLL a2, 2
278: LI v0, 3
279: and v0, a1
280: bne v0, zero, 3f # arghh, unaligned.
281: PTR_ADDU a2, a1
282: 1:
283: lw v0, 0(a1)
284: PTR_ADDU a1, 4
285: bne a1, a2, 1b
286: sw v0, 0(a0)
287: 2:
288: jr ra
289: nop
290: 3:
291: LWHI v0, 0(a1)
292: LWLO v0, 3(a1)
293: PTR_ADDU a1, 4
294: bne a1, a2, 3b
295: sw v0, 0(a0)
296:
297: jr ra
298: nop
299: END(outsl)
300:
301: /*
302: * Copy a null terminated string from the user address space into
303: * the kernel address space.
304: *
305: * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
306: * caddr_t fromaddr;
307: * caddr_t toaddr;
308: * u_int maxlength;
309: * u_int *lencopied;
310: */
311: NON_LEAF(copyinstr, FRAMESZ(CF_SZ), ra)
312: PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
313: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
314: PTR_S ra, CF_RA_OFFS(sp)
315: blt a0, zero, _copyerr # make sure address is in user space
316: li v0, KT_COPYERR
317: PTR_L t3, curprocpaddr
318: jal copystr
319: sw v0, PCB_ONFAULT(t3)
320:
321: PTR_L ra, CF_RA_OFFS(sp)
322: PTR_L t3, curprocpaddr
323: sw zero, PCB_ONFAULT(t3)
324: PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
325: j ra
326: move v0, zero
327: END(copyinstr)
328:
329: /*
330: * Copy a null terminated string from the kernel address space into
331: * the user address space.
332: *
333: * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
334: * caddr_t fromaddr;
335: * caddr_t toaddr;
336: * u_int maxlength;
337: * u_int *lencopied;
338: */
339: NON_LEAF(copyoutstr, FRAMESZ(CF_SZ), ra)
340: PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
341: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
342: PTR_S ra, CF_RA_OFFS(sp)
343: blt a1, zero, _copyerr # make sure address is in user space
344: li v0, KT_COPYERR
345: PTR_L t3, curprocpaddr
346: jal copystr
347: sw v0, PCB_ONFAULT(t3)
348:
349: PTR_L ra, CF_RA_OFFS(sp)
350: PTR_L t3, curprocpaddr
351: sw zero, PCB_ONFAULT(t3)
352: PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
353: j ra
354: move v0, zero
355: END(copyoutstr)
356:
357: /*
358: * Copy specified amount of data from user space into the kernel
359: * copyin(from, to, len)
360: * caddr_t *from; (user source address)
361: * caddr_t *to; (kernel destination address)
362: * unsigned len;
363: */
364: NON_LEAF(copyin, FRAMESZ(CF_SZ), ra)
365: PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
366: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
367: PTR_S ra, CF_RA_OFFS(sp)
368: blt a0, zero, _copyerr # make sure address is in user space
369: li v0, KT_COPYERR
370: PTR_L t3, curprocpaddr
371: jal bcopy
372: sw v0, PCB_ONFAULT(t3)
373:
374: PTR_L ra, CF_RA_OFFS(sp)
375: PTR_L t3, curprocpaddr
376: sw zero, PCB_ONFAULT(t3)
377: PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
378: j ra
379: move v0, zero
380: END(copyin)
381:
382: /*
383: * Copy specified amount of data from kernel to the user space
384: * copyout(from, to, len)
385: * caddr_t *from; (kernel source address)
386: * caddr_t *to; (user destination address)
387: * unsigned len;
388: */
389: NON_LEAF(copyout, FRAMESZ(CF_SZ), ra)
390: PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
391: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
392: PTR_S ra, CF_RA_OFFS(sp)
393: blt a1, zero, _copyerr # make sure address is in user space
394: li v0, KT_COPYERR
395: PTR_L t3, curprocpaddr
396: jal bcopy
397: sw v0, PCB_ONFAULT(t3)
398:
399: PTR_L ra, CF_RA_OFFS(sp)
400: PTR_L t3, curprocpaddr
401: sw zero, PCB_ONFAULT(t3)
402: PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
403: j ra
404: move v0, zero
405: END(copyout)
406:
407: _copyerr:
408: PTR_L ra, CF_RA_OFFS(sp)
409: PTR_L t3, curprocpaddr
410: sw zero, PCB_ONFAULT(t3)
411: PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
412: j ra
413: li v0, EFAULT # return error
414:
415: /*
416: * kcopy is a wrapper around bcopy that catches bad memory references.
417: */
418: NON_LEAF(kcopy, FRAMESZ(CF_SZ), ra)
419: PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
420: .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
421: PTR_S ra, CF_RA_OFFS(sp)
422: li v0, KT_KCOPYERR
423: PTR_L t3, curprocpaddr
424: jal bcopy
425: sw v0, PCB_ONFAULT(t3)
426:
427: PTR_L ra, CF_RA_OFFS(sp)
428: PTR_L t3, curprocpaddr
429: sw zero, PCB_ONFAULT(t3)
430: PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
431: j ra
432: move v0, zero
433: END(kcopy)
CVSweb