diff options
author | 1999-11-25 18:47:45 +0000 | |
---|---|---|
committer | 1999-11-25 18:47:45 +0000 | |
commit | 7adaa56ba47e2b1ebac90ed716e83ac592f09b4b (patch) | |
tree | 0c0afa54d7e48a3d7d6022ccbf7180f818c13d12 | |
parent | bus stuff is in mainbus now, the rest is rewritten many ways (diff) | |
download | wireguard-openbsd-7adaa56ba47e2b1ebac90ed716e83ac592f09b4b.tar.xz wireguard-openbsd-7adaa56ba47e2b1ebac90ed716e83ac592f09b4b.zip |
convey and convex it traps on both ways, and a little syscalls in between
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 1217 |
1 files changed, 720 insertions, 497 deletions
diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S index 529b96aadb3..0aa3b39e309 100644 --- a/sys/arch/hppa/hppa/locore.S +++ b/sys/arch/hppa/hppa/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.20 1999/09/20 21:40:53 mickey Exp $ */ +/* $OpenBSD: locore.S,v 1.21 1999/11/25 18:47:45 mickey Exp $ */ /* * Copyright (c) 1998,1999 Michael Shalayeff @@ -14,23 +14,24 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by Michael Shalayeff. + * This product includes software developed by Michael Shalayeff. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. * * Portitions of this file are derived from other sources, see - * the copyrights and acknowledgements. + * the copyrights and acknowledgements below. */ /* * Copyright (c) 1990,1991,1992,1994 The University of Utah and @@ -61,6 +62,7 @@ */ #include <sys/errno.h> +#include <machine/param.h> #include <machine/asm.h> #include <machine/psl.h> #include <machine/trap.h> @@ -86,29 +88,19 @@ .import curproc, data .import fpu_curproc, data .import want_resched, data + .import virtual_avail, data .import proc0, data .import proc0paddr, data - .import intr_recurse, data + .import kpsw, data .import panic, code .space $PRIVATE$ .subspa $BSS$ - .export proc0stack, data - .export proc0stack_end, data -proc0stack - .block 4*NBPG -proc0stack_end - - .export intr_stack, data - .export intr_stack_end, data - .export intr_stack_red, data -intr_stack - .block 5*NBPG -intr_stack_end - .block 2*NBPG -intr_stack_red - .block 1*NBPG - + .export pdc_stack, data +pdc_stack + .block 3*NBPG +kernelmapped /* set when kernel is mapped */ + .block 4 /* * This is the starting location for the kernel @@ -138,6 +130,10 @@ ENTRY($start) ldil L%esym,r1 stw arg3,R%esym(r1) + /* Align arg3, which is the start of available memory */ + ldo NBPG-1(arg3), arg3 + dep r0, 31, PGSHIFT, arg3 + /* * disable interrupts and turn off all bits in the psw so that * we start in a known state. @@ -157,31 +153,51 @@ ENTRY($start) ldil L%$global$,dp ldo R%$global$(dp),dp + /* zero fake trapframe and proc0 u-area */ + ldo NBPG+TF_SIZE(arg3), t1 + copy arg3, t2 +$start_zero_tf + stw r0, 0(t2) + stw r0, 4(t2) + comb,<,n t2, t1, $start_zero_tf + ldo 8(t2), t2 + /* - * kernel stack lives here (arg3 is esym) + * kernel stack lives here (arg3 is page-aligned esym) + * initialize the pcb * arg0 will be available space for hppa_init() */ - ldil L%proc0stack, t2 - ldo R%proc0stack(t2), sp + ldo NBPG(arg3), sp + mtctl arg3, cr30 + stw r0, u_pcb+pcb_onfault(arg3) + stw r0, u_pcb+pcb_space(arg3) /* XXX HPPA_SID_KERNEL == 0 */ + stw arg3, u_pcb+pcb_uva(arg3) + ldil L%USPACE, arg0 + add arg3, arg0, arg0 ldil L%proc0paddr, t1 - ldo NBPG(arg3), arg0 stw arg3, R%proc0paddr(t1) ldil L%proc0, t2 stw arg3, R%proc0+p_addr(t2) + /* create a fake trapframe */ + ldil L%TFF_LAST, t1 + stw t1, TF_FLAGS(sp) + /* accomodate the trapframe, once we created one */ + ldo TF_SIZE(sp), sp + /* * We need to set the Q bit so that we can take TLB misses after we * turn on virtual memory. */ - mtctl r0,pcsq - mtctl r0,pcsq - ldil L%$qisnowon,t1 - ldo R%$qisnowon(t1),t1 - mtctl t1,pcoq + mtctl r0, pcsq + mtctl r0, pcsq + ldil L%$qisnowon, t1 + ldo R%$qisnowon(t1), t1 + mtctl t1, pcoq ldo 4(t1),t1 - mtctl t1,pcoq - ldi PSW_Q|PSW_I,t1 - mtctl t1,ipsw + mtctl t1, pcoq + ldi PSW_Q|PSW_I, t1 + mtctl t1, ipsw rfi nop @@ -229,55 +245,54 @@ $qisnowon * go to virtual mode... * get things ready for the kernel to run in virtual mode */ - ldi HPPA_PID_KERNEL,r1 - mtctl r1,pidr1 - mtctl r1,pidr2 - mtctl r1,pidr3 - mtctl r1,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 HPPA_PID_KERNEL, r1 + mtctl r1, pidr1 + mtctl r1, pidr2 + mtctl r1, pidr3 + mtctl r1, 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 /* * Cannot change the queues or IPSW with the Q-bit on */ - rsm RESET_PSW,r0 + rsm RESET_PSW, r0 /* * We need to do an rfi to get the C bit set */ - mtctl r0,pcsq - mtctl r0,pcsq - ldil L%$virtual_mode,t1 - ldo R%$virtual_mode(t1),t1 - mtctl t1,pcoq - ldo 4(t1),t1 - mtctl t1,pcoq - ldil L%KERNEL_PSW,t1 - ldo R%KERNEL_PSW(t1),t1 - mtctl t1,ipsw + mtctl r0, pcsq + mtctl r0, pcsq + ldil L%$virtual_mode, t1 + ldo R%$virtual_mode(t1), t1 + mtctl t1, pcoq + ldo 4(t1), t1 + mtctl t1, pcoq + ldil L%kpsw, t1 + ldw R%kpsw(t1), t2 + mtctl t2, ipsw rfi nop $virtual_mode + ldil L%kernelmapped, t1 + stw t1, R%kernelmapped(t1) -#ifdef DDB_DDB +#ifdef DDB .import Debugger, code /* have to call debugger from here, from virtual mode */ ldil L%boothowto, r1 - ldo R%boothowto(r1), r1 - bb,>=,n r1,25,$noddb + ldw R%boothowto(r1), r1 + bb,>= r1, 25, $noddb + nop - ldil L%Debugger, r1 - ldo R%Debugger(r1), r1 - .call - blr r0,rp - bv,n (r1) + break HPPA_BREAK_KERNEL, HPPA_BREAK_KGDB nop $noddb #endif @@ -285,15 +300,106 @@ $noddb .import main,code ldil L%main, r1 ldo R%main(r1), r1 +$callmain .call blr r0, rp bv,n (r1) nop /* should never return... */ - bv,n (rp) + bv (rp) + nop EXIT(__start) +/* int + * pdc_call(func, pdc_flag, ...) + * iodcio_t func; + * int pdc_flag; + */ +ENTRY(pdc_call) + + mfctl eiem, t1 + mtctl r0, eiem + stw t1, HPPA_FRAME_ARG(0)(sp) + stw rp, HPPA_FRAME_CRP(sp) + copy arg0, r31 + copy sp, ret1 + + ldil L%kernelmapped, ret0 + ldw R%kernelmapped(ret0), ret0 + comb,= r0, ret0, pdc_call_unmapped1 + nop + ldil L%pdc_stack, ret1 + +pdc_call_unmapped1 + ldo HPPA_FRAME_SIZE+16*4(ret1), ret1 + + stw sp, HPPA_FRAME_PSP(ret1) + copy arg2, arg0 + copy arg3, arg1 + ldw HPPA_FRAME_ARG(4)(sp), arg2 + ldw HPPA_FRAME_ARG(5)(sp), arg3 + ldw HPPA_FRAME_ARG(6)(sp), t1 + ldw HPPA_FRAME_ARG(7)(sp), t2 + ldw HPPA_FRAME_ARG(8)(sp), t3 + ldw HPPA_FRAME_ARG(9)(sp), t4 + stw t1, HPPA_FRAME_ARG(4)(ret1) + stw t2, HPPA_FRAME_ARG(5)(ret1) + stw t3, HPPA_FRAME_ARG(6)(ret1) + stw t4, HPPA_FRAME_ARG(7)(ret1) + ldw HPPA_FRAME_ARG(10)(sp), t1 + ldw HPPA_FRAME_ARG(11)(sp), t2 + ldw HPPA_FRAME_ARG(12)(sp), t3 + ldw HPPA_FRAME_ARG(13)(sp), t4 + stw t1, HPPA_FRAME_ARG(8)(ret1) + stw t2, HPPA_FRAME_ARG(9)(ret1) + stw t3, HPPA_FRAME_ARG(10)(ret1) + stw t4, HPPA_FRAME_ARG(11)(ret1) + + comb,= r0, ret0, pdc_call_unmapped2 + nop + + copy arg0, t4 + mfctl eiem, t1 + mtctl r0, eiem + + ldi PSW_Q, arg0 /* (!pdc_flag && args[0] == PDC_PIM)? PSW_M:0) */ + break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW + nop + stw t1, HPPA_FRAME_ARG(12)(ret1) + stw ret0, HPPA_FRAME_ARG(13)(ret1) + copy t4, arg0 + +pdc_call_unmapped2 + copy ret1, sp + .call + blr r0, rp + bv,n (r31) + nop + + copy sp, t4 + ldw HPPA_FRAME_PSP(t4), sp + + ldil L%kernelmapped, t1 + ldw R%kernelmapped(t1), t1 + comb,= r0, t1, pdc_call_unmapped3 + nop + + copy ret0, t3 + ldw HPPA_FRAME_ARG(12)(t4), t1 + ldw HPPA_FRAME_ARG(13)(t4), arg0 + break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW + nop + copy t3, ret0 + mtctl t1, eiem + +pdc_call_unmapped3 + ldw HPPA_FRAME_ARG(0)(sp), t1 + ldw HPPA_FRAME_CRP(sp), rp + bv r0(rp) + mtctl t1, eiem +EXIT(pdc_call) + /* * Kernel Gateway Page (must be at known address) * System Call Gate @@ -333,11 +439,11 @@ $osf_syscall * We also need to save r29 (aka ret1) for the emulator since it may * get clobbered between here and there. */ - stw r22,HPPA_FRAME_ARG(4)(sp) - stw r21,HPPA_FRAME_ARG(5)(sp) - stw r29,HPPA_FRAME_SL(sp) + stw r22, HPPA_FRAME_ARG(4)(sp) + stw r21, HPPA_FRAME_ARG(5)(sp) + stw r29, HPPA_FRAME_SL(sp) gate $bsd_syscall,r0 - copy r1,r22 + copy r1, r22 #endif /* COMPAT_OSF1 */ $bsd_syscall @@ -346,9 +452,9 @@ $bsd_syscall * we can access kernel memory */ mtsp r0, sr1 - mfctl pidr2, r28 - ldi HPPA_PID_KERNEL, r1 - mtctl r1, pidr2 + mfctl pidr1, r28 + ldi HPPA_PID_KERNEL, t2 + mtctl t2, pidr1 /* * now call the syscall handler @@ -356,12 +462,16 @@ $bsd_syscall .import $syscall,code .call ldil L%$syscall,r1 - be,n R%$syscall(sr1,r1) + be,n R%$syscall(sr7,r1) nop + .align NBPG .export gateway_page_end, entry gateway_page_end +$trap_tmp_save + .block TF_PHYS /* XXX must be aligned to 64 */ + .import syscall,code .export $syscall,entry .proc @@ -375,152 +485,303 @@ $syscall * t3: args * t4: user stack */ - ldil L%curproc, t1 - ldw R%curproc(sr1, t1), t1 - ldw p_addr(sr1, t1), t2 - - /* save sp first */ - stw sp, TF_R30+pcb_tf+u_pcb(sr1, t2) - copy sp, t4 + ldil L%curproc, t3 + ldw R%curproc(sr1, t3), t3 + ldw p_addr(sr1, t3), t2 /* calculate kernel sp, load, create kernel stack frame */ - ldo HPPA_FRAME_SIZE+HPPA_FRAME_MAXARGS+NBPG(t2), sp - - stw r1 , TF_R1 +pcb_tf+u_pcb(sr1, t2) - stw r2 , TF_R2 +pcb_tf+u_pcb(sr1, t2) - stw r3 , TF_R3 +pcb_tf+u_pcb(sr1, t2) - stw r4 , TF_R4 +pcb_tf+u_pcb(sr1, t2) - stw r5 , TF_R5 +pcb_tf+u_pcb(sr1, t2) - stw r6 , TF_R6 +pcb_tf+u_pcb(sr1, t2) - stw r7 , TF_R7 +pcb_tf+u_pcb(sr1, t2) - stw r8 , TF_R8 +pcb_tf+u_pcb(sr1, t2) - stw r9 , TF_R9 +pcb_tf+u_pcb(sr1, t2) - stw r10, TF_R10+pcb_tf+u_pcb(sr1, t2) - stw r11, TF_R11+pcb_tf+u_pcb(sr1, t2) - stw r12, TF_R12+pcb_tf+u_pcb(sr1, t2) - stw r13, TF_R13+pcb_tf+u_pcb(sr1, t2) - stw r14, TF_R14+pcb_tf+u_pcb(sr1, t2) - stw r15, TF_R15+pcb_tf+u_pcb(sr1, t2) - stw r16, TF_R16+pcb_tf+u_pcb(sr1, t2) - stw r17, TF_R17+pcb_tf+u_pcb(sr1, t2) - stw r18, TF_R18+pcb_tf+u_pcb(sr1, t2) - stw r27, TF_R27+pcb_tf+u_pcb(sr1, t2) /* dp */ - stw r28, TF_CR8+pcb_tf+u_pcb(sr1, t2) /* saved pidr2 */ + copy sp, t4 + ldo NBPG(t2), t2 + ldo TF_SIZE(t2), sp + stw t1, TF_R22 (sr1, t2) + stw t4, TF_R30 (sr1, t2) + + stw r2 , TF_R2 (sr1, t2) + stw r3 , TF_R3 (sr1, t2) + stw r4 , TF_R4 (sr1, t2) + stw r5 , TF_R5 (sr1, t2) + stw r6 , TF_R6 (sr1, t2) + stw r7 , TF_R7 (sr1, t2) + stw r8 , TF_R8 (sr1, t2) + stw r9 , TF_R9 (sr1, t2) + stw r10, TF_R10(sr1, t2) + stw r11, TF_R11(sr1, t2) + stw r12, TF_R12(sr1, t2) + stw r13, TF_R13(sr1, t2) + stw r14, TF_R14(sr1, t2) + stw r15, TF_R15(sr1, t2) + stw r16, TF_R16(sr1, t2) + stw r17, TF_R17(sr1, t2) + stw r18, TF_R18(sr1, t2) + stw r27, TF_R27(sr1, t2) /* dp */ /* copy arguments */ + ldo 0(sp), t3 + ldo HPPA_FRAME_SIZE+HPPA_FRAME_MAXARGS(sp), sp copy t3, r1 - stwm arg0, 4(sr1, t3) - stwm arg1, 4(sr1, t3) - stwm arg2, 4(sr1, t3) - stwm arg3, 4(sr1, t3) - ldw HPPA_FRAME_ARG( 4)(sr0, t4), arg0 - ldw HPPA_FRAME_ARG( 5)(sr0, t4), arg1 - ldw HPPA_FRAME_ARG( 6)(sr0, t4), arg2 - ldw HPPA_FRAME_ARG( 7)(sr0, t4), arg3 - stwm arg0, 4(sr1, t3) - stwm arg1, 4(sr1, t3) - stwm arg2, 4(sr1, t3) - stwm arg3, 4(sr1, t3) - ldw HPPA_FRAME_ARG( 8)(sr0, t4), arg0 - ldw HPPA_FRAME_ARG( 9)(sr0, t4), arg1 - ldw HPPA_FRAME_ARG(10)(sr0, t4), arg2 - ldw HPPA_FRAME_ARG(11)(sr0, t4), arg3 - stwm arg0, 4(sr1, t3) - stwm arg1, 4(sr1, t3) - stwm arg2, 4(sr1, t3) - stwm arg3, 4(sr1, t3) + stw arg0, 0(sr1, t3) + stw arg1, 4(sr1, t3) + stw arg2, 8(sr1, t3) + stw arg3, 12(sr1, t3) + ldw HPPA_FRAME_ARG( 4)(t4), arg0 + ldw HPPA_FRAME_ARG( 5)(t4), arg1 + ldw HPPA_FRAME_ARG( 6)(t4), arg2 + ldw HPPA_FRAME_ARG( 7)(t4), arg3 + stw arg0, 16(sr1, t3) + stw arg1, 20(sr1, t3) + stw arg2, 24(sr1, t3) + stw arg3, 28(sr1, t3) + ldw HPPA_FRAME_ARG( 8)(t4), arg0 + ldw HPPA_FRAME_ARG( 9)(t4), arg1 + ldw HPPA_FRAME_ARG(10)(t4), arg2 + ldw HPPA_FRAME_ARG(11)(t4), arg3 + stw arg0, 32(sr1, t3) + stw arg1, 36(sr1, t3) + stw arg2, 40(sr1, t3) + stw arg3, 44(sr1, t3) + + /* + * Save the rest of the CPU context + */ + + ldo -4(r31), arg1 + stw r31, TF_IIOQH(sr1, t2) + stw arg1, TF_IIOQT(sr1, t2) + + mfsp sr0, arg0 + mfsp sr0, arg1 + stw arg0, TF_IISQH(sr1, t2) + stw arg1, TF_IISQT(sr1, t2) + + mfctl eiem, arg0 + mfctl ipsw, arg1 + stw arg0, TF_CR15(sr1, t2) + stw arg1, TF_CR22(sr1, t2) + + mfsp sr3, arg0 + copy r28, arg1 + stw arg0, TF_SR3(sr1, t2) + stw arg1, TF_CR8(sr1, t2) + + mfctl isr, arg0 + mfctl ior, arg1 + stw arg0, TF_CR20(sr1, t2) + stw arg1, TF_CR21(sr1, t2) + + mfctl iir, arg0 + stw arg0, TF_CR19(sr1, t2) + stw arg1, TF_FLAGS(sr1, t2) + + mfsp sr0, arg0 + mfsp sr0, arg1 + mfsp sr2, arg2 + mfsp sr4, arg3 + stw arg0, TF_SR0(sr1, t2) + stw arg1, TF_SR1(sr1, t2) + stw arg2, TF_SR2(sr1, t2) + stw arg3, TF_SR4(sr1, t2) + + mfsp sr5, arg0 + mfsp sr6, arg1 + mfsp sr7, arg2 + mfctl pidr2, arg3 + stw arg0, TF_SR5(sr1, t2) + stw arg1, TF_SR6(sr1, t2) + stw arg2, TF_SR7(sr1, t2) + stw arg3, TF_CR9 (sr1, t2) + + mfctl pidr3, arg2 + mfctl pidr4, arg3 + stw arg2, TF_CR12(sr1, t2) + stw arg3, TF_CR13(sr1, t2) + +#ifdef DDB + /* + * Save hpt mask and v2p translation table pointer + */ + mfctl eirr, arg0 + mfctl hptmask, arg1 + stw arg0, TF_CR23(sr1, t2) + stw arg1, TF_CR24(sr1, t2) + + mfctl vtop, arg0 + mfctl cr28, arg1 + stw arg0, TF_CR25(sr1, t2) + stw arg1, TF_CR28(sr1, t2) +#endif /* setup kernel context */ - mtctl r0, sr0 - mtctl r0, sr1 - mtctl r0, sr2 - mtctl r0, sr3 - mtctl r0, sr4 - mtctl r0, sr5 - mtctl r0, sr6 - mtctl r0, sr7 + mtsp r0, sr0 + mtsp r0, sr1 + mtsp r0, sr2 + mtsp r0, sr3 + mtsp r0, sr4 + mtsp r0, sr5 + mtsp r0, sr6 + mtsp r0, sr7 - /* leave pidr4 in user space so copy* work */ +#ifdef notdef + /* leave pidr2 in user space so copy* work */ ldi HPPA_PID_KERNEL, t4 - mtctl t4, pidr1 mtctl t4, pidr3 + mtctl t4, pidr4 +#endif /* setup frame */ - stw r0, HPPA_FRAME_PSP(sr1, sp) - stw r0, HPPA_FRAME_CRP(sr1, sp) + stw r0, HPPA_FRAME_PSP(sp) + stw r0, HPPA_FRAME_CRP(sp) - ldo pcb_tf+u_pcb(t2), arg0 + copy t2, arg0 copy r1, arg1 ldil L%$global$,dp ldo R%$global$(dp),dp /* do a syscall */ - ldil L%syscall, ret0 - ldo R%syscall(ret0), ret0 + ldil L%syscall, r1 + ldo R%syscall(r1), r1 .call blr r0, rp - bv,n 0(ret0) + bv,n 0(r1) + + ldil L%curproc, r1 + ldw R%curproc(r1), r1 + ldw p_md(r1), t3 + .exit .procend -/* fall through */ + /* FALLTHROUGH */ + .export $syscall_return, entry .proc .callinfo no_calls .entry $syscall_return + /* t3 == VA trapframe */ /* check for AST ? XXX */ + /* - * t1: curproc - * t2: user + * Copy partially saved state from the store into the frame */ - ldil L%curproc, t1 - ldw R%curproc(t1), t1 - ldw p_addr(t1), t4 - - /* restore state */ - ldw TF_R1 +pcb_tf+u_pcb(t4), r1 - ldw TF_R2 +pcb_tf+u_pcb(t4), r2 - ldw TF_R3 +pcb_tf+u_pcb(t4), r3 - ldw TF_R4 +pcb_tf+u_pcb(t4), r4 - ldw TF_R5 +pcb_tf+u_pcb(t4), r5 - ldw TF_R6 +pcb_tf+u_pcb(t4), r6 - ldw TF_R7 +pcb_tf+u_pcb(t4), r7 - ldw TF_R8 +pcb_tf+u_pcb(t4), r8 - ldw TF_R9 +pcb_tf+u_pcb(t4), r9 - ldw TF_R10+pcb_tf+u_pcb(t4), r10 - ldw TF_R11+pcb_tf+u_pcb(t4), r11 - ldw TF_R12+pcb_tf+u_pcb(t4), r12 - ldw TF_R13+pcb_tf+u_pcb(t4), r13 - ldw TF_R14+pcb_tf+u_pcb(t4), r14 - ldw TF_R15+pcb_tf+u_pcb(t4), r15 - ldw TF_R16+pcb_tf+u_pcb(t4), r16 - ldw TF_R17+pcb_tf+u_pcb(t4), r17 - ldw TF_R18+pcb_tf+u_pcb(t4), r18 - - ldw TF_CR8+pcb_tf(sr1,t4), t1 - ldw TF_CR9+pcb_tf(sr1,t4), t2 - ldw TF_CR12+pcb_tf(sr1,t4), t3 - mtctl t1, pidr1 + ldi $trap_tmp_save, arg1 + copy t3, arg0 + ldo TF_PHYS(arg0), arg2 +$syscall_return_copy_loop + ldw 0(arg0), t1 + ldw 4(arg0), t2 + ldo 8(arg0), arg0 + stw t1, 0(arg1) + stw t2, 4(arg1) + comb,<,n arg0, arg2, $syscall_return_copy_loop + ldo 8(arg1), arg1 + + /* 1. restore most of the general registers */ + ldw TF_CR11(t3), t1 + ldw TF_R1(t3), r1 + mtctl t1, sar + ldw TF_R2(t3), r2 + ldw TF_R3(t3), r3 + ldw TF_R4(t3), r4 + ldw TF_R5(t3), r5 + ldw TF_R6(t3), r6 + ldw TF_R7(t3), r7 + ldw TF_R8(t3), r8 + ldw TF_R9(t3), r9 + ldw TF_R10(t3), r10 + ldw TF_R11(t3), r11 + ldw TF_R12(t3), r12 + ldw TF_R13(t3), r13 + ldw TF_R14(t3), r14 + ldw TF_R15(t3), r15 + ldw TF_R16(t3), r16 + ldw TF_R17(t3), r17 + ldw TF_R18(t3), r18 + ldw TF_R19(t3), r19 + /* r20(t3) is used as a temporary and will be restored later */ + /* r21(t3) is used as a temporary and will be restored later */ + /* r22(t3) is used as a temporary and will be restored later */ + ldw TF_R23(t3), r23 + ldw TF_R24(t3), r24 + ldw TF_R25(t3), r25 + ldw TF_R26(t3), r26 + ldw TF_R27(t3), r27 + ldw TF_R28(t3), r28 + ldw TF_R29(t3), r29 + /* r30 (sp) will be restored later */ + ldw TF_R31(t3), r31 + + /* 2. restore all the space regs and pid regs, except sr3, pidr1 */ + ldw TF_SR0(t3), t1 + ldw TF_SR1(t3), t2 + mtsp t1, sr0 + mtsp t2, sr1 + + ldw TF_SR2(sr3, t3), t1 + ldw TF_SR4(sr3, t3), t2 + mtsp t1, sr2 + mtsp t2, sr4 + + ldw TF_SR5(sr3, t3), t1 + ldw TF_SR6(sr3, t3), t2 + mtsp t1, sr5 + mtsp t2, sr6 + + ldw TF_SR7(sr3, t3), t1 + ldw TF_CR9(sr3, t3), t2 + mtsp t1, sr7 mtctl t2, pidr2 - mtctl t3, pidr3 - ldw pcb_space+u_pcb(t4), t3 - mtctl t3, sr0 - mtctl t3, sr2 - mtctl t3, sr3 - mtctl t3, sr4 - mtctl t3, sr5 - mtctl t3, sr6 - - ldw TF_CR13+pcb_tf(sr1,t4), t4 - bv 0(rp) - mtctl t4, pidr4 + ldw TF_CR12(sr3, t3), t1 + ldw TF_CR13(sr3, t3), t2 + mtctl t1, pidr3 + mtctl t2, pidr4 + + ldw TF_CR30(sr3, t3), t1 + mtctl t1, cr30 + + /* + * clear the system mask, this puts us back into physical mode. + * reload trapframe pointer w/ correspondent PA value. + * sp will be left in virtual until restored from trapframe, + * since we don't use it anyway. + */ + rsm RESET_PSW, r0 + nop ! nop ! nop ! nop ! nop ! nop ! nop ! nop +$syscall_return_phys + + ldi $trap_tmp_save, t3 + + /* finally we can restore the space and offset queues and the ipsw */ + ldw TF_IISQH(t3), t1 + ldw TF_IISQT(t3), t2 + mtctl t1, pcsq + mtctl t2, pcsq + + ldw TF_IIOQH(t3), t1 + ldw TF_IIOQT(t3), t2 + mtctl t1, pcoq + mtctl t2, pcoq + + ldw TF_CR15(t3), t1 + ldw TF_CR22(t3), t2 + mtctl t1, eiem + mtctl t2, ipsw + + ldw TF_SR3(t3), t1 + ldw TF_CR8(t3), t2 + mtsp t1, sr3 + mtctl t2, pidr1 + + ldw TF_R22(t3), t1 + ldw TF_R21(t3), t2 + ldw TF_R30(t3), sp + ldw TF_R20(t3), t3 + + rfi + nop .exit .procend - $syscall_end - .align NBPG /* * interrupt vector table @@ -554,11 +815,11 @@ $syscall_end #define ITLBPRE \ mfctl pcoq,r9 /* Offset */ ! \ mfctl pcsq,r8 /* Space */ ! \ - depi 0,31,12,r9 /* align offset to page */ + depi 0,31,PGSHIFT,r9 /* align offset to page */ #define DTLBPRE \ mfctl ior, r9 /* Offset */ ! \ mfctl isr, r8 /* Space */ ! \ - depi 0,31,12,r9 /* align offset to page */ ! \ + depi 0,31,PGSHIFT,r9 /* align offset to page */ ! \ LDCR28 .align NBPG @@ -601,9 +862,39 @@ $ivaaddr ATRAP(unk29,29) ATRAP(unk30,30) ATRAP(unk31,31) - /* 32 */ - .align 32*32 - + ATRAP(unk32,32) + ATRAP(unk33,33) + ATRAP(unk34,34) + ATRAP(unk35,35) + ATRAP(unk36,36) + ATRAP(unk37,37) + ATRAP(unk38,38) + ATRAP(unk39,39) + ATRAP(unk40,40) + ATRAP(unk41,41) + ATRAP(unk42,42) + ATRAP(unk43,43) + ATRAP(unk44,44) + ATRAP(unk45,45) + ATRAP(unk46,46) + ATRAP(unk47,47) + ATRAP(unk48,48) + ATRAP(unk49,49) + ATRAP(unk50,50) + ATRAP(unk51,51) + ATRAP(unk52,52) + ATRAP(unk53,53) + ATRAP(unk54,54) + ATRAP(unk55,55) + ATRAP(unk56,56) + ATRAP(unk57,57) + ATRAP(unk58,58) + ATRAP(unk59,59) + ATRAP(unk60,60) + ATRAP(unk61,61) + ATRAP(unk62,62) + ATRAP(unk63,63) + /* 64 */ .export TLABEL(hpmc), entry TLABEL(hpmc) @@ -806,8 +1097,9 @@ TLABEL(excpt) .export $sfu_emu, entry $sfu_emu - rfi ldo 1(r0), ret0 /* none supported by now */ + rfi + nop /* Compute the hpt entry ptr */ #define HPTENT \ @@ -862,7 +1154,7 @@ TLABEL(itlb) #if USECR28 HPTENT /* will update cr28 */ #endif - depi 1, 0, 1, r1 /* mark for ITLB insert */ + depi 1, TFF_ITLB_POS, 1, r1 /* mark for ITLB insert */ /* FALLTHROUGH */ .export TLABEL(dtlb), entry @@ -927,7 +1219,7 @@ $tlb_inshpt $tlb_gothpt mfsp sr1, r16 - bb,< r1, 0, $tlb_itlb + bb,< r1, TFF_ITLB_POS, $tlb_itlb mtsp r8, sr1 idtlba r17,(sr1, r9) @@ -986,7 +1278,13 @@ $ibrk_setpsw b $ibrk_exit mtctl arg0, ipsw +$ibrk_setpsw_tovirt + + b $ibrk_exit + ldw HPPA_FRAME_PSP(sp), sp + /* insert other fast breaks here */ + nop ! nop $ibrk_exit /* skip the break */ @@ -1015,38 +1313,40 @@ TLABEL(all) * trap number in r1 (old r1 is saved in tr7) */ - mtctl sp, tr2 /* do not overwrite tr4(cr28) */ - mtctl t1, tr3 + /* do not overwrite tr4(cr28) */ + mtctl t1, tr2 + mtctl t2, tr3 mtctl t3, tr5 - ldil L%intr_recurse, t1 - ldw R%intr_recurse(t1), t3 - ldo 1(t3), t3 - comib,<> 1, t3, $trap_recurse - stw t3, R%intr_recurse(t1) - - ldil L%intr_stack, sp - ldo R%intr_stack(sp), sp - -$trap_recurse - copy sp, t3 - ldo HPPA_FRAME_SIZE+TF_SIZE(sp), sp - - /* t3 is (struct trapframe *) */ -$trap_trap - stw arg0, TF_R26(t3) - copy r1, arg0 - mfctl tr7, r1 + mfctl pcoq, t2 + bb,>= t2, 31, $trap_from_kernel + nop + /* if trapped from user space load proc's ksp pa */ + mfctl cr30, t1 + depi 1, T_USER_POS, 1, r1 + depi 1, TFF_LAST_POS, 1, r1 + ldw u_pcb+pcb_uva(t1), t3 + b $trap_make_frame + ldo NBPG(t3), t3 + +$trap_from_kernel + /* align stack */ + ldo TF_PHYS-1(sp), t3 + dep r0, 31, 6, t3 + +$trap_make_frame + /* t3 is va, t1 is pa of (struct trapframe *) */ + mfctl tr3, t2 + mtctl t3, tr3 + ldi $trap_tmp_save, t3 /* we know it's in the low mem XXX */ mfctl tr2, t1 - stw t1, TF_R30(t3) - - mfctl tr5, t1 - stw t1, TF_R20(t3) /* t3 */ + stw t1, TF_R22(t3) stw t2, TF_R21(t3) - mfctl tr3, t1 - stw t1, TF_R22(t3) + mfctl tr5, t1 + stw sp, TF_R30(t3) /* sp */ + stw t1, TF_R20(t3) /* t3 */ /* * Now, save away other volatile state that prevents us from turning @@ -1054,99 +1354,65 @@ $trap_trap * interrupt information. */ - mfctl pcoq, t1 - mtctl r0, pcoq - mfctl pcoq, t2 - stw t1, TF_IIOQH(t3) - stw t2, TF_IIOQT(t3) - mfctl pcsq, t1 mtctl r0, pcsq mfctl pcsq, t2 stw t1, TF_IISQH(t3) stw t2, TF_IISQT(t3) + mtctl r0, pcsq - mfctl ior, t1 - mfctl ipsw, t2 - stw t1, TF_CR21(t3) - stw t2, TF_CR22(t3) + mfctl pcoq, t1 + mtctl r0, pcoq + mfctl pcoq, t2 + stw t1, TF_IIOQH(t3) + stw t2, TF_IIOQT(t3) mfctl eiem, t1 + mfctl ipsw, t2 stw t1, TF_CR15(t3) + stw t2, TF_CR22(t3) - mfctl iir, t1 - mfctl isr, t2 - stw t1, TF_CR19(t3) - stw t2, TF_CR20(t3) - - /* - * Now we're about to turn on the PC queue. We'll also go to virtual - * mode in the same step. Save the space registers sr4 - sr7 and - * point them to the kernel space - */ - - mfsp sr4, t1 - mfsp sr5, t2 - stw t1, TF_SR4(t3) - stw t2, TF_SR5(t3) + mfsp sr3, t1 + mfctl pidr1, t2 + stw t1, TF_SR3(t3) + stw t2, TF_CR8(t3) - mfsp sr6, t1 - mfsp sr7, t2 - stw t1, TF_SR6(t3) - stw t2, TF_SR7(t3) + mfctl isr, t1 + mfctl ior, t2 + stw t1, TF_CR20(t3) + stw t2, TF_CR21(t3) - /* XXX HPPA_SID_KERNEL == 0 */ - mtsp r0, sr4 - mtsp r0, sr5 - mtsp r0, sr6 - mtsp r0, sr7 + mfctl iir, t2 + stw t2, TF_CR19(t3) + stw r1, TF_FLAGS(t3) + mfctl tr7, r1 /* - * save the protection ID registers. We will keep the last one - * with the protection of the user's area and set the remaining - * ones to be the kernel. + * Setup kernel context */ - mfctl pidr1, t1 - mfctl pidr2, t2 - stw t1, TF_CR8(t3) - stw t2, TF_CR9(t3) - - mfctl pidr3, t1 - mfctl pidr4, t2 - stw t1, TF_CR12(t3) - stw t2, TF_CR13(t3) - ldi HPPA_PID_KERNEL,t1 - mtctl t1,pidr1 - mtctl t1,pidr2 - mtctl t1,pidr3 + mtctl t1, pidr1 + mtsp r0, sr3 /* load the space queue */ mtctl r0, pcsq mtctl r0, pcsq - /* - * set the new psw to be data and code translation, interrupts - * disabled, protection enabled, Q bit on - */ - - ldil L%KERNEL_PSW, t1 - ldo R%KERNEL_PSW(t1), t1 - mtctl t1, ipsw - - /* - * Load up a real value into eiem to reflect an spl level of splhigh. - * Right now interrupts are still off. - */ - ldi IPL_NONE, t1 - mtctl t1, eiem + /* this will enable interrupts after `cold' */ + ldil L%kpsw, t1 + ldw R%kpsw(t1), t2 + mtctl r0, eiem + mtctl t2, ipsw /* load in the address to "return" to with the rfir instruction */ ldil L%$trapnowvirt, t1 ldo R%$trapnowvirt(t1), t1 - /* load the offset queue */ + /* + * load the offset queue, space queue was loaded as a side effect of + * saving the space queue above + */ mtctl t1, pcoq ldo 4(t1), t1 mtctl t1, pcoq @@ -1154,37 +1420,64 @@ $trap_trap /* * Must do rfir not rfi since we may be called from tlbmiss routine * (to handle page fault) and it uses the shadowed registers. + * + * Also translate the t3 (trapframe) back into va */ + mfctl tr3, t3 + ldo HPPA_FRAME_SIZE+TF_SIZE(t3), sp rfir nop $trapnowvirt /* - * t3 contains the virtual address of the saved status area - * t1 contains the trap flags - * sp contains the virtual address of the stack pointer + * t3 contains the physical address of the trapframe + * sp is loaded w/ the right VA (we did not need it being physical) */ -#if 0 - ldil L%curproc, t1 - ldw R%curproc(t1), t3 - comb,= r0, t3, $trap_recurse - nop - ldo HPPA_FRAME_SIZE(sp), sp - b $trap_trap - ldo p_md(t3), t3 -#endif - stw t1, TF_FLAGS(t3) /* XXX not really */ + mfsp sr0, t1 + mfsp sr1, t2 + stw t1, TF_SR0(sr3, t3) + stw t2, TF_SR1(sr3, t3) + + mfsp sr2, t1 + mfsp sr4, t2 + stw t1, TF_SR2(sr3, t3) + stw t2, TF_SR4(sr3, t3) + + mfsp sr5, t2 + mfsp sr6, t1 + stw t2, TF_SR5(sr3, t3) + stw t1, TF_SR6(sr3, t3) + + mfsp sr7, t1 + mfctl pidr2, t2 + stw t1, TF_SR7(sr3, t3) + stw t2, TF_CR9(sr3, t3) + + mtsp r0, sr0 + mtsp r0, sr1 + mtsp r0, sr2 + mtsp r0, sr4 + mtsp r0, sr5 + mtsp r0, sr6 + mtsp r0, sr7 + + mfctl pidr3, t1 + mfctl pidr4, t2 + stw t1, TF_CR12(t3) + stw t2, TF_CR13(t3) /* * Save all general registers that we haven't saved already */ + mfctl sar, t1 + stw t1, TF_CR11(t3) stw r1,TF_R1(t3) stw r2,TF_R2(t3) #ifdef DDB - stw rp,HPPA_FRAME_CRP(sp) - stw r3,HPPA_FRAME_PSP(sp) + stw rp, HPPA_FRAME_CRP(sp) + stw r3, -HPPA_FRAME_SIZE(sp) #endif stw r3,TF_R3(t3) stw r4,TF_R4(t3) @@ -1203,32 +1496,33 @@ $trapnowvirt stw r17,TF_R17(t3) stw r18,TF_R18(t3) stw r19,TF_R19(t3) - /* r20 already saved - * r21 already saved - * r22 already saved */ + /* r20 already saved (t1) + * r21 already saved (t2) + * r22 already saved (t3) */ stw r23,TF_R23(t3) stw r24,TF_R24(t3) stw r25,TF_R25(t3) - /* r26 already saved */ + stw r26,TF_R26(t3) stw r27,TF_R27(t3) stw r28,TF_R28(t3) stw r29,TF_R29(t3) - /* r30 already saved */ + /* r30 already saved (sp) */ stw r31,TF_R31(t3) /* - * Save the space registers. + * Copy partially saved state from the store into the frame */ - - mfsp sr0, t1 - mfsp sr1, t2 - stw t1, TF_SR0(t3) - stw t2, TF_SR1(t3) - - mfsp sr2, t1 - mfsp sr3, t2 - stw t1, TF_SR2(t3) - stw t2, TF_SR3(t3) + ldi $trap_tmp_save, arg0 + copy t3, arg1 + ldo TF_PHYS(arg0), arg2 +$trap_copy_loop + ldw 0(arg0), t1 + ldw 4(arg0), t2 + ldo 8(arg0), arg0 + stw t1, 0(arg1) + stw t2, 4(arg1) + comb,<,n arg0, arg2, $trap_copy_loop + ldo 8(arg1), arg1 /* * Save the necessary control registers that were not already saved. @@ -1236,10 +1530,8 @@ $trapnowvirt mfctl rctr, t1 stw t1, TF_CR0(t3) - - mfctl sar, t1 - stw t1, TF_CR11(t3) - + /* XXX save ccr here w/ rctr */ + #ifdef DDB /* * Save hpt mask and v2p translation table pointer @@ -1254,18 +1546,22 @@ $trapnowvirt stw t1, TF_CR25(t3) stw t2, TF_CR28(t3) #endif + mfctl cr30, t1 + stw t1, TF_CR30(t3) /* * load the global pointer for the kernel */ - ldil L%$global$,dp - ldo R%$global$(dp),dp + ldil L%$global$, dp + ldo R%$global$(dp), dp /* * call the C routine trap(). - * Trap type (arg0) was setup back in the beginning of the handler + * form trap type in the first argument to trap() */ + ldw TF_FLAGS(t3), arg0 + dep r0, 26, 27, arg0 copy t3, arg1 #ifdef DDB @@ -1279,153 +1575,22 @@ $trapnowvirt blr r0,rp bv,n r0(t1) nop -#if 0 - /* see if context really changed */ - ldil L%curproc, t1 - ldw R%curproc(t1), t2 - comb,= t2, r0, $curproc_zero - copy r5, t3 - ldo p_md(t2), t3 -$curproc_zero -#else + /* see if curproc have changed */ + ldw TF_FLAGS(r5), arg0 + bb,>=,n arg0, TFF_LAST_POS, $syscall_return copy r5, t3 -#endif - /* - * Restore most of the state, up to the point where we need to turn - * off the PC queue. Going backwards, starting with control regs. - */ - - ldw TF_CR0(t3), t1 - ldw TF_CR15(t3), t2 - mtctl t1, rctr - mtctl t2, eiem - - ldw TF_CR11(t3),t1 - mtctl t1,sar - - ldw TF_CR8(t3),t1 - mtctl t1,pidr1 - - - /* - * Restore the lower space registers, we'll restore sr4 - sr7 after - * we have turned off translations - */ - - ldw TF_SR0(t3), t1 - ldw TF_SR1(t3), t2 - mtsp t1, sr0 - mtsp t2, sr1 - - ldw TF_SR2(t3), t1 - ldw TF_SR3(t3), t2 - mtsp t1, sr2 - mtsp t2, sr3 - - /* - * restore most of the general registers - */ - - ldw TF_R1(t3),r1 - ldw TF_R2(t3),r2 - ldw TF_R3(t3),r3 - ldw TF_R4(t3),r4 - ldw TF_R5(t3),r5 - ldw TF_R6(t3),r6 - ldw TF_R7(t3),r7 - ldw TF_R8(t3),r8 - ldw TF_R9(t3),r9 - ldw TF_R10(t3),r10 - ldw TF_R11(t3),r11 - ldw TF_R12(t3),r12 - ldw TF_R13(t3),r13 - ldw TF_R14(t3),r14 - ldw TF_R15(t3),r15 - ldw TF_R16(t3),r16 - ldw TF_R17(t3),r17 - ldw TF_R18(t3),r18 - ldw TF_R19(t3),r19 - /* r20(t3) is used as a temporary and will be restored later */ - /* r21(t3) is used as a temporary and will be restored later */ - /* r22(t3) is used as a temporary and will be restored later */ - ldw TF_R23(t3),r23 - ldw TF_R24(t3),r24 - ldw TF_R25(t3),r25 - ldw TF_R26(t3),r26 - ldw TF_R27(t3),r27 - ldw TF_R28(t3),r28 - ldw TF_R29(t3),r29 - /* r30 (sp) will be restored later */ - ldw TF_R31(t3),r31 - - /* - * clear the system mask, this puts us back into physical mode. - * - * N.B: Better not be any code translation traps from this point - * on. Of course, we know this routine could never be *that* big. - */ - rsm RESET_PSW,r0 - - /* - * restore the protection ID registers - */ - - ldw TF_CR8(t3),t1 - mtctl t1,pidr1 - - ldw TF_CR9(t3),t1 - mtctl t1,pidr2 - - ldw TF_CR12(t3),t1 - mtctl t1,pidr3 - - /* - * restore the space registers - */ - - ldw TF_SR4(t3),t1 - ldw TF_SR5(t3),t2 - mtsp t1,sr4 - mtsp t2,sr5 - - ldw TF_SR6(t3), t1 - ldw TF_SR7(t3), t2 - mtsp t1, sr6 - mtsp t2, sr7 - - /* - * finally we can restore the space and offset queues and the ipsw - */ - - ldw TF_IISQH(t3), t1 - ldw TF_IISQT(t3), t2 - mtctl t1, pcsq - mtctl t2, pcsq - ldw TF_IIOQH(t3), t1 - ldw TF_IIOQT(t3), t2 - mtctl t1, pcoq - mtctl t2, pcoq + /* see if curproc have really changed */ + ldil L%curproc, t1 + ldw R%curproc(t1), t2 + comb,=,n r0, t2, $syscall_return + copy r5, t3 - ldw TF_CR22(t3), t1 - mtctl t1, ipsw + /* means curproc have actually changed */ + b $syscall_return + ldw p_md(t2), t3 - /* - * restore the last registers,r30, r22, and finally r21(t2) - * decrement interrupt recursion level - */ - ldil L%intr_recurse, t1 - ldw R%intr_recurse(t1), t2 - addi -1, t2, t2 - stw t2, R%intr_recurse(t1) - ldw TF_R22(t3),t1 - ldw TF_R21(t3),t2 - ldw TF_R30(t3),sp - ldw TF_R20(t3),t3 - - rfi - nop .export $trap$all$end, entry $trap$all$end @@ -1558,9 +1723,9 @@ ENTRY(spstrcpy) stw t2, pcb_onfault+u_pcb(r31) ldw HPPA_FRAME_ARG(4)(sp), ret1 - mfctl sr2, ret0 /* XXX need this? */ - mtctl arg0, sr1 - mtctl arg2, sr2 + mfsp sr2, ret0 /* XXX need this? */ + mtsp arg0, sr1 + mtsp arg2, sr2 add ret1, arg1, ret1 $spstrcpy_loop @@ -1574,7 +1739,7 @@ $spstrcpy_exit stw r0, pcb_onfault+u_pcb(r31) copy r0, ret0 ldw HPPA_FRAME_ARG(4)(sp), t1 - mtctl ret0, sr2 + mtsp ret0, sr2 sub ret1, t1, ret1 bv 0(rp) stw ret1, HPPA_FRAME_ARG(5)(sp) @@ -1737,8 +1902,9 @@ ENTRY(cpu_switch) * Clear curproc so that we don't accumulate system time while idle. */ ldil L%curproc, t1 - ldw R%curproc(t1), t2 + ldw R%curproc(t1), arg2 stw r0, R%curproc(t1) + /* remain on the old (curproc)'s stack until we have better choice */ /* * arg3: spl @@ -1801,6 +1967,7 @@ link_ok ldw p_forw(arg1), arg0 stw arg0, p_forw(t2) stw t2, p_back(arg0) + stw r0, p_back(arg1) comb,<> arg0, t2, sw_qnempty nop @@ -1822,37 +1989,81 @@ sw_qnempty copy arg1, t2 #endif ldil L%curproc, t1 - stw r0, p_back(arg1) stw arg1, R%curproc(t1) /* Skip context switch if same process. */ - comb,=,n arg1, t2, switch_return + comb,=,n arg1, arg2, switch_return /* If old process exited, don't bother. */ - comb,=,n r0, t2, switch_exited + comb,=,n r0, arg2, switch_exited /* * 2. save old proc context * - * t2: old proc - * - * nothing to save, everything needed to be done is already - * done on enter, wonderfull. + * arg2: old proc */ - - /* don't need old curproc(t2) starting from here */ + ldw p_md(arg2), t1 + copy sp, t2 + ldo HPPA_FRAME_SIZE+16*4(sp), sp + ldw TF_R30(t1), t3 + stw t2, HPPA_FRAME_PSP(sp) + stw rp, HPPA_FRAME_CRP(sp) + stw t3, HPPA_FRAME_ARG(0)(sp) + stw sp, TF_R30(t1) + fdc r0(t1) + /* save callee-save registers */ + stw r3, 0*4(t2) + stw r4, 1*4(t2) + stw r5, 2*4(t2) + stw r6, 3*4(t2) + stw r7, 4*4(t2) + stw r8, 5*4(t2) + stw r9, 6*4(t2) + stw r10, 7*4(t2) + stw r11, 8*4(t2) + stw r12, 9*4(t2) + stw r13, 10*4(t2) + stw r14, 11*4(t2) + stw r15, 12*4(t2) + stw r16, 13*4(t2) + stw r17, 14*4(t2) + stw r18, 15*4(t2) + + /* don't need old curproc (arg2) starting from here */ switch_exited /* * 3. restore new proc context * * arg1: new proc - * arg2: new pcb */ - - ldw p_addr(arg1), arg2 - /* only pidr needs restoring, so we can access user space */ - ldw TF_CR13+pcb_tf+u_pcb(arg2), t1 - mtctl t1, pidr4 + ldw p_md(arg1), t1 + ldw TF_CR30(t1), t2 + ldw TF_R30(t1), sp + ldw TF_CR9(t1), t3 + mtctl t3, pidr2 + mtctl t2, cr30 + ldw HPPA_FRAME_ARG(0)(sp), t3 + ldw HPPA_FRAME_CRP(sp), rp + ldw HPPA_FRAME_PSP(sp), t2 + stw t3, TF_R30(t1) + fdc r0(t1) + ldw 0*4(t2), r3 + ldw 1*4(t2), r4 + ldw 2*4(t2), r5 + ldw 3*4(t2), r6 + ldw 4*4(t2), r7 + ldw 5*4(t2), r8 + ldw 6*4(t2), r9 + ldw 7*4(t2), r10 + ldw 8*4(t2), r11 + ldw 9*4(t2), r12 + ldw 10*4(t2), r13 + ldw 11*4(t2), r14 + ldw 12*4(t2), r15 + ldw 13*4(t2), r16 + ldw 14*4(t2), r17 + ldw 15*4(t2), r18 + copy t2, sp switch_return bv 0(rp) @@ -1873,6 +2084,10 @@ ENTRY(switch_exit) ldil L%proc0, t2 ldo R%proc0(t2), t2 + ldw p_md(t2), t1 + ldw TF_CR30(t1), t1 + mtctl t1, cr30 + /* setup kernel context */ mtctl r0, sr0 mtctl r0, sr1 @@ -1883,11 +2098,11 @@ ENTRY(switch_exit) mtctl r0, sr6 mtctl r0, sr7 - /* leave pidr4 in user space so copy* work */ + /* leave pidr2 in user space so copy* work */ ldi HPPA_PID_KERNEL, t4 mtctl t4, pidr1 - mtctl t4, pidr2 mtctl t4, pidr3 + mtctl t4, pidr4 b switch_search nop @@ -1895,8 +2110,16 @@ EXIT(switch_exit) ENTRY(switch_trampoline) /* XXX load curproc here? */ - bv 0(arg0) - copy arg1, arg0 + ldw HPPA_FRAME_ARG(1)(sp), t1 + ldw HPPA_FRAME_ARG(2)(sp), arg0 + .call + blr %r0, rp + bv,n %r0(t1) + nop + ldil L%curproc, t1 + ldw R%curproc(t1), t2 + b $syscall_return + ldw p_md(t2), t3 EXIT(switch_trampoline) /* @@ -1904,19 +2127,19 @@ EXIT(switch_trampoline) */ ENTRY(sigcode) /* TODO signal trampoline */ -ALTENTRY(esigcode) bv 0(rp) nop +ALTENTRY(esigcode) EXIT(sigcode) #ifdef COMPAT_LINUX ENTRY(linux_sigcode) -ALTENTRY(linux_esigcode) /* TODO linux signal trampoline */ bv 0(rp) nop -EXIT(linix_esigcode) +ALTENTRY(linux_esigcode) +EXIT(linix_sigcode) #endif /* COMPAT_LINUX */ .end |