diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-05-16 15:56:59 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-05-16 15:56:59 +0000 |
commit | 5236db452d5b06e3faf03f1827771f70170b6c71 (patch) | |
tree | f0f09cf22154126476afdd90af6bf8dee7567b20 /sys/powerpc/ofw | |
parent | 2f3db6c19db76e7ee197d4431d9d8b7c786c55cd (diff) | |
download | FreeBSD-src-5236db452d5b06e3faf03f1827771f70170b6c71.zip FreeBSD-src-5236db452d5b06e3faf03f1827771f70170b6c71.tar.gz |
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.
Diffstat (limited to 'sys/powerpc/ofw')
-rw-r--r-- | sys/powerpc/ofw/ofw_real.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sys/powerpc/ofw/ofw_real.c b/sys/powerpc/ofw/ofw_real.c index 4425ad1..1590eb6 100644 --- a/sys/powerpc/ofw/ofw_real.c +++ b/sys/powerpc/ofw/ofw_real.c @@ -106,6 +106,7 @@ static ssize_t ofw_real_write(ofw_t, ihandle_t instance, const void *addr, 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); @@ -133,6 +134,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), @@ -889,6 +891,27 @@ ofw_real_release(ofw_t ofw, void *virt, size_t size) * 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) |