From 7fe63926ae441c3395e2af8be4e8aa2bc16fbdb3 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 23 May 2010 02:18:40 +0000 Subject: [PATCH] MFC r208152,208172: On PowerMac11,2 and (presumably) PowerMac12,1, we need to quiesce the firmware in order to take over control of the SMU. Without doing this, the firmware background process doing fan control will run amok as we take over the system and crash the management chip. This is limited to these two machines because our kernel is heavily dependent on firmware accesses, and so quiescing firmware can cause nasty problems. --- sys/powerpc/aim/ofw_machdep.c | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c index 6e276970edd..dc43c1b8125 100644 --- a/sys/powerpc/aim/ofw_machdep.c +++ b/sys/powerpc/aim/ofw_machdep.c @@ -75,6 +75,7 @@ static int (*ofwcall)(void *); static void *fdt; int ofw_real_mode; +static void ofw_quiesce(void); static int openfirmware(void *args); /* @@ -291,6 +292,12 @@ OF_bootstrap() return status; OF_init(openfirmware); + + /* + * On some machines, we need to quiesce OF to turn off + * background processes. + */ + ofw_quiesce(); } else { status = OF_install(OFW_FDT, 0); @@ -303,6 +310,39 @@ OF_bootstrap() return (status); } +static 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. + */ + + 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); + } + } +} + static int openfirmware(void *args) {