1 /* $NetBSD: elan520.c,v 1.52 2021/08/07 16:18:55 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Device driver for the AMD Elan SC520 System Controller. This attaches 34 * where the "pchb" driver might normally attach, and provides support for 35 * extra features on the SC520, such as the watchdog timer and GPIO. 36 * 37 * Information about the GP bus echo bug work-around is from code posted 38 * to the "soekris-tech" mailing list by Jasper Wallace. 39 */ 40 41 #include <sys/cdefs.h> 42 43 __KERNEL_RCSID(0, "$NetBSD: elan520.c,v 1.52 2021/08/07 16:18:55 thorpej Exp $"); 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/time.h> 48 #include <sys/device.h> 49 #include <sys/gpio.h> 50 #include <sys/mutex.h> 51 #include <sys/wdog.h> 52 #include <sys/reboot.h> 53 54 #include <uvm/uvm_extern.h> 55 56 #include <sys/bus.h> 57 58 #include <x86/nmi.h> 59 60 #include <dev/pci/pcivar.h> 61 62 #include <dev/pci/pcidevs.h> 63 64 #include "gpio.h" 65 #if NGPIO > 0 66 #include <dev/gpio/gpiovar.h> 67 #endif 68 69 #include <arch/i386/pci/elan520reg.h> 70 71 #include <dev/sysmon/sysmonvar.h> 72 73 #define ELAN_IRQ 1 74 #define PG0_PROT_SIZE PAGE_SIZE 75 76 struct elansc_softc { 77 device_t sc_dev; 78 device_t sc_gpio; 79 device_t sc_par; 80 device_t sc_pex; 81 device_t sc_pci; 82 83 pci_chipset_tag_t sc_pc; 84 pcitag_t sc_tag; 85 bus_dma_tag_t sc_dmat; 86 bus_dma_tag_t sc_dmat64; 87 bus_space_tag_t sc_iot; 88 bus_space_tag_t sc_memt; 89 bus_space_handle_t sc_memh; 90 int sc_pciflags; 91 92 int sc_echobug; 93 94 kmutex_t sc_mtx; 95 96 struct sysmon_wdog sc_smw; 97 void *sc_eih; 98 void *sc_pih; 99 void *sc_sh; 100 uint8_t sc_mpicmode; 101 uint8_t sc_picicr; 102 int sc_pg0par; 103 int sc_textpar[3]; 104 #if NGPIO > 0 105 /* GPIO interface */ 106 struct gpio_chipset_tag sc_gpio_gc; 107 gpio_pin_t sc_gpio_pins[ELANSC_PIO_NPINS]; 108 #endif 109 }; 110 111 struct pareg { 112 paddr_t start; 113 paddr_t end; 114 }; 115 116 static bool elansc_attached = false; 117 int elansc_wpvnmi = 1; 118 int elansc_pcinmi = 1; 119 int elansc_do_protect_pg0 = 1; 120 121 #if NGPIO > 0 122 static int elansc_gpio_pin_read(void *, int); 123 static void elansc_gpio_pin_write(void *, int, int); 124 static void elansc_gpio_pin_ctl(void *, int, int); 125 #endif 126 127 static void elansc_print_par(device_t, int, uint32_t); 128 129 static void elanpar_intr_establish(device_t, struct elansc_softc *); 130 static void elanpar_intr_disestablish(struct elansc_softc *); 131 static bool elanpar_shutdown(device_t, int); 132 133 static void elanpex_intr_establish(device_t, struct elansc_softc *); 134 static void elanpex_intr_disestablish(struct elansc_softc *); 135 static bool elanpex_shutdown(device_t, int); 136 static int elansc_rescan(device_t, const char *, const int *); 137 138 static void elansc_protect(struct elansc_softc *, int, paddr_t, uint32_t); 139 static bool elansc_shutdown(device_t, int); 140 141 static const uint32_t sfkb = 64 * 1024, fkb = 4 * 1024; 142 143 static void 144 elansc_childdetached(device_t self, device_t child) 145 { 146 struct elansc_softc *sc = device_private(self); 147 148 if (child == sc->sc_par) 149 sc->sc_par = NULL; 150 if (child == sc->sc_pex) 151 sc->sc_pex = NULL; 152 if (child == sc->sc_pci) 153 sc->sc_pci = NULL; 154 if (child == sc->sc_gpio) 155 sc->sc_gpio = NULL; 156 } 157 158 static int 159 elansc_match(device_t parent, cfdata_t match, void *aux) 160 { 161 struct pcibus_attach_args *pba = aux; 162 pcitag_t tag; 163 pcireg_t id; 164 165 if (elansc_attached) 166 return 0; 167 168 if (pcimatch(parent, match, aux) == 0) 169 return 0; 170 171 if (pba->pba_bus != 0) 172 return 0; 173 174 tag = pci_make_tag(pba->pba_pc, 0, 0, 0); 175 id = pci_conf_read(pba->pba_pc, tag, PCI_ID_REG); 176 177 if (PCI_VENDOR(id) == PCI_VENDOR_AMD && 178 PCI_PRODUCT(id) == PCI_PRODUCT_AMD_SC520_SC) 179 return 10; 180 181 return 0; 182 } 183 184 /* 185 * Performance tuning for Soekris net4501: 186 * - enable SDRAM write buffer and read prefetching 187 */ 188 #if 0 189 uint8_t dbctl; 190 191 dbctl = bus_space_read_1(memt, memh, MMCR_DBCTL); 192 dbctl &= ~MMCR_DBCTL_WB_WM_MASK; 193 dbctl |= MMCR_DBCTL_WB_WM_16DW; 194 dbctl |= MMCR_DBCTL_WB_ENB | MMCR_DBCTL_RAB_ENB; 195 bus_space_write_1(memt, memh, MMCR_DBCTL, dbctl); 196 #endif 197 198 /* 199 * Performance tuning for PCI bus on the AMD Elan SC520: 200 * - enable concurrent arbitration of PCI and CPU busses 201 * (and PCI buffer) 202 * - enable PCI automatic delayed read transactions and 203 * write posting 204 * - enable PCI read buffer snooping (coherency) 205 */ 206 static void 207 elansc_perf_tune(device_t self, bus_space_tag_t memt, bus_space_handle_t memh) 208 { 209 uint8_t sysarbctl; 210 uint16_t hbctl; 211 const bool concurrency = true; /* concurrent bus arbitration */ 212 213 sysarbctl = bus_space_read_1(memt, memh, MMCR_SYSARBCTL); 214 if ((sysarbctl & MMCR_SYSARBCTL_CNCR_MODE_ENB) != 0) { 215 aprint_debug_dev(self, 216 "concurrent arbitration mode is active\n"); 217 } else if (concurrency) { 218 aprint_verbose_dev(self, "activating concurrent " 219 "arbitration mode\n"); 220 /* activate concurrent bus arbitration */ 221 sysarbctl |= MMCR_SYSARBCTL_CNCR_MODE_ENB; 222 bus_space_write_1(memt, memh, MMCR_SYSARBCTL, sysarbctl); 223 } 224 225 hbctl = bus_space_read_2(memt, memh, MMCR_HBCTL); 226 227 /* target read FIFO snoop */ 228 if ((hbctl & MMCR_HBCTL_T_PURGE_RD_ENB) != 0) 229 aprint_debug_dev(self, "read-FIFO snooping is active\n"); 230 else { 231 aprint_verbose_dev(self, "activating read-FIFO snooping\n"); 232 hbctl |= MMCR_HBCTL_T_PURGE_RD_ENB; 233 } 234 235 if ((hbctl & MMCR_HBCTL_M_WPOST_ENB) != 0) 236 aprint_debug_dev(self, "CPU->PCI write-posting is active\n"); 237 else if (concurrency) { 238 aprint_verbose_dev(self, "activating CPU->PCI write-posting\n"); 239 hbctl |= MMCR_HBCTL_M_WPOST_ENB; 240 } 241 242 /* auto delay read txn: looks safe, but seems to cause 243 * net4526 w/ minipci ath fits 244 */ 245 #if 0 246 if ((hbctl & MMCR_HBCTL_T_DLYTR_ENB_AUTORETRY) != 0) 247 aprint_debug_dev(self, 248 "automatic read transaction delay is active\n"); 249 else { 250 aprint_verbose_dev(self, 251 "activating automatic read transaction delay\n"); 252 hbctl |= MMCR_HBCTL_T_DLYTR_ENB_AUTORETRY; 253 } 254 #endif 255 bus_space_write_2(memt, memh, MMCR_HBCTL, hbctl); 256 } 257 258 static void 259 elansc_wdogctl_write(struct elansc_softc *sc, uint16_t val) 260 { 261 uint8_t echo_mode = 0; /* XXX: gcc */ 262 263 KASSERT(mutex_owned(&sc->sc_mtx)); 264 265 /* Switch off GP bus echo mode if we need to. */ 266 if (sc->sc_echobug) { 267 echo_mode = bus_space_read_1(sc->sc_memt, sc->sc_memh, 268 MMCR_GPECHO); 269 bus_space_write_1(sc->sc_memt, sc->sc_memh, 270 MMCR_GPECHO, echo_mode & ~GPECHO_GP_ECHO_ENB); 271 } 272 273 /* Unlock the register. */ 274 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WDTMRCTL, 275 WDTMRCTL_UNLOCK1); 276 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WDTMRCTL, 277 WDTMRCTL_UNLOCK2); 278 279 /* Write the value. */ 280 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WDTMRCTL, val); 281 282 /* Switch GP bus echo mode back. */ 283 if (sc->sc_echobug) 284 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_GPECHO, 285 echo_mode); 286 } 287 288 static void 289 elansc_wdogctl_reset(struct elansc_softc *sc) 290 { 291 uint8_t echo_mode = 0/* XXX: gcc */; 292 293 KASSERT(mutex_owned(&sc->sc_mtx)); 294 295 /* Switch off GP bus echo mode if we need to. */ 296 if (sc->sc_echobug) { 297 echo_mode = bus_space_read_1(sc->sc_memt, sc->sc_memh, 298 MMCR_GPECHO); 299 bus_space_write_1(sc->sc_memt, sc->sc_memh, 300 MMCR_GPECHO, echo_mode & ~GPECHO_GP_ECHO_ENB); 301 } 302 303 /* Reset the watchdog. */ 304 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WDTMRCTL, 305 WDTMRCTL_RESET1); 306 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WDTMRCTL, 307 WDTMRCTL_RESET2); 308 309 /* Switch GP bus echo mode back. */ 310 if (sc->sc_echobug) 311 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_GPECHO, 312 echo_mode); 313 } 314 315 static const struct { 316 int period; /* whole seconds */ 317 uint16_t exp; /* exponent select */ 318 } elansc_wdog_periods[] = { 319 { 1, WDTMRCTL_EXP_SEL25 }, 320 { 2, WDTMRCTL_EXP_SEL26 }, 321 { 4, WDTMRCTL_EXP_SEL27 }, 322 { 8, WDTMRCTL_EXP_SEL28 }, 323 { 16, WDTMRCTL_EXP_SEL29 }, 324 { 32, WDTMRCTL_EXP_SEL30 }, 325 { 0, 0 }, 326 }; 327 328 static int 329 elansc_wdog_arm(struct elansc_softc *sc) 330 { 331 struct sysmon_wdog *smw = &sc->sc_smw; 332 int i; 333 uint16_t exp_sel = 0; /* XXX: gcc */ 334 335 KASSERT(mutex_owned(&sc->sc_mtx)); 336 337 if (smw->smw_period == WDOG_PERIOD_DEFAULT) { 338 smw->smw_period = 32; 339 exp_sel = WDTMRCTL_EXP_SEL30; 340 } else { 341 for (i = 0; elansc_wdog_periods[i].period != 0; i++) { 342 if (elansc_wdog_periods[i].period == 343 smw->smw_period) { 344 exp_sel = elansc_wdog_periods[i].exp; 345 break; 346 } 347 } 348 if (elansc_wdog_periods[i].period == 0) 349 return EINVAL; 350 } 351 elansc_wdogctl_write(sc, WDTMRCTL_ENB | 352 WDTMRCTL_WRST_ENB | exp_sel); 353 elansc_wdogctl_reset(sc); 354 return 0; 355 } 356 357 static int 358 elansc_wdog_setmode(struct sysmon_wdog *smw) 359 { 360 struct elansc_softc *sc = smw->smw_cookie; 361 int rc = 0; 362 363 mutex_enter(&sc->sc_mtx); 364 365 if (!device_is_active(sc->sc_dev)) 366 rc = EBUSY; 367 else if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { 368 elansc_wdogctl_write(sc, 369 WDTMRCTL_WRST_ENB | WDTMRCTL_EXP_SEL30); 370 } else 371 rc = elansc_wdog_arm(sc); 372 373 mutex_exit(&sc->sc_mtx); 374 return rc; 375 } 376 377 static int 378 elansc_wdog_tickle(struct sysmon_wdog *smw) 379 { 380 struct elansc_softc *sc = smw->smw_cookie; 381 382 mutex_enter(&sc->sc_mtx); 383 elansc_wdogctl_reset(sc); 384 mutex_exit(&sc->sc_mtx); 385 return 0; 386 } 387 388 static const char *elansc_speeds[] = { 389 "(reserved 00)", 390 "100MHz", 391 "133MHz", 392 "(reserved 11)", 393 }; 394 395 static int 396 elanpar_intr(void *arg) 397 { 398 struct elansc_softc *sc = arg; 399 uint16_t wpvsta; 400 unsigned win; 401 uint32_t par; 402 const char *wpvstr; 403 404 wpvsta = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_WPVSTA); 405 406 if ((wpvsta & MMCR_WPVSTA_WPV_STA) == 0) 407 return 0; 408 409 win = __SHIFTOUT(wpvsta, MMCR_WPVSTA_WPV_WINDOW); 410 411 par = bus_space_read_4(sc->sc_memt, sc->sc_memh, MMCR_PAR(win)); 412 413 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WPVSTA, 414 MMCR_WPVSTA_WPV_STA); 415 416 switch (wpvsta & MMCR_WPVSTA_WPV_MSTR) { 417 case MMCR_WPVSTA_WPV_MSTR_CPU: 418 wpvstr = "cpu"; 419 break; 420 case MMCR_WPVSTA_WPV_MSTR_PCI: 421 wpvstr = "pci"; 422 break; 423 case MMCR_WPVSTA_WPV_MSTR_GP: 424 wpvstr = "gp"; 425 break; 426 default: 427 wpvstr = "unknown"; 428 break; 429 } 430 printf_tolog("%s: %s violated write-protect window %u\n", 431 device_xname(sc->sc_par), wpvstr, win); 432 elansc_print_par(sc->sc_par, win, par); 433 return 0; 434 } 435 436 static int 437 elanpar_nmi(const struct trapframe *tf, void *arg) 438 { 439 440 return elanpar_intr(arg); 441 } 442 443 static int 444 elanpex_intr(void *arg) 445 { 446 static struct { 447 const char *string; 448 bool nonfatal; 449 } cmd[16] = { 450 [0] = {.string = "not latched"} 451 , [1] = {.string = "special cycle"} 452 , [2] = {.string = "i/o read"} 453 , [3] = {.string = "i/o write"} 454 , [4] = {.string = "4"} 455 , [5] = {.string = "5"} 456 , [6] = {.string = "memory rd"} 457 , [7] = {.string = "memory wr"} 458 , [8] = {.string = "8"} 459 , [9] = {.string = "9"} 460 , [10] = {.string = "cfg rd", .nonfatal = true} 461 , [11] = {.string = "cfg wr"} 462 , [12] = {.string = "memory rd mul"} 463 , [13] = {.string = "dual-address cycle"} 464 , [14] = {.string = "memory rd line"} 465 , [15] = {.string = "memory wr & inv"} 466 }; 467 468 static const struct { 469 uint16_t bit; 470 const char *msg; 471 } mmsg[] = { 472 {MMCR_HBMSTIRQSTA_M_RTRTO_IRQ_STA, "retry timeout"} 473 , {MMCR_HBMSTIRQSTA_M_TABRT_IRQ_STA, "target abort"} 474 , {MMCR_HBMSTIRQSTA_M_MABRT_IRQ_STA, "abort"} 475 , {MMCR_HBMSTIRQSTA_M_SERR_IRQ_STA, "system error"} 476 , {MMCR_HBMSTIRQSTA_M_RPER_IRQ_STA, "received parity error"} 477 , {MMCR_HBMSTIRQSTA_M_DPER_IRQ_STA, "detected parity error"} 478 }, tmsg[] = { 479 {MMCR_HBTGTIRQSTA_T_DLYTO_IRQ_STA, "delayed txn timeout"} 480 , {MMCR_HBTGTIRQSTA_T_APER_IRQ_STA, "address parity"} 481 , {MMCR_HBTGTIRQSTA_T_DPER_IRQ_STA, "data parity"} 482 }; 483 uint8_t pciarbsta; 484 uint16_t mstcmd, mstirq, tgtid, tgtirq; 485 uint32_t mstaddr; 486 uint16_t mstack = 0, tgtack = 0; 487 int fatal = 0, i, handled = 0; 488 struct elansc_softc *sc = arg; 489 490 pciarbsta = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_PCIARBSTA); 491 mstirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQSTA); 492 mstaddr = bus_space_read_4(sc->sc_memt, sc->sc_memh, MMCR_MSTINTADD); 493 tgtirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQSTA); 494 495 if ((pciarbsta & MMCR_PCIARBSTA_GNT_TO_STA) != 0) { 496 printf_tolog( 497 "%s: grant time-out, GNT%" __PRIuBITS "# asserted\n", 498 device_xname(sc->sc_pex), 499 __SHIFTOUT(pciarbsta, MMCR_PCIARBSTA_GNT_TO_ID)); 500 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_PCIARBSTA, 501 MMCR_PCIARBSTA_GNT_TO_STA); 502 handled = true; 503 } 504 505 mstcmd = __SHIFTOUT(mstirq, MMCR_HBMSTIRQSTA_M_CMD_IRQ_ID); 506 507 for (i = 0; i < __arraycount(mmsg); i++) { 508 if ((mstirq & mmsg[i].bit) == 0) 509 continue; 510 printf_tolog("%s: %s %08" PRIx32 " master %s\n", 511 device_xname(sc->sc_pex), cmd[mstcmd].string, mstaddr, 512 mmsg[i].msg); 513 514 mstack |= mmsg[i].bit; 515 if (!cmd[mstcmd].nonfatal) 516 fatal = true; 517 } 518 519 tgtid = __SHIFTOUT(tgtirq, MMCR_HBTGTIRQSTA_T_IRQ_ID); 520 521 for (i = 0; i < __arraycount(tmsg); i++) { 522 if ((tgtirq & tmsg[i].bit) == 0) 523 continue; 524 printf_tolog("%s: %1x target %s\n", device_xname(sc->sc_pex), 525 tgtid, tmsg[i].msg); 526 tgtack |= tmsg[i].bit; 527 } 528 529 /* acknowledge interrupts */ 530 if (tgtack != 0) { 531 handled = true; 532 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQSTA, 533 tgtack); 534 } 535 if (mstack != 0) { 536 handled = true; 537 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQSTA, 538 mstack); 539 } 540 return fatal ? 0 : (handled ? 1 : 0); 541 } 542 543 static int 544 elanpex_nmi(const struct trapframe *tf, void *arg) 545 { 546 547 return elanpex_intr(arg); 548 } 549 550 #define elansc_print_1(__dev, __sc, __reg) \ 551 do { \ 552 aprint_debug_dev(__dev, \ 553 "%s: %s %02" PRIx8 "\n", __func__, #__reg, \ 554 bus_space_read_1((__sc)->sc_memt, (__sc)->sc_memh, __reg)); \ 555 } while (/*CONSTCOND*/0) 556 557 static void 558 elansc_print_par(device_t dev, int i, uint32_t par) 559 { 560 uint32_t addr, sz, unit; 561 const char *tgtstr; 562 563 if ((boothowto & AB_DEBUG) == 0) 564 return; 565 566 switch (par & MMCR_PAR_TARGET) { 567 default: 568 case MMCR_PAR_TARGET_OFF: 569 tgtstr = "off"; 570 break; 571 case MMCR_PAR_TARGET_GPIO: 572 tgtstr = "gpio"; 573 break; 574 case MMCR_PAR_TARGET_GPMEM: 575 tgtstr = "gpmem"; 576 break; 577 case MMCR_PAR_TARGET_PCI: 578 tgtstr = "pci"; 579 break; 580 case MMCR_PAR_TARGET_BOOTCS: 581 tgtstr = "bootcs"; 582 break; 583 case MMCR_PAR_TARGET_ROMCS1: 584 tgtstr = "romcs1"; 585 break; 586 case MMCR_PAR_TARGET_ROMCS2: 587 tgtstr = "romcs2"; 588 break; 589 case MMCR_PAR_TARGET_SDRAM: 590 tgtstr = "sdram"; 591 break; 592 } 593 if ((par & MMCR_PAR_TARGET) == MMCR_PAR_TARGET_GPIO) { 594 unit = 1; 595 sz = __SHIFTOUT(par, MMCR_PAR_IO_SZ); 596 addr = __SHIFTOUT(par, MMCR_PAR_IO_ST_ADR); 597 } else if ((par & MMCR_PAR_PG_SZ) != 0) { 598 unit = 64 * 1024; 599 sz = __SHIFTOUT(par, MMCR_PAR_64KB_SZ); 600 addr = __SHIFTOUT(par, MMCR_PAR_64KB_ST_ADR); 601 } else { 602 unit = 4 * 1024; 603 sz = __SHIFTOUT(par, MMCR_PAR_4KB_SZ); 604 addr = __SHIFTOUT(par, MMCR_PAR_4KB_ST_ADR); 605 } 606 607 printf_tolog( 608 "%s: PAR[%d] %08" PRIx32 " tgt %s attr %1" __PRIxBITS 609 " start %08" PRIx32 " size %" PRIu32 "\n", device_xname(dev), 610 i, par, tgtstr, __SHIFTOUT(par, MMCR_PAR_ATTR), 611 addr * unit, (sz + 1) * unit); 612 } 613 614 static void 615 elansc_print_all_par(device_t dev, 616 bus_space_tag_t memt, bus_space_handle_t memh) 617 { 618 int i; 619 uint32_t par; 620 621 for (i = 0; i < 16; i++) { 622 par = bus_space_read_4(memt, memh, MMCR_PAR(i)); 623 elansc_print_par(dev, i, par); 624 } 625 } 626 627 static int 628 elansc_alloc_par(bus_space_tag_t memt, bus_space_handle_t memh) 629 { 630 int i; 631 uint32_t par; 632 633 for (i = 0; i < 16; i++) { 634 635 par = bus_space_read_4(memt, memh, MMCR_PAR(i)); 636 637 if ((par & MMCR_PAR_TARGET) == MMCR_PAR_TARGET_OFF) 638 break; 639 } 640 if (i == 16) 641 return -1; 642 return i; 643 } 644 645 static void 646 elansc_disable_par(bus_space_tag_t memt, bus_space_handle_t memh, int idx) 647 { 648 uint32_t par; 649 par = bus_space_read_4(memt, memh, MMCR_PAR(idx)); 650 par &= ~MMCR_PAR_TARGET; 651 par |= MMCR_PAR_TARGET_OFF; 652 bus_space_write_4(memt, memh, MMCR_PAR(idx), par); 653 } 654 655 static int 656 region_paddr_to_par(struct pareg *region0, struct pareg *regions, uint32_t unit) 657 { 658 struct pareg *residue = regions; 659 paddr_t start, end; 660 paddr_t start0, end0; 661 662 start0 = region0->start; 663 end0 = region0->end; 664 665 if (start0 % unit != 0) 666 start = start0 + unit - start0 % unit; 667 else 668 start = start0; 669 670 end = end0 - end0 % unit; 671 672 if (start >= end) 673 return 0; 674 675 residue->start = start; 676 residue->end = end; 677 residue++; 678 679 if (start0 < start) { 680 residue->start = start0; 681 residue->end = start; 682 residue++; 683 } 684 if (end < end0) { 685 residue->start = end; 686 residue->end = end0; 687 residue++; 688 } 689 return residue - regions; 690 } 691 692 static void 693 elansc_protect_text(device_t self, struct elansc_softc *sc) 694 { 695 int i, j, nregion, pidx, tidx = 0, xnregion; 696 uint32_t protsize, unprotsize; 697 paddr_t start_pa, end_pa; 698 extern char kernel_text, etext; 699 bus_space_tag_t memt; 700 bus_space_handle_t memh; 701 struct pareg region0, regions[3], xregions[3]; 702 703 sc->sc_textpar[0] = sc->sc_textpar[1] = sc->sc_textpar[2] = -1; 704 705 memt = sc->sc_memt; 706 memh = sc->sc_memh; 707 708 if (!pmap_extract(pmap_kernel(), (vaddr_t)&kernel_text, 709 ®ion0.start) || 710 !pmap_extract(pmap_kernel(), (vaddr_t)&etext, 711 ®ion0.end)) 712 return; 713 714 if (&etext - &kernel_text != region0.end - region0.start) { 715 aprint_error_dev(self, "kernel text may not be contiguous\n"); 716 return; 717 } 718 719 if ((pidx = elansc_alloc_par(memt, memh)) == -1) { 720 aprint_error_dev(self, "cannot allocate PAR\n"); 721 return; 722 } 723 724 (void) bus_space_read_4(memt, memh, MMCR_PAR(pidx)); 725 726 aprint_debug_dev(self, 727 "protect kernel text at physical addresses " 728 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 729 region0.start, region0.end); 730 731 nregion = region_paddr_to_par(®ion0, regions, sfkb); 732 if (nregion == 0) { 733 aprint_error_dev(self, "kernel text is unprotected\n"); 734 return; 735 } 736 737 unprotsize = 0; 738 for (i = 1; i < nregion; i++) 739 unprotsize += regions[i].end - regions[i].start; 740 741 start_pa = regions[0].start; 742 end_pa = regions[0].end; 743 744 aprint_debug_dev(self, 745 "actually protect kernel text at physical addresses " 746 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 747 start_pa, end_pa); 748 749 aprint_verbose_dev(self, 750 "%" PRIu32 " bytes of kernel text are unprotected\n", unprotsize); 751 752 protsize = end_pa - start_pa; 753 754 elansc_protect(sc, pidx, start_pa, protsize); 755 756 sc->sc_textpar[tidx++] = pidx; 757 758 unprotsize = 0; 759 for (i = 1; i < nregion; i++) { 760 xnregion = region_paddr_to_par(®ions[i], xregions, fkb); 761 if (xnregion == 0) { 762 aprint_verbose_dev(self, "skip region " 763 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 764 regions[i].start, regions[i].end); 765 continue; 766 } 767 if ((pidx = elansc_alloc_par(memt, memh)) == -1) { 768 unprotsize += regions[i].end - regions[i].start; 769 continue; 770 } 771 elansc_protect(sc, pidx, xregions[0].start, 772 xregions[0].end - xregions[0].start); 773 sc->sc_textpar[tidx++] = pidx; 774 775 aprint_debug_dev(self, 776 "protect add'l kernel text at physical addresses " 777 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 778 xregions[0].start, xregions[0].end); 779 780 for (j = 1; j < xnregion; j++) 781 unprotsize += xregions[j].end - xregions[j].start; 782 } 783 aprint_verbose_dev(self, 784 "%" PRIu32 " bytes of kernel text still unprotected\n", unprotsize); 785 786 } 787 788 static void 789 elansc_protect(struct elansc_softc *sc, int pidx, paddr_t addr, uint32_t sz) 790 { 791 uint32_t addr_field, blksz, par, size_field; 792 793 /* set attribute, target. */ 794 par = MMCR_PAR_TARGET_SDRAM | MMCR_PAR_ATTR_NOWRITE; 795 796 KASSERT(addr % fkb == 0 && sz % fkb == 0); 797 798 if (addr % sfkb == 0 && sz % sfkb == 0) { 799 par |= MMCR_PAR_PG_SZ; 800 801 size_field = MMCR_PAR_64KB_SZ; 802 addr_field = MMCR_PAR_64KB_ST_ADR; 803 blksz = 64 * 1024; 804 } else { 805 size_field = MMCR_PAR_4KB_SZ; 806 addr_field = MMCR_PAR_4KB_ST_ADR; 807 blksz = 4 * 1024; 808 } 809 810 KASSERT(sz / blksz - 1 <= __SHIFTOUT_MASK(size_field)); 811 KASSERT(addr / blksz <= __SHIFTOUT_MASK(addr_field)); 812 813 /* set size and address. */ 814 par |= __SHIFTIN(sz / blksz - 1, size_field); 815 par |= __SHIFTIN(addr / blksz, addr_field); 816 817 bus_space_write_4(sc->sc_memt, sc->sc_memh, MMCR_PAR(pidx), par); 818 } 819 820 static int 821 elansc_protect_pg0(device_t self, struct elansc_softc *sc) 822 { 823 int pidx; 824 const paddr_t pg0_paddr = 0; 825 bus_space_tag_t memt; 826 bus_space_handle_t memh; 827 828 memt = sc->sc_memt; 829 memh = sc->sc_memh; 830 831 if (elansc_do_protect_pg0 == 0) 832 return -1; 833 834 if ((pidx = elansc_alloc_par(memt, memh)) == -1) 835 return -1; 836 837 aprint_debug_dev(self, "protect page 0\n"); 838 839 elansc_protect(sc, pidx, pg0_paddr, PG0_PROT_SIZE); 840 return pidx; 841 } 842 843 static void 844 elanpex_intr_ack(bus_space_tag_t memt, bus_space_handle_t memh) 845 { 846 bus_space_write_1(memt, memh, MMCR_PCIARBSTA, 847 MMCR_PCIARBSTA_GNT_TO_STA); 848 bus_space_write_2(memt, memh, MMCR_HBTGTIRQSTA, MMCR_TGTIRQ_ACT); 849 bus_space_write_2(memt, memh, MMCR_HBMSTIRQSTA, MMCR_MSTIRQ_ACT); 850 } 851 852 static bool 853 elansc_suspend(device_t dev, const pmf_qual_t *qual) 854 { 855 bool rc; 856 struct elansc_softc *sc = device_private(dev); 857 858 mutex_enter(&sc->sc_mtx); 859 rc = ((sc->sc_smw.smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED); 860 mutex_exit(&sc->sc_mtx); 861 if (!rc) 862 aprint_debug_dev(dev, "watchdog enabled, suspend forbidden"); 863 return rc; 864 } 865 866 static bool 867 elansc_resume(device_t dev, const pmf_qual_t *qual) 868 { 869 struct elansc_softc *sc = device_private(dev); 870 871 mutex_enter(&sc->sc_mtx); 872 /* Set up the watchdog registers with some defaults. */ 873 elansc_wdogctl_write(sc, WDTMRCTL_WRST_ENB | WDTMRCTL_EXP_SEL30); 874 875 /* ...and clear it. */ 876 elansc_wdogctl_reset(sc); 877 mutex_exit(&sc->sc_mtx); 878 879 elansc_perf_tune(dev, sc->sc_memt, sc->sc_memh); 880 881 return true; 882 } 883 884 static bool 885 elansc_shutdown(device_t self, int how) 886 { 887 struct elansc_softc *sc = device_private(self); 888 889 /* Set up the watchdog registers with some defaults. */ 890 elansc_wdogctl_write(sc, WDTMRCTL_WRST_ENB | WDTMRCTL_EXP_SEL30); 891 892 /* ...and clear it. */ 893 elansc_wdogctl_reset(sc); 894 895 return true; 896 } 897 898 static int 899 elansc_detach(device_t self, int flags) 900 { 901 int rc; 902 struct elansc_softc *sc = device_private(self); 903 904 if ((rc = config_detach_children(self, flags)) != 0) 905 return rc; 906 907 pmf_device_deregister(self); 908 909 if ((flags & DETACH_SHUTDOWN) == 0 && 910 (rc = sysmon_wdog_unregister(&sc->sc_smw)) != 0) { 911 if (rc == ERESTART) 912 rc = EINTR; 913 return rc; 914 } 915 916 mutex_enter(&sc->sc_mtx); 917 918 (void)elansc_shutdown(self, 0); 919 920 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_PICICR, sc->sc_picicr); 921 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_MPICMODE, 922 sc->sc_mpicmode); 923 924 mutex_exit(&sc->sc_mtx); 925 mutex_destroy(&sc->sc_mtx); 926 927 bus_space_unmap(sc->sc_memt, sc->sc_memh, PAGE_SIZE); 928 elansc_attached = false; 929 return 0; 930 } 931 932 static void * 933 elansc_intr_establish(device_t dev, int (*handler)(void *), void *arg) 934 { 935 struct pic *pic; 936 void *ih; 937 938 if ((pic = intr_findpic(ELAN_IRQ)) == NULL) { 939 aprint_error_dev(dev, "PIC for irq %d not found\n", 940 ELAN_IRQ); 941 return NULL; 942 } else if ((ih = intr_establish(ELAN_IRQ, pic, ELAN_IRQ, 943 IST_LEVEL, IPL_HIGH, handler, arg, false)) == NULL) { 944 aprint_error_dev(dev, 945 "could not establish interrupt\n"); 946 return NULL; 947 } 948 aprint_verbose_dev(dev, "interrupting at irq %d\n", ELAN_IRQ); 949 return ih; 950 } 951 952 static bool 953 elanpex_resume(device_t self, const pmf_qual_t *qual) 954 { 955 struct elansc_softc *sc = device_private(device_parent(self)); 956 957 elanpex_intr_establish(self, sc); 958 return sc->sc_eih != NULL; 959 } 960 961 static bool 962 elanpex_suspend(device_t self, const pmf_qual_t *qual) 963 { 964 struct elansc_softc *sc = device_private(device_parent(self)); 965 966 elanpex_intr_disestablish(sc); 967 968 return true; 969 } 970 971 static bool 972 elanpar_resume(device_t self, const pmf_qual_t *qual) 973 { 974 struct elansc_softc *sc = device_private(device_parent(self)); 975 976 elanpar_intr_establish(self, sc); 977 return sc->sc_pih != NULL; 978 } 979 980 static bool 981 elanpar_suspend(device_t self, const pmf_qual_t *qual) 982 { 983 struct elansc_softc *sc = device_private(device_parent(self)); 984 985 elanpar_intr_disestablish(sc); 986 987 return true; 988 } 989 990 static void 991 elanpex_intr_establish(device_t self, struct elansc_softc *sc) 992 { 993 uint8_t sysarbctl; 994 uint16_t pcihostmap, mstirq, tgtirq; 995 996 pcihostmap = bus_space_read_2(sc->sc_memt, sc->sc_memh, 997 MMCR_PCIHOSTMAP); 998 /* Priority P2 (Master PIC IR1) */ 999 pcihostmap &= ~MMCR_PCIHOSTMAP_PCI_IRQ_MAP; 1000 pcihostmap |= __SHIFTIN(__BIT(ELAN_IRQ), MMCR_PCIHOSTMAP_PCI_IRQ_MAP); 1001 if (elansc_pcinmi) 1002 pcihostmap |= MMCR_PCIHOSTMAP_PCI_NMI_ENB; 1003 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_PCIHOSTMAP, 1004 pcihostmap); 1005 1006 elanpex_intr_ack(sc->sc_memt, sc->sc_memh); 1007 1008 sysarbctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL); 1009 mstirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL); 1010 tgtirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL); 1011 1012 sysarbctl |= MMCR_SYSARBCTL_GNT_TO_INT_ENB; 1013 1014 mstirq |= MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_ENB; 1015 mstirq |= MMCR_HBMSTIRQCTL_M_TABRT_IRQ_ENB; 1016 mstirq |= MMCR_HBMSTIRQCTL_M_MABRT_IRQ_ENB; 1017 mstirq |= MMCR_HBMSTIRQCTL_M_SERR_IRQ_ENB; 1018 mstirq |= MMCR_HBMSTIRQCTL_M_RPER_IRQ_ENB; 1019 mstirq |= MMCR_HBMSTIRQCTL_M_DPER_IRQ_ENB; 1020 1021 tgtirq |= MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_ENB; 1022 tgtirq |= MMCR_HBTGTIRQCTL_T_APER_IRQ_ENB; 1023 tgtirq |= MMCR_HBTGTIRQCTL_T_DPER_IRQ_ENB; 1024 1025 if (elansc_pcinmi) { 1026 sc->sc_eih = nmi_establish(elanpex_nmi, sc); 1027 1028 /* Activate NMI instead of maskable interrupts for 1029 * all PCI exceptions: 1030 */ 1031 mstirq |= MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_SEL; 1032 mstirq |= MMCR_HBMSTIRQCTL_M_TABRT_IRQ_SEL; 1033 mstirq |= MMCR_HBMSTIRQCTL_M_MABRT_IRQ_SEL; 1034 mstirq |= MMCR_HBMSTIRQCTL_M_SERR_IRQ_SEL; 1035 mstirq |= MMCR_HBMSTIRQCTL_M_RPER_IRQ_SEL; 1036 mstirq |= MMCR_HBMSTIRQCTL_M_DPER_IRQ_SEL; 1037 1038 tgtirq |= MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_SEL; 1039 tgtirq |= MMCR_HBTGTIRQCTL_T_APER_IRQ_SEL; 1040 tgtirq |= MMCR_HBTGTIRQCTL_T_DPER_IRQ_SEL; 1041 } else 1042 sc->sc_eih = elansc_intr_establish(self, elanpex_intr, sc); 1043 1044 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL, sysarbctl); 1045 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL, mstirq); 1046 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL, tgtirq); 1047 } 1048 1049 static void 1050 elanpex_attach(device_t parent, device_t self, void *aux) 1051 { 1052 struct elansc_softc *sc = device_private(parent); 1053 1054 aprint_naive(": PCI Exceptions\n"); 1055 aprint_normal(": AMD Elan SC520 PCI Exceptions\n"); 1056 1057 elanpex_intr_establish(self, sc); 1058 1059 aprint_debug_dev(self, "HBMSTIRQCTL %04x\n", 1060 bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL)); 1061 1062 aprint_debug_dev(self, "HBTGTIRQCTL %04x\n", 1063 bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL)); 1064 1065 aprint_debug_dev(self, "PCIHOSTMAP %04x\n", 1066 bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_PCIHOSTMAP)); 1067 1068 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, 1069 pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG) | 1070 PCI_COMMAND_PARITY_ENABLE|PCI_COMMAND_SERR_ENABLE); 1071 1072 if (!pmf_device_register1(self, elanpex_suspend, elanpex_resume, 1073 elanpex_shutdown)) 1074 aprint_error_dev(self, "could not establish power hooks\n"); 1075 } 1076 1077 static bool 1078 elanpex_shutdown(device_t self, int flags) 1079 { 1080 struct elansc_softc *sc = device_private(device_parent(self)); 1081 uint8_t sysarbctl; 1082 uint16_t pcihostmap, mstirq, tgtirq; 1083 1084 sysarbctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL); 1085 sysarbctl &= ~MMCR_SYSARBCTL_GNT_TO_INT_ENB; 1086 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL, sysarbctl); 1087 1088 mstirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL); 1089 mstirq &= ~MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_ENB; 1090 mstirq &= ~MMCR_HBMSTIRQCTL_M_TABRT_IRQ_ENB; 1091 mstirq &= ~MMCR_HBMSTIRQCTL_M_MABRT_IRQ_ENB; 1092 mstirq &= ~MMCR_HBMSTIRQCTL_M_SERR_IRQ_ENB; 1093 mstirq &= ~MMCR_HBMSTIRQCTL_M_RPER_IRQ_ENB; 1094 mstirq &= ~MMCR_HBMSTIRQCTL_M_DPER_IRQ_ENB; 1095 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL, mstirq); 1096 1097 tgtirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL); 1098 tgtirq &= ~MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_ENB; 1099 tgtirq &= ~MMCR_HBTGTIRQCTL_T_APER_IRQ_ENB; 1100 tgtirq &= ~MMCR_HBTGTIRQCTL_T_DPER_IRQ_ENB; 1101 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL, tgtirq); 1102 1103 pcihostmap = bus_space_read_2(sc->sc_memt, sc->sc_memh, 1104 MMCR_PCIHOSTMAP); 1105 /* Priority P2 (Master PIC IR1) */ 1106 pcihostmap &= ~MMCR_PCIHOSTMAP_PCI_IRQ_MAP; 1107 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_PCIHOSTMAP, 1108 pcihostmap); 1109 1110 return true; 1111 } 1112 1113 static void 1114 elanpex_intr_disestablish(struct elansc_softc *sc) 1115 { 1116 elanpex_shutdown(sc->sc_pex, 0); 1117 1118 if (elansc_pcinmi) 1119 nmi_disestablish(sc->sc_eih); 1120 else 1121 intr_disestablish(sc->sc_eih); 1122 sc->sc_eih = NULL; 1123 1124 } 1125 1126 static int 1127 elanpex_detach(device_t self, int flags) 1128 { 1129 struct elansc_softc *sc = device_private(device_parent(self)); 1130 1131 pmf_device_deregister(self); 1132 elanpex_intr_disestablish(sc); 1133 1134 return 0; 1135 } 1136 1137 static void 1138 elanpar_intr_establish(device_t self, struct elansc_softc *sc) 1139 { 1140 uint8_t adddecctl, wpvmap; 1141 1142 wpvmap = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP); 1143 wpvmap &= ~MMCR_WPVMAP_INT_MAP; 1144 if (elansc_wpvnmi) 1145 wpvmap |= MMCR_WPVMAP_INT_NMI; 1146 else 1147 wpvmap |= __SHIFTIN(__BIT(ELAN_IRQ), MMCR_WPVMAP_INT_MAP); 1148 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP, wpvmap); 1149 1150 /* clear interrupt status */ 1151 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WPVSTA, 1152 MMCR_WPVSTA_WPV_STA); 1153 1154 /* establish interrupt */ 1155 if (elansc_wpvnmi) 1156 sc->sc_pih = nmi_establish(elanpar_nmi, sc); 1157 else 1158 sc->sc_pih = elansc_intr_establish(self, elanpar_intr, sc); 1159 1160 adddecctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL); 1161 adddecctl |= MMCR_ADDDECCTL_WPV_INT_ENB; 1162 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL, adddecctl); 1163 } 1164 1165 static bool 1166 elanpar_shutdown(device_t self, int flags) 1167 { 1168 int i; 1169 struct elansc_softc *sc = device_private(device_parent(self)); 1170 1171 for (i = 0; i < __arraycount(sc->sc_textpar); i++) { 1172 if (sc->sc_textpar[i] == -1) 1173 continue; 1174 elansc_disable_par(sc->sc_memt, sc->sc_memh, sc->sc_textpar[i]); 1175 sc->sc_textpar[i] = -1; 1176 } 1177 if (sc->sc_pg0par != -1) { 1178 elansc_disable_par(sc->sc_memt, sc->sc_memh, sc->sc_pg0par); 1179 sc->sc_pg0par = -1; 1180 } 1181 return true; 1182 } 1183 1184 static void 1185 elanpar_deferred_attach(device_t self) 1186 { 1187 struct elansc_softc *sc = device_private(device_parent(self)); 1188 1189 elansc_protect_text(self, sc); 1190 } 1191 1192 static void 1193 elanpar_attach(device_t parent, device_t self, void *aux) 1194 { 1195 struct elansc_softc *sc = device_private(parent); 1196 1197 aprint_naive(": Programmable Address Regions\n"); 1198 aprint_normal(": AMD Elan SC520 Programmable Address Regions\n"); 1199 1200 elansc_print_1(self, sc, MMCR_WPVMAP); 1201 elansc_print_all_par(self, sc->sc_memt, sc->sc_memh); 1202 1203 sc->sc_pg0par = elansc_protect_pg0(self, sc); 1204 /* XXX grotty hack to avoid trapping writes by x86_patch() 1205 * to the kernel text on a MULTIPROCESSOR kernel. 1206 */ 1207 config_interrupts(self, elanpar_deferred_attach); 1208 1209 elansc_print_all_par(self, sc->sc_memt, sc->sc_memh); 1210 1211 elanpar_intr_establish(self, sc); 1212 1213 elansc_print_1(self, sc, MMCR_ADDDECCTL); 1214 1215 if (!pmf_device_register1(self, elanpar_suspend, elanpar_resume, 1216 elanpar_shutdown)) 1217 aprint_error_dev(self, "could not establish power hooks\n"); 1218 } 1219 1220 static void 1221 elanpar_intr_disestablish(struct elansc_softc *sc) 1222 { 1223 uint8_t adddecctl, wpvmap; 1224 1225 /* disable interrupt, acknowledge it, disestablish our 1226 * handler, unmap it 1227 */ 1228 adddecctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL); 1229 adddecctl &= ~MMCR_ADDDECCTL_WPV_INT_ENB; 1230 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL, adddecctl); 1231 1232 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WPVSTA, 1233 MMCR_WPVSTA_WPV_STA); 1234 1235 if (elansc_wpvnmi) 1236 nmi_disestablish(sc->sc_pih); 1237 else 1238 intr_disestablish(sc->sc_pih); 1239 sc->sc_pih = NULL; 1240 1241 wpvmap = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP); 1242 wpvmap &= ~MMCR_WPVMAP_INT_MAP; 1243 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP, wpvmap); 1244 } 1245 1246 static int 1247 elanpar_detach(device_t self, int flags) 1248 { 1249 struct elansc_softc *sc = device_private(device_parent(self)); 1250 1251 pmf_device_deregister(self); 1252 1253 elanpar_shutdown(self, 0); 1254 1255 elanpar_intr_disestablish(sc); 1256 1257 return 0; 1258 } 1259 1260 static void 1261 elansc_attach(device_t parent, device_t self, void *aux) 1262 { 1263 struct elansc_softc *sc = device_private(self); 1264 struct pcibus_attach_args *pba = aux; 1265 uint16_t rev; 1266 uint8_t cpuctl, picicr, ressta; 1267 #if NGPIO > 0 1268 int pin, reg, shift; 1269 uint16_t data; 1270 #endif 1271 1272 sc->sc_dev = self; 1273 1274 sc->sc_pc = pba->pba_pc; 1275 sc->sc_pciflags = pba->pba_flags; 1276 sc->sc_dmat = pba->pba_dmat; 1277 sc->sc_dmat64 = pba->pba_dmat64; 1278 sc->sc_tag = pci_make_tag(sc->sc_pc, 0, 0, 0); 1279 1280 aprint_naive(": System Controller\n"); 1281 aprint_normal(": AMD Elan SC520 System Controller\n"); 1282 1283 sc->sc_iot = pba->pba_iot; 1284 sc->sc_memt = pba->pba_memt; 1285 if (bus_space_map(sc->sc_memt, MMCR_BASE_ADDR, PAGE_SIZE, 0, 1286 &sc->sc_memh) != 0) { 1287 aprint_error_dev(sc->sc_dev, "unable to map registers\n"); 1288 return; 1289 } 1290 1291 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_HIGH); 1292 1293 rev = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_REVID); 1294 cpuctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_CPUCTL); 1295 1296 aprint_normal_dev(sc->sc_dev, 1297 "product %d stepping %d.%d, CPU clock %s\n", 1298 (rev & REVID_PRODID) >> REVID_PRODID_SHIFT, 1299 (rev & REVID_MAJSTEP) >> REVID_MAJSTEP_SHIFT, 1300 (rev & REVID_MINSTEP), 1301 elansc_speeds[cpuctl & CPUCTL_CPU_CLK_SPD_MASK]); 1302 1303 /* 1304 * SC520 rev A1 has a bug that affects the watchdog timer. If 1305 * the GP bus echo mode is enabled, writing to the watchdog control 1306 * register is blocked. 1307 * 1308 * The BIOS in some systems (e.g. the Soekris net4501) enables 1309 * GP bus echo for various reasons, so we need to switch it off 1310 * when we talk to the watchdog timer. 1311 * 1312 * XXX The step 1.1 (B1?) in my Soekris net4501 also has this 1313 * XXX problem, so we'll just enable it for all Elan SC520s 1314 * XXX for now. --thorpej (at) NetBSD.org 1315 */ 1316 if (1 || rev == ((PRODID_ELAN_SC520 << REVID_PRODID_SHIFT) | 1317 (0 << REVID_MAJSTEP_SHIFT) | (1))) 1318 sc->sc_echobug = 1; 1319 1320 /* 1321 * Determine cause of the last reset, and issue a warning if it 1322 * was due to watchdog expiry. 1323 */ 1324 ressta = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_RESSTA); 1325 if (ressta & RESSTA_WDT_RST_DET) 1326 aprint_error_dev(sc->sc_dev, 1327 "WARNING: LAST RESET DUE TO WATCHDOG EXPIRATION!\n"); 1328 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_RESSTA, ressta); 1329 1330 elansc_print_1(self, sc, MMCR_MPICMODE); 1331 elansc_print_1(self, sc, MMCR_SL1PICMODE); 1332 elansc_print_1(self, sc, MMCR_SL2PICMODE); 1333 elansc_print_1(self, sc, MMCR_PICICR); 1334 1335 sc->sc_mpicmode = bus_space_read_1(sc->sc_memt, sc->sc_memh, 1336 MMCR_MPICMODE); 1337 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_MPICMODE, 1338 sc->sc_mpicmode | __BIT(ELAN_IRQ)); 1339 1340 sc->sc_picicr = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_PICICR); 1341 picicr = sc->sc_picicr; 1342 if (elansc_pcinmi || elansc_wpvnmi) 1343 picicr |= MMCR_PICICR_NMI_ENB; 1344 #if 0 1345 /* PC/AT compatibility */ 1346 picicr |= MMCR_PICICR_S1_GINT_MODE|MMCR_PICICR_M_GINT_MODE; 1347 #endif 1348 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_PICICR, picicr); 1349 1350 elansc_print_1(self, sc, MMCR_PICICR); 1351 elansc_print_1(self, sc, MMCR_MPICMODE); 1352 1353 mutex_enter(&sc->sc_mtx); 1354 /* Set up the watchdog registers with some defaults. */ 1355 elansc_wdogctl_write(sc, WDTMRCTL_WRST_ENB | WDTMRCTL_EXP_SEL30); 1356 1357 /* ...and clear it. */ 1358 elansc_wdogctl_reset(sc); 1359 mutex_exit(&sc->sc_mtx); 1360 1361 if (!pmf_device_register1(self, elansc_suspend, elansc_resume, 1362 elansc_shutdown)) 1363 aprint_error_dev(self, "could not establish power hooks\n"); 1364 1365 #if NGPIO > 0 1366 /* Initialize GPIO pins array */ 1367 for (pin = 0; pin < ELANSC_PIO_NPINS; pin++) { 1368 sc->sc_gpio_pins[pin].pin_num = pin; 1369 sc->sc_gpio_pins[pin].pin_caps = GPIO_PIN_INPUT | 1370 GPIO_PIN_OUTPUT; 1371 1372 /* Read initial state */ 1373 reg = (pin < 16 ? MMCR_PIODIR15_0 : MMCR_PIODIR31_16); 1374 shift = pin % 16; 1375 data = bus_space_read_2(sc->sc_memt, sc->sc_memh, reg); 1376 if ((data & (1 << shift)) == 0) 1377 sc->sc_gpio_pins[pin].pin_flags = GPIO_PIN_INPUT; 1378 else 1379 sc->sc_gpio_pins[pin].pin_flags = GPIO_PIN_OUTPUT; 1380 if (elansc_gpio_pin_read(sc, pin) == 0) 1381 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_LOW; 1382 else 1383 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_HIGH; 1384 } 1385 1386 /* Create controller tag */ 1387 sc->sc_gpio_gc.gp_cookie = sc; 1388 sc->sc_gpio_gc.gp_pin_read = elansc_gpio_pin_read; 1389 sc->sc_gpio_gc.gp_pin_write = elansc_gpio_pin_write; 1390 sc->sc_gpio_gc.gp_pin_ctl = elansc_gpio_pin_ctl; 1391 1392 #endif /* NGPIO */ 1393 1394 elansc_rescan(sc->sc_dev, "elanparbus", NULL); 1395 elansc_rescan(sc->sc_dev, "elanpexbus", NULL); 1396 elansc_rescan(sc->sc_dev, "gpiobus", NULL); 1397 1398 /* 1399 * Hook up the watchdog timer. 1400 */ 1401 sc->sc_smw.smw_name = device_xname(sc->sc_dev); 1402 sc->sc_smw.smw_cookie = sc; 1403 sc->sc_smw.smw_setmode = elansc_wdog_setmode; 1404 sc->sc_smw.smw_tickle = elansc_wdog_tickle; 1405 sc->sc_smw.smw_period = 32; /* actually 32.54 */ 1406 if (sysmon_wdog_register(&sc->sc_smw) != 0) { 1407 aprint_error_dev(sc->sc_dev, 1408 "unable to register watchdog with sysmon\n"); 1409 } 1410 elansc_attached = true; 1411 elansc_rescan(sc->sc_dev, "pcibus", NULL); 1412 } 1413 1414 static int 1415 elanpex_match(device_t parent, cfdata_t match, void *aux) 1416 { 1417 struct elansc_softc *sc = device_private(parent); 1418 1419 return sc->sc_pex == NULL; 1420 } 1421 1422 static int 1423 elanpar_match(device_t parent, cfdata_t match, void *aux) 1424 { 1425 struct elansc_softc *sc = device_private(parent); 1426 1427 return sc->sc_par == NULL; 1428 } 1429 1430 /* scan for new children */ 1431 static int 1432 elansc_rescan(device_t self, const char *ifattr, const int *locators) 1433 { 1434 struct elansc_softc *sc = device_private(self); 1435 1436 if (ifattr_match(ifattr, "elanparbus") && sc->sc_par == NULL) { 1437 sc->sc_par = config_found(sc->sc_dev, NULL, NULL, 1438 CFARGS(.iattr = "elanparbus")); 1439 } 1440 1441 if (ifattr_match(ifattr, "elanpexbus") && sc->sc_pex == NULL) { 1442 sc->sc_pex = config_found(sc->sc_dev, NULL, NULL, 1443 CFARGS(.iattr = "elanpexbus")); 1444 } 1445 1446 if (ifattr_match(ifattr, "gpiobus") && sc->sc_gpio == NULL) { 1447 #if NGPIO > 0 1448 struct gpiobus_attach_args gba; 1449 1450 memset(&gba, 0, sizeof(gba)); 1451 1452 gba.gba_gc = &sc->sc_gpio_gc; 1453 gba.gba_pins = sc->sc_gpio_pins; 1454 gba.gba_npins = ELANSC_PIO_NPINS; 1455 sc->sc_gpio = config_found(sc->sc_dev, &gba, gpiobus_print, 1456 CFARGS(.iattr = "gpiobus")); 1457 #endif 1458 } 1459 1460 if (ifattr_match(ifattr, "pcibus") && sc->sc_pci == NULL) { 1461 struct pcibus_attach_args pba; 1462 1463 memset(&pba, 0, sizeof(pba)); 1464 pba.pba_iot = sc->sc_iot; 1465 pba.pba_memt = sc->sc_memt; 1466 pba.pba_dmat = sc->sc_dmat; 1467 pba.pba_dmat64 = sc->sc_dmat64; 1468 pba.pba_pc = sc->sc_pc; 1469 pba.pba_flags = sc->sc_pciflags; 1470 pba.pba_bus = 0; 1471 pba.pba_bridgetag = NULL; 1472 sc->sc_pci = config_found(self, &pba, pcibusprint, 1473 CFARGS(.iattr = "pcibus")); 1474 } 1475 1476 return 0; 1477 } 1478 1479 CFATTACH_DECL3_NEW(elanpar, 0, 1480 elanpar_match, elanpar_attach, elanpar_detach, NULL, NULL, NULL, 1481 DVF_DETACH_SHUTDOWN); 1482 1483 CFATTACH_DECL3_NEW(elanpex, 0, 1484 elanpex_match, elanpex_attach, elanpex_detach, NULL, NULL, NULL, 1485 DVF_DETACH_SHUTDOWN); 1486 1487 CFATTACH_DECL3_NEW(elansc, sizeof(struct elansc_softc), 1488 elansc_match, elansc_attach, elansc_detach, NULL, elansc_rescan, 1489 elansc_childdetached, DVF_DETACH_SHUTDOWN); 1490 1491 #if NGPIO > 0 1492 static int 1493 elansc_gpio_pin_read(void *arg, int pin) 1494 { 1495 struct elansc_softc *sc = arg; 1496 int reg, shift; 1497 uint16_t data; 1498 1499 reg = (pin < 16 ? MMCR_PIODATA15_0 : MMCR_PIODATA31_16); 1500 shift = pin % 16; 1501 1502 mutex_enter(&sc->sc_mtx); 1503 data = bus_space_read_2(sc->sc_memt, sc->sc_memh, reg); 1504 mutex_exit(&sc->sc_mtx); 1505 1506 return ((data >> shift) & 0x1); 1507 } 1508 1509 static void 1510 elansc_gpio_pin_write(void *arg, int pin, int value) 1511 { 1512 struct elansc_softc *sc = arg; 1513 int reg, shift; 1514 uint16_t data; 1515 1516 reg = (pin < 16 ? MMCR_PIODATA15_0 : MMCR_PIODATA31_16); 1517 shift = pin % 16; 1518 1519 mutex_enter(&sc->sc_mtx); 1520 data = bus_space_read_2(sc->sc_memt, sc->sc_memh, reg); 1521 if (value == 0) 1522 data &= ~(1 << shift); 1523 else if (value == 1) 1524 data |= (1 << shift); 1525 1526 bus_space_write_2(sc->sc_memt, sc->sc_memh, reg, data); 1527 mutex_exit(&sc->sc_mtx); 1528 } 1529 1530 static void 1531 elansc_gpio_pin_ctl(void *arg, int pin, int flags) 1532 { 1533 struct elansc_softc *sc = arg; 1534 int reg, shift; 1535 uint16_t data; 1536 1537 reg = (pin < 16 ? MMCR_PIODIR15_0 : MMCR_PIODIR31_16); 1538 shift = pin % 16; 1539 mutex_enter(&sc->sc_mtx); 1540 data = bus_space_read_2(sc->sc_memt, sc->sc_memh, reg); 1541 if (flags & GPIO_PIN_INPUT) 1542 data &= ~(1 << shift); 1543 if (flags & GPIO_PIN_OUTPUT) 1544 data |= (1 << shift); 1545 1546 bus_space_write_2(sc->sc_memt, sc->sc_memh, reg, data); 1547 mutex_exit(&sc->sc_mtx); 1548 } 1549 #endif /* NGPIO */ 1550