/* $OpenBSD: locore.S,v 1.6 2007/05/26 00:36:03 krw Exp $ */ /* * Copyright (c) 2005 Michael Shalayeff * All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ .level 2.0w #include #include #include #include #include #include #include #include #include #include #include "assym.h" .import __gp, data .import pdc, data .import boothowto, data .import bootdev, data .import esym, data .import want_resched, data .import proc0, data .import proc0paddr, data #define EMRG_STACKSIZE (1*PAGE_SIZE) #define FPEMU_STACKSIZE (1*PAGE_SIZE) .data .export netisr, data .align 16 netisr .word 0 .align 16 $kpsl .word PSL_W | PSL_Q | PSL_P | PSL_C | PSL_D | PSL_S | PSL_O .export cpl, data cpl .word IPL_HIGH BSS(pdc_stack, 8) /* temp stack for PDC call */ BSS(emrg_stack, 8) /* stack for HPMC/TOC/PWRF */ BSS(fpemu_stack, 8) /* stack for FPU emulation */ .export fpu_enable, data BSS(fpu_enable, 4) /* bits to set in the %cr10 to enable fpu */ .export fpu_curpcb, data BSS(fpu_curpcb, 8) /* pcb of the fpu owner */ BSS(fpu_scratch, 16) /* FPU scratch space, enough for a quad */ .text /* * $start(pdc, boothowto, bootdev, esym) */ .export $start, entry $start rsm (PSL_R|PSL_Q|PSL_I|PSL_P|PSL_D), %r0 nop ! nop ! nop ! nop ldil L%__gp, %dp ldo R%__gp(%dp), %dp ldi HPPA_PID_KERNEL, %r1 mtctl %r1, %pidr1 mtctl %r1, %pidr2 mtctl %r0, %pidr3 mtctl %r0, %pidr4 mtsp %r0, %sr0 mtsp %r0, %sr1 mtsp %r0, %sr2 mtsp %r0, %sr3 mtsp %r0, %sr4 mtsp %r0, %sr5 mtsp %r0, %sr6 mtsp %r0, %sr7 ldi -1, %r1 mtctl %r0, %eiem mtctl %r1, %eirr mtctl %r0, %cr10 /* ccr */ ldil L%pdc, %r1 std %arg0, R%pdc(%r1) ldil L%boothowto, %r1 stw %arg1, R%boothowto(%r1) ldil L%bootdev, %r1 stw %arg2, R%bootdev(%r1) ldil L%esym, %r1 std %arg3, R%esym(%r1) /* align esym */ ldo PAGE_MASK(%arg3), %arg3 depw %r0, 31, PAGE_SHIFT, %arg3 .import __kernel_pagedir, data ldil L%__kernel_pagedir, %r1 ldo R%__kernel_pagedir(%r1), %r1 mtctl %r1, %cr25 /* vtop */ /* setup kernel initial PIEs */ ldo PAGE_SIZE(%r1), %r31 extrd,u %r31, 51, 32, %arg0 ldo 1(%arg0), %arg1 ldo 2(%arg0), %arg2 stw %arg0, 0(%r1) stw %arg1, 4(%r1) /* (VM_MIN_KERNEL_ADDRESS & PIE_MASK) >> PIE_SHIFT */ ldo 1(%arg2), %arg0 stw %arg2, 0x20*4(%r1) stw %arg0, 0xffc(%r1) .import kernel_ptes, data ldil L%kernel_ptes, %r1 ldo R%kernel_ptes(%r1), %r1 ldd,ma 8(%r1), %r8 ldd,ma 8(%r1), %r9 ldd,ma 8(%r1), %r10 ldd,ma 8(%r1), %r11 /* fill eight pages at the same time */ copy %arg3, %arg0 ldo PAGE_SIZE(%arg0), %arg1 extrd,u %arg0, 51, 32, %r1 stw,ma %r1, 4(%r31) ldo PAGE_SIZE(%arg1), %arg2 extrd,u %arg1, 51, 32, %r1 stw,ma %r1, 4(%r31) ldo PAGE_SIZE(%arg2), %arg3 extrd,u %arg2, 51, 32, %r1 stw,ma %r1, 4(%r31) ldo PAGE_SIZE(%arg3), arg4 extrd,u %arg3, 51, 32, %r1 stw,ma %r1, 4(%r31) ldo PAGE_SIZE(arg4), arg5 extrd,u arg4, 51, 32, %r1 stw,ma %r1, 4(%r31) ldo PAGE_SIZE(arg5), arg6 extrd,u arg5, 51, 32, %r1 stw,ma %r1, 4(%r31) ldo PAGE_SIZE(arg6), arg7 extrd,u arg6, 51, 32, %r1 stw,ma %r1, 4(%r31) extrd,u arg7, 51, 32, %r1 stw,ma %r1, 4(%r31) ldi PAGE_SIZE, %r1 $start_set_ptes std,ma,bc %r8, 8(%arg0) std,ma,bc %r8, 8(%arg1) std,ma,bc %r9, 8(%arg2) std,ma,bc %r9, 8(%arg3) std,ma,bc %r10, 8(arg4) std,ma,bc %r10, 8(arg5) std,ma,bc %r11, 8(arg6) addib,>= -8, %r1, $start_set_ptes std,ma,bc %r11, 8(arg7) ldo -8(arg7), %arg3 /* assuming size being page-aligned */ #define STACK_ALLOC(n,s) \ ldil L%n, %r1 ! \ ldil L%s, %r31 ! \ std %arg3, R%n(%r1) ! \ add %arg3, %r31, %arg3 STACK_ALLOC(pdc_stack, PDC_STACKSIZE) STACK_ALLOC(emrg_stack, EMRG_STACKSIZE) STACK_ALLOC(fpemu_stack, FPEMU_STACKSIZE) copy %arg3, %arg0 ldi PAGE_SIZE+TRAPFRAME_SIZEOF, %r1 $start_zero_tf std,ma,bc %r0, 8(%arg0) addib,>= -16, %r1, $start_zero_tf std,ma,bc %r0, 8(%arg0) /* setup proc0/user0 */ ldil L%(USPACE+PAGE_SIZE), %arg0 add %arg0, %arg3, %arg0 ldil L%proc0paddr, %r1 std %arg3, R%proc0paddr(%r1) ldo PAGE_SIZE(%arg3), %sp mtctl %arg3, %cr30 std %r0, U_PCB+PCB_ONFAULT(%arg3) std %r0, U_PCB+PCB_SPACE(%arg3) std %arg3, U_PCB+PCB_UVA(%arg3) ldil L%proc0, %r1 ldo R%proc0(%r1), %r1 ldo -TRAPFRAME_SIZEOF(%sp), %arg2 std %arg3, P_ADDR(%r1) std %arg2, P_MD_REGS(%r1) ldil TFF_LAST, %r1 std %r1, TF_FLAGS(%arg2) std %arg3, TF_CR30(%arg2) ldil L%$kpsl, %r1 ldw R%$kpsl(%r1), arg7 ldil L%$start_virt, %r31 ldo R%$start_virt(%r31), %r31 ldil L%$ivaaddr, %r1 ldo R%$ivaaddr(%r1), %r1 mtctl %r1, %iva mtctl %r0, %pcsq mtctl %r0, %pcsq mtctl %r31, %pcoq ldo 4(%r31), %r31 mtctl %r31, %pcoq mtctl arg7, %ipsw rfi nop $start_virt copy %arg0, %r5 copy %sp, %r3 std,ma %r0, HPPA_FRAME_SIZE(%sp) .call b,l hppa_init, %rp ldo -16(%sp), ap $start_callmain .import main, code .call b,l main, %rp ldo -TRAPFRAME_SIZEOF(%arg0), %r5 .size $start, .-$start /* int * pdc_call(func, pdc_flag, ...) * iodcio_t func; * int pdc_flag; */ ENTRY(pdc_call,160) std %rp, HPPA_FRAME_RP(%sp) std %sp, HPPA_FRAME_PSP(%sp) copy %r3, %r31 copy %sp, %ret0 ldil L%pdc_stack, %r1 ldd R%pdc_stack(%r1), %r3 copy %r3, %sp std,ma %r31, 32+12*4+12*8(%sp) /* old frame+args+save(64) */ mfctl %eiem, %r1 mtctl %r0, %eiem std %r1, 1*8(%r3) copy %arg0, %r31 /* copy arguments */ copy %arg2, %arg0 copy %arg3, %arg1 copy arg4, %arg2 copy arg5, %arg3 ldd 0*8(ap), arg4 ldd 1*8(ap), arg5 stw arg6, -32-(4+1)*4(%sp) stw arg7, -32-(5+1)*4(%sp) stw arg4, -32-(6+1)*4(%sp) stw arg5, -32-(7+1)*4(%sp) ldd 2*8(ap), arg4 ldd 3*8(ap), arg5 ldd 4*8(ap), arg6 ldd 5*8(ap), arg7 stw arg4, -32-(8+1)*4(%sp) stw arg5, -32-(9+1)*4(%sp) stw arg6, -32-(10+1)*4(%sp) stw arg7, -32-(11+1)*4(%sp) mfctl %cr24, arg4 mfctl %cr25, arg5 mfctl %cr26, arg6 mfctl %cr27, arg7 std arg4, 2*8(%r3) std arg5, 3*8(%r3) std arg6, 4*8(%r3) std arg7, 5*8(%r3) mfctl %cr28, arg4 mfctl %cr29, arg5 mfctl %cr30, arg6 mfctl %cr31, arg7 std arg4, 6*8(%r3) std arg5, 7*8(%r3) std arg6, 8*8(%r3) std arg7, 9*8(%r3) copy %arg0, %ret1 std %ret0, 11*8(%r3) /* old %sp */ ldi PSL_Q, %arg0 break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW copy %ret1, %arg0 .call blr %r0, %rp bv,n (%r31) nop /* load temp control regs */ ldd 2*8(%r3), arg4 ldd 3*8(%r3), arg5 ldd 4*8(%r3), arg6 ldd 5*8(%r3), arg7 mtctl arg4, %cr24 mtctl arg5, %cr25 mtctl arg6, %cr26 mtctl arg7, %cr27 ldd 6*8(%r3), arg4 ldd 7*8(%r3), arg5 ldd 8*8(%r3), arg6 ldd 9*8(%r3), arg7 mtctl arg4, %cr28 mtctl arg5, %cr29 mtctl arg6, %cr30 mtctl arg7, %cr31 ldil L%$kpsl, %r1 ldw R%$kpsl(%r1), %arg0 copy %ret0, %arg1 break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW copy %arg1, %ret0 ldd 1*8(%r3), arg5 /* %eiem */ ldd 11*8(%r3), %sp ldd HPPA_FRAME_RP(%sp), %rp ldd 0(%r3), %r3 bv %r0(%rp) mtctl arg5, %eiem EXIT(pdc_call) /* * the whole syscall() glue is fit on one page * both enter and return paths */ /* TODO has to be mapped w/a special perms */ .align PAGE_SIZE .export gateway_page, entry gateway_page nop gate,n $bsd_syscall,%r0 nop .align 256 #ifdef COMPAT_LINUX gate,n $linux_syscall, %r0 /* TODO linux syscall fix */ nop $linux_syscall nop #endif $bsd_syscall mfctl %eiem, %r1 mtctl %r0, %eiem mtsp %r0, %sr1 mfctl %pidr1, %ret0 ldi HPPA_PID_KERNEL, %ret0 mtctl %ret0, %pidr1 /* TODO prepare for syscall() */ .import syscall,code b,l syscall, %rp nop mfctl %cr24, %arg1 ldd CI_CURPROC(%arg1), %r1 ldw P_MD_REGS(%r1), %arg0 $syscall_return /* %arg0 -- trapframe */ mtctl %r0, %eiem ldo 8(%arg0), %r31 /* flags */ rfi nop .size $bsd_syscall, .-$bsd_syscall .size $syscall_return, .-$syscall_return gateway_end . = gateway_page + PAGE_SIZE .size gateway_page, .-gateway_page /* * interrupt vector table */ #define TLABEL(name) $trap$name #define TRAP(name,num,pre) \ .export TLABEL(name)$num, entry ! \ .label TLABEL(name)$num ! \ pre ! \ .call ! \ .import TLABEL(name), code ! \ b TLABEL(name) ! \ ldi num, %r1 ! \ .align 32 #define ITLBPRE \ mfctl %pcsq, %r8 ! \ mfctl %pcoq, %r9 ! \ extrd,u %r8, 63, SID_SHIFT, %r1 ! \ depd %r1, 31, SID_SHIFT, %r9 ! \ depd %r0, 63, SID_SHIFT, %r8 #define DTLBPRE \ mfctl %isr, %r8 ! \ mfctl %ior, %r9 ! \ extrd,u %r8, 63, SID_SHIFT, %r1 ! \ depd %r1, 31, SID_SHIFT, %r9 ! \ depd %r0, 63, SID_SHIFT, %r8 #define HPMCPRE nop #define BRKPRE \ mfctl %pcoq, %r8 .align PAGE_SIZE /* already */ .export $ivaaddr, entry .export hpmc_v, entry $ivaaddr TRAP(all,T_NONEXIST,) /* 0. invalid interrupt vector */ hpmc_v TRAP(hpmc,T_HPMC,HPMCPRE) /* 1. high priority machine check */ TRAP(pfr,T_POWERFAIL,) /* 2. power failure */ TRAP(all,T_RECOVERY,) /* 3. recovery counter trap */ TRAP(all,T_INTERRUPT,) /* 4. external interrupt */ TRAP(all,T_LPMC,) /* 5. low-priority machine check */ TRAP(itlb,T_ITLBMISS,ITLBPRE) /* 6. instruction TLB miss fault */ TRAP(all,T_IPROT,) /* 7. instruction protection trap */ TRAP(all,T_ILLEGAL,) /* 8. Illegal instruction trap */ TRAP(ibrk,T_IBREAK,BRKPRE) /* 9. break instruction trap */ TRAP(all,T_PRIV_OP,) /* 10. privileged operation trap */ TRAP(all,T_PRIV_REG,) /* 11. privileged register trap */ TRAP(all,T_OVERFLOW,) /* 12. overflow trap */ TRAP(all,T_CONDITION,) /* 13. conditional trap */ TRAP(excpt,T_EXCEPTION,) /* 14. assist exception trap */ TRAP(dtlb,T_DTLBMISS,DTLBPRE) /* 15. data TLB miss fault */ TRAP(itlbna,T_ITLBMISSNA,DTLBPRE)/* 16. ITLB non-access miss fault */ TRAP(dtlbna,T_DTLBMISSNA,DTLBPRE)/* 17. DTLB non-access miss fault */ TRAP(all,T_DPROT,) /* 18. data protection trap unaligned data reference trap */ TRAP(all,T_DBREAK,) /* 19. data break trap */ TRAP(tlbd,T_TLB_DIRTY,DTLBPRE) /* 20. TLB dirty bit trap */ TRAP(all,T_PAGEREF,) /* 21. page reference trap */ TRAP(emu,T_EMULATION,) /* 22. assist emulation trap */ TRAP(all,T_HIGHERPL,) /* 23. higher-privelege transfer trap*/ TRAP(all,T_LOWERPL,) /* 24. lower-privilege transfer trap */ TRAP(all,T_TAKENBR,) /* 25. taken branch trap */ TRAP(all,T_DATACC,) /* 26. data access rights trap */ TRAP(all,T_DATAPID,) /* 27. data protection ID trap */ TRAP(all,T_DATALIGN,) /* 28. unaligned data ref trap */ TRAP(all,29,) TRAP(all,30,) TRAP(all,31,) TRAP(all,32,) TRAP(all,33,) TRAP(all,34,) TRAP(all,35,) TRAP(all,36,) TRAP(all,37,) TRAP(all,38,) TRAP(all,39,) TRAP(all,40,) TRAP(all,41,) TRAP(all,42,) TRAP(all,43,) TRAP(all,44,) TRAP(all,45,) TRAP(all,46,) TRAP(all,47,) TRAP(all,48,) TRAP(all,49,) TRAP(all,50,) TRAP(all,51,) TRAP(all,52,) TRAP(all,53,) TRAP(all,54,) TRAP(all,55,) TRAP(all,56,) TRAP(all,57,) TRAP(all,58,) TRAP(all,59,) TRAP(all,60,) TRAP(all,61,) TRAP(all,62,) TRAP(all,63,) /* 64 */ /* * High Priority Machine Check Interrupt */ .export TLABEL(hpmc), entry ENTRY(TLABEL(hpmc),0) rfi nop hpmc_never_dies b hpmc_never_dies nop EXIT(TLABEL(hpmc)) /* * transfer of control handler */ ENTRY(hppa_toc,0) rfi nop ALTENTRY(hppa_toc_end) .word 0 EXIT(hppa_toc) /* * power fail recovery handler */ ENTRY(TLABEL(pfr),0) rfi nop ALTENTRY(hppa_pfr_end) .word 0 EXIT(hppa_pfr) /* * system breaks */ .export TLABEL(ibrk), entry ENTRY(TLABEL(ibrk),0) /* If called by a user process then always pass it to trap() */ extrd,u,*= %r8, 63, 2, %r0 b,n TLABEL(all) /* don't accept breaks from data segments */ .import etext, code ldil L%etext, %r9 ldo R%etext(%r9), %r9 cmpb,*>>=,n %r8, %r9, TLABEL(all) mfctl %iir, %r8 extrd,u,*= %r8, 63, 5, %r0 b,n TLABEL(all) /* now process all those `break' calls we make */ extrd,u %r8, 50, 13, %r9 comib,=,n HPPA_BREAK_GET_PSW, %r9, $ibrk_getpsw comib,=,n HPPA_BREAK_SET_PSW, %r9, $ibrk_setpsw b TLABEL(all) nop $ibrk_getpsw b $ibrk_exit mfctl %ipsw, %ret0 $ibrk_setpsw mfctl %ipsw, %ret0 b $ibrk_exit mtctl %arg0, %ipsw /* insert other fast breaks here */ nop ! nop $ibrk_exit /* skip the break */ mtctl %r0, %pcoq mfctl %pcoq, %r9 mtctl %r9, %pcoq ldo 4(%r9), %r9 mtctl %r9, %pcoq rfi,r nop EXIT(TLABEL(ibrk)) .export TLABEL(all), entry ENTRY(TLABEL(all),0) /* %r1 still has trap type */ mfctl %ipsw, %r9 mtctl %r9, %cr31 mtsp %r0, %sr3 ldi HPPA_PID_KERNEL, %r9 mtctl %r9, %pidr3 mfctl %isr, %r8 mfctl %ior, %r9 extrd,u %r8, 63, SID_SHIFT, %r16 depd %r16, 31, SID_SHIFT, %r9 depd %r0, 63, SID_SHIFT, %r8 mtsp %r8, %sr6 mtctl %r9, %cr27 mfctl %pcsq, %r24 mtctl %r0, %pcsq mfctl %pcsq, %r25 mtctl %r0, %pcsq mtsp %r24, %sr4 mtsp %r25, %sr5 /* TODO fix pcsq:pcoq split */ ldil L%TLABEL(all_virt), %r9 ldo R%TLABEL(all_virt)(%r9), %r9 mfctl %pcoq, %r24 mtctl %r9, %pcoq mfctl %pcoq, %r25 ldo 4(%r9), %r9 mtctl %r24, %cr28 mtctl %r9, %pcoq mtctl %r25, %cr29 ldil L%$kpsl, %r9 ldw R%$kpsl(%r9), %r9 mtctl %r9, %ipsw mfctl %cr30, %r9 mfsp %sr0, %r8 extrd,u,*<> %r24, 63, 2, %r0 /* still pcoq head */ cmpb,*= %r0, %r8, TLABEL(all_kern) copy %sp, %r17 depdi 1, T_USER_POS, 1, %r1 depdi 1, TFF_LAST_POS, 1, %r1 ldd U_PCB+PCB_UVA(%r9), %sp ldo PAGE_SIZE-TRAPFRAME_SIZEOF(%sp), %sp TLABEL(all_kern) ldo 127(%sp), %sp depdi 0, 63, 7, %sp ldo TF_SP(%sp), %r8 std %r17, 0(%r8) fdc %r0(%r8) mfctl %iir, %r16 ldo TF_IIR(%sp), %r8 std %r16, 0(%r8) fdc %r0(%r8) mtctl %r1, %cr26 rfi,r nop ! nop ! nop ! nop ! nop ! nop ! nop ! nop TLABEL(all_virt) ldo 8(%sp), %sp /* space for flags */ std,ma %r1, 8(%sr3,%sp) mfctl %cr26, %r1 /* sar */ std %r1, -16(%sr3,%sp) std,ma %rp, 8(%sr3,%sp) std,ma %r3, 8(%sr3,%sp) std,ma %r4, 8(%sr3,%sp) std,ma %r5, 8(%sr3,%sp) std,ma %r6, 8(%sr3,%sp) std,ma %r7, 8(%sr3,%sp) std,ma %r8, 8(%sr3,%sp) std,ma %r9, 8(%sr3,%sp) std,ma %r10, 8(%sr3,%sp) std,ma %r11, 8(%sr3,%sp) std,ma %r12, 8(%sr3,%sp) std,ma %r13, 8(%sr3,%sp) std,ma %r14, 8(%sr3,%sp) std,ma %r15, 8(%sr3,%sp) std,ma %r16, 8(%sr3,%sp) std,ma %r17, 8(%sr3,%sp) std,ma %r18, 8(%sr3,%sp) std,ma %r19, 8(%sr3,%sp) std,ma %r20, 8(%sr3,%sp) std,ma %r21, 8(%sr3,%sp) std,ma %r22, 8(%sr3,%sp) std,ma %r23, 8(%sr3,%sp) std,ma %r24, 8(%sr3,%sp) std,ma %r25, 8(%sr3,%sp) std,ma %r26, 8(%sr3,%sp) std,ma %r27, 8(%sr3,%sp) std,ma %r28, 8(%sr3,%sp) std,ma %r29, 8(%sr3,%sp) ldo -30*8(%sp), %arg1 ldo 8(%sp), %sp /* %sp */ std,ma %r31, 8(%sr3,%sp) copy %r1, %arg0 mfsp %sr0, %arg2 mfsp %sr1, %arg3 std,ma %arg2, 8(%sr3,%sp) /* %sr0 */ std,ma %arg3, 8(%sr3,%sp) /* %sr1 */ std,ma %arg2, 8(%sr3,%sp) /* %sr2 */ std,ma %arg2, 8(%sr3,%sp) /* %sr3 */ std,ma %arg2, 8(%sr3,%sp) /* %sr4 */ std,ma %arg2, 8(%sr3,%sp) /* %sr5 */ std,ma %arg2, 8(%sr3,%sp) /* %sr6 */ std,ma %arg2, 8(%sr3,%sp) /* %sr7 */ mfctl %cr0, %arg3 mfctl %cr10, %arg2 std,ma %arg3, 8(%sr3,%sp) /* rctr */ std,ma %arg2, 8(%sr3,%sp) /* ccr */ mfctl %cr28, %arg2 /* pcoq */ mfctl %cr29, %arg3 std,ma %arg2, 8(%sr3,%sp) std,ma %arg3, 8(%sr3,%sp) mfsp %sr4, %arg2 /* pcsq */ mfsp %sr5, %arg3 std,ma %arg2, 8(%sr3,%sp) std,ma %arg3, 8(%sr3,%sp) mfctl %pidr1, %arg2 mfctl %pidr2, %arg3 std,ma %arg2, 8(%sr3,%sp) /* pidr1 */ std,ma %arg3, 8(%sr3,%sp) /* pidr2 */ mfctl %pidr3, %r1 mtctl %r1, %pidr1 mtctl %r0, %pidr3 mfctl %eiem, %arg2 mfctl %eirr, %arg3 std,ma %arg2, 8(%sr3,%sp) /* eiem */ std,ma %arg3, 8(%sr3,%sp) /* eirr */ mfctl %cr27, %arg2 mfsp %sr6, %arg3 std,ma %arg2, 8(%sr3,%sp) /* ior */ std,ma %arg3, 8(%sr3,%sp) /* isr */ ldo 8(%sp), %sp /* iir */ mfctl %cr31, %arg3 std,ma %arg3, 8(%sr3,%sp) /* ipsw */ mfctl %cr24, %arg2 mfctl %cr25, %arg3 std,ma %arg2, 8(%sr3,%sp) /* curcpuinfo */ std,ma %arg3, 8(%sr3,%sp) /* vtop */ mfctl %cr30, %arg2 mfctl %cr27, %arg3 /* XXX */ std,ma %arg2, 8(%sr3,%sp) /* pa(u) */ std,ma %arg3, 8(%sr3,%sp) /* user curthread */ mfctl %sar, %arg2 std,ma %arg2, 8(%sr3,%sp) /* sar */ mtsp %r0, %sr0 mtsp %r0, %sr1 mtsp %r0, %sr2 mtsp %r0, %sr3 mtsp %r0, %sr4 mtsp %r0, %sr5 mtsp %r0, %sr6 mtsp %r0, %sr7 ldo TRAPFRAME_SIZEOF(%arg1), %sp copy %sp, %r3 std,ma %r0, HPPA_FRAME_SIZE(%sp) ldil L%__gp, %dp ldo R%__gp(%dp), %dp copy %arg1, %r5 depd %r0, T_USER_POS+1, T_USER_POS, %arg0 .import trap, code b,l trap, %rp copy %arg0, %r4 /* non-terminal frames return to the same proc */ bb,*>=,n %r4, TFF_LAST_POS, $syscall_return copy %r5, %arg0 /* see if curproc have really changed */ mfctl %cr24, %arg1 ldd CI_CURPROC(%arg1), %r1 sub,*= %r0, %r1, %r0 ldd P_MD_REGS(%r1), %r5 b $syscall_return copy %r5, %arg0 EXIT(TLABEL(all)) #define PTPULL(bits,lbl) \ /* space:offset -- %r8:%r9 */ ! \ ldil L%__kernel_pagedir, %r24 ! \ or,*= %r8, %r8, %r0 ! \ mfctl %cr25, %r24 /* vtop */ ! \ ldo PAGE_SIZE(%r24), %r25 ! \ extrd,u %r25, 51, 32, %r25 ! \ extrd,u,*= %r9, 32, 10, %r17 ! \ ldw,s %r17(%r24), %r25 ! \ extrd,u %r9, 42, 10, %r17 ! \ depd,z,*<> %r25, 51, 32, %r25 ! \ b,n lbl ! \ ldw,s %r17(%r25), %r25 ! \ extrd,u %r9, 51, 9, %r24 ! \ depd,z,*<> %r25, 51, 32, %r25 ! \ b,n lbl ! \ ldd,s %r24(%r25), %r16 ! \ or,*<> %r16, %r0, %r17 ! \ b,n lbl ! \ depdi bits, 2+bits, 1+bits, %r17 ! \ shladd,l %r24, 3, %r25, %r25 ! \ sub,*= %r16, %r17, %r0 ! \ std %r17, 0(%r25) ! \ extrd,s %r16, 63, 37, %r16 ! \ depd %r8, 63, 48, %r17 ! \ depdi 1, 62, 1, %r17 TLABEL(itlb) PTPULL(0, TLABEL(all)) iitlbt %r16, %r17 rfi,r nop TLABEL(tlbd) PTPULL(1, TLABEL(all)) idtlbt %r16, %r17 rfi,r nop TLABEL(itlbna) TLABEL(dtlbna) PTPULL(0, TLABEL(dtlbna_fake)) idtlbt %r16, %r17 rfi,r nop TLABEL(dtlbna_fake) /* parse probei?,[rw] insns, decent to trap() to set regs proper */ mfctl %iir, %r16 extrd,u %r16, 38, 6, %r24 comib,=,n 1, %r24, TLABEL(all) extrd,u %r16, 56, 6, %r24 subi,<> 0x23, %r24, %r0 b TLABEL(all) subi,<> 0x63, %r24, %r0 b TLABEL(all) /* otherwise generate a flush-only tlb entry */ depd,z %r8, 62, 47, %r17 depdi -13, 11, 7, %r17 ldo 2(%r17), %r17 /* 3? */ idtlbt %r0, %r17 rfi,r nop TLABEL(dtlb) PTPULL(0, TLABEL(all)) idtlbt %r16, %r17 rfi,r nop .export TLABEL(excpt), entry ENTRY(TLABEL(excpt),0) /* assume we never get this one w/o fpu [enabled] */ copy %rp, %r1 copy %arg0, %r8 mfctl %cr30, %r9 #if (PCB_FPREGS+U_PCB) != 0 ldo PCB_FPREGS+U_PCB(%r9), %r9 #endif .import fpu_save, code .call b,l fpu_save, %rp copy %r9, %arg0 copy %r1, %rp copy %r8, %arg0 mtctl %r0, %cr10 /* reset ccr: cause a reload after exception */ ldil L%fpu_curpcb, %r1 std %r0, R%fpu_curpcb(%r1) /* now, check for trap */ ldw 0(%r9), %r1 bb,>=,n %r1, HPPA_FPU_T_POS, excpt_notrap ldw 1*4(%r9), %r1 comb,<>,n %r0, %r1, excpt_emulate ldw 2*4(%r9), %r1 comb,<>,n %r0, %r1, excpt_emulate ldw 3*4(%r9), %r1 comb,<>,n %r0, %r1, excpt_emulate ldw 4*4(%r9), %r1 comb,<>,n %r0, %r1, excpt_emulate ldw 5*4(%r9), %r1 comb,<>,n %r0, %r1, excpt_emulate ldw 6*4(%r9), %r1 comb,<>,n %r0, %r1, excpt_emulate ldw 7*4(%r9), %r1 excpt_emulate bb,*>=,n %r1, 37, excpt_notrap /* HPPA_FPU_UNMPL not set */ #if TODO_emulate ldw 0(%r9), %r16 depi 0, HPPA_FPU_T_POS, 1, %r16 .import $fpu_emulate, code b $fpu_emulate stw %r16, 0(%r9) #endif excpt_notrap sync b TLABEL(all) ldi T_EXCEPTION, %r1 EXIT(TLABEL(excpt)) .export TLABEL(emu), entry ENTRY(TLABEL(emu),0) /* * Switch FPU/SFU context * * %isr:%ior - data address * %iir - instruction to emulate * iisq:iioq - address of instruction to emulate * * note: ISR and IOR contain valid data only if the * instruction is a coprocessor load or store. * */ mfctl %iir, %r8 extrd,u %r8, 37, 6, %r9 /* no sfu implementation right now */ comib,= 4, %r9, TLABEL(all) ldi T_ILLEGAL, %r1 /* * pass through for all coprocessors now and * do not check the uid here. * in case that piece does not exist emulate * or the trap will be generted later. */ /* if we are already enabled and hit again, emulate */ mfctl %cr10, %r1 /* ccr */ extru,<> %r1, 25, 2, %r0 b,n $fpusw_set nop $fpusw_emu mtctl %r0, %cr10 /* reset ccr: cause a reload after exception */ std %r0, R%fpu_curpcb(%r1) #if TODO_emulate /* here we emulate the fld/fst */ mfctl %iir, %r1 extrd,u %r1, 37, 6, %r1 comib,= 0xb, %r9, TLABEL(all) ldi T_ILLEGAL, %r1 mfctl %iir, %r1 extrd,u %r1, 37, 6, %r1 comib,= 0x9, %r9, TLABEL(all) ldi T_ILLEGAL, %r1 mfctl %iir, %r1 .import $fpu_emulate, code b $fpu_emulate nop #else b TLABEL(all) ldi T_ILLEGAL, %r1 #endif $fpusw_set /* enable coprocessor */ depdi 3, 37, 2, %r1 mtctl %r1, %cr10 /* ccr */ ldil L%fpu_curpcb, %r16 mfctl %cr30, %r9 ldd R%fpu_curpcb(%r16), %r16 comb,=,n %r16, %r0, $fpusw_nosave comb,=,n %r16, %r9, $fpusw_done copy %arg0, %r17 copy %rp, %r1 #if (PCB_FPREGS+U_PCB) != 0 ldo PCB_FPREGS+U_PCB(%r16), %r16 #endif .import fpu_save, code .call b,l fpu_save, %rp copy %r16, %arg0 copy %r1, %rp copy %r17, %arg0 $fpusw_nosave /* count switches */ .import umvexp, data ldil L%(uvmexp+FPSWTCH), %r1 ldw R%(uvmexp+FPSWTCH)(%r1), %r16 ldo 31*8+PCB_FPREGS+U_PCB(%r9), %r17 ldo 1(%r16), %r16 stw %r16, R%(uvmexp+FPSWTCH)(%r1) fldds,ma -8(%r17), %fr31 fldds,ma -8(%r17), %fr30 fldds,ma -8(%r17), %fr29 fldds,ma -8(%r17), %fr28 fldds,ma -8(%r17), %fr27 fldds,ma -8(%r17), %fr26 fldds,ma -8(%r17), %fr25 fldds,ma -8(%r17), %fr24 fldds,ma -8(%r17), %fr23 fldds,ma -8(%r17), %fr22 fldds,ma -8(%r17), %fr21 fldds,ma -8(%r17), %fr20 fldds,ma -8(%r17), %fr19 fldds,ma -8(%r17), %fr18 fldds,ma -8(%r17), %fr17 fldds,ma -8(%r17), %fr16 fldds,ma -8(%r17), %fr15 fldds,ma -8(%r17), %fr14 fldds,ma -8(%r17), %fr13 fldds,ma -8(%r17), %fr12 fldds,ma -8(%r17), %fr11 fldds,ma -8(%r17), %fr10 fldds,ma -8(%r17), %fr9 fldds,ma -8(%r17), %fr8 fldds,ma -8(%r17), %fr7 fldds,ma -8(%r17), %fr6 fldds,ma -8(%r17), %fr5 fldds,ma -8(%r17), %fr4 fldds,ma -8(%r17), %fr3 fldds,ma -8(%r17), %fr2 fldds,ma -8(%r17), %fr1 fldds 0(%r17), %fr0 /* fr0 must be restored last */ ldil L%fpu_curpcb, %r1 std %r17, R%fpu_curpcb(%r1) $fpusw_done rfir nop EXIT(TLABEL(emu)) LEAF_ENTRY(fpu_exit) /* enable coprocessor XXX */ depi 3, 25, 2, %r1 mtctl %r1, %cr10 ldil L%fpu_scratch, %r25 ldo R%fpu_scratch(%r25), %r25 fstds %fr0, 0(%r25) sync bv %r0(%rp) mtctl %r0, %cr10 EXIT(fpu_exit) LEAF_ENTRY(fpu_save) fstds,ma %fr0 , 8(%arg0) fstds,ma %fr1 , 8(%arg0) fstds,ma %fr2 , 8(%arg0) fstds,ma %fr3 , 8(%arg0) fstds,ma %fr4 , 8(%arg0) fstds,ma %fr5 , 8(%arg0) fstds,ma %fr6 , 8(%arg0) fstds,ma %fr7 , 8(%arg0) fstds,ma %fr8 , 8(%arg0) fstds,ma %fr9 , 8(%arg0) fstds,ma %fr10, 8(%arg0) fstds,ma %fr11, 8(%arg0) fstds,ma %fr12, 8(%arg0) fstds,ma %fr13, 8(%arg0) fstds,ma %fr14, 8(%arg0) fstds,ma %fr15, 8(%arg0) fstds,ma %fr16, 8(%arg0) fstds,ma %fr17, 8(%arg0) fstds,ma %fr18, 8(%arg0) fstds,ma %fr19, 8(%arg0) fstds,ma %fr20, 8(%arg0) fstds,ma %fr21, 8(%arg0) fstds,ma %fr22, 8(%arg0) fstds,ma %fr23, 8(%arg0) fstds,ma %fr24, 8(%arg0) fstds,ma %fr25, 8(%arg0) fstds,ma %fr26, 8(%arg0) fstds,ma %fr27, 8(%arg0) fstds,ma %fr28, 8(%arg0) fstds,ma %fr29, 8(%arg0) fstds,ma %fr30, 8(%arg0) fstds %fr31, 0(%arg0) ldo -24(%arg0), %arg0 ldi -32, %r25 /* gotta be free for all callers */ fdc,m %r25(%arg0) fdc,m %r25(%arg0) fdc,m %r25(%arg0) fdc,m %r25(%arg0) fdc,m %r25(%arg0) fdc,m %r25(%arg0) fdc,m %r25(%arg0) fdc,m %r25(%arg0) bv %r0(%rp) sync EXIT(fpu_save) /* * void * mtctl(register_t val, int reg) */ LEAF_ENTRY(mtctl) b,l mtctl_end, %r1 extrd,u %arg1, 63, 32, %arg1 bv %r0(%rp) mtctl %arg0, %cr0 bv %r0(%rp) nop /* mtctl %arg0, %cr1 */ bv %r0(%rp) nop /* mtctl %arg0, %cr2 */ bv %r0(%rp) nop /* mtctl %arg0, %cr3 */ bv %r0(%rp) nop /* mtctl %arg0, %cr4 */ bv %r0(%rp) nop /* mtctl %arg0, %cr5 */ bv %r0(%rp) nop /* mtctl %arg0, %cr6 */ bv %r0(%rp) nop /* mtctl %arg0, %cr7 */ bv %r0(%rp) mtctl %arg0, %cr8 bv %r0(%rp) mtctl %arg0, %cr9 bv %r0(%rp) mtctl %arg0, %cr10 bv %r0(%rp) mtctl %arg0, %cr11 bv %r0(%rp) mtctl %arg0, %cr12 bv %r0(%rp) mtctl %arg0, %cr13 bv %r0(%rp) mtctl %arg0, %cr14 bv %r0(%rp) mtctl %arg0, %cr15 bv %r0(%rp) mtctl %arg0, %cr16 bv %r0(%rp) mtctl %arg0, %cr17 bv %r0(%rp) mtctl %arg0, %cr18 bv %r0(%rp) mtctl %arg0, %cr19 bv %r0(%rp) mtctl %arg0, %cr20 bv %r0(%rp) mtctl %arg0, %cr21 bv %r0(%rp) mtctl %arg0, %cr22 bv %r0(%rp) mtctl %arg0, %cr23 bv %r0(%rp) mtctl %arg0, %cr24 bv %r0(%rp) mtctl %arg0, %cr25 bv %r0(%rp) mtctl %arg0, %cr26 bv %r0(%rp) mtctl %arg0, %cr27 bv %r0(%rp) mtctl %arg0, %cr28 bv %r0(%rp) mtctl %arg0, %cr29 bv %r0(%rp) mtctl %arg0, %cr30 bv %r0(%rp) mtctl %arg0, %cr31 mtctl_end subi,<< 31, %arg1, %r0 bv,n %arg1(%r1) bv %r0(%rp) nop EXIT(mtctl) /* * void * pdtlb(pa_space_t sp, vaddr_t va) */ LEAF_ENTRY(pdtlb) mfsp %sr1, %arg2 mtsp %arg0, %sr1 pdtlb %r0(%sr1, %arg1) bv %r0(%rp) mtsp %arg2, %sr1 EXIT(pdtlb) /* * void * pitlb(pa_space_t sp, vaddr_t va) */ LEAF_ENTRY(pitlb) mfsp %sr1, %arg2 mtsp %arg0, %sr1 pitlb %r0(%sr1, %arg1) bv %r0(%rp) mtsp %arg2, %sr1 EXIT(pitlb) /* * register_t * mfctl(int reg) */ LEAF_ENTRY(mfctl) b,l mfctl_end, %r1 extrd,u %arg0, 63, 32, %arg0 bv %r0(%rp) mfctl %cr0, %ret0 bv %r0(%rp) nop /* mfctl %cr1, %ret0 */ bv %r0(%rp) nop /* mfctl %cr2, %ret0 */ bv %r0(%rp) nop /* mfctl %cr3, %ret0 */ bv %r0(%rp) nop /* mfctl %cr4, %ret0 */ bv %r0(%rp) nop /* mfctl %cr5, %ret0 */ bv %r0(%rp) nop /* mfctl %cr6, %ret0 */ bv %r0(%rp) nop /* mfctl %cr7, %ret0 */ bv %r0(%rp) mfctl %cr8, %ret0 bv %r0(%rp) mfctl %cr9, %ret0 bv %r0(%rp) mfctl %cr10, %ret0 bv %r0(%rp) mfctl %cr11, %ret0 bv %r0(%rp) mfctl %cr12, %ret0 bv %r0(%rp) mfctl %cr13, %ret0 bv %r0(%rp) mfctl %cr14, %ret0 bv %r0(%rp) mfctl %cr15, %ret0 bv %r0(%rp) mfctl %cr16, %ret0 bv %r0(%rp) mfctl %cr17, %ret0 bv %r0(%rp) mfctl %cr18, %ret0 bv %r0(%rp) mfctl %cr19, %ret0 bv %r0(%rp) mfctl %cr20, %ret0 bv %r0(%rp) mfctl %cr21, %ret0 bv %r0(%rp) mfctl %cr22, %ret0 bv %r0(%rp) mfctl %cr23, %ret0 bv %r0(%rp) mfctl %cr24, %ret0 bv %r0(%rp) mfctl %cr25, %ret0 bv %r0(%rp) mfctl %cr26, %ret0 bv %r0(%rp) mfctl %cr27, %ret0 bv %r0(%rp) mfctl %cr28, %ret0 bv %r0(%rp) mfctl %cr29, %ret0 bv %r30(%rp) mfctl %cr30, %ret0 bv %r30(%rp) mfctl %cr31, %ret0 mfctl_end subi,<< 31, %arg0, %r0 bv,n %arg0(%r1) bv %r0(%rp) nop EXIT(mfctl) #define CACHELOOP(sp,addr,len,step,insn) \ mtsp sp, %sr1 ! \ ldi -1, arg7 ! \ sh3add step, arg7, %r1 ! \ andcm len, %r1, %r1 ! \ add addr, %r1, %r1 ! \ b __CONCAT(insn,_loop) ! \ add addr, len, len ! \ .label __CONCAT(insn,_loop8) ! \ insn,m step(%sr1, addr) ! \ insn,m step(%sr1, addr) ! \ insn,m step(%sr1, addr) ! \ insn,m step(%sr1, addr) ! \ insn,m step(%sr1, addr) ! \ insn,m step(%sr1, addr) ! \ insn,m step(%sr1, addr) ! \ .label __CONCAT(insn,_loop) ! \ comb,<< addr, %r1, __CONCAT(insn,_loop8) ! \ insn,m step(%sr1, addr) ! \ .label __CONCAT(insn,_loop1) ! \ comb,<<,n addr, len, __CONCAT(insn,_loop1) ! \ insn,m step(%sr1, addr) LEAF_ENTRY(fdcache) ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %arg3 CACHELOOP(%arg0,%arg1,%arg2,%arg3,fdc) bv %r0(%rp) sync EXIT(fdcache) LEAF_ENTRY(pdcache) ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %arg3 CACHELOOP(%arg0,%arg1,%arg2,%arg3,pdc) bv %r0(%rp) sync EXIT(pdcache) LEAF_ENTRY(ficache) ldil L%icache_stride, %r1 ldw R%icache_stride(%r1), %arg3 CACHELOOP(%arg0,%arg1,%arg2,%arg3,fic) bv %r0(%rp) sync EXIT(ficache) LEAF_ENTRY(copy_on_fault) mtsp %r0, %sr1 mtsp %r0, %sr2 std %r1, PCB_ONFAULT+U_PCB(%rp) ldd HPPA_FRAME_RP(%sp), %rp ldo -HPPA_FRAME_SIZE(%sp), %sp bv %r0(%rp) ldi EFAULT, %ret0 EXIT(copy_on_fault) LEAF_ENTRY(sync_caches) sync syncdma sync nop nop nop nop nop nop bv %r0(%rp) nop EXIT(sync_caches) /* * int spstrcpy (pa_space_t ssp, const void *src, pa_space_t dsp, void *dst, * size_t size, size_t *rsize) * do a space to space strncpy, return actual copy size in the rsize; */ LEAF_ENTRY(spstrcpy) stw %rp, HPPA_FRAME_RP(%sp) ldo HPPA_FRAME_SIZE(%sp), %sp add arg4, %arg1, arg4 /* setup fault handler */ mfctl %cr24, %arg1 ldd CI_CURPROC(%arg1), %r1 ldil L%copy_on_fault, arg7 ldd P_ADDR(arg6), %rp ldo R%copy_on_fault(arg7), arg7 ldd PCB_ONFAULT+U_PCB(%rp), %r1 std arg7, PCB_ONFAULT+U_PCB(%rp) mtsp %arg0, %sr1 mtsp %arg2, %sr2 copy %arg1, %arg0 $spstrcpy_loop ldbs,ma 1(%sr1, %arg1), arg7 comb,= arg4, %arg1, $spstrcpy_exit stbs,ma arg7, 1(%sr2, %arg3) comb,<>,n %r0, arg7, $spstrcpy_loop nop $spstrcpy_exit ldo -HPPA_FRAME_SIZE(%sp), %sp mtsp %r0, %sr1 mtsp %r0, %sr2 std %r1, PCB_ONFAULT+U_PCB(%rp) sub %arg1, %arg0, %arg1 ldd HPPA_FRAME_RP(%sp), %rp sub,= %r0, arg5, %r0 stw %arg1, 0(arg5) bv 0(%rp) copy %r0, %ret0 EXIT(spstrcpy) LEAF_ENTRY(setjmp) std,ma %rp, 8(%arg0) std,ma %sp, 8(%arg0) std,ma %r3, 8(%arg0) std,ma %r4, 8(%arg0) std,ma %r5, 8(%arg0) std,ma %r6, 8(%arg0) std,ma %r7, 8(%arg0) std,ma %r8, 8(%arg0) std,ma %r9, 8(%arg0) std,ma %r10, 8(%arg0) std,ma %r11, 8(%arg0) std,ma %r12, 8(%arg0) std,ma %r13, 8(%arg0) std,ma %r14, 8(%arg0) std,ma %r15, 8(%arg0) std,ma %r16, 8(%arg0) std,ma %r17, 8(%arg0) std,ma %r18, 8(%arg0) std,ma %r19, 8(%arg0) std,ma %r27, 8(%arg0) bv %r0(%rp) copy %r0, %ret0 EXIT(setjmp) LEAF_ENTRY(longjmp) ldd,ma 8(%arg0), %rp ldd,ma 8(%arg0), %sp ldd,ma 8(%arg0), %r3 ldd,ma 8(%arg0), %r4 ldd,ma 8(%arg0), %r5 ldd,ma 8(%arg0), %r6 ldd,ma 8(%arg0), %r7 ldd,ma 8(%arg0), %r8 ldd,ma 8(%arg0), %r9 ldd,ma 8(%arg0), %r10 ldd,ma 8(%arg0), %r11 ldd,ma 8(%arg0), %r12 ldd,ma 8(%arg0), %r13 ldd,ma 8(%arg0), %r14 ldd,ma 8(%arg0), %r15 ldd,ma 8(%arg0), %r16 ldd,ma 8(%arg0), %r17 ldd,ma 8(%arg0), %r18 ldd,ma 8(%arg0), %r19 ldd,ma 8(%arg0), %r27 bv %r0(%rp) copy %arg1, %ret0 EXIT(longjmp) .import whichqs, data .import qs, data /* * setrunqueue(struct proc *p); * Insert a process on the appropriate queue. Should be called at splclock(). */ .align 32 ENTRY(setrunqueue,0) #ifdef DIAGNOSTIC ldd P_BACK(%arg0), %r1 comb,<>,n %r0, %r1, Lsetrunqueue_panic ldd P_WCHAN(%arg0), %r1 comb,<>,n %r0, %r1, Lsetrunqueue_panic ldb P_STAT(%arg0), %r1 comib,=,n SRUN, %r1, Lsetrunqueue_ok Lsetrunqueue_panic copy %arg0, %arg1 ldil L%Lsrqpstr, %arg0 .call b,l panic, %rp ldo R%Lsrqpstr(%arg0), %arg0 Lsrqpstr .asciz "setrunqueue(%p)" .align 8 Lsetrunqueue_ok #endif ldb P_PRIORITY(%arg0), %r1 ldil L%qs, arg7 shd %r0, %r1, 2, %r1 ldo R%qs(arg7), arg7 sh3add %r1, arg7, arg7 ldil L%whichqs, %arg3 ldd P_BACK(arg7), arg6 std arg7, P_FORW(%arg0) std %arg0, P_BACK(arg7) ldw R%whichqs(%arg3), arg5 std %arg0, P_FORW(arg6) mtctl %r1, %sar std arg6, P_BACK(%arg0) vdepi 1, 1, arg5 bv 0(%rp) stw arg5, R%whichqs(%arg3) EXIT(setrunqueue) /* * remrunqueue(struct proc *p); * Remove a process from its queue. Should be called at splclock(). */ .align 32 ENTRY(remrunqueue,0) ldb P_PRIORITY(%arg0), %r1 shd %r0, %r1, 2, %r1 ldil L%whichqs, arg5 mtsar %r1 ldw R%whichqs(arg5), arg6 #ifdef DIAGNOSTIC bvb,<,n arg6, remrunqueue_ok Lremrunqueue_panic copy %arg0, %arg1 ldil L%Lrrqpstr, %arg0 .call b,l panic, %rp ldo R%Lrrqpstr(%arg0), %arg0 Lrrqpstr .asciz "remrunqueue(%p), bit=%x" .align 8 remrunqueue_ok #endif ldd P_BACK(%arg0), arg7 std %r0, P_BACK(%arg0) ldd P_FORW(%arg0), %arg0 std %arg0, P_FORW(arg7) vdepi 0, 1, arg6 sub,*<> arg7, %arg0, %r0 stw arg6, R%whichqs(arg5) bv 0(%rp) std arg7, P_BACK(%arg0) EXIT(remrunqueue) /* * cpu_switch() * find the highest priority process and resume it. */ .align 32 ENTRY(cpu_switch,128) ldil L%cpl, %r1 ldw R%cpl(%r1), %ret0 copy %r3, %r1 std %rp, HPPA_FRAME_RP(%sp) copy %sp, %r3 stwm %r1, HPPA_FRAME_SIZE+20*8(%sp) ldo -(HPPA_FRAME_SIZE)(%sp), ap stw %ret0, 2*8(ap) /* cpl */ /* * Clear curproc so that we don't accumulate system time while idle. */ mfctl %cr24, %r1 ldd CI_CURPROC(%r1), %arg2 b switch_search std %r0, CI_CURPROC(%r1) /* remain on the old (curproc)'s stack until we have a better choice */ cpu_idle .call b,l spllower, %rp copy %r0, %arg0 .import uvm, data ldil L%uvm, %r1 ldo R%uvm(%r1), %r1 ldw PAGE_IDLE_ZERO(%r1), %r1 sub,<> %r0, %r1, %r0 b,n cpu_loop .call b,l uvm_pageidlezero, %rp std %arg2, 8(%r3) ldw 2*8(ap), %ret0 /* cpl */ ldd 8(%r3), %arg2 cpu_loop ldil L%cpl, %arg0 stw %ret0, R%cpl(%arg0) switch_search /* * t1: &whichqs * arg2: old curproc * */ ldil L%whichqs, %r1 ldw R%whichqs(%r1), %arg2 comb,=,n %r0, %arg2, cpu_idle copy %r0, %arg0 ldi 0, %arg3 getbit mtsar %arg3 bvb,>=,n %arg2, getbit ldo 1(%arg3), %arg3 ldil L%qs, %arg2 ldo R%qs(%arg2), %arg2 depd %arg3, 62, 63, %arg3 shladd,l %arg3, 3, %arg2, %arg2 ldd P_FORW(%arg2), %arg1 #ifdef DIAGNOSTIC comb,<> %arg2, %arg1, link_ok nop switch_error copy %arg3, %arg1 copy %arg2, %arg2 ldil L%Lcspstr, %arg0 .call b,l panic, %rp ldo R%Lcspstr(%arg0), %arg0 Lcspstr .asciz "cpu_switch: bit=%x, q/p=%p" .align 8 link_ok #endif ldil L%want_resched, %r1 stw %r0, R%want_resched(%r1) ldd P_FORW(%arg1), %arg0 std %arg0, P_FORW(%arg2) std %arg2, P_BACK(%arg0) std %r0, P_BACK(%arg1) ldil L%whichqs, %r1 vdepi 0, 1, %arg3 sub,<> %arg2, %arg0, %r0 stw %arg3, R%whichqs(%r1) /* don't need &whichqs (t1) starting here */ #ifdef DIAGNOSTIC ldd P_WCHAN(%arg1), %arg3 comb,<>,n %r0, %arg3, switch_error copy %arg1, %t2 ldb P_STAT(%arg1), %arg3 comib,<>,n SRUN, %arg3, switch_error copy %arg1, %arg2 /* * Either we must be switching to the same process, or * the new process' kernel stack must be reasonable. */ comb,=,n %arg1, %arg2, kstack_ok ldd P_ADDR(%arg1), %arg0 ldd U_PCB+PCB_KSP(%arg0), %arg3 ldo NBPG(%arg0), %arg0 comb,>>,n %arg0, %arg3, switch_error copy %arg1, %arg2 sub %arg3, %arg0, %arg3 ldil L%USPACE, %arg0 ldo R%USPACE(%arg0), %arg0 comb,<<=,n %arg0, %arg3, switch_error copy %arg1, %arg2 kstack_ok #endif ldi SONPROC, %r1 stb %r1, P_STAT(%arg1) /* Skip context switch if same process. */ comb,=,n %arg1, %arg2, switch_return /* If old process exited, don't bother. */ comb,=,n %r0, %arg2, switch_exited /* * 2. save old proc context * * arg2: old proc */ ldd P_ADDR(%arg2), %r1 /* save callee-save registers */ std %r4, 1*8(%r3) std %sp, U_PCB+PCB_KSP(%r1) std %r5, 2*8(%r3) std %r6, 3*8(%r3) std %r7, 4*8(%r3) std %r8, 5*8(%r3) std %r9, 6*8(%r3) std %r10, 7*8(%r3) std %r11, 8*8(%r3) std %r12, 9*8(%r3) std %r13, 10*8(%r3) std %r14, 11*8(%r3) std %r15, 12*8(%r3) std %r16, 13*8(%r3) std %r17, 14*8(%r3) std %r18, 15*8(%r3) fdc %r0(%r1) std %r0, 1*8(ap) /* say no trampoline */ sync /* don't need old curproc (arg2) starting from here */ switch_exited /* * 3. restore new proc context * * arg1: new proc */ ldd P_ADDR(%arg1), %arg3 ldd P_MD_REGS(%arg1), %r1 ldd U_PCB+PCB_KSP(%arg3), %sp mtctl %r0, %cr10 /* ccr */ ldd TF_CR30(%r1), %arg2 ldd TF_PIDR2(%r1), %arg3 mtctl %arg2, %cr30 mtctl %arg3, %pidr2 ldo -(HPPA_FRAME_SIZE+20*8)(%sp), %r3 ldo -(HPPA_FRAME_SIZE)(%sp), ap ldd 0*8(ap), %arg0 ldd 1*8(ap), %arg3 /* in case we're on trampoline */ sub,*= %r0, %arg3, %r0 b,n switch_gonnajump ldd 1*8(%r3), %r4 ldd 2*8(%r3), %r5 ldd 3*8(%r3), %r6 ldd 4*8(%r3), %r7 ldd 5*8(%r3), %r8 ldd 6*8(%r3), %r9 ldd 7*8(%r3), %r10 ldd 8*8(%r3), %r11 ldd 9*8(%r3), %r12 ldd 10*8(%r3), %r13 ldd 11*8(%r3), %r14 ldd 12*8(%r3), %r15 ldd 13*8(%r3), %r16 ldd 14*8(%r3), %r17 ldd 15*8(%r3), %r18 switch_gonnajump ldw 2*8(ap), %ret0 /* cpl */ ldil L%cpl, %r1 stw %ret0, R%cpl(%r1) sync switch_return mfctl %cr24, %r1 std %arg1, CI_CURPROC(%r1) ldd HPPA_FRAME_RP(%r3), %rp bv 0(%rp) ldd,mb -(HPPA_FRAME_SIZE+20*8)(%sp), %r3 EXIT(cpu_switch) .align 8 .export switch_tramp_p, code switch_tramp_p .dword switch_trampoline ENTRY(switch_trampoline,0) /* ldd 0x18(%arg3), %r19 but we know we are in kernel! */ ldd 0x10(%arg3), %arg3 .call ble 0(%sr0, %arg3) copy %r31, %rp mfctl %cr24, %arg1 ldd CI_CURPROC(%arg1), %r1 b $syscall_return ldd P_MD_REGS(%r1), %arg0 EXIT(switch_trampoline) /* * Signal "trampoline" code. Invoked from RTE setup by sendsig(). */ ENTRY(sigcode,0) ldd 0x18(%arg3), %r19 ldd 0x10(%arg3), %arg3 .call ble 0(%sr0, %arg3) copy %r31, %rp ldil L%SYSCALLGATE, %r1 copy %r4, %arg0 .call ble 4(%sr7, %r1) ldi SYS_sigreturn, %r1 ldil L%SYSCALLGATE, %r1 copy %ret0, %arg0 .call ble 4(%sr7, %r1) ldi SYS_exit, %r1 ALTENTRY(esigcode) EXIT(sigcode) /* * struct cpu_info *curcpu(void); */ LEAF_ENTRY(curcpu) bv %r0(%rp) mfctl %cr24, %ret0 EXIT(curcpu) /* * int splraise(int newcpl); */ LEAF_ENTRY(splraise) bv %r0(%rp) nop extrd,u %arg0, 63, 32, %arg0 #ifdef DEBUG cmpib,<=,n NIPL, %arg0, splraise_ok copy %arg0, %arg1 ldil L%splraise_fmt, %arg0 b,l panic, %rp ldo R%splraise_fmt(%arg0), %arg0 bv %r0(%rp) ldi IPL_HIGH, %ret0 splraise_fmt .asciz "splraise(%d)" .align 8 splraise_ok #endif sync mfctl %eiem, %arg2 mtctl %r0, %eiem ldil L%cpl, %r1 ldw R%cpl(%r1), %ret0 ldil L%imask, %arg3 ldo R%imask(%arg3), %arg3 sub,<= %arg0, %ret0, %r0 ldd,s %arg0(%arg3), %arg2 sub,<= %arg0, %ret0, %r0 stw %arg0, R%cpl(%r1) sync bv %r0(%rp) mtctl %arg2, %eiem EXIT(splraise) /* * int spllower(int newcpl); */ LEAF_ENTRY(spllower) bv %r0(%rp) nop extrd,u %arg0, 63, 32, %arg0 #ifdef DEBUG cmpib,<=,n NIPL, %arg0, spllower_ok copy %arg0, %arg1 ldil L%spllower_fmt, %arg0 b,l panic, %rp ldo R%spllower_fmt(%arg0), %arg0 bv %r0(%rp) ldi IPL_HIGH, %ret0 spllower_fmt .asciz "spllower(%d)" .align 8 spllower_ok #endif sync mfctl %eiem, %arg2 mtctl %r0, %eiem ldil L%cpl, %r1 ldw R%cpl(%r1), %ret0 ldil L%imask, %arg3 ldo R%imask(%arg3), %arg3 sub,>= %arg0, %ret0, %r0 ldd,s %arg0(%arg3), %arg2 sub,>= %arg0, %ret0, %r0 stw %arg0, R%cpl(%r1) sync bv %r0(%rp) mtctl %arg2, %eiem EXIT(spllower) .end