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: [email protected] [mailto:owner-freebsd-
>> [email protected]] On Behalf Of John Baldwin
>> Sent: Monday, June 30, 2014 7:44 AM
>> To: [email protected]
>> 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
>> _______________________________________________
>> [email protected] mailing list
>> http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
>> To unsubscribe, send any mail to "[email protected]"
> _______________________________________________
> [email protected] mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
> To unsubscribe, send any mail to "[email protected]"
>
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 */
+
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-acpi
To unsubscribe, send any mail to "[email protected]"