summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorgkoehler <gkoehler@cvs.openbsd.org>2020-04-02 19:27:52 +0000
committergkoehler <gkoehler@cvs.openbsd.org>2020-04-02 19:27:52 +0000
commite938cf4d986f5223c38e7a0b1277de3cbecf3510 (patch)
treea72ea3555a46a33a4feec2db52afcec08c5bc6e2 /sys/arch
parentedc1550759d95ccd1f83f7790a8946d0eacc8456 (diff)
Make the OpenFirmware functions work with clang.
ofw_stack() was changing its caller's stack frame, but this stops working when clang inlines the caller into another function. Move the stack-switching logic into openfirmware(). Now ofw_stack() becomes ofw_msr() and only sets the msr. ok deraadt@ kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/macppc/macppc/ofw_machdep.h14
-rw-r--r--sys/arch/macppc/macppc/ofwreal.S98
-rw-r--r--sys/arch/macppc/macppc/opendev.c138
-rw-r--r--sys/arch/macppc/macppc/openfirm.c132
4 files changed, 212 insertions, 170 deletions
diff --git a/sys/arch/macppc/macppc/ofw_machdep.h b/sys/arch/macppc/macppc/ofw_machdep.h
index 270aed5a525..1a62f71470c 100644
--- a/sys/arch/macppc/macppc/ofw_machdep.h
+++ b/sys/arch/macppc/macppc/ofw_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofw_machdep.h,v 1.9 2015/04/07 14:36:34 mpi Exp $ */
+/* $OpenBSD: ofw_machdep.h,v 1.10 2020/04/02 19:27:51 gkoehler Exp $ */
/*
* Copyright (c) 2002, Miodrag Vallat.
@@ -26,6 +26,9 @@
*
*/
+#include <machine/cpu.h>
+#include <machine/psl.h>
+
extern int cons_backlight_available;
void ofwconprobe(void);
@@ -49,3 +52,12 @@ void of_setbrightness(int);
void of_setcolors(const uint8_t *, unsigned int, unsigned int);
void OF_quiesce(void);
+
+static inline uint32_t
+ofw_msr(void)
+{
+ uint32_t s = ppc_mfmsr();
+
+ ppc_mtmsr(s & ~(PSL_EE|PSL_RI)); /* turn off interrupts */
+ return s;
+}
diff --git a/sys/arch/macppc/macppc/ofwreal.S b/sys/arch/macppc/macppc/ofwreal.S
index 72418c797d0..61d703b23c3 100644
--- a/sys/arch/macppc/macppc/ofwreal.S
+++ b/sys/arch/macppc/macppc/ofwreal.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofwreal.S,v 1.5 2019/09/03 14:37:22 deraadt Exp $ */
+/* $OpenBSD: ofwreal.S,v 1.6 2020/04/02 19:27:51 gkoehler Exp $ */
/* $NetBSD: ofwreal.S,v 1.1 1996/09/30 16:34:51 ws Exp $ */
/*
@@ -355,96 +355,32 @@ _ENTRY(_C_LABEL(fwentry))
addi %r1,%r1,16
blr
+.lcomm firmstk,NBPG,16
+.comm _C_LABEL(OF_buf),NBPG
+
/*
* OpenFirmware entry point
+ *
+ * Note: caller has to set the machine state register (msr)
+ * to be correct for OpenFirmware.
*/
_ENTRY(_C_LABEL(openfirmware))
- stwu %r1,-16(%r1)
- mflr %r0 /* save return address */
- stw %r0,20(%r1)
+ mflr %r0
+ stw %r0,4(%r1) /* save return address */
+
+ /* switch to OpenFirmware real mode stack */
+ lis %r7,firmstk+NBPG-16@ha
+ addi %r7,%r7,firmstk+NBPG-16@l
+ stw %r1,0(%r7)
+ mr %r1,%r7
lis %r4,fwcall@ha
lwz %r4,fwcall@l(%r4)
- mtlr %r4
- blrl
-
- lwz %r0,20(%r1)
- mtlr %r0
- lwz %r1,0(%r1)
- 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;
- * }
- */
-.lcomm firmstk,NBPG,16
-.comm _C_LABEL(OF_buf),NBPG
-
-_ENTRY(_C_LABEL(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
- li %r6,0xf
- andc %r7,%r7,%r6
- lis %r6,ofw_back@ha
- addi %r6,%r6,ofw_back@l
- subf %r4,%r5,%r7 /* make room for stack frame on new stack */
- stwu %r1,-16(%r7)
- stw %r6,4(%r7) /* setup return pointer */
+ mtctr %r4
+ bctrl
- stw %r7,-16(%r4)
-
- addi %r3,%r1,%r8
- addi %r1,%r4,-16
- subi %r5,%r5,%r8
- subi %r4,%r4,%r8
-
- b _C_LABEL(ofbcopy) /* and copy it */
-
- .type ofw_back,@function
-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 --git a/sys/arch/macppc/macppc/opendev.c b/sys/arch/macppc/macppc/opendev.c
index 9394ac2fd12..f05aa76580e 100644
--- a/sys/arch/macppc/macppc/opendev.c
+++ b/sys/arch/macppc/macppc/opendev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: opendev.c,v 1.9 2006/03/09 23:06:19 miod Exp $ */
+/* $OpenBSD: opendev.c,v 1.10 2020/04/02 19:27:51 gkoehler Exp $ */
/* $NetBSD: openfirm.c,v 1.1 1996/09/30 16:34:52 ws Exp $ */
/*
@@ -34,11 +34,12 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/stdarg.h>
+#include <machine/cpu.h>
#include <machine/psl.h>
#include <dev/ofw/openfirm.h>
+#include "ofw_machdep.h"
-extern void ofw_stack(void);
extern void ofbcopy(const void *, void *, size_t);
int
@@ -55,12 +56,17 @@ OF_instance_to_package(int ihandle)
1,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.ihandle = ihandle;
if (openfirmware(&args) == -1)
- return -1;
- return args.phandle;
+ ret = -1;
+ else
+ ret = args.phandle;
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -79,18 +85,24 @@ OF_package_to_path(int phandle, char *buf, int buflen)
3,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
if (buflen > PAGE_SIZE)
return -1;
+ s = ofw_msr();
args.phandle = phandle;
args.buf = OF_buf;
args.buflen = buflen;
if (openfirmware(&args) < 0)
- return -1;
- if (args.length > 0)
- ofbcopy(OF_buf, buf, args.length);
- return args.length;
+ ret = -1;
+ else {
+ if (args.length > 0)
+ ofbcopy(OF_buf, buf, args.length);
+ ret = args.length;
+ }
+ ppc_mtmsr(s);
+ return ret;
}
@@ -110,10 +122,12 @@ OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...)
2,
1,
};
- int *ip, n;
+ uint32_t s;
+ int *ip, n, ret;
if (nargs > 6)
return -1;
+ s = ofw_msr();
args.nargs = nargs + 2;
args.nreturns = nreturns + 1;
args.method = method;
@@ -121,19 +135,19 @@ OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...)
va_start(ap, nreturns);
for (ip = args.args_n_results + (n = nargs); --n >= 0;)
*--ip = va_arg(ap, int);
- ofw_stack();
- if (openfirmware(&args) == -1) {
- va_end(ap);
- return -1;
- }
- if (args.args_n_results[nargs]) {
- va_end(ap);
- return args.args_n_results[nargs];
+ if (openfirmware(&args) == -1)
+ ret = -1;
+ else if (args.args_n_results[nargs])
+ ret = args.args_n_results[nargs];
+ else {
+ for (ip = args.args_n_results + nargs + (n = args.nreturns);
+ --n > 0;)
+ *va_arg(ap, int *) = *--ip;
+ ret = 0;
}
- for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
- *va_arg(ap, int *) = *--ip;
va_end(ap);
- return 0;
+ ppc_mtmsr(s);
+ return ret;
}
int
OF_call_method_1(char *method, int ihandle, int nargs, ...)
@@ -151,10 +165,12 @@ OF_call_method_1(char *method, int ihandle, int nargs, ...)
2,
2,
};
- int *ip, n;
+ uint32_t s;
+ int *ip, n, ret;
if (nargs > 6)
return -1;
+ s = ofw_msr();
args.nargs = nargs + 2;
args.method = method;
args.ihandle = ihandle;
@@ -162,12 +178,14 @@ OF_call_method_1(char *method, int ihandle, int nargs, ...)
for (ip = args.args_n_results + (n = nargs); --n >= 0;)
*--ip = va_arg(ap, int);
va_end(ap);
- ofw_stack();
if (openfirmware(&args) == -1)
- return -1;
- if (args.args_n_results[nargs])
- return -1;
- return args.args_n_results[nargs + 1];
+ ret = -1;
+ else if (args.args_n_results[nargs])
+ ret = -1;
+ else
+ ret = args.args_n_results[nargs + 1];
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -184,16 +202,20 @@ OF_open(char *dname)
1,
1,
};
- int l;
+ uint32_t s;
+ int l, ret;
- ofw_stack();
if ((l = strlen(dname)) >= PAGE_SIZE)
return -1;
+ s = ofw_msr();
ofbcopy(dname, OF_buf, l + 1);
args.dname = OF_buf;
if (openfirmware(&args) == -1)
- return -1;
- return args.handle;
+ ret = -1;
+ else
+ ret = args.handle;
+ ppc_mtmsr(s);
+ return ret;
}
void
@@ -209,10 +231,12 @@ OF_close(int handle)
1,
0,
};
+ uint32_t s;
- ofw_stack();
+ s = ofw_msr();
args.handle = handle;
openfirmware(&args);
+ ppc_mtmsr(s);
}
/*
@@ -234,28 +258,35 @@ OF_read(int handle, void *addr, int len)
3,
1,
};
- int l, act = 0;
+ uint32_t s;
+ int act = 0, l, ret;
- ofw_stack();
+ s = ofw_msr();
args.ihandle = handle;
args.addr = OF_buf;
for (; len > 0; len -= l, addr += l) {
l = min(PAGE_SIZE, len);
args.len = l;
- if (openfirmware(&args) == -1)
- return -1;
+ if (openfirmware(&args) == -1) {
+ ret = -1;
+ goto out;
+ }
if (args.actual > 0) {
ofbcopy(OF_buf, addr, args.actual);
act += args.actual;
}
if (args.actual < l) {
if (act)
- return act;
+ ret = act;
else
- return args.actual;
+ ret = args.actual;
+ goto out;
}
}
- return act;
+ ret = act;
+out:
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -274,21 +305,27 @@ OF_write(int handle, void *addr, int len)
3,
1,
};
- int l, act = 0;
+ uint32_t s;
+ int act = 0, l, ret;
- ofw_stack();
+ s = ofw_msr();
args.ihandle = handle;
args.addr = OF_buf;
for (; len > 0; len -= l, addr += l) {
l = min(PAGE_SIZE, len);
ofbcopy(addr, OF_buf, l);
args.len = l;
- if (openfirmware(&args) == -1)
- return -1;
+ if (openfirmware(&args) == -1) {
+ ret = -1;
+ goto out;
+ }
l = args.actual;
act += l;
}
- return act;
+ ret = act;
+out:
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -307,12 +344,17 @@ OF_seek(int handle, u_quad_t pos)
3,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.handle = handle;
args.poshi = (int)(pos >> 32);
args.poslo = (int)pos;
if (openfirmware(&args) == -1)
- return -1;
- return args.status;
+ ret = -1;
+ else
+ ret = args.status;
+ ppc_mtmsr(s);
+ return ret;
}
diff --git a/sys/arch/macppc/macppc/openfirm.c b/sys/arch/macppc/macppc/openfirm.c
index f891aa4c10a..c78aad87ca6 100644
--- a/sys/arch/macppc/macppc/openfirm.c
+++ b/sys/arch/macppc/macppc/openfirm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: openfirm.c,v 1.12 2019/09/03 17:51:52 deraadt Exp $ */
+/* $OpenBSD: openfirm.c,v 1.13 2020/04/02 19:27:51 gkoehler Exp $ */
/* $NetBSD: openfirm.c,v 1.1 1996/09/30 16:34:52 ws Exp $ */
/*
@@ -34,11 +34,12 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/stdarg.h>
+#include <machine/cpu.h>
#include <machine/psl.h>
#include <dev/ofw/openfirm.h>
+#include "ofw_machdep.h"
-extern void ofw_stack(void);
extern void ofbcopy(const void *, void *, size_t);
int
@@ -55,12 +56,17 @@ OF_peer(int phandle)
1,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.phandle = phandle;
if (openfirmware(&args) == -1)
- return 0;
- return args.sibling;
+ ret = 0;
+ else
+ ret = args.sibling;
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -77,12 +83,17 @@ OF_child(int phandle)
1,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.phandle = phandle;
if (openfirmware(&args) == -1)
- return 0;
- return args.child;
+ ret = 0;
+ else
+ ret = args.child;
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -99,12 +110,17 @@ OF_parent(int phandle)
1,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.phandle = phandle;
if (openfirmware(&args) == -1)
- return 0;
- return args.parent;
+ ret = 0;
+ else
+ ret = args.parent;
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -122,13 +138,18 @@ OF_getproplen(int handle, char *prop)
2,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.phandle = handle;
args.prop = prop;
if (openfirmware(&args) == -1)
- return -1;
- return args.size;
+ ret = -1;
+ else
+ ret = args.size;
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -148,19 +169,25 @@ OF_getprop(int handle, char *prop, void *buf, int buflen)
4,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
if (buflen > NBPG)
return -1;
+ s = ofw_msr();
args.phandle = handle;
args.prop = prop;
args.buf = OF_buf;
args.buflen = buflen;
if (openfirmware(&args) == -1)
- return -1;
- if (args.size > 0)
- ofbcopy(OF_buf, buf, args.size);
- return args.size;
+ ret = -1;
+ else {
+ if (args.size > 0)
+ ofbcopy(OF_buf, buf, args.size);
+ ret = args.size;
+ }
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -180,18 +207,23 @@ OF_setprop(int handle, char *prop, const void *buf, int buflen)
4,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
if (buflen > NBPG)
return -1;
+ s = ofw_msr();
args.phandle = handle;
args.prop = prop;
ofbcopy(buf, OF_buf, buflen);
args.buf = OF_buf;
args.buflen = buflen;
if (openfirmware(&args) == -1)
- return -1;
- return args.size;
+ ret = -1;
+ else
+ ret = args.size;
+ ppc_mtmsr(s);
+ return ret;
}
int
@@ -210,22 +242,27 @@ OF_nextprop(int handle, char *prop, void *nextprop)
3,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.phandle = handle;
args.prop = prop;
args.buf = OF_buf;
if (openfirmware(&args) == -1)
- return -1;
- strlcpy(nextprop, OF_buf, 32);
- return args.flag;
+ ret = -1;
+ else {
+ strlcpy(nextprop, OF_buf, 32);
+ ret = args.flag;
+ }
+ ppc_mtmsr(s);
+ return ret;
}
int
OF_interpret(char *cmd, int nreturns, ...)
{
va_list ap;
- int i;
static struct {
char *name;
int nargs;
@@ -238,23 +275,29 @@ OF_interpret(char *cmd, int nreturns, ...)
1,
2,
};
+ uint32_t s;
+ int i, ret;
- ofw_stack();
if (nreturns > 8)
return -1;
if ((i = strlen(cmd)) >= NBPG)
return -1;
+ s = ofw_msr();
ofbcopy(cmd, OF_buf, i + 1);
args.cmd = OF_buf;
args.nargs = 1;
args.nreturns = nreturns + 1;
if (openfirmware(&args) == -1)
- return -1;
- va_start(ap, nreturns);
- for (i = 0; i < nreturns; i++)
- *va_arg(ap, int *) = args.results[i];
- va_end(ap);
- return args.status;
+ ret = -1;
+ else {
+ va_start(ap, nreturns);
+ for (i = 0; i < nreturns; i++)
+ *va_arg(ap, int *) = args.results[i];
+ va_end(ap);
+ ret = args.status;
+ }
+ ppc_mtmsr(s);
+ return ret;
}
@@ -272,12 +315,17 @@ OF_finddevice(char *name)
1,
1,
};
+ uint32_t s;
+ int ret;
- ofw_stack();
+ s = ofw_msr();
args.device = name;
if (openfirmware(&args) == -1)
- return -1;
- return args.phandle;
+ ret = -1;
+ else
+ ret = args.phandle;
+ ppc_mtmsr(s);
+ return ret;
}
static void OF_rboot(char *bootspec);
@@ -293,12 +341,14 @@ OF_rboot(char *bootspec)
0,
0,
};
+ uint32_t s;
int l;
if ((l = strlen(bootspec)) >= NBPG)
panic("OF_boot");
- ofw_stack();
+ s = ofw_msr();
openfirmware(&args);
+ ppc_mtmsr(s);
/* will attempt exit in OF_boot */
}
@@ -325,7 +375,7 @@ OF_exit(void)
0,
};
- ofw_stack();
+ ofw_msr();
openfirmware(&args);
panic ("OF_exit returned!"); /* just in case */
while (1);
@@ -343,9 +393,11 @@ OF_quiesce(void)
0,
0,
};
+ uint32_t s;
- ofw_stack();
+ s = ofw_msr();
openfirmware(&args);
+ ppc_mtmsr(s);
}
/* XXX What is the reason to have this instead of bcopy/memcpy? */