1 1.5 andvar /* $NetBSD: acpi_wdrt.c,v 1.5 2023/05/06 21:34:40 andvar Exp $ */ 2 1.1 jmcneill 3 1.1 jmcneill /* 4 1.1 jmcneill * Copyright (c) 2011 Jared D. McNeill <jmcneill (at) invisible.ca> 5 1.1 jmcneill * All rights reserved. 6 1.1 jmcneill * 7 1.1 jmcneill * Redistribution and use in source and binary forms, with or without 8 1.1 jmcneill * modification, are permitted provided that the following conditions 9 1.1 jmcneill * are met: 10 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright 11 1.1 jmcneill * notice, this list of conditions and the following disclaimer. 12 1.1 jmcneill * 2. The name of the author may not be used to endorse or promote products 13 1.1 jmcneill * derived from this software without specific prior written permission. 14 1.1 jmcneill * 15 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 1.1 jmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 1.1 jmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 1.1 jmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 1.1 jmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 1.1 jmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 1.1 jmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 1.1 jmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 1.1 jmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 jmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 jmcneill * SUCH DAMAGE. 26 1.1 jmcneill */ 27 1.1 jmcneill 28 1.1 jmcneill /* 29 1.1 jmcneill * ACPI "WDRT" watchdog support, based on: 30 1.1 jmcneill * 31 1.1 jmcneill * Watchdog Timer Hardware Requirements for Windows Server 2003, version 1.01 32 1.1 jmcneill * http://www.microsoft.com/whdc/system/sysinternals/watchdog.mspx 33 1.1 jmcneill */ 34 1.1 jmcneill 35 1.1 jmcneill /* #define ACPIWDRT_DEBUG */ 36 1.1 jmcneill 37 1.1 jmcneill #include <sys/cdefs.h> 38 1.5 andvar __KERNEL_RCSID(0, "$NetBSD: acpi_wdrt.c,v 1.5 2023/05/06 21:34:40 andvar Exp $"); 39 1.1 jmcneill 40 1.1 jmcneill #include <sys/param.h> 41 1.1 jmcneill #include <sys/device.h> 42 1.1 jmcneill #include <sys/systm.h> 43 1.1 jmcneill #include <sys/module.h> 44 1.1 jmcneill 45 1.1 jmcneill #include <dev/acpi/acpireg.h> 46 1.1 jmcneill #include <dev/acpi/acpivar.h> 47 1.1 jmcneill 48 1.1 jmcneill #include <dev/sysmon/sysmonvar.h> 49 1.1 jmcneill 50 1.1 jmcneill #define _COMPONENT ACPI_RESOURCE_COMPONENT 51 1.1 jmcneill ACPI_MODULE_NAME ("acpi_wdrt") 52 1.1 jmcneill 53 1.1 jmcneill #ifdef ACPIWDRT_DEBUG 54 1.1 jmcneill #define DPRINTF(x) printf x 55 1.1 jmcneill #else 56 1.1 jmcneill #define DPRINTF(x) do { } while (0) 57 1.1 jmcneill #endif 58 1.1 jmcneill 59 1.1 jmcneill /* Watchdog Control/Status Register (32 bits) */ 60 1.1 jmcneill #define ACPI_WDRT_CSR_RUNSTOP (1 << 0) /* rw */ 61 1.1 jmcneill #define ACPI_WDRT_RUNSTOP_STOPPED (0 << 0) 62 1.1 jmcneill #define ACPI_WDRT_RUNSTOP_RUNNING (1 << 0) 63 1.1 jmcneill #define ACPI_WDRT_CSR_FIRED (1 << 1) /* rw */ 64 1.1 jmcneill #define ACPI_WDRT_CSR_ACTION (1 << 2) /* rw */ 65 1.1 jmcneill #define ACPI_WDRT_ACTION_RESET (0 << 2) 66 1.1 jmcneill #define ACPI_WDRT_ACTION_POWEROFF (1 << 2) 67 1.1 jmcneill #define ACPI_WDRT_CSR_WDOGEN (1 << 3) /* ro */ 68 1.1 jmcneill #define ACPI_WDRT_WDOGEN_ENABLE (0 << 3) 69 1.1 jmcneill #define ACPI_WDRT_WDOGEN_DISABLE (1 << 3) 70 1.1 jmcneill #define ACPI_WDRT_CSR_TRIGGER (1 << 7) /* wo */ 71 1.1 jmcneill /* Watchdog Count Register (32 bits) */ 72 1.1 jmcneill #define ACPI_WDRT_COUNT_DATA_MASK 0xffff 73 1.1 jmcneill 74 1.1 jmcneill /* Watchdog Resource Table - Units */ 75 1.1 jmcneill #define ACPI_WDRT_UNITS_1S 0x0 76 1.1 jmcneill #define ACPI_WDRT_UNITS_100MS 0x1 77 1.1 jmcneill #define ACPI_WDRT_UNITS_10MS 0x2 78 1.1 jmcneill 79 1.1 jmcneill struct acpi_wdrt_softc { 80 1.1 jmcneill device_t sc_dev; 81 1.1 jmcneill 82 1.1 jmcneill bus_space_tag_t sc_memt; 83 1.1 jmcneill bus_space_handle_t sc_memh; 84 1.1 jmcneill 85 1.1 jmcneill struct sysmon_wdog sc_smw; 86 1.1 jmcneill bool sc_smw_valid; 87 1.1 jmcneill 88 1.1 jmcneill uint32_t sc_max_period; 89 1.1 jmcneill unsigned int sc_period_scale; 90 1.1 jmcneill 91 1.1 jmcneill ACPI_GENERIC_ADDRESS sc_control_reg; 92 1.1 jmcneill ACPI_GENERIC_ADDRESS sc_count_reg; 93 1.1 jmcneill }; 94 1.1 jmcneill 95 1.1 jmcneill static int acpi_wdrt_match(device_t, cfdata_t, void *); 96 1.1 jmcneill static void acpi_wdrt_attach(device_t, device_t, void *); 97 1.1 jmcneill static int acpi_wdrt_detach(device_t, int); 98 1.1 jmcneill static bool acpi_wdrt_suspend(device_t, const pmf_qual_t *); 99 1.1 jmcneill 100 1.1 jmcneill static int acpi_wdrt_setmode(struct sysmon_wdog *); 101 1.1 jmcneill static int acpi_wdrt_tickle(struct sysmon_wdog *); 102 1.1 jmcneill 103 1.3 christos static ACPI_STATUS acpi_wdrt_read_control(struct acpi_wdrt_softc *, uint64_t *); 104 1.3 christos static ACPI_STATUS acpi_wdrt_write_control(struct acpi_wdrt_softc *, uint64_t); 105 1.1 jmcneill #if 0 106 1.1 jmcneill static ACPI_STATUS acpi_wdrt_read_count(struct acpi_wdrt_softc *, uint32_t *); 107 1.1 jmcneill #endif 108 1.1 jmcneill static ACPI_STATUS acpi_wdrt_write_count(struct acpi_wdrt_softc *, uint32_t); 109 1.1 jmcneill 110 1.1 jmcneill CFATTACH_DECL_NEW( 111 1.1 jmcneill acpiwdrt, 112 1.1 jmcneill sizeof(struct acpi_wdrt_softc), 113 1.1 jmcneill acpi_wdrt_match, 114 1.1 jmcneill acpi_wdrt_attach, 115 1.1 jmcneill acpi_wdrt_detach, 116 1.1 jmcneill NULL 117 1.1 jmcneill ); 118 1.1 jmcneill 119 1.1 jmcneill static int 120 1.1 jmcneill acpi_wdrt_match(device_t parent, cfdata_t match, void *opaque) 121 1.1 jmcneill { 122 1.1 jmcneill ACPI_TABLE_WDRT *wdrt; 123 1.1 jmcneill ACPI_STATUS rv; 124 1.3 christos uint64_t val; 125 1.1 jmcneill 126 1.1 jmcneill rv = AcpiGetTable(ACPI_SIG_WDRT, 1, (ACPI_TABLE_HEADER **)&wdrt); 127 1.1 jmcneill if (ACPI_FAILURE(rv)) 128 1.1 jmcneill return 0; 129 1.1 jmcneill 130 1.1 jmcneill /* Only system memory address spaces are allowed */ 131 1.1 jmcneill if (wdrt->ControlRegister.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY || 132 1.1 jmcneill wdrt->CountRegister.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) { 133 1.1 jmcneill return 0; 134 1.1 jmcneill } 135 1.1 jmcneill /* Sanity check control & count register addresses */ 136 1.1 jmcneill if (wdrt->ControlRegister.Address == 0 || 137 1.1 jmcneill wdrt->ControlRegister.Address == 0xffffffff || 138 1.1 jmcneill wdrt->ControlRegister.Address == 0xffffffffffffffff || 139 1.1 jmcneill wdrt->CountRegister.Address == 0 || 140 1.1 jmcneill wdrt->CountRegister.Address == 0xffffffff || 141 1.1 jmcneill wdrt->CountRegister.Address == 0xffffffffffffffff) { 142 1.1 jmcneill return 0; 143 1.1 jmcneill } 144 1.1 jmcneill 145 1.5 andvar /* Read control register */ 146 1.1 jmcneill rv = AcpiOsReadMemory(wdrt->ControlRegister.Address, &val, 147 1.1 jmcneill wdrt->ControlRegister.BitWidth); 148 1.1 jmcneill if (ACPI_FAILURE(rv)) 149 1.1 jmcneill return 0; 150 1.1 jmcneill 151 1.1 jmcneill /* Make sure the hardware watchdog is enabled */ 152 1.1 jmcneill if ((val & ACPI_WDRT_CSR_WDOGEN) == ACPI_WDRT_WDOGEN_DISABLE) 153 1.1 jmcneill return 0; 154 1.1 jmcneill 155 1.1 jmcneill return 1; 156 1.1 jmcneill } 157 1.1 jmcneill 158 1.1 jmcneill static void 159 1.1 jmcneill acpi_wdrt_attach(device_t parent, device_t self, void *opaque) 160 1.1 jmcneill { 161 1.1 jmcneill struct acpi_wdrt_softc *sc = device_private(self); 162 1.1 jmcneill ACPI_TABLE_WDRT *wdrt; 163 1.1 jmcneill ACPI_STATUS rv; 164 1.1 jmcneill 165 1.1 jmcneill sc->sc_dev = self; 166 1.1 jmcneill 167 1.1 jmcneill pmf_device_register(self, acpi_wdrt_suspend, NULL); 168 1.1 jmcneill 169 1.1 jmcneill rv = AcpiGetTable(ACPI_SIG_WDRT, 1, (ACPI_TABLE_HEADER **)&wdrt); 170 1.1 jmcneill if (ACPI_FAILURE(rv)) { 171 1.1 jmcneill aprint_error(": couldn't get WDRT (%s)\n", 172 1.1 jmcneill AcpiFormatException(rv)); 173 1.1 jmcneill return; 174 1.1 jmcneill } 175 1.1 jmcneill 176 1.1 jmcneill /* Maximum counter value must be 511 - 65535 */ 177 1.1 jmcneill if (wdrt->MaxCount < 511) { 178 1.1 jmcneill aprint_error(": maximum counter value out of range (%d)\n", 179 1.1 jmcneill wdrt->MaxCount); 180 1.1 jmcneill return; 181 1.1 jmcneill } 182 1.1 jmcneill /* Counter units can be 1s, 100ms, or 10ms */ 183 1.1 jmcneill switch (wdrt->Units) { 184 1.1 jmcneill case ACPI_WDRT_UNITS_1S: 185 1.1 jmcneill case ACPI_WDRT_UNITS_100MS: 186 1.1 jmcneill case ACPI_WDRT_UNITS_10MS: 187 1.1 jmcneill break; 188 1.1 jmcneill default: 189 1.1 jmcneill aprint_error(": units not supported (0x%x)\n", wdrt->Units); 190 1.1 jmcneill return; 191 1.1 jmcneill } 192 1.1 jmcneill 193 1.1 jmcneill sc->sc_control_reg = wdrt->ControlRegister; 194 1.1 jmcneill sc->sc_count_reg = wdrt->CountRegister; 195 1.1 jmcneill 196 1.1 jmcneill aprint_naive("\n"); 197 1.2 jmcneill aprint_normal(": mem 0x%" PRIx64 ",0x%" PRIx64 "\n", 198 1.1 jmcneill sc->sc_control_reg.Address, sc->sc_count_reg.Address); 199 1.1 jmcneill 200 1.1 jmcneill if (wdrt->PciVendorId != 0xffff && wdrt->PciDeviceId != 0xffff) { 201 1.1 jmcneill aprint_verbose_dev(sc->sc_dev, "PCI %u:%03u:%02u:%01u", 202 1.1 jmcneill wdrt->PciSegment, wdrt->PciBus, wdrt->PciDevice, 203 1.1 jmcneill wdrt->PciFunction); 204 1.1 jmcneill aprint_verbose(" vendor 0x%04x product 0x%04x\n", 205 1.1 jmcneill wdrt->PciVendorId, wdrt->PciDeviceId); 206 1.1 jmcneill } 207 1.1 jmcneill 208 1.1 jmcneill sc->sc_max_period = wdrt->MaxCount; 209 1.1 jmcneill sc->sc_period_scale = 1; 210 1.1 jmcneill if (wdrt->Units == ACPI_WDRT_UNITS_100MS) 211 1.1 jmcneill sc->sc_period_scale = 10; 212 1.1 jmcneill if (wdrt->Units == ACPI_WDRT_UNITS_10MS) 213 1.1 jmcneill sc->sc_period_scale = 100; 214 1.1 jmcneill sc->sc_max_period /= sc->sc_period_scale; 215 1.1 jmcneill aprint_normal_dev(self, "watchdog interval 1-%d sec.\n", 216 1.1 jmcneill sc->sc_max_period); 217 1.1 jmcneill 218 1.1 jmcneill sc->sc_smw.smw_name = device_xname(self); 219 1.1 jmcneill sc->sc_smw.smw_cookie = sc; 220 1.1 jmcneill sc->sc_smw.smw_setmode = acpi_wdrt_setmode; 221 1.1 jmcneill sc->sc_smw.smw_tickle = acpi_wdrt_tickle; 222 1.1 jmcneill sc->sc_smw.smw_period = sc->sc_max_period; 223 1.1 jmcneill 224 1.1 jmcneill if (sysmon_wdog_register(&sc->sc_smw)) 225 1.1 jmcneill aprint_error_dev(self, "couldn't register with sysmon\n"); 226 1.1 jmcneill else 227 1.1 jmcneill sc->sc_smw_valid = true; 228 1.1 jmcneill } 229 1.1 jmcneill 230 1.1 jmcneill static int 231 1.1 jmcneill acpi_wdrt_detach(device_t self, int flags) 232 1.1 jmcneill { 233 1.1 jmcneill struct acpi_wdrt_softc *sc = device_private(self); 234 1.1 jmcneill 235 1.1 jmcneill /* Don't allow detach if watchdog is armed */ 236 1.1 jmcneill if (sc->sc_smw_valid && 237 1.1 jmcneill (sc->sc_smw.smw_mode & WDOG_MODE_MASK) != WDOG_MODE_DISARMED) 238 1.1 jmcneill return EBUSY; 239 1.1 jmcneill 240 1.1 jmcneill if (sc->sc_smw_valid) { 241 1.1 jmcneill sysmon_wdog_unregister(&sc->sc_smw); 242 1.1 jmcneill sc->sc_smw_valid = false; 243 1.1 jmcneill } 244 1.1 jmcneill 245 1.1 jmcneill pmf_device_deregister(self); 246 1.1 jmcneill 247 1.1 jmcneill return 0; 248 1.1 jmcneill } 249 1.1 jmcneill 250 1.1 jmcneill static bool 251 1.1 jmcneill acpi_wdrt_suspend(device_t self, const pmf_qual_t *qual) 252 1.1 jmcneill { 253 1.1 jmcneill struct acpi_wdrt_softc *sc = device_private(self); 254 1.1 jmcneill 255 1.1 jmcneill if (sc->sc_smw_valid == false) 256 1.1 jmcneill return true; 257 1.1 jmcneill 258 1.1 jmcneill /* Don't allow suspend if watchdog is armed */ 259 1.1 jmcneill if ((sc->sc_smw.smw_mode & WDOG_MODE_MASK) != WDOG_MODE_DISARMED) 260 1.1 jmcneill return false; 261 1.1 jmcneill 262 1.1 jmcneill return true; 263 1.1 jmcneill } 264 1.1 jmcneill 265 1.1 jmcneill static int 266 1.1 jmcneill acpi_wdrt_setmode(struct sysmon_wdog *smw) 267 1.1 jmcneill { 268 1.1 jmcneill struct acpi_wdrt_softc *sc = smw->smw_cookie; 269 1.3 christos uint64_t val; 270 1.1 jmcneill 271 1.1 jmcneill DPRINTF(("%s: %s mode 0x%x period %u\n", device_xname(sc->sc_dev), 272 1.1 jmcneill __func__, smw->smw_mode, smw->smw_period)); 273 1.1 jmcneill 274 1.1 jmcneill switch (smw->smw_mode & WDOG_MODE_MASK) { 275 1.1 jmcneill case WDOG_MODE_DISARMED: 276 1.1 jmcneill /* Disable watchdog timer */ 277 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_read_control(sc, &val))) 278 1.1 jmcneill goto failed; 279 1.1 jmcneill val &= ~ACPI_WDRT_CSR_RUNSTOP; 280 1.1 jmcneill val |= ACPI_WDRT_RUNSTOP_STOPPED; 281 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_write_control(sc, val))) 282 1.1 jmcneill goto failed; 283 1.1 jmcneill break; 284 1.1 jmcneill default: 285 1.1 jmcneill if (smw->smw_period == 0) 286 1.1 jmcneill return EINVAL; 287 1.1 jmcneill if (smw->smw_period > sc->sc_max_period) 288 1.1 jmcneill smw->smw_period = sc->sc_max_period; 289 1.1 jmcneill 290 1.1 jmcneill /* Enable watchdog timer */ 291 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_read_control(sc, &val))) 292 1.1 jmcneill goto failed; 293 1.1 jmcneill val &= ~ACPI_WDRT_CSR_RUNSTOP; 294 1.1 jmcneill val &= ~ACPI_WDRT_CSR_ACTION; 295 1.1 jmcneill val |= ACPI_WDRT_ACTION_RESET; 296 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_write_control(sc, val))) 297 1.1 jmcneill goto failed; 298 1.1 jmcneill /* Reset count register */ 299 1.1 jmcneill if (acpi_wdrt_tickle(smw)) 300 1.1 jmcneill goto failed; 301 1.1 jmcneill val |= ACPI_WDRT_RUNSTOP_RUNNING; 302 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_write_control(sc, val))) 303 1.1 jmcneill goto failed; 304 1.1 jmcneill break; 305 1.1 jmcneill } 306 1.1 jmcneill 307 1.1 jmcneill return 0; 308 1.1 jmcneill 309 1.1 jmcneill failed: 310 1.1 jmcneill return EIO; 311 1.1 jmcneill } 312 1.1 jmcneill 313 1.1 jmcneill static int 314 1.1 jmcneill acpi_wdrt_tickle(struct sysmon_wdog *smw) 315 1.1 jmcneill { 316 1.1 jmcneill struct acpi_wdrt_softc *sc = smw->smw_cookie; 317 1.3 christos uint64_t val; 318 1.1 jmcneill 319 1.1 jmcneill DPRINTF(("%s: %s mode 0x%x period %u\n", device_xname(sc->sc_dev), 320 1.1 jmcneill __func__, smw->smw_mode, smw->smw_period)); 321 1.1 jmcneill 322 1.1 jmcneill /* Reset count register */ 323 1.1 jmcneill val = smw->smw_period * sc->sc_period_scale; 324 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_write_count(sc, val))) 325 1.1 jmcneill return EIO; 326 1.1 jmcneill 327 1.1 jmcneill /* Trigger new count interval */ 328 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_read_control(sc, &val))) 329 1.1 jmcneill return EIO; 330 1.1 jmcneill val |= ACPI_WDRT_CSR_TRIGGER; 331 1.1 jmcneill if (ACPI_FAILURE(acpi_wdrt_write_control(sc, val))) 332 1.1 jmcneill return EIO; 333 1.1 jmcneill 334 1.1 jmcneill return 0; 335 1.1 jmcneill } 336 1.1 jmcneill 337 1.1 jmcneill static ACPI_STATUS 338 1.3 christos acpi_wdrt_read_control(struct acpi_wdrt_softc *sc, uint64_t *val) 339 1.1 jmcneill { 340 1.1 jmcneill ACPI_STATUS rv; 341 1.1 jmcneill 342 1.1 jmcneill KASSERT(sc->sc_smw_valid == true); 343 1.1 jmcneill 344 1.1 jmcneill rv = AcpiOsReadMemory(sc->sc_control_reg.Address, 345 1.1 jmcneill val, sc->sc_control_reg.BitWidth); 346 1.1 jmcneill 347 1.2 jmcneill DPRINTF(("%s: %s 0x%" PRIx64 "/%u 0x%08x (%u)\n", 348 1.2 jmcneill device_xname(sc->sc_dev), 349 1.1 jmcneill __func__, sc->sc_control_reg.Address, sc->sc_control_reg.BitWidth, 350 1.1 jmcneill *val, rv)); 351 1.1 jmcneill 352 1.1 jmcneill return rv; 353 1.1 jmcneill } 354 1.1 jmcneill 355 1.1 jmcneill static ACPI_STATUS 356 1.3 christos acpi_wdrt_write_control(struct acpi_wdrt_softc *sc, uint64_t val) 357 1.1 jmcneill { 358 1.1 jmcneill ACPI_STATUS rv; 359 1.1 jmcneill 360 1.1 jmcneill KASSERT(sc->sc_smw_valid == true); 361 1.1 jmcneill 362 1.1 jmcneill rv = AcpiOsWriteMemory(sc->sc_control_reg.Address, 363 1.1 jmcneill val, sc->sc_control_reg.BitWidth); 364 1.1 jmcneill 365 1.2 jmcneill DPRINTF(("%s: %s 0x%" PRIx64 "/%u 0x%08x (%u)\n", 366 1.2 jmcneill device_xname(sc->sc_dev), 367 1.1 jmcneill __func__, sc->sc_control_reg.Address, sc->sc_control_reg.BitWidth, 368 1.1 jmcneill val, rv)); 369 1.1 jmcneill 370 1.1 jmcneill return rv; 371 1.1 jmcneill } 372 1.1 jmcneill 373 1.1 jmcneill #if 0 374 1.1 jmcneill static ACPI_STATUS 375 1.1 jmcneill acpi_wdrt_read_count(struct acpi_wdrt_softc *sc, uint32_t *val) 376 1.1 jmcneill { 377 1.1 jmcneill ACPI_STATUS rv; 378 1.1 jmcneill 379 1.1 jmcneill KASSERT(sc->sc_smw_valid == true); 380 1.1 jmcneill 381 1.1 jmcneill rv = AcpiOsReadMemory(sc->sc_count_reg.Address, 382 1.1 jmcneill val, sc->sc_count_reg.BitWidth); 383 1.1 jmcneill 384 1.2 jmcneill DPRINTF(("%s: %s 0x%" PRIx64 "/%u 0x%08x (%u)\n", 385 1.2 jmcneill device_xname(sc->sc_dev), 386 1.1 jmcneill __func__, sc->sc_count_reg.Address, sc->sc_count_reg.BitWidth, 387 1.1 jmcneill *val, rv)); 388 1.1 jmcneill 389 1.1 jmcneill return rv; 390 1.1 jmcneill } 391 1.1 jmcneill #endif 392 1.1 jmcneill 393 1.1 jmcneill static ACPI_STATUS 394 1.1 jmcneill acpi_wdrt_write_count(struct acpi_wdrt_softc *sc, uint32_t val) 395 1.1 jmcneill { 396 1.1 jmcneill ACPI_STATUS rv; 397 1.1 jmcneill 398 1.1 jmcneill KASSERT(sc->sc_smw_valid == true); 399 1.1 jmcneill 400 1.1 jmcneill rv = AcpiOsWriteMemory(sc->sc_count_reg.Address, 401 1.1 jmcneill val, sc->sc_count_reg.BitWidth); 402 1.1 jmcneill 403 1.2 jmcneill DPRINTF(("%s: %s 0x%" PRIx64 "/%u 0x%08x (%u)\n", 404 1.2 jmcneill device_xname(sc->sc_dev), 405 1.1 jmcneill __func__, sc->sc_count_reg.Address, sc->sc_count_reg.BitWidth, 406 1.1 jmcneill val, rv)); 407 1.1 jmcneill 408 1.1 jmcneill return rv; 409 1.1 jmcneill } 410 1.1 jmcneill 411 1.4 pgoyette MODULE(MODULE_CLASS_DRIVER, acpiwdrt, "sysmon_wdog"); 412 1.1 jmcneill 413 1.1 jmcneill #ifdef _MODULE 414 1.1 jmcneill #include "ioconf.c" 415 1.1 jmcneill #endif 416 1.1 jmcneill 417 1.1 jmcneill static int 418 1.1 jmcneill acpiwdrt_modcmd(modcmd_t cmd, void *opaque) 419 1.1 jmcneill { 420 1.1 jmcneill int error = 0; 421 1.1 jmcneill 422 1.1 jmcneill switch (cmd) { 423 1.1 jmcneill case MODULE_CMD_INIT: 424 1.1 jmcneill #ifdef _MODULE 425 1.1 jmcneill error = config_init_component(cfdriver_ioconf_acpiwdrt, 426 1.1 jmcneill cfattach_ioconf_acpiwdrt, cfdata_ioconf_acpiwdrt); 427 1.1 jmcneill #endif 428 1.1 jmcneill return error; 429 1.1 jmcneill case MODULE_CMD_FINI: 430 1.1 jmcneill #ifdef _MODULE 431 1.1 jmcneill error = config_fini_component(cfdriver_ioconf_acpiwdrt, 432 1.1 jmcneill cfattach_ioconf_acpiwdrt, cfdata_ioconf_acpiwdrt); 433 1.1 jmcneill #endif 434 1.1 jmcneill return error; 435 1.1 jmcneill default: 436 1.1 jmcneill return ENOTTY; 437 1.1 jmcneill } 438 1.1 jmcneill } 439