1 /* $NetBSD: vme.c,v 1.14 2008/04/28 20:23:38 martin Exp $ */
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: vme.c,v 1.14 2008/04/28 20:23:38 martin Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
39 #include <uvm/uvm_extern.h>
41 #define _SUN68K_BUS_DMA_PRIVATE
42 #include <machine/autoconf.h>
43 #include <machine/bus.h>
44 #include <machine/dvma.h>
45 #include <machine/pmap.h>
47 #include <sun3/sun3x/vme.h>
49 /* Does this machine have a VME bus? */
50 extern int cpu_has_vme
;
53 * Convert vme unit number to bus type,
54 * but only for supported bus types.
55 * (See autoconf.h and vme.h)
64 } vme_info
[VME_UNITS
] = {
65 { BUS_VME16D16
, "A16/D16", PMAP_VME16
, VME16_BASE
, VME16_MASK
},
66 { BUS_VME16D32
, "A16/D32", PMAP_VME32
, VME16_BASE
, VME16_MASK
},
67 { BUS_VME24D16
, "A24/D16", PMAP_VME16
, VME24_BASE
, VME24_MASK
},
68 { BUS_VME24D32
, "A24/D32", PMAP_VME32
, VME24_BASE
, VME24_MASK
},
69 { BUS_VME32D16
, "A32/D16", PMAP_VME16
, VME32_BASE
, VME32_MASK
},
70 { BUS_VME32D32
, "A32/D32", PMAP_VME32
, VME32_BASE
, VME32_MASK
},
73 static int vme_match(struct device
*, struct cfdata
*, void *);
74 static void vme_attach(struct device
*, struct device
*, void *);
78 bus_space_tag_t sc_bustag
;
79 bus_dma_tag_t sc_dmatag
;
83 CFATTACH_DECL_NEW(vme
, sizeof(struct vme_softc
),
84 vme_match
, vme_attach
, NULL
, NULL
);
86 static int vme_bus_map(bus_space_tag_t
, bus_type_t
, bus_addr_t
, bus_size_t
,
87 int, vaddr_t
, bus_space_handle_t
*);
88 static paddr_t
vme_bus_mmap(bus_space_tag_t
, bus_type_t
, bus_addr_t
,
90 static int vme_dmamap_load(bus_dma_tag_t
, bus_dmamap_t
, void *, bus_size_t
,
93 static struct sun68k_bus_space_tag vme_space_tag
= {
95 NULL
, /* parent bus space tag */
96 vme_bus_map
, /* bus_space_map */
97 NULL
, /* bus_space_unmap */
98 NULL
, /* bus_space_subregion */
99 NULL
, /* bus_space_barrier */
100 vme_bus_mmap
, /* bus_space_mmap */
101 NULL
, /* bus_intr_establish */
102 NULL
, /* bus_space_peek_N */
103 NULL
/* bus_space_poke_N */
106 static struct sun68k_bus_dma_tag vme_dma_tag
;
109 vme_match(device_t parent
, cfdata_t cf
, void *aux
)
111 struct confargs
*ca
= aux
;
114 if (cpu_has_vme
== 0)
118 if (unit
>= VME_UNITS
)
121 if (ca
->ca_bustype
!= vme_info
[unit
].bustype
)
128 vme_attach(device_t parent
, device_t self
, void *args
)
130 struct confargs
*ca
= aux
;
131 struct vme_softc
*sc
= device_private(self
);
132 struct confargs vmea
;
137 unit
= device_unit(self
);
138 aprint_normal(": (%s)\n", vme_info
[unit
].name
);
140 sc
->sc_bustag
= ca
->ca_bustag
;
141 sc
->sc_dmatag
= ca
->ca_dmatag
;
142 sc
->sc_bustype
= unit
;
144 vme_space_tag
.cookie
= sc
;
145 vme_space_tag
.parent
= sc
->sc_bustag
;
147 vme_dma_tag
= *sc
->sc_dmatag
;
148 vme_dma_tag
._cookie
= sc
;
149 vme_dma_tag
._dmamap_load
= vme_dmamap_load
;
152 vmea
.ca_bustag
= &vme_space_tag
;
153 vmea
.ca_dmatag
= &vme_dma_tag
;
155 /* We know ca_bustype == BUS_VMExx */
156 config_search_ia(bus_scan
, self
, "vme", args
);
160 vme_bus_map(bus_space_tag_t t
, bus_type_t btype
, bus_addr_t paddr
,
161 bus_size_t size
, int flags
, vaddr_t vaddr
, bus_space_handle_t
*hp
)
163 struct vme_softc
*sc
= t
->cookie
;
167 bustype
= sc
->sc_bustype
;
169 pa
&= vme_info
[bustype
].mask
;
170 pa
|= vme_info
[bustype
].base
;
171 pmtype
= vme_info
[bustype
].pmtype
;
173 return bus_space_map2(sc
->sc_bustag
, pmtype
, pa
, size
,
174 flags
| _SUN68K_BUS_MAP_USE_PROM
, vaddr
, hp
);
178 vme_bus_mmap(bus_space_tag_t t
, bus_type_t btype
, bus_addr_t paddr
, off_t off
,
181 struct vme_softc
*sc
= t
->cookie
;
185 bustype
= sc
->sc_bustype
;
187 pa
&= vme_info
[bustype
].mask
;
188 pa
|= vme_info
[bustype
].base
;
189 pmtype
= vme_info
[bustype
].pmtype
;
191 return bus_space_mmap2(sc
->sc_bustag
, pmtype
, pa
, off
, prot
, flags
);
195 vme_dmamap_load(bus_dma_tag_t t
, bus_dmamap_t map
, void *buf
,
196 bus_size_t buflen
, struct proc
*p
, int flags
)
200 error
= _bus_dmamap_load(t
, map
, buf
, buflen
, p
, flags
);
202 map
->dm_segs
[0].ds_addr
&= DVMA_VME_SLAVE_MASK
;