998 obsolete DMA driver interfaces should be removed
[unleashed.git] / usr / src / uts / sparc / ml / sparc_ddi.s
blob7497459b4ac4c86eed89756dfb27d1781b24df0c
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
31 * Assembler routines to make some DDI routines go faster.
32 * These routines should ONLY be ISA-dependent.
35 #if defined(lint)
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/file.h>
40 #include <sys/sunddi.h>
42 #else /* lint */
44 #include <sys/asm_linkage.h>
45 #include <sys/clock.h>
46 #include <sys/intreg.h>
48 #include "assym.h" /* for FKIOCTL etc. */
50 #endif /* lint */
54 * Layered driver routines.
56 * At the time of writing, the compiler converts
58 * a() { return (b()); }
60 * into
61 * save, call b, restore
63 * Though this is sort of ok, if the called routine is leaf routine,
64 * then we just burnt a register window.
66 * When the compiler understands this optimization, many
67 * of these routines can go back to C again.
70 #define FLATCALL(routine) \
71 mov %o7, %g1; \
72 call routine; \
73 mov %g1, %o7
75 #ifdef lint
77 int
78 ddi_copyin(const void *buf, void *kernbuf, size_t size, int flags)
80 if (flags & FKIOCTL)
81 return (kcopy(buf, kernbuf, size) ? -1 : 0);
82 return (copyin(buf, kernbuf, size));
85 #else /* lint */
87 ENTRY(ddi_copyin)
88 set FKIOCTL, %o4
89 andcc %o3, %o4, %g0
90 bne .do_kcopy ! share code with ddi_copyout
91 FLATCALL(copyin)
92 /*NOTREACHED*/
94 .do_kcopy:
95 save %sp, -SA(MINFRAME), %sp
96 mov %i2, %o2
97 mov %i1, %o1
98 call kcopy
99 mov %i0, %o0
100 orcc %g0, %o0, %i0 ! if kcopy returns EFAULT ..
101 bne,a 1f
102 mov -1, %i0 ! .. we return -1
103 1: ret
104 restore
105 SET_SIZE(ddi_copyin)
107 #endif /* lint */
109 #ifdef lint
112 ddi_copyout(const void *buf, void *kernbuf, size_t size, int flags)
114 if (flags & FKIOCTL)
115 return (kcopy(buf, kernbuf, size) ? -1 : 0);
116 return (copyout(buf, kernbuf, size));
119 #else /* lint */
121 ENTRY(ddi_copyout)
122 set FKIOCTL, %o4
123 andcc %o3, %o4, %g0
124 bne .do_kcopy ! share code with ddi_copyin
125 FLATCALL(copyout)
126 /*NOTREACHED*/
127 SET_SIZE(ddi_copyout)
129 #endif /* lint */
132 * DDI spine wrapper routines - here so as to not have to
133 * buy register windows when climbing the device tree (which cost!)
136 #if defined(lint)
138 /*ARGSUSED*/
140 ddi_ctlops(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t op, void *a, void *v)
142 return (DDI_SUCCESS);
145 #else /* lint */
147 ENTRY(ddi_ctlops)
148 tst %o0 ! dip != 0?
149 be,pn %ncc, 2f ! nope
150 tst %o1 ! rdip != 0?
151 be,pn %ncc, 2f ! nope
152 ldn [%o0 + DEVI_BUS_CTL], %o0
153 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_ctl;
154 brz,pn %o0, 2f
155 nop ! Delay slot
156 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
157 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
158 ldn [%g1 + OPS_CTL], %g1 ! dip->dev_ops->devo_bus_ops->bus_ctl
159 jmpl %g1, %g0 ! bop off to new routine
160 nop ! as if we had never been here
161 2: retl
162 sub %g0, 1, %o0 ! return (DDI_FAILURE);
163 SET_SIZE(ddi_ctlops)
165 #endif /* lint */
167 #if defined(lint)
169 /* ARGSUSED */
171 ddi_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
172 int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
174 return (DDI_SUCCESS);
177 #else /* lint */
179 ENTRY(ddi_dma_allochdl)
180 ldn [%o0 + DEVI_BUS_DMA_ALLOCHDL], %o0
181 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_allochdl;
182 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
183 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
184 ldn [%g1 + OPS_ALLOCHDL], %g1
185 ! dip->dev_ops->devo_bus_ops->bus_dma_allochdl
186 jmpl %g1, %g0 ! bop off to new routine
187 nop ! as if we had never been here
188 SET_SIZE(ddi_dma_allochdl)
190 #endif /* lint */
192 #if defined(lint)
194 /* ARGSUSED */
196 ddi_dma_freehdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handlep)
198 return (DDI_SUCCESS);
201 #else /* lint */
203 ENTRY(ddi_dma_freehdl)
204 ldn [%o0 + DEVI_BUS_DMA_FREEHDL], %o0
205 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_freehdl;
206 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
207 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
208 ldn [%g1 + OPS_FREEHDL], %g1
209 ! dip->dev_ops->devo_bus_ops->bus_dma_freehdl
210 jmpl %g1, %g0 ! bop off to new routine
211 nop ! as if we had never been here
212 SET_SIZE(ddi_dma_freehdl)
214 #endif /* lint */
216 #if defined(lint)
218 /* ARGSUSED */
220 ddi_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
221 ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
222 ddi_dma_cookie_t *cp, u_int *ccountp)
224 return (DDI_SUCCESS);
227 #else /* lint */
229 ENTRY(ddi_dma_bindhdl)
230 ldn [%o0 + DEVI_BUS_DMA_BINDHDL], %o0
231 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_bindhdl;
232 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
233 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
234 ldn [%g1 + OPS_BINDHDL], %g1
235 ! dip->dev_ops->devo_bus_ops->bus_dma_bindhdl
236 jmpl %g1, %g0 ! bop off to new routine
237 nop ! as if we had never been here
238 SET_SIZE(ddi_dma_bindhdl)
240 #endif /* lint */
242 #if defined(lint)
244 /* ARGSUSED */
246 ddi_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
247 ddi_dma_handle_t handle)
249 return (DDI_SUCCESS);
252 #else /* lint */
254 ENTRY(ddi_dma_unbindhdl)
255 ldn [%o0 + DEVI_BUS_DMA_UNBINDHDL], %o0
256 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_unbindhdl;
257 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
258 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
259 ldn [%g1 + OPS_UNBINDHDL], %g1
260 ! dip->dev_ops->devo_bus_ops->bus_dma_unbindhdl
261 jmpl %g1, %g0 ! bop off to new routine
262 nop ! as if we had never been here
263 SET_SIZE(ddi_dma_unbindhdl)
265 #endif /* lint */
267 #if defined(lint)
269 /* ARGSUSED */
271 ddi_dma_flush(dev_info_t *dip, dev_info_t *rdip,
272 ddi_dma_handle_t handle, off_t off, size_t len,
273 u_int cache_flags)
275 return (DDI_SUCCESS);
278 #else /* lint */
280 ENTRY(ddi_dma_flush)
281 ldn [%o0 + DEVI_BUS_DMA_FLUSH], %o0
282 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_flush;
283 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
284 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
285 ldn [%g1 + OPS_FLUSH], %g1
286 ! dip->dev_ops->devo_bus_ops->bus_dma_flush
287 jmpl %g1, %g0 ! bop off to new routine
288 nop ! as if we had never been here
289 SET_SIZE(ddi_dma_flush)
291 #endif /* lint */
293 #if defined(lint)
295 /* ARGSUSED */
297 ddi_dma_win(dev_info_t *dip, dev_info_t *rdip,
298 ddi_dma_handle_t handle, uint_t win, off_t *offp,
299 size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
301 return (DDI_SUCCESS);
304 #else /* lint */
306 ENTRY(ddi_dma_win)
307 ldn [%o0 + DEVI_BUS_DMA_WIN], %o0
308 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_win;
309 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
310 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
311 ldn [%g1 + OPS_WIN], %g1
312 ! dip->dev_ops->devo_bus_ops->bus_dma_win
313 jmpl %g1, %g0 ! bop off to new routine
314 nop ! as if we had never been here
315 SET_SIZE(ddi_dma_win)
317 #endif /* lint */
319 #if defined(lint)
321 /* ARGSUSED */
323 ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, u_int whom)
325 return (DDI_SUCCESS);
328 #else /* lint */
330 ENTRY(ddi_dma_sync)
331 ld [%o0 + DMA_HANDLE_RFLAGS], %o4 ! hp->dmai_rflags;
332 sethi %hi(DMP_NOSYNC), %o5
333 and %o4, %o5, %o4
334 cmp %o4, %o5
335 bne 1f
336 mov %o3, %o5
337 retl
338 clr %o0
339 1: mov %o1, %o3
340 ldn [%o0 + DMA_HANDLE_RDIP], %o1 ! dip = hp->dmai_rdip;
341 mov %o0, %g2
342 ldn [%o1 + DEVI_BUS_DMA_FLUSH], %o0
343 ! dip = DEVI(dip)->devi_bus_dma_flush;
344 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
345 mov %o2, %o4
346 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
347 mov %g2, %o2
348 ldn [%g1 + OPS_FLUSH], %g1
349 ! dip->dev_ops->devo_bus_ops->bus_dma_flush
350 jmpl %g1, %g0 ! bop off to new routine
351 nop ! as if we had never been here
352 SET_SIZE(ddi_dma_sync)
354 #endif /* lint */
356 #if defined(lint)
358 /* ARGSUSED */
360 ddi_dma_unbind_handle(ddi_dma_handle_t h)
362 return (DDI_SUCCESS);
365 #else /* lint */
367 ENTRY(ddi_dma_unbind_handle)
368 ldn [%o0 + DMA_HANDLE_RDIP], %o1 ! dip = hp->dmai_rdip;
369 mov %o0, %o2
370 ldn [%o1 + DEVI_BUS_DMA_UNBINDFUNC ], %g1
371 ! funcp = DEVI(dip)->devi_bus_dma_unbindfunc;
372 jmpl %g1, %g0 ! bop off to new routine
373 ldn [%o1 + DEVI_BUS_DMA_UNBINDHDL], %o0
374 ! hdip = (dev_info_t *)DEVI(dip)->devi_bus_dma_unbindhdl;
375 SET_SIZE(ddi_dma_unbind_handle)
377 #endif /* lint */
380 #if defined(lint)
382 /*ARGSUSED*/
384 ddi_dma_mctl(register dev_info_t *dip, dev_info_t *rdip,
385 ddi_dma_handle_t handle, enum ddi_dma_ctlops request,
386 off_t *offp, size_t *lenp, caddr_t *objp, u_int flags)
388 return (DDI_SUCCESS);
391 #else /* lint */
393 ENTRY(ddi_dma_mctl)
394 ldn [%o0 + DEVI_BUS_DMA_CTL], %o0
395 ! dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_ctl;
396 ldn [%o0 + DEVI_DEV_OPS], %g1 ! dip->dev_ops
397 ldn [%g1 + DEVI_BUS_OPS], %g1 ! dip->dev_ops->devo_bus_ops
398 ldn [%g1 + OPS_MCTL], %g1 ! dip->dev_ops->devo_bus_ops->bus_dma_ctl
399 jmpl %g1, %g0 ! bop off to new routine
400 nop ! as if we had never been here
401 SET_SIZE(ddi_dma_mctl)
403 #endif /* lint */