1 /* $OpenBSD: dino.c,v 1.2 2003/10/30 19:25:12 mickey Exp $ */ 2 3 /* 4 * Copyright (c) 2003 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "cardbus.h" 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/device.h> 34 #include <sys/reboot.h> 35 #include <sys/malloc.h> 36 #include <sys/extent.h> 37 38 #include <machine/iomod.h> 39 #include <machine/autoconf.h> 40 41 #include <hppa/dev/cpudevs.h> 42 43 #if NCARDBUS > 0 44 #include <dev/cardbus/rbus.h> 45 #endif 46 47 #include <dev/pci/pcireg.h> 48 #include <dev/pci/pcivar.h> 49 #include <dev/pci/pcidevs.h> 50 51 #define DINO_MEM_CHUNK 0x800000 52 #define DINO_MEM_WINDOW (2 * DINO_MEM_CHUNK) 53 54 struct dino_regs { 55 u_int32_t pad0; /* 0x000 */ 56 u_int32_t iar0; /* 0x004 rw intr addr reg 0 */ 57 u_int32_t iodc; /* 0x008 rw iodc data/addr */ 58 u_int32_t irr0; /* 0x00c r intr req reg 0 */ 59 u_int32_t iar1; /* 0x010 rw intr addr reg 1 */ 60 u_int32_t irr1; /* 0x014 r intr req reg 1 */ 61 u_int32_t imr; /* 0x018 rw intr mask reg */ 62 u_int32_t ipr; /* 0x01c rw intr pending reg */ 63 u_int32_t toc_addr; /* 0x020 rw TOC addr reg */ 64 u_int32_t icr; /* 0x024 rw intr control reg */ 65 u_int32_t ilr; /* 0x028 r intr level reg */ 66 u_int32_t pad1; /* 0x02c */ 67 u_int32_t io_command; /* 0x030 w command register */ 68 u_int32_t io_status; /* 0x034 r status register */ 69 u_int32_t io_control; /* 0x038 rw control register */ 70 u_int32_t pad2; /* 0x03c AUX registers follow */ 71 u_int32_t io_gsc_err_addr;/* 0x040 GSC error address */ 72 u_int32_t io_err_info; /* 0x044 error info register */ 73 u_int32_t io_pci_err_addr;/* 0x048 PCI error address */ 74 u_int32_t pad3[4]; /* 0x04c */ 75 u_int32_t io_fbb_en; /* 0x05c fast back2back enable reg */ 76 u_int32_t io_addr_en; /* 0x060 address enable reg */ 77 u_int32_t pci_addr; /* 0x064 PCI conf/io/mem addr reg */ 78 u_int32_t pci_conf_data; /* 0x068 PCI conf data reg */ 79 u_int32_t pci_io_data; /* 0x06c PCI io data reg */ 80 u_int32_t pci_mem_data; /* 0x070 PCI memory data reg */ 81 u_int32_t pad4[0x740/4]; /* 0x074 */ 82 u_int32_t gsc2x_config; /* 0x7b4 GSC2X config reg */ 83 u_int32_t pad5[0x48/4]; /* 0x7b8: BSRS registers follow */ 84 u_int32_t gmask; /* 0x800 GSC arbitration mask */ 85 u_int32_t pamr; /* 0x804 PCI arbitration mask */ 86 u_int32_t papr; /* 0x808 PCI arbitration priority */ 87 u_int32_t damode; /* 0x80c PCI arbitration mode */ 88 u_int32_t pcicmd; /* 0x810 PCI command register */ 89 u_int32_t pcists; /* 0x814 PCI status register */ 90 u_int32_t pad6; /* 0x818 */ 91 u_int32_t mltim; /* 0x81c PCI master latency timer */ 92 u_int32_t brdg_feat; /* 0x820 PCI bridge feature enable */ 93 u_int32_t pciror; /* 0x824 PCI read optimization reg */ 94 u_int32_t pciwor; /* 0x828 PCI write optimization reg */ 95 u_int32_t pad7; /* 0x82c */ 96 u_int32_t tltim; /* 0x830 PCI target latency reg */ 97 }; 98 99 struct dino_softc { 100 struct device sc_dv; 101 102 int sc_ver; 103 void *sc_ih; 104 u_int32_t sc_imr; 105 bus_space_tag_t sc_bt; 106 bus_space_handle_t sc_bh; 107 bus_space_handle_t sc_memh; 108 bus_dma_tag_t sc_dmat; 109 volatile struct dino_regs *sc_regs; 110 111 struct hppa_pci_chipset_tag sc_pc; 112 struct hppa_bus_space_tag sc_iot; 113 char sc_ioexname[20]; 114 struct extent *sc_ioex; 115 struct hppa_bus_space_tag sc_memt; 116 char sc_memexname[20]; 117 struct extent *sc_memex; 118 struct hppa_bus_dma_tag sc_dmatag; 119 }; 120 121 int dinomatch(struct device *, void *, void *); 122 void dinoattach(struct device *, struct device *, void *); 123 int dino_intr(void *); 124 125 struct cfattach dino_ca = { 126 sizeof(struct dino_softc), dinomatch, dinoattach 127 }; 128 129 struct cfdriver dino_cd = { 130 NULL, "dino", DV_DULL 131 }; 132 133 int 134 dinomatch(parent, cfdata, aux) 135 struct device *parent; 136 void *cfdata; 137 void *aux; 138 { 139 struct confargs *ca = aux; 140 /* struct cfdata *cf = cfdata; */ 141 142 /* there will be only one */ 143 if (ca->ca_type.iodc_type != HPPA_TYPE_BRIDGE || 144 ca->ca_type.iodc_sv_model != HPPA_BRIDGE_DINO) 145 return (0); 146 147 return (1); 148 } 149 150 void 151 dino_attach_hook(struct device *parent, struct device *self, 152 struct pcibus_attach_args *pba) 153 { 154 155 } 156 157 int 158 dino_maxdevs(void *v, int bus) 159 { 160 return (32); 161 } 162 163 pcitag_t 164 dino_make_tag(void *v, int bus, int dev, int func) 165 { 166 if (bus > 255 || dev > 31 || func > 7) 167 panic("dino_make_tag: bad request"); 168 169 return ((bus << 16) | (dev << 11) | (func << 8)); 170 } 171 172 void 173 dino_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func) 174 { 175 *bus = (tag >> 16) & 0xff; 176 *dev = (tag >> 11) & 0x1f; 177 *func= (tag >> 8) & 0x07; 178 } 179 180 pcireg_t 181 dino_conf_read(void *v, pcitag_t tag, int reg) 182 { 183 struct dino_softc *sc = v; 184 volatile struct dino_regs *r = sc->sc_regs; 185 pcireg_t data; 186 187 r->pci_addr = tag | reg; 188 data = r->pci_conf_data; 189 return (letoh32(data)); 190 } 191 192 void 193 dino_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 194 { 195 struct dino_softc *sc = v; 196 volatile struct dino_regs *r = sc->sc_regs; 197 198 r->pci_addr = tag | reg; 199 r->pci_conf_data = htole32(data); 200 } 201 202 int 203 dino_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 204 { 205 /* struct dino_softc *sc = v; 206 volatile struct dino_regs *r = sc->sc_regs; */ 207 pci_chipset_tag_t pc = pa->pa_pc; 208 pcitag_t tag = pa->pa_tag; 209 pcireg_t reg; 210 211 reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 212 *ihp = PCI_INTERRUPT_LINE(reg) + 1; 213 return (*ihp == 0); 214 } 215 216 const char * 217 dino_intr_string(void *v, pci_intr_handle_t ih) 218 { 219 static char buf[32]; 220 221 snprintf(buf, 32, "irq %d", ih); 222 223 return (buf); 224 } 225 226 void * 227 dino_intr_establish(void *v, pci_intr_handle_t ih, 228 int pri, int (*handler)(void *), void *arg, char *name) 229 { 230 struct dino_softc *sc = v; 231 volatile struct dino_regs *r = sc->sc_regs; 232 void *iv; 233 234 /* no mapping */ 235 if (ih == 0) 236 return (NULL); 237 238 if ((iv = cpu_intr_map(sc->sc_ih, pri, ih - 1, handler, arg, name))) { 239 if (cold) 240 sc->sc_imr |= (1 << (ih - 1)); 241 else 242 r->imr |= (1 << (ih - 1)); 243 r->icr &= ~(1 << (ih - 1)); 244 } 245 246 return (iv); 247 } 248 249 void 250 dino_intr_disestablish(void *v, void *cookie) 251 { 252 #if 0 253 struct dino_softc *sc = v; 254 volatile struct dino_regs *r = sc->sc_regs; 255 256 r->imr &= ~(1 << (ih - 1)); 257 258 TODO cpu_intr_unmap(sc->sc_ih, cookie); 259 #endif 260 } 261 262 #if NCARDBUS > 0 263 void * 264 dino_alloc_parent(struct device *self, struct pci_attach_args *pa, int io) 265 { 266 struct dino_softc *sc = pa->pa_pc->_cookie; 267 struct extent *ex; 268 bus_space_tag_t tag; 269 bus_addr_t start; 270 bus_size_t size; 271 272 if (io) { 273 ex = sc->sc_ioex; 274 tag = pa->pa_iot; 275 start = 0xa000; 276 size = 0x1000; 277 } else { 278 ex = sc->sc_memex; 279 tag = pa->pa_memt; 280 start = ex->ex_start; 281 size = DINO_MEM_CHUNK; 282 } 283 284 if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0, 285 EX_NOBOUNDARY, EX_NOWAIT, &start)) 286 return (NULL); 287 288 extent_free(ex, start, size, EX_NOWAIT); 289 return rbus_new_root_share(tag, ex, start, size, start); 290 } 291 #endif 292 293 int 294 dino_iomap(void *v, bus_addr_t bpa, bus_size_t size, 295 int flags, bus_space_handle_t *bshp) 296 { 297 struct dino_softc *sc = v; 298 int error; 299 300 if (!(flags & BUS_SPACE_MAP_NOEXTENT) && 301 (error = extent_alloc_region(sc->sc_ioex, bpa, size, EX_NOWAIT))) 302 return (error); 303 304 if (bshp) 305 *bshp = bpa; 306 307 return (0); 308 } 309 310 int 311 dino_memmap(void *v, bus_addr_t bpa, bus_size_t size, 312 int flags, bus_space_handle_t *bshp) 313 { 314 struct dino_softc *sc = v; 315 volatile struct dino_regs *r = sc->sc_regs; 316 u_int32_t reg; 317 int error; 318 319 reg = r->io_addr_en; 320 reg |= 1 << ((bpa >> 23) & 0x1f); 321 #ifdef DEBUG 322 if (reg & 0x80000001) 323 panic("mapping outside the mem extent range"); 324 #endif 325 /* map into the upper bus space, if not yet mapped this 8M */ 326 if (reg != r->io_addr_en) { 327 bus_addr_t sbpa = bpa & 0xff800000; 328 329 if ((error = bus_space_map(sc->sc_bt, sbpa, DINO_MEM_CHUNK, 330 flags, bshp))) { 331 return (error); 332 } 333 r->io_addr_en = reg; 334 335 if (bshp) 336 *bshp += (bpa - sbpa); 337 } else if (bshp) 338 *bshp = bpa; 339 340 return (0); 341 } 342 343 int 344 dino_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset, 345 bus_size_t size, bus_space_handle_t *nbshp) 346 { 347 *nbshp = bsh + offset; 348 return (0); 349 } 350 351 int 352 dino_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 353 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 354 bus_space_handle_t *bshp) 355 { 356 struct dino_softc *sc = v; 357 struct extent *ex = sc->sc_ioex; 358 bus_addr_t bpa; 359 int error; 360 361 if (rstart < ex->ex_start || rend > ex->ex_end) 362 panic("dino_ioalloc: bad region start/end"); 363 364 if ((error = extent_alloc_subregion(ex, rstart, rend, size, 365 align, 0, boundary, EX_NOWAIT, &bpa))) 366 return (error); 367 368 if (addrp) 369 *addrp = bpa; 370 if (bshp) 371 *bshp = bpa; 372 373 return (0); 374 } 375 376 int 377 dino_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 378 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, 379 bus_space_handle_t *bshp) 380 { 381 /* TODO dino_memalloc */ 382 return (-1); 383 } 384 385 void 386 dino_unmap(void *v, bus_space_handle_t bsh, bus_size_t size) 387 { 388 struct dino_softc *sc = v; 389 struct extent *ex; 390 bus_addr_t bpa; 391 392 bpa = bsh; 393 if (bsh & 0xf0000000) { 394 /* TODO dino_unmap mem */ 395 /* TODO unmap from the upper bus if the last use in this 8M */ 396 return; 397 } else 398 ex = sc->sc_ioex; 399 400 /* XXX gotta follow the BUS_SPACE_MAP_NOEXTENT flag */ 401 if (extent_free(ex, bpa, size, EX_NOWAIT)) 402 printf("dino_unmap: ps 0x%lx, size 0x%lx\n" 403 "dino_unmap: can't free region\n", bpa, size); 404 } 405 406 void 407 dino_free(void *v, bus_space_handle_t bh, bus_size_t size) 408 { 409 /* should be enough */ 410 dino_unmap(v, bh, size); 411 } 412 413 void 414 dino_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op) 415 { 416 sync_caches(); 417 } 418 419 u_int8_t 420 dino_r1(void *v, bus_space_handle_t h, bus_size_t o) 421 { 422 h += o; 423 if (h & 0xf0000000) 424 return *(volatile u_int8_t *)h; 425 else { 426 struct dino_softc *sc = v; 427 volatile struct dino_regs *r = sc->sc_regs; 428 u_int8_t data; 429 430 r->pci_addr = h & ~3; 431 data = *((volatile u_int8_t *)&r->pci_io_data + (h & 3)); 432 return (data); 433 } 434 } 435 436 u_int16_t 437 dino_r2(void *v, bus_space_handle_t h, bus_size_t o) 438 { 439 u_int16_t data; 440 441 h += o; 442 if (h & 0xf0000000) 443 data = *(volatile u_int16_t *)h; 444 else { 445 struct dino_softc *sc = v; 446 volatile struct dino_regs *r = sc->sc_regs; 447 448 r->pci_addr = h & ~3; 449 data = *((volatile u_int16_t *)&r->pci_io_data + (h & 2)); 450 } 451 452 return (letoh16(data)); 453 } 454 455 u_int32_t 456 dino_r4(void *v, bus_space_handle_t h, bus_size_t o) 457 { 458 u_int32_t data; 459 460 h += o; 461 if (h & 0xf0000000) 462 data = *(volatile u_int32_t *)h; 463 else { 464 struct dino_softc *sc = v; 465 volatile struct dino_regs *r = sc->sc_regs; 466 467 r->pci_addr = h; 468 data = r->pci_io_data; 469 } 470 471 return (letoh32(data)); 472 } 473 474 u_int64_t 475 dino_r8(void *v, bus_space_handle_t h, bus_size_t o) 476 { 477 h += o; 478 if (h & 0xf0000000) 479 return *(volatile u_int64_t *)h; 480 else 481 panic("dino_r8: not implemented"); 482 } 483 484 void 485 dino_w1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv) 486 { 487 h += o; 488 if (h & 0xf0000000) 489 *(volatile u_int8_t *)h = vv; 490 else { 491 struct dino_softc *sc = v; 492 volatile struct dino_regs *r = sc->sc_regs; 493 494 r->pci_addr = h & ~3; 495 *((volatile u_int8_t *)&r->pci_io_data + (h & 3)) = vv; 496 } 497 } 498 499 void 500 dino_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv) 501 { 502 h += o; 503 vv = htole16(vv); 504 if (h & 0xf0000000) 505 *(volatile u_int16_t *)h = vv; 506 else { 507 struct dino_softc *sc = v; 508 volatile struct dino_regs *r = sc->sc_regs; 509 510 r->pci_addr = h & ~3; 511 *((volatile u_int16_t *)&r->pci_io_data + (h & 2)) = vv; 512 } 513 } 514 515 void 516 dino_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv) 517 { 518 h += o; 519 vv = htole32(vv); 520 if (h & 0xf0000000) 521 *(volatile u_int32_t *)h = vv; 522 else { 523 struct dino_softc *sc = v; 524 volatile struct dino_regs *r = sc->sc_regs; 525 526 r->pci_addr = h; 527 r->pci_io_data = vv; 528 } 529 } 530 531 void 532 dino_w8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv) 533 { 534 h += o; 535 if (h & 0xf0000000) 536 *(volatile u_int64_t *)h = vv; 537 else 538 panic("dino_w8: not implemented"); 539 } 540 541 542 void 543 dino_rm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c) 544 { 545 volatile u_int8_t *p; 546 547 h += o; 548 if (h & 0xf0000000) 549 p = (volatile u_int8_t *)h; 550 else { 551 struct dino_softc *sc = v; 552 volatile struct dino_regs *r = sc->sc_regs; 553 554 r->pci_addr = h & ~3; 555 p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); 556 } 557 558 while (c--) 559 *a++ = *p; 560 } 561 562 void 563 dino_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c) 564 { 565 volatile u_int16_t *p; 566 567 h += o; 568 if (h & 0xf0000000) 569 p = (volatile u_int16_t *)h; 570 else { 571 struct dino_softc *sc = v; 572 volatile struct dino_regs *r = sc->sc_regs; 573 574 r->pci_addr = h & ~3; 575 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 576 } 577 578 while (c--) 579 *a++ = *p; 580 } 581 582 void 583 dino_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c) 584 { 585 volatile u_int32_t *p; 586 587 h += o; 588 if (h & 0xf0000000) 589 p = (volatile u_int32_t *)h; 590 else { 591 struct dino_softc *sc = v; 592 volatile struct dino_regs *r = sc->sc_regs; 593 594 r->pci_addr = h; 595 p = (volatile u_int32_t *)&r->pci_io_data; 596 } 597 598 while (c--) 599 *a++ = *p; 600 } 601 602 void 603 dino_rm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c) 604 { 605 panic("dino_rm_8: not implemented"); 606 } 607 608 void 609 dino_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c) 610 { 611 volatile u_int8_t *p; 612 613 h += o; 614 if (h & 0xf0000000) 615 p = (volatile u_int8_t *)h; 616 else { 617 struct dino_softc *sc = v; 618 volatile struct dino_regs *r = sc->sc_regs; 619 620 r->pci_addr = h & ~3; 621 p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); 622 } 623 624 while (c--) 625 *p = *a++; 626 } 627 628 void 629 dino_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c) 630 { 631 volatile u_int16_t *p; 632 633 h += o; 634 if (h & 0xf0000000) 635 p = (volatile u_int16_t *)h; 636 else { 637 struct dino_softc *sc = v; 638 volatile struct dino_regs *r = sc->sc_regs; 639 640 r->pci_addr = h & ~3; 641 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 642 } 643 644 while (c--) 645 *p = *a++; 646 } 647 648 void 649 dino_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c) 650 { 651 volatile u_int32_t *p; 652 653 h += o; 654 if (h & 0xf0000000) 655 p = (volatile u_int32_t *)h; 656 else { 657 struct dino_softc *sc = v; 658 volatile struct dino_regs *r = sc->sc_regs; 659 660 r->pci_addr = h; 661 p = (volatile u_int32_t *)&r->pci_io_data; 662 } 663 664 while (c--) 665 *p = *a++; 666 } 667 668 void 669 dino_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c) 670 { 671 panic("dino_wm_8: not implemented"); 672 } 673 674 void 675 dino_sm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c) 676 { 677 volatile u_int8_t *p; 678 679 h += o; 680 if (h & 0xf0000000) 681 p = (volatile u_int8_t *)h; 682 else { 683 struct dino_softc *sc = v; 684 volatile struct dino_regs *r = sc->sc_regs; 685 686 r->pci_addr = h & ~3; 687 p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); 688 } 689 690 while (c--) 691 *p = vv; 692 } 693 694 void 695 dino_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c) 696 { 697 volatile u_int16_t *p; 698 699 h += o; 700 if (h & 0xf0000000) 701 p = (volatile u_int16_t *)h; 702 else { 703 struct dino_softc *sc = v; 704 volatile struct dino_regs *r = sc->sc_regs; 705 706 r->pci_addr = h & ~3; 707 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 708 } 709 710 while (c--) 711 *p = vv; 712 } 713 714 void 715 dino_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c) 716 { 717 volatile u_int32_t *p; 718 719 h += o; 720 if (h & 0xf0000000) 721 p = (volatile u_int32_t *)h; 722 else { 723 struct dino_softc *sc = v; 724 volatile struct dino_regs *r = sc->sc_regs; 725 726 r->pci_addr = h; 727 p = (volatile u_int32_t *)&r->pci_io_data; 728 } 729 730 while (c--) 731 *p = vv; 732 } 733 734 void 735 dino_sm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c) 736 { 737 panic("dino_sm_8: not implemented"); 738 } 739 740 void 741 dino_rrm_2(void *v, bus_space_handle_t h, bus_size_t o, 742 u_int8_t *a, bus_size_t c) 743 { 744 volatile u_int16_t *p; 745 746 h += o; 747 if (h & 0xf0000000) 748 p = (volatile u_int16_t *)h; 749 else { 750 struct dino_softc *sc = v; 751 volatile struct dino_regs *r = sc->sc_regs; 752 753 r->pci_addr = h & ~3; 754 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 755 } 756 757 while (c--) 758 *a++ = swap16(*p); 759 } 760 761 void 762 dino_rrm_4(void *v, bus_space_handle_t h, bus_size_t o, 763 u_int8_t *a, bus_size_t c) 764 { 765 volatile u_int32_t *p; 766 767 h += o; 768 if (h & 0xf0000000) 769 p = (volatile u_int32_t *)h; 770 else { 771 struct dino_softc *sc = v; 772 volatile struct dino_regs *r = sc->sc_regs; 773 774 r->pci_addr = h; 775 p = (volatile u_int32_t *)&r->pci_io_data; 776 } 777 778 while (c--) 779 *a++ = swap32(*p); 780 } 781 782 void 783 dino_rrm_8(void *v, bus_space_handle_t h, bus_size_t o, 784 u_int8_t *a, bus_size_t c) 785 { 786 panic("dino_rrm_8: not implemented"); 787 } 788 789 void 790 dino_wrm_2(void *v, bus_space_handle_t h, bus_size_t o, 791 const u_int8_t *a, bus_size_t c) 792 { 793 volatile u_int16_t *p; 794 795 h += o; 796 if (h & 0xf0000000) 797 p = (volatile u_int16_t *)h; 798 else { 799 struct dino_softc *sc = v; 800 volatile struct dino_regs *r = sc->sc_regs; 801 802 r->pci_addr = h & ~3; 803 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 804 } 805 806 while (c--) 807 *p = swap16(*a++); 808 } 809 810 void 811 dino_wrm_4(void *v, bus_space_handle_t h, bus_size_t o, 812 const u_int8_t *a, bus_size_t c) 813 { 814 volatile u_int32_t *p; 815 816 h += o; 817 if (h & 0xf0000000) 818 p = (volatile u_int32_t *)h; 819 else { 820 struct dino_softc *sc = v; 821 volatile struct dino_regs *r = sc->sc_regs; 822 823 r->pci_addr = h; 824 p = (volatile u_int32_t *)&r->pci_io_data; 825 } 826 827 while (c--) 828 *p = swap32(*a++); 829 } 830 831 void 832 dino_wrm_8(void *v, bus_space_handle_t h, bus_size_t o, 833 const u_int8_t *a, bus_size_t c) 834 { 835 panic("dino_wrm_8: not implemented"); 836 } 837 838 void 839 dino_rr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c) 840 { 841 volatile u_int8_t *p; 842 843 h += o; 844 if (h & 0xf0000000) { 845 p = (volatile u_int8_t *)h; 846 while (c--) 847 *a++ = *p++; 848 } else { 849 struct dino_softc *sc = v; 850 volatile struct dino_regs *r = sc->sc_regs; 851 852 r->pci_addr = h & ~3; 853 while (c--) { 854 p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); 855 *a++ = *p; 856 if (!(++h & 3)) 857 r->pci_addr = h; 858 } 859 } 860 } 861 862 void 863 dino_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c) 864 { 865 volatile u_int16_t *p; 866 867 h += o; 868 if (h & 0xf0000000) { 869 p = (volatile u_int16_t *)h; 870 while (c--) 871 *a++ = *p++; 872 } else { 873 struct dino_softc *sc = v; 874 volatile struct dino_regs *r = sc->sc_regs; 875 876 r->pci_addr = h & ~3; 877 while (c--) { 878 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 879 *a++ = *p; 880 h += 2; 881 if (!(h & 3)) 882 r->pci_addr = h; 883 } 884 } 885 } 886 887 void 888 dino_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c) 889 { 890 volatile u_int32_t *p; 891 892 h += o; 893 if (h & 0xf0000000) { 894 p = (volatile u_int32_t *)h; 895 while (c--) 896 *a++ = *p++; 897 } else { 898 struct dino_softc *sc = v; 899 volatile struct dino_regs *r = sc->sc_regs; 900 901 for (; c--; h += 4) { 902 r->pci_addr = h; 903 *a++ = r->pci_io_data; 904 } 905 } 906 } 907 908 void 909 dino_rr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c) 910 { 911 panic("dino_rr_8: not implemented"); 912 } 913 914 void 915 dino_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c) 916 { 917 volatile u_int8_t *p; 918 919 h += o; 920 if (h & 0xf0000000) { 921 p = (volatile u_int8_t *)h; 922 while (c--) 923 *p++ = *a++; 924 } else { 925 struct dino_softc *sc = v; 926 volatile struct dino_regs *r = sc->sc_regs; 927 928 r->pci_addr = h & ~3; 929 while (c--) { 930 p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); 931 *p = *a++; 932 if (!(++h & 3)) 933 r->pci_addr = h; 934 } 935 } 936 } 937 938 void 939 dino_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c) 940 { 941 volatile u_int16_t *p; 942 943 h += o; 944 if (h & 0xf0000000) { 945 p = (volatile u_int16_t *)h; 946 while (c--) 947 *p++ = *a++; 948 } else { 949 struct dino_softc *sc = v; 950 volatile struct dino_regs *r = sc->sc_regs; 951 952 r->pci_addr = h & ~3; 953 while (c--) { 954 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 955 *p = *a++; 956 h += 2; 957 if (!(h & 3)) 958 r->pci_addr = h; 959 } 960 } 961 } 962 963 void 964 dino_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c) 965 { 966 volatile u_int32_t *p; 967 968 h += o; 969 if (h & 0xf0000000) { 970 p = (volatile u_int32_t *)h; 971 while (c--) 972 *p++ = *a++; 973 } else { 974 struct dino_softc *sc = v; 975 volatile struct dino_regs *r = sc->sc_regs; 976 977 for (; c--; h += 4) { 978 r->pci_addr = h; 979 r->pci_io_data = *a++; 980 } 981 } 982 } 983 984 void 985 dino_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c) 986 { 987 panic("dino_wr_8: not implemented"); 988 } 989 990 void 991 dino_rrr_2(void *v, bus_space_handle_t h, bus_size_t o, 992 u_int8_t *a, bus_size_t c) 993 { 994 volatile u_int16_t *p; 995 996 h += o; 997 if (h & 0xf0000000) { 998 p = (volatile u_int16_t *)h; 999 while (c--) 1000 *a++ = swap16(*p++); 1001 } else { 1002 struct dino_softc *sc = v; 1003 volatile struct dino_regs *r = sc->sc_regs; 1004 1005 r->pci_addr = h & ~3; 1006 while (c--) { 1007 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 1008 *a++ = swap16(*p); 1009 h += 2; 1010 if (!(h & 3)) 1011 r->pci_addr = h; 1012 } 1013 } 1014 } 1015 1016 void 1017 dino_rrr_4(void *v, bus_space_handle_t h, bus_size_t o, 1018 u_int8_t *a, bus_size_t c) 1019 { 1020 volatile u_int32_t *p; 1021 1022 h += o; 1023 if (h & 0xf0000000) { 1024 p = (volatile u_int32_t *)h; 1025 while (c--) 1026 *a++ = swap32(*p++); 1027 } else { 1028 struct dino_softc *sc = v; 1029 volatile struct dino_regs *r = sc->sc_regs; 1030 1031 for (; c--; h += 4) { 1032 r->pci_addr = h; 1033 *a++ = swap32(r->pci_io_data); 1034 } 1035 } 1036 } 1037 1038 void 1039 dino_rrr_8(void *v, bus_space_handle_t h, bus_size_t o, 1040 u_int8_t *a, bus_size_t c) 1041 { 1042 panic("dino_rrr_8: not implemented"); 1043 } 1044 1045 void 1046 dino_wrr_2(void *v, bus_space_handle_t h, bus_size_t o, 1047 const u_int8_t *a, bus_size_t c) 1048 { 1049 volatile u_int16_t *p; 1050 1051 h += o; 1052 if (h & 0xf0000000) { 1053 p = (volatile u_int16_t *)h; 1054 while (c--) 1055 *p++ = swap16(*a++); 1056 } else { 1057 struct dino_softc *sc = v; 1058 volatile struct dino_regs *r = sc->sc_regs; 1059 1060 r->pci_addr = h & ~3; 1061 while (c--) { 1062 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 1063 *p = swap16(*a++); 1064 h += 2; 1065 if (!(h & 3)) 1066 r->pci_addr = h; 1067 } 1068 } 1069 } 1070 1071 void 1072 dino_wrr_4(void *v, bus_space_handle_t h, bus_size_t o, 1073 const u_int8_t *a, bus_size_t c) 1074 { 1075 volatile u_int32_t *p; 1076 1077 h += o; 1078 if (h & 0xf0000000) { 1079 p = (volatile u_int32_t *)h; 1080 while (c--) 1081 *p++ = swap32(*a++); 1082 } else { 1083 struct dino_softc *sc = v; 1084 volatile struct dino_regs *r = sc->sc_regs; 1085 1086 for (; c--; h += 4) { 1087 r->pci_addr = h; 1088 r->pci_io_data = swap32(*a++); 1089 } 1090 } 1091 } 1092 1093 void 1094 dino_wrr_8(void *v, bus_space_handle_t h, bus_size_t o, 1095 const u_int8_t *a, bus_size_t c) 1096 { 1097 panic("dino_wrr_8: not implemented"); 1098 } 1099 1100 void 1101 dino_sr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c) 1102 { 1103 volatile u_int8_t *p; 1104 1105 h += o; 1106 if (h & 0xf0000000) { 1107 p = (volatile u_int8_t *)h; 1108 while (c--) 1109 *p++ = vv; 1110 } else { 1111 struct dino_softc *sc = v; 1112 volatile struct dino_regs *r = sc->sc_regs; 1113 1114 r->pci_addr = h & ~3; 1115 while (c--) { 1116 p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); 1117 *p = vv; 1118 if (!(++h & 3)) 1119 r->pci_addr = h; 1120 } 1121 } 1122 } 1123 1124 void 1125 dino_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c) 1126 { 1127 volatile u_int16_t *p; 1128 1129 h += o; 1130 if (h & 0xf0000000) { 1131 p = (volatile u_int16_t *)h; 1132 while (c--) 1133 *p++ = vv; 1134 } else { 1135 struct dino_softc *sc = v; 1136 volatile struct dino_regs *r = sc->sc_regs; 1137 1138 r->pci_addr = h & ~3; 1139 while (c--) { 1140 p = (volatile u_int16_t *)&r->pci_io_data + (h & 2); 1141 *p = vv; 1142 h += 2; 1143 if (!(h & 3)) 1144 r->pci_addr = h; 1145 } 1146 } 1147 } 1148 1149 void 1150 dino_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c) 1151 { 1152 volatile u_int32_t *p; 1153 1154 h += o; 1155 if (h & 0xf0000000) { 1156 p = (volatile u_int32_t *)h; 1157 while (c--) 1158 *p++ = vv; 1159 } else { 1160 struct dino_softc *sc = v; 1161 volatile struct dino_regs *r = sc->sc_regs; 1162 1163 for (; c--; h += 4) { 1164 r->pci_addr = h; 1165 r->pci_io_data = vv; 1166 } 1167 } 1168 } 1169 1170 void 1171 dino_sr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c) 1172 { 1173 panic("dino_sr_8: not implemented"); 1174 } 1175 1176 void 1177 dino_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1, 1178 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 1179 { 1180 while (c--) 1181 dino_w1(v, h1, o1++, dino_r1(v, h2, o2++)); 1182 } 1183 1184 void 1185 dino_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1, 1186 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 1187 { 1188 while (c--) { 1189 dino_w2(v, h1, o1, dino_r2(v, h2, o2)); 1190 o1 += 2; 1191 o2 += 2; 1192 } 1193 } 1194 1195 void 1196 dino_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1, 1197 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 1198 { 1199 while (c--) { 1200 dino_w4(v, h1, o1, dino_r4(v, h2, o2)); 1201 o1 += 4; 1202 o2 += 4; 1203 } 1204 } 1205 1206 void 1207 dino_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1, 1208 bus_space_handle_t h2, bus_size_t o2, bus_size_t c) 1209 { 1210 while (c--) { 1211 dino_w8(v, h1, o1, dino_r8(v, h2, o2)); 1212 o1 += 8; 1213 o2 += 8; 1214 } 1215 } 1216 1217 1218 const struct hppa_bus_space_tag dino_iomemt = { 1219 NULL, 1220 1221 NULL, dino_unmap, dino_subregion, NULL, dino_free, 1222 dino_barrier, 1223 dino_r1, dino_r2, dino_r4, dino_r8, 1224 dino_w1, dino_w2, dino_w4, dino_w8, 1225 dino_rm_1, dino_rm_2, dino_rm_4, dino_rm_8, 1226 dino_wm_1, dino_wm_2, dino_wm_4, dino_wm_8, 1227 dino_sm_1, dino_sm_2, dino_sm_4, dino_sm_8, 1228 dino_rrm_2, dino_rrm_4, dino_rrm_8, 1229 dino_wrm_2, dino_wrm_4, dino_wrm_8, 1230 dino_rr_1, dino_rr_2, dino_rr_4, dino_rr_8, 1231 dino_wr_1, dino_wr_2, dino_wr_4, dino_wr_8, 1232 dino_rrr_2, dino_rrr_4, dino_rrr_8, 1233 dino_wrr_2, dino_wrr_4, dino_wrr_8, 1234 dino_sr_1, dino_sr_2, dino_sr_4, dino_sr_8, 1235 dino_cp_1, dino_cp_2, dino_cp_4, dino_cp_8 1236 }; 1237 1238 int 1239 dino_dmamap_create(void *v, bus_size_t size, int nsegments, 1240 bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp) 1241 { 1242 struct dino_softc *sc = v; 1243 1244 /* TODO check the addresses, boundary, enable dma */ 1245 1246 return (bus_dmamap_create(sc->sc_dmat, size, nsegments, 1247 maxsegsz, boundary, flags, dmamp)); 1248 } 1249 1250 void 1251 dino_dmamap_destroy(void *v, bus_dmamap_t map) 1252 { 1253 struct dino_softc *sc = v; 1254 1255 bus_dmamap_destroy(sc->sc_dmat, map); 1256 } 1257 1258 int 1259 dino_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size, 1260 struct proc *p, int flags) 1261 { 1262 struct dino_softc *sc = v; 1263 1264 return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags)); 1265 } 1266 1267 int 1268 dino_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags) 1269 { 1270 struct dino_softc *sc = v; 1271 1272 return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags)); 1273 } 1274 1275 int 1276 dino_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags) 1277 { 1278 struct dino_softc *sc = v; 1279 1280 return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags)); 1281 } 1282 1283 int 1284 dino_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs, 1285 int nsegs, bus_size_t size, int flags) 1286 { 1287 struct dino_softc *sc = v; 1288 1289 return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags)); 1290 } 1291 1292 void 1293 dino_dmamap_unload(void *v, bus_dmamap_t map) 1294 { 1295 struct dino_softc *sc = v; 1296 1297 bus_dmamap_unload(sc->sc_dmat, map); 1298 } 1299 1300 void 1301 dino_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off, 1302 bus_size_t len, int ops) 1303 { 1304 struct dino_softc *sc = v; 1305 1306 return (bus_dmamap_sync(sc->sc_dmat, map, off, len, ops)); 1307 } 1308 1309 int 1310 dino_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment, 1311 bus_size_t boundary, bus_dma_segment_t *segs, 1312 int nsegs, int *rsegs, int flags) 1313 { 1314 struct dino_softc *sc = v; 1315 1316 return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary, 1317 segs, nsegs, rsegs, flags)); 1318 } 1319 1320 void 1321 dino_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs) 1322 { 1323 struct dino_softc *sc = v; 1324 1325 bus_dmamem_free(sc->sc_dmat, segs, nsegs); 1326 } 1327 1328 int 1329 dino_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size, 1330 caddr_t *kvap, int flags) 1331 { 1332 struct dino_softc *sc = v; 1333 1334 return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags)); 1335 } 1336 1337 void 1338 dino_dmamem_unmap(void *v, caddr_t kva, size_t size) 1339 { 1340 struct dino_softc *sc = v; 1341 1342 bus_dmamem_unmap(sc->sc_dmat, kva, size); 1343 } 1344 1345 paddr_t 1346 dino_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off, 1347 int prot, int flags) 1348 { 1349 struct dino_softc *sc = v; 1350 1351 return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags)); 1352 } 1353 1354 const struct hppa_bus_dma_tag dino_dmat = { 1355 NULL, 1356 dino_dmamap_create, dino_dmamap_destroy, 1357 dino_dmamap_load, dino_dmamap_load_mbuf, 1358 dino_dmamap_load_uio, dino_dmamap_load_raw, 1359 dino_dmamap_unload, dino_dmamap_sync, 1360 1361 dino_dmamem_alloc, dino_dmamem_free, dino_dmamem_map, 1362 dino_dmamem_unmap, dino_dmamem_mmap 1363 }; 1364 1365 const struct hppa_pci_chipset_tag dino_pc = { 1366 NULL, 1367 dino_attach_hook, dino_maxdevs, dino_make_tag, dino_decompose_tag, 1368 dino_conf_read, dino_conf_write, 1369 dino_intr_map, dino_intr_string, 1370 dino_intr_establish, dino_intr_disestablish, 1371 #if NCARDBUS > 0 1372 dino_alloc_parent 1373 #else 1374 NULL 1375 #endif 1376 }; 1377 1378 int 1379 dinoprint(void *aux, const char *pnp) 1380 { 1381 struct pcibus_attach_args *pba = aux; 1382 1383 if (pnp) 1384 printf("%s at %s\n", pba->pba_busname, pnp); 1385 return (UNCONF); 1386 } 1387 1388 void 1389 dinoattach(parent, self, aux) 1390 struct device *parent; 1391 struct device *self; 1392 void *aux; 1393 { 1394 struct dino_softc *sc = (struct dino_softc *)self; 1395 struct confargs *ca = (struct confargs *)aux; 1396 struct pcibus_attach_args pba; 1397 volatile struct dino_regs *r; 1398 bus_addr_t mem_start; 1399 const char *p; 1400 u_int data; 1401 int s, ver; 1402 1403 sc->sc_bt = ca->ca_iot; 1404 sc->sc_dmat = ca->ca_dmatag; 1405 if (bus_space_map(sc->sc_bt, ca->ca_hpa, PAGE_SIZE, 0, &sc->sc_bh)) { 1406 printf(": can't map space\n"); 1407 return; 1408 } 1409 1410 sc->sc_regs = r = (volatile struct dino_regs *)sc->sc_bh; 1411 r->io_control = 0x80; 1412 r->pamr = 0; 1413 r->papr = 0; 1414 r->io_fbb_en |= 1; 1415 r->io_addr_en = 0; 1416 r->damode = 0; 1417 r->gmask &= ~1; /* allow GSC bus req */ 1418 r->pciror = 0; 1419 r->pciwor = 0; 1420 r->brdg_feat = 0xc0000000; 1421 1422 /* PCI reset */ 1423 r->pcicmd = 0x6f; 1424 1425 snprintf(sc->sc_ioexname, sizeof(sc->sc_ioexname), 1426 "%s_io", sc->sc_dv.dv_xname); 1427 if ((sc->sc_ioex = extent_create(sc->sc_ioexname, 0, 0xffff, 1428 M_DEVBUF, NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) { 1429 printf(": cannot allocate I/O extent map\n"); 1430 bus_space_unmap(sc->sc_bt, sc->sc_bh, PAGE_SIZE); 1431 return; 1432 } 1433 1434 /* TODO reserve dino's pci space ? */ 1435 1436 /* XXX assuming that dino attaches the last */ 1437 if (bus_space_alloc(sc->sc_bt, 0xf0800000, 0xff7fffff, DINO_MEM_WINDOW, 1438 DINO_MEM_CHUNK, EX_NOBOUNDARY, 0, &mem_start, &sc->sc_memh)) { 1439 printf(": cannot allocate memory window\n"); 1440 bus_space_unmap(sc->sc_bt, sc->sc_bh, PAGE_SIZE); 1441 return; 1442 } 1443 snprintf(sc->sc_memexname, sizeof(sc->sc_memexname), 1444 "%s_mem", sc->sc_dv.dv_xname); 1445 if ((sc->sc_memex = extent_create(sc->sc_memexname, mem_start, 1446 mem_start + DINO_MEM_WINDOW, M_DEVBUF, NULL, 0, 1447 EX_NOWAIT | EX_MALLOCOK)) == NULL) { 1448 printf(": cannot allocate MEM extent map\n"); 1449 extent_destroy(sc->sc_ioex); 1450 bus_space_unmap(sc->sc_bt, sc->sc_bh, PAGE_SIZE); 1451 bus_space_unmap(sc->sc_bt, sc->sc_memh, DINO_MEM_WINDOW); 1452 return; 1453 } 1454 1455 s = splhigh(); 1456 r->imr = ~0; 1457 data = r->irr0; 1458 r->imr = 0; 1459 r->iar0 = cpu_gethpa(0) | (31 - ca->ca_irq); 1460 splx(s); 1461 1462 sc->sc_ih = cpu_intr_establish(IPL_NESTED, ca->ca_irq, 1463 dino_intr, (void *)sc->sc_regs, sc->sc_dv.dv_xname); 1464 /* TODO establish the bus error interrupt */ 1465 1466 r->iodc = 0; 1467 data = r->iodc; 1468 ver = (ca->ca_type.iodc_model << 4) | 1469 (ca->ca_type.iodc_revision >> 4); 1470 switch (ver) { 1471 case 0x05d: p = "Dino"; /* j2240 */ 1472 case 0x680: p = "Dino"; 1473 switch (data >> 16) { 1474 case 0x6800: ver = 0x20; break; 1475 case 0x6801: ver = 0x21; break; 1476 case 0x6802: ver = 0x30; break; 1477 case 0x6803: ver = 0x31; break; 1478 default: ver = 0x40; break; 1479 } 1480 break; 1481 1482 case 0x682: p = "Cujo"; 1483 switch (data >> 16) { 1484 case 0x6820: ver = 0x10; break; 1485 case 0x6821: ver = 0x20; break; 1486 default: ver = 0x30; break; 1487 } 1488 break; 1489 1490 default: p = "Mojo"; 1491 ver = (data >> 16) & 0xff; 1492 break; 1493 } 1494 sc->sc_ver = ver; 1495 printf(": %s V%d.%d\n", p, ver >> 4, ver & 0xf); 1496 1497 sc->sc_iot = dino_iomemt; 1498 sc->sc_iot.hbt_cookie = sc; 1499 sc->sc_iot.hbt_map = dino_iomap; 1500 sc->sc_iot.hbt_alloc = dino_ioalloc; 1501 sc->sc_memt = dino_iomemt; 1502 sc->sc_memt.hbt_cookie = sc; 1503 sc->sc_memt.hbt_map = dino_memmap; 1504 sc->sc_memt.hbt_alloc = dino_memalloc; 1505 sc->sc_pc = dino_pc; 1506 sc->sc_pc._cookie = sc; 1507 sc->sc_dmatag = dino_dmat; 1508 sc->sc_dmatag._cookie = sc; 1509 1510 pba.pba_busname = "pci"; 1511 pba.pba_iot = &sc->sc_iot; 1512 pba.pba_memt = &sc->sc_memt; 1513 pba.pba_dmat = &sc->sc_dmatag; 1514 pba.pba_pc = &sc->sc_pc; 1515 pba.pba_bus = 0; 1516 config_found(self, &pba, dinoprint); 1517 1518 /* enable interrupts now that all the devices are there */ 1519 r->imr = sc->sc_imr; 1520 } 1521