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