summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2017-10-29 08:50:44 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2017-10-29 08:50:44 +0000
commit2afd375ec19edb8a2115dc4bab2cfb3b3faee2cf (patch)
treeacddbc919829a021903eb1765f6048e0b680a07e
parent0ad115de732d7412195a161be8120691c14d5068 (diff)
Finish TURBOchannel scatter/gather map code (i.e. make it work) and
enable it when available (i.e. all DEC 3000 models but models 300). Tested on DEC 3000/600 (sgmap) and DEC 3000/300LX (no sgmap). from miod@
-rw-r--r--sys/arch/alpha/tc/tc_3000_500.c21
-rw-r--r--sys/arch/alpha/tc/tc_conf.h7
-rw-r--r--sys/arch/alpha/tc/tc_dma_3000_500.c140
-rw-r--r--sys/arch/alpha/tc/tc_dma_3000_500.h5
-rw-r--r--sys/arch/alpha/tc/tcasic.c21
5 files changed, 91 insertions, 103 deletions
diff --git a/sys/arch/alpha/tc/tc_3000_500.c b/sys/arch/alpha/tc/tc_3000_500.c
index 427f73f8147..171572a0f75 100644
--- a/sys/arch/alpha/tc/tc_3000_500.c
+++ b/sys/arch/alpha/tc/tc_3000_500.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tc_3000_500.c,v 1.19 2015/05/19 20:28:14 miod Exp $ */
+/* $OpenBSD: tc_3000_500.c,v 1.20 2017/10/29 08:50:43 mpi Exp $ */
/* $NetBSD: tc_3000_500.c,v 1.24 2001/07/27 00:25:21 thorpej Exp $ */
/*
@@ -311,7 +311,6 @@ tc_3000_500_fb_cnattach(turbo_slot)
}
#endif /* NWSDISPLAY */
-#if 0
/*
* tc_3000_500_ioslot --
* Set the PBS bits for devices on the TC.
@@ -337,4 +336,20 @@ tc_3000_500_ioslot(slot, flags, set)
tc_mb();
splx(s);
}
-#endif
+
+int
+tc_3000_500_activate(struct device *self, int act)
+{
+ int rc = config_activate_children(self, act);
+ int slot;
+
+ /*
+ * Reset all slots to non-sgmap when halting.
+ */
+ if (act == DVACT_POWERDOWN) {
+ for (slot = 0; slot < tc_3000_500_nslots; slot++)
+ tc_3000_500_ioslot(slot, IOSLOT_S, 0);
+ }
+
+ return rc;
+}
diff --git a/sys/arch/alpha/tc/tc_conf.h b/sys/arch/alpha/tc/tc_conf.h
index 4abefe530cb..0978b1c33ed 100644
--- a/sys/arch/alpha/tc/tc_conf.h
+++ b/sys/arch/alpha/tc/tc_conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tc_conf.h,v 1.11 2010/09/22 12:36:32 miod Exp $ */
+/* $OpenBSD: tc_conf.h,v 1.12 2017/10/29 08:50:43 mpi Exp $ */
/* $NetBSD: tc_conf.h,v 1.10 2000/06/04 19:14:29 cgd Exp $ */
/*
@@ -49,6 +49,10 @@ extern int tc_3000_500_graphics_nbuiltins;
extern struct tc_builtin tc_3000_500_graphics_builtins[];
extern int tc_3000_500_nographics_nbuiltins;
extern struct tc_builtin tc_3000_500_nographics_builtins[];
+
+extern void tc_3000_500_ioslot(u_int32_t, u_int32_t, int);
+
+extern int tc_3000_500_activate(struct device *, int);
#endif /* DEC_3000_500 */
#ifdef DEC_3000_300
@@ -69,4 +73,3 @@ extern struct tc_builtin tc_3000_300_builtins[];
#endif /* DEC_3000_300 */
extern int tc_fb_cnattach(tc_addr_t);
-
diff --git a/sys/arch/alpha/tc/tc_dma_3000_500.c b/sys/arch/alpha/tc/tc_dma_3000_500.c
index c21e0f54452..2f1818eaf92 100644
--- a/sys/arch/alpha/tc/tc_dma_3000_500.c
+++ b/sys/arch/alpha/tc/tc_dma_3000_500.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tc_dma_3000_500.c,v 1.6 2014/12/13 21:05:32 doug Exp $ */
+/* $OpenBSD: tc_dma_3000_500.c,v 1.7 2017/10/29 08:50:43 mpi Exp $ */
/* $NetBSD: tc_dma_3000_500.c,v 1.13 2001/07/19 06:40:03 thorpej Exp $ */
/*-
@@ -41,22 +41,29 @@
#include <uvm/uvm_extern.h>
+#include <machine/alpha_cpu.h>
#include <machine/bus.h>
#include <dev/tc/tcvar.h>
+#include <alpha/tc/tc_conf.h>
+#include <alpha/tc/tc_3000_500.h>
#include <alpha/tc/tc_sgmap.h>
#include <alpha/tc/tc_dma_3000_500.h>
+#define KV(x) (ALPHA_PHYS_TO_K0SEG(x))
+
+struct alpha_sgmap tc_dma_sgmap; /* sgmap shared by all slots */
+
struct alpha_bus_dma_tag tc_dmat_sgmap = {
- NULL, /* _cookie */
+ NULL, /* _cookie, not used */
0, /* _wbase */
- 0, /* _wsize */
+ 0x1000000, /* _wsize (256MB: 32K entries) */
NULL, /* _next_window */
0, /* _boundary */
- NULL, /* _sgmap */
- NULL, /* _get_tag */
- tc_bus_dmamap_create_sgmap,
- tc_bus_dmamap_destroy_sgmap,
+ &tc_dma_sgmap, /* _sgmap */
+ NULL, /* _get_tag, not used */
+ alpha_sgmap_dmamap_create,
+ alpha_sgmap_dmamap_destroy,
tc_bus_dmamap_load_sgmap,
tc_bus_dmamap_load_mbuf_sgmap,
tc_bus_dmamap_load_uio_sgmap,
@@ -70,29 +77,34 @@ struct alpha_bus_dma_tag tc_dmat_sgmap = {
_bus_dmamem_mmap,
};
-struct tc_dma_slot_info {
- struct alpha_sgmap tdsi_sgmap; /* sgmap for slot */
- struct alpha_bus_dma_tag tdsi_dmat; /* dma tag for slot */
-};
-struct tc_dma_slot_info *tc_dma_slot_info;
-
void
tc_dma_init_3000_500(nslots)
int nslots;
{
- extern struct alpha_bus_dma_tag tc_dmat_direct;
int i;
-
- /* Allocate per-slot DMA info. */
- tc_dma_slot_info = mallocarray(nslots, sizeof(struct tc_dma_slot_info),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- if (tc_dma_slot_info == NULL)
- panic("tc_dma_init: can't allocate per-slot DMA info");
-
- /* Default all slots to direct-mapped. */
- for (i = 0; i < nslots; i++)
- memcpy(&tc_dma_slot_info[i].tdsi_dmat, &tc_dmat_direct,
- sizeof(tc_dma_slot_info[i].tdsi_dmat));
+ struct alpha_bus_dma_tag *t;
+
+ for (i = 0; i < nslots; i++) {
+ /*
+ * Note that the use of sgmap on a slot is global, so we
+ * can not afford reverting to direct dma (by making
+ * _next_window point to the direct tag).
+ * On the other hand, the sgmap allows for 256MB of
+ * DMA transfers being programmed at the same time for all
+ * the slots, which should not be a liability.
+ */
+ tc_3000_500_ioslot(i, IOSLOT_S, !0);
+ }
+ /*
+ * The TURBOchannel sgmap is shared by all slots.
+ * We need a valid bus_dma_tag_t to pass alpha_sgmap_init() in order
+ * to allocate the sgmap fill page, so pick the first.
+ */
+ t = &tc_dmat_sgmap;
+ alpha_sgmap_init(t, t->_sgmap, "tc_sgmap",
+ t->_wbase, 0, t->_wsize,
+ SGMAP_PTE_SPACING * sizeof(SGMAP_PTE_TYPE),
+ (void *)TC_3000_500_SCMAP, 0);
}
/*
@@ -102,55 +114,11 @@ bus_dma_tag_t
tc_dma_get_tag_3000_500(slot)
int slot;
{
-
- return (&tc_dma_slot_info[slot].tdsi_dmat);
-}
-
-/*
- * Create a TurboChannel SGMAP-mapped DMA map.
- */
-int
-tc_bus_dmamap_create_sgmap(t, size, nsegments, maxsegsz, boundary,
- flags, dmamp)
- 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;
-{
- bus_dmamap_t map;
- int error;
-
- error = _bus_dmamap_create(t, size, nsegments, maxsegsz,
- boundary, flags, dmamp);
- if (error)
- return (error);
-
- map = *dmamp;
-
- /* XXX BUS_DMA_ALLOCNOW */
-
- return (error);
-}
-
-/*
- * Destroy a TurboChannel SGMAP-mapped DMA map.
- */
-void
-tc_bus_dmamap_destroy_sgmap(t, map)
- bus_dma_tag_t t;
- bus_dmamap_t map;
-{
-
- KASSERT(map->dm_mapsize == 0);
-
- _bus_dmamap_destroy(t, map);
+ return &tc_dmat_sgmap;
}
/*
- * Load a TurboChannel SGMAP-mapped DMA map with a linear buffer.
+ * Load a TURBOchannel SGMAP-mapped DMA map with a linear buffer.
*/
int
tc_bus_dmamap_load_sgmap(t, map, buf, buflen, p, flags)
@@ -161,14 +129,11 @@ tc_bus_dmamap_load_sgmap(t, map, buf, buflen, p, flags)
struct proc *p;
int flags;
{
- struct tc_dma_slot_info *tdsi = t->_cookie;
-
- return (tc_sgmap_load(t, map, buf, buflen, p, flags,
- &tdsi->tdsi_sgmap));
+ return (tc_sgmap_load(t, map, buf, buflen, p, flags, t->_sgmap));
}
/*
- * Load a TurboChannel SGMAP-mapped DMA map with an mbuf chain.
+ * Load a TURBOchannel SGMAP-mapped DMA map with an mbuf chain.
*/
int
tc_bus_dmamap_load_mbuf_sgmap(t, map, m, flags)
@@ -177,13 +142,11 @@ tc_bus_dmamap_load_mbuf_sgmap(t, map, m, flags)
struct mbuf *m;
int flags;
{
- struct tc_dma_slot_info *tdsi = t->_cookie;
-
- return (tc_sgmap_load_mbuf(t, map, m, flags, &tdsi->tdsi_sgmap));
+ return (tc_sgmap_load_mbuf(t, map, m, flags, t->_sgmap));
}
/*
- * Load a TurboChannel SGMAP-mapped DMA map with a uio.
+ * Load a TURBOchannel SGMAP-mapped DMA map with a uio.
*/
int
tc_bus_dmamap_load_uio_sgmap(t, map, uio, flags)
@@ -192,13 +155,11 @@ tc_bus_dmamap_load_uio_sgmap(t, map, uio, flags)
struct uio *uio;
int flags;
{
- struct tc_dma_slot_info *tdsi = t->_cookie;
-
- return (tc_sgmap_load_uio(t, map, uio, flags, &tdsi->tdsi_sgmap));
+ return (tc_sgmap_load_uio(t, map, uio, flags, t->_sgmap));
}
/*
- * Load a TurboChannel SGMAP-mapped DMA map with raw memory.
+ * Load a TURBOchannel SGMAP-mapped DMA map with raw memory.
*/
int
tc_bus_dmamap_load_raw_sgmap(t, map, segs, nsegs, size, flags)
@@ -209,27 +170,22 @@ tc_bus_dmamap_load_raw_sgmap(t, map, segs, nsegs, size, flags)
bus_size_t size;
int flags;
{
- struct tc_dma_slot_info *tdsi = t->_cookie;
-
- return (tc_sgmap_load_raw(t, map, segs, nsegs, size, flags,
- &tdsi->tdsi_sgmap));
+ return (tc_sgmap_load_raw(t, map, segs, nsegs, size, flags, t->_sgmap));
}
/*
- * Unload a TurboChannel SGMAP-mapped DMA map.
+ * Unload a TURBOchannel SGMAP-mapped DMA map.
*/
void
tc_bus_dmamap_unload_sgmap(t, map)
bus_dma_tag_t t;
bus_dmamap_t map;
{
- struct tc_dma_slot_info *tdsi = t->_cookie;
-
/*
* Invalidate any SGMAP page table entries used by this
* mapping.
*/
- tc_sgmap_unload(t, map, &tdsi->tdsi_sgmap);
+ tc_sgmap_unload(t, map, t->_sgmap);
/*
* Do the generic bits of the unload.
diff --git a/sys/arch/alpha/tc/tc_dma_3000_500.h b/sys/arch/alpha/tc/tc_dma_3000_500.h
index be7ac4cb96b..b919c762dfd 100644
--- a/sys/arch/alpha/tc/tc_dma_3000_500.h
+++ b/sys/arch/alpha/tc/tc_dma_3000_500.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tc_dma_3000_500.h,v 1.2 2008/06/26 05:42:09 ray Exp $ */
+/* $OpenBSD: tc_dma_3000_500.h,v 1.3 2017/10/29 08:50:43 mpi Exp $ */
/* $NetBSD: tc_dma_3000_500.h,v 1.2 1997/06/07 00:02:19 thorpej Exp $ */
/*-
@@ -34,9 +34,6 @@
void tc_dma_init_3000_500(int);
bus_dma_tag_t tc_dma_get_tag_3000_500(int);
-int tc_bus_dmamap_create_sgmap(bus_dma_tag_t, bus_size_t, int,
- bus_size_t, bus_size_t, int, bus_dmamap_t *);
-void tc_bus_dmamap_destroy_sgmap(bus_dma_tag_t, bus_dmamap_t);
int tc_bus_dmamap_load_sgmap(bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, struct proc *, int);
int tc_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t, bus_dmamap_t,
diff --git a/sys/arch/alpha/tc/tcasic.c b/sys/arch/alpha/tc/tcasic.c
index b1641130f6e..d3244f20a2a 100644
--- a/sys/arch/alpha/tc/tcasic.c
+++ b/sys/arch/alpha/tc/tcasic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcasic.c,v 1.16 2010/11/11 17:54:52 miod Exp $ */
+/* $OpenBSD: tcasic.c,v 1.17 2017/10/29 08:50:43 mpi Exp $ */
/* $NetBSD: tcasic.c,v 1.36 2001/08/23 01:16:52 nisimura Exp $ */
/*
@@ -42,9 +42,13 @@
/* Definition of the driver for autoconfig. */
int tcasicmatch(struct device *, void *, void *);
void tcasicattach(struct device *, struct device *, void *);
+int tcasicactivate(struct device *, int);
struct cfattach tcasic_ca = {
- sizeof (struct device), tcasicmatch, tcasicattach,
+ .ca_devsize = sizeof (struct device),
+ .ca_match = tcasicmatch,
+ .ca_attach = tcasicattach,
+ .ca_activate = tcasicactivate
};
struct cfdriver tcasic_cd = {
@@ -151,6 +155,19 @@ tcasicattach(parent, self, aux)
}
int
+tcasicactivate(struct device *self, int act)
+{
+ switch (cputype) {
+#ifdef DEC_3000_500
+ case ST_DEC_3000_500:
+ return tc_3000_500_activate(self, act);
+#endif
+ default:
+ return config_activate_children(self, act);
+ }
+}
+
+int
tcasicprint(aux, pnp)
void *aux;
const char *pnp;