svn commit: r223571 - head/sys/powerpc/ofw

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Jun 26 16:11:36 UTC 2011


Author: nwhitehorn
Date: Sun Jun 26 16:11:36 2011
New Revision: 223571
URL: http://svn.freebsd.org/changeset/base/223571

Log:
  Add better error handling for RTAS calls. These can potentially cause
  machine checks (e.g. invalid PCI configuration cycles), but these can
  be caught and recovered from. This change also the RTAS PCI driver to
  work without modification as a replacement for the Grackle driver on
  Grackle-based Powermacs.

Modified:
  head/sys/powerpc/ofw/rtas.c

Modified: head/sys/powerpc/ofw/rtas.c
==============================================================================
--- head/sys/powerpc/ofw/rtas.c	Sun Jun 26 15:08:14 2011	(r223570)
+++ head/sys/powerpc/ofw/rtas.c	Sun Jun 26 16:11:36 2011	(r223571)
@@ -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, uin
 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
 		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);
 


More information about the svn-src-head mailing list