Annotation of sys/arch/hppa64/hppa64/locore.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: locore.S,v 1.6 2007/05/26 00:36:03 krw Exp $ */
2:
3: /*
4: * Copyright (c) 2005 Michael Shalayeff
5: * All rights reserved.
6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
16: * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: .level 2.0w
21:
22: #include <sys/reboot.h>
23: #include <machine/param.h>
24: #include <machine/asm.h>
25: #include <machine/psl.h>
26: #include <machine/trap.h>
27: #include <machine/iomod.h>
28: #include <machine/pdc.h>
29: #include <machine/frame.h>
30: #include <machine/reg.h>
31: #include <machine/pte.h>
32: #include "assym.h"
33:
34: .import __gp, data
35: .import pdc, data
36: .import boothowto, data
37: .import bootdev, data
38: .import esym, data
39: .import want_resched, data
40: .import proc0, data
41: .import proc0paddr, data
42:
43: #define EMRG_STACKSIZE (1*PAGE_SIZE)
44: #define FPEMU_STACKSIZE (1*PAGE_SIZE)
45:
46: .data
47:
48: .export netisr, data
49: .align 16
50: netisr
51: .word 0
52: .align 16
53: $kpsl
54: .word PSL_W | PSL_Q | PSL_P | PSL_C | PSL_D | PSL_S | PSL_O
55: .export cpl, data
56: cpl
57: .word IPL_HIGH
58:
59: BSS(pdc_stack, 8) /* temp stack for PDC call */
60: BSS(emrg_stack, 8) /* stack for HPMC/TOC/PWRF */
61: BSS(fpemu_stack, 8) /* stack for FPU emulation */
62:
63: .export fpu_enable, data
64: BSS(fpu_enable, 4) /* bits to set in the %cr10 to enable fpu */
65: .export fpu_curpcb, data
66: BSS(fpu_curpcb, 8) /* pcb of the fpu owner */
67: BSS(fpu_scratch, 16) /* FPU scratch space, enough for a quad */
68:
69: .text
70:
71: /*
72: * $start(pdc, boothowto, bootdev, esym)
73: */
74: .export $start, entry
75: $start
76: rsm (PSL_R|PSL_Q|PSL_I|PSL_P|PSL_D), %r0
77: nop ! nop ! nop ! nop
78:
79: ldil L%__gp, %dp
80: ldo R%__gp(%dp), %dp
81:
82: ldi HPPA_PID_KERNEL, %r1
83: mtctl %r1, %pidr1
84: mtctl %r1, %pidr2
85: mtctl %r0, %pidr3
86: mtctl %r0, %pidr4
87:
88: mtsp %r0, %sr0
89: mtsp %r0, %sr1
90: mtsp %r0, %sr2
91: mtsp %r0, %sr3
92: mtsp %r0, %sr4
93: mtsp %r0, %sr5
94: mtsp %r0, %sr6
95: mtsp %r0, %sr7
96:
97: ldi -1, %r1
98: mtctl %r0, %eiem
99: mtctl %r1, %eirr
100: mtctl %r0, %cr10 /* ccr */
101:
102: ldil L%pdc, %r1
103: std %arg0, R%pdc(%r1)
104: ldil L%boothowto, %r1
105: stw %arg1, R%boothowto(%r1)
106: ldil L%bootdev, %r1
107: stw %arg2, R%bootdev(%r1)
108: ldil L%esym, %r1
109: std %arg3, R%esym(%r1)
110:
111: /* align esym */
112: ldo PAGE_MASK(%arg3), %arg3
113: depw %r0, 31, PAGE_SHIFT, %arg3
114:
115: .import __kernel_pagedir, data
116: ldil L%__kernel_pagedir, %r1
117: ldo R%__kernel_pagedir(%r1), %r1
118: mtctl %r1, %cr25 /* vtop */
119:
120: /* setup kernel initial PIEs */
121: ldo PAGE_SIZE(%r1), %r31
122: extrd,u %r31, 51, 32, %arg0
123: ldo 1(%arg0), %arg1
124: ldo 2(%arg0), %arg2
125: stw %arg0, 0(%r1)
126: stw %arg1, 4(%r1)
127: /* (VM_MIN_KERNEL_ADDRESS & PIE_MASK) >> PIE_SHIFT */
128: ldo 1(%arg2), %arg0
129: stw %arg2, 0x20*4(%r1)
130: stw %arg0, 0xffc(%r1)
131:
132: .import kernel_ptes, data
133: ldil L%kernel_ptes, %r1
134: ldo R%kernel_ptes(%r1), %r1
135:
136: ldd,ma 8(%r1), %r8
137: ldd,ma 8(%r1), %r9
138: ldd,ma 8(%r1), %r10
139: ldd,ma 8(%r1), %r11
140:
141: /* fill eight pages at the same time */
142: copy %arg3, %arg0
143: ldo PAGE_SIZE(%arg0), %arg1
144: extrd,u %arg0, 51, 32, %r1
145: stw,ma %r1, 4(%r31)
146: ldo PAGE_SIZE(%arg1), %arg2
147: extrd,u %arg1, 51, 32, %r1
148: stw,ma %r1, 4(%r31)
149: ldo PAGE_SIZE(%arg2), %arg3
150: extrd,u %arg2, 51, 32, %r1
151: stw,ma %r1, 4(%r31)
152: ldo PAGE_SIZE(%arg3), arg4
153: extrd,u %arg3, 51, 32, %r1
154: stw,ma %r1, 4(%r31)
155: ldo PAGE_SIZE(arg4), arg5
156: extrd,u arg4, 51, 32, %r1
157: stw,ma %r1, 4(%r31)
158: ldo PAGE_SIZE(arg5), arg6
159: extrd,u arg5, 51, 32, %r1
160: stw,ma %r1, 4(%r31)
161: ldo PAGE_SIZE(arg6), arg7
162: extrd,u arg6, 51, 32, %r1
163: stw,ma %r1, 4(%r31)
164: extrd,u arg7, 51, 32, %r1
165: stw,ma %r1, 4(%r31)
166: ldi PAGE_SIZE, %r1
167: $start_set_ptes
168: std,ma,bc %r8, 8(%arg0)
169: std,ma,bc %r8, 8(%arg1)
170: std,ma,bc %r9, 8(%arg2)
171: std,ma,bc %r9, 8(%arg3)
172: std,ma,bc %r10, 8(arg4)
173: std,ma,bc %r10, 8(arg5)
174: std,ma,bc %r11, 8(arg6)
175: addib,>= -8, %r1, $start_set_ptes
176: std,ma,bc %r11, 8(arg7)
177:
178: ldo -8(arg7), %arg3
179:
180: /* assuming size being page-aligned */
181: #define STACK_ALLOC(n,s) \
182: ldil L%n, %r1 ! \
183: ldil L%s, %r31 ! \
184: std %arg3, R%n(%r1) ! \
185: add %arg3, %r31, %arg3
186:
187: STACK_ALLOC(pdc_stack, PDC_STACKSIZE)
188: STACK_ALLOC(emrg_stack, EMRG_STACKSIZE)
189: STACK_ALLOC(fpemu_stack, FPEMU_STACKSIZE)
190:
191: copy %arg3, %arg0
192: ldi PAGE_SIZE+TRAPFRAME_SIZEOF, %r1
193: $start_zero_tf
194: std,ma,bc %r0, 8(%arg0)
195: addib,>= -16, %r1, $start_zero_tf
196: std,ma,bc %r0, 8(%arg0)
197:
198: /* setup proc0/user0 */
199: ldil L%(USPACE+PAGE_SIZE), %arg0
200: add %arg0, %arg3, %arg0
201: ldil L%proc0paddr, %r1
202: std %arg3, R%proc0paddr(%r1)
203:
204: ldo PAGE_SIZE(%arg3), %sp
205: mtctl %arg3, %cr30
206: std %r0, U_PCB+PCB_ONFAULT(%arg3)
207: std %r0, U_PCB+PCB_SPACE(%arg3)
208: std %arg3, U_PCB+PCB_UVA(%arg3)
209:
210: ldil L%proc0, %r1
211: ldo R%proc0(%r1), %r1
212: ldo -TRAPFRAME_SIZEOF(%sp), %arg2
213: std %arg3, P_ADDR(%r1)
214: std %arg2, P_MD_REGS(%r1)
215:
216: ldil TFF_LAST, %r1
217: std %r1, TF_FLAGS(%arg2)
218: std %arg3, TF_CR30(%arg2)
219:
220: ldil L%$kpsl, %r1
221: ldw R%$kpsl(%r1), arg7
222: ldil L%$start_virt, %r31
223: ldo R%$start_virt(%r31), %r31
224: ldil L%$ivaaddr, %r1
225: ldo R%$ivaaddr(%r1), %r1
226: mtctl %r1, %iva
227: mtctl %r0, %pcsq
228: mtctl %r0, %pcsq
229: mtctl %r31, %pcoq
230: ldo 4(%r31), %r31
231: mtctl %r31, %pcoq
232: mtctl arg7, %ipsw
233: rfi
234: nop
235:
236: $start_virt
237: copy %arg0, %r5
238: copy %sp, %r3
239: std,ma %r0, HPPA_FRAME_SIZE(%sp)
240: .call
241: b,l hppa_init, %rp
242: ldo -16(%sp), ap
243:
244: $start_callmain
245: .import main, code
246: .call
247: b,l main, %rp
248: ldo -TRAPFRAME_SIZEOF(%arg0), %r5
249: .size $start, .-$start
250:
251: /* int
252: * pdc_call(func, pdc_flag, ...)
253: * iodcio_t func;
254: * int pdc_flag;
255: */
256: ENTRY(pdc_call,160)
257: std %rp, HPPA_FRAME_RP(%sp)
258: std %sp, HPPA_FRAME_PSP(%sp)
259: copy %r3, %r31
260: copy %sp, %ret0
261:
262: ldil L%pdc_stack, %r1
263: ldd R%pdc_stack(%r1), %r3
264: copy %r3, %sp
265: std,ma %r31, 32+12*4+12*8(%sp) /* old frame+args+save(64) */
266:
267: mfctl %eiem, %r1
268: mtctl %r0, %eiem
269: std %r1, 1*8(%r3)
270:
271: copy %arg0, %r31
272: /* copy arguments */
273: copy %arg2, %arg0
274: copy %arg3, %arg1
275: copy arg4, %arg2
276: copy arg5, %arg3
277:
278: ldd 0*8(ap), arg4
279: ldd 1*8(ap), arg5
280: stw arg6, -32-(4+1)*4(%sp)
281: stw arg7, -32-(5+1)*4(%sp)
282: stw arg4, -32-(6+1)*4(%sp)
283: stw arg5, -32-(7+1)*4(%sp)
284: ldd 2*8(ap), arg4
285: ldd 3*8(ap), arg5
286: ldd 4*8(ap), arg6
287: ldd 5*8(ap), arg7
288: stw arg4, -32-(8+1)*4(%sp)
289: stw arg5, -32-(9+1)*4(%sp)
290: stw arg6, -32-(10+1)*4(%sp)
291: stw arg7, -32-(11+1)*4(%sp)
292:
293: mfctl %cr24, arg4
294: mfctl %cr25, arg5
295: mfctl %cr26, arg6
296: mfctl %cr27, arg7
297: std arg4, 2*8(%r3)
298: std arg5, 3*8(%r3)
299: std arg6, 4*8(%r3)
300: std arg7, 5*8(%r3)
301: mfctl %cr28, arg4
302: mfctl %cr29, arg5
303: mfctl %cr30, arg6
304: mfctl %cr31, arg7
305: std arg4, 6*8(%r3)
306: std arg5, 7*8(%r3)
307: std arg6, 8*8(%r3)
308: std arg7, 9*8(%r3)
309:
310: copy %arg0, %ret1
311: std %ret0, 11*8(%r3) /* old %sp */
312: ldi PSL_Q, %arg0
313: break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW
314: copy %ret1, %arg0
315:
316: .call
317: blr %r0, %rp
318: bv,n (%r31)
319: nop
320:
321: /* load temp control regs */
322: ldd 2*8(%r3), arg4
323: ldd 3*8(%r3), arg5
324: ldd 4*8(%r3), arg6
325: ldd 5*8(%r3), arg7
326: mtctl arg4, %cr24
327: mtctl arg5, %cr25
328: mtctl arg6, %cr26
329: mtctl arg7, %cr27
330: ldd 6*8(%r3), arg4
331: ldd 7*8(%r3), arg5
332: ldd 8*8(%r3), arg6
333: ldd 9*8(%r3), arg7
334: mtctl arg4, %cr28
335: mtctl arg5, %cr29
336: mtctl arg6, %cr30
337: mtctl arg7, %cr31
338:
339: ldil L%$kpsl, %r1
340: ldw R%$kpsl(%r1), %arg0
341: copy %ret0, %arg1
342: break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW
343: copy %arg1, %ret0
344:
345: ldd 1*8(%r3), arg5 /* %eiem */
346: ldd 11*8(%r3), %sp
347: ldd HPPA_FRAME_RP(%sp), %rp
348: ldd 0(%r3), %r3
349:
350: bv %r0(%rp)
351: mtctl arg5, %eiem
352: EXIT(pdc_call)
353:
354: /*
355: * the whole syscall() glue is fit on one page
356: * both enter and return paths
357: */
358: /* TODO has to be mapped w/a special perms */
359: .align PAGE_SIZE
360: .export gateway_page, entry
361: gateway_page
362: nop
363: gate,n $bsd_syscall,%r0
364: nop
365:
366: .align 256
367: #ifdef COMPAT_LINUX
368: gate,n $linux_syscall, %r0 /* TODO linux syscall fix */
369: nop
370:
371: $linux_syscall
372: nop
373: #endif
374:
375: $bsd_syscall
376: mfctl %eiem, %r1
377: mtctl %r0, %eiem
378: mtsp %r0, %sr1
379: mfctl %pidr1, %ret0
380: ldi HPPA_PID_KERNEL, %ret0
381: mtctl %ret0, %pidr1
382:
383: /* TODO prepare for syscall() */
384:
385: .import syscall,code
386: b,l syscall, %rp
387: nop
388:
389: mfctl %cr24, %arg1
390: ldd CI_CURPROC(%arg1), %r1
391: ldw P_MD_REGS(%r1), %arg0
392:
393: $syscall_return
394: /* %arg0 -- trapframe */
395:
396: mtctl %r0, %eiem
397:
398: ldo 8(%arg0), %r31 /* flags */
399:
400: rfi
401: nop
402: .size $bsd_syscall, .-$bsd_syscall
403: .size $syscall_return, .-$syscall_return
404:
405: gateway_end
406: . = gateway_page + PAGE_SIZE
407: .size gateway_page, .-gateway_page
408:
409: /*
410: * interrupt vector table
411: */
412: #define TLABEL(name) $trap$name
413: #define TRAP(name,num,pre) \
414: .export TLABEL(name)$num, entry ! \
415: .label TLABEL(name)$num ! \
416: pre ! \
417: .call ! \
418: .import TLABEL(name), code ! \
419: b TLABEL(name) ! \
420: ldi num, %r1 ! \
421: .align 32
422:
423: #define ITLBPRE \
424: mfctl %pcsq, %r8 ! \
425: mfctl %pcoq, %r9 ! \
426: extrd,u %r8, 63, SID_SHIFT, %r1 ! \
427: depd %r1, 31, SID_SHIFT, %r9 ! \
428: depd %r0, 63, SID_SHIFT, %r8
429:
430: #define DTLBPRE \
431: mfctl %isr, %r8 ! \
432: mfctl %ior, %r9 ! \
433: extrd,u %r8, 63, SID_SHIFT, %r1 ! \
434: depd %r1, 31, SID_SHIFT, %r9 ! \
435: depd %r0, 63, SID_SHIFT, %r8
436:
437: #define HPMCPRE nop
438:
439: #define BRKPRE \
440: mfctl %pcoq, %r8
441:
442: .align PAGE_SIZE /* already */
443: .export $ivaaddr, entry
444: .export hpmc_v, entry
445: $ivaaddr
446: TRAP(all,T_NONEXIST,) /* 0. invalid interrupt vector */
447: hpmc_v
448: TRAP(hpmc,T_HPMC,HPMCPRE) /* 1. high priority machine check */
449: TRAP(pfr,T_POWERFAIL,) /* 2. power failure */
450: TRAP(all,T_RECOVERY,) /* 3. recovery counter trap */
451: TRAP(all,T_INTERRUPT,) /* 4. external interrupt */
452: TRAP(all,T_LPMC,) /* 5. low-priority machine check */
453: TRAP(itlb,T_ITLBMISS,ITLBPRE) /* 6. instruction TLB miss fault */
454: TRAP(all,T_IPROT,) /* 7. instruction protection trap */
455: TRAP(all,T_ILLEGAL,) /* 8. Illegal instruction trap */
456: TRAP(ibrk,T_IBREAK,BRKPRE) /* 9. break instruction trap */
457: TRAP(all,T_PRIV_OP,) /* 10. privileged operation trap */
458: TRAP(all,T_PRIV_REG,) /* 11. privileged register trap */
459: TRAP(all,T_OVERFLOW,) /* 12. overflow trap */
460: TRAP(all,T_CONDITION,) /* 13. conditional trap */
461: TRAP(excpt,T_EXCEPTION,) /* 14. assist exception trap */
462: TRAP(dtlb,T_DTLBMISS,DTLBPRE) /* 15. data TLB miss fault */
463: TRAP(itlbna,T_ITLBMISSNA,DTLBPRE)/* 16. ITLB non-access miss fault */
464: TRAP(dtlbna,T_DTLBMISSNA,DTLBPRE)/* 17. DTLB non-access miss fault */
465: TRAP(all,T_DPROT,) /* 18. data protection trap
466: unaligned data reference trap */
467: TRAP(all,T_DBREAK,) /* 19. data break trap */
468: TRAP(tlbd,T_TLB_DIRTY,DTLBPRE) /* 20. TLB dirty bit trap */
469: TRAP(all,T_PAGEREF,) /* 21. page reference trap */
470: TRAP(emu,T_EMULATION,) /* 22. assist emulation trap */
471: TRAP(all,T_HIGHERPL,) /* 23. higher-privelege transfer trap*/
472: TRAP(all,T_LOWERPL,) /* 24. lower-privilege transfer trap */
473: TRAP(all,T_TAKENBR,) /* 25. taken branch trap */
474: TRAP(all,T_DATACC,) /* 26. data access rights trap */
475: TRAP(all,T_DATAPID,) /* 27. data protection ID trap */
476: TRAP(all,T_DATALIGN,) /* 28. unaligned data ref trap */
477: TRAP(all,29,)
478: TRAP(all,30,)
479: TRAP(all,31,)
480: TRAP(all,32,)
481: TRAP(all,33,)
482: TRAP(all,34,)
483: TRAP(all,35,)
484: TRAP(all,36,)
485: TRAP(all,37,)
486: TRAP(all,38,)
487: TRAP(all,39,)
488: TRAP(all,40,)
489: TRAP(all,41,)
490: TRAP(all,42,)
491: TRAP(all,43,)
492: TRAP(all,44,)
493: TRAP(all,45,)
494: TRAP(all,46,)
495: TRAP(all,47,)
496: TRAP(all,48,)
497: TRAP(all,49,)
498: TRAP(all,50,)
499: TRAP(all,51,)
500: TRAP(all,52,)
501: TRAP(all,53,)
502: TRAP(all,54,)
503: TRAP(all,55,)
504: TRAP(all,56,)
505: TRAP(all,57,)
506: TRAP(all,58,)
507: TRAP(all,59,)
508: TRAP(all,60,)
509: TRAP(all,61,)
510: TRAP(all,62,)
511: TRAP(all,63,)
512: /* 64 */
513:
514: /*
515: * High Priority Machine Check Interrupt
516: */
517: .export TLABEL(hpmc), entry
518: ENTRY(TLABEL(hpmc),0)
519: rfi
520: nop
521:
522: hpmc_never_dies
523: b hpmc_never_dies
524: nop
525: EXIT(TLABEL(hpmc))
526:
527: /*
528: * transfer of control handler
529: */
530: ENTRY(hppa_toc,0)
531: rfi
532: nop
533:
534: ALTENTRY(hppa_toc_end)
535: .word 0
536: EXIT(hppa_toc)
537:
538: /*
539: * power fail recovery handler
540: */
541: ENTRY(TLABEL(pfr),0)
542: rfi
543: nop
544:
545: ALTENTRY(hppa_pfr_end)
546: .word 0
547: EXIT(hppa_pfr)
548:
549: /*
550: * system breaks
551: */
552: .export TLABEL(ibrk), entry
553: ENTRY(TLABEL(ibrk),0)
554: /* If called by a user process then always pass it to trap() */
555: extrd,u,*= %r8, 63, 2, %r0
556: b,n TLABEL(all)
557:
558: /* don't accept breaks from data segments */
559: .import etext, code
560: ldil L%etext, %r9
561: ldo R%etext(%r9), %r9
562: cmpb,*>>=,n %r8, %r9, TLABEL(all)
563:
564: mfctl %iir, %r8
565: extrd,u,*= %r8, 63, 5, %r0
566: b,n TLABEL(all)
567:
568: /* now process all those `break' calls we make */
569: extrd,u %r8, 50, 13, %r9
570: comib,=,n HPPA_BREAK_GET_PSW, %r9, $ibrk_getpsw
571: comib,=,n HPPA_BREAK_SET_PSW, %r9, $ibrk_setpsw
572:
573: b TLABEL(all)
574: nop
575:
576: $ibrk_getpsw
577: b $ibrk_exit
578: mfctl %ipsw, %ret0
579:
580: $ibrk_setpsw
581: mfctl %ipsw, %ret0
582: b $ibrk_exit
583: mtctl %arg0, %ipsw
584:
585: /* insert other fast breaks here */
586: nop ! nop
587:
588: $ibrk_exit
589: /* skip the break */
590: mtctl %r0, %pcoq
591: mfctl %pcoq, %r9
592: mtctl %r9, %pcoq
593: ldo 4(%r9), %r9
594: mtctl %r9, %pcoq
595:
596: rfi,r
597: nop
598: EXIT(TLABEL(ibrk))
599:
600: .export TLABEL(all), entry
601: ENTRY(TLABEL(all),0)
602: /* %r1 still has trap type */
603: mfctl %ipsw, %r9
604: mtctl %r9, %cr31
605:
606: mtsp %r0, %sr3
607: ldi HPPA_PID_KERNEL, %r9
608: mtctl %r9, %pidr3
609:
610: mfctl %isr, %r8
611: mfctl %ior, %r9
612: extrd,u %r8, 63, SID_SHIFT, %r16
613: depd %r16, 31, SID_SHIFT, %r9
614: depd %r0, 63, SID_SHIFT, %r8
615: mtsp %r8, %sr6
616: mtctl %r9, %cr27
617:
618: mfctl %pcsq, %r24
619: mtctl %r0, %pcsq
620: mfctl %pcsq, %r25
621: mtctl %r0, %pcsq
622: mtsp %r24, %sr4
623: mtsp %r25, %sr5
624:
625: /* TODO fix pcsq:pcoq split */
626: ldil L%TLABEL(all_virt), %r9
627: ldo R%TLABEL(all_virt)(%r9), %r9
628: mfctl %pcoq, %r24
629: mtctl %r9, %pcoq
630: mfctl %pcoq, %r25
631: ldo 4(%r9), %r9
632: mtctl %r24, %cr28
633: mtctl %r9, %pcoq
634: mtctl %r25, %cr29
635:
636: ldil L%$kpsl, %r9
637: ldw R%$kpsl(%r9), %r9
638: mtctl %r9, %ipsw
639:
640: mfctl %cr30, %r9
641:
642: mfsp %sr0, %r8
643: extrd,u,*<> %r24, 63, 2, %r0 /* still pcoq head */
644: cmpb,*= %r0, %r8, TLABEL(all_kern)
645: copy %sp, %r17
646:
647: depdi 1, T_USER_POS, 1, %r1
648: depdi 1, TFF_LAST_POS, 1, %r1
649: ldd U_PCB+PCB_UVA(%r9), %sp
650: ldo PAGE_SIZE-TRAPFRAME_SIZEOF(%sp), %sp
651:
652: TLABEL(all_kern)
653: ldo 127(%sp), %sp
654: depdi 0, 63, 7, %sp
655:
656: ldo TF_SP(%sp), %r8
657: std %r17, 0(%r8)
658: fdc %r0(%r8)
659:
660: mfctl %iir, %r16
661: ldo TF_IIR(%sp), %r8
662: std %r16, 0(%r8)
663: fdc %r0(%r8)
664:
665: mtctl %r1, %cr26
666: rfi,r
667: nop ! nop ! nop ! nop ! nop ! nop ! nop ! nop
668: TLABEL(all_virt)
669:
670: ldo 8(%sp), %sp /* space for flags */
671: std,ma %r1, 8(%sr3,%sp)
672: mfctl %cr26, %r1 /* sar */
673: std %r1, -16(%sr3,%sp)
674: std,ma %rp, 8(%sr3,%sp)
675: std,ma %r3, 8(%sr3,%sp)
676: std,ma %r4, 8(%sr3,%sp)
677: std,ma %r5, 8(%sr3,%sp)
678: std,ma %r6, 8(%sr3,%sp)
679: std,ma %r7, 8(%sr3,%sp)
680: std,ma %r8, 8(%sr3,%sp)
681: std,ma %r9, 8(%sr3,%sp)
682: std,ma %r10, 8(%sr3,%sp)
683: std,ma %r11, 8(%sr3,%sp)
684: std,ma %r12, 8(%sr3,%sp)
685: std,ma %r13, 8(%sr3,%sp)
686: std,ma %r14, 8(%sr3,%sp)
687: std,ma %r15, 8(%sr3,%sp)
688: std,ma %r16, 8(%sr3,%sp)
689: std,ma %r17, 8(%sr3,%sp)
690: std,ma %r18, 8(%sr3,%sp)
691: std,ma %r19, 8(%sr3,%sp)
692: std,ma %r20, 8(%sr3,%sp)
693: std,ma %r21, 8(%sr3,%sp)
694: std,ma %r22, 8(%sr3,%sp)
695: std,ma %r23, 8(%sr3,%sp)
696: std,ma %r24, 8(%sr3,%sp)
697: std,ma %r25, 8(%sr3,%sp)
698: std,ma %r26, 8(%sr3,%sp)
699: std,ma %r27, 8(%sr3,%sp)
700: std,ma %r28, 8(%sr3,%sp)
701: std,ma %r29, 8(%sr3,%sp)
702: ldo -30*8(%sp), %arg1
703: ldo 8(%sp), %sp /* %sp */
704: std,ma %r31, 8(%sr3,%sp)
705: copy %r1, %arg0
706:
707: mfsp %sr0, %arg2
708: mfsp %sr1, %arg3
709: std,ma %arg2, 8(%sr3,%sp) /* %sr0 */
710: std,ma %arg3, 8(%sr3,%sp) /* %sr1 */
711: std,ma %arg2, 8(%sr3,%sp) /* %sr2 */
712: std,ma %arg2, 8(%sr3,%sp) /* %sr3 */
713: std,ma %arg2, 8(%sr3,%sp) /* %sr4 */
714: std,ma %arg2, 8(%sr3,%sp) /* %sr5 */
715: std,ma %arg2, 8(%sr3,%sp) /* %sr6 */
716: std,ma %arg2, 8(%sr3,%sp) /* %sr7 */
717:
718: mfctl %cr0, %arg3
719: mfctl %cr10, %arg2
720: std,ma %arg3, 8(%sr3,%sp) /* rctr */
721: std,ma %arg2, 8(%sr3,%sp) /* ccr */
722:
723: mfctl %cr28, %arg2 /* pcoq */
724: mfctl %cr29, %arg3
725: std,ma %arg2, 8(%sr3,%sp)
726: std,ma %arg3, 8(%sr3,%sp)
727:
728: mfsp %sr4, %arg2 /* pcsq */
729: mfsp %sr5, %arg3
730: std,ma %arg2, 8(%sr3,%sp)
731: std,ma %arg3, 8(%sr3,%sp)
732:
733: mfctl %pidr1, %arg2
734: mfctl %pidr2, %arg3
735: std,ma %arg2, 8(%sr3,%sp) /* pidr1 */
736: std,ma %arg3, 8(%sr3,%sp) /* pidr2 */
737:
738: mfctl %pidr3, %r1
739: mtctl %r1, %pidr1
740: mtctl %r0, %pidr3
741:
742: mfctl %eiem, %arg2
743: mfctl %eirr, %arg3
744: std,ma %arg2, 8(%sr3,%sp) /* eiem */
745: std,ma %arg3, 8(%sr3,%sp) /* eirr */
746:
747: mfctl %cr27, %arg2
748: mfsp %sr6, %arg3
749: std,ma %arg2, 8(%sr3,%sp) /* ior */
750: std,ma %arg3, 8(%sr3,%sp) /* isr */
751:
752: ldo 8(%sp), %sp /* iir */
753: mfctl %cr31, %arg3
754: std,ma %arg3, 8(%sr3,%sp) /* ipsw */
755:
756: mfctl %cr24, %arg2
757: mfctl %cr25, %arg3
758: std,ma %arg2, 8(%sr3,%sp) /* curcpuinfo */
759: std,ma %arg3, 8(%sr3,%sp) /* vtop */
760:
761: mfctl %cr30, %arg2
762: mfctl %cr27, %arg3 /* XXX */
763: std,ma %arg2, 8(%sr3,%sp) /* pa(u) */
764: std,ma %arg3, 8(%sr3,%sp) /* user curthread */
765:
766: mfctl %sar, %arg2
767: std,ma %arg2, 8(%sr3,%sp) /* sar */
768:
769: mtsp %r0, %sr0
770: mtsp %r0, %sr1
771: mtsp %r0, %sr2
772: mtsp %r0, %sr3
773: mtsp %r0, %sr4
774: mtsp %r0, %sr5
775: mtsp %r0, %sr6
776: mtsp %r0, %sr7
777:
778: ldo TRAPFRAME_SIZEOF(%arg1), %sp
779: copy %sp, %r3
780: std,ma %r0, HPPA_FRAME_SIZE(%sp)
781:
782: ldil L%__gp, %dp
783: ldo R%__gp(%dp), %dp
784: copy %arg1, %r5
785:
786: depd %r0, T_USER_POS+1, T_USER_POS, %arg0
787: .import trap, code
788: b,l trap, %rp
789: copy %arg0, %r4
790:
791: /* non-terminal frames return to the same proc */
792: bb,*>=,n %r4, TFF_LAST_POS, $syscall_return
793: copy %r5, %arg0
794:
795: /* see if curproc have really changed */
796: mfctl %cr24, %arg1
797: ldd CI_CURPROC(%arg1), %r1
798: sub,*= %r0, %r1, %r0
799: ldd P_MD_REGS(%r1), %r5
800:
801: b $syscall_return
802: copy %r5, %arg0
803: EXIT(TLABEL(all))
804:
805: #define PTPULL(bits,lbl) \
806: /* space:offset -- %r8:%r9 */ ! \
807: ldil L%__kernel_pagedir, %r24 ! \
808: or,*= %r8, %r8, %r0 ! \
809: mfctl %cr25, %r24 /* vtop */ ! \
810: ldo PAGE_SIZE(%r24), %r25 ! \
811: extrd,u %r25, 51, 32, %r25 ! \
812: extrd,u,*= %r9, 32, 10, %r17 ! \
813: ldw,s %r17(%r24), %r25 ! \
814: extrd,u %r9, 42, 10, %r17 ! \
815: depd,z,*<> %r25, 51, 32, %r25 ! \
816: b,n lbl ! \
817: ldw,s %r17(%r25), %r25 ! \
818: extrd,u %r9, 51, 9, %r24 ! \
819: depd,z,*<> %r25, 51, 32, %r25 ! \
820: b,n lbl ! \
821: ldd,s %r24(%r25), %r16 ! \
822: or,*<> %r16, %r0, %r17 ! \
823: b,n lbl ! \
824: depdi bits, 2+bits, 1+bits, %r17 ! \
825: shladd,l %r24, 3, %r25, %r25 ! \
826: sub,*= %r16, %r17, %r0 ! \
827: std %r17, 0(%r25) ! \
828: extrd,s %r16, 63, 37, %r16 ! \
829: depd %r8, 63, 48, %r17 ! \
830: depdi 1, 62, 1, %r17
831:
832: TLABEL(itlb)
833: PTPULL(0, TLABEL(all))
834: iitlbt %r16, %r17
835: rfi,r
836: nop
837:
838: TLABEL(tlbd)
839: PTPULL(1, TLABEL(all))
840: idtlbt %r16, %r17
841: rfi,r
842: nop
843:
844: TLABEL(itlbna)
845: TLABEL(dtlbna)
846: PTPULL(0, TLABEL(dtlbna_fake))
847: idtlbt %r16, %r17
848: rfi,r
849: nop
850: TLABEL(dtlbna_fake)
851: /* parse probei?,[rw] insns, decent to trap() to set regs proper */
852: mfctl %iir, %r16
853: extrd,u %r16, 38, 6, %r24
854: comib,=,n 1, %r24, TLABEL(all)
855: extrd,u %r16, 56, 6, %r24
856: subi,<> 0x23, %r24, %r0
857: b TLABEL(all)
858: subi,<> 0x63, %r24, %r0
859: b TLABEL(all)
860: /* otherwise generate a flush-only tlb entry */
861: depd,z %r8, 62, 47, %r17
862: depdi -13, 11, 7, %r17
863: ldo 2(%r17), %r17 /* 3? */
864: idtlbt %r0, %r17
865: rfi,r
866: nop
867:
868: TLABEL(dtlb)
869: PTPULL(0, TLABEL(all))
870: idtlbt %r16, %r17
871: rfi,r
872: nop
873:
874: .export TLABEL(excpt), entry
875: ENTRY(TLABEL(excpt),0)
876: /* assume we never get this one w/o fpu [enabled] */
877: copy %rp, %r1
878: copy %arg0, %r8
879: mfctl %cr30, %r9
880: #if (PCB_FPREGS+U_PCB) != 0
881: ldo PCB_FPREGS+U_PCB(%r9), %r9
882: #endif
883: .import fpu_save, code
884: .call
885: b,l fpu_save, %rp
886: copy %r9, %arg0
887: copy %r1, %rp
888: copy %r8, %arg0
889: mtctl %r0, %cr10 /* reset ccr: cause a reload after exception */
890: ldil L%fpu_curpcb, %r1
891: std %r0, R%fpu_curpcb(%r1)
892:
893: /* now, check for trap */
894: ldw 0(%r9), %r1
895: bb,>=,n %r1, HPPA_FPU_T_POS, excpt_notrap
896: ldw 1*4(%r9), %r1
897: comb,<>,n %r0, %r1, excpt_emulate
898: ldw 2*4(%r9), %r1
899: comb,<>,n %r0, %r1, excpt_emulate
900: ldw 3*4(%r9), %r1
901: comb,<>,n %r0, %r1, excpt_emulate
902: ldw 4*4(%r9), %r1
903: comb,<>,n %r0, %r1, excpt_emulate
904: ldw 5*4(%r9), %r1
905: comb,<>,n %r0, %r1, excpt_emulate
906: ldw 6*4(%r9), %r1
907: comb,<>,n %r0, %r1, excpt_emulate
908: ldw 7*4(%r9), %r1
909:
910: excpt_emulate
911: bb,*>=,n %r1, 37, excpt_notrap /* HPPA_FPU_UNMPL not set */
912:
913: #if TODO_emulate
914: ldw 0(%r9), %r16
915: depi 0, HPPA_FPU_T_POS, 1, %r16
916: .import $fpu_emulate, code
917: b $fpu_emulate
918: stw %r16, 0(%r9)
919: #endif
920:
921: excpt_notrap
922: sync
923: b TLABEL(all)
924: ldi T_EXCEPTION, %r1
925: EXIT(TLABEL(excpt))
926:
927: .export TLABEL(emu), entry
928: ENTRY(TLABEL(emu),0)
929: /*
930: * Switch FPU/SFU context
931: *
932: * %isr:%ior - data address
933: * %iir - instruction to emulate
934: * iisq:iioq - address of instruction to emulate
935: *
936: * note: ISR and IOR contain valid data only if the
937: * instruction is a coprocessor load or store.
938: *
939: */
940:
941: mfctl %iir, %r8
942: extrd,u %r8, 37, 6, %r9 /* no sfu implementation right now */
943: comib,= 4, %r9, TLABEL(all)
944: ldi T_ILLEGAL, %r1
945:
946: /*
947: * pass through for all coprocessors now and
948: * do not check the uid here.
949: * in case that piece does not exist emulate
950: * or the trap will be generted later.
951: */
952:
953: /* if we are already enabled and hit again, emulate */
954: mfctl %cr10, %r1 /* ccr */
955: extru,<> %r1, 25, 2, %r0
956: b,n $fpusw_set
957: nop
958:
959: $fpusw_emu
960: mtctl %r0, %cr10 /* reset ccr: cause a reload after exception */
961: std %r0, R%fpu_curpcb(%r1)
962: #if TODO_emulate
963: /* here we emulate the fld/fst */
964: mfctl %iir, %r1
965: extrd,u %r1, 37, 6, %r1
966: comib,= 0xb, %r9, TLABEL(all)
967: ldi T_ILLEGAL, %r1
968:
969: mfctl %iir, %r1
970: extrd,u %r1, 37, 6, %r1
971: comib,= 0x9, %r9, TLABEL(all)
972: ldi T_ILLEGAL, %r1
973:
974: mfctl %iir, %r1
975: .import $fpu_emulate, code
976: b $fpu_emulate
977: nop
978: #else
979: b TLABEL(all)
980: ldi T_ILLEGAL, %r1
981: #endif
982: $fpusw_set
983: /* enable coprocessor */
984: depdi 3, 37, 2, %r1
985: mtctl %r1, %cr10 /* ccr */
986:
987: ldil L%fpu_curpcb, %r16
988: mfctl %cr30, %r9
989: ldd R%fpu_curpcb(%r16), %r16
990:
991: comb,=,n %r16, %r0, $fpusw_nosave
992: comb,=,n %r16, %r9, $fpusw_done
993:
994: copy %arg0, %r17
995: copy %rp, %r1
996: #if (PCB_FPREGS+U_PCB) != 0
997: ldo PCB_FPREGS+U_PCB(%r16), %r16
998: #endif
999: .import fpu_save, code
1000: .call
1001: b,l fpu_save, %rp
1002: copy %r16, %arg0
1003: copy %r1, %rp
1004: copy %r17, %arg0
1005:
1006: $fpusw_nosave
1007: /* count switches */
1008: .import umvexp, data
1009: ldil L%(uvmexp+FPSWTCH), %r1
1010: ldw R%(uvmexp+FPSWTCH)(%r1), %r16
1011: ldo 31*8+PCB_FPREGS+U_PCB(%r9), %r17
1012: ldo 1(%r16), %r16
1013: stw %r16, R%(uvmexp+FPSWTCH)(%r1)
1014:
1015: fldds,ma -8(%r17), %fr31
1016: fldds,ma -8(%r17), %fr30
1017: fldds,ma -8(%r17), %fr29
1018: fldds,ma -8(%r17), %fr28
1019: fldds,ma -8(%r17), %fr27
1020: fldds,ma -8(%r17), %fr26
1021: fldds,ma -8(%r17), %fr25
1022: fldds,ma -8(%r17), %fr24
1023: fldds,ma -8(%r17), %fr23
1024: fldds,ma -8(%r17), %fr22
1025: fldds,ma -8(%r17), %fr21
1026: fldds,ma -8(%r17), %fr20
1027: fldds,ma -8(%r17), %fr19
1028: fldds,ma -8(%r17), %fr18
1029: fldds,ma -8(%r17), %fr17
1030: fldds,ma -8(%r17), %fr16
1031: fldds,ma -8(%r17), %fr15
1032: fldds,ma -8(%r17), %fr14
1033: fldds,ma -8(%r17), %fr13
1034: fldds,ma -8(%r17), %fr12
1035: fldds,ma -8(%r17), %fr11
1036: fldds,ma -8(%r17), %fr10
1037: fldds,ma -8(%r17), %fr9
1038: fldds,ma -8(%r17), %fr8
1039: fldds,ma -8(%r17), %fr7
1040: fldds,ma -8(%r17), %fr6
1041: fldds,ma -8(%r17), %fr5
1042: fldds,ma -8(%r17), %fr4
1043: fldds,ma -8(%r17), %fr3
1044: fldds,ma -8(%r17), %fr2
1045: fldds,ma -8(%r17), %fr1
1046: fldds 0(%r17), %fr0 /* fr0 must be restored last */
1047:
1048: ldil L%fpu_curpcb, %r1
1049: std %r17, R%fpu_curpcb(%r1)
1050:
1051: $fpusw_done
1052: rfir
1053: nop
1054: EXIT(TLABEL(emu))
1055:
1056: LEAF_ENTRY(fpu_exit)
1057: /* enable coprocessor XXX */
1058: depi 3, 25, 2, %r1
1059: mtctl %r1, %cr10
1060:
1061: ldil L%fpu_scratch, %r25
1062: ldo R%fpu_scratch(%r25), %r25
1063: fstds %fr0, 0(%r25)
1064: sync
1065: bv %r0(%rp)
1066: mtctl %r0, %cr10
1067: EXIT(fpu_exit)
1068:
1069: LEAF_ENTRY(fpu_save)
1070: fstds,ma %fr0 , 8(%arg0)
1071: fstds,ma %fr1 , 8(%arg0)
1072: fstds,ma %fr2 , 8(%arg0)
1073: fstds,ma %fr3 , 8(%arg0)
1074: fstds,ma %fr4 , 8(%arg0)
1075: fstds,ma %fr5 , 8(%arg0)
1076: fstds,ma %fr6 , 8(%arg0)
1077: fstds,ma %fr7 , 8(%arg0)
1078: fstds,ma %fr8 , 8(%arg0)
1079: fstds,ma %fr9 , 8(%arg0)
1080: fstds,ma %fr10, 8(%arg0)
1081: fstds,ma %fr11, 8(%arg0)
1082: fstds,ma %fr12, 8(%arg0)
1083: fstds,ma %fr13, 8(%arg0)
1084: fstds,ma %fr14, 8(%arg0)
1085: fstds,ma %fr15, 8(%arg0)
1086: fstds,ma %fr16, 8(%arg0)
1087: fstds,ma %fr17, 8(%arg0)
1088: fstds,ma %fr18, 8(%arg0)
1089: fstds,ma %fr19, 8(%arg0)
1090: fstds,ma %fr20, 8(%arg0)
1091: fstds,ma %fr21, 8(%arg0)
1092: fstds,ma %fr22, 8(%arg0)
1093: fstds,ma %fr23, 8(%arg0)
1094: fstds,ma %fr24, 8(%arg0)
1095: fstds,ma %fr25, 8(%arg0)
1096: fstds,ma %fr26, 8(%arg0)
1097: fstds,ma %fr27, 8(%arg0)
1098: fstds,ma %fr28, 8(%arg0)
1099: fstds,ma %fr29, 8(%arg0)
1100: fstds,ma %fr30, 8(%arg0)
1101: fstds %fr31, 0(%arg0)
1102: ldo -24(%arg0), %arg0
1103: ldi -32, %r25 /* gotta be free for all callers */
1104: fdc,m %r25(%arg0)
1105: fdc,m %r25(%arg0)
1106: fdc,m %r25(%arg0)
1107: fdc,m %r25(%arg0)
1108: fdc,m %r25(%arg0)
1109: fdc,m %r25(%arg0)
1110: fdc,m %r25(%arg0)
1111: fdc,m %r25(%arg0)
1112: bv %r0(%rp)
1113: sync
1114: EXIT(fpu_save)
1115:
1116: /*
1117: * void
1118: * mtctl(register_t val, int reg)
1119: */
1120: LEAF_ENTRY(mtctl)
1121: b,l mtctl_end, %r1
1122: extrd,u %arg1, 63, 32, %arg1
1123: bv %r0(%rp)
1124: mtctl %arg0, %cr0
1125: bv %r0(%rp)
1126: nop /* mtctl %arg0, %cr1 */
1127: bv %r0(%rp)
1128: nop /* mtctl %arg0, %cr2 */
1129: bv %r0(%rp)
1130: nop /* mtctl %arg0, %cr3 */
1131: bv %r0(%rp)
1132: nop /* mtctl %arg0, %cr4 */
1133: bv %r0(%rp)
1134: nop /* mtctl %arg0, %cr5 */
1135: bv %r0(%rp)
1136: nop /* mtctl %arg0, %cr6 */
1137: bv %r0(%rp)
1138: nop /* mtctl %arg0, %cr7 */
1139: bv %r0(%rp)
1140: mtctl %arg0, %cr8
1141: bv %r0(%rp)
1142: mtctl %arg0, %cr9
1143: bv %r0(%rp)
1144: mtctl %arg0, %cr10
1145: bv %r0(%rp)
1146: mtctl %arg0, %cr11
1147: bv %r0(%rp)
1148: mtctl %arg0, %cr12
1149: bv %r0(%rp)
1150: mtctl %arg0, %cr13
1151: bv %r0(%rp)
1152: mtctl %arg0, %cr14
1153: bv %r0(%rp)
1154: mtctl %arg0, %cr15
1155: bv %r0(%rp)
1156: mtctl %arg0, %cr16
1157: bv %r0(%rp)
1158: mtctl %arg0, %cr17
1159: bv %r0(%rp)
1160: mtctl %arg0, %cr18
1161: bv %r0(%rp)
1162: mtctl %arg0, %cr19
1163: bv %r0(%rp)
1164: mtctl %arg0, %cr20
1165: bv %r0(%rp)
1166: mtctl %arg0, %cr21
1167: bv %r0(%rp)
1168: mtctl %arg0, %cr22
1169: bv %r0(%rp)
1170: mtctl %arg0, %cr23
1171: bv %r0(%rp)
1172: mtctl %arg0, %cr24
1173: bv %r0(%rp)
1174: mtctl %arg0, %cr25
1175: bv %r0(%rp)
1176: mtctl %arg0, %cr26
1177: bv %r0(%rp)
1178: mtctl %arg0, %cr27
1179: bv %r0(%rp)
1180: mtctl %arg0, %cr28
1181: bv %r0(%rp)
1182: mtctl %arg0, %cr29
1183: bv %r0(%rp)
1184: mtctl %arg0, %cr30
1185: bv %r0(%rp)
1186: mtctl %arg0, %cr31
1187: mtctl_end
1188: subi,<< 31, %arg1, %r0
1189: bv,n %arg1(%r1)
1190: bv %r0(%rp)
1191: nop
1192: EXIT(mtctl)
1193:
1194: /*
1195: * void
1196: * pdtlb(pa_space_t sp, vaddr_t va)
1197: */
1198: LEAF_ENTRY(pdtlb)
1199: mfsp %sr1, %arg2
1200: mtsp %arg0, %sr1
1201: pdtlb %r0(%sr1, %arg1)
1202: bv %r0(%rp)
1203: mtsp %arg2, %sr1
1204: EXIT(pdtlb)
1205:
1206: /*
1207: * void
1208: * pitlb(pa_space_t sp, vaddr_t va)
1209: */
1210: LEAF_ENTRY(pitlb)
1211: mfsp %sr1, %arg2
1212: mtsp %arg0, %sr1
1213: pitlb %r0(%sr1, %arg1)
1214: bv %r0(%rp)
1215: mtsp %arg2, %sr1
1216: EXIT(pitlb)
1217:
1218: /*
1219: * register_t
1220: * mfctl(int reg)
1221: */
1222: LEAF_ENTRY(mfctl)
1223: b,l mfctl_end, %r1
1224: extrd,u %arg0, 63, 32, %arg0
1225: bv %r0(%rp)
1226: mfctl %cr0, %ret0
1227: bv %r0(%rp)
1228: nop /* mfctl %cr1, %ret0 */
1229: bv %r0(%rp)
1230: nop /* mfctl %cr2, %ret0 */
1231: bv %r0(%rp)
1232: nop /* mfctl %cr3, %ret0 */
1233: bv %r0(%rp)
1234: nop /* mfctl %cr4, %ret0 */
1235: bv %r0(%rp)
1236: nop /* mfctl %cr5, %ret0 */
1237: bv %r0(%rp)
1238: nop /* mfctl %cr6, %ret0 */
1239: bv %r0(%rp)
1240: nop /* mfctl %cr7, %ret0 */
1241: bv %r0(%rp)
1242: mfctl %cr8, %ret0
1243: bv %r0(%rp)
1244: mfctl %cr9, %ret0
1245: bv %r0(%rp)
1246: mfctl %cr10, %ret0
1247: bv %r0(%rp)
1248: mfctl %cr11, %ret0
1249: bv %r0(%rp)
1250: mfctl %cr12, %ret0
1251: bv %r0(%rp)
1252: mfctl %cr13, %ret0
1253: bv %r0(%rp)
1254: mfctl %cr14, %ret0
1255: bv %r0(%rp)
1256: mfctl %cr15, %ret0
1257: bv %r0(%rp)
1258: mfctl %cr16, %ret0
1259: bv %r0(%rp)
1260: mfctl %cr17, %ret0
1261: bv %r0(%rp)
1262: mfctl %cr18, %ret0
1263: bv %r0(%rp)
1264: mfctl %cr19, %ret0
1265: bv %r0(%rp)
1266: mfctl %cr20, %ret0
1267: bv %r0(%rp)
1268: mfctl %cr21, %ret0
1269: bv %r0(%rp)
1270: mfctl %cr22, %ret0
1271: bv %r0(%rp)
1272: mfctl %cr23, %ret0
1273: bv %r0(%rp)
1274: mfctl %cr24, %ret0
1275: bv %r0(%rp)
1276: mfctl %cr25, %ret0
1277: bv %r0(%rp)
1278: mfctl %cr26, %ret0
1279: bv %r0(%rp)
1280: mfctl %cr27, %ret0
1281: bv %r0(%rp)
1282: mfctl %cr28, %ret0
1283: bv %r0(%rp)
1284: mfctl %cr29, %ret0
1285: bv %r30(%rp)
1286: mfctl %cr30, %ret0
1287: bv %r30(%rp)
1288: mfctl %cr31, %ret0
1289:
1290: mfctl_end
1291: subi,<< 31, %arg0, %r0
1292: bv,n %arg0(%r1)
1293: bv %r0(%rp)
1294: nop
1295: EXIT(mfctl)
1296:
1297: #define CACHELOOP(sp,addr,len,step,insn) \
1298: mtsp sp, %sr1 ! \
1299: ldi -1, arg7 ! \
1300: sh3add step, arg7, %r1 ! \
1301: andcm len, %r1, %r1 ! \
1302: add addr, %r1, %r1 ! \
1303: b __CONCAT(insn,_loop) ! \
1304: add addr, len, len ! \
1305: .label __CONCAT(insn,_loop8) ! \
1306: insn,m step(%sr1, addr) ! \
1307: insn,m step(%sr1, addr) ! \
1308: insn,m step(%sr1, addr) ! \
1309: insn,m step(%sr1, addr) ! \
1310: insn,m step(%sr1, addr) ! \
1311: insn,m step(%sr1, addr) ! \
1312: insn,m step(%sr1, addr) ! \
1313: .label __CONCAT(insn,_loop) ! \
1314: comb,<< addr, %r1, __CONCAT(insn,_loop8) ! \
1315: insn,m step(%sr1, addr) ! \
1316: .label __CONCAT(insn,_loop1) ! \
1317: comb,<<,n addr, len, __CONCAT(insn,_loop1) ! \
1318: insn,m step(%sr1, addr)
1319:
1320:
1321: LEAF_ENTRY(fdcache)
1322: ldil L%dcache_stride, %r1
1323: ldw R%dcache_stride(%r1), %arg3
1324: CACHELOOP(%arg0,%arg1,%arg2,%arg3,fdc)
1325: bv %r0(%rp)
1326: sync
1327: EXIT(fdcache)
1328:
1329: LEAF_ENTRY(pdcache)
1330: ldil L%dcache_stride, %r1
1331: ldw R%dcache_stride(%r1), %arg3
1332: CACHELOOP(%arg0,%arg1,%arg2,%arg3,pdc)
1333: bv %r0(%rp)
1334: sync
1335: EXIT(pdcache)
1336:
1337: LEAF_ENTRY(ficache)
1338: ldil L%icache_stride, %r1
1339: ldw R%icache_stride(%r1), %arg3
1340: CACHELOOP(%arg0,%arg1,%arg2,%arg3,fic)
1341: bv %r0(%rp)
1342: sync
1343: EXIT(ficache)
1344:
1345: LEAF_ENTRY(copy_on_fault)
1346: mtsp %r0, %sr1
1347: mtsp %r0, %sr2
1348: std %r1, PCB_ONFAULT+U_PCB(%rp)
1349: ldd HPPA_FRAME_RP(%sp), %rp
1350: ldo -HPPA_FRAME_SIZE(%sp), %sp
1351: bv %r0(%rp)
1352: ldi EFAULT, %ret0
1353: EXIT(copy_on_fault)
1354:
1355: LEAF_ENTRY(sync_caches)
1356: sync
1357: syncdma
1358: sync
1359: nop
1360: nop
1361: nop
1362: nop
1363: nop
1364: nop
1365: bv %r0(%rp)
1366: nop
1367: EXIT(sync_caches)
1368:
1369: /*
1370: * int spstrcpy (pa_space_t ssp, const void *src, pa_space_t dsp, void *dst,
1371: * size_t size, size_t *rsize)
1372: * do a space to space strncpy, return actual copy size in the rsize;
1373: */
1374: LEAF_ENTRY(spstrcpy)
1375: stw %rp, HPPA_FRAME_RP(%sp)
1376: ldo HPPA_FRAME_SIZE(%sp), %sp
1377: add arg4, %arg1, arg4
1378: /* setup fault handler */
1379: mfctl %cr24, %arg1
1380: ldd CI_CURPROC(%arg1), %r1
1381: ldil L%copy_on_fault, arg7
1382: ldd P_ADDR(arg6), %rp
1383: ldo R%copy_on_fault(arg7), arg7
1384: ldd PCB_ONFAULT+U_PCB(%rp), %r1
1385: std arg7, PCB_ONFAULT+U_PCB(%rp)
1386:
1387: mtsp %arg0, %sr1
1388: mtsp %arg2, %sr2
1389: copy %arg1, %arg0
1390:
1391: $spstrcpy_loop
1392: ldbs,ma 1(%sr1, %arg1), arg7
1393: comb,= arg4, %arg1, $spstrcpy_exit
1394: stbs,ma arg7, 1(%sr2, %arg3)
1395: comb,<>,n %r0, arg7, $spstrcpy_loop
1396: nop
1397:
1398: $spstrcpy_exit
1399: ldo -HPPA_FRAME_SIZE(%sp), %sp
1400: mtsp %r0, %sr1
1401: mtsp %r0, %sr2
1402: std %r1, PCB_ONFAULT+U_PCB(%rp)
1403: sub %arg1, %arg0, %arg1
1404: ldd HPPA_FRAME_RP(%sp), %rp
1405: sub,= %r0, arg5, %r0
1406: stw %arg1, 0(arg5)
1407: bv 0(%rp)
1408: copy %r0, %ret0
1409: EXIT(spstrcpy)
1410:
1411: LEAF_ENTRY(setjmp)
1412: std,ma %rp, 8(%arg0)
1413: std,ma %sp, 8(%arg0)
1414: std,ma %r3, 8(%arg0)
1415: std,ma %r4, 8(%arg0)
1416: std,ma %r5, 8(%arg0)
1417: std,ma %r6, 8(%arg0)
1418: std,ma %r7, 8(%arg0)
1419: std,ma %r8, 8(%arg0)
1420: std,ma %r9, 8(%arg0)
1421: std,ma %r10, 8(%arg0)
1422: std,ma %r11, 8(%arg0)
1423: std,ma %r12, 8(%arg0)
1424: std,ma %r13, 8(%arg0)
1425: std,ma %r14, 8(%arg0)
1426: std,ma %r15, 8(%arg0)
1427: std,ma %r16, 8(%arg0)
1428: std,ma %r17, 8(%arg0)
1429: std,ma %r18, 8(%arg0)
1430: std,ma %r19, 8(%arg0)
1431: std,ma %r27, 8(%arg0)
1432:
1433: bv %r0(%rp)
1434: copy %r0, %ret0
1435: EXIT(setjmp)
1436:
1437: LEAF_ENTRY(longjmp)
1438: ldd,ma 8(%arg0), %rp
1439: ldd,ma 8(%arg0), %sp
1440: ldd,ma 8(%arg0), %r3
1441: ldd,ma 8(%arg0), %r4
1442: ldd,ma 8(%arg0), %r5
1443: ldd,ma 8(%arg0), %r6
1444: ldd,ma 8(%arg0), %r7
1445: ldd,ma 8(%arg0), %r8
1446: ldd,ma 8(%arg0), %r9
1447: ldd,ma 8(%arg0), %r10
1448: ldd,ma 8(%arg0), %r11
1449: ldd,ma 8(%arg0), %r12
1450: ldd,ma 8(%arg0), %r13
1451: ldd,ma 8(%arg0), %r14
1452: ldd,ma 8(%arg0), %r15
1453: ldd,ma 8(%arg0), %r16
1454: ldd,ma 8(%arg0), %r17
1455: ldd,ma 8(%arg0), %r18
1456: ldd,ma 8(%arg0), %r19
1457: ldd,ma 8(%arg0), %r27
1458:
1459: bv %r0(%rp)
1460: copy %arg1, %ret0
1461: EXIT(longjmp)
1462:
1463: .import whichqs, data
1464: .import qs, data
1465: /*
1466: * setrunqueue(struct proc *p);
1467: * Insert a process on the appropriate queue. Should be called at splclock().
1468: */
1469: .align 32
1470: ENTRY(setrunqueue,0)
1471: #ifdef DIAGNOSTIC
1472: ldd P_BACK(%arg0), %r1
1473: comb,<>,n %r0, %r1, Lsetrunqueue_panic
1474: ldd P_WCHAN(%arg0), %r1
1475: comb,<>,n %r0, %r1, Lsetrunqueue_panic
1476: ldb P_STAT(%arg0), %r1
1477: comib,=,n SRUN, %r1, Lsetrunqueue_ok
1478: Lsetrunqueue_panic
1479: copy %arg0, %arg1
1480: ldil L%Lsrqpstr, %arg0
1481: .call
1482: b,l panic, %rp
1483: ldo R%Lsrqpstr(%arg0), %arg0
1484: Lsrqpstr
1485: .asciz "setrunqueue(%p)"
1486: .align 8
1487: Lsetrunqueue_ok
1488: #endif
1489:
1490: ldb P_PRIORITY(%arg0), %r1
1491: ldil L%qs, arg7
1492: shd %r0, %r1, 2, %r1
1493: ldo R%qs(arg7), arg7
1494: sh3add %r1, arg7, arg7
1495: ldil L%whichqs, %arg3
1496: ldd P_BACK(arg7), arg6
1497: std arg7, P_FORW(%arg0)
1498: std %arg0, P_BACK(arg7)
1499: ldw R%whichqs(%arg3), arg5
1500: std %arg0, P_FORW(arg6)
1501: mtctl %r1, %sar
1502: std arg6, P_BACK(%arg0)
1503: vdepi 1, 1, arg5
1504: bv 0(%rp)
1505: stw arg5, R%whichqs(%arg3)
1506: EXIT(setrunqueue)
1507:
1508: /*
1509: * remrunqueue(struct proc *p);
1510: * Remove a process from its queue. Should be called at splclock().
1511: */
1512: .align 32
1513: ENTRY(remrunqueue,0)
1514: ldb P_PRIORITY(%arg0), %r1
1515: shd %r0, %r1, 2, %r1
1516: ldil L%whichqs, arg5
1517: mtsar %r1
1518: ldw R%whichqs(arg5), arg6
1519:
1520: #ifdef DIAGNOSTIC
1521: bvb,<,n arg6, remrunqueue_ok
1522:
1523: Lremrunqueue_panic
1524: copy %arg0, %arg1
1525: ldil L%Lrrqpstr, %arg0
1526: .call
1527: b,l panic, %rp
1528: ldo R%Lrrqpstr(%arg0), %arg0
1529:
1530: Lrrqpstr
1531: .asciz "remrunqueue(%p), bit=%x"
1532: .align 8
1533: remrunqueue_ok
1534: #endif
1535: ldd P_BACK(%arg0), arg7
1536: std %r0, P_BACK(%arg0)
1537: ldd P_FORW(%arg0), %arg0
1538: std %arg0, P_FORW(arg7)
1539: vdepi 0, 1, arg6
1540: sub,*<> arg7, %arg0, %r0
1541: stw arg6, R%whichqs(arg5)
1542: bv 0(%rp)
1543: std arg7, P_BACK(%arg0)
1544: EXIT(remrunqueue)
1545:
1546: /*
1547: * cpu_switch()
1548: * find the highest priority process and resume it.
1549: */
1550: .align 32
1551: ENTRY(cpu_switch,128)
1552: ldil L%cpl, %r1
1553: ldw R%cpl(%r1), %ret0
1554: copy %r3, %r1
1555: std %rp, HPPA_FRAME_RP(%sp)
1556: copy %sp, %r3
1557: stwm %r1, HPPA_FRAME_SIZE+20*8(%sp)
1558: ldo -(HPPA_FRAME_SIZE)(%sp), ap
1559: stw %ret0, 2*8(ap) /* cpl */
1560:
1561: /*
1562: * Clear curproc so that we don't accumulate system time while idle.
1563: */
1564: mfctl %cr24, %r1
1565: ldd CI_CURPROC(%r1), %arg2
1566: b switch_search
1567: std %r0, CI_CURPROC(%r1)
1568: /* remain on the old (curproc)'s stack until we have a better choice */
1569:
1570: cpu_idle
1571: .call
1572: b,l spllower, %rp
1573: copy %r0, %arg0
1574: .import uvm, data
1575: ldil L%uvm, %r1
1576: ldo R%uvm(%r1), %r1
1577: ldw PAGE_IDLE_ZERO(%r1), %r1
1578: sub,<> %r0, %r1, %r0
1579: b,n cpu_loop
1580:
1581: .call
1582: b,l uvm_pageidlezero, %rp
1583: std %arg2, 8(%r3)
1584:
1585: ldw 2*8(ap), %ret0 /* cpl */
1586: ldd 8(%r3), %arg2
1587:
1588: cpu_loop
1589: ldil L%cpl, %arg0
1590: stw %ret0, R%cpl(%arg0)
1591:
1592: switch_search
1593: /*
1594: * t1: &whichqs
1595: * arg2: old curproc
1596: *
1597: */
1598: ldil L%whichqs, %r1
1599: ldw R%whichqs(%r1), %arg2
1600: comb,=,n %r0, %arg2, cpu_idle
1601: copy %r0, %arg0
1602:
1603: ldi 0, %arg3
1604: getbit
1605: mtsar %arg3
1606: bvb,>=,n %arg2, getbit
1607: ldo 1(%arg3), %arg3
1608:
1609: ldil L%qs, %arg2
1610: ldo R%qs(%arg2), %arg2
1611: depd %arg3, 62, 63, %arg3
1612: shladd,l %arg3, 3, %arg2, %arg2
1613:
1614: ldd P_FORW(%arg2), %arg1
1615: #ifdef DIAGNOSTIC
1616: comb,<> %arg2, %arg1, link_ok
1617: nop
1618: switch_error
1619: copy %arg3, %arg1
1620: copy %arg2, %arg2
1621: ldil L%Lcspstr, %arg0
1622: .call
1623: b,l panic, %rp
1624: ldo R%Lcspstr(%arg0), %arg0
1625: Lcspstr
1626: .asciz "cpu_switch: bit=%x, q/p=%p"
1627: .align 8
1628: link_ok
1629: #endif
1630: ldil L%want_resched, %r1
1631: stw %r0, R%want_resched(%r1)
1632:
1633: ldd P_FORW(%arg1), %arg0
1634: std %arg0, P_FORW(%arg2)
1635: std %arg2, P_BACK(%arg0)
1636: std %r0, P_BACK(%arg1)
1637:
1638: ldil L%whichqs, %r1
1639: vdepi 0, 1, %arg3
1640: sub,<> %arg2, %arg0, %r0
1641: stw %arg3, R%whichqs(%r1)
1642:
1643: /* don't need &whichqs (t1) starting here */
1644: #ifdef DIAGNOSTIC
1645: ldd P_WCHAN(%arg1), %arg3
1646: comb,<>,n %r0, %arg3, switch_error
1647: copy %arg1, %t2
1648: ldb P_STAT(%arg1), %arg3
1649: comib,<>,n SRUN, %arg3, switch_error
1650: copy %arg1, %arg2
1651: /*
1652: * Either we must be switching to the same process, or
1653: * the new process' kernel stack must be reasonable.
1654: */
1655: comb,=,n %arg1, %arg2, kstack_ok
1656: ldd P_ADDR(%arg1), %arg0
1657: ldd U_PCB+PCB_KSP(%arg0), %arg3
1658: ldo NBPG(%arg0), %arg0
1659: comb,>>,n %arg0, %arg3, switch_error
1660: copy %arg1, %arg2
1661: sub %arg3, %arg0, %arg3
1662: ldil L%USPACE, %arg0
1663: ldo R%USPACE(%arg0), %arg0
1664: comb,<<=,n %arg0, %arg3, switch_error
1665: copy %arg1, %arg2
1666: kstack_ok
1667: #endif
1668: ldi SONPROC, %r1
1669: stb %r1, P_STAT(%arg1)
1670: /* Skip context switch if same process. */
1671: comb,=,n %arg1, %arg2, switch_return
1672:
1673: /* If old process exited, don't bother. */
1674: comb,=,n %r0, %arg2, switch_exited
1675:
1676: /*
1677: * 2. save old proc context
1678: *
1679: * arg2: old proc
1680: */
1681: ldd P_ADDR(%arg2), %r1
1682: /* save callee-save registers */
1683: std %r4, 1*8(%r3)
1684: std %sp, U_PCB+PCB_KSP(%r1)
1685: std %r5, 2*8(%r3)
1686: std %r6, 3*8(%r3)
1687: std %r7, 4*8(%r3)
1688: std %r8, 5*8(%r3)
1689: std %r9, 6*8(%r3)
1690: std %r10, 7*8(%r3)
1691: std %r11, 8*8(%r3)
1692: std %r12, 9*8(%r3)
1693: std %r13, 10*8(%r3)
1694: std %r14, 11*8(%r3)
1695: std %r15, 12*8(%r3)
1696: std %r16, 13*8(%r3)
1697: std %r17, 14*8(%r3)
1698: std %r18, 15*8(%r3)
1699: fdc %r0(%r1)
1700: std %r0, 1*8(ap) /* say no trampoline */
1701: sync
1702:
1703: /* don't need old curproc (arg2) starting from here */
1704: switch_exited
1705: /*
1706: * 3. restore new proc context
1707: *
1708: * arg1: new proc
1709: */
1710: ldd P_ADDR(%arg1), %arg3
1711: ldd P_MD_REGS(%arg1), %r1
1712: ldd U_PCB+PCB_KSP(%arg3), %sp
1713: mtctl %r0, %cr10 /* ccr */
1714: ldd TF_CR30(%r1), %arg2
1715: ldd TF_PIDR2(%r1), %arg3
1716: mtctl %arg2, %cr30
1717: mtctl %arg3, %pidr2
1718: ldo -(HPPA_FRAME_SIZE+20*8)(%sp), %r3
1719: ldo -(HPPA_FRAME_SIZE)(%sp), ap
1720: ldd 0*8(ap), %arg0
1721: ldd 1*8(ap), %arg3 /* in case we're on trampoline */
1722: sub,*= %r0, %arg3, %r0
1723: b,n switch_gonnajump
1724: ldd 1*8(%r3), %r4
1725: ldd 2*8(%r3), %r5
1726: ldd 3*8(%r3), %r6
1727: ldd 4*8(%r3), %r7
1728: ldd 5*8(%r3), %r8
1729: ldd 6*8(%r3), %r9
1730: ldd 7*8(%r3), %r10
1731: ldd 8*8(%r3), %r11
1732: ldd 9*8(%r3), %r12
1733: ldd 10*8(%r3), %r13
1734: ldd 11*8(%r3), %r14
1735: ldd 12*8(%r3), %r15
1736: ldd 13*8(%r3), %r16
1737: ldd 14*8(%r3), %r17
1738: ldd 15*8(%r3), %r18
1739: switch_gonnajump
1740: ldw 2*8(ap), %ret0 /* cpl */
1741: ldil L%cpl, %r1
1742: stw %ret0, R%cpl(%r1)
1743: sync
1744:
1745: switch_return
1746: mfctl %cr24, %r1
1747: std %arg1, CI_CURPROC(%r1)
1748: ldd HPPA_FRAME_RP(%r3), %rp
1749: bv 0(%rp)
1750: ldd,mb -(HPPA_FRAME_SIZE+20*8)(%sp), %r3
1751: EXIT(cpu_switch)
1752:
1753: .align 8
1754: .export switch_tramp_p, code
1755: switch_tramp_p
1756: .dword switch_trampoline
1757:
1758: ENTRY(switch_trampoline,0)
1759: /* ldd 0x18(%arg3), %r19 but we know we are in kernel! */
1760: ldd 0x10(%arg3), %arg3
1761: .call
1762: ble 0(%sr0, %arg3)
1763: copy %r31, %rp
1764:
1765: mfctl %cr24, %arg1
1766: ldd CI_CURPROC(%arg1), %r1
1767: b $syscall_return
1768: ldd P_MD_REGS(%r1), %arg0
1769: EXIT(switch_trampoline)
1770:
1771: /*
1772: * Signal "trampoline" code. Invoked from RTE setup by sendsig().
1773: */
1774: ENTRY(sigcode,0)
1775: ldd 0x18(%arg3), %r19
1776: ldd 0x10(%arg3), %arg3
1777: .call
1778: ble 0(%sr0, %arg3)
1779: copy %r31, %rp
1780:
1781: ldil L%SYSCALLGATE, %r1
1782: copy %r4, %arg0
1783: .call
1784: ble 4(%sr7, %r1)
1785: ldi SYS_sigreturn, %r1
1786:
1787: ldil L%SYSCALLGATE, %r1
1788: copy %ret0, %arg0
1789: .call
1790: ble 4(%sr7, %r1)
1791: ldi SYS_exit, %r1
1792: ALTENTRY(esigcode)
1793: EXIT(sigcode)
1794:
1795: /*
1796: * struct cpu_info *curcpu(void);
1797: */
1798: LEAF_ENTRY(curcpu)
1799: bv %r0(%rp)
1800: mfctl %cr24, %ret0
1801: EXIT(curcpu)
1802:
1803: /*
1804: * int splraise(int newcpl);
1805: */
1806: LEAF_ENTRY(splraise)
1807: bv %r0(%rp)
1808: nop
1809:
1810: extrd,u %arg0, 63, 32, %arg0
1811: #ifdef DEBUG
1812: cmpib,<=,n NIPL, %arg0, splraise_ok
1813: copy %arg0, %arg1
1814: ldil L%splraise_fmt, %arg0
1815: b,l panic, %rp
1816: ldo R%splraise_fmt(%arg0), %arg0
1817: bv %r0(%rp)
1818: ldi IPL_HIGH, %ret0
1819: splraise_fmt
1820: .asciz "splraise(%d)"
1821: .align 8
1822: splraise_ok
1823: #endif
1824: sync
1825: mfctl %eiem, %arg2
1826: mtctl %r0, %eiem
1827: ldil L%cpl, %r1
1828: ldw R%cpl(%r1), %ret0
1829: ldil L%imask, %arg3
1830: ldo R%imask(%arg3), %arg3
1831: sub,<= %arg0, %ret0, %r0
1832: ldd,s %arg0(%arg3), %arg2
1833: sub,<= %arg0, %ret0, %r0
1834: stw %arg0, R%cpl(%r1)
1835: sync
1836: bv %r0(%rp)
1837: mtctl %arg2, %eiem
1838: EXIT(splraise)
1839:
1840: /*
1841: * int spllower(int newcpl);
1842: */
1843: LEAF_ENTRY(spllower)
1844: bv %r0(%rp)
1845: nop
1846:
1847: extrd,u %arg0, 63, 32, %arg0
1848: #ifdef DEBUG
1849: cmpib,<=,n NIPL, %arg0, spllower_ok
1850: copy %arg0, %arg1
1851: ldil L%spllower_fmt, %arg0
1852: b,l panic, %rp
1853: ldo R%spllower_fmt(%arg0), %arg0
1854: bv %r0(%rp)
1855: ldi IPL_HIGH, %ret0
1856: spllower_fmt
1857: .asciz "spllower(%d)"
1858: .align 8
1859: spllower_ok
1860: #endif
1861: sync
1862: mfctl %eiem, %arg2
1863: mtctl %r0, %eiem
1864: ldil L%cpl, %r1
1865: ldw R%cpl(%r1), %ret0
1866: ldil L%imask, %arg3
1867: ldo R%imask(%arg3), %arg3
1868: sub,>= %arg0, %ret0, %r0
1869: ldd,s %arg0(%arg3), %arg2
1870: sub,>= %arg0, %ret0, %r0
1871: stw %arg0, R%cpl(%r1)
1872: sync
1873: bv %r0(%rp)
1874: mtctl %arg2, %eiem
1875: EXIT(spllower)
1876:
1877: .end
CVSweb