diff options
-rw-r--r-- | sys/powerpc/ofw/rtas.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/powerpc/ofw/rtas.c b/sys/powerpc/ofw/rtas.c index 59692c9..66ce12f 100644 --- a/sys/powerpc/ofw/rtas.c +++ b/sys/powerpc/ofw/rtas.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include <sys/lock.h> #include <sys/mutex.h> #include <sys/systm.h> +#include <sys/proc.h> #include <vm/vm.h> #include <vm/vm_page.h> @@ -39,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #include <machine/md_var.h> +#include <machine/pcb.h> #include <machine/pmap.h> #include <machine/rtas.h> #include <machine/stdarg.h> @@ -60,6 +62,8 @@ 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 */ @@ -188,6 +192,7 @@ int rtas_call_method(cell_t token, int nargs, int nreturns, ...) { vm_offset_t argsptr; + faultbuf env; va_list ap; struct { cell_t token; @@ -213,7 +218,19 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...) args.args_n_results[n] = va_arg(ap, cell_t); argsptr = rtas_real_map(&args, sizeof(args)); - result = rtascall(argsptr, rtas_private_data); + + /* Get rid of any stale machine checks that have been waiting. */ + __asm __volatile ("sync; isync"); + if (!setfault(env)) { + __asm __volatile ("sync"); + result = rtascall(argsptr, rtas_private_data); + __asm __volatile ("sync; isync"); + } else { + result = RTAS_HW_ERROR; + } + curthread->td_pcb->pcb_onfault = 0; + __asm __volatile ("sync"); + rtas_real_unmap(argsptr, &args, sizeof(args)); mtx_unlock(&rtas_mtx); |