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 ([email protected])
* 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;