Module Name: src Committed By: mrg Date: Tue Mar 15 11:42:03 UTC 2011
Modified Files: src/sys/arch/sparc64/dev: ebus_mainbus.c pyro.c pyrovar.h Log Message: initial port of these drivers to netbsd. both pyro(4) and ebus(4) at mainbus depend upon other as-yet uncommited changes. To generate a diff of this commit: cvs rdiff -u -r1.1.1.1 -r1.2 src/sys/arch/sparc64/dev/ebus_mainbus.c \ src/sys/arch/sparc64/dev/pyro.c src/sys/arch/sparc64/dev/pyrovar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc64/dev/ebus_mainbus.c diff -u src/sys/arch/sparc64/dev/ebus_mainbus.c:1.1.1.1 src/sys/arch/sparc64/dev/ebus_mainbus.c:1.2 --- src/sys/arch/sparc64/dev/ebus_mainbus.c:1.1.1.1 Tue Mar 15 11:21:04 2011 +++ src/sys/arch/sparc64/dev/ebus_mainbus.c Tue Mar 15 11:42:03 2011 @@ -1,3 +1,4 @@ +/* $NetBSD: ebus_mainbus.c,v 1.2 2011/03/15 11:42:03 mrg Exp $ */ /* $OpenBSD: ebus_mainbus.c,v 1.7 2010/11/11 17:58:23 miod Exp $ */ /* @@ -41,35 +42,33 @@ #define _SPARC_BUS_DMA_PRIVATE #include <machine/bus.h> #include <machine/autoconf.h> -#include <machine/hypervisor.h> +//#include <machine/hypervisor.h> #include <machine/openfirm.h> #include <dev/pci/pcivar.h> #include <sparc64/dev/iommureg.h> -#include <sparc64/dev/ebusreg.h> -#include <sparc64/dev/ebusvar.h> +#include <sparc64/dev/iommuvar.h> #include <sparc64/dev/pyrovar.h> +#include <dev/ebus/ebusreg.h> +#include <dev/ebus/ebusvar.h> +#include <sparc64/dev/ebusvar.h> -extern struct cfdriver pyro_cd; - -int ebus_mainbus_match(struct device *, void *, void *); +int ebus_mainbus_match(struct device *, struct cfdata *, void *); void ebus_mainbus_attach(struct device *, struct device *, void *); -struct cfattach ebus_mainbus_ca = { - sizeof(struct ebus_softc), ebus_mainbus_match, ebus_mainbus_attach -}; - +CFATTACH_DECL(ebus_mainbus, sizeof(struct ebus_softc), + ebus_mainbus_match, ebus_mainbus_attach, NULL, NULL); -int ebus_mainbus_bus_map(bus_space_tag_t, bus_space_tag_t, - bus_addr_t, bus_size_t, int, bus_space_handle_t *); -void *ebus_mainbus_intr_establish(bus_space_tag_t, bus_space_tag_t, - int, int, int, int (*)(void *), void *, const char *); -bus_space_tag_t ebus_alloc_bus_tag(struct ebus_softc *, bus_space_tag_t); +int ebus_mainbus_bus_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, + vaddr_t, bus_space_handle_t *); +void *ebus_mainbus_intr_establish(bus_space_tag_t, int, int, + int (*)(void *), void *, void (*)(void)); +bus_space_tag_t ebus_mainbus_alloc_bus_tag(struct ebus_softc *, bus_space_tag_t, int); void ebus_mainbus_intr_ack(struct intrhand *); int -ebus_mainbus_match(struct device *parent, void *match, void *aux) +ebus_mainbus_match(struct device *parent, struct cfdata *match, void *aux) { struct mainbus_attach_args *ma = aux; @@ -94,11 +93,14 @@ if (CPU_ISSUN4U) { printf(": ign %x", sc->sc_ign); + /* XXX */ + extern struct cfdriver pyro_cd; for (i = 0; i < pyro_cd.cd_ndevs; i++) { - psc = pyro_cd.cd_devs[i]; + device_t dt = pyro_cd.cd_devs[i]; + psc = (struct pyro_softc *)dt; if (psc && psc->sc_ign == sc->sc_ign) { - sc->sc_bust = psc->sc_bust; + sc->sc_bust = psc->sc_bustag; sc->sc_csr = psc->sc_csr; sc->sc_csrh = psc->sc_csrh; break; @@ -113,22 +115,23 @@ printf("\n"); - sc->sc_memtag = ebus_alloc_bus_tag(sc, ma->ma_bustag); - sc->sc_iotag = ebus_alloc_bus_tag(sc, ma->ma_bustag); - sc->sc_dmatag = ebus_alloc_dma_tag(sc, ma->ma_dmatag); + sc->sc_memtag = ebus_mainbus_alloc_bus_tag(sc, ma->ma_bustag, PCI_MEMORY_BUS_SPACE); + sc->sc_iotag = ebus_mainbus_alloc_bus_tag(sc, ma->ma_bustag, PCI_IO_BUS_SPACE); + sc->sc_childbustag = sc->sc_memtag; + sc->sc_dmatag = ma->ma_dmatag; /* * fill in our softc with information from the prom */ sc->sc_intmap = NULL; sc->sc_range = NULL; - error = getprop(node, "interrupt-map", + error = prom_getprop(node, "interrupt-map", sizeof(struct ebus_interrupt_map), &sc->sc_nintmap, (void **)&sc->sc_intmap); switch (error) { case 0: immp = &sc->sc_intmapmask; - error = getprop(node, "interrupt-map-mask", + error = prom_getprop(node, "interrupt-map-mask", sizeof(struct ebus_interrupt_map_mask), &nmapmask, (void **)&immp); if (error) @@ -143,7 +146,7 @@ break; } - error = getprop(node, "ranges", sizeof(struct ebus_mainbus_ranges), + error = prom_getprop(node, "ranges", sizeof(struct ebus_mainbus_ranges), &sc->sc_nrange, (void **)&sc->sc_range); if (error) panic("ebus ranges: error %d", error); @@ -156,7 +159,7 @@ if (ebus_setup_attach_args(sc, node, &eba) != 0) { DPRINTF(EDB_CHILD, ("ebus_mainbus_attach: %s: incomplete\n", - getpropstring(node, "name"))); + prom_getpropstring(node, "name"))); continue; } else { DPRINTF(EDB_CHILD, ("- found child `%s', attaching\n", @@ -168,7 +171,7 @@ } bus_space_tag_t -ebus_alloc_bus_tag(struct ebus_softc *sc, bus_space_tag_t parent) +ebus_mainbus_alloc_bus_tag(struct ebus_softc *sc, bus_space_tag_t parent, int type) { struct sparc_bus_space_tag *bt; @@ -176,25 +179,24 @@ if (bt == NULL) panic("could not allocate ebus bus tag"); - strlcpy(bt->name, sc->sc_dev.dv_xname, sizeof(bt->name)); bt->cookie = sc; bt->parent = parent; - bt->asi = parent->asi; - bt->sasi = parent->sasi; + bt->type = type; bt->sparc_bus_map = ebus_mainbus_bus_map; + bt->sparc_bus_mmap = ebus_bus_mmap; bt->sparc_intr_establish = ebus_mainbus_intr_establish; return (bt); } int -ebus_mainbus_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset, - bus_size_t size, int flags, bus_space_handle_t *hp) +ebus_mainbus_bus_map(bus_space_tag_t t, bus_addr_t offset, bus_size_t size, + int flags, vaddr_t va, bus_space_handle_t *hp) { struct ebus_softc *sc = t->cookie; struct ebus_mainbus_ranges *range; bus_addr_t hi, lo; - int i; + int i, ss; DPRINTF(EDB_BUSMAP, ("\n_ebus_mainbus_bus_map: off %016llx sz %x flags %d", @@ -207,11 +209,6 @@ t = t->parent; - if (flags & BUS_SPACE_MAP_PROMADDRESS) { - return ((*t->sparc_bus_map) - (t, t0, offset, size, flags, hp)); - } - hi = offset >> 32UL; lo = offset & 0xffffffff; range = (struct ebus_mainbus_ranges *)sc->sc_range; @@ -226,25 +223,47 @@ (lo + size) > (range[i].child_lo + range[i].size)) continue; +#if 0 + /* Isolate address space and find the right tag */ + ss = (range[i].phys_hi>>24)&3; + switch (ss) { + case 1: /* I/O space */ + t = sc->sc_iotag; + break; + case 2: /* Memory space */ + t = sc->sc_memtag; + break; + case 0: /* Config space */ + case 3: /* 64-bit Memory space */ + default: /* WTF? */ + /* We don't handle these */ + panic("ebus_mainbus_bus_map: illegal space %x", ss); + break; + } +#else +ss = 0; +#endif + addr = ((bus_addr_t)range[i].phys_hi << 32UL) | range[i].phys_lo; addr += lo; DPRINTF(EDB_BUSMAP, ("\n_ebus_mainbus_bus_map: paddr offset %qx addr %qx\n", (unsigned long long)offset, (unsigned long long)addr)); - return ((*t->sparc_bus_map)(t, t0, addr, size, flags, hp)); + return (bus_space_map(t, addr, size, flags, hp)); } DPRINTF(EDB_BUSMAP, (": FAILED\n")); return (EINVAL); } void * -ebus_mainbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, - int level, int flags, int (*handler)(void *), void *arg, const char *what) +ebus_mainbus_intr_establish(bus_space_tag_t t, int ihandle, int level, + int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */) { struct ebus_softc *sc = t->cookie; struct intrhand *ih = NULL; volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL; + u_int64_t *imap, *iclr; int ino; #ifdef SUN4V @@ -301,33 +320,37 @@ ihandle |= sc->sc_ign; ino = INTINO(ihandle); - if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) { - u_int64_t *imap, *iclr; + /* XXX */ + imap = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1000); + iclr = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1400); + intrmapptr = &imap[ino]; + intrclrptr = &iclr[ino]; + ino |= INTVEC(ihandle); - /* XXX */ - imap = bus_space_vaddr(sc->sc_bust, sc->sc_csrh) + 0x1000; - iclr = bus_space_vaddr(sc->sc_bust, sc->sc_csrh) + 0x1400; - intrmapptr = &imap[ino]; - intrclrptr = &iclr[ino]; - ino |= INTVEC(ihandle); - } - - ih = bus_intr_allocate(t0, handler, arg, ino, level, intrmapptr, - intrclrptr, what); + ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT); if (ih == NULL) return (NULL); - intr_establish(ih->ih_pil, ih); + /* Register the map and clear intr registers */ + ih->ih_map = intrmapptr; + ih->ih_clr = intrclrptr; + + ih->ih_fun = handler; + ih->ih_arg = arg; + ih->ih_pil = level; + ih->ih_number = ino; + + intr_establish(ih->ih_pil, level != IPL_VM, ih); if (intrmapptr != NULL) { - u_int64_t intrmap; + u_int64_t imapval; - intrmap = *intrmapptr; - intrmap |= (1LL << 6); - intrmap |= INTMAP_V; - *intrmapptr = intrmap; - intrmap = *intrmapptr; - ih->ih_number |= intrmap & INTMAP_INR; + imapval = *intrmapptr; + imapval |= (1LL << 6); + imapval |= INTMAP_V; + *intrmapptr = imapval; + imapval = *intrmapptr; + ih->ih_number |= imapval & INTMAP_INR; } return (ih); Index: src/sys/arch/sparc64/dev/pyro.c diff -u src/sys/arch/sparc64/dev/pyro.c:1.1.1.1 src/sys/arch/sparc64/dev/pyro.c:1.2 --- src/sys/arch/sparc64/dev/pyro.c:1.1.1.1 Tue Mar 15 11:21:04 2011 +++ src/sys/arch/sparc64/dev/pyro.c Tue Mar 15 11:42:03 2011 @@ -1,9 +1,11 @@ -/* $OpenBSD: pyro.c,v 1.20 2010/12/05 15:15:14 kettenis Exp $ */ +/* $NetBSD: pyro.c,v 1.2 2011/03/15 11:42:03 mrg Exp $ */ +/* from: $OpenBSD: pyro.c,v 1.20 2010/12/05 15:15:14 kettenis Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (ja...@thought.net) * Copyright (c) 2003 Henric Jungheim * Copyright (c) 2007 Mark Kettenis + * Copyright (c) 2011 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,7 +56,7 @@ #define PDB_BUSMAP 0x02 #define PDB_INTR 0x04 #define PDB_CONF 0x08 -int pyro_debug = ~0; +int pyro_debug = 0x4; #define DPRINTF(l, s) do { if (pyro_debug & l) printf s; } while (0) #else #define DPRINTF(l, s) @@ -77,42 +79,53 @@ extern struct sparc_pci_chipset _sparc_pci_chipset; -int pyro_match(struct device *, void *, void *); +int pyro_match(struct device *, struct cfdata *, void *); void pyro_attach(struct device *, struct device *, void *); +int pyro_print(void *, const char *); + +CFATTACH_DECL(pyro, sizeof(struct pyro_softc), + pyro_match, pyro_attach, NULL, NULL); + void pyro_init(struct pyro_softc *, int); void pyro_init_iommu(struct pyro_softc *, struct pyro_pbm *); -int pyro_print(void *, const char *); pci_chipset_tag_t pyro_alloc_chipset(struct pyro_pbm *, int, pci_chipset_tag_t); bus_space_tag_t pyro_alloc_mem_tag(struct pyro_pbm *); bus_space_tag_t pyro_alloc_io_tag(struct pyro_pbm *); bus_space_tag_t pyro_alloc_config_tag(struct pyro_pbm *); -bus_space_tag_t _pyro_alloc_bus_tag(struct pyro_pbm *, const char *, - int, int, int); +bus_space_tag_t pyro_alloc_bus_tag(struct pyro_pbm *, const char *, int); bus_dma_tag_t pyro_alloc_dma_tag(struct pyro_pbm *); +#if 0 int pyro_conf_size(pci_chipset_tag_t, pcitag_t); +#endif pcireg_t pyro_conf_read(pci_chipset_tag_t, pcitag_t, int); void pyro_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); +static void * pyro_pci_intr_establish(pci_chipset_tag_t pc, + pci_intr_handle_t ih, int level, + int (*func)(void *), void *arg); + int pyro_intr_map(struct pci_attach_args *, pci_intr_handle_t *); -int _pyro_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, - bus_size_t, int, bus_space_handle_t *); -paddr_t _pyro_bus_mmap(bus_space_tag_t, bus_space_tag_t, bus_addr_t, off_t, +int pyro_bus_map(bus_space_tag_t, bus_addr_t, + bus_size_t, int, vaddr_t, bus_space_handle_t *); +paddr_t pyro_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); -void *_pyro_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, int, - int (*)(void *), void *, const char *); +void *pyro_intr_establish(bus_space_tag_t, int, int, + int (*)(void *), void *, void (*)(void)); -int pyro_dmamap_create(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, int, +int pyro_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, bus_size_t, int, bus_dmamap_t *); +#if 0 #ifdef DDB void pyro_xir(void *, int); #endif +#endif int -pyro_match(struct device *parent, void *match, void *aux) +pyro_match(struct device *parent, struct cfdata *match, void *aux) { struct mainbus_attach_args *ma = aux; char *str; @@ -120,7 +133,7 @@ if (strcmp(ma->ma_name, "pci") != 0) return (0); - str = getpropstring(ma->ma_node, "compatible"); + str = prom_getpropstring(ma->ma_node, "compatible"); if (strcmp(str, "pciex108e,80f0") == 0 || strcmp(str, "pciex108e,80f8") == 0) return (1); @@ -138,7 +151,7 @@ sc->sc_node = ma->ma_node; sc->sc_dmat = ma->ma_dmatag; - sc->sc_bust = ma->ma_bustag; + sc->sc_bustag = ma->ma_bustag; sc->sc_csr = ma->ma_reg[0].ur_paddr; sc->sc_xbc = ma->ma_reg[1].ur_paddr; sc->sc_ign = INTIGN(ma->ma_upaid << INTMAP_IGN_SHIFT); @@ -148,19 +161,19 @@ else busa = 0; - if (bus_space_map(sc->sc_bust, sc->sc_csr, - ma->ma_reg[0].ur_len, 0, &sc->sc_csrh)) { + if (bus_space_map(sc->sc_bustag, sc->sc_csr, + ma->ma_reg[0].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_csrh)) { printf(": failed to map csr registers\n"); return; } - if (bus_space_map(sc->sc_bust, sc->sc_xbc, + if (bus_space_map(sc->sc_bustag, sc->sc_xbc, ma->ma_reg[1].ur_len, 0, &sc->sc_xbch)) { printf(": failed to map xbc registers\n"); return; } - str = getpropstring(ma->ma_node, "compatible"); + str = prom_getpropstring(ma->ma_node, "compatible"); if (strcmp(str, "pciex108e,80f8") == 0) sc->sc_oberon = 1; @@ -181,17 +194,17 @@ pbm->pp_sc = sc; pbm->pp_bus_a = busa; - if (getprop(sc->sc_node, "ranges", sizeof(struct pyro_range), + if (prom_getprop(sc->sc_node, "ranges", sizeof(struct pyro_range), &pbm->pp_nrange, (void **)&pbm->pp_range)) panic("pyro: can't get ranges"); - if (getprop(sc->sc_node, "bus-range", sizeof(int), &nranges, + if (prom_getprop(sc->sc_node, "bus-range", sizeof(int), &nranges, (void **)&busranges)) panic("pyro: can't get bus-range"); printf(": \"%s\", rev %d, ign %x, bus %c %d to %d\n", sc->sc_oberon ? "Oberon" : "Fire", - getpropint(sc->sc_node, "module-revision#", 0), sc->sc_ign, + prom_getpropint(sc->sc_node, "module-revision#", 0), sc->sc_ign, busa ? 'A' : 'B', busranges[0], busranges[1]); printf("%s: ", sc->sc_dv.dv_xname); @@ -201,36 +214,41 @@ pbm->pp_iot = pyro_alloc_io_tag(pbm); pbm->pp_cfgt = pyro_alloc_config_tag(pbm); pbm->pp_dmat = pyro_alloc_dma_tag(pbm); + pbm->pp_flags = (pbm->pp_memt ? PCI_FLAGS_MEM_ENABLED : 0) | + (pbm->pp_iot ? PCI_FLAGS_IO_ENABLED : 0); if (bus_space_map(pbm->pp_cfgt, 0, 0x10000000, 0, &pbm->pp_cfgh)) panic("pyro: can't map config space"); +printf("cfgh: _ptr %p _asi %x _sasi %x\n", (void *)pbm->pp_cfgh._ptr, pbm->pp_cfgh._asi, pbm->pp_cfgh._sasi); pbm->pp_pc = pyro_alloc_chipset(pbm, sc->sc_node, &_sparc_pci_chipset); + pbm->pp_pc->spc_busmax = busranges[1]; + pbm->pp_pc->spc_busnode = malloc(sizeof(*pbm->pp_pc->spc_busnode), + M_DEVBUF, M_NOWAIT | M_ZERO); + if (pbm->pp_pc->spc_busnode == NULL) + panic("schizo: malloc busnode"); +#if 0 pbm->pp_pc->bustag = pbm->pp_cfgt; pbm->pp_pc->bushandle = pbm->pp_cfgh; +#endif bzero(&pba, sizeof(pba)); - pba.pba_busname = "pci"; - pba.pba_domain = pci_ndomains++; pba.pba_bus = busranges[0]; pba.pba_pc = pbm->pp_pc; -#if 0 pba.pba_flags = pbm->pp_flags; -#endif pba.pba_dmat = pbm->pp_dmat; + pba.pba_dmat64 = NULL; /* XXX */ pba.pba_memt = pbm->pp_memt; pba.pba_iot = pbm->pp_iot; - pba.pba_pc->conf_size = pyro_conf_size; - pba.pba_pc->conf_read = pyro_conf_read; - pba.pba_pc->conf_write = pyro_conf_write; - pba.pba_pc->intr_map = pyro_intr_map; free(busranges, M_DEVBUF); -#ifdef DDB +#if 0 +#ifdef DDB db_register_xir(pyro_xir, sc); #endif +#endif config_found(&sc->sc_dv, &pba, pyro_print); } @@ -243,15 +261,18 @@ u_int32_t iobase = -1; char *name; - is->is_bustag = sc->sc_bust; + pbm->pp_sb.sb_is = is; + is->is_bustag = sc->sc_bustag; if (bus_space_subregion(is->is_bustag, sc->sc_csrh, 0x40000, 0x100, &is->is_iommu)) { panic("pyro: unable to create iommu handle"); } +#if 0 is->is_sb[0] = &pbm->pp_sb; is->is_sb[0]->sb_bustag = is->is_bustag; +#endif name = (char *)malloc(32, M_DEVBUF, M_NOWAIT); if (name == NULL) @@ -273,24 +294,45 @@ return (QUIET); } +#if 0 /* XXXMRG */ int pyro_conf_size(pci_chipset_tag_t pc, pcitag_t tag) { return PCIE_CONFIG_SPACE_SIZE; } +#endif pcireg_t pyro_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) { - return (bus_space_read_4(pc->bustag, pc->bushandle, - (PCITAG_OFFSET(tag) << 4) + reg)); + struct pyro_pbm *pp = pc->cookie; + pcireg_t val = (pcireg_t)~0; + + DPRINTF(PDB_CONF, ("%s: tag %lx reg %x ", __func__, (long)tag, reg)); + if (PCITAG_NODE(tag) != -1) + val = bus_space_read_4(pp->pp_cfgt, pp->pp_cfgh, + (PCITAG_OFFSET(tag) << 4) + reg); + DPRINTF(PDB_CONF, (" returning %08x\n", (u_int)val)); + return (val); } void pyro_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) { - bus_space_write_4(pc->bustag, pc->bushandle, + struct pyro_pbm *pp = pc->cookie; + + DPRINTF(PDB_CONF, ("%s: tag %lx; reg %x; data %x", __func__, + (long)tag, reg, (int)data)); + + /* If we don't know it, just punt it. */ + if (PCITAG_NODE(tag) == -1) { + DPRINTF(PDB_CONF, (" .. bad addr\n")); + return; + } + + bus_space_write_4(pp->pp_cfgt, pp->pp_cfgh, (PCITAG_OFFSET(tag) << 4) + reg, data); + DPRINTF(PDB_CONF, (" .. done\n")); } /* @@ -305,6 +347,7 @@ if (*ihp != (pci_intr_handle_t)-1) { *ihp |= sc->sc_ign; + DPRINTF(PDB_INTR, ("%s: not -1 -> ih %lx", __func__, (u_long)*ihp)); return (0); } @@ -315,8 +358,10 @@ * UltraSPARC-IIi User's Manual. */ - if (pa->pa_intrpin == 0) + if (pa->pa_intrpin == 0) { + DPRINTF(PDB_INTR, ("%s: no intrpen", __func__)); return (-1); + } /* * This deserves some documentation. Should anyone @@ -328,36 +373,30 @@ *ihp |= (dev << 2) & INTMAP_PCISLOT; *ihp |= sc->sc_ign; + DPRINTF(PDB_INTR, ("%s: weird hack -> ih %lx", __func__, (u_long)*ihp)); return (0); } bus_space_tag_t pyro_alloc_mem_tag(struct pyro_pbm *pp) { - return (_pyro_alloc_bus_tag(pp, "mem", - 0x02, /* 32-bit mem space (where's the #define???) */ - ASI_PRIMARY, ASI_PRIMARY_LITTLE)); + return (pyro_alloc_bus_tag(pp, "mem", PCI_MEMORY_BUS_SPACE)); } bus_space_tag_t pyro_alloc_io_tag(struct pyro_pbm *pp) { - return (_pyro_alloc_bus_tag(pp, "io", - 0x01, /* IO space (where's the #define???) */ - ASI_PHYS_NON_CACHED_LITTLE, ASI_PHYS_NON_CACHED)); + return (pyro_alloc_bus_tag(pp, "io", PCI_IO_BUS_SPACE)); } bus_space_tag_t pyro_alloc_config_tag(struct pyro_pbm *pp) { - return (_pyro_alloc_bus_tag(pp, "cfg", - 0x00, /* Config space (where's the #define???) */ - ASI_PHYS_NON_CACHED_LITTLE, ASI_PHYS_NON_CACHED)); + return (pyro_alloc_bus_tag(pp, "cfg", PCI_CONFIG_BUS_SPACE)); } bus_space_tag_t -_pyro_alloc_bus_tag(struct pyro_pbm *pbm, const char *name, int ss, - int asi, int sasi) +pyro_alloc_bus_tag(struct pyro_pbm *pbm, const char *name, int type) { struct pyro_softc *sc = pbm->pp_sc; struct sparc_bus_space_tag *bt; @@ -366,17 +405,17 @@ if (bt == NULL) panic("pyro: could not allocate bus tag"); +#if 0 snprintf(bt->name, sizeof(bt->name), "%s-pbm_%s(%d/%2.2x)", sc->sc_dv.dv_xname, name, ss, asi); +#endif bt->cookie = pbm; - bt->parent = sc->sc_bust; - bt->default_type = ss; - bt->asi = asi; - bt->sasi = sasi; - bt->sparc_bus_map = _pyro_bus_map; - bt->sparc_bus_mmap = _pyro_bus_mmap; - bt->sparc_intr_establish = _pyro_intr_establish; + bt->parent = sc->sc_bustag; + bt->type = type; + bt->sparc_bus_map = pyro_bus_map; + bt->sparc_bus_mmap = pyro_bus_mmap; + bt->sparc_intr_establish = pyro_intr_establish; return (bt); } @@ -392,14 +431,21 @@ dt->_cookie = pbm; dt->_parent = pdt; +#define PCOPY(x) dt->x = pdt->x dt->_dmamap_create = pyro_dmamap_create; - dt->_dmamap_destroy = iommu_dvmamap_destroy; + PCOPY(_dmamap_destroy); dt->_dmamap_load = iommu_dvmamap_load; + PCOPY(_dmamap_load_mbuf); + PCOPY(_dmamap_load_uio); dt->_dmamap_load_raw = iommu_dvmamap_load_raw; dt->_dmamap_unload = iommu_dvmamap_unload; dt->_dmamap_sync = iommu_dvmamap_sync; dt->_dmamem_alloc = iommu_dvmamem_alloc; dt->_dmamem_free = iommu_dvmamem_free; + dt->_dmamem_map = iommu_dvmamem_map; + dt->_dmamem_unmap = iommu_dvmamem_unmap; + PCOPY(_dmamem_mmap); +#undef PCOPY return (dt); } @@ -414,34 +460,44 @@ memcpy(npc, pc, sizeof *pc); npc->cookie = pbm; npc->rootnode = node; + npc->spc_conf_read = pyro_conf_read; + npc->spc_conf_write = pyro_conf_write; + npc->spc_intr_map = pyro_intr_map; + npc->spc_intr_establish = pyro_pci_intr_establish; + npc->spc_find_ino = NULL; return (npc); } int -pyro_dmamap_create(bus_dma_tag_t t, bus_dma_tag_t t0, bus_size_t size, +pyro_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp) { - struct pyro_pbm *pp = t->_cookie; + struct pyro_pbm *pbm = t->_cookie; + int error; - return (iommu_dvmamap_create(t, t0, &pp->pp_sb, size, nsegments, - maxsegsz, boundary, flags, dmamp)); + error = bus_dmamap_create(t->_parent, size, nsegments, maxsegsz, + boundary, flags, dmamp); + if (error == 0) + (*dmamp)->_dm_cookie = &pbm->pp_sb; + return error; } int -_pyro_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset, - bus_size_t size, int flags, bus_space_handle_t *hp) +pyro_bus_map(bus_space_tag_t t, bus_addr_t offset, + bus_size_t size, int flags, vaddr_t unused, bus_space_handle_t *hp) { struct pyro_pbm *pbm = t->cookie; + struct pyro_softc *sc = pbm->pp_sc; int i, ss; - DPRINTF(PDB_BUSMAP, ("_pyro_bus_map: type %d off %qx sz %qx flags %d", - t->default_type, + DPRINTF(PDB_BUSMAP, ("pyro_bus_map: type %d off %qx sz %qx flags %d", + t->type, (unsigned long long)offset, (unsigned long long)size, flags)); - ss = t->default_type; + ss = sparc_pci_childspace(t->type); DPRINTF(PDB_BUSMAP, (" cspace %d", ss)); if (t->parent == 0 || t->parent->sparc_bus_map == 0) { @@ -449,37 +505,33 @@ return (EINVAL); } - if (flags & BUS_SPACE_MAP_PROMADDRESS) { - return ((*t->parent->sparc_bus_map) - (t, t0, offset, size, flags, hp)); - } - for (i = 0; i < pbm->pp_nrange; i++) { bus_addr_t paddr; + struct pyro_range *pr = &pbm->pp_range[i]; - if (((pbm->pp_range[i].cspace >> 24) & 0x03) != ss) + if (((pr->cspace >> 24) & 0x03) != ss) continue; - paddr = pbm->pp_range[i].phys_lo + offset; - paddr |= ((bus_addr_t)pbm->pp_range[i].phys_hi) << 32; - return ((*t->parent->sparc_bus_map) - (t, t0, paddr, size, flags, hp)); + paddr = BUS_ADDR(pr->phys_hi, pr->phys_lo + offset); + return ((*sc->sc_bustag->sparc_bus_map)(t, paddr, size, + flags, 0, hp)); } return (EINVAL); } paddr_t -_pyro_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, +pyro_bus_mmap(bus_space_tag_t t, bus_addr_t paddr, off_t off, int prot, int flags) { bus_addr_t offset = paddr; struct pyro_pbm *pbm = t->cookie; + struct pyro_softc *sc = pbm->pp_sc; int i, ss; - ss = t->default_type; + ss = sparc_pci_childspace(t->type); - DPRINTF(PDB_BUSMAP, ("_pyro_bus_mmap: prot %d flags %d pa %qx\n", + DPRINTF(PDB_BUSMAP, ("pyro_bus_mmap: prot %d flags %d pa %qx\n", prot, flags, (unsigned long long)paddr)); if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { @@ -488,31 +540,32 @@ } for (i = 0; i < pbm->pp_nrange; i++) { - bus_addr_t paddr; + struct pyro_range *pr = &pbm->pp_range[i]; - if (((pbm->pp_range[i].cspace >> 24) & 0x03) != ss) + if (((pr->cspace >> 24) & 0x03) != ss) continue; - paddr = pbm->pp_range[i].phys_lo + offset; - paddr |= ((bus_addr_t)pbm->pp_range[i].phys_hi<<32); - return ((*t->parent->sparc_bus_mmap) - (t, t0, paddr, off, prot, flags)); + paddr = BUS_ADDR(pr->phys_hi, pr->phys_lo + offset); + return (bus_space_mmap(sc->sc_bustag, paddr, off, + prot, flags)); } return (-1); } void * -_pyro_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, - int level, int flags, int (*handler)(void *), void *arg, const char *what) +pyro_intr_establish(bus_space_tag_t t, int ihandle, int level, + int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */) { struct pyro_pbm *pbm = t->cookie; struct pyro_softc *sc = pbm->pp_sc; struct intrhand *ih = NULL; volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL; + u_int64_t *imap, *iclr; int ino; ino = INTINO(ihandle); + DPRINTF(PDB_INTR, ("%s: ih %lx; level %d ino %d", __func__, (u_long)ih, level, ino)); if (level == IPL_NONE) level = INTLEV(ihandle); @@ -521,61 +574,80 @@ level = 2; } - if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) { - u_int64_t *imap, *iclr; - - imap = bus_space_vaddr(sc->sc_bust, sc->sc_csrh) + 0x1000; - iclr = bus_space_vaddr(sc->sc_bust, sc->sc_csrh) + 0x1400; - intrmapptr = &imap[ino]; - intrclrptr = &iclr[ino]; - ino |= INTVEC(ihandle); - } + imap = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1000); + iclr = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1400); + intrmapptr = &imap[ino]; + intrclrptr = &iclr[ino]; + DPRINTF(PDB_INTR, (" imap %p iclr %p mapptr %p clrptr %p", imap, iclr, intrmapptr, intrclrptr)); + ino |= INTVEC(ihandle); - ih = bus_intr_allocate(t0, handler, arg, ino, level, intrmapptr, - intrclrptr, what); + ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT); if (ih == NULL) return (NULL); - intr_establish(ih->ih_pil, ih); + /* Register the map and clear intr registers */ + ih->ih_map = intrmapptr; + ih->ih_clr = intrclrptr; + + ih->ih_fun = handler; + ih->ih_arg = arg; + ih->ih_pil = level; + ih->ih_number = ino; + + intr_establish(ih->ih_pil, level != IPL_VM, ih); if (intrmapptr != NULL) { - u_int64_t intrmap; + u_int64_t ival; - intrmap = *intrmapptr; - intrmap &= ~FIRE_INTRMAP_INT_CNTRL_NUM_MASK; - intrmap |= FIRE_INTRMAP_INT_CNTRL_NUM0; + ival = *intrmapptr; + ival &= ~FIRE_INTRMAP_INT_CNTRL_NUM_MASK; + ival |= FIRE_INTRMAP_INT_CNTRL_NUM0; if (sc->sc_oberon) { - intrmap &= ~OBERON_INTRMAP_T_DESTID_MASK; - intrmap |= CPU_JUPITERID << + ival &= ~OBERON_INTRMAP_T_DESTID_MASK; + ival |= CPU_JUPITERID << OBERON_INTRMAP_T_DESTID_SHIFT; } else { - intrmap &= ~FIRE_INTRMAP_T_JPID_MASK; - intrmap |= CPU_UPAID << FIRE_INTRMAP_T_JPID_SHIFT; + ival &= ~FIRE_INTRMAP_T_JPID_MASK; + ival |= CPU_UPAID << FIRE_INTRMAP_T_JPID_SHIFT; } - intrmap |= INTMAP_V; - *intrmapptr = intrmap; - intrmap = *intrmapptr; - ih->ih_number |= intrmap & INTMAP_INR; - } + ival |= INTMAP_V; + *intrmapptr = ival; + ival = *intrmapptr; + ih->ih_number |= ival & INTMAP_INR; + } +#if 0 /* XXXMRG? do this? our schizo does. */ + if (intrclrptr) { + /* set state to IDLE */ + *intrclrptr = 0; + } +#endif return (ih); } +static void * +pyro_pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, + int (*func)(void *), void *arg) +{ + void *cookie; + struct pyro_pbm *pbm = (struct pyro_pbm *)pc->cookie; + + DPRINTF(PDB_INTR, ("%s: ih %lx; level %d", __func__, (u_long)ih, level)); + cookie = bus_intr_establish(pbm->pp_memt, ih, level, func, arg); + + DPRINTF(PDB_INTR, ("; returning handle %p\n", cookie)); + return (cookie); +} + +#if 0 #ifdef DDB void pyro_xir(void *arg, int cpu) { struct pyro_softc *sc = arg; - bus_space_write_8(sc->sc_bust, sc->sc_xbch, FIRE_RESET_GEN, + bus_space_write_8(sc->sc_bustag, sc->sc_xbch, FIRE_RESET_GEN, FIRE_RESET_GEN_XIR); } #endif - -const struct cfattach pyro_ca = { - sizeof(struct pyro_softc), pyro_match, pyro_attach -}; - -struct cfdriver pyro_cd = { - NULL, "pyro", DV_DULL -}; +#endif Index: src/sys/arch/sparc64/dev/pyrovar.h diff -u src/sys/arch/sparc64/dev/pyrovar.h:1.1.1.1 src/sys/arch/sparc64/dev/pyrovar.h:1.2 --- src/sys/arch/sparc64/dev/pyrovar.h:1.1.1.1 Tue Mar 15 11:21:04 2011 +++ src/sys/arch/sparc64/dev/pyrovar.h Tue Mar 15 11:42:03 2011 @@ -48,6 +48,7 @@ bus_space_tag_t pp_cfgt; bus_space_handle_t pp_cfgh; bus_dma_tag_t pp_dmat; + int pp_flags; int pp_bus_a; struct iommu_state pp_is; struct strbuf_ctl pp_sb; @@ -58,7 +59,7 @@ int sc_node; int sc_ign; bus_dma_tag_t sc_dmat; - bus_space_tag_t sc_bust; + bus_space_tag_t sc_bustag; bus_addr_t sc_csr, sc_xbc; bus_space_handle_t sc_csrh, sc_xbch;