Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc - Don't change to the OFW stack in C code; ...
details: https://anonhg.NetBSD.org/src/rev/4dbcac687eb7
branches: trunk
changeset: 952320:4dbcac687eb7
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat Feb 13 01:48:33 2021 +0000
description:
- Don't change to the OFW stack in C code; instead, switch to the OFW
stack in the openfirmware() wrapper itself. Inspired by a similar
change in OpenBSD designed to appease clang.
- The OF_*() entry firmware interfaces use several global resources;
protect those global resources with a __cpu_simple_lock_t.
- Make ofbcopy() static -- it's no longer referenced outside openfirm.c
diffstat:
sys/arch/powerpc/oea/ofw_subr.S | 91 +------
sys/arch/powerpc/powerpc/openfirm.c | 405 ++++++++++++++++++++++++++---------
2 files changed, 309 insertions(+), 187 deletions(-)
diffs (truncated from 870 to 300 lines):
diff -r f2109d00e4c8 -r 4dbcac687eb7 sys/arch/powerpc/oea/ofw_subr.S
--- a/sys/arch/powerpc/oea/ofw_subr.S Sat Feb 13 01:11:58 2021 +0000
+++ b/sys/arch/powerpc/oea/ofw_subr.S Sat Feb 13 01:48:33 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ofw_subr.S,v 1.12 2020/07/06 10:31:23 rin Exp $ */
+/* $NetBSD: ofw_subr.S,v 1.13 2021/02/13 01:48:33 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -103,9 +103,18 @@
*/
.text
ENTRY(openfirmware)
- mflr %r0 /* save return address */
- stw %r0,4(%r1)
- stwu %r1,-32(%r1) /* setup stack frame */
+ mflr %r0
+ stw %r0,4(%r1) /* save return address */
+
+ /*
+ * Switch to OpenFirmware stack.
+ *
+ * -48 == -16 to stack old SP and align, -32 for save area
+ */
+ lis %r7,firmstk+NBPG-48@ha
+ addi %r7,%r7,firmstk+NBPG-48@l
+ stw %r1,32(%r7) /* stash away prev stack pointer */
+ mr %r1,%r7
lis %r4,openfirmware_entry@ha /* get firmware entry point */
lwz %r4,openfirmware_entry@l(%r4)
@@ -202,77 +211,7 @@
lwz %r5,28(%r1)
mtsprg3 %r5
- lwz %r1,0(%r1) /* and return */
- lwz %r0,4(%r1)
+ lwz %r1,32(%r1) /* restore previous stack pointer */
+ lwz %r0,4(%r1) /* return address */
mtlr %r0
blr
-
-/*
- * Switch to/from OpenFirmware real mode stack
- *
- * Note: has to be called as the very first thing in OpenFirmware interface
- * routines.
- * E.g.:
- * int
- * OF_xxx(arg1, arg2)
- * type arg1, arg2;
- * {
- * static struct {
- * char *name;
- * int nargs;
- * int nreturns;
- * char *method;
- * int arg1;
- * int arg2;
- * int ret;
- * } args = {
- * "xxx",
- * 2,
- * 1,
- * };
- *
- * ofw_stack();
- * args.arg1 = arg1;
- * args.arg2 = arg2;
- * if (openfirmware(&args) < 0)
- * return -1;
- * return args.ret;
- * }
- */
-
-ENTRY(ofw_stack)
- mfmsr %r8 /* turn off interrupts */
- andi. %r0,%r8,~(PSL_EE|PSL_RI)@l
- mtmsr %r0
- stw %r8,4(%r1) /* abuse return address slot */
-
- lwz %r5,0(%r1) /* get length of stack frame */
- subf %r5,%r1,%r5
-
- lis %r7,firmstk+NBPG-8@ha
- addi %r7,%r7,firmstk+NBPG-8@l
- lis %r6,ofw_back@ha
- addi %r6,%r6,ofw_back@l
- subf %r4,%r5,%r7 /* make room for stack frame on
- new stack */
- stw %r6,-4(%r7) /* setup return pointer */
- stwu %r1,-8(%r7)
-
- stw %r7,-8(%r4)
-
- addi %r3,%r1,8
- addi %r1,%r4,-8
- subi %r5,%r5,8
-
- b _C_LABEL(ofbcopy) /* and copy it */
-
-ofw_back:
- lwz %r1,0(%r1) /* get callers original stack pointer */
-
- lwz %r0,4(%r1) /* get saved msr from abused slot */
- mtmsr %r0
-
- lwz %r1,0(%r1) /* return */
- lwz %r0,4(%r1)
- mtlr %r0
- blr
diff -r f2109d00e4c8 -r 4dbcac687eb7 sys/arch/powerpc/powerpc/openfirm.c
--- a/sys/arch/powerpc/powerpc/openfirm.c Sat Feb 13 01:11:58 2021 +0000
+++ b/sys/arch/powerpc/powerpc/openfirm.c Sat Feb 13 01:48:33 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: openfirm.c,v 1.32 2021/02/05 00:06:11 thorpej Exp $ */
+/* $NetBSD: openfirm.c,v 1.33 2021/02/13 01:48:33 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.32 2021/02/05 00:06:11 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: openfirm.c,v 1.33 2021/02/13 01:48:33 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_multiprocessor.h"
@@ -50,11 +50,37 @@
char *OF_buf;
-void ofw_stack(void);
-void ofbcopy(const void *, void *, size_t);
+static void ofbcopy(const void *, void *, size_t);
+
#ifdef MULTIPROCESSOR
void OF_start_cpu(int, u_int, int);
-#endif
+
+
+static __cpu_simple_lock_t ofw_mutex = __SIMPLELOCK_UNLOCKED;
+#endif /* MULTIPROCESSOR */
+
+static inline register_t
+ofw_lock(void)
+{
+ const register_t s = mfmsr();
+
+ mtmsr(s & ~(PSL_EE|PSL_RI)); /* disable interrupts */
+
+#ifdef MULTIPROCESSOR
+ __cpu_simple_lock(&ofw_mutex);
+#endif /* MULTIPROCESSOR */
+
+ return s;
+}
+
+static inline void
+ofw_unlock(register_t s)
+{
+#ifdef MULTIPROCESSOR
+ __cpu_simple_unlock(&ofw_mutex);
+#endif /* MULTIPROCESSOR */
+ mtmsr(s);
+}
int
OF_peer(int phandle)
@@ -71,11 +97,17 @@
1,
};
- ofw_stack();
+ const register_t s = ofw_lock();
+ int rv;
+
args.phandle = phandle;
if (openfirmware(&args) == -1)
- return 0;
- return args.sibling;
+ rv = 0;
+ else
+ rv = args.sibling;
+
+ ofw_unlock(s);
+ return rv;
}
int
@@ -93,11 +125,17 @@
1,
};
- ofw_stack();
+ const register_t s = ofw_lock();
+ int rv;
+
args.phandle = phandle;
if (openfirmware(&args) == -1)
- return 0;
- return args.child;
+ rv = 0;
+ else
+ rv = args.child;
+
+ ofw_unlock(s);
+ return rv;
}
int
@@ -115,11 +153,17 @@
1,
};
- ofw_stack();
+ const register_t s = ofw_lock();
+ int rv;
+
args.phandle = phandle;
if (openfirmware(&args) == -1)
- return 0;
- return args.parent;
+ rv = 0;
+ else
+ rv = args.parent;
+
+ ofw_unlock(s);
+ return rv;
}
int
@@ -137,11 +181,17 @@
1,
};
- ofw_stack();
+ const register_t s = ofw_lock();
+ int rv;
+
args.ihandle = ihandle;
if (openfirmware(&args) == -1)
- return -1;
- return args.phandle;
+ rv = -1;
+ else
+ rv = args.phandle;
+
+ ofw_unlock(s);
+ return rv;
}
int
@@ -160,13 +210,19 @@
1,
};
- ofw_stack();
+ const register_t s = ofw_lock();
+ int rv;
+
strncpy(OF_buf, prop, 32);
args.phandle = handle;
args.prop = OF_buf;
if (openfirmware(&args) == -1)
- return -1;
- return args.proplen;
+ rv = -1;
+ else
+ rv = args.proplen;
+
+ ofw_unlock(s);
+ return rv;
}
int
@@ -187,21 +243,29 @@
1,
};
- ofw_stack();
if (buflen > PAGE_SIZE)
return -1;
+
+ const register_t s = ofw_lock();
+ int rv;
+
strncpy(OF_buf, prop, 32);
args.phandle = handle;
args.prop = OF_buf;
args.buf = &OF_buf[33];
args.buflen = buflen;
if (openfirmware(&args) == -1)
- return -1;
- if (args.size > buflen)
- args.size = buflen;
- if (args.size > 0)
- ofbcopy(&OF_buf[33], buf, args.size);
- return args.size;
Home |
Main Index |
Thread Index |
Old Index