xref: /illumos-gate/usr/src/uts/intel/ml/ddi_i86_asm.S (revision 1e56f352c1c208679012bca47d552e127f5b1072)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*
28 * Copyright 2019 Joyent, Inc.
29 */
30
31#include <sys/asm_linkage.h>
32#include <sys/asm_misc.h>
33#include "assym.h"
34
35	ENTRY(ddi_get8)
36	ALTENTRY(ddi_mem_get8)
37	ALTENTRY(ddi_io_get8)
38	movl	ACC_ATTR(%rdi), %edx
39	cmpl	$_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx
40	jne	1f
41	movq	%rsi, %rdx
42	xorq	%rax, %rax
43	inb	(%dx)
44	ret
451:
46	cmpl	$_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx
47	jne	2f
48	movzbq	(%rsi), %rax
49	ret
502:
51	movq	ACC_GETB(%rdi), %rax
52	INDIRECT_JMP_REG(rax)
53	SET_SIZE(ddi_get8)
54	SET_SIZE(ddi_mem_get8)
55	SET_SIZE(ddi_io_get8)
56
57
58	ENTRY(ddi_get16)
59	ALTENTRY(ddi_mem_get16)
60	ALTENTRY(ddi_io_get16)
61	movl	ACC_ATTR(%rdi), %edx
62	cmpl	$_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx
63	jne	3f
64	movq	%rsi, %rdx
65	xorq	%rax, %rax
66	inw	(%dx)
67	ret
683:
69	cmpl	$_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx
70	jne	4f
71	movzwq	(%rsi), %rax
72	ret
734:
74	movq	ACC_GETW(%rdi), %rax
75	INDIRECT_JMP_REG(rax)
76	SET_SIZE(ddi_get16)
77	SET_SIZE(ddi_mem_get16)
78	SET_SIZE(ddi_io_get16)
79
80
81	ENTRY(ddi_get32)
82	ALTENTRY(ddi_mem_get32)
83	ALTENTRY(ddi_io_get32)
84	movl	ACC_ATTR(%rdi), %edx
85	cmpl	$_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx
86	jne	5f
87	movq	%rsi, %rdx
88	inl	(%dx)
89	ret
905:
91	cmpl	$_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx
92	jne	6f
93	movl	(%rsi), %eax
94	ret
956:
96	movq	ACC_GETL(%rdi), %rax
97	INDIRECT_JMP_REG(rax)
98	SET_SIZE(ddi_get32)
99	SET_SIZE(ddi_mem_get32)
100	SET_SIZE(ddi_io_get32)
101
102
103	ENTRY(ddi_get64)
104	ALTENTRY(ddi_mem_get64)
105	movq	ACC_GETLL(%rdi), %rax
106	INDIRECT_JMP_REG(rax)
107	SET_SIZE(ddi_get64)
108	SET_SIZE(ddi_mem_get64)
109
110
111	ENTRY(ddi_put8)
112	ALTENTRY(ddi_mem_put8)
113	ALTENTRY(ddi_io_put8)
114	movl	ACC_ATTR(%rdi), %ecx
115	cmpl	$_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx
116	jne	7f
117	movq	%rdx, %rax
118	movq	%rsi, %rdx
119	outb	(%dx)
120	ret
1217:
122	cmpl	$_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx
123	jne	8f
124	movb	%dl, (%rsi)
125	ret
1268:
127	movq	ACC_PUTB(%rdi), %rax
128	INDIRECT_JMP_REG(rax)
129	SET_SIZE(ddi_put8)
130	SET_SIZE(ddi_mem_put8)
131	SET_SIZE(ddi_io_put8)
132
133
134	ENTRY(ddi_put16)
135	ALTENTRY(ddi_mem_put16)
136	ALTENTRY(ddi_io_put16)
137	movl	ACC_ATTR(%rdi), %ecx
138	cmpl	$_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx
139	jne	8f
140	movq	%rdx, %rax
141	movq	%rsi, %rdx
142	outw	(%dx)
143	ret
1448:
145	cmpl	$_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx
146	jne	9f
147	movw	%dx, (%rsi)
148	ret
1499:
150	movq	ACC_PUTW(%rdi), %rax
151	INDIRECT_JMP_REG(rax)
152	SET_SIZE(ddi_put16)
153	SET_SIZE(ddi_mem_put16)
154	SET_SIZE(ddi_io_put16)
155
156
157	ENTRY(ddi_put32)
158	ALTENTRY(ddi_mem_put32)
159	ALTENTRY(ddi_io_put32)
160	movl	ACC_ATTR(%rdi), %ecx
161	cmpl	$_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx
162	jne	8f
163	movq	%rdx, %rax
164	movq	%rsi, %rdx
165	outl	(%dx)
166	ret
1678:
168	cmpl	$_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx
169	jne	9f
170	movl	%edx, (%rsi)
171	ret
1729:
173	movq	ACC_PUTL(%rdi), %rax
174	INDIRECT_JMP_REG(rax)
175	SET_SIZE(ddi_put32)
176	SET_SIZE(ddi_mem_put32)
177	SET_SIZE(ddi_io_put32)
178
179
180	ENTRY(ddi_put64)
181	ALTENTRY(ddi_mem_put64)
182	movq	ACC_PUTLL(%rdi), %rax
183	INDIRECT_JMP_REG(rax)
184	SET_SIZE(ddi_put64)
185	SET_SIZE(ddi_mem_put64)
186
187
188	ENTRY(ddi_rep_get8)
189	ALTENTRY(ddi_mem_rep_get8)
190	movq	ACC_REP_GETB(%rdi), %rax
191	INDIRECT_JMP_REG(rax)
192	SET_SIZE(ddi_rep_get8)
193	SET_SIZE(ddi_mem_rep_get8)
194
195
196	ENTRY(ddi_rep_get16)
197	ALTENTRY(ddi_mem_rep_get16)
198	movq	ACC_REP_GETW(%rdi), %rax
199	INDIRECT_JMP_REG(rax)
200	SET_SIZE(ddi_rep_get16)
201	SET_SIZE(ddi_mem_rep_get16)
202
203
204	ENTRY(ddi_rep_get32)
205	ALTENTRY(ddi_mem_rep_get32)
206	movq	ACC_REP_GETL(%rdi), %rax
207	INDIRECT_JMP_REG(rax)
208	SET_SIZE(ddi_rep_get32)
209	SET_SIZE(ddi_mem_rep_get32)
210
211
212	ENTRY(ddi_rep_get64)
213	ALTENTRY(ddi_mem_rep_get64)
214	movq	ACC_REP_GETLL(%rdi), %rax
215	INDIRECT_JMP_REG(rax)
216	SET_SIZE(ddi_rep_get64)
217	SET_SIZE(ddi_mem_rep_get64)
218
219
220	ENTRY(ddi_rep_put8)
221	ALTENTRY(ddi_mem_rep_put8)
222	movq	ACC_REP_PUTB(%rdi), %rax
223	INDIRECT_JMP_REG(rax)
224	SET_SIZE(ddi_rep_put8)
225	SET_SIZE(ddi_mem_rep_put8)
226
227
228	ENTRY(ddi_rep_put16)
229	ALTENTRY(ddi_mem_rep_put16)
230	movq	ACC_REP_PUTW(%rdi), %rax
231	INDIRECT_JMP_REG(rax)
232	SET_SIZE(ddi_rep_put16)
233	SET_SIZE(ddi_mem_rep_put16)
234
235
236	ENTRY(ddi_rep_put32)
237	ALTENTRY(ddi_mem_rep_put32)
238	movq	ACC_REP_PUTL(%rdi), %rax
239	INDIRECT_JMP_REG(rax)
240	SET_SIZE(ddi_rep_put32)
241	SET_SIZE(ddi_mem_rep_put32)
242
243
244	ENTRY(ddi_rep_put64)
245	ALTENTRY(ddi_mem_rep_put64)
246	movq	ACC_REP_PUTLL(%rdi), %rax
247	INDIRECT_JMP_REG(rax)
248	SET_SIZE(ddi_rep_put64)
249	SET_SIZE(ddi_mem_rep_put64)
250
251	ENTRY(i_ddi_vaddr_get8)
252	movzbq	(%rsi), %rax
253	ret
254	SET_SIZE(i_ddi_vaddr_get8)
255
256	ENTRY(i_ddi_vaddr_get16)
257	movzwq	(%rsi), %rax
258	ret
259	SET_SIZE(i_ddi_vaddr_get16)
260
261
262	ENTRY(i_ddi_vaddr_get32)
263	movl	(%rsi), %eax
264	ret
265	SET_SIZE(i_ddi_vaddr_get32)
266
267
268	ENTRY(i_ddi_vaddr_get64)
269	movq	(%rsi), %rax
270	ret
271	SET_SIZE(i_ddi_vaddr_get64)
272
273
274	ENTRY(i_ddi_io_get8)
275	movq	%rsi, %rdx
276	inb	(%dx)
277	movzbq	%al, %rax
278	ret
279	SET_SIZE(i_ddi_io_get8)
280
281
282	ENTRY(i_ddi_io_get16)
283	movq	%rsi, %rdx
284	inw	(%dx)
285	movzwq	%ax, %rax
286	ret
287	SET_SIZE(i_ddi_io_get16)
288
289
290	ENTRY(i_ddi_io_get32)
291	movq	%rsi, %rdx
292	inl	(%dx)
293	ret
294	SET_SIZE(i_ddi_io_get32)
295
296	ENTRY(i_ddi_vaddr_put8)
297	movb	%dl, (%rsi)
298	ret
299	SET_SIZE(i_ddi_vaddr_put8)
300
301
302	ENTRY(i_ddi_vaddr_put16)
303	movw	%dx, (%rsi)
304	ret
305	SET_SIZE(i_ddi_vaddr_put16)
306
307
308	ENTRY(i_ddi_vaddr_put32)
309	movl	%edx, (%rsi)
310	ret
311	SET_SIZE(i_ddi_vaddr_put32)
312
313
314	ENTRY(i_ddi_vaddr_put64)
315	movq	%rdx, (%rsi)
316	ret
317	SET_SIZE(i_ddi_vaddr_put64)
318
319	ENTRY(i_ddi_io_put8)
320	movq	%rdx, %rax
321	movq	%rsi, %rdx
322	outb	(%dx)
323	ret
324	SET_SIZE(i_ddi_io_put8)
325
326
327	ENTRY(i_ddi_io_put16)
328	movq	%rdx, %rax
329	movq	%rsi, %rdx
330	outw	(%dx)
331	ret
332	SET_SIZE(i_ddi_io_put16)
333
334
335	ENTRY(i_ddi_io_put32)
336	movq	%rdx, %rax
337	movq	%rsi, %rdx
338	outl	(%dx)
339	ret
340	SET_SIZE(i_ddi_io_put32)
341
342	/*
343	 * Incoming arguments
344	 *
345	 * %rdi	: hdlp
346	 * %rsi	: host_addr
347	 * %rdx	: dev_addr
348	 * %rcx	: repcount
349	 * %r8	: flags
350	 *
351	 * This routine will destroy values in %rdx, %rsi, %rcx.
352	 */
353	ENTRY(i_ddi_io_rep_get8)
354
355	cmpq	$DDI_DEV_AUTOINCR, %r8
356	je	gb_ioadv
357	movq	%rsi, %rdi
358	rep
359	insb
360	ret
361
362gb_ioadv:
363	andq	%rcx, %rcx
364	jz	gb_ioadv_done
365gb_ioadv2:
366	inb	(%dx)
367	movb	%al, (%rsi)
368	incq	%rdx
369	incq	%rsi
370	decq	%rcx
371	jg	gb_ioadv2
372
373gb_ioadv_done:
374	rep;	ret	/* use 2 byte return instruction when branch target */
375			/* AMD Software Optimization Guide - Section 6.2 */
376
377	SET_SIZE(i_ddi_io_rep_get8)
378
379
380	ENTRY(i_ddi_io_rep_get16)
381
382	cmpq	$DDI_DEV_AUTOINCR, %r8
383	je	gw_ioadv
384
385	movq	%rsi, %rdi
386	rep
387	insw
388	ret
389
390gw_ioadv:
391	andq	%rcx, %rcx
392	jz	gw_ioadv_done
393gw_ioadv2:
394	inw	(%dx)
395	movw	%ax,(%rsi)
396	addq	$2, %rsi
397	addq	$2, %rdx
398	decq	%rcx
399	jg	gw_ioadv2
400
401gw_ioadv_done:
402	rep;	ret	/* use 2 byte return instruction when branch target */
403			/* AMD Software Optimization Guide - Section 6.2 */
404	SET_SIZE(i_ddi_io_rep_get16)
405
406
407	ENTRY(i_ddi_io_rep_get32)
408
409	cmpq	$DDI_DEV_AUTOINCR, %r8
410	je	gl_ioadv
411
412	movq	%rsi, %rdi
413	rep
414	insl
415	ret
416
417gl_ioadv:
418	andq	%rcx, %rcx
419	jz	gl_ioadv_done
420gl_ioadv2:
421	inl	(%dx)
422	movl	%eax,(%rsi)
423	addq	$4, %rsi
424	addq	$4, %rdx
425	decq	%rcx
426	jg	gl_ioadv2
427
428gl_ioadv_done:
429	rep;	ret	/* use 2 byte return instruction when branch target */
430			/* AMD Software Optimization Guide - Section 6.2 */
431
432	SET_SIZE(i_ddi_io_rep_get32)
433
434	/*
435	 * Incoming arguments
436	 *
437	 * %rdi	: hdlp
438	 * %rsi	: host_addr
439	 * %rdx	: dev_addr
440	 * %rcx	: repcount
441	 * %r8	: flags
442	 *
443	 * This routine will destroy values in %rdx, %rsi, %rcx.
444	 */
445	ENTRY(i_ddi_io_rep_put8)
446
447	cmpq	$DDI_DEV_AUTOINCR, %r8
448	je	pb_ioadv
449
450	movq	%rsi, %rdi
451	rep
452	outsb
453	ret
454
455pb_ioadv:
456	andq	%rcx, %rcx
457	jz	pb_ioadv_done
458pb_ioadv2:
459	movb	(%rsi), %al
460	outb	(%dx)
461	incq	%rsi
462	incq	%rdx
463	decq	%rcx
464	jg	pb_ioadv2
465
466pb_ioadv_done:
467	rep;	ret	/* use 2 byte return instruction when branch target */
468			/* AMD Software Optimization Guide - Section 6.2 */
469	SET_SIZE(i_ddi_io_rep_put8)
470
471	ENTRY(i_ddi_io_rep_put16)
472
473	cmpq	$DDI_DEV_AUTOINCR, %r8
474	je	pw_ioadv
475
476	movq	%rsi, %rdi
477	rep
478	outsw
479	ret
480
481pw_ioadv:
482	andq	%rcx, %rcx
483	jz	pw_ioadv_done
484pw_ioadv2:
485	movw	(%rsi), %ax
486	outw	(%dx)
487	addq	$2, %rsi
488	addq	$2, %rdx
489	decq	%rcx
490	jg	pw_ioadv2
491
492pw_ioadv_done:
493	rep;	ret	/* use 2 byte return instruction when branch target */
494			/* AMD Software Optimization Guide - Section 6.2 */
495	SET_SIZE(i_ddi_io_rep_put16)
496
497
498	ENTRY(i_ddi_io_rep_put32)
499
500	cmpq	$DDI_DEV_AUTOINCR, %r8
501	je	pl_ioadv
502
503	movq	%rsi, %rdi
504	rep
505	outsl
506	ret
507
508pl_ioadv:
509	andq	%rcx, %rcx
510	jz	pl_ioadv_done
511pl_ioadv2:
512	movl	(%rsi), %eax
513	outl	(%dx)
514	addq	$4, %rsi
515	addq	$4, %rdx
516	decq	%rcx
517	jg	pl_ioadv2
518
519pl_ioadv_done:
520	rep;	ret	/* use 2 byte return instruction when branch target */
521			/* AMD Software Optimization Guide - Section 6.2 */
522	SET_SIZE(i_ddi_io_rep_put32)
523