summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/hppa64/hppa64/genassym.cf3
-rw-r--r--sys/arch/hppa64/hppa64/locore.S140
-rw-r--r--sys/arch/hppa64/include/cpu.h9
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;