diff options
-rw-r--r-- | sys/arch/hppa64/hppa64/genassym.cf | 3 | ||||
-rw-r--r-- | sys/arch/hppa64/hppa64/locore.S | 140 | ||||
-rw-r--r-- | sys/arch/hppa64/include/cpu.h | 9 |
3 files changed, 148 insertions, 4 deletions
diff --git a/sys/arch/hppa64/hppa64/genassym.cf b/sys/arch/hppa64/hppa64/genassym.cf index 31bb023d329..bed7034674a 100644 --- a/sys/arch/hppa64/hppa64/genassym.cf +++ b/sys/arch/hppa64/hppa64/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.5 2011/04/05 15:46:53 jsing Exp $ +# $OpenBSD: genassym.cf,v 1.6 2011/04/05 16:05:51 jsing Exp $ # # Copyright (c) 1982, 1990, 1993 @@ -128,6 +128,7 @@ member pcb_ksp member pcb_space struct cpu_info +member ci_trap_save member ci_psw member ci_curproc diff --git a/sys/arch/hppa64/hppa64/locore.S b/sys/arch/hppa64/hppa64/locore.S index d1735bdeaf0..7f4871d5544 100644 --- a/sys/arch/hppa64/hppa64/locore.S +++ b/sys/arch/hppa64/hppa64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.15 2011/04/05 15:46:53 jsing Exp $ */ +/* $OpenBSD: locore.S,v 1.16 2011/04/05 16:05:51 jsing Exp $ */ /* * Copyright (c) 2005 Michael Shalayeff @@ -418,7 +418,143 @@ $syscall_return mtctl %r0, %eiem - ldo 8(%arg0), %r31 /* flags */ + /* + * Store registers in physical trap save area for restore after the + * system mask has been reset and we are no longer in virtual mode. + */ + mfctl %cr24, %r1 + ldo CI_TRAP_SAVE(%r1), %r1 + + ldd TF_ARGS+4*8(%arg0), %arg2 /* arg3 */ + ldd TF_ARGS+5*8(%arg0), %arg3 /* arg2 */ + std %arg2, 0*8(%r1) + std %arg3, 1*8(%r1) + + ldd TF_ARGS+6*8(%arg0), %arg2 /* arg1 */ + ldd TF_ARGS+7*8(%arg0), %arg3 /* arg0 */ + std %arg2, 2*8(%r1) + std %arg3, 3*8(%r1) + + ldd TF_IIOQ+0(%arg0), %arg2 /* pcoq */ + ldd TF_IIOQ+8(%arg0), %arg3 + std %arg2, 4*8(%r1) + std %arg3, 5*8(%r1) + + ldd TF_IISQ+0(%arg0), %arg2 /* pcsq */ + ldd TF_IISQ+8(%arg0), %arg3 + std %arg2, 6*8(%r1) + std %arg3, 7*8(%r1) + + ldd TF_PIDR1(%arg0), %arg2 /* pidr1 */ + ldd TF_PIDR2(%arg0), %arg3 /* pidr2 */ + std %arg2, 8*8(%r1) + std %arg3, 9*8(%r1) + + ldd TF_SR0(%arg0), %arg2 /* sr0 */ + ldd TF_SR1(%arg0), %arg3 /* sr1 */ + std %arg2, 10*8(%r1) + std %arg3, 11*8(%r1) + + ldd TF_IPSW(%arg0), %arg2 /* ipsw */ + ldd TF_EIEM(%arg0), %arg3 /* eiem */ + std %arg2, 12*8(%r1) + std %arg3, 13*8(%r1) + + ldd TF_SP(%arg1), %arg2 /* sp */ + std %arg2, 14*8(%r1) + + /* + * Restore general registers. + */ + ldd TF_R1(%arg0), %r1 + ldd TF_RP(%arg0), %rp + ldd TF_R3(%arg0), %r3 + ldd TF_R4(%arg0), %r4 + ldd TF_R5(%arg0), %r5 + ldd TF_R6(%arg0), %r6 + ldd TF_R7(%arg0), %r7 + ldd TF_R8(%arg0), %r8 + ldd TF_R9(%arg0), %r9 + ldd TF_R10(%arg0), %r10 + ldd TF_R11(%arg0), %r11 + ldd TF_R12(%arg0), %r12 + ldd TF_R13(%arg0), %r13 + ldd TF_R14(%arg0), %r14 + ldd TF_R15(%arg0), %r15 + ldd TF_R16(%arg0), %r16 + ldd TF_R17(%arg0), %r17 + ldd TF_R18(%arg0), %r18 + ldd TF_ARGS+0*8(%arg0), %r19 + ldd TF_ARGS+1*8(%arg0), %r20 + ldd TF_ARGS+2*8(%arg0), %r21 + ldd TF_ARGS+3*8(%arg0), %r22 + /* Restore arg3, arg2, arg1 and arg0 later. */ + ldd TF_DP(%arg0), %r27 + ldd TF_RET0(%arg0), %r28 + ldd TF_RET1(%arg0), %r29 + /* Restore sp later. */ + ldd TF_R31(%arg0), %r31 + + /* Restore control registers. */ + ldd TF_RCTR(%arg0), %arg2 /* rctr */ + ldd TF_CCR(%arg0), %arg3 /* ccr */ + mtctl %arg2, %cr0 + mtctl %arg3, %cr10 + + ldd TF_IOR(%arg0), %arg2 /* ior */ + ldd TF_ISR(%arg0), %arg3 /* isr */ + mtctl %arg2, %cr27 + mtsp %arg3, %sr6 + + ldd TF_SAR(%arg0), %arg2 /* sar */ + ldd TF_VTOP(%arg0), %arg3 /* vtop */ + mtctl %arg2, %sar + mtctl %arg3, %cr25 + + ldd TF_CR30(%arg0), %arg2 /* pa(u) */ + ldd TF_CR27(%arg0), %arg3 /* user curthread */ + mtctl %arg2, %cr30 + mtctl %arg3, %cr27 + + /* Clear system masks before restoring queues and space registers. */ + rsm (PSL_R|PSL_Q|PSL_P|PSL_I|PSL_D), %r0 + nop ! nop ! nop ! nop + + mfctl %cr24, %arg0 + ldo CI_TRAP_SAVE(%arg0), %arg0 + + ldd 4*8(%arg0), %arg2 /* pcoq */ + ldd 5*8(%arg0), %arg3 + mtctl %arg2, %pcoq + mtctl %arg3, %pcoq + + ldd 6*8(%arg0), %arg2 /* pcsq */ + ldd 7*8(%arg0), %arg3 + mtctl %arg2, %pcsq + mtctl %arg3, %pcsq + + ldd 8*8(%arg0), %arg2 /* pidr1 */ + ldd 9*8(%arg0), %arg3 /* pidr2 */ + mtctl %arg2, %pidr1 + mtctl %arg3, %pidr2 + + ldd 10*8(%arg0), %arg2 /* sr0 */ + ldd 11*8(%arg0), %arg3 /* sr1 */ + mtsp %arg2, %sr0 + mtsp %arg3, %sr1 + + ldd 12*8(%arg0), %arg2 /* ipsw */ + ldd 13*8(%arg0), %arg3 /* eiem */ + mtctl %arg2, %ipsw + mtctl %arg3, %eiem + + ldd 14*8(%arg0), %sp /* sp */ + + /* Restore temporary registers. */ + ldd 0*8(%arg1), %arg3 + ldd 1*8(%arg1), %arg2 + ldd 2*8(%arg1), %arg1 + ldd 3*8(%arg1), %arg0 rfi nop diff --git a/sys/arch/hppa64/include/cpu.h b/sys/arch/hppa64/include/cpu.h index 4a328282ce5..aa88b02be8a 100644 --- a/sys/arch/hppa64/include/cpu.h +++ b/sys/arch/hppa64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.20 2011/04/05 15:46:53 jsing Exp $ */ +/* $OpenBSD: cpu.h,v 1.21 2011/04/05 16:05:51 jsing Exp $ */ /* * Copyright (c) 2005 Michael Shalayeff @@ -115,7 +115,14 @@ #include <sys/time.h> #include <sys/sched.h> +/* + * Note that the alignment of ci_trap_save is important since we want to keep + * it within a single cache line. As a result, it must be kept as the first + * entry within the cpu_info struct. + */ struct cpu_info { + volatile u_long ci_trap_save[16]; + volatile int ci_psw; struct proc *ci_curproc; |