summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2013-09-27 13:12:47 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2013-09-27 13:12:47 +0000
commitb4b3864eb0bde04901e921f56a4c88a4884b882f (patch)
tree87940e9ff38421a0b307f5dd3cda5673012b8ada
parent40809f1aaf52ffccc4f55985e5f79ecec25ea4b9 (diff)
downloadFreeBSD-src-b4b3864eb0bde04901e921f56a4c88a4884b882f.zip
FreeBSD-src-b4b3864eb0bde04901e921f56a4c88a4884b882f.tar.gz
Rework handling of ofw_quiesce(), making it the responsibility of the
platform modules. Whether to call this function or not is highly machine dependent: on some systems, it is required, while on others it breaks everything. Platform modules are in a better position to figure this out. This is required for POWER hypervisor SCSI to work correctly. There are no functional changes on Powermac systems. Approved by: re (kib)
-rw-r--r--sys/powerpc/include/ofw_machdep.h1
-rw-r--r--sys/powerpc/ofw/ofw_machdep.c35
-rw-r--r--sys/powerpc/powermac/platform_powermac.c31
-rw-r--r--sys/powerpc/pseries/platform_chrp.c3
4 files changed, 41 insertions, 29 deletions
diff --git a/sys/powerpc/include/ofw_machdep.h b/sys/powerpc/include/ofw_machdep.h
index 612b45b..b85ebe1 100644
--- a/sys/powerpc/include/ofw_machdep.h
+++ b/sys/powerpc/include/ofw_machdep.h
@@ -46,5 +46,6 @@ boolean_t OF_bootstrap(void);
void OF_reboot(void);
void ofw_mem_regions(struct mem_region **, int *, struct mem_region **, int *);
+void ofw_quiesce(void); /* Must be called before VM is up! */
#endif /* _MACHINE_OFW_MACHDEP_H_ */
diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c
index 24aa24e..92470f0 100644
--- a/sys/powerpc/ofw/ofw_machdep.c
+++ b/sys/powerpc/ofw/ofw_machdep.c
@@ -69,7 +69,6 @@ static void *fdt;
int ofw_real_mode;
int ofwcall(void *);
-static void ofw_quiesce(void);
static int openfirmware(void *args);
/*
@@ -472,12 +471,6 @@ OF_bootstrap()
return status;
OF_init(openfirmware);
-
- /*
- * On some machines, we need to quiesce OF to turn off
- * background processes.
- */
- ofw_quiesce();
} else if (fdt != NULL) {
status = OF_install(OFW_FDT, 0);
@@ -490,37 +483,21 @@ OF_bootstrap()
return (status);
}
-static void
+void
ofw_quiesce(void)
{
- phandle_t rootnode;
- char model[32];
struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
} args;
- /*
- * Only quiesce Open Firmware on PowerMac11,2 and 12,1. It is
- * necessary there to shut down a background thread doing fan
- * management, and is harmful on other machines.
- *
- * Note: we don't need to worry about which OF module we are
- * using since this is called only from very early boot, within
- * OF's boot context.
- */
+ KASSERT(!pmap_bootstrapped, ("Cannot call ofw_quiesce after VM is up"));
- rootnode = OF_finddevice("/");
- if (OF_getprop(rootnode, "model", model, sizeof(model)) > 0) {
- if (strcmp(model, "PowerMac11,2") == 0 ||
- strcmp(model, "PowerMac12,1") == 0) {
- args.name = (cell_t)(uintptr_t)"quiesce";
- args.nargs = 0;
- args.nreturns = 0;
- openfirmware(&args);
- }
- }
+ args.name = (cell_t)(uintptr_t)"quiesce";
+ args.nargs = 0;
+ args.nreturns = 0;
+ openfirmware(&args);
}
static int
diff --git a/sys/powerpc/powermac/platform_powermac.c b/sys/powerpc/powermac/platform_powermac.c
index e21a48c..1954ae9 100644
--- a/sys/powerpc/powermac/platform_powermac.c
+++ b/sys/powerpc/powermac/platform_powermac.c
@@ -56,6 +56,7 @@ extern void *ap_pcpu;
#endif
static int powermac_probe(platform_t);
+static int powermac_attach(platform_t);
void powermac_mem_regions(platform_t, struct mem_region **phys, int *physsz,
struct mem_region **avail, int *availsz);
static u_long powermac_timebase_freq(platform_t, struct cpuref *cpuref);
@@ -67,6 +68,7 @@ static void powermac_reset(platform_t);
static platform_method_t powermac_methods[] = {
PLATFORMMETHOD(platform_probe, powermac_probe),
+ PLATFORMMETHOD(platform_attach, powermac_attach),
PLATFORMMETHOD(platform_mem_regions, powermac_mem_regions),
PLATFORMMETHOD(platform_timebase_freq, powermac_timebase_freq),
@@ -118,6 +120,35 @@ powermac_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
ofw_mem_regions(phys,physsz,avail,availsz);
}
+static int
+powermac_attach(platform_t plat)
+{
+ phandle_t rootnode;
+ char model[32];
+
+
+ /*
+ * Quiesce Open Firmware on PowerMac11,2 and 12,1. It is
+ * necessary there to shut down a background thread doing fan
+ * management, and is harmful on other machines (it will make OF
+ * shut off power to various system components it had turned on).
+ *
+ * Note: we don't need to worry about which OF module we are
+ * using since this is called only from very early boot, within
+ * OF's boot context.
+ */
+
+ rootnode = OF_finddevice("/");
+ if (OF_getprop(rootnode, "model", model, sizeof(model)) > 0) {
+ if (strcmp(model, "PowerMac11,2") == 0 ||
+ strcmp(model, "PowerMac12,1") == 0) {
+ ofw_quiesce();
+ }
+ }
+
+ return (0);
+}
+
static u_long
powermac_timebase_freq(platform_t plat, struct cpuref *cpuref)
{
diff --git a/sys/powerpc/pseries/platform_chrp.c b/sys/powerpc/pseries/platform_chrp.c
index 1a9be4c..8d0f857 100644
--- a/sys/powerpc/pseries/platform_chrp.c
+++ b/sys/powerpc/pseries/platform_chrp.c
@@ -151,6 +151,9 @@ chrp_attach(platform_t plat)
}
#endif
+ /* Some systems (e.g. QEMU) need Open Firmware to stand down */
+ ofw_quiesce();
+
return (0);
}
OpenPOWER on IntegriCloud