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