xref: /netbsd/sys/arch/i386/i386/busfunc.S (revision 11580e23)
1/*	$NetBSD: busfunc.S,v 1.9 2013/06/22 05:20:57 uebayasi Exp $	*/
2
3/*-
4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
18 *
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.
30 */
31
32#include <machine/asm.h>
33__KERNEL_RCSID(0, "$NetBSD: busfunc.S,v 1.9 2013/06/22 05:20:57 uebayasi Exp $");
34
35#include "assym.h"
36
37/*
38 * uint8_t bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t bsh,
39 *    bus_size_t offset);
40 */
41ENTRY(bus_space_read_1)
42	movl	4(%esp), %eax
43	movl	8(%esp), %edx
44	addl	12(%esp), %edx
45	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
46	je	1f
47	movzbl	(%edx), %eax
48	ret
491:
50	xorl	%eax, %eax
51	inb	%dx, %al
52	ret
53END(bus_space_read_1)
54
55/*
56 * uint16_t bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t bsh,
57 *    bus_size_t offset);
58 */
59ENTRY(bus_space_read_2)
60	movl	4(%esp), %eax
61	movl	8(%esp), %edx
62	addl	12(%esp), %edx
63	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
64	je	1f
65	movzwl	(%edx), %eax
66	ret
671:
68	xorl	%eax, %eax
69	inw	%dx, %ax
70	ret
71END(bus_space_read_2)
72
73/*
74 * uint32_t bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t bsh,
75 *    bus_size_t offset);
76 */
77ENTRY(bus_space_read_4)
78	movl	4(%esp), %eax
79	movl	8(%esp), %edx
80	addl	12(%esp), %edx
81	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
82	je	1f
83	movl	(%edx), %eax
84	ret
851:
86	inl	%dx, %eax
87	ret
88END(bus_space_read_4)
89
90STRONG_ALIAS(bus_space_read_stream_1,bus_space_read_1)
91STRONG_ALIAS(bus_space_read_stream_2,bus_space_read_2)
92STRONG_ALIAS(bus_space_read_stream_4,bus_space_read_4)
93
94/*
95 * void bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
96 *    bus_size_t offset, uint8_t value);
97 */
98ENTRY(bus_space_write_1)
99	movl	4(%esp), %eax
100	movl	8(%esp), %edx
101	addl	12(%esp), %edx
102	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
103	movl	16(%esp), %eax
104	je	1f
105	movb	%al, (%edx)
106	ret
1071:
108	outb	%al, %dx
109	ret
110END(bus_space_write_1)
111
112/*
113 * void bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
114 *    bus_size_t offset, uint16_t value);
115 */
116ENTRY(bus_space_write_2)
117	movl	4(%esp), %eax
118	movl	8(%esp), %edx
119	addl	12(%esp), %edx
120	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
121	movl	16(%esp), %eax
122	je	1f
123	movw	%ax, (%edx)
124	ret
1251:
126	outw	%ax, %dx
127	ret
128END(bus_space_write_2)
129
130/*
131 * void bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
132 *     bus_size_t offset, uint32_t value);
133 */
134ENTRY(bus_space_write_4)
135	movl	4(%esp), %eax
136	movl	8(%esp), %edx
137	addl	12(%esp), %edx
138	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
139	movl	16(%esp), %eax
140	je	1f
141	movl	%eax, (%edx)
142	ret
1431:
144	outl	%eax, %dx
145	ret
146END(bus_space_write_4)
147
148STRONG_ALIAS(bus_space_write_stream_1,bus_space_write_1)
149STRONG_ALIAS(bus_space_write_stream_2,bus_space_write_2)
150STRONG_ALIAS(bus_space_write_stream_4,bus_space_write_4)
151
152/*
153 * void bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
154 *    bus_size_t offset, uint8_t *addr, size_t count);
155 */
156ENTRY(bus_space_read_multi_1)
157	pushl	%edi
158	movl	8(%esp), %eax
159	movl	12(%esp), %edx
160	addl	16(%esp), %edx
161	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
162	movl	20(%esp), %edi
163	movl	24(%esp), %ecx
164	jne	1f
165	rep
166	insb	%dx, %es:(%edi)
167	popl	%edi
168	ret
169	.align	16
1701:
171	movb	(%edx), %al
172	decl	%ecx
173	movb	%al, (%edi)
174	leal	1(%edi), %edi
175	jnz	1b
176	popl	%edi
177	ret
178END(bus_space_read_multi_1)
179
180/*
181 * void bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
182 *    bus_size_t offset, uint16_t *addr, size_t count);
183 */
184ENTRY(bus_space_read_multi_2)
185	pushl	%edi
186	movl	8(%esp), %eax
187	movl	12(%esp), %edx
188	addl	16(%esp), %edx
189	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
190	movl	20(%esp), %edi
191	movl	24(%esp), %ecx
192	jne	1f
193	rep
194	insw	%dx, %es:(%edi)
195	popl	%edi
196	ret
197	.align	16
1981:
199	movw	(%edx), %ax
200	decl	%ecx
201	movw	%ax, (%edi)
202	leal	2(%edi), %edi
203	jnz	1b
204	popl	%edi
205	ret
206END(bus_space_read_multi_2)
207
208/*
209 * void bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
210 *    bus_size_t offset, uint32_t *addr, size_t count);
211 */
212ENTRY(bus_space_read_multi_4)
213	pushl	%edi
214	movl	8(%esp), %eax
215	movl	12(%esp), %edx
216	addl	16(%esp), %edx
217	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
218	movl	20(%esp), %edi
219	movl	24(%esp), %ecx
220	jne	1f
221	rep
222	insl	%dx, %es:(%edi)
223	popl	%edi
224	ret
225	.align	16
2261:
227	movl	(%edx), %eax
228	decl	%ecx
229	movl	%eax, (%edi)
230	leal	4(%edi), %edi
231	jnz	1b
232	popl	%edi
233	ret
234END(bus_space_read_multi_4)
235
236STRONG_ALIAS(bus_space_read_multi_stream_1,bus_space_read_multi_1)
237STRONG_ALIAS(bus_space_read_multi_stream_2,bus_space_read_multi_2)
238STRONG_ALIAS(bus_space_read_multi_stream_4,bus_space_read_multi_4)
239
240/*
241 * void bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
242 *    bus_size_t offset, const uint8_t *addr, size_t count);
243 */
244ENTRY(bus_space_write_multi_1)
245	pushl	%esi
246	movl	8(%esp), %eax
247	movl	12(%esp), %edx
248	addl	16(%esp), %edx
249	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
250	movl	20(%esp), %esi
251	movl	24(%esp), %ecx
252	jne	1f
253	rep
254	outsb	%ds:(%esi), %dx
255	popl	%esi
256	ret
257	.align	16
2581:
259	movb	(%esi), %al
260	decl	%ecx
261	movb	%al, (%edx)
262	leal	1(%esi), %esi
263	jnz	1b
264	popl	%esi
265	ret
266END(bus_space_write_multi_1)
267
268/*
269 * void bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
270 *    bus_size_t offset, const uint16_t *addr, size_t count);
271 */
272ENTRY(bus_space_write_multi_2)
273	pushl	%esi
274	movl	8(%esp), %eax
275	movl	12(%esp), %edx
276	addl	16(%esp), %edx
277	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
278	movl	20(%esp), %esi
279	movl	24(%esp), %ecx
280	jne	1f
281	rep
282	outsw	%ds:(%esi), %dx
283	popl	%esi
284	ret
285	.align	16
2861:
287	movw	(%esi), %ax
288	decl	%ecx
289	movw	%ax, (%edx)
290	leal	2(%esi), %esi
291	jnz	1b
292	popl	%esi
293	ret
294END(bus_space_write_multi_2)
295
296/*
297 * void bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
298 *    bus_size_t offset, const uint32_t *addr, size_t count);
299 */
300ENTRY(bus_space_write_multi_4)
301	pushl	%esi
302	movl	8(%esp), %eax
303	movl	12(%esp), %edx
304	addl	16(%esp), %edx
305	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
306	movl	20(%esp), %esi
307	movl	24(%esp), %ecx
308	jne	1f
309	rep
310	outsl	%ds:(%esi), %dx
311	popl	%esi
312	ret
313	.align	16
3141:
315	movl	(%esi), %eax
316	decl	%ecx
317	movl	%eax, (%edx)
318	leal	4(%esi), %esi
319	jnz	1b
320	popl	%esi
321	ret
322END(bus_space_write_multi_4)
323
324STRONG_ALIAS(bus_space_write_multi_stream_1,bus_space_write_multi_1)
325STRONG_ALIAS(bus_space_write_multi_stream_2,bus_space_write_multi_2)
326STRONG_ALIAS(bus_space_write_multi_stream_4,bus_space_write_multi_4)
327
328/*
329 * void bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
330 *    bus_size_t offset, uint8_t *addr, size_t count);
331 */
332ENTRY(bus_space_read_region_1)
333	pushl	%edi
334	movl	8(%esp), %eax
335	movl	12(%esp), %edx
336	addl	16(%esp), %edx
337	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
338	movl	20(%esp), %edi
339	movl	24(%esp), %ecx
340	je	2f
3411:
342	xchgl	%edx, %esi
343	rep
344	movsb	%ds:(%esi), %es:(%edi)
345	movl	%edx, %esi
346	popl	%edi
347	ret
3482:
349	inb	%dx, %al
350	incl	%edx
351	decl	%ecx
352	movb	%al, (%edi)
353	leal	1(%edi), %edi
354	jnz	2b
355	popl	%edi
356	ret
357END(bus_space_read_region_1)
358
359/*
360 * void bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
361 *    bus_size_t offset, uint16_t *addr, size_t count);
362 */
363ENTRY(bus_space_read_region_2)
364	pushl	%edi
365	movl	8(%esp), %eax
366	movl	12(%esp), %edx
367	addl	16(%esp), %edx
368	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
369	movl	20(%esp), %edi
370	movl	24(%esp), %ecx
371	je	2f
3721:
373	xchgl	%edx, %esi
374	rep
375	movsw	%ds:(%esi), %es:(%edi)
376	movl	%edx, %esi
377	popl	%edi
378	ret
3792:
380	inw	%dx, %ax
381	addl	$2, %edx
382	decl	%ecx
383	movw	%ax, (%edi)
384	leal	2(%edi), %edi
385	jnz	2b
386	popl	%edi
387	ret
388END(bus_space_read_region_2)
389
390/*
391 * void bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
392 *    bus_size_t offset, uint32_t *addr, size_t count);
393 */
394ENTRY(bus_space_read_region_4)
395	pushl	%edi
396	movl	8(%esp), %eax
397	movl	12(%esp), %edx
398	addl	16(%esp), %edx
399	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
400	movl	20(%esp), %edi
401	movl	24(%esp), %ecx
402	je	2f
4031:
404	xchgl	%edx, %esi
405	rep
406	movsl	%ds:(%esi), %es:(%edi)
407	movl	%edx, %esi
408	popl	%edi
409	ret
4102:
411	inl	%dx, %eax
412	addl	$4, %edx
413	decl	%ecx
414	movl	%eax, (%edi)
415	leal	4(%edi), %edi
416	jnz	2b
417	popl	%edi
418	ret
419END(bus_space_read_region_4)
420
421STRONG_ALIAS(bus_space_read_region_stream_1,bus_space_read_region_1)
422STRONG_ALIAS(bus_space_read_region_stream_2,bus_space_read_region_2)
423STRONG_ALIAS(bus_space_read_region_stream_4,bus_space_read_region_4)
424
425/*
426 * void bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
427 *    bus_size_t offset, const uint8_t *addr, size_t count);
428 */
429ENTRY(bus_space_write_region_1)
430	pushl	%esi
431	movl	8(%esp), %eax
432	movl	12(%esp), %edx
433	addl	16(%esp), %edx
434	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
435	movl	20(%esp), %esi
436	movl	24(%esp), %ecx
437	je	2f
4381:
439	xchgl	%edx, %edi
440	rep
441	movsb	%ds:(%esi), %es:(%edi)
442	movl	%edx, %edi
443	popl	%esi
444	ret
4452:
446	movb	(%esi), %al
447	incl	%esi
448	decl	%ecx
449	outb	%al, %dx
450	leal	1(%edx), %edx
451	jnz	2b
452	popl	%esi
453	ret
454END(bus_space_write_region_1)
455
456/*
457 * void bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
458 *    bus_size_t offset, const uint16_t *addr, size_t count);
459 */
460ENTRY(bus_space_write_region_2)
461	pushl	%esi
462	movl	8(%esp), %eax
463	movl	12(%esp), %edx
464	addl	16(%esp), %edx
465	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
466	movl	20(%esp), %esi
467	movl	24(%esp), %ecx
468	je	2f
4691:
470	xchgl	%edx, %edi
471	rep
472	movsw	%ds:(%esi), %es:(%edi)
473	movl	%edx, %edi
474	popl	%esi
475	ret
4762:
477	movw	(%esi), %ax
478	addl	$2, %esi
479	decl	%ecx
480	outw	%ax, %dx
481	leal	2(%edx), %edx
482	jnz	2b
483	popl	%esi
484	ret
485END(bus_space_write_region_2)
486
487/*
488 * void bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
489 *    bus_size_t offset, const uint32_t *addr, size_t count);
490 */
491ENTRY(bus_space_write_region_4)
492	pushl	%esi
493	movl	8(%esp), %eax
494	movl	12(%esp), %edx
495	addl	16(%esp), %edx
496	cmpl	$X86_BUS_SPACE_IO, BST_TYPE(%eax)
497	movl	20(%esp), %esi
498	movl	24(%esp), %ecx
499	je	2f
5001:
501	xchgl	%edx, %edi
502	rep
503	movsl	%ds:(%esi), %es:(%edi)
504	movl	%edx, %edi
505	popl	%esi
506	ret
5072:
508	movl	(%esi), %eax
509	addl	$4, %esi
510	decl	%ecx
511	outl	%eax, %dx
512	leal	4(%edx), %edx
513	jnz	2b
514	popl	%esi
515	ret
516END(bus_space_write_region_4)
517
518STRONG_ALIAS(bus_space_write_region_stream_1,bus_space_write_region_1)
519STRONG_ALIAS(bus_space_write_region_stream_2,bus_space_write_region_2)
520STRONG_ALIAS(bus_space_write_region_stream_4,bus_space_write_region_4)
521