summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2016-01-10 16:42:14 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2016-01-10 16:42:14 +0000
commitf5d714b876f969adce2affd720c9237b29047693 (patch)
tree27594a95bb41f2c889fd13be830d29451361e818 /sys/powerpc
parentd42a26ab2089d53213cf28c22508023ea16e7efb (diff)
downloadFreeBSD-src-f5d714b876f969adce2affd720c9237b29047693.zip
FreeBSD-src-f5d714b876f969adce2affd720c9237b29047693.tar.gz
Use setjmp() instead of the identical-except-for-having-a-wrong-prototype
setfault() when testing for faults. This should also help the compiler do the right thing with this complicated-to-optimize function.
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/include/pcb.h4
-rw-r--r--sys/powerpc/include/setjmp.h4
-rw-r--r--sys/powerpc/ofw/rtas.c7
-rw-r--r--sys/powerpc/powermac/grackle.c7
-rw-r--r--sys/powerpc/powerpc/copyinout.c62
-rw-r--r--sys/powerpc/powerpc/mp_machdep.c1
-rw-r--r--sys/powerpc/powerpc/trap.c22
7 files changed, 60 insertions, 47 deletions
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 6caf5d2..094949e 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -35,7 +35,7 @@
#ifndef _MACHINE_PCB_H_
#define _MACHINE_PCB_H_
-typedef register_t faultbuf[25];
+#include <machine/setjmp.h>
struct pcb {
register_t pcb_context[20]; /* non-volatile r14-r31 */
@@ -44,7 +44,7 @@ struct pcb {
register_t pcb_toc; /* toc pointer */
register_t pcb_lr; /* link register */
struct pmap *pcb_pm; /* pmap of our vmspace */
- faultbuf *pcb_onfault; /* For use during
+ jmp_buf *pcb_onfault; /* For use during
copyin/copyout */
int pcb_flags;
#define PCB_FPU 1 /* Process uses FPU */
diff --git a/sys/powerpc/include/setjmp.h b/sys/powerpc/include/setjmp.h
index e453044..b95a111 100644
--- a/sys/powerpc/include/setjmp.h
+++ b/sys/powerpc/include/setjmp.h
@@ -8,7 +8,11 @@
#include <sys/cdefs.h>
+#ifdef _KERNEL
+#define _JBLEN 25 /* Kernel doesn't save FP and Altivec regs */
+#else
#define _JBLEN 100
+#endif
/*
* jmp_buf and sigjmp_buf are encapsulated in different structs to force
diff --git a/sys/powerpc/ofw/rtas.c b/sys/powerpc/ofw/rtas.c
index 15cb58e..5dff8ef 100644
--- a/sys/powerpc/ofw/rtas.c
+++ b/sys/powerpc/ofw/rtas.c
@@ -62,8 +62,6 @@ int rtascall(vm_offset_t callbuffer, uintptr_t rtas_privdat);
extern uintptr_t rtas_entry;
extern register_t rtasmsr;
-int setfault(faultbuf); /* defined in locore.S */
-
/*
* After the VM is up, allocate RTAS memory and instantiate it
*/
@@ -203,7 +201,7 @@ int
rtas_call_method(cell_t token, int nargs, int nreturns, ...)
{
vm_offset_t argsptr;
- faultbuf env, *oldfaultbuf;
+ jmp_buf env, *oldfaultbuf;
va_list ap;
struct {
cell_t token;
@@ -233,7 +231,8 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...)
/* Get rid of any stale machine checks that have been waiting. */
__asm __volatile ("sync; isync");
oldfaultbuf = curthread->td_pcb->pcb_onfault;
- if (!setfault(env)) {
+ curthread->td_pcb->pcb_onfault = &env;
+ if (!setjmp(env)) {
__asm __volatile ("sync");
result = rtascall(argsptr, rtas_private_data);
__asm __volatile ("sync; isync");
diff --git a/sys/powerpc/powermac/grackle.c b/sys/powerpc/powermac/grackle.c
index b4a8a3b..95d59a1 100644
--- a/sys/powerpc/powermac/grackle.c
+++ b/sys/powerpc/powermac/grackle.c
@@ -82,8 +82,6 @@ static int grackle_enable_config(struct grackle_softc *, u_int,
static void grackle_disable_config(struct grackle_softc *);
static int badaddr(void *, size_t);
-int setfault(faultbuf); /* defined in locore.S */
-
/*
* Driver methods.
*/
@@ -244,7 +242,7 @@ static int
badaddr(void *addr, size_t size)
{
struct thread *td;
- faultbuf env, *oldfaultbuf;
+ jmp_buf env, *oldfaultbuf;
int x;
/* Get rid of any stale machine checks that have been waiting. */
@@ -253,7 +251,8 @@ badaddr(void *addr, size_t size)
td = curthread;
oldfaultbuf = td->td_pcb->pcb_onfault;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = oldfaultbuf;
__asm __volatile ("sync");
return 1;
diff --git a/sys/powerpc/powerpc/copyinout.c b/sys/powerpc/powerpc/copyinout.c
index fdee51d..29c4561 100644
--- a/sys/powerpc/powerpc/copyinout.c
+++ b/sys/powerpc/powerpc/copyinout.c
@@ -71,8 +71,6 @@ __FBSDID("$FreeBSD$");
#include <machine/slb.h>
#include <machine/vmparam.h>
-int setfault(faultbuf); /* defined in locore.S */
-
#ifdef AIM
/*
* Makes sure that the right segment of userspace is mapped in.
@@ -176,7 +174,7 @@ copyout(const void *kaddr, void *udaddr, size_t len)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
const char *kp;
char *up, *p;
size_t l;
@@ -184,7 +182,8 @@ copyout(const void *kaddr, void *udaddr, size_t len)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (EFAULT);
}
@@ -214,7 +213,7 @@ copyin(const void *udaddr, void *kaddr, size_t len)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
const char *up;
char *kp, *p;
size_t l;
@@ -222,7 +221,8 @@ copyin(const void *udaddr, void *kaddr, size_t len)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (EFAULT);
}
@@ -285,13 +285,14 @@ subyte(volatile void *addr, int byte)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
char *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -313,13 +314,14 @@ suword32(volatile void *addr, int word)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
int *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -341,13 +343,14 @@ suword(volatile void *addr, long word)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
long *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -382,14 +385,15 @@ fubyte(volatile const void *addr)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
u_char *p;
int val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -410,13 +414,14 @@ fuword16(volatile const void *addr)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
uint16_t *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -437,13 +442,14 @@ fueword32(volatile const void *addr, int32_t *val)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
int32_t *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -465,13 +471,14 @@ fueword64(volatile const void *addr, int64_t *val)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
int64_t *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -493,13 +500,14 @@ fueword(volatile const void *addr, long *val)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
long *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -521,13 +529,14 @@ casueword32(volatile uint32_t *addr, uint32_t old, uint32_t *oldvalp,
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
uint32_t *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -572,13 +581,14 @@ casueword(volatile u_long *addr, u_long old, u_long *oldvalp, u_long new)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
u_long *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c
index 9d26e95..2f20b71 100644
--- a/sys/powerpc/powerpc/mp_machdep.c
+++ b/sys/powerpc/powerpc/mp_machdep.c
@@ -67,7 +67,6 @@ volatile static u_quad_t ap_timebase;
static u_int ipi_msg_cnt[32];
static struct mtx ap_boot_mtx;
struct pcb stoppcbs[MAXCPU];
-int longfault(faultbuf, int);
void
machdep_ap_bootstrap(void)
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 4c9735a..d4dac2e 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -74,11 +74,12 @@ __FBSDID("$FreeBSD$");
#include <machine/spr.h>
#include <machine/sr.h>
-#define FAULTBUF_LR 0
+/* Below matches setjmp.S */
+#define FAULTBUF_LR 21
#define FAULTBUF_R1 1
#define FAULTBUF_R2 2
-#define FAULTBUF_CR 3
-#define FAULTBUF_R13 4
+#define FAULTBUF_CR 22
+#define FAULTBUF_R14 3
static void trap_fatal(struct trapframe *frame);
static void printtrap(u_int vector, struct trapframe *frame, int isfatal,
@@ -462,18 +463,19 @@ static int
handle_onfault(struct trapframe *frame)
{
struct thread *td;
- faultbuf *fb;
+ jmp_buf *fb;
td = curthread;
fb = td->td_pcb->pcb_onfault;
if (fb != NULL) {
- frame->srr0 = (*fb)[FAULTBUF_LR];
- frame->fixreg[1] = (*fb)[FAULTBUF_R1];
- frame->fixreg[2] = (*fb)[FAULTBUF_R2];
+ frame->srr0 = (*fb)->_jb[FAULTBUF_LR];
+ frame->fixreg[1] = (*fb)->_jb[FAULTBUF_R1];
+ frame->fixreg[2] = (*fb)->_jb[FAULTBUF_R2];
frame->fixreg[3] = 1;
- frame->cr = (*fb)[FAULTBUF_CR];
- bcopy(&(*fb)[FAULTBUF_R13], &frame->fixreg[13],
- 19 * sizeof(register_t));
+ frame->cr = (*fb)->_jb[FAULTBUF_CR];
+ bcopy(&(*fb)->_jb[FAULTBUF_R14], &frame->fixreg[14],
+ 18 * sizeof(register_t));
+ td->td_pcb->pcb_onfault = NULL; /* Returns twice, not thrice */
return (1);
}
return (0);
OpenPOWER on IntegriCloud