| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tsp_dma.c,v 1.18 2021/07/04 22:42:36 thorpej Exp $ */ | | 1 | /* $NetBSD: tsp_dma.c,v 1.19 2021/07/18 00:01:20 thorpej Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1997, 1998, 2021 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1997, 1998, 2021 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | | 8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, |
9 | * NASA Ames Research Center. | | 9 | * NASA Ames Research Center. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -51,47 +51,47 @@ | | | @@ -51,47 +51,47 @@ |
51 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | | 51 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
52 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP0SE | | 52 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP0SE |
53 | * ARE DISCLAIMED. IN NO EVENT SHALL ROSS HARVEY BE LIABLE FOR ANY | | 53 | * ARE DISCLAIMED. IN NO EVENT SHALL ROSS HARVEY BE LIABLE FOR ANY |
54 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 54 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
57 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 57 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
58 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 58 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
59 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 59 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
60 | * SUCH DAMAGE. | | 60 | * SUCH DAMAGE. |
61 | */ | | 61 | */ |
62 | | | 62 | |
63 | #include <sys/cdefs.h> | | 63 | #include <sys/cdefs.h> |
64 | __KERNEL_RCSID(0, "$NetBSD: tsp_dma.c,v 1.18 2021/07/04 22:42:36 thorpej Exp $"); | | 64 | __KERNEL_RCSID(0, "$NetBSD: tsp_dma.c,v 1.19 2021/07/18 00:01:20 thorpej Exp $"); |
65 | | | 65 | |
66 | #include <sys/param.h> | | 66 | #include <sys/param.h> |
67 | #include <sys/systm.h> | | 67 | #include <sys/systm.h> |
68 | #include <sys/kernel.h> | | 68 | #include <sys/kernel.h> |
69 | #include <sys/device.h> | | 69 | #include <sys/device.h> |
70 | | | 70 | |
| | | 71 | #include <uvm/uvm_extern.h> |
| | | 72 | |
71 | #include <machine/autoconf.h> | | 73 | #include <machine/autoconf.h> |
72 | #define _ALPHA_BUS_DMA_PRIVATE | | 74 | #define _ALPHA_BUS_DMA_PRIVATE |
73 | #include <sys/bus.h> | | 75 | #include <sys/bus.h> |
74 | #include <machine/rpb.h> | | 76 | #include <machine/rpb.h> |
75 | | | 77 | |
76 | #include <dev/pci/pcireg.h> | | 78 | #include <dev/pci/pcireg.h> |
77 | #include <dev/pci/pcivar.h> | | 79 | #include <dev/pci/pcivar.h> |
78 | #include <alpha/pci/tsreg.h> | | 80 | #include <alpha/pci/tsreg.h> |
79 | #include <alpha/pci/tsvar.h> | | 81 | #include <alpha/pci/tsvar.h> |
80 | | | 82 | |
81 | #define tsp_dma() { Generate ctags(1) key. } | | 83 | #define tsp_dma() { Generate ctags(1) key. } |
82 | | | 84 | |
83 | #define EDIFF(a, b) (((a) | WSBA_ENA | WSBA_SG) != ((b) | WSBA_ENA | WSBA_SG)) | | | |
84 | | | | |
85 | static bus_dma_tag_t tsp_dma_get_tag(bus_dma_tag_t, alpha_bus_t); | | 85 | static bus_dma_tag_t tsp_dma_get_tag(bus_dma_tag_t, alpha_bus_t); |
86 | | | 86 | |
87 | static int tsp_bus_dmamap_load_sgmap(bus_dma_tag_t, bus_dmamap_t, void *, | | 87 | static int tsp_bus_dmamap_load_sgmap(bus_dma_tag_t, bus_dmamap_t, void *, |
88 | bus_size_t, struct proc *, int); | | 88 | bus_size_t, struct proc *, int); |
89 | | | 89 | |
90 | static int tsp_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t, bus_dmamap_t, | | 90 | static int tsp_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t, bus_dmamap_t, |
91 | struct mbuf *, int); | | 91 | struct mbuf *, int); |
92 | | | 92 | |
93 | static int tsp_bus_dmamap_load_uio_sgmap(bus_dma_tag_t, bus_dmamap_t, | | 93 | static int tsp_bus_dmamap_load_uio_sgmap(bus_dma_tag_t, bus_dmamap_t, |
94 | struct uio *, int); | | 94 | struct uio *, int); |
95 | | | 95 | |
96 | static int tsp_bus_dmamap_load_raw_sgmap(bus_dma_tag_t, bus_dmamap_t, | | 96 | static int tsp_bus_dmamap_load_raw_sgmap(bus_dma_tag_t, bus_dmamap_t, |
97 | bus_dma_segment_t *, int, bus_size_t, int); | | 97 | bus_dma_segment_t *, int, bus_size_t, int); |
| @@ -116,179 +116,249 @@ static void tsp_tlb_invalidate(struct ts | | | @@ -116,179 +116,249 @@ static void tsp_tlb_invalidate(struct ts |
116 | * bits <63:40> are compared to the constant value 0x0000_01 (that is, bit | | 116 | * bits <63:40> are compared to the constant value 0x0000_01 (that is, bit |
117 | * <40> = 1; all other bits = 0). If these bits match, a monster window hit | | 117 | * <40> = 1; all other bits = 0). If these bits match, a monster window hit |
118 | * has occurred and the low-order PCI address bits <34:0> are used unchanged | | 118 | * has occurred and the low-order PCI address bits <34:0> are used unchanged |
119 | * as the system address bits <34:0>. PCI address bits <39:35> are ignored. | | 119 | * as the system address bits <34:0>. PCI address bits <39:35> are ignored. |
120 | * The high-order 32 PCI address bits are available on b_ad<31:0> in the | | 120 | * The high-order 32 PCI address bits are available on b_ad<31:0> in the |
121 | * second cycle of a DAC, and also on b_ad<63:32> in the first cycle of a | | 121 | * second cycle of a DAC, and also on b_ad<63:32> in the first cycle of a |
122 | * DAC if b_req64_l is asserted. | | 122 | * DAC if b_req64_l is asserted. |
123 | * </quote> | | 123 | * </quote> |
124 | * | | 124 | * |
125 | * This means that we can address up to 32GB of RAM using a direct-mapped | | 125 | * This means that we can address up to 32GB of RAM using a direct-mapped |
126 | * 64-bit DMA tag. This leaves us possibly having to fall back on SGMAP | | 126 | * 64-bit DMA tag. This leaves us possibly having to fall back on SGMAP |
127 | * DMA on a Titan system (those support up to 64GB of RAM), and we may have | | 127 | * DMA on a Titan system (those support up to 64GB of RAM), and we may have |
128 | * to address that with an additional large SGMAP DAC window at another | | 128 | * to address that with an additional large SGMAP DAC window at another |
129 | * time. | | 129 | * time. XXX Does the Titan Monster Window support the extra bit? |
130 | */ | | 130 | */ |
131 | #define TSP_MONSTER_DMA_WINDOW_BASE 0x100##00000000UL | | 131 | #define TSP_MONSTER_DMA_WINDOW_BASE 0x100##00000000UL |
132 | #define TSP_MONSTER_DMA_WINDOW_SIZE 0x008##00000000UL | | 132 | #define TSP_MONSTER_DMA_WINDOW_SIZE 0x008##00000000UL |
133 | | | 133 | |
| | | 134 | /* |
| | | 135 | * Basic 24-bit ISA DMA window is 8MB @ 8MB. The firmware will |
| | | 136 | * have set this up in Window 0. |
| | | 137 | */ |
| | | 138 | #define TSP_SGMAP_MAPPED_LO_BASE (8UL * 1024 * 1024) |
| | | 139 | #define TSP_SGMAP_MAPPED_LO_SIZE (8UL * 1024 * 1024) |
| | | 140 | |
| | | 141 | /* |
| | | 142 | * Basic 32-bit PCI DMA window is 1GB @ 2GB. The firmware will |
| | | 143 | * have set this up in Window 1. |
| | | 144 | */ |
| | | 145 | #define TSP_DIRECT_MAPPED_BASE (2UL * 1024 * 1024 * 1024) |
| | | 146 | #define TSP_DIRECT_MAPPED_SIZE (1UL * 1024 * 1024 * 1024) |
| | | 147 | |
| | | 148 | /* |
| | | 149 | * For systems that have > 1GB of RAM, but PCI devices that don't |
| | | 150 | * support dual-address cycle, we will also set up an additional |
| | | 151 | * SGMAP DMA window 1GB @ 3GB. We will use Window 2 for this purpose. |
| | | 152 | */ |
| | | 153 | #define TSP_SGMAP_MAPPED_HI_BASE (3UL * 1024 * 1024 * 1024) |
| | | 154 | #define TSP_SGMAP_MAPPED_HI_SIZE (1UL * 1024 * 1024 * 1024) |
| | | 155 | |
| | | 156 | /* |
| | | 157 | * Window 3 is still available for use in the future. Window 3 supports |
| | | 158 | * dual address cycle. |
| | | 159 | */ |
| | | 160 | |
134 | void | | 161 | void |
135 | tsp_dma_init(struct tsp_config *pcp) | | 162 | tsp_dma_init(struct tsp_config *pcp) |
136 | { | | 163 | { |
137 | int i; | | | |
138 | bus_dma_tag_t t; | | 164 | bus_dma_tag_t t; |
| | | 165 | bus_dma_tag_t t_sg_hi = NULL; |
139 | struct ts_pchip *pccsr = pcp->pc_csr; | | 166 | struct ts_pchip *pccsr = pcp->pc_csr; |
140 | bus_addr_t dwbase, dwlen, sgwbase, sgwlen, tbase; | | 167 | bus_addr_t tbase; |
141 | static struct map_expected { | | | |
142 | uint32_t base, mask, enables; | | | |
143 | } premap[4] = { | | | |
144 | { 0x00800000, 0x00700000, WSBA_ENA | WSBA_SG }, | | | |
145 | { 0x80000000, 0x3ff00000, WSBA_ENA }, | | | |
146 | { 0, 0, 0 }, | | | |
147 | { 0, 0, 0 } | | | |
148 | }; | | | |
149 | | | | |
150 | alpha_mb(); | | | |
151 | for(i = 0; i < 4; ++i) { | | | |
152 | if (EDIFF(pccsr->tsp_wsba[i].tsg_r, premap[i].base) || | | | |
153 | EDIFF(pccsr->tsp_wsm[i].tsg_r, premap[i].mask)) | | | |
154 | printf("tsp%d: window %d: %lx/base %lx/mask %lx" | | | |
155 | " reinitialized\n", | | | |
156 | pcp->pc_pslot, i, | | | |
157 | pccsr->tsp_wsba[i].tsg_r, | | | |
158 | pccsr->tsp_wsm[i].tsg_r, | | | |
159 | pccsr->tsp_tba[i].tsg_r); | | | |
160 | pccsr->tsp_wsba[i].tsg_r = premap[i].base | premap[i].enables; | | | |
161 | pccsr->tsp_wsm[i].tsg_r = premap[i].mask; | | | |
162 | } | | | |
163 | | | 168 | |
164 | /* Ensure the Monster Window is enabled. */ | | 169 | /* Ensure the Monster Window is enabled. */ |
| | | 170 | alpha_mb(); |
165 | pccsr->tsp_pctl.tsg_r |= PCTL_MWIN; | | 171 | pccsr->tsp_pctl.tsg_r |= PCTL_MWIN; |
166 | alpha_mb(); | | 172 | alpha_mb(); |
167 | | | 173 | |
168 | /* | | 174 | /* |
| | | 175 | * If we have more than 1GB of RAM, then set up an sgmap-mapped |
| | | 176 | * DMA window for non-DAC PCI. This is better than using the ISA |
| | | 177 | * window, which is pretty small and PCI devices could starve it. |
| | | 178 | * |
| | | 179 | * N.B. avail_end is "last-usable PFN + 1". |
| | | 180 | */ |
| | | 181 | if (uvm_physseg_get_avail_end(uvm_physseg_get_last()) > |
| | | 182 | atop(TSP_DIRECT_MAPPED_SIZE)) { |
| | | 183 | t = t_sg_hi = &pcp->pc_dmat_sgmap_hi; |
| | | 184 | t->_cookie = pcp; |
| | | 185 | t->_wbase = TSP_SGMAP_MAPPED_HI_BASE; |
| | | 186 | t->_wsize = TSP_SGMAP_MAPPED_HI_SIZE; |
| | | 187 | t->_next_window = NULL; |
| | | 188 | t->_boundary = 0; |
| | | 189 | t->_sgmap = &pcp->pc_sgmap_hi; |
| | | 190 | t->_pfthresh = TSP_SGMAP_PFTHRESH; |
| | | 191 | t->_get_tag = tsp_dma_get_tag; |
| | | 192 | t->_dmamap_create = alpha_sgmap_dmamap_create; |
| | | 193 | t->_dmamap_destroy = alpha_sgmap_dmamap_destroy; |
| | | 194 | t->_dmamap_load = tsp_bus_dmamap_load_sgmap; |
| | | 195 | t->_dmamap_load_mbuf = tsp_bus_dmamap_load_mbuf_sgmap; |
| | | 196 | t->_dmamap_load_uio = tsp_bus_dmamap_load_uio_sgmap; |
| | | 197 | t->_dmamap_load_raw = tsp_bus_dmamap_load_raw_sgmap; |
| | | 198 | t->_dmamap_unload = tsp_bus_dmamap_unload_sgmap; |
| | | 199 | t->_dmamap_sync = _bus_dmamap_sync; |
| | | 200 | |
| | | 201 | t->_dmamem_alloc = _bus_dmamem_alloc; |
| | | 202 | t->_dmamem_free = _bus_dmamem_free; |
| | | 203 | t->_dmamem_map = _bus_dmamem_map; |
| | | 204 | t->_dmamem_unmap = _bus_dmamem_unmap; |
| | | 205 | t->_dmamem_mmap = _bus_dmamem_mmap; |
| | | 206 | } |
| | | 207 | |
| | | 208 | /* |
169 | * Initialize the DMA tag used for direct-mapped 64-bit DMA. | | 209 | * Initialize the DMA tag used for direct-mapped 64-bit DMA. |
170 | */ | | 210 | */ |
171 | t = &pcp->pc_dmat64_direct; | | 211 | t = &pcp->pc_dmat64_direct; |
172 | t->_cookie = pcp; | | 212 | t->_cookie = pcp; |
173 | t->_wbase = TSP_MONSTER_DMA_WINDOW_BASE; | | 213 | t->_wbase = TSP_MONSTER_DMA_WINDOW_BASE; |
174 | t->_wsize = TSP_MONSTER_DMA_WINDOW_SIZE; | | 214 | t->_wsize = TSP_MONSTER_DMA_WINDOW_SIZE; |
175 | t->_next_window = &pcp->pc_dmat_sgmap; | | 215 | t->_next_window = t_sg_hi; |
176 | t->_boundary = 0; | | 216 | t->_boundary = 0; |
177 | t->_sgmap = NULL; | | 217 | t->_sgmap = NULL; |
178 | t->_get_tag = tsp_dma_get_tag; | | 218 | t->_get_tag = tsp_dma_get_tag; |
179 | t->_dmamap_create = _bus_dmamap_create; | | 219 | t->_dmamap_create = _bus_dmamap_create; |
180 | t->_dmamap_destroy = _bus_dmamap_destroy; | | 220 | t->_dmamap_destroy = _bus_dmamap_destroy; |
181 | t->_dmamap_load = _bus_dmamap_load_direct; | | 221 | t->_dmamap_load = _bus_dmamap_load_direct; |
182 | t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf_direct; | | 222 | t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf_direct; |
183 | t->_dmamap_load_uio = _bus_dmamap_load_uio_direct; | | 223 | t->_dmamap_load_uio = _bus_dmamap_load_uio_direct; |
184 | t->_dmamap_load_raw = _bus_dmamap_load_raw_direct; | | 224 | t->_dmamap_load_raw = _bus_dmamap_load_raw_direct; |
185 | t->_dmamap_unload = _bus_dmamap_unload; | | 225 | t->_dmamap_unload = _bus_dmamap_unload; |
186 | t->_dmamap_sync = _bus_dmamap_sync; | | 226 | t->_dmamap_sync = _bus_dmamap_sync; |
187 | | | 227 | |
188 | t->_dmamem_alloc = _bus_dmamem_alloc; | | 228 | t->_dmamem_alloc = _bus_dmamem_alloc; |
189 | t->_dmamem_free = _bus_dmamem_free; | | 229 | t->_dmamem_free = _bus_dmamem_free; |
190 | t->_dmamem_map = _bus_dmamem_map; | | 230 | t->_dmamem_map = _bus_dmamem_map; |
191 | t->_dmamem_unmap = _bus_dmamem_unmap; | | 231 | t->_dmamem_unmap = _bus_dmamem_unmap; |
192 | t->_dmamem_mmap = _bus_dmamem_mmap; | | 232 | t->_dmamem_mmap = _bus_dmamem_mmap; |
193 | | | 233 | |
194 | /* | | 234 | /* |
195 | * Initialize the DMA tag used for direct-mapped DMA. | | 235 | * Initialize the DMA tag used for direct-mapped DMA. |
196 | */ | | 236 | */ |
197 | t = &pcp->pc_dmat_direct; | | 237 | t = &pcp->pc_dmat_direct; |
198 | t->_cookie = pcp; | | 238 | t->_cookie = pcp; |
199 | t->_wbase = dwbase = WSBA_ADDR(pccsr->tsp_wsba[1].tsg_r); | | 239 | t->_wbase = TSP_DIRECT_MAPPED_BASE; |
200 | t->_wsize = dwlen = WSM_LEN(pccsr->tsp_wsm[1].tsg_r); | | 240 | t->_wsize = TSP_DIRECT_MAPPED_SIZE; |
201 | t->_next_window = &pcp->pc_dmat_sgmap; | | 241 | t->_next_window = t_sg_hi; |
202 | t->_boundary = 0; | | 242 | t->_boundary = 0; |
203 | t->_sgmap = NULL; | | 243 | t->_sgmap = NULL; |
204 | t->_get_tag = tsp_dma_get_tag; | | 244 | t->_get_tag = tsp_dma_get_tag; |
205 | t->_dmamap_create = _bus_dmamap_create; | | 245 | t->_dmamap_create = _bus_dmamap_create; |
206 | t->_dmamap_destroy = _bus_dmamap_destroy; | | 246 | t->_dmamap_destroy = _bus_dmamap_destroy; |
207 | t->_dmamap_load = _bus_dmamap_load_direct; | | 247 | t->_dmamap_load = _bus_dmamap_load_direct; |
208 | t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf_direct; | | 248 | t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf_direct; |
209 | t->_dmamap_load_uio = _bus_dmamap_load_uio_direct; | | 249 | t->_dmamap_load_uio = _bus_dmamap_load_uio_direct; |
210 | t->_dmamap_load_raw = _bus_dmamap_load_raw_direct; | | 250 | t->_dmamap_load_raw = _bus_dmamap_load_raw_direct; |
211 | t->_dmamap_unload = _bus_dmamap_unload; | | 251 | t->_dmamap_unload = _bus_dmamap_unload; |
212 | t->_dmamap_sync = _bus_dmamap_sync; | | 252 | t->_dmamap_sync = _bus_dmamap_sync; |
213 | | | 253 | |
214 | t->_dmamem_alloc = _bus_dmamem_alloc; | | 254 | t->_dmamem_alloc = _bus_dmamem_alloc; |
215 | t->_dmamem_free = _bus_dmamem_free; | | 255 | t->_dmamem_free = _bus_dmamem_free; |
216 | t->_dmamem_map = _bus_dmamem_map; | | 256 | t->_dmamem_map = _bus_dmamem_map; |
217 | t->_dmamem_unmap = _bus_dmamem_unmap; | | 257 | t->_dmamem_unmap = _bus_dmamem_unmap; |
218 | t->_dmamem_mmap = _bus_dmamem_mmap; | | 258 | t->_dmamem_mmap = _bus_dmamem_mmap; |
219 | | | 259 | |
220 | /* | | 260 | /* |
221 | * Initialize the DMA tag used for sgmap-mapped DMA. | | 261 | * Initialize the DMA tag used for ISA sgmap-mapped DMA. |
222 | */ | | 262 | */ |
223 | t = &pcp->pc_dmat_sgmap; | | 263 | t = &pcp->pc_dmat_sgmap_lo; |
224 | t->_cookie = pcp; | | 264 | t->_cookie = pcp; |
225 | t->_wbase = sgwbase = WSBA_ADDR(pccsr->tsp_wsba[0].tsg_r); | | 265 | t->_wbase = TSP_SGMAP_MAPPED_LO_BASE; |
226 | t->_wsize = sgwlen = WSM_LEN(pccsr->tsp_wsm[0].tsg_r); | | 266 | t->_wsize = TSP_SGMAP_MAPPED_LO_SIZE; |
227 | t->_next_window = NULL; | | 267 | t->_next_window = NULL; |
228 | t->_boundary = 0; | | 268 | t->_boundary = 0; |
229 | t->_sgmap = &pcp->pc_sgmap; | | 269 | t->_sgmap = &pcp->pc_sgmap_lo; |
230 | t->_pfthresh = TSP_SGMAP_PFTHRESH; | | 270 | t->_pfthresh = TSP_SGMAP_PFTHRESH; |
231 | t->_get_tag = tsp_dma_get_tag; | | 271 | t->_get_tag = tsp_dma_get_tag; |
232 | t->_dmamap_create = alpha_sgmap_dmamap_create; | | 272 | t->_dmamap_create = alpha_sgmap_dmamap_create; |
233 | t->_dmamap_destroy = alpha_sgmap_dmamap_destroy; | | 273 | t->_dmamap_destroy = alpha_sgmap_dmamap_destroy; |
234 | t->_dmamap_load = tsp_bus_dmamap_load_sgmap; | | 274 | t->_dmamap_load = tsp_bus_dmamap_load_sgmap; |
235 | t->_dmamap_load_mbuf = tsp_bus_dmamap_load_mbuf_sgmap; | | 275 | t->_dmamap_load_mbuf = tsp_bus_dmamap_load_mbuf_sgmap; |
236 | t->_dmamap_load_uio = tsp_bus_dmamap_load_uio_sgmap; | | 276 | t->_dmamap_load_uio = tsp_bus_dmamap_load_uio_sgmap; |
237 | t->_dmamap_load_raw = tsp_bus_dmamap_load_raw_sgmap; | | 277 | t->_dmamap_load_raw = tsp_bus_dmamap_load_raw_sgmap; |
238 | t->_dmamap_unload = tsp_bus_dmamap_unload_sgmap; | | 278 | t->_dmamap_unload = tsp_bus_dmamap_unload_sgmap; |
239 | t->_dmamap_sync = _bus_dmamap_sync; | | 279 | t->_dmamap_sync = _bus_dmamap_sync; |
240 | | | 280 | |
241 | t->_dmamem_alloc = _bus_dmamem_alloc; | | 281 | t->_dmamem_alloc = _bus_dmamem_alloc; |
242 | t->_dmamem_free = _bus_dmamem_free; | | 282 | t->_dmamem_free = _bus_dmamem_free; |
243 | t->_dmamem_map = _bus_dmamem_map; | | 283 | t->_dmamem_map = _bus_dmamem_map; |
244 | t->_dmamem_unmap = _bus_dmamem_unmap; | | 284 | t->_dmamem_unmap = _bus_dmamem_unmap; |
245 | t->_dmamem_mmap = _bus_dmamem_mmap; | | 285 | t->_dmamem_mmap = _bus_dmamem_mmap; |
246 | | | 286 | |
247 | /* | | 287 | /* |
248 | * Initialize the SGMAP. Align page table to 32k in case | | 288 | * Initialize the SGMAPs. Align page tables to 32k in case |
249 | * window is somewhat larger than expected. | | 289 | * window is somewhat larger than expected. |
250 | */ | | 290 | */ |
251 | alpha_sgmap_init(t, &pcp->pc_sgmap, "tsp_sgmap", | | 291 | alpha_sgmap_init(t, &pcp->pc_sgmap_lo, "tsp_sgmap_lo", |
252 | sgwbase, 0, sgwlen, sizeof(uint64_t), NULL, (32*1024)); | | 292 | TSP_SGMAP_MAPPED_LO_BASE, 0, TSP_SGMAP_MAPPED_LO_SIZE, |
| | | 293 | sizeof(uint64_t), NULL, (32*1024)); |
| | | 294 | if (t_sg_hi != NULL) { |
| | | 295 | alpha_sgmap_init(t, &pcp->pc_sgmap_hi, "tsp_sgmap_hi", |
| | | 296 | TSP_SGMAP_MAPPED_HI_BASE, 0, TSP_SGMAP_MAPPED_HI_SIZE, |
| | | 297 | sizeof(uint64_t), NULL, (32*1024)); |
| | | 298 | } |
253 | | | 299 | |
254 | /* | | 300 | /* |
255 | * Enable window 0 and enable SG PTE mapping. | | 301 | * Enable window 0 and enable SG PTE mapping. |
256 | */ | | 302 | */ |
257 | alpha_mb(); | | 303 | alpha_mb(); |
258 | pccsr->tsp_wsba[0].tsg_r |= WSBA_SG | WSBA_ENA; | | 304 | pccsr->tsp_wsba[0].tsg_r = |
| | | 305 | TSP_SGMAP_MAPPED_LO_BASE | WSBA_SG | WSBA_ENA; |
| | | 306 | alpha_mb(); |
| | | 307 | pccsr->tsp_wsm[0].tsg_r = WSM_8MB; |
| | | 308 | alpha_mb(); |
| | | 309 | tbase = pcp->pc_sgmap_lo.aps_ptpa; |
| | | 310 | if (tbase & ~0x7fffffc00UL) |
| | | 311 | panic("tsp_dma_init: bad page table address"); |
| | | 312 | pccsr->tsp_tba[0].tsg_r = tbase; |
259 | alpha_mb(); | | 313 | alpha_mb(); |
260 | | | 314 | |
261 | /* | | 315 | /* |
262 | * Enable window 1 in direct mode. | | 316 | * Enable window 1 in direct mode. |
263 | */ | | 317 | */ |
264 | alpha_mb(); | | 318 | alpha_mb(); |
265 | pccsr->tsp_wsba[1].tsg_r = | | 319 | pccsr->tsp_wsba[1].tsg_r = TSP_DIRECT_MAPPED_BASE | WSBA_ENA; |
266 | (pccsr->tsp_wsba[1].tsg_r & ~WSBA_SG) | WSBA_ENA; | | 320 | alpha_mb(); |
| | | 321 | pccsr->tsp_wsm[1].tsg_r = WSM_1GB; |
| | | 322 | alpha_mb(); |
| | | 323 | pccsr->tsp_tba[1].tsg_r = 0; |
267 | alpha_mb(); | | 324 | alpha_mb(); |
268 | | | 325 | |
| | | 326 | if (t_sg_hi != NULL) { |
| | | 327 | /* |
| | | 328 | * Enable window 2 and enable SG PTE mapping. |
| | | 329 | */ |
| | | 330 | alpha_mb(); |
| | | 331 | pccsr->tsp_wsba[2].tsg_r = |
| | | 332 | TSP_SGMAP_MAPPED_HI_BASE | WSBA_SG | WSBA_ENA; |
| | | 333 | alpha_mb(); |
| | | 334 | pccsr->tsp_wsm[2].tsg_r = WSM_1GB; |
| | | 335 | alpha_mb(); |
| | | 336 | tbase = pcp->pc_sgmap_hi.aps_ptpa; |
| | | 337 | if (tbase & ~0x7fffffc00UL) |
| | | 338 | panic("tsp_dma_init: bad page table address"); |
| | | 339 | pccsr->tsp_tba[2].tsg_r = tbase; |
| | | 340 | alpha_mb(); |
| | | 341 | } |
| | | 342 | |
269 | /* | | 343 | /* |
270 | * Check windows for sanity, especially if we later decide to | | 344 | * Disable window 3. |
271 | * use the firmware's initialization in some cases. | | | |
272 | */ | | 345 | */ |
273 | if ((sgwbase <= dwbase && dwbase < sgwbase + sgwlen) || | | | |
274 | (dwbase <= sgwbase && sgwbase < dwbase + dwlen)) | | | |
275 | panic("tsp_dma_init: overlap"); | | | |
276 | | | | |
277 | tbase = pcp->pc_sgmap.aps_ptpa; | | | |
278 | if (tbase & ~0x7fffffc00UL) | | | |
279 | panic("tsp_dma_init: bad page table address"); | | | |
280 | alpha_mb(); | | 346 | alpha_mb(); |
281 | pccsr->tsp_tba[0].tsg_r = tbase; | | 347 | pccsr->tsp_wsba[3].tsg_r = 0; |
| | | 348 | alpha_mb(); |
| | | 349 | pccsr->tsp_wsm[3].tsg_r = 0; |
| | | 350 | alpha_mb(); |
| | | 351 | pccsr->tsp_tba[3].tsg_r = 0; |
282 | alpha_mb(); | | 352 | alpha_mb(); |
283 | | | 353 | |
284 | tsp_tlb_invalidate(pcp); | | 354 | tsp_tlb_invalidate(pcp); |
285 | alpha_mb(); | | 355 | alpha_mb(); |
286 | } | | 356 | } |
287 | | | 357 | |
288 | /* | | 358 | /* |
289 | * Return the bus dma tag to be used for the specified bus type. | | 359 | * Return the bus dma tag to be used for the specified bus type. |
290 | * INTERNAL USE ONLY! | | 360 | * INTERNAL USE ONLY! |
291 | */ | | 361 | */ |
292 | static bus_dma_tag_t | | 362 | static bus_dma_tag_t |
293 | tsp_dma_get_tag(bus_dma_tag_t t, alpha_bus_t bustype) | | 363 | tsp_dma_get_tag(bus_dma_tag_t t, alpha_bus_t bustype) |
294 | { | | 364 | { |
| @@ -300,27 +370,27 @@ tsp_dma_get_tag(bus_dma_tag_t t, alpha_b | | | @@ -300,27 +370,27 @@ tsp_dma_get_tag(bus_dma_tag_t t, alpha_b |
300 | /* | | 370 | /* |
301 | * The direct mapped window will work for most systems, | | 371 | * The direct mapped window will work for most systems, |
302 | * most of the time. When it doesn't, we chain to the sgmap | | 372 | * most of the time. When it doesn't, we chain to the sgmap |
303 | * window automatically. | | 373 | * window automatically. |
304 | */ | | 374 | */ |
305 | return (&pcp->pc_dmat_direct); | | 375 | return (&pcp->pc_dmat_direct); |
306 | | | 376 | |
307 | case ALPHA_BUS_ISA: | | 377 | case ALPHA_BUS_ISA: |
308 | /* | | 378 | /* |
309 | * ISA doesn't have enough address bits to use | | 379 | * ISA doesn't have enough address bits to use |
310 | * the direct-mapped DMA window, so we must use | | 380 | * the direct-mapped DMA window, so we must use |
311 | * SGMAPs. | | 381 | * SGMAPs. |
312 | */ | | 382 | */ |
313 | return (&pcp->pc_dmat_sgmap); | | 383 | return (&pcp->pc_dmat_sgmap_lo); |
314 | | | 384 | |
315 | default: | | 385 | default: |
316 | panic("tsp_dma_get_tag: shouldn't be here, really..."); | | 386 | panic("tsp_dma_get_tag: shouldn't be here, really..."); |
317 | } | | 387 | } |
318 | } | | 388 | } |
319 | | | 389 | |
320 | /* | | 390 | /* |
321 | * Load a TSP SGMAP-mapped DMA map with a linear buffer. | | 391 | * Load a TSP SGMAP-mapped DMA map with a linear buffer. |
322 | */ | | 392 | */ |
323 | static int | | 393 | static int |
324 | tsp_bus_dmamap_load_sgmap(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags) | | 394 | tsp_bus_dmamap_load_sgmap(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags) |
325 | { | | 395 | { |
326 | int error; | | 396 | int error; |