svn commit: r208118 - in projects/ppc64/sys: dev/ofw powerpc/aim powerpc/ofw

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sat May 15 20:25:30 UTC 2010


Author: nwhitehorn
Date: Sat May 15 20:25:29 2010
New Revision: 208118
URL: http://svn.freebsd.org/changeset/base/208118

Log:
  Quiesce Open Firmware before taking control of the exception vectors and
  MMU. On U4-based Apple systems, there is a firmware background process
  to manage fans while in OF. Booting the kernel without stopping it causes
  the SMU to crash, which implies no fan control and no RTC.

Modified:
  projects/ppc64/sys/dev/ofw/ofw_if.m
  projects/ppc64/sys/dev/ofw/ofw_standard.c
  projects/ppc64/sys/dev/ofw/openfirm.c
  projects/ppc64/sys/dev/ofw/openfirm.h
  projects/ppc64/sys/powerpc/aim/machdep.c
  projects/ppc64/sys/powerpc/ofw/ofw_real.c

Modified: projects/ppc64/sys/dev/ofw/ofw_if.m
==============================================================================
--- projects/ppc64/sys/dev/ofw/ofw_if.m	Sat May 15 19:46:16 2010	(r208117)
+++ projects/ppc64/sys/dev/ofw/ofw_if.m	Sat May 15 20:25:29 2010	(r208118)
@@ -340,6 +340,13 @@ METHOD void release {
 # Commands for returning control to the firmware
 
 /**
+ * @brief Turn off firmware background activities
+ */
+METHOD void quiesce {
+	ofw_t		_ofw;
+};
+
+/**
  * @brief Temporarily return control to firmware.
  */
 METHOD void enter {

Modified: projects/ppc64/sys/dev/ofw/ofw_standard.c
==============================================================================
--- projects/ppc64/sys/dev/ofw/ofw_standard.c	Sat May 15 19:46:16 2010	(r208117)
+++ projects/ppc64/sys/dev/ofw/ofw_standard.c	Sat May 15 20:25:29 2010	(r208118)
@@ -105,6 +105,7 @@ static ssize_t ofw_std_write(ofw_t ofw, 
 static int ofw_std_seek(ofw_t ofw, ihandle_t instance, uint64_t pos);
 static caddr_t ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align);
 static void ofw_std_release(ofw_t ofw, void *virt, size_t size);
+static void ofw_std_quiesce(ofw_t ofw);
 static void ofw_std_enter(ofw_t ofw);
 static void ofw_std_exit(ofw_t ofw);
 
@@ -133,6 +134,7 @@ static ofw_method_t ofw_std_methods[] = 
 	OFWMETHOD(ofw_seek,			ofw_std_seek),
 	OFWMETHOD(ofw_claim,			ofw_std_claim),
 	OFWMETHOD(ofw_release,			ofw_std_release),
+	OFWMETHOD(ofw_quiesce,			ofw_std_quiesce),
 	OFWMETHOD(ofw_enter,			ofw_std_enter),
 	OFWMETHOD(ofw_exit,			ofw_std_exit),
 
@@ -729,6 +731,23 @@ ofw_std_release(ofw_t ofw, void *virt, s
  * Control transfer functions
  */
 
+/* Turn off OF background tasks */
+static void
+ofw_std_quiesce(ofw_t ofw)
+{
+	struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+	} args = {
+		(cell_t)"quiesce",
+		0,
+		0,
+	};
+
+	openfirmware(&args);
+}
+
 /* Suspend and drop back to the Open Firmware interface. */
 static void
 ofw_std_enter(ofw_t ofw)

Modified: projects/ppc64/sys/dev/ofw/openfirm.c
==============================================================================
--- projects/ppc64/sys/dev/ofw/openfirm.c	Sat May 15 19:46:16 2010	(r208117)
+++ projects/ppc64/sys/dev/ofw/openfirm.c	Sat May 15 20:25:29 2010	(r208118)
@@ -409,6 +409,15 @@ OF_release(void *virt, size_t size)
  * Control transfer functions
  */
 
+/* Turn off OF background tasks */
+void
+OF_quiesce()
+{
+
+	OFW_QUIESCE(ofw_obj);
+}
+
+
 /* Suspend and drop back to the Open Firmware interface. */
 void
 OF_enter()

Modified: projects/ppc64/sys/dev/ofw/openfirm.h
==============================================================================
--- projects/ppc64/sys/dev/ofw/openfirm.h	Sat May 15 19:46:16 2010	(r208117)
+++ projects/ppc64/sys/dev/ofw/openfirm.h	Sat May 15 20:25:29 2010	(r208118)
@@ -134,6 +134,7 @@ void		*OF_claim(void *virtrequest, size_
 void		OF_release(void *virt, size_t size);
 
 /* Control transfer functions */
+void		OF_quiesce(void);
 void		OF_enter(void);
 void		OF_exit(void) __attribute__((noreturn));
 

Modified: projects/ppc64/sys/powerpc/aim/machdep.c
==============================================================================
--- projects/ppc64/sys/powerpc/aim/machdep.c	Sat May 15 19:46:16 2010	(r208117)
+++ projects/ppc64/sys/powerpc/aim/machdep.c	Sat May 15 20:25:29 2010	(r208118)
@@ -213,10 +213,11 @@ cpu_startup(void *dummy)
 
 		printf("Physical memory chunk(s):\n");
 		for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
-			int size1 = phys_avail[indx + 1] - phys_avail[indx];
+			vm_offset_t size1 =
+			    phys_avail[indx + 1] - phys_avail[indx];
 
 			#ifdef __powerpc64__
-			printf("0x%16lx - 0x%16lx, %d bytes (%ld pages)\n",
+			printf("0x%16lx - 0x%16lx, %ld bytes (%ld pages)\n",
 			#else
 			printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n",
 			#endif
@@ -260,6 +261,8 @@ extern void	*decrint, *decrsize;
 extern void     *extint, *extsize;
 extern void	*dblow, *dbsize;
 
+void ofw_real_quiesce(void);
+
 uintptr_t
 powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
     vm_offset_t basekernel, void *mdp)
@@ -327,10 +330,11 @@ powerpc_init(vm_offset_t startkernel, vm
 	mutex_init();
 
 	/*
-	 * Install the OF client interface
+	 * Install the OF client interface and then take over the machine
 	 */
 
 	OF_bootstrap();
+	OF_quiesce();
 
 	/*
 	 * Initialize the console before printing anything.

Modified: projects/ppc64/sys/powerpc/ofw/ofw_real.c
==============================================================================
--- projects/ppc64/sys/powerpc/ofw/ofw_real.c	Sat May 15 19:46:16 2010	(r208117)
+++ projects/ppc64/sys/powerpc/ofw/ofw_real.c	Sat May 15 20:25:29 2010	(r208118)
@@ -110,6 +110,7 @@ static ssize_t ofw_real_write(ofw_t, iha
 static int ofw_real_seek(ofw_t, ihandle_t instance, u_int64_t pos);
 static caddr_t ofw_real_claim(ofw_t, void *virt, size_t size, u_int align);
 static void ofw_real_release(ofw_t, void *virt, size_t size);
+static void ofw_real_quiesce(ofw_t);
 static void ofw_real_enter(ofw_t);
 static void ofw_real_exit(ofw_t);
 
@@ -138,6 +139,7 @@ static ofw_method_t ofw_real_methods[] =
 	OFWMETHOD(ofw_seek,			ofw_real_seek),
 	OFWMETHOD(ofw_claim,			ofw_real_claim),
 	OFWMETHOD(ofw_release,			ofw_real_release),
+	OFWMETHOD(ofw_quiesce,			ofw_real_quiesce),
 	OFWMETHOD(ofw_enter,			ofw_real_enter),
 	OFWMETHOD(ofw_exit,			ofw_real_exit),
 
@@ -1048,6 +1050,27 @@ ofw_real_release(ofw_t ofw, void *virt, 
  * Control transfer functions
  */
 
+/* Turn off OF background tasks */
+static void
+ofw_real_quiesce(ofw_t ofw)
+{
+	vm_offset_t argsptr;
+	struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+	} args;
+
+	args.name = (cell_t)(uintptr_t)"quiesce";
+	args.nargs = 0;
+	args.nreturns = 0;
+
+	ofw_real_start();
+	argsptr = ofw_real_map(&args, sizeof(args));
+	openfirmware((void *)argsptr);
+	ofw_real_stop();
+}
+
 /* Suspend and drop back to the Open Firmware interface. */
 static void
 ofw_real_enter(ofw_t ofw)


More information about the svn-src-projects mailing list