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
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]
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.
37 #include <sys/types.h>
38 #include <sys/systm.h>
40 #include <sys/sunddi.h>
44 #include <sys/asm_linkage.h>
45 #include <sys/clock.h>
46 #include <sys/intreg.h>
48 #include "assym.h" /* for FKIOCTL etc. */
54 * Layered driver routines.
56 * At the time of writing, the compiler converts
58 * a() { return (b()); }
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) \
78 ddi_copyin
(const void
*buf
, void
*kernbuf
, size_t size
, int flags
)
81 return
(kcopy
(buf
, kernbuf
, size
) ?
-1 : 0);
82 return
(copyin
(buf
, kernbuf
, size
));
90 bne .do_kcopy ! share code with ddi_copyout
95 save
%sp
, -SA
(MINFRAME
), %sp
100 orcc
%g0
, %o0
, %i0
! if kcopy returns EFAULT
..
102 mov
-1, %i0
! .. we return -1
112 ddi_copyout
(const void
*buf
, void
*kernbuf
, size_t size
, int flags
)
115 return
(kcopy
(buf
, kernbuf
, size
) ?
-1 : 0);
116 return
(copyout
(buf
, kernbuf
, size
));
124 bne .do_kcopy ! share code with ddi_copyin
127 SET_SIZE
(ddi_copyout
)
132 * DDI spine wrapper routines - here so as to not have to
133 * buy register windows when climbing the device tree (which cost!)
140 ddi_ctlops
(dev_info_t
*d
, dev_info_t
*r
, ddi_ctl_enum_t op
, void
*a, void
*v
)
142 return
(DDI_SUCCESS
);
149 be,pn
%ncc
, 2f
! nope
151 be,pn
%ncc
, 2f
! nope
152 ldn
[%o0
+ DEVI_BUS_CTL
], %o0
153 ! dip
= (dev_info_t
*)DEVI
(dip
)->devi_bus_ctl;
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
162 sub %g0
, 1, %o0
! return
(DDI_FAILURE
);
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
);
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
)
196 ddi_dma_freehdl
(dev_info_t
*dip
, dev_info_t
*rdip
, ddi_dma_handle_t handlep
)
198 return
(DDI_SUCCESS
);
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
)
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
);
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
)
246 ddi_dma_unbindhdl
(dev_info_t
*dip
, dev_info_t
*rdip
,
247 ddi_dma_handle_t handle
)
249 return
(DDI_SUCCESS
);
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
)
271 ddi_dma_flush
(dev_info_t
*dip
, dev_info_t
*rdip
,
272 ddi_dma_handle_t handle
, off_t off
, size_t len
,
275 return
(DDI_SUCCESS
);
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
)
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
);
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
)
323 ddi_dma_sync
(ddi_dma_handle_t h
, off_t o
, size_t
l, u_int whom
)
325 return
(DDI_SUCCESS
);
331 ld [%o0
+ DMA_HANDLE_RFLAGS
], %o4
! hp-
>dmai_rflags;
332 sethi
%hi
(DMP_NOSYNC
), %o5
340 ldn
[%o0
+ DMA_HANDLE_RDIP
], %o1
! dip
= hp-
>dmai_rdip;
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
346 ldn
[%g1
+ DEVI_BUS_OPS
], %g1
! dip-
>dev_ops-
>devo_bus_ops
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
)
360 ddi_dma_unbind_handle
(ddi_dma_handle_t h
)
362 return
(DDI_SUCCESS
);
367 ENTRY
(ddi_dma_unbind_handle
)
368 ldn
[%o0
+ DMA_HANDLE_RDIP
], %o1
! dip
= hp-
>dmai_rdip;
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
)
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
);
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
)