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