xref: /minix3/sys/arch/i386/stand/lib/bios_pci.S (revision 58a2b0008e28f606a7f7f5faaeaba4faac57a1ea)
1*58a2b000SEvgeniy Ivanov/*	$NetBSD: bios_pci.S,v 1.6 2005/12/11 12:17:48 christos Exp $	*/
2*58a2b000SEvgeniy Ivanov
3*58a2b000SEvgeniy Ivanov/*
4*58a2b000SEvgeniy Ivanov * Copyright (c) 1996
5*58a2b000SEvgeniy Ivanov *	Matthias Drochner.  All rights reserved.
6*58a2b000SEvgeniy Ivanov *
7*58a2b000SEvgeniy Ivanov * Redistribution and use in source and binary forms, with or without
8*58a2b000SEvgeniy Ivanov * modification, are permitted provided that the following conditions
9*58a2b000SEvgeniy Ivanov * are met:
10*58a2b000SEvgeniy Ivanov * 1. Redistributions of source code must retain the above copyright
11*58a2b000SEvgeniy Ivanov *    notice, this list of conditions and the following disclaimer.
12*58a2b000SEvgeniy Ivanov * 2. Redistributions in binary form must reproduce the above copyright
13*58a2b000SEvgeniy Ivanov *    notice, this list of conditions and the following disclaimer in the
14*58a2b000SEvgeniy Ivanov *    documentation and/or other materials provided with the distribution.
15*58a2b000SEvgeniy Ivanov *
16*58a2b000SEvgeniy Ivanov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*58a2b000SEvgeniy Ivanov * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*58a2b000SEvgeniy Ivanov * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*58a2b000SEvgeniy Ivanov * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*58a2b000SEvgeniy Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*58a2b000SEvgeniy Ivanov * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*58a2b000SEvgeniy Ivanov * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*58a2b000SEvgeniy Ivanov * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*58a2b000SEvgeniy Ivanov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*58a2b000SEvgeniy Ivanov * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*58a2b000SEvgeniy Ivanov *
27*58a2b000SEvgeniy Ivanov */
28*58a2b000SEvgeniy Ivanov
29*58a2b000SEvgeniy Ivanov/* minimal calls to PCI BIOS */
30*58a2b000SEvgeniy Ivanov
31*58a2b000SEvgeniy Ivanov#include <machine/asm.h>
32*58a2b000SEvgeniy Ivanov
33*58a2b000SEvgeniy Ivanov#define	addr32	.byte 0x67
34*58a2b000SEvgeniy Ivanov#define	data32	.byte 0x66
35*58a2b000SEvgeniy Ivanov
36*58a2b000SEvgeniy Ivanov#define PCI_FUNCTION_ID 0xb1
37*58a2b000SEvgeniy Ivanov#define PCI_BIOS_PRESENT 0x01
38*58a2b000SEvgeniy Ivanov#define FIND_PCI_DEVICE 0x02
39*58a2b000SEvgeniy Ivanov#define READ_CONFIG_DWORD 0x0a
40*58a2b000SEvgeniy Ivanov#define WRITE_CONFIG_DWORD 0x0d
41*58a2b000SEvgeniy Ivanov
42*58a2b000SEvgeniy Ivanov/* int pcibios_present(int *signature)
43*58a2b000SEvgeniy Ivanov    return: AX from BIOS call, -1 on error
44*58a2b000SEvgeniy Ivanov    var param: EDX from BIOS call, must be signature "PCI "
45*58a2b000SEvgeniy Ivanov*/
46*58a2b000SEvgeniy IvanovENTRY(pcibios_present)
47*58a2b000SEvgeniy Ivanov	pushl	%ebp
48*58a2b000SEvgeniy Ivanov	movl	%esp, %ebp
49*58a2b000SEvgeniy Ivanov	pushl	%ebx
50*58a2b000SEvgeniy Ivanov	pushl	%ecx
51*58a2b000SEvgeniy Ivanov	pushl	%edx
52*58a2b000SEvgeniy Ivanov
53*58a2b000SEvgeniy Ivanov	call	_C_LABEL(prot_to_real)	# enter real mode
54*58a2b000SEvgeniy Ivanov	.code16
55*58a2b000SEvgeniy Ivanov
56*58a2b000SEvgeniy Ivanov	movb	$PCI_FUNCTION_ID, %ah
57*58a2b000SEvgeniy Ivanov	movb	$PCI_BIOS_PRESENT, %al
58*58a2b000SEvgeniy Ivanov	int	$0x1a
59*58a2b000SEvgeniy Ivanov
60*58a2b000SEvgeniy Ivanov	jnc	ok1
61*58a2b000SEvgeniy Ivanov	movl	$-1, %ebx
62*58a2b000SEvgeniy Ivanov	jmp err1
63*58a2b000SEvgeniy Ivanov
64*58a2b000SEvgeniy Ivanovok1:
65*58a2b000SEvgeniy Ivanov	xorl	%ebx, %ebx
66*58a2b000SEvgeniy Ivanov	mov	%ax, %bx
67*58a2b000SEvgeniy Ivanoverr1:
68*58a2b000SEvgeniy Ivanov	calll	_C_LABEL(real_to_prot) # back to protected mode
69*58a2b000SEvgeniy Ivanov	.code32
70*58a2b000SEvgeniy Ivanov
71*58a2b000SEvgeniy Ivanov	movl	8(%ebp), %eax
72*58a2b000SEvgeniy Ivanov	movl	%edx, (%eax)
73*58a2b000SEvgeniy Ivanov
74*58a2b000SEvgeniy Ivanov	movl	%ebx, %eax		# return value in %eax
75*58a2b000SEvgeniy Ivanov
76*58a2b000SEvgeniy Ivanov	popl	%edx
77*58a2b000SEvgeniy Ivanov	popl	%ecx
78*58a2b000SEvgeniy Ivanov	popl	%ebx
79*58a2b000SEvgeniy Ivanov	popl	%ebp
80*58a2b000SEvgeniy Ivanov	ret
81*58a2b000SEvgeniy Ivanov
82*58a2b000SEvgeniy Ivanov/* int pcibios_finddev(int vendor, int device, int index, int *busdevfcn)
83*58a2b000SEvgeniy Ivanov    return: AH from BIOS call, -1 on error
84*58a2b000SEvgeniy Ivanov    var param: BX from BIOS call, contains bus/device/function
85*58a2b000SEvgeniy Ivanov*/
86*58a2b000SEvgeniy IvanovENTRY(pcibios_finddev)
87*58a2b000SEvgeniy Ivanov	pushl	%ebp
88*58a2b000SEvgeniy Ivanov	movl	%esp, %ebp
89*58a2b000SEvgeniy Ivanov	pushl	%ebx
90*58a2b000SEvgeniy Ivanov	pushl	%ecx
91*58a2b000SEvgeniy Ivanov	pushl	%edx
92*58a2b000SEvgeniy Ivanov	pushl	%esi
93*58a2b000SEvgeniy Ivanov
94*58a2b000SEvgeniy Ivanov	movl	8(%ebp), %edx
95*58a2b000SEvgeniy Ivanov	movl	12(%ebp), %ecx
96*58a2b000SEvgeniy Ivanov	movl	16(%ebp), %esi
97*58a2b000SEvgeniy Ivanov
98*58a2b000SEvgeniy Ivanov	call	_C_LABEL(prot_to_real)	# enter real mode
99*58a2b000SEvgeniy Ivanov	.code16
100*58a2b000SEvgeniy Ivanov
101*58a2b000SEvgeniy Ivanov	movb	$PCI_FUNCTION_ID, %ah
102*58a2b000SEvgeniy Ivanov	movb	$FIND_PCI_DEVICE, %al
103*58a2b000SEvgeniy Ivanov	int	$0x1a
104*58a2b000SEvgeniy Ivanov
105*58a2b000SEvgeniy Ivanov	jnc	ok2
106*58a2b000SEvgeniy Ivanov	movl	$-1, %edx
107*58a2b000SEvgeniy Ivanov	jmp err2
108*58a2b000SEvgeniy Ivanov
109*58a2b000SEvgeniy Ivanovok2:
110*58a2b000SEvgeniy Ivanov	movl	$0,%edx
111*58a2b000SEvgeniy Ivanov	movb	%ah, %dl
112*58a2b000SEvgeniy Ivanoverr2:
113*58a2b000SEvgeniy Ivanov	calll	_C_LABEL(real_to_prot) # back to protected mode
114*58a2b000SEvgeniy Ivanov	.code32
115*58a2b000SEvgeniy Ivanov
116*58a2b000SEvgeniy Ivanov	movl	20(%ebp), %eax
117*58a2b000SEvgeniy Ivanov	mov	%bx, (%eax)
118*58a2b000SEvgeniy Ivanov
119*58a2b000SEvgeniy Ivanov	movl	%edx, %eax		# return value in %eax
120*58a2b000SEvgeniy Ivanov
121*58a2b000SEvgeniy Ivanov	popl	%esi
122*58a2b000SEvgeniy Ivanov	popl	%edx
123*58a2b000SEvgeniy Ivanov	popl	%ecx
124*58a2b000SEvgeniy Ivanov	popl	%ebx
125*58a2b000SEvgeniy Ivanov	popl	%ebp
126*58a2b000SEvgeniy Ivanov	ret
127*58a2b000SEvgeniy Ivanov
128*58a2b000SEvgeniy Ivanov/* int pcibios_cfgread(int busdevfcn, int offset, int *value)
129*58a2b000SEvgeniy Ivanov    return: AH from BIOS call, -1 on error
130*58a2b000SEvgeniy Ivanov    var param: ECX from BIOS call, contains value read
131*58a2b000SEvgeniy Ivanov*/
132*58a2b000SEvgeniy IvanovENTRY(pcibios_cfgread)
133*58a2b000SEvgeniy Ivanov	pushl	%ebp
134*58a2b000SEvgeniy Ivanov	movl	%esp, %ebp
135*58a2b000SEvgeniy Ivanov	pushl	%ebx
136*58a2b000SEvgeniy Ivanov	pushl	%ecx
137*58a2b000SEvgeniy Ivanov	pushl	%edx
138*58a2b000SEvgeniy Ivanov	pushl	%edi
139*58a2b000SEvgeniy Ivanov
140*58a2b000SEvgeniy Ivanov	movl	8(%ebp), %ebx
141*58a2b000SEvgeniy Ivanov	movl	12(%ebp), %edi
142*58a2b000SEvgeniy Ivanov
143*58a2b000SEvgeniy Ivanov	call	_C_LABEL(prot_to_real)	# enter real mode
144*58a2b000SEvgeniy Ivanov	.code16
145*58a2b000SEvgeniy Ivanov
146*58a2b000SEvgeniy Ivanov	movb	$PCI_FUNCTION_ID, %ah
147*58a2b000SEvgeniy Ivanov	movb	$READ_CONFIG_DWORD, %al
148*58a2b000SEvgeniy Ivanov	int	$0x1a
149*58a2b000SEvgeniy Ivanov
150*58a2b000SEvgeniy Ivanov	jnc	ok3
151*58a2b000SEvgeniy Ivanov	movl	$-1, %edx
152*58a2b000SEvgeniy Ivanov	jmp err3
153*58a2b000SEvgeniy Ivanov
154*58a2b000SEvgeniy Ivanovok3:
155*58a2b000SEvgeniy Ivanov	movl	$0,%edx
156*58a2b000SEvgeniy Ivanov	movb	%ah, %dl
157*58a2b000SEvgeniy Ivanoverr3:
158*58a2b000SEvgeniy Ivanov	calll	_C_LABEL(real_to_prot) # back to protected mode
159*58a2b000SEvgeniy Ivanov	.code32
160*58a2b000SEvgeniy Ivanov
161*58a2b000SEvgeniy Ivanov	movl	16(%ebp), %eax
162*58a2b000SEvgeniy Ivanov	movl	%ecx, (%eax)
163*58a2b000SEvgeniy Ivanov
164*58a2b000SEvgeniy Ivanov	movl	%edx, %eax		# return value in %eax
165*58a2b000SEvgeniy Ivanov
166*58a2b000SEvgeniy Ivanov	popl	%edi
167*58a2b000SEvgeniy Ivanov	popl	%edx
168*58a2b000SEvgeniy Ivanov	popl	%ecx
169*58a2b000SEvgeniy Ivanov	popl	%ebx
170*58a2b000SEvgeniy Ivanov	popl	%ebp
171*58a2b000SEvgeniy Ivanov	ret
172*58a2b000SEvgeniy Ivanov
173*58a2b000SEvgeniy Ivanov/* int pcibios_cfgwrite(int busdevfcn, int offset, int value)
174*58a2b000SEvgeniy Ivanov    return: AH from BIOS call, -1 on error
175*58a2b000SEvgeniy Ivanov    var param: ECX from BIOS call, contains value read
176*58a2b000SEvgeniy Ivanov*/
177*58a2b000SEvgeniy IvanovENTRY(pcibios_cfgwrite)
178*58a2b000SEvgeniy Ivanov	pushl	%ebp
179*58a2b000SEvgeniy Ivanov	movl	%esp, %ebp
180*58a2b000SEvgeniy Ivanov	pushl	%ebx
181*58a2b000SEvgeniy Ivanov	pushl	%ecx
182*58a2b000SEvgeniy Ivanov	pushl	%edx
183*58a2b000SEvgeniy Ivanov	pushl	%edi
184*58a2b000SEvgeniy Ivanov
185*58a2b000SEvgeniy Ivanov	movl	8(%ebp), %ebx
186*58a2b000SEvgeniy Ivanov	movl	12(%ebp), %edi
187*58a2b000SEvgeniy Ivanov	movl	16(%ebp), %ecx
188*58a2b000SEvgeniy Ivanov
189*58a2b000SEvgeniy Ivanov	call	_C_LABEL(prot_to_real)	# enter real mode
190*58a2b000SEvgeniy Ivanov	.code16
191*58a2b000SEvgeniy Ivanov
192*58a2b000SEvgeniy Ivanov	movb	$PCI_FUNCTION_ID, %ah
193*58a2b000SEvgeniy Ivanov	movb	$WRITE_CONFIG_DWORD, %al
194*58a2b000SEvgeniy Ivanov	int	$0x1a
195*58a2b000SEvgeniy Ivanov
196*58a2b000SEvgeniy Ivanov	jnc	ok4
197*58a2b000SEvgeniy Ivanov	movl	$-1, %edx
198*58a2b000SEvgeniy Ivanov	jmp err4
199*58a2b000SEvgeniy Ivanov
200*58a2b000SEvgeniy Ivanovok4:
201*58a2b000SEvgeniy Ivanov	movl	$0,%edx
202*58a2b000SEvgeniy Ivanov	movb	%ah, %dl
203*58a2b000SEvgeniy Ivanoverr4:
204*58a2b000SEvgeniy Ivanov	calll	_C_LABEL(real_to_prot) # back to protected mode
205*58a2b000SEvgeniy Ivanov	.code32
206*58a2b000SEvgeniy Ivanov
207*58a2b000SEvgeniy Ivanov	movl	%edx, %eax		# return value in %eax
208*58a2b000SEvgeniy Ivanov
209*58a2b000SEvgeniy Ivanov	popl	%edi
210*58a2b000SEvgeniy Ivanov	popl	%edx
211*58a2b000SEvgeniy Ivanov	popl	%ecx
212*58a2b000SEvgeniy Ivanov	popl	%ebx
213*58a2b000SEvgeniy Ivanov	popl	%ebp
214*58a2b000SEvgeniy Ivanov	ret
215