From owner-freebsd-acpi@FreeBSD.ORG Sun Mar 15 03:43:09 2015 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 255FBD94 for ; Sun, 15 Mar 2015 03:43:09 +0000 (UTC) Received: from nm7-vm4.bullet.mail.ne1.yahoo.com (nm7-vm4.bullet.mail.ne1.yahoo.com [98.138.91.167]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DADBD302 for ; Sun, 15 Mar 2015 03:43:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=att.net; s=s1024; t=1426390835; bh=ld7THl5IKGwGEv2xyAlJ4O97WLJGuNdq7i1c3J9jJ38=; h=Date:From:To:CC:Subject:References:In-Reply-To:From:Subject; b=I22DAyvQJb9uMzgKrn/rC5pGUO6f8dVFUtjHPJR5M5b2raOzpmXf03oby1Vwhagcx1aSl1NdsCP9OY/aYAQGVlWLd3WhstfJMAVfOulNd15GRl+5+Uc+QNctCMn3Yj1ClhKvxkRJCAiTWpUPjO7qqbj28/0w3EFhMgr6hcC0+9k= Received: from [98.138.100.117] by nm7.bullet.mail.ne1.yahoo.com with NNFMP; 15 Mar 2015 03:40:35 -0000 Received: from [98.138.226.59] by tm108.bullet.mail.ne1.yahoo.com with NNFMP; 15 Mar 2015 03:40:35 -0000 Received: from [127.0.0.1] by smtp210.mail.ne1.yahoo.com with NNFMP; 15 Mar 2015 03:40:35 -0000 X-Yahoo-Newman-Id: 569123.55907.bm@smtp210.mail.ne1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: YGUx5OYVM1lq5G3s6.h7M7ZpEG8r_3jk5thxTAE82VQSeP6 VrGzJyLZmC33SQN0ggk8pImEHhOAjqNOeHRO7naK7t5DZeveLth16h1NKTNM HpYEf8oXQL3Hmf184cuGJkBuEWwaoZ.T9k8.z4sMwRdt4UPdK4qJNEYAYy_d Dy8a6eYCj36Y9jh7i8Qu7YZ6gPgEsS2GyKFWV14B4OLbLuarkzHxWE0AJ95F 0HOwrMDnWtf3K5qQImwZ0YwKHVqZlxw98qmLCibZ0JioKZadSYu9YZ5Fo4O1 HOigTg.MmUTeQWu85mCAL8wRlrj_Vt5HS6qLHUcSXgjNbL9tep1KmsmxT38R O7Uz5aRuYwC08kfvs4N3r5Q.he5exkWnUW4jtKxUFi6.wS9YLhXjzfAMfHvj hBSKE.htC9vetTbYyOUb5DDBgwfIyohn9kQmZ35PHNmhhbdWMEl9MoBKQVCp 3yOP7FJZJPnf6b2TaspzaZSCzYfdrpQTP7xA96To_XSsTobpWpVF_1XxeTOB doeO36C5VsoPvGmW5WyWeJb0TH1FYVTcxsz67A7kwPgMj3QGu X-Yahoo-SMTP: OKD1keCswBBTAmAF1s00hLyKW3wE3YfSK0Eazl6b4VZG4LTqJxg- Message-ID: <5504FF32.3020202@att.net> Date: Sat, 14 Mar 2015 23:40:34 -0400 From: Anthony Jenkins User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Ian Smith Subject: [PATCH] ACPI CMOS region support rev. 4 References: <20150222180817.GD27984@strugglingcoder.info> <54EB8C21.2080600@att.net> <2401337.2oUs7iAbtB@ralph.baldwin.cx> <54EF3D5D.4010106@att.net> <20150227222203.P38620@sola.nimnet.asn.au> <20150228125857.D1277@besplex.bde.org> <54F14368.4020807@att.net> <20150302002647.W42658@sola.nimnet.asn.au> <54F5E53D.1090601@att.net> <20150306025800.U46361@sola.nimnet.asn.au> <54F9D7E6.4050807@att.net> In-Reply-To: <54F9D7E6.4050807@att.net> Content-Type: multipart/mixed; boundary="------------090406000600090209050409" Cc: freebsd-acpi@freebsd.org X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Mar 2015 03:43:09 -0000 This is a multi-part message in MIME format. --------------090406000600090209050409 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit How about this one? :-) Sorry it's a week late. Anthony On 03/06/15 11:37, Anthony Jenkins wrote: > On 03/06/2015 06:49 AM, Ian Smith wrote: >> On Tue, 3 Mar 2015 11:45:49 -0500, Anthony Jenkins wrote: >> > On 03/01/2015 09:29 AM, Ian Smith wrote: >> [..] >> Regarding systems without ACPI loaded, or active: what happens when the >> below AcpiInstallAddressSpaceHandler() call fails, but returns 0? Would >> not that prevent rtc_start() from running atrtc_start() etc for non-ACPI >> clock initialisation and registration? > Good catch, there's technically no reason to bail on rtc_start() if I > fail to register the ACPI CMOS handler; it'll just never get called > (same as old behaviour). I'll change "Error" to "Warning" and remove > the return 0. > >> I suppose there's a global kernel variable for acpi_is_active ono? >> >> > +static int >> > rtc_start(struct eventtimer *et, sbintime_t first, sbintime_t period) >> > { >> > >> > @@ -245,10 +323,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 +371,15 @@ >> > return(0); >> > } >> >> Might that not matter for detach, as you're not testing for return code? > Yeah I'd prefer to remember the failure to install the handler and > conditionally uninstall it in the detach method. > > I'll fix up the logging and add these suggestions this weekend. > > Thanks, > Anthony > >> > +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); >> > +} >> >> cheers, Ian >> _______________________________________________ >> 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" --------------090406000600090209050409 Content-Type: text/x-patch; name="atrtc_c_rev4.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="atrtc_c_rev4.diff" Index: sys/x86/isa/atrtc.c =================================================================== --- sys/x86/isa/atrtc.c (revision 279957) +++ sys/x86/isa/atrtc.c (working copy) @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_isa.h" +#include "opt_acpi.h" #include #include @@ -53,9 +54,17 @@ #include #include "clock_if.h" +#include +#include +#include + #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) +#define IO_DELAY() (void)inb(0x84) +#define IO_RTC_ADDR (IO_RTC + 0) +#define IO_RTC_DATA (IO_RTC + 1) + int atrtcclock_disable = 0; static int rtc_reg = -1; @@ -62,6 +71,12 @@ static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; static u_char rtc_statusb = RTCSB_24HR; +static unsigned int atrtc_verbose = 0; +SYSCTL_UINT(_debug, OID_AUTO, atrtc_verbose, CTLFLAG_RWTUN, + &atrtc_verbose, 0, "AT-RTC Debug Level (0-2)"); +#define ATRTC_DBG_PRINTF(level, format, ...) \ + if (atrtc_verbose >= level) printf(format, ##__VA_ARGS__) + /* * RTC support routines */ @@ -73,10 +88,10 @@ RTC_LOCK; if (rtc_reg != reg) { - inb(0x84); + IO_DELAY(); outb(IO_RTC, reg); rtc_reg = reg; - inb(0x84); + IO_DELAY(); } val = inb(IO_RTC + 1); RTC_UNLOCK; @@ -89,16 +104,36 @@ RTC_LOCK; if (rtc_reg != reg) { - inb(0x84); + IO_DELAY(); outb(IO_RTC, reg); rtc_reg = reg; - inb(0x84); + IO_DELAY(); } outb(IO_RTC + 1, val); - inb(0x84); + IO_DELAY(); RTC_UNLOCK; } +static void +acpi_cmos_read(ACPI_PHYSICAL_ADDRESS address, UINT8 *buf, UINT32 buflen) +{ + UINT32 offset; + + for (offset = 0; offset < buflen; ++offset) { + buf[offset] = rtcin(address + offset) & 0xff; + } +} + +static void +acpi_cmos_write(ACPI_PHYSICAL_ADDRESS address, const UINT8 *buf, UINT32 buflen) +{ + UINT32 offset; + + for (offset = 0; offset < buflen; ++offset) { + writertc(address + offset, buf[offset]); + } +} + static __inline int readrtc(int port) { @@ -161,9 +196,68 @@ struct resource *intr_res; void *intr_handler; struct eventtimer et; + ACPI_HANDLE acpi_handle; /* Handle of the PNP0B00 node */ + int acpi_handle_registered; /* 0 = acpi_handle not registered */ }; static int +acpi_check_rtc_byteaccess(int is_read, u_long addr) +{ + int retval = 1; /* Success */ + + if (is_read) { + /* Reading 0x0C will muck with interrupts */ + if (addr == 0x0C) + retval = 0; + } else { + if (!((addr <= 0x05 && (addr & 0x01)) || + (addr >= 0x30 && addr < 0x40))) + retval = 0; + } + return retval; +} + +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) { + ATRTC_DBG_PRINTF(1, "%s: NULL parameter.\n", __FUNCTION__); + return AE_BAD_PARAMETER; + } + if (width > 32 || (width & 0x07) || address >= 64) { + ATRTC_DBG_PRINTF(1, "%s: Invalid width (%u) or address (0x%08lx).\n", + __FUNCTION__, width, address); + return AE_BAD_PARAMETER; + } + if (!acpi_check_rtc_byteaccess(function == ACPI_READ, address)) { + ATRTC_DBG_PRINTF(1, "%s: Bad CMOS %s access at address 0x%08lx.\n", + __FUNCTION__, function == ACPI_READ ? "read" : "write", address); + return AE_BAD_PARAMETER; + } + + switch (function) { + case ACPI_READ: + acpi_cmos_read(address, (UINT8 *)value, width >> 3); + break; + case ACPI_WRITE: + acpi_cmos_write(address, (const UINT8 *)value, + width >> 3); + break; + default: + ATRTC_DBG_PRINTF(1, "%s: Invalid function: %d.\n", __FUNCTION__, function); + return AE_BAD_PARAMETER; + } + ATRTC_DBG_PRINTF(1, "%s: %-5s%02u address=%04lx value=%08x\n", + __FUNCTION__, function == ACPI_READ ? "READ" : "WRITE", + width >> 3, address, *((UINT32 *)value)); + return AE_OK; +} + +static int rtc_start(struct eventtimer *et, sbintime_t first, sbintime_t period) { @@ -245,10 +339,19 @@ 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, "Warning: Couldn't register ACPI CMOS address space handler.\n"); + /* I assume the softc was memset() to 0? */ + } else + sc->acpi_handle_registered = 1; atrtc_start(); clock_register(dev, 1000000); bzero(&sc->et, sizeof(struct eventtimer)); @@ -286,6 +389,17 @@ return(0); } +static int atrtc_detach(device_t dev) +{ + struct atrtc_softc *sc; + + sc = device_get_softc(dev); + if (sc->acpi_handle_registered) + 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 +480,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? */ --------------090406000600090209050409--