Annotation of sys/arch/sgi/pci/macepcibridge.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: macepcibridge.c,v 1.12 2007/06/21 20:17:12 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se)
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: * 1. Redistributions of source code must retain the above copyright
! 10: * notice, this list of conditions and the following disclaimer.
! 11: * 2. Redistributions in binary form must reproduce the above copyright
! 12: * notice, this list of conditions and the following disclaimer in the
! 13: * documentation and/or other materials provided with the distribution.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
! 16: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 18: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
! 19: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 20: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 21: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 23: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 24: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 25: * SUCH DAMAGE.
! 26: *
! 27: */
! 28:
! 29: /*
! 30: * Machine dependent PCI BUS Bridge driver on Mace (O2).
! 31: */
! 32:
! 33: #include <sys/param.h>
! 34: #include <sys/systm.h>
! 35: #include <sys/kernel.h>
! 36: #include <sys/malloc.h>
! 37: #include <sys/device.h>
! 38: #include <sys/proc.h>
! 39: #include <sys/ioctl.h>
! 40: #include <sys/extent.h>
! 41: #include <uvm/uvm.h>
! 42:
! 43: #include <machine/autoconf.h>
! 44: #include <machine/pte.h>
! 45: #include <machine/cpu.h>
! 46: #include <machine/vmparam.h>
! 47:
! 48: #include <dev/pci/pcireg.h>
! 49: #include <dev/pci/pcivar.h>
! 50:
! 51: #include <mips64/archtype.h>
! 52: #include <sgi/localbus/crimebus.h>
! 53: #include <sgi/localbus/macebus.h>
! 54: #include <sgi/pci/macepcibrvar.h>
! 55:
! 56: extern void *macebus_intr_establish(void *, u_long, int, int,
! 57: int (*)(void *), void *, char *);
! 58: extern void macebus_intr_disestablish(void *, void *);
! 59: extern void pciaddr_remap(pci_chipset_tag_t);
! 60:
! 61: /**/
! 62: int mace_pcibrmatch(struct device *, void *, void *);
! 63: void mace_pcibrattach(struct device *, struct device *, void *);
! 64: void mace_pcibr_attach_hook(struct device *, struct device *,
! 65: struct pcibus_attach_args *);
! 66: int mace_pcibr_errintr(void *);
! 67:
! 68: pcitag_t mace_pcibr_make_tag(void *, int, int, int);
! 69: void mace_pcibr_decompose_tag(void *, pcitag_t, int *, int *, int *);
! 70:
! 71: int mace_pcibr_bus_maxdevs(void *, int);
! 72: pcireg_t mace_pcibr_conf_read(void *, pcitag_t, int);
! 73: void mace_pcibr_conf_write(void *, pcitag_t, int, pcireg_t);
! 74:
! 75: int mace_pcibr_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
! 76: const char *mace_pcibr_intr_string(void *, pci_intr_handle_t);
! 77: void *mace_pcibr_intr_establish(void *, pci_intr_handle_t,
! 78: int, int (*func)(void *), void *, char *);
! 79: void mace_pcibr_intr_disestablish(void *, void *);
! 80:
! 81: bus_addr_t mace_pcibr_pa_to_device(paddr_t);
! 82: paddr_t mace_pcibr_device_to_pa(bus_addr_t);
! 83:
! 84: struct cfattach macepcibr_ca = {
! 85: sizeof(struct mace_pcibr_softc), mace_pcibrmatch, mace_pcibrattach,
! 86: };
! 87:
! 88: struct cfdriver macepcibr_cd = {
! 89: NULL, "macepcibr", DV_DULL,
! 90: };
! 91:
! 92: long pci_io_ext_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof (long)];
! 93: long pci_mem_ext_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof (long)];
! 94:
! 95: bus_space_t mace_pcibbus_mem_tag = {
! 96: NULL,
! 97: (bus_addr_t)MACE_PCI_MEM_BASE,
! 98: NULL,
! 99: 0,
! 100: mace_pcib_read_1, mace_pcib_write_1,
! 101: mace_pcib_read_2, mace_pcib_write_2,
! 102: mace_pcib_read_4, mace_pcib_write_4,
! 103: mace_pcib_read_8, mace_pcib_write_8,
! 104: mace_pcib_space_map, mace_pcib_space_unmap, mace_pcib_space_region,
! 105: };
! 106:
! 107: bus_space_t mace_pcibbus_io_tag = {
! 108: NULL,
! 109: (bus_addr_t)MACE_PCI_IO_BASE,
! 110: NULL,
! 111: 0,
! 112: mace_pcib_read_1, mace_pcib_write_1,
! 113: mace_pcib_read_2, mace_pcib_write_2,
! 114: mace_pcib_read_4, mace_pcib_write_4,
! 115: mace_pcib_read_8, mace_pcib_write_8,
! 116: mace_pcib_space_map, mace_pcib_space_unmap, mace_pcib_space_region,
! 117: };
! 118:
! 119: /*
! 120: * PCI doesn't have any special needs; just use the generic versions
! 121: * of these functions.
! 122: */
! 123: struct machine_bus_dma_tag pci_bus_dma_tag = {
! 124: NULL, /* _cookie */
! 125: _dmamap_create,
! 126: _dmamap_destroy,
! 127: _dmamap_load,
! 128: _dmamap_load_mbuf,
! 129: _dmamap_load_uio,
! 130: _dmamap_load_raw,
! 131: _dmamap_unload,
! 132: _dmamap_sync,
! 133: _dmamem_alloc,
! 134: _dmamem_free,
! 135: _dmamem_map,
! 136: _dmamem_unmap,
! 137: _dmamem_mmap,
! 138: mace_pcibr_pa_to_device,
! 139: mace_pcibr_device_to_pa,
! 140: CRIME_MEMORY_MASK
! 141: };
! 142:
! 143: struct _perr_map {
! 144: pcireg_t mask;
! 145: pcireg_t flag;
! 146: char *text;
! 147: } perr_map[] = {
! 148: { PERR_MASTER_ABORT, PERR_MASTER_ABORT_ADDR_VALID, "master abort" },
! 149: { PERR_TARGET_ABORT, PERR_TARGET_ABORT_ADDR_VALID, "target abort" },
! 150: { PERR_DATA_PARITY_ERR,PERR_DATA_PARITY_ADDR_VALID, "data parity error" },
! 151: { PERR_RETRY_ERR, PERR_RETRY_ADDR_VALID, "retry error" },
! 152: { PERR_ILLEGAL_CMD, 0, "illegal command" },
! 153: { PERR_SYSTEM_ERR, 0, "system error" },
! 154: { PERR_INTERRUPT_TEST,0, "interrupt test" },
! 155: { PERR_PARITY_ERR, 0, "parity error" },
! 156: { PERR_OVERRUN, 0, "overrun error" },
! 157: { PERR_RSVD, 0, "reserved ??" },
! 158: { PERR_MEMORY_ADDR, 0, "memory address" },
! 159: { PERR_CONFIG_ADDR, 0, "config address" },
! 160: { 0, 0 }
! 161: };
! 162:
! 163:
! 164: static int mace_pcibrprint(void *, const char *pnp);
! 165:
! 166:
! 167: int
! 168: mace_pcibrmatch(struct device *parent, void *match, void *aux)
! 169: {
! 170: switch(sys_config.system_type) {
! 171: case SGI_O2:
! 172: return 1;
! 173: }
! 174: return (0);
! 175: }
! 176:
! 177: void
! 178: mace_pcibrattach(struct device *parent, struct device *self, void *aux)
! 179: {
! 180: struct mace_pcibr_softc *sc = (struct mace_pcibr_softc *)self;
! 181: struct pcibus_attach_args pba;
! 182: struct confargs *ca = aux;
! 183: pcireg_t pcireg;
! 184:
! 185: /*
! 186: * Common to all bridge chips.
! 187: */
! 188: sc->sc_pc.pc_conf_v = sc;
! 189: sc->sc_pc.pc_attach_hook = mace_pcibr_attach_hook;
! 190: sc->sc_pc.pc_make_tag = mace_pcibr_make_tag;
! 191: sc->sc_pc.pc_decompose_tag = mace_pcibr_decompose_tag;
! 192: sc->sc_pc.pc_sync_cache = sys_config._IOSyncDCache;
! 193:
! 194: /* Create extents for PCI mappings */
! 195: mace_pcibbus_io_tag.bus_extent = extent_create("pci_io",
! 196: MACE_PCI_IO_BASE, MACE_PCI_IO_BASE + MACE_PCI_IO_SIZE - 1,
! 197: M_DEVBUF, (caddr_t)pci_io_ext_storage,
! 198: sizeof(pci_io_ext_storage), EX_NOCOALESCE|EX_NOWAIT);
! 199:
! 200: mace_pcibbus_mem_tag.bus_extent = extent_create("pci_mem",
! 201: MACE_PCI_MEM_BASE, MACE_PCI_MEM_BASE + MACE_PCI_MEM_SIZE - 1,
! 202: M_DEVBUF, (caddr_t)pci_mem_ext_storage,
! 203: sizeof(pci_mem_ext_storage), EX_NOCOALESCE|EX_NOWAIT);
! 204:
! 205: /* local -> PCI MEM mapping offset */
! 206: sc->sc_mem_bus_space = &mace_pcibbus_mem_tag;
! 207:
! 208: /* local -> PCI IO mapping offset */
! 209: sc->sc_io_bus_space = &mace_pcibbus_io_tag;
! 210:
! 211: /* Map in PCI control registers */
! 212: sc->sc_memt = ca->ca_memt;
! 213: if (bus_space_map(sc->sc_memt, MACE_PCI_OFFS, 4096, 0, &sc->sc_memh)) {
! 214: printf("UH-OH! Can't map PCI control registers!\n");
! 215: return;
! 216: }
! 217: pcireg = bus_space_read_4(sc->sc_memt, sc->sc_memh, MACE_PCI_REVISION);
! 218:
! 219: printf(": mace rev %d, host system O2\n", pcireg);
! 220:
! 221: /* Register the PCI ERROR interrupt handler */
! 222: BUS_INTR_ESTABLISH(ca, NULL, 8, IST_LEVEL, IPL_HIGH,
! 223: mace_pcibr_errintr, (void *)sc, sc->sc_dev.dv_xname);
! 224:
! 225: sc->sc_pc.pc_bus_maxdevs = mace_pcibr_bus_maxdevs;
! 226: sc->sc_pc.pc_conf_read = mace_pcibr_conf_read;
! 227: sc->sc_pc.pc_conf_write = mace_pcibr_conf_write;
! 228:
! 229: sc->sc_pc.pc_intr_v = NULL;
! 230: sc->sc_pc.pc_intr_map = mace_pcibr_intr_map;
! 231: sc->sc_pc.pc_intr_string = mace_pcibr_intr_string;
! 232: sc->sc_pc.pc_intr_establish = mace_pcibr_intr_establish;
! 233: sc->sc_pc.pc_intr_disestablish = mace_pcibr_intr_disestablish;
! 234:
! 235: /*
! 236: * Firmware sucks. Remap PCI BAR registers. (sigh)
! 237: */
! 238: pciaddr_remap(&sc->sc_pc);
! 239:
! 240: /*
! 241: * Configure our PCI devices.
! 242: */
! 243: pba.pba_busname = "pci";
! 244: pba.pba_iot = sc->sc_io_bus_space;
! 245: pba.pba_memt = sc->sc_mem_bus_space;
! 246: pba.pba_dmat = malloc(sizeof(pci_bus_dma_tag), M_DEVBUF, M_NOWAIT);
! 247: *pba.pba_dmat = pci_bus_dma_tag;
! 248: pba.pba_pc = &sc->sc_pc;
! 249: pba.pba_domain = pci_ndomains++;
! 250: pba.pba_bus = sc->sc_dev.dv_unit;
! 251: pba.pba_bridgetag = NULL;
! 252: config_found(self, &pba, mace_pcibrprint);
! 253:
! 254: /* Clear PCI errors and set up error interrupt */
! 255: bus_space_write_4(sc->sc_memt, sc->sc_memh, MACE_PCI_ERROR_FLAGS, 0);
! 256: pcireg = bus_space_read_4(sc->sc_memt, sc->sc_memh, MACE_PCI_CONTROL);
! 257: pcireg |= MACE_PCI_INTCTRL;
! 258: bus_space_write_4(sc->sc_memt, sc->sc_memh, MACE_PCI_CONTROL, pcireg);
! 259: }
! 260:
! 261: static int
! 262: mace_pcibrprint(aux, pnp)
! 263: void *aux;
! 264: const char *pnp;
! 265: {
! 266: struct pcibus_attach_args *pba = aux;
! 267:
! 268: if (pnp)
! 269: printf("%s at %s", pba->pba_busname, pnp);
! 270: printf(" bus %d", pba->pba_bus);
! 271: return(UNCONF);
! 272: }
! 273:
! 274: void
! 275: mace_pcibr_attach_hook(parent, self, pba)
! 276: struct device *parent, *self;
! 277: struct pcibus_attach_args *pba;
! 278: {
! 279: }
! 280:
! 281: int
! 282: mace_pcibr_errintr(void *v)
! 283: {
! 284: struct mace_pcibr_softc *sc = v;
! 285: bus_space_tag_t memt = sc->sc_memt;
! 286: bus_space_handle_t memh = sc->sc_memh;
! 287: struct _perr_map *emap = perr_map;
! 288: pcireg_t stat, erraddr;
! 289:
! 290: /* Check and clear any PCI error, report found */
! 291: stat = bus_space_read_4(memt, memh, MACE_PCI_ERROR_FLAGS);
! 292: erraddr = bus_space_read_4(memt, memh, MACE_PCI_ERROR_ADDRESS);
! 293: while (emap->mask) {
! 294: if (stat & emap->mask) {
! 295: printf("mace: pci err %s", emap->text);
! 296: if (emap->flag && stat & emap->flag)
! 297: printf(" at address %p", erraddr);
! 298: printf("\n");
! 299: }
! 300: emap++;
! 301: }
! 302: bus_space_write_4(memt, memh, MACE_PCI_ERROR_FLAGS, 0);
! 303: return 1;
! 304: }
! 305:
! 306: /*
! 307: * PCI access drivers
! 308: */
! 309:
! 310: pcitag_t
! 311: mace_pcibr_make_tag(cpv, bus, dev, fnc)
! 312: void *cpv;
! 313: int bus, dev, fnc;
! 314: {
! 315: return (bus << 16) | (dev << 11) | (fnc << 8);
! 316: }
! 317:
! 318: void
! 319: mace_pcibr_decompose_tag(cpv, tag, busp, devp, fncp)
! 320: void *cpv;
! 321: pcitag_t tag;
! 322: int *busp, *devp, *fncp;
! 323: {
! 324: if (busp != NULL)
! 325: *busp = (tag >> 16) & 0x7;
! 326: if (devp != NULL)
! 327: *devp = (tag >> 11) & 0x1f;
! 328: if (fncp != NULL)
! 329: *fncp = (tag >> 8) & 0x7;
! 330: }
! 331:
! 332: int
! 333: mace_pcibr_bus_maxdevs(cpv, busno)
! 334: void *cpv;
! 335: int busno;
! 336: {
! 337: return(16);
! 338: }
! 339:
! 340: pcireg_t
! 341: mace_pcibr_conf_read(cpv, tag, offset)
! 342: void *cpv;
! 343: pcitag_t tag;
! 344: int offset;
! 345: {
! 346: struct mace_pcibr_softc *sc = cpv;
! 347: bus_space_tag_t memt = sc->sc_memt;
! 348: bus_space_handle_t memh = sc->sc_memh;
! 349: pcireg_t data, stat;
! 350: int s;
! 351:
! 352: s = splhigh();
! 353:
! 354: bus_space_write_4(memt, memh, MACE_PCI_ERROR_FLAGS, 0);
! 355: data = tag | offset;
! 356: bus_space_write_4(memt, memh, MACE_PCI_CFGADDR, data);
! 357: data = bus_space_read_4(memt, memh, MACE_PCI_CFGDATA);
! 358: bus_space_write_4(memt, memh, MACE_PCI_CFGADDR, 0);
! 359:
! 360: /* Check and clear any PCI error, returns -1 if error is found */
! 361: stat = bus_space_read_4(memt, memh, MACE_PCI_ERROR_FLAGS);
! 362: bus_space_write_4(memt, memh, MACE_PCI_ERROR_FLAGS, 0);
! 363: if (stat & (PERR_MASTER_ABORT | PERR_TARGET_ABORT |
! 364: PERR_DATA_PARITY_ERR | PERR_RETRY_ERR)) {
! 365: data = -1;
! 366: }
! 367:
! 368: splx(s);
! 369: return(data);
! 370: }
! 371:
! 372: void
! 373: mace_pcibr_conf_write(cpv, tag, offset, data)
! 374: void *cpv;
! 375: pcitag_t tag;
! 376: int offset;
! 377: pcireg_t data;
! 378: {
! 379: struct mace_pcibr_softc *sc = cpv;
! 380: pcireg_t addr;
! 381: int s;
! 382:
! 383: s = splhigh();
! 384:
! 385: addr = tag | offset;
! 386: bus_space_write_4(sc->sc_memt, sc->sc_memh, MACE_PCI_CFGADDR, addr);
! 387: bus_space_write_4(sc->sc_memt, sc->sc_memh, MACE_PCI_CFGDATA, data);
! 388: bus_space_write_4(sc->sc_memt, sc->sc_memh, MACE_PCI_CFGADDR, 0);
! 389:
! 390: splx(s);
! 391: }
! 392:
! 393: int
! 394: mace_pcibr_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
! 395: {
! 396: int bus, device, pirq;
! 397:
! 398: *ihp = -1;
! 399:
! 400: if (pa->pa_intrpin == 0) {
! 401: /* No IRQ used. */
! 402: return 1;
! 403: }
! 404: if (pa->pa_intrpin > 4) {
! 405: printf("mace_pcibr_intr_map: bad interrupt pin %d\n", pa->pa_intrpin);
! 406: return 1;
! 407: }
! 408:
! 409: mace_pcibr_decompose_tag((void *)NULL, pa->pa_tag, &bus, &device, NULL);
! 410:
! 411: if (sys_config.system_type == SGI_O2) {
! 412: pirq = -1;
! 413: switch (device) {
! 414: case 1:
! 415: pirq = 9;
! 416: break;
! 417: case 2:
! 418: pirq = 10;
! 419: break;
! 420: case 3:
! 421: pirq = 11;
! 422: break;
! 423: }
! 424: }
! 425:
! 426: *ihp = pirq;
! 427: return 0;
! 428: }
! 429:
! 430: const char *
! 431: mace_pcibr_intr_string(lcv, ih)
! 432: void *lcv;
! 433: pci_intr_handle_t ih;
! 434: {
! 435: static char str[16];
! 436:
! 437: snprintf(str, sizeof(str), "irq %d", ih);
! 438: return(str);
! 439: }
! 440:
! 441: void *
! 442: mace_pcibr_intr_establish(lcv, ih, level, func, arg, name)
! 443: void *lcv;
! 444: pci_intr_handle_t ih;
! 445: int level;
! 446: int (*func)(void *);
! 447: void *arg;
! 448: char *name;
! 449: {
! 450: return macebus_intr_establish(NULL, ih, IST_LEVEL, level, func, arg, name);
! 451: }
! 452:
! 453: void
! 454: mace_pcibr_intr_disestablish(lcv, cookie)
! 455: void *lcv, *cookie;
! 456: {
! 457: macebus_intr_disestablish(lcv, cookie);
! 458: }
! 459:
! 460: /*
! 461: * Bus access primitives
! 462: * XXX 64 bit access not clean in lp32 mode.
! 463: */
! 464:
! 465: u_int8_t
! 466: mace_pcib_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
! 467: {
! 468: return *(volatile u_int8_t *)(h + (o | 3) - (o & 3));
! 469: }
! 470:
! 471: u_int16_t
! 472: mace_pcib_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
! 473: {
! 474: return *(volatile u_int16_t *)(h + (o | 2) - (o & 3));
! 475: }
! 476:
! 477: u_int32_t
! 478: mace_pcib_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
! 479: {
! 480: return *(volatile u_int32_t *)(h + o);
! 481: }
! 482:
! 483: u_int64_t
! 484: mace_pcib_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
! 485: {
! 486: return *(volatile u_int64_t *)(h + o);
! 487: }
! 488:
! 489: void
! 490: mace_pcib_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
! 491: {
! 492: *(volatile u_int8_t *)(h + (o | 3) - (o & 3)) = v;
! 493: }
! 494:
! 495: void
! 496: mace_pcib_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v)
! 497: {
! 498: *(volatile u_int16_t *)(h + (o | 2) - (o & 3)) = v;
! 499: }
! 500:
! 501: void
! 502: mace_pcib_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v)
! 503: {
! 504: *(volatile u_int32_t *)(h + o) = v;
! 505: }
! 506:
! 507: void
! 508: mace_pcib_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v)
! 509: {
! 510: *(volatile u_int64_t *)(h + o) = v;
! 511: }
! 512:
! 513: extern int extent_malloc_flags;
! 514:
! 515: int
! 516: mace_pcib_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
! 517: int cacheable, bus_space_handle_t *bshp)
! 518: {
! 519: bus_addr_t bpa;
! 520: int error;
! 521: bpa = t->bus_base + (offs & 0x01ffffff);
! 522:
! 523: if ((error = extent_alloc_region(t->bus_extent, bpa, size,
! 524: EX_NOWAIT | extent_malloc_flags))) {
! 525: return error;
! 526: }
! 527:
! 528: if ((error = bus_mem_add_mapping(bpa, size, cacheable, bshp))) {
! 529: if (extent_free(t->bus_extent, bpa, size,
! 530: EX_NOWAIT | extent_malloc_flags)) {
! 531: printf("bus_space_map: pa %p, size %p\n", bpa, size);
! 532: printf("bus_space_map: can't free region\n");
! 533: }
! 534: }
! 535:
! 536: return (error);
! 537: }
! 538:
! 539: void
! 540: mace_pcib_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
! 541: {
! 542: bus_addr_t sva;
! 543: bus_size_t off, len;
! 544: bus_addr_t paddr;
! 545:
! 546: /* should this verify that the proper size is freed? */
! 547: sva = trunc_page(bsh);
! 548: off = bsh - sva;
! 549: len = size+off;
! 550:
! 551: if (pmap_extract(pmap_kernel(), bsh, (void *)&paddr) == 0) {
! 552: printf("bus_space_unmap: no pa for va %p\n", bsh);
! 553: return;
! 554: }
! 555:
! 556: if (extent_free(t->bus_extent, paddr, size,
! 557: EX_NOWAIT | extent_malloc_flags)) {
! 558: printf("bus_space_map: pa %p, size %p\n", paddr, size);
! 559: printf("bus_space_map: can't free region\n");
! 560: }
! 561: }
! 562:
! 563: int
! 564: mace_pcib_space_region(bus_space_tag_t t, bus_space_handle_t bsh,
! 565: bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
! 566: {
! 567: *nbshp = bsh + offset;
! 568: return (0);
! 569: }
! 570:
! 571: /*
! 572: * Mace PCI bus_dma helpers.
! 573: * The PCI bus accesses memory contiguously at 0x00000000 onwards.
! 574: */
! 575:
! 576: bus_addr_t
! 577: mace_pcibr_pa_to_device(paddr_t pa)
! 578: {
! 579: return (pa & CRIME_MEMORY_MASK);
! 580: }
! 581:
! 582: paddr_t
! 583: mace_pcibr_device_to_pa(bus_addr_t addr)
! 584: {
! 585: paddr_t pa = (paddr_t)addr & CRIME_MEMORY_MASK;
! 586:
! 587: if (pa >= 256 * 1024 * 1024)
! 588: pa |= CRIME_MEMORY_OFFSET;
! 589:
! 590: return (pa);
! 591: }
CVSweb