1 /* $NetBSD: elan520.c,v 1.48 2010/02/26 19:25:07 jym 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.48 2010/02/26 19:25:07 jym 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 <machine/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 par; 697 uint32_t protsize, unprotsize; 698 paddr_t start_pa, end_pa; 699 extern char kernel_text, etext; 700 bus_space_tag_t memt; 701 bus_space_handle_t memh; 702 struct pareg region0, regions[3], xregions[3]; 703 704 sc->sc_textpar[0] = sc->sc_textpar[1] = sc->sc_textpar[2] = -1; 705 706 memt = sc->sc_memt; 707 memh = sc->sc_memh; 708 709 if (!pmap_extract(pmap_kernel(), (vaddr_t)&kernel_text, 710 ®ion0.start) || 711 !pmap_extract(pmap_kernel(), (vaddr_t)&etext, 712 ®ion0.end)) 713 return; 714 715 if (&etext - &kernel_text != region0.end - region0.start) { 716 aprint_error_dev(self, "kernel text may not be contiguous\n"); 717 return; 718 } 719 720 if ((pidx = elansc_alloc_par(memt, memh)) == -1) { 721 aprint_error_dev(self, "cannot allocate PAR\n"); 722 return; 723 } 724 725 par = bus_space_read_4(memt, memh, MMCR_PAR(pidx)); 726 727 aprint_debug_dev(self, 728 "protect kernel text at physical addresses " 729 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 730 region0.start, region0.end); 731 732 nregion = region_paddr_to_par(®ion0, regions, sfkb); 733 if (nregion == 0) { 734 aprint_error_dev(self, "kernel text is unprotected\n"); 735 return; 736 } 737 738 unprotsize = 0; 739 for (i = 1; i < nregion; i++) 740 unprotsize += regions[i].end - regions[i].start; 741 742 start_pa = regions[0].start; 743 end_pa = regions[0].end; 744 745 aprint_debug_dev(self, 746 "actually protect kernel text at physical addresses " 747 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 748 start_pa, end_pa); 749 750 aprint_verbose_dev(self, 751 "%" PRIu32 " bytes of kernel text are unprotected\n", unprotsize); 752 753 protsize = end_pa - start_pa; 754 755 elansc_protect(sc, pidx, start_pa, protsize); 756 757 sc->sc_textpar[tidx++] = pidx; 758 759 unprotsize = 0; 760 for (i = 1; i < nregion; i++) { 761 xnregion = region_paddr_to_par(®ions[i], xregions, fkb); 762 if (xnregion == 0) { 763 aprint_verbose_dev(self, "skip region " 764 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 765 regions[i].start, regions[i].end); 766 continue; 767 } 768 if ((pidx = elansc_alloc_par(memt, memh)) == -1) { 769 unprotsize += regions[i].end - regions[i].start; 770 continue; 771 } 772 elansc_protect(sc, pidx, xregions[0].start, 773 xregions[0].end - xregions[0].start); 774 sc->sc_textpar[tidx++] = pidx; 775 776 aprint_debug_dev(self, 777 "protect add'l kernel text at physical addresses " 778 "%#" PRIxPADDR " - %#" PRIxPADDR "\n", 779 xregions[0].start, xregions[0].end); 780 781 for (j = 1; j < xnregion; j++) 782 unprotsize += xregions[j].end - xregions[j].start; 783 } 784 aprint_verbose_dev(self, 785 "%" PRIu32 " bytes of kernel text still unprotected\n", unprotsize); 786 787 } 788 789 static void 790 elansc_protect(struct elansc_softc *sc, int pidx, paddr_t addr, uint32_t sz) 791 { 792 uint32_t addr_field, blksz, par, size_field; 793 794 /* set attribute, target. */ 795 par = MMCR_PAR_TARGET_SDRAM | MMCR_PAR_ATTR_NOWRITE; 796 797 KASSERT(addr % fkb == 0 && sz % fkb == 0); 798 799 if (addr % sfkb == 0 && sz % sfkb == 0) { 800 par |= MMCR_PAR_PG_SZ; 801 802 size_field = MMCR_PAR_64KB_SZ; 803 addr_field = MMCR_PAR_64KB_ST_ADR; 804 blksz = 64 * 1024; 805 } else { 806 size_field = MMCR_PAR_4KB_SZ; 807 addr_field = MMCR_PAR_4KB_ST_ADR; 808 blksz = 4 * 1024; 809 } 810 811 KASSERT(sz / blksz - 1 <= __SHIFTOUT_MASK(size_field)); 812 KASSERT(addr / blksz <= __SHIFTOUT_MASK(addr_field)); 813 814 /* set size and address. */ 815 par |= __SHIFTIN(sz / blksz - 1, size_field); 816 par |= __SHIFTIN(addr / blksz, addr_field); 817 818 bus_space_write_4(sc->sc_memt, sc->sc_memh, MMCR_PAR(pidx), par); 819 } 820 821 static int 822 elansc_protect_pg0(device_t self, struct elansc_softc *sc) 823 { 824 int pidx; 825 const paddr_t pg0_paddr = 0; 826 bus_space_tag_t memt; 827 bus_space_handle_t memh; 828 829 memt = sc->sc_memt; 830 memh = sc->sc_memh; 831 832 if (elansc_do_protect_pg0 == 0) 833 return -1; 834 835 if ((pidx = elansc_alloc_par(memt, memh)) == -1) 836 return -1; 837 838 aprint_debug_dev(self, "protect page 0\n"); 839 840 elansc_protect(sc, pidx, pg0_paddr, PG0_PROT_SIZE); 841 return pidx; 842 } 843 844 static void 845 elanpex_intr_ack(bus_space_tag_t memt, bus_space_handle_t memh) 846 { 847 bus_space_write_1(memt, memh, MMCR_PCIARBSTA, 848 MMCR_PCIARBSTA_GNT_TO_STA); 849 bus_space_write_2(memt, memh, MMCR_HBTGTIRQSTA, MMCR_TGTIRQ_ACT); 850 bus_space_write_2(memt, memh, MMCR_HBMSTIRQSTA, MMCR_MSTIRQ_ACT); 851 } 852 853 static bool 854 elansc_suspend(device_t dev, const pmf_qual_t *qual) 855 { 856 bool rc; 857 struct elansc_softc *sc = device_private(dev); 858 859 mutex_enter(&sc->sc_mtx); 860 rc = ((sc->sc_smw.smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED); 861 mutex_exit(&sc->sc_mtx); 862 if (!rc) 863 aprint_debug_dev(dev, "watchdog enabled, suspend forbidden"); 864 return rc; 865 } 866 867 static bool 868 elansc_resume(device_t dev, const pmf_qual_t *qual) 869 { 870 struct elansc_softc *sc = device_private(dev); 871 872 mutex_enter(&sc->sc_mtx); 873 /* Set up the watchdog registers with some defaults. */ 874 elansc_wdogctl_write(sc, WDTMRCTL_WRST_ENB | WDTMRCTL_EXP_SEL30); 875 876 /* ...and clear it. */ 877 elansc_wdogctl_reset(sc); 878 mutex_exit(&sc->sc_mtx); 879 880 elansc_perf_tune(dev, sc->sc_memt, sc->sc_memh); 881 882 return true; 883 } 884 885 static bool 886 elansc_shutdown(device_t self, int how) 887 { 888 struct elansc_softc *sc = device_private(self); 889 890 /* Set up the watchdog registers with some defaults. */ 891 elansc_wdogctl_write(sc, WDTMRCTL_WRST_ENB | WDTMRCTL_EXP_SEL30); 892 893 /* ...and clear it. */ 894 elansc_wdogctl_reset(sc); 895 896 return true; 897 } 898 899 static int 900 elansc_detach(device_t self, int flags) 901 { 902 int rc; 903 struct elansc_softc *sc = device_private(self); 904 905 if ((rc = config_detach_children(self, flags)) != 0) 906 return rc; 907 908 pmf_device_deregister(self); 909 910 if ((flags & DETACH_SHUTDOWN) == 0 && 911 (rc = sysmon_wdog_unregister(&sc->sc_smw)) != 0) { 912 if (rc == ERESTART) 913 rc = EINTR; 914 return rc; 915 } 916 917 mutex_enter(&sc->sc_mtx); 918 919 (void)elansc_shutdown(self, 0); 920 921 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_PICICR, sc->sc_picicr); 922 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_MPICMODE, 923 sc->sc_mpicmode); 924 925 mutex_exit(&sc->sc_mtx); 926 mutex_destroy(&sc->sc_mtx); 927 928 bus_space_unmap(sc->sc_memt, sc->sc_memh, PAGE_SIZE); 929 elansc_attached = false; 930 return 0; 931 } 932 933 static void * 934 elansc_intr_establish(device_t dev, int (*handler)(void *), void *arg) 935 { 936 struct pic *pic; 937 void *ih; 938 939 if ((pic = intr_findpic(ELAN_IRQ)) == NULL) { 940 aprint_error_dev(dev, "PIC for irq %d not found\n", 941 ELAN_IRQ); 942 return NULL; 943 } else if ((ih = intr_establish(ELAN_IRQ, pic, ELAN_IRQ, 944 IST_LEVEL, IPL_HIGH, handler, arg, false)) == NULL) { 945 aprint_error_dev(dev, 946 "could not establish interrupt\n"); 947 return NULL; 948 } 949 aprint_verbose_dev(dev, "interrupting at irq %d\n", ELAN_IRQ); 950 return ih; 951 } 952 953 static bool 954 elanpex_resume(device_t self, const pmf_qual_t *qual) 955 { 956 struct elansc_softc *sc = device_private(device_parent(self)); 957 958 elanpex_intr_establish(self, sc); 959 return sc->sc_eih != NULL; 960 } 961 962 static bool 963 elanpex_suspend(device_t self, const pmf_qual_t *qual) 964 { 965 struct elansc_softc *sc = device_private(device_parent(self)); 966 967 elanpex_intr_disestablish(sc); 968 969 return true; 970 } 971 972 static bool 973 elanpar_resume(device_t self, const pmf_qual_t *qual) 974 { 975 struct elansc_softc *sc = device_private(device_parent(self)); 976 977 elanpar_intr_establish(self, sc); 978 return sc->sc_pih != NULL; 979 } 980 981 static bool 982 elanpar_suspend(device_t self, const pmf_qual_t *qual) 983 { 984 struct elansc_softc *sc = device_private(device_parent(self)); 985 986 elanpar_intr_disestablish(sc); 987 988 return true; 989 } 990 991 static void 992 elanpex_intr_establish(device_t self, struct elansc_softc *sc) 993 { 994 uint8_t sysarbctl; 995 uint16_t pcihostmap, mstirq, tgtirq; 996 997 pcihostmap = bus_space_read_2(sc->sc_memt, sc->sc_memh, 998 MMCR_PCIHOSTMAP); 999 /* Priority P2 (Master PIC IR1) */ 1000 pcihostmap &= ~MMCR_PCIHOSTMAP_PCI_IRQ_MAP; 1001 pcihostmap |= __SHIFTIN(__BIT(ELAN_IRQ), MMCR_PCIHOSTMAP_PCI_IRQ_MAP); 1002 if (elansc_pcinmi) 1003 pcihostmap |= MMCR_PCIHOSTMAP_PCI_NMI_ENB; 1004 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_PCIHOSTMAP, 1005 pcihostmap); 1006 1007 elanpex_intr_ack(sc->sc_memt, sc->sc_memh); 1008 1009 sysarbctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL); 1010 mstirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL); 1011 tgtirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL); 1012 1013 sysarbctl |= MMCR_SYSARBCTL_GNT_TO_INT_ENB; 1014 1015 mstirq |= MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_ENB; 1016 mstirq |= MMCR_HBMSTIRQCTL_M_TABRT_IRQ_ENB; 1017 mstirq |= MMCR_HBMSTIRQCTL_M_MABRT_IRQ_ENB; 1018 mstirq |= MMCR_HBMSTIRQCTL_M_SERR_IRQ_ENB; 1019 mstirq |= MMCR_HBMSTIRQCTL_M_RPER_IRQ_ENB; 1020 mstirq |= MMCR_HBMSTIRQCTL_M_DPER_IRQ_ENB; 1021 1022 tgtirq |= MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_ENB; 1023 tgtirq |= MMCR_HBTGTIRQCTL_T_APER_IRQ_ENB; 1024 tgtirq |= MMCR_HBTGTIRQCTL_T_DPER_IRQ_ENB; 1025 1026 if (elansc_pcinmi) { 1027 sc->sc_eih = nmi_establish(elanpex_nmi, sc); 1028 1029 /* Activate NMI instead of maskable interrupts for 1030 * all PCI exceptions: 1031 */ 1032 mstirq |= MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_SEL; 1033 mstirq |= MMCR_HBMSTIRQCTL_M_TABRT_IRQ_SEL; 1034 mstirq |= MMCR_HBMSTIRQCTL_M_MABRT_IRQ_SEL; 1035 mstirq |= MMCR_HBMSTIRQCTL_M_SERR_IRQ_SEL; 1036 mstirq |= MMCR_HBMSTIRQCTL_M_RPER_IRQ_SEL; 1037 mstirq |= MMCR_HBMSTIRQCTL_M_DPER_IRQ_SEL; 1038 1039 tgtirq |= MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_SEL; 1040 tgtirq |= MMCR_HBTGTIRQCTL_T_APER_IRQ_SEL; 1041 tgtirq |= MMCR_HBTGTIRQCTL_T_DPER_IRQ_SEL; 1042 } else 1043 sc->sc_eih = elansc_intr_establish(self, elanpex_intr, sc); 1044 1045 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL, sysarbctl); 1046 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL, mstirq); 1047 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL, tgtirq); 1048 } 1049 1050 static void 1051 elanpex_attach(device_t parent, device_t self, void *aux) 1052 { 1053 struct elansc_softc *sc = device_private(parent); 1054 1055 aprint_naive(": PCI Exceptions\n"); 1056 aprint_normal(": AMD Elan SC520 PCI Exceptions\n"); 1057 1058 elanpex_intr_establish(self, sc); 1059 1060 aprint_debug_dev(self, "HBMSTIRQCTL %04x\n", 1061 bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL)); 1062 1063 aprint_debug_dev(self, "HBTGTIRQCTL %04x\n", 1064 bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL)); 1065 1066 aprint_debug_dev(self, "PCIHOSTMAP %04x\n", 1067 bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_PCIHOSTMAP)); 1068 1069 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, 1070 pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG) | 1071 PCI_COMMAND_PARITY_ENABLE|PCI_COMMAND_SERR_ENABLE); 1072 1073 if (!pmf_device_register1(self, elanpex_suspend, elanpex_resume, 1074 elanpex_shutdown)) 1075 aprint_error_dev(self, "could not establish power hooks\n"); 1076 } 1077 1078 static bool 1079 elanpex_shutdown(device_t self, int flags) 1080 { 1081 struct elansc_softc *sc = device_private(device_parent(self)); 1082 uint8_t sysarbctl; 1083 uint16_t pcihostmap, mstirq, tgtirq; 1084 1085 sysarbctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL); 1086 sysarbctl &= ~MMCR_SYSARBCTL_GNT_TO_INT_ENB; 1087 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_SYSARBCTL, sysarbctl); 1088 1089 mstirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL); 1090 mstirq &= ~MMCR_HBMSTIRQCTL_M_RTRTO_IRQ_ENB; 1091 mstirq &= ~MMCR_HBMSTIRQCTL_M_TABRT_IRQ_ENB; 1092 mstirq &= ~MMCR_HBMSTIRQCTL_M_MABRT_IRQ_ENB; 1093 mstirq &= ~MMCR_HBMSTIRQCTL_M_SERR_IRQ_ENB; 1094 mstirq &= ~MMCR_HBMSTIRQCTL_M_RPER_IRQ_ENB; 1095 mstirq &= ~MMCR_HBMSTIRQCTL_M_DPER_IRQ_ENB; 1096 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBMSTIRQCTL, mstirq); 1097 1098 tgtirq = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL); 1099 tgtirq &= ~MMCR_HBTGTIRQCTL_T_DLYTO_IRQ_ENB; 1100 tgtirq &= ~MMCR_HBTGTIRQCTL_T_APER_IRQ_ENB; 1101 tgtirq &= ~MMCR_HBTGTIRQCTL_T_DPER_IRQ_ENB; 1102 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_HBTGTIRQCTL, tgtirq); 1103 1104 pcihostmap = bus_space_read_2(sc->sc_memt, sc->sc_memh, 1105 MMCR_PCIHOSTMAP); 1106 /* Priority P2 (Master PIC IR1) */ 1107 pcihostmap &= ~MMCR_PCIHOSTMAP_PCI_IRQ_MAP; 1108 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_PCIHOSTMAP, 1109 pcihostmap); 1110 1111 return true; 1112 } 1113 1114 static void 1115 elanpex_intr_disestablish(struct elansc_softc *sc) 1116 { 1117 elanpex_shutdown(sc->sc_pex, 0); 1118 1119 if (elansc_pcinmi) 1120 nmi_disestablish(sc->sc_eih); 1121 else 1122 intr_disestablish(sc->sc_eih); 1123 sc->sc_eih = NULL; 1124 1125 } 1126 1127 static int 1128 elanpex_detach(device_t self, int flags) 1129 { 1130 struct elansc_softc *sc = device_private(device_parent(self)); 1131 1132 pmf_device_deregister(self); 1133 elanpex_intr_disestablish(sc); 1134 1135 return 0; 1136 } 1137 1138 static void 1139 elanpar_intr_establish(device_t self, struct elansc_softc *sc) 1140 { 1141 uint8_t adddecctl, wpvmap; 1142 1143 wpvmap = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP); 1144 wpvmap &= ~MMCR_WPVMAP_INT_MAP; 1145 if (elansc_wpvnmi) 1146 wpvmap |= MMCR_WPVMAP_INT_NMI; 1147 else 1148 wpvmap |= __SHIFTIN(__BIT(ELAN_IRQ), MMCR_WPVMAP_INT_MAP); 1149 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP, wpvmap); 1150 1151 /* clear interrupt status */ 1152 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WPVSTA, 1153 MMCR_WPVSTA_WPV_STA); 1154 1155 /* establish interrupt */ 1156 if (elansc_wpvnmi) 1157 sc->sc_pih = nmi_establish(elanpar_nmi, sc); 1158 else 1159 sc->sc_pih = elansc_intr_establish(self, elanpar_intr, sc); 1160 1161 adddecctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL); 1162 adddecctl |= MMCR_ADDDECCTL_WPV_INT_ENB; 1163 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL, adddecctl); 1164 } 1165 1166 static bool 1167 elanpar_shutdown(device_t self, int flags) 1168 { 1169 int i; 1170 struct elansc_softc *sc = device_private(device_parent(self)); 1171 1172 for (i = 0; i < __arraycount(sc->sc_textpar); i++) { 1173 if (sc->sc_textpar[i] == -1) 1174 continue; 1175 elansc_disable_par(sc->sc_memt, sc->sc_memh, sc->sc_textpar[i]); 1176 sc->sc_textpar[i] = -1; 1177 } 1178 if (sc->sc_pg0par != -1) { 1179 elansc_disable_par(sc->sc_memt, sc->sc_memh, sc->sc_pg0par); 1180 sc->sc_pg0par = -1; 1181 } 1182 return true; 1183 } 1184 1185 static void 1186 elanpar_deferred_attach(device_t self) 1187 { 1188 struct elansc_softc *sc = device_private(device_parent(self)); 1189 1190 elansc_protect_text(self, sc); 1191 } 1192 1193 static void 1194 elanpar_attach(device_t parent, device_t self, void *aux) 1195 { 1196 struct elansc_softc *sc = device_private(parent); 1197 1198 aprint_naive(": Programmable Address Regions\n"); 1199 aprint_normal(": AMD Elan SC520 Programmable Address Regions\n"); 1200 1201 elansc_print_1(self, sc, MMCR_WPVMAP); 1202 elansc_print_all_par(self, sc->sc_memt, sc->sc_memh); 1203 1204 sc->sc_pg0par = elansc_protect_pg0(self, sc); 1205 /* XXX grotty hack to avoid trapping writes by x86_patch() 1206 * to the kernel text on a MULTIPROCESSOR kernel. 1207 */ 1208 config_interrupts(self, elanpar_deferred_attach); 1209 1210 elansc_print_all_par(self, sc->sc_memt, sc->sc_memh); 1211 1212 elanpar_intr_establish(self, sc); 1213 1214 elansc_print_1(self, sc, MMCR_ADDDECCTL); 1215 1216 if (!pmf_device_register1(self, elanpar_suspend, elanpar_resume, 1217 elanpar_shutdown)) 1218 aprint_error_dev(self, "could not establish power hooks\n"); 1219 } 1220 1221 static void 1222 elanpar_intr_disestablish(struct elansc_softc *sc) 1223 { 1224 uint8_t adddecctl, wpvmap; 1225 1226 /* disable interrupt, acknowledge it, disestablish our 1227 * handler, unmap it 1228 */ 1229 adddecctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL); 1230 adddecctl &= ~MMCR_ADDDECCTL_WPV_INT_ENB; 1231 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_ADDDECCTL, adddecctl); 1232 1233 bus_space_write_2(sc->sc_memt, sc->sc_memh, MMCR_WPVSTA, 1234 MMCR_WPVSTA_WPV_STA); 1235 1236 if (elansc_wpvnmi) 1237 nmi_disestablish(sc->sc_pih); 1238 else 1239 intr_disestablish(sc->sc_pih); 1240 sc->sc_pih = NULL; 1241 1242 wpvmap = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP); 1243 wpvmap &= ~MMCR_WPVMAP_INT_MAP; 1244 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_WPVMAP, wpvmap); 1245 } 1246 1247 static int 1248 elanpar_detach(device_t self, int flags) 1249 { 1250 struct elansc_softc *sc = device_private(device_parent(self)); 1251 1252 pmf_device_deregister(self); 1253 1254 elanpar_shutdown(self, 0); 1255 1256 elanpar_intr_disestablish(sc); 1257 1258 return 0; 1259 } 1260 1261 static void 1262 elansc_attach(device_t parent, device_t self, void *aux) 1263 { 1264 struct elansc_softc *sc = device_private(self); 1265 struct pcibus_attach_args *pba = aux; 1266 uint16_t rev; 1267 uint8_t cpuctl, picicr, ressta; 1268 #if NGPIO > 0 1269 int pin, reg, shift; 1270 uint16_t data; 1271 #endif 1272 1273 sc->sc_dev = self; 1274 1275 sc->sc_pc = pba->pba_pc; 1276 sc->sc_pciflags = pba->pba_flags; 1277 sc->sc_dmat = pba->pba_dmat; 1278 sc->sc_dmat64 = pba->pba_dmat64; 1279 sc->sc_tag = pci_make_tag(sc->sc_pc, 0, 0, 0); 1280 1281 aprint_naive(": System Controller\n"); 1282 aprint_normal(": AMD Elan SC520 System Controller\n"); 1283 1284 sc->sc_iot = pba->pba_iot; 1285 sc->sc_memt = pba->pba_memt; 1286 if (bus_space_map(sc->sc_memt, MMCR_BASE_ADDR, PAGE_SIZE, 0, 1287 &sc->sc_memh) != 0) { 1288 aprint_error_dev(sc->sc_dev, "unable to map registers\n"); 1289 return; 1290 } 1291 1292 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_HIGH); 1293 1294 rev = bus_space_read_2(sc->sc_memt, sc->sc_memh, MMCR_REVID); 1295 cpuctl = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_CPUCTL); 1296 1297 aprint_normal_dev(sc->sc_dev, 1298 "product %d stepping %d.%d, CPU clock %s\n", 1299 (rev & REVID_PRODID) >> REVID_PRODID_SHIFT, 1300 (rev & REVID_MAJSTEP) >> REVID_MAJSTEP_SHIFT, 1301 (rev & REVID_MINSTEP), 1302 elansc_speeds[cpuctl & CPUCTL_CPU_CLK_SPD_MASK]); 1303 1304 /* 1305 * SC520 rev A1 has a bug that affects the watchdog timer. If 1306 * the GP bus echo mode is enabled, writing to the watchdog control 1307 * register is blocked. 1308 * 1309 * The BIOS in some systems (e.g. the Soekris net4501) enables 1310 * GP bus echo for various reasons, so we need to switch it off 1311 * when we talk to the watchdog timer. 1312 * 1313 * XXX The step 1.1 (B1?) in my Soekris net4501 also has this 1314 * XXX problem, so we'll just enable it for all Elan SC520s 1315 * XXX for now. --thorpej@NetBSD.org 1316 */ 1317 if (1 || rev == ((PRODID_ELAN_SC520 << REVID_PRODID_SHIFT) | 1318 (0 << REVID_MAJSTEP_SHIFT) | (1))) 1319 sc->sc_echobug = 1; 1320 1321 /* 1322 * Determine cause of the last reset, and issue a warning if it 1323 * was due to watchdog expiry. 1324 */ 1325 ressta = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_RESSTA); 1326 if (ressta & RESSTA_WDT_RST_DET) 1327 aprint_error_dev(sc->sc_dev, 1328 "WARNING: LAST RESET DUE TO WATCHDOG EXPIRATION!\n"); 1329 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_RESSTA, ressta); 1330 1331 elansc_print_1(self, sc, MMCR_MPICMODE); 1332 elansc_print_1(self, sc, MMCR_SL1PICMODE); 1333 elansc_print_1(self, sc, MMCR_SL2PICMODE); 1334 elansc_print_1(self, sc, MMCR_PICICR); 1335 1336 sc->sc_mpicmode = bus_space_read_1(sc->sc_memt, sc->sc_memh, 1337 MMCR_MPICMODE); 1338 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_MPICMODE, 1339 sc->sc_mpicmode | __BIT(ELAN_IRQ)); 1340 1341 sc->sc_picicr = bus_space_read_1(sc->sc_memt, sc->sc_memh, MMCR_PICICR); 1342 picicr = sc->sc_picicr; 1343 if (elansc_pcinmi || elansc_wpvnmi) 1344 picicr |= MMCR_PICICR_NMI_ENB; 1345 #if 0 1346 /* PC/AT compatibility */ 1347 picicr |= MMCR_PICICR_S1_GINT_MODE|MMCR_PICICR_M_GINT_MODE; 1348 #endif 1349 bus_space_write_1(sc->sc_memt, sc->sc_memh, MMCR_PICICR, picicr); 1350 1351 elansc_print_1(self, sc, MMCR_PICICR); 1352 elansc_print_1(self, sc, MMCR_MPICMODE); 1353 1354 mutex_enter(&sc->sc_mtx); 1355 /* Set up the watchdog registers with some defaults. */ 1356 elansc_wdogctl_write(sc, WDTMRCTL_WRST_ENB | WDTMRCTL_EXP_SEL30); 1357 1358 /* ...and clear it. */ 1359 elansc_wdogctl_reset(sc); 1360 mutex_exit(&sc->sc_mtx); 1361 1362 if (!pmf_device_register1(self, elansc_suspend, elansc_resume, 1363 elansc_shutdown)) 1364 aprint_error_dev(self, "could not establish power hooks\n"); 1365 1366 #if NGPIO > 0 1367 /* Initialize GPIO pins array */ 1368 for (pin = 0; pin < ELANSC_PIO_NPINS; pin++) { 1369 sc->sc_gpio_pins[pin].pin_num = pin; 1370 sc->sc_gpio_pins[pin].pin_caps = GPIO_PIN_INPUT | 1371 GPIO_PIN_OUTPUT; 1372 1373 /* Read initial state */ 1374 reg = (pin < 16 ? MMCR_PIODIR15_0 : MMCR_PIODIR31_16); 1375 shift = pin % 16; 1376 data = bus_space_read_2(sc->sc_memt, sc->sc_memh, reg); 1377 if ((data & (1 << shift)) == 0) 1378 sc->sc_gpio_pins[pin].pin_flags = GPIO_PIN_INPUT; 1379 else 1380 sc->sc_gpio_pins[pin].pin_flags = GPIO_PIN_OUTPUT; 1381 if (elansc_gpio_pin_read(sc, pin) == 0) 1382 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_LOW; 1383 else 1384 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_HIGH; 1385 } 1386 1387 /* Create controller tag */ 1388 sc->sc_gpio_gc.gp_cookie = sc; 1389 sc->sc_gpio_gc.gp_pin_read = elansc_gpio_pin_read; 1390 sc->sc_gpio_gc.gp_pin_write = elansc_gpio_pin_write; 1391 sc->sc_gpio_gc.gp_pin_ctl = elansc_gpio_pin_ctl; 1392 1393 #endif /* NGPIO */ 1394 1395 elansc_rescan(sc->sc_dev, "elanparbus", NULL); 1396 elansc_rescan(sc->sc_dev, "elanpexbus", NULL); 1397 elansc_rescan(sc->sc_dev, "gpiobus", NULL); 1398 1399 /* 1400 * Hook up the watchdog timer. 1401 */ 1402 sc->sc_smw.smw_name = device_xname(sc->sc_dev); 1403 sc->sc_smw.smw_cookie = sc; 1404 sc->sc_smw.smw_setmode = elansc_wdog_setmode; 1405 sc->sc_smw.smw_tickle = elansc_wdog_tickle; 1406 sc->sc_smw.smw_period = 32; /* actually 32.54 */ 1407 if (sysmon_wdog_register(&sc->sc_smw) != 0) { 1408 aprint_error_dev(sc->sc_dev, 1409 "unable to register watchdog with sysmon\n"); 1410 } 1411 elansc_attached = true; 1412 elansc_rescan(sc->sc_dev, "pcibus", NULL); 1413 } 1414 1415 static int 1416 elanpex_match(device_t parent, cfdata_t match, void *aux) 1417 { 1418 struct elansc_softc *sc = device_private(parent); 1419 1420 return sc->sc_pex == NULL; 1421 } 1422 1423 static int 1424 elanpar_match(device_t parent, cfdata_t match, void *aux) 1425 { 1426 struct elansc_softc *sc = device_private(parent); 1427 1428 return sc->sc_par == NULL; 1429 } 1430 1431 /* scan for new children */ 1432 static int 1433 elansc_rescan(device_t self, const char *ifattr, const int *locators) 1434 { 1435 struct elansc_softc *sc = device_private(self); 1436 1437 if (ifattr_match(ifattr, "elanparbus") && sc->sc_par == NULL) { 1438 sc->sc_par = config_found_ia(sc->sc_dev, "elanparbus", NULL, 1439 NULL); 1440 } 1441 1442 if (ifattr_match(ifattr, "elanpexbus") && sc->sc_pex == NULL) { 1443 sc->sc_pex = config_found_ia(sc->sc_dev, "elanpexbus", NULL, 1444 NULL); 1445 } 1446 1447 if (ifattr_match(ifattr, "gpiobus") && sc->sc_gpio == NULL) { 1448 #if NGPIO > 0 1449 struct gpiobus_attach_args gba; 1450 1451 memset(&gba, 0, sizeof(gba)); 1452 1453 gba.gba_gc = &sc->sc_gpio_gc; 1454 gba.gba_pins = sc->sc_gpio_pins; 1455 gba.gba_npins = ELANSC_PIO_NPINS; 1456 sc->sc_gpio = config_found_ia(sc->sc_dev, "gpiobus", &gba, 1457 gpiobus_print); 1458 #endif 1459 } 1460 1461 if (ifattr_match(ifattr, "pcibus") && sc->sc_pci == NULL) { 1462 struct pcibus_attach_args pba; 1463 1464 memset(&pba, 0, sizeof(pba)); 1465 pba.pba_iot = sc->sc_iot; 1466 pba.pba_memt = sc->sc_memt; 1467 pba.pba_dmat = sc->sc_dmat; 1468 pba.pba_dmat64 = sc->sc_dmat64; 1469 pba.pba_pc = sc->sc_pc; 1470 pba.pba_flags = sc->sc_pciflags; 1471 pba.pba_bus = 0; 1472 pba.pba_bridgetag = NULL; 1473 sc->sc_pci = config_found_ia(self, "pcibus", &pba, pcibusprint); 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