From owner-freebsd-acpi@FreeBSD.ORG Sat Aug 2 22:13:23 2014 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 609B6740 for ; Sat, 2 Aug 2014 22:13:23 +0000 (UTC) Received: from nm26-vm3.access.bullet.mail.gq1.yahoo.com (nm26-vm3.access.bullet.mail.gq1.yahoo.com [216.39.63.84]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 239DE252F for ; Sat, 2 Aug 2014 22:13:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=att.net; s=s2048; t=1407017420; bh=JOwUzElgl7ADwp7kqoeQrDg91WsHVxyf7kNvsRZheXA=; h=Received:Received:Received:DKIM-Signature:X-Yahoo-Newman-Id:X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type; b=CEA3bhkMizl2MeSEtJXE6nzdDM78MJrrzdwIQUWBJnDqErvitw/j/CiBRv/V8fACA67Cwemt/TaNFgkYIYDQ7iBMCe5r2Sh8GYmhbuBksQgZAQ7pdgfm4PRmfvsnZY8jo38M8sSiwfGvmVw5DjQvV8NmQqHI3ZFSop4ZSmuZCt0tufoxg6HE/fwZfH0R99xzYRT2Q4XRzX7v8iDQHQRW2mtAvuc05TCkGbsMhP+e1ga3xRnTe/DjaXJkyluTcm86euPeyjHpe17vUiModShj0CYfn/mxXMKQSXUKp3k8AAhfFmfyWJN4Us0lSt/RIRZvO2Fz5aSoh0ndgQhsNCHwUw== DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s2048; d=att.net; b=azw3+ZXlitSIMq9zM/K5JAxpV90jSDUzNrJzNlIXfDG6q5kjbGhbKFbJ5jlQC+wL/FcrvITd7EWveQPcSPtu28T6dwNStoWqLWWoX6amJQh0NK/q4m/EiEwwrUS31aZiBpGyRljw0E38Ps8n5gDns3C6EPz28fpnhLFR5vbu1pO6ghSfMXydEiUDoxVb3GIbTIsfW0uFbv+TfjHdyayds/Bpmucx9pY+rSt7/Pj6dYwsvhA5o2JG3KDFUCJF4X67KejDL3ZC2iLbzHhvcZgPANARUPPJRUGFWU0FmTSKP4fEOQTICthqVuSS7nVsQh2AvnHS4DY+hXAXLdpK4uVqMg==; Received: from [216.39.60.173] by nm26.access.bullet.mail.gq1.yahoo.com with NNFMP; 02 Aug 2014 22:10:20 -0000 Received: from [67.195.22.113] by tm9.access.bullet.mail.gq1.yahoo.com with NNFMP; 02 Aug 2014 22:10:20 -0000 Received: from [127.0.0.1] by smtp115.sbc.mail.gq1.yahoo.com with NNFMP; 02 Aug 2014 22:10:20 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=att.net; s=s1024; t=1407017420; bh=JOwUzElgl7ADwp7kqoeQrDg91WsHVxyf7kNvsRZheXA=; h=X-Yahoo-Newman-Id:X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type; b=ZcLoEZWZoZXtkTpe5fbb4WGMvBXZCuq35VecOtq4L9IpvQzcQ3+L83tcSKaiuk3PT0mzpWHKwr2hXWlhpFcHPS+u8mLD3csCsgy5wNhq8wMreJ5dAi5HXuQDkFb6bJVL2IBJxixbvCn578BbsrK5imo57Hhj8KhA3GnpyLkOcJA= X-Yahoo-Newman-Id: 238623.41817.bm@smtp115.sbc.mail.gq1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: fs4cwYkVM1k7heLw8JgsV5On.NeKjNjxcTPbB1F5_0.SjG2 QaXBEvl9cOT1SIChB7tJOwfTU6JjPOVhFk7641zbSgMrVuxNyxB19F_J77h3 Djb7l2BsrddH4y_bIlqeuiIS6ZuRoUk0Ilqz6kCzHL8qCRviSZgkX.fTC_aq xrHh2_.hc3oHJWo4kOsu6LxlCoaaQUW_7QPDpPNB6I4qJyUzLarGBPcUjlXP PE8M7Hr1rtWV0kWYvnNz9wNNcMUbhVdjLHpN5HNREGBcUMuFDGV.lmuOI6l1 Sni5P4oW3MavK0y9vj7JFFfeDe4XTvbGvCDb2PENfLzg8rzJklSH7sBKhKg0 CrRLwgh9ZP3YfyhQ5a4I9bi3bsbfDPkxhpGJRuC.A0qxeUi4qSZvkv.KlRQr 9182cN5rXF9.BpKQyViNERTlnJ45PphEPePp23ccaQLYifmkTGtLd71wWKTU cqX0OQTWIV_z195kslZpo3_dBQY6N7VOGnG9DUiU40le4XpcDPdOKOtcW3IB MgmcCJePeb1RE.SIFmzkuQ2LpS2CHL79UM9kfLdsiGjq_J1xuvLwD16MwoCK u5g-- X-Yahoo-SMTP: OKD1keCswBBTAmAF1s00hLyKW3wE3YfSK0Eazl6b4VZG4LTqJxg- Message-ID: <53DD61BD.7050508@att.net> Date: Sat, 02 Aug 2014 18:10:05 -0400 From: Anthony Jenkins User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: freebsd-acpi@freebsd.org Subject: [PATCH] ACPI CMOS region support - submission? Content-Type: multipart/mixed; boundary="------------050105070904000203050100" X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Aug 2014 22:13:23 -0000 This is a multi-part message in MIME format. --------------050105070904000203050100 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Okay how do I get this bad boy into -CURRENT? Do I need a sponsor to do the commit? Get my own FreeBSD developer status? I made a few minor changes since the last incarnation: - Defined the CMOS address/data register addresses as macros - Defined the (apparent) I/O delay as a macro I also verified the ACPI CMOS region code only accesses up to register 63 (0x3F - in previous emails I mistakenly said 0x7F). If/when this gets in, I'd like to add sysctl controls to e.g. allow ACPI access to the date/time registers (I currently return failure when attempting to write them via ACPI). I don't see anything in the spec (after re-reading it) that disallows ACPI from touching those. Thanks, Anthony Jenkins --------------050105070904000203050100 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 268728) +++ sys/x86/isa/atrtc.c (working copy) @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_isa.h" +#include "opt_acpi.h" #include #include @@ -53,12 +54,19 @@ #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; static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; static u_char rtc_statusb = RTCSB_24HR; @@ -66,39 +74,50 @@ * RTC support routines */ -int -rtcin(int reg) +static void acpi_cmos_read(ACPI_PHYSICAL_ADDRESS address, UINT8 *buf, UINT32 buflen) { - u_char val; + UINT32 offset; RTC_LOCK; - if (rtc_reg != reg) { - inb(0x84); - outb(IO_RTC, reg); - rtc_reg = reg; - inb(0x84); + for (offset = 0U; offset < buflen; ++offset) { + IO_DELAY(); + outb(IO_RTC_ADDR, ((address + offset) | 0x80) & 0xFF); + IO_DELAY(); + buf[offset] = inb(IO_RTC_DATA); } - val = inb(IO_RTC + 1); RTC_UNLOCK; - return (val); } -void -writertc(int reg, u_char val) +static void acpi_cmos_write(ACPI_PHYSICAL_ADDRESS address, const UINT8 *buf, UINT32 buflen) { + UINT32 offset; RTC_LOCK; - if (rtc_reg != reg) { - inb(0x84); - outb(IO_RTC, reg); - rtc_reg = reg; - inb(0x84); + for (offset = 0U; offset < buflen; ++offset) { + IO_DELAY(); + outb(IO_RTC_ADDR, ((address + offset) | 0x80) & 0xFF); + IO_DELAY(); + outb(IO_RTC_DATA, buf[offset]); } - outb(IO_RTC + 1, val); - inb(0x84); + IO_DELAY(); RTC_UNLOCK; } +int +rtcin(int reg) +{ + u_char val; + + acpi_cmos_read(reg & 0xFF, &val, 1); + return (val); +} + +void +writertc(int reg, u_char val) +{ + acpi_cmos_write(reg & 0xFF, &val, 1); +} + static __inline int readrtc(int port) { @@ -144,7 +163,6 @@ { /* Restore all of the RTC's "status" (actually, control) registers. */ - rtcin(RTC_STATUSA); /* dummy to get rtc_reg set */ writertc(RTC_STATUSB, RTCSB_24HR); writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, rtc_statusb); @@ -161,9 +179,52 @@ struct resource *intr_res; void *intr_handler; struct eventtimer et; + ACPI_HANDLE acpi_handle; /* Handle of the PNP0B00 node */ }; static int +is_datetime_reg(ACPI_PHYSICAL_ADDRESS address) +{ + return address == 0x00 || + address == 0x02 || + address == 0x04 || + address == 0x04 || + (address >= 0x06 && address <= 0x09); +} + +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 > 32 || (width & 0x07) || address >= 64U) + return AE_BAD_PARAMETER; + if (function == ACPI_WRITE && + (is_datetime_reg(address) || + (width > 8 && address <= 0x09))) + 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: + return AE_BAD_PARAMETER; + } + printf("%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 +306,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 +354,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 +443,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? */ --------------050105070904000203050100--