summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-05-22 16:27:50 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-05-22 16:27:50 +0000
commit7fa0136b18e5b4688b453c72160050bd8372cce9 (patch)
tree6d1c7144f1600d040a65b434e982600e885b4d6a /sys
parent70ed608633331a71e1c6573076a67d5c43af4099 (diff)
Fill complete trap frame.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/powerpc64/include/cpu.h3
-rw-r--r--sys/arch/powerpc64/powerpc64/genassym.cf83
-rw-r--r--sys/arch/powerpc64/powerpc64/machdep.c3
-rw-r--r--sys/arch/powerpc64/powerpc64/trap_subr.S126
4 files changed, 202 insertions, 13 deletions
diff --git a/sys/arch/powerpc64/include/cpu.h b/sys/arch/powerpc64/include/cpu.h
index 962572d225f..30efd9f46ad 100644
--- a/sys/arch/powerpc64/include/cpu.h
+++ b/sys/arch/powerpc64/include/cpu.h
@@ -14,6 +14,9 @@ struct cpu_info {
struct proc *ci_curproc;
+#define CPUSAVE_LEN 9
+ register_t ci_tempsave[CPUSAVE_LEN];
+
uint32_t ci_ipending;
#ifdef DIAGNOSTIC
int ci_mutex_level;
diff --git a/sys/arch/powerpc64/powerpc64/genassym.cf b/sys/arch/powerpc64/powerpc64/genassym.cf
index d22c047eac0..cc15a195a0e 100644
--- a/sys/arch/powerpc64/powerpc64/genassym.cf
+++ b/sys/arch/powerpc64/powerpc64/genassym.cf
@@ -1,6 +1,89 @@
+# $OpenBSD: genassym.cf,v 1.3 2020/05/22 16:27:49 kettenis Exp $
+#
+# Copyright (c) 1982, 1990 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+#
+# @(#)genassym.c 7.8 (Berkeley) 5/7/91
+#
+
include <sys/param.h>
+struct cpu_info
+member ci_tempsave
+define CPUSAVE_SRR0 0
+define CPUSAVE_SRR1 8
+define CPUSAVE_R27 16
+define CPUSAVE_R28 24
+define CPUSAVE_R29 32
+define CPUSAVE_R30 40
+define CPUSAVE_R31 48
+define CPUSAVE_DAR 56
+define CPUSAVE_DSISR 64
+
export FRAMELEN
struct trapframe FRAME_
+member 0 fixreg[0]
member 1 fixreg[1]
+member 2 fixreg[2]
+member 3 fixreg[3]
+member 4 fixreg[4]
+member 5 fixreg[5]
+member 6 fixreg[6]
+member 7 fixreg[7]
+member 8 fixreg[8]
+member 9 fixreg[9]
+member 10 fixreg[10]
+member 11 fixreg[11]
+member 12 fixreg[12]
+member 13 fixreg[13]
+member 14 fixreg[14]
+member 15 fixreg[15]
+member 16 fixreg[16]
+member 17 fixreg[17]
+member 18 fixreg[18]
+member 19 fixreg[19]
+member 20 fixreg[20]
+member 21 fixreg[21]
+member 22 fixreg[22]
+member 23 fixreg[23]
+member 24 fixreg[24]
+member 25 fixreg[25]
+member 26 fixreg[26]
+member 27 fixreg[27]
+member 28 fixreg[28]
+member 29 fixreg[29]
+member 30 fixreg[30]
+member 31 fixreg[31]
+member lr
+member cr
+member ctr
+member xer
+member srr0
+member srr1
+member dar
+member dsisr
member exc
diff --git a/sys/arch/powerpc64/powerpc64/machdep.c b/sys/arch/powerpc64/powerpc64/machdep.c
index 3199d88a646..107074710e0 100644
--- a/sys/arch/powerpc64/powerpc64/machdep.c
+++ b/sys/arch/powerpc64/powerpc64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.7 2020/05/22 15:29:21 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.8 2020/05/22 16:27:49 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -81,6 +81,7 @@ init_powernv(void *fdt, void *tocbase)
int i;
/* Store pointer to our struct cpu_info. */
+ __asm volatile ("mtsprg0 %0" :: "r"(&cpu_info_primary));
__asm volatile ("mr %%r13, %0" :: "r"(&cpu_info_primary));
/* Clear BSS. */
diff --git a/sys/arch/powerpc64/powerpc64/trap_subr.S b/sys/arch/powerpc64/powerpc64/trap_subr.S
index 3d171158466..eeeaa41b759 100644
--- a/sys/arch/powerpc64/powerpc64/trap_subr.S
+++ b/sys/arch/powerpc64/powerpc64/trap_subr.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap_subr.S,v 1.1 2020/05/22 15:07:47 kettenis Exp $ */
+/* $OpenBSD: trap_subr.S,v 1.2 2020/05/22 16:27:49 kettenis Exp $ */
/* $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $ */
/*-
@@ -39,9 +39,96 @@
.abiversion 2
+#define GET_CPUINFO(r) \
+ mfsprg0 r
+
#define GET_TOCBASE(r) \
ld r, TRAP_TOCBASE(0)
+/*
+ * FRAME_SETUP assumes:
+ * SPRG1 SP (1)
+ * SPRG3 trap type
+ * savearea r27-r31,DAR,DSISR (DAR & DSISR only for DSI traps)
+ * r28 LR
+ * r29 CR
+ * r30 scratch
+ * r31 scratch
+ * r1 kernel stack
+ * SRR0/1 as at start of trap
+ *
+ * NOTE: SPRG1 is never used while the MMU is on, making it safe to reuse
+ * in any real-mode fault handler, including those handling double faults.
+ */
+#define FRAME_SETUP(savearea) \
+/* Have to enable translation to allow access of kernel stack: */ \
+ GET_CPUINFO(%r31); \
+ mfsrr0 %r30; \
+ std %r30, (savearea+CPUSAVE_SRR0)(%r31); /* save SRR0 */ \
+ mfsrr1 %r30; \
+ std %r30, (savearea+CPUSAVE_SRR1)(%r31); /* save SRR1 */ \
+ mfsprg1 %r31; /* get saved SP (clears SPRG1) */ \
+ mfmsr %r30; \
+ ori %r30, %r30, (PSL_RI)@l; /* XXX */ \
+ mtmsr %r30; /* stack can now be accessed */ \
+ isync; \
+ stdu %r31, -(FRAMELEN+288)(%r1); /* save it in the callframe */ \
+ std %r0, FRAME_0+48(%r1); /* save r0 in the trapframe */ \
+ std %r31, FRAME_1+48(%r1); /* save SP " " */ \
+ std %r2, FRAME_2+48(%r1); /* save r2 " " */ \
+ std %r28, FRAME_LR+48(%r1); /* save LR " " */ \
+ std %r29, FRAME_CR+48(%r1); /* save CR " " */ \
+ GET_CPUINFO(%r2); \
+ ld %r27, (savearea+CPUSAVE_R27)(%r2); /* get saved r27 */ \
+ ld %r28, (savearea+CPUSAVE_R28)(%r2); /* get saved r28 */ \
+ ld %r29, (savearea+CPUSAVE_R29)(%r2); /* get saved r29 */ \
+ ld %r30, (savearea+CPUSAVE_R30)(%r2); /* get saved r30 */ \
+ ld %r31, (savearea+CPUSAVE_R31)(%r2); /* get saved r31 */ \
+ std %r3, FRAME_3+48(%r1); /* save r3-r31 */ \
+ std %r4, FRAME_4+48(%r1); \
+ std %r5, FRAME_5+48(%r1); \
+ std %r6, FRAME_6+48(%r1); \
+ std %r7, FRAME_7+48(%r1); \
+ std %r8, FRAME_8+48(%r1); \
+ std %r9, FRAME_9+48(%r1); \
+ std %r10, FRAME_10+48(%r1); \
+ std %r11, FRAME_11+48(%r1); \
+ std %r12, FRAME_12+48(%r1); \
+ std %r13, FRAME_13+48(%r1); \
+ std %r14, FRAME_14+48(%r1); \
+ std %r15, FRAME_15+48(%r1); \
+ std %r16, FRAME_16+48(%r1); \
+ std %r17, FRAME_17+48(%r1); \
+ std %r18, FRAME_18+48(%r1); \
+ std %r19, FRAME_19+48(%r1); \
+ std %r20, FRAME_20+48(%r1); \
+ std %r21, FRAME_21+48(%r1); \
+ std %r22, FRAME_22+48(%r1); \
+ std %r23, FRAME_23+48(%r1); \
+ std %r24, FRAME_24+48(%r1); \
+ std %r25, FRAME_25+48(%r1); \
+ std %r26, FRAME_26+48(%r1); \
+ std %r27, FRAME_27+48(%r1); \
+ std %r28, FRAME_28+48(%r1); \
+ std %r29, FRAME_29+48(%r1); \
+ std %r30, FRAME_30+48(%r1); \
+ std %r31, FRAME_31+48(%r1); \
+ ld %r28, (savearea+CPUSAVE_DAR)(%r2); /* saved DAR */ \
+ ld %r29, (savearea+CPUSAVE_DSISR)(%r2);/* saved DSISR */ \
+ ld %r30, (savearea+CPUSAVE_SRR0)(%r2); /* saved SRR0 */ \
+ ld %r31, (savearea+CPUSAVE_SRR1)(%r2); /* saved SRR1 */ \
+ mfxer %r3; \
+ mfctr %r4; \
+ mfsprg3 %r5; \
+ std %r3,FRAME_XER+48(%r1); /* save xer/ctr/exc */ \
+ std %r4,FRAME_CTR+48(%r1); \
+ std %r5,FRAME_EXC+48(%r1); \
+ std %r28, FRAME_DAR+48(%r1); \
+ std %r29, FRAME_DSISR+48(%r1); /* save dsisr/srr0/srr1 */ \
+ std %r30, FRAME_SRR0+48(%r1); \
+ std %r31, FRAME_SRR1+48(%r1);
+
+
.text
.globl trapcode, trapcodeend
@@ -55,11 +142,36 @@ trapcode:
blrl
trapcodeend:
+/*
+ * generictrap does some standard setup for trap handling to minimize
+ * the code that need be installed in the actual vectors. It expects
+ * the following conditions.
+ *
+ * R1 - Trap vector = LR & (0xff00 | R1)
+ * SPRG1 - Original R1 contents
+ * SPRG2 - Original LR
+ */
+
.globl generictrap
generictrap:
/* Save R1 for computing the exception vector */
mtsprg3 %r1
+ /* Save interesting registers */
+ GET_CPUINFO(%r1)
+ std %r27, (CI_TEMPSAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */
+ std %r28, (CI_TEMPSAVE+CPUSAVE_R28)(%r1)
+ std %r29, (CI_TEMPSAVE+CPUSAVE_R29)(%r1)
+ std %r30, (CI_TEMPSAVE+CPUSAVE_R30)(%r1)
+ std %r31, (CI_TEMPSAVE+CPUSAVE_R31)(%r1)
+ mfdar %r30
+ std %r30, (CI_TEMPSAVE+CPUSAVE_DAR)(%r1)
+ mfdsisr %r30
+ std %r30, (CI_TEMPSAVE+CPUSAVE_DSISR)(%r1)
+ mfsprg1 %r1 /* restore SP, in case of branch */
+ mfsprg2 %r28 /* save LR */
+ mfcr %r29 /* save CR */
+
/* Compute the exception vector from the link register */
mfsprg3 %r31
ori %r31, %r31, 0xff00
@@ -68,17 +180,7 @@ generictrap:
and %r30, %r30, %r31
mtsprg3 %r30
- mfsprg1 %r1
- mfmsr %r30
- ori %r30, %r30, PSL_RI@l
- mtmsr %r30
- mfsprg1 %r31
- stdu %r31, -(FRAMELEN+288)(%r1)
- std %r31, FRAME_1+48(%r1)
- mfsprg3 %r5
- std %r5, FRAME_EXC+48(%r1)
-
+ FRAME_SETUP(CI_TEMPSAVE)
GET_TOCBASE(%r2)
-
addi %r3, %r1, 48
bl trap