Skip site navigation (1)Skip section navigation (2)
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>