Date: Sat, 05 Jul 2014 08:03:44 -0400 From: Anthony Jenkins <Anthony.B.Jenkins@att.net> To: "Moore, Robert" <robert.moore@intel.com>, John Baldwin <jhb@freebsd.org>, "freebsd-acpi@freebsd.org" <freebsd-acpi@freebsd.org> Cc: Bykov Vladislav <envolyse@gmail.com>, Ian Smith <smithi@nimnet.asn.au> Subject: ACPI SystemCMOS region handler rev. 2 (was Re: Impossible shutdown) Message-ID: <53B7E9A0.3040608@att.net> In-Reply-To: <94F2FBAB4432B54E8AACC7DFDE6C92E37D1BE9E7@ORSMSX112.amr.corp.intel.com> References: <20140625222911.GA34447@hellgate.Dlink> <20140627143031.P50382@sola.nimnet.asn.au> <53ADD8B9.5060401@att.net> <201406301043.55003.jhb@freebsd.org> <94F2FBAB4432B54E8AACC7DFDE6C92E37D1BE9E7@ORSMSX112.amr.corp.intel.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------090601000000080708030601 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit How about this (attached) patch to atrtc.c? I threw this together (not sure about limiting the width to 8 bits, I can make it more) and backed out my patch to acpica and I can still power down my machine properly (haven't tried suspend/resume yet due to backlight issue). But this seems to be the Right Thing To Do (TM). Anthony On 07/02/2014 17:11, Moore, Robert wrote: > The host detects the PNP IDs. Therefore, it needs to recognize the PNP ID for system CMOS and install a driver which in turn installs a handler for the SystemCMOS address space. > > >> -----Original Message----- >> From: owner-freebsd-acpi@freebsd.org [mailto:owner-freebsd- >> acpi@freebsd.org] On Behalf Of John Baldwin >> Sent: Monday, June 30, 2014 7:44 AM >> To: freebsd-acpi@freebsd.org >> Cc: Anthony Jenkins; Bykov Vladislav; Ian Smith >> Subject: Re: Impossible shutdown >> >> On Friday, June 27, 2014 4:48:57 pm Anthony Jenkins wrote: >>> On 06/27/2014 01:16, Ian Smith wrote: >>>> On Thu, 26 Jun 2014 07:44:35 -0400, Anthony Jenkins wrote: >>>> > On 06/25/2014 18:29, Bykov Vladislav wrote: >>>> > > Hello. >>>> > > >>>> > > I have a problem with ACPI on HP Envy 4 that causes in >>>> impossible >> shutdown. It >>>> > > reaches an error while prepairing to shutdown, and reboots the >> machine. >>>> > > >>>> > > I already did sent a bug report about 2-3 months ago, but >>>> things >> doesn't seems >>>> > > to move on. >>>> > > >>>> > > Here's an error when booting the machine: >>>> > > >>>> > > ACPI Error: No handler for Region [RCM0] (0xfffffe0002b0f800) >> [SystemCMOS] (20110527/evregion-421) >>>> > > ACPI Error: Region SystemCMOS (ID=5) has no handler >> (20110527/exfldio-310) >>>> > > ACPI Error: Method parse/execution failed [\134_SB_.WMID.ESDT] >> (Node 0xfffffe0002aee440), AE_NOT_EXIST (20110527/psparse-560) >>>> > > ACPI Error: Method parse/execution failed >> [\134_SB_.PCI0.LPCB.EC0_._Q42] (Node 0xfffffe0002b16d40), AE_NOT_EXIST >> (20110527/psparse-560) >>>> > > acpi_ec0: evaluation of query method _Q42 failed: AE_NOT_EXIST >>>> > > >>>> > > And here's the one when I'm trying to shut it down: >>>> > > >>>> > > usbus2: Controller shutdown complete >>>> > > ACPI Error: No handler for Region [RCM0] (0xfffffe0002b15900) >> [SystemCMOS] (20110527/evregion-421) >>>> > > ACPI Error: Region SystemCMOS (ID=5) has no handler >> (20110527/exfldio-310) >>>> > > ACPI Error: Method parse/execution failed [\_SB_.WMID.ESDT] >> (Node >> 0xfffffe0002af5800), AE_NOT_EXIST (20110527/psparse-560) >>>> > > ACPI Error: Method parse/execution failed [\_PTS] (Node >> 0xfffffe0002af86c0), AE_NOT_EXIST (20110527/psparse-560) >>>> > > acpi0: AcpiEnterSleepStatePrep failed - AE_NOT_EXIST >>>> > > Rebooting... >>>> > > >>>> > > I've tried FreeBSD 9, FreeBSD 10, and -CURRENT. All have the >>>> same >> problem. >>>> > >>>> > Here's a case where my patch to implement the SystemCMOS region >>>>> handler should help; it allows my HP Envy to power down and allows >>>> it > to suspend/resume except the LCD backlight doesn't come back >>>> when > resuming. Biggest problem with the patch IMHO is I'm >>>> stealing > ("borrowing") from the real time clock (RTC) I/O region, >>>> but I don't > think we have an "actual" FreeBSD driver for that. >>>> > >>>> > Reposting here, or search this list for "Naive implementation of >>>>> AcpiExCmosSpaceHandler", let me know if it doesn't apply cleanly >>>> to > your version of FreeBSD . I've posted it upstream to the >>>> acpica > mailing list, but no response. >>>> > >>>> > diff --git a/source/components/events/evhandler.c >> b/source/components/events/evhandler.c >>>> Interesting. I wonder if this is needed for reading the RTC for the >>>> time on boot, and writing it back on shutdown - which I would have >>>> thought too generic to have left out on any machine? Or is this >> perhaps >>>> retrieving at boot then restoring at shutdown some other system- >> specific >>>> information in NVRAM? >>> It's the latter; they (presumably the BIOS ACPI shutdown/resume methods) >> are >> just reading/writing locations in the non-volatile CMOS storage, which >> just >> happens to be shared with the RTC. The RTC proper has some 16 bytes of >> registers which represent the real time clock - the rest are presumably >> storage, though the platform could probably do whatever it wants with >> various >> locations. >>>> If the latter, then the usage in /sys/dev/acpi_support/acpi_ibm.c >>>> revealed below might illustrate another way of dealing with this? >>>> >>>> % find /sys/ -type f -exec egrep -H 'rtcin|writertc' {} \; | grep -v >> drm_mode_set_crtcinfo >>>> shows everything using the rtcin() and writertc() functions, >> implemented >>>> for x86 at least in /sys/x86/isa/atrtc.c .. but I have no idea whether >>>> you can access those functions from where / when you're tinkering >> here. >>> This is the way I think it's /supposed/ to be done - from my skimming of >> one >> of the ACPI specs, there's a PNP identifier for the CMOS/RTC device. If >> that >> identifier is probed, the OS should install a SystemCMOS region handler >> (which >> would use the I/O methods of the RTC driver which takes care of >> locking/consistency). >>>> Yours looks more likely portable for upstream acpica, but it also >> looks >>>> potentially quite dangerous 'in the wrong hands' :) >>> Personally I don't think my patch can live upstream in acpica-land >> because >> it can step on the toes of an existing OS CMOS/RTC driver talking to the >> RTC >> I/O ports. I just don't know how to do all this with our rtc driver yet, >> particularly the PNPxxxxxx stuff. I'll look into it when I get some free >> cycles. >> >> Probably the "right" thing to do for ACPICA is to have CMOS accesses call >> out >> to a set of AcpiOs* hooks that the OS-dependent layer provides (would be >> in >> sys/dev/acpica/Osd/*). See how the PCI config space accesses work for an >> example. I would ask on the ACPICA mailing list (jkim@ can point you at >> it) >> for feedback on what approach they would prefer. >> >> -- >> John Baldwin >> _______________________________________________ >> freebsd-acpi@freebsd.org mailing list >> http://lists.freebsd.org/mailman/listinfo/freebsd-acpi >> To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org" > _______________________________________________ > freebsd-acpi@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-acpi > To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org" > --------------090601000000080708030601 Content-Type: text/x-patch; name="atrtc.c.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="atrtc.c.patch" Index: sys/x86/isa/atrtc.c =================================================================== --- sys/x86/isa/atrtc.c (revision 267519) +++ sys/x86/isa/atrtc.c (working copy) @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_isa.h" +#include "opt_acpi.h" #include <sys/param.h> #include <sys/systm.h> @@ -53,6 +54,10 @@ #include <machine/intr_machdep.h> #include "clock_if.h" +#include <contrib/dev/acpica/include/acpi.h> +#include <contrib/dev/acpica/include/accommon.h> +#include <dev/acpica/acpivar.h> + #define RTC_LOCK do { if (!kdb_active) mtx_lock_spin(&clock_lock); } while (0) #define RTC_UNLOCK do { if (!kdb_active) mtx_unlock_spin(&clock_lock); } while (0) @@ -161,8 +166,33 @@ struct resource *intr_res; void *intr_handler; struct eventtimer et; + ACPI_HANDLE acpi_handle; /* Handle of the PNP0B00 node */ }; +static ACPI_STATUS +acpi_rtc_cmos_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, UINT32 width, + UINT64 *value, void *context, void *region_context) +{ + struct atrtc_softc *sc; + + sc = (struct atrtc_softc *)context; + if (!value || !sc) + return AE_BAD_PARAMETER; + if (width != 8 || address >= 64U) + return AE_BAD_PARAMETER; + switch (function) { + case ACPI_READ: + *((UINT8 *)value) = rtcin((int)address); + break; + case ACPI_WRITE: + writertc((int)address, *((UINT8 *)value)); + break; + default: + return AE_BAD_PARAMETER; + } + return AE_OK; +} + static int rtc_start(struct eventtimer *et, sbintime_t first, sbintime_t period) { @@ -245,10 +275,17 @@ int i; sc = device_get_softc(dev); + sc->acpi_handle = acpi_get_handle(dev); sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, IO_RTC, IO_RTC + 1, 2, RF_ACTIVE); if (sc->port_res == NULL) device_printf(dev, "Warning: Couldn't map I/O.\n"); + if (ACPI_FAILURE(AcpiInstallAddressSpaceHandler(sc->acpi_handle, + ACPI_ADR_SPACE_CMOS, acpi_rtc_cmos_handler, NULL, sc))) + { + device_printf(dev, "Error registering ACPI CMOS address space handler.\n"); + return 0; + } atrtc_start(); clock_register(dev, 1000000); bzero(&sc->et, sizeof(struct eventtimer)); @@ -286,6 +323,15 @@ return(0); } +static int atrtc_detach(device_t dev) +{ + struct atrtc_softc *sc; + + sc = device_get_softc(dev); + AcpiRemoveAddressSpaceHandler(sc->acpi_handle, ACPI_ADR_SPACE_CMOS, acpi_rtc_cmos_handler); + return bus_generic_detach(dev); +} + static int atrtc_resume(device_t dev) { @@ -366,7 +412,7 @@ /* Device interface */ DEVMETHOD(device_probe, atrtc_probe), DEVMETHOD(device_attach, atrtc_attach), - DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_detach, atrtc_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX stop statclock? */ @@ -402,3 +448,4 @@ rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR)); } #endif /* DDB */ + --------------090601000000080708030601--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53B7E9A0.3040608>