]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/x86/lib/bios_pci.S
cosmetic: checkpatch cleanup of arch/x86/lib/*.c
[karo-tx-uboot.git] / arch / x86 / lib / bios_pci.S
1 /*
2  * (C) Copyright 2002
3  * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * x86 realmode assembly implementation of a PCI BIOS
26  * for platforms that use one PCI hose and configuration
27  * access type 1. (The common case for low-end PC's)
28  */
29
30 #include "bios.h"
31
32 #define PCI_BIOS_DEBUG
33
34 .section .bios, "ax"
35 .code16
36 .globl realmode_pci_bios_call_entry
37 .hidden realmode_pci_bios_call_entry
38 .type realmode_pci_bios_call_entry, @function
39 realmode_pci_bios_call_entry:
40         MAKE_BIOS_STACK
41         call realmode_pci_bios
42         RESTORE_CALLERS_STACK
43         ret
44
45
46 .globl realmode_pci_bios
47 realmode_pci_bios:
48 gs      movw    OFFS_AX(%bp), %ax
49         cmpb    $1, %al
50         je      pci_bios_present
51         cmpb    $2, %al
52         je      pci_bios_find_device
53         cmpb    $3, %al
54         je      pci_bios_find_class
55         cmpb    $6, %al
56         je      pci_bios_generate_special_cycle
57         cmpb    $8, %al
58         je      pci_bios_read_cfg_byte
59         cmpb    $9, %al
60         je      pci_bios_read_cfg_word
61         cmpb    $10, %al
62         je      pci_bios_read_cfg_dword
63         cmpb    $11, %al
64         je      pci_bios_write_cfg_byte
65         cmpb    $12, %al
66         je      pci_bios_write_cfg_word
67         cmpb    $13, %al
68         je      pci_bios_write_cfg_dword
69         cmpb    $14, %al
70         je      pci_bios_get_irq_routing
71         cmpb    $15, %al
72         je      pci_bios_set_irq
73         jmp     unknown_function
74
75 /*****************************************************************************/
76
77 pci_bios_present:
78 #ifdef PCI_BIOS_DEBUG
79 cs      incl    num_pci_bios_present
80 #endif
81         movl    $0x20494350, %eax
82 gs      movl    %eax, OFFS_EDX(%bp)
83
84         /* We support cfg type 1 version 2.10 */
85         movb    $0x01, %al
86 gs      movb    %al, OFFS_AL(%bp)
87         movw    $0x0210, %ax
88 gs      movw    %ax, OFFS_BX(%bp)
89
90         /* last bus number */
91 cs      movb    pci_last_bus, %al
92 gs      movb    %al, OFFS_CL(%bp)
93         jmp     clear_carry
94
95 /*****************************************************************************/
96
97 /* device 0-31, function 0-7 */
98 pci_bios_find_device:
99 #ifdef PCI_BIOS_DEBUG
100 cs      incl    num_pci_bios_find_device
101 #endif
102 gs      movw    OFFS_CX(%bp), %di
103         shll    $16, %edi
104 gs      movw    OFFS_DX(%bp), %di
105         /* edi now holds device in upper 16 bits and vendor in lower 16 bits */
106
107 gs      movw    OFFS_SI(%bp), %si
108
109         /* start at bus 0 dev 0 function 0 */
110         xorw    %bx, %bx
111 pfd_loop:
112         /* dword 0 is vendor/device */
113         xorw    %ax, %ax
114         call    __pci_bios_select_register
115         movw    $0xcfc, %dx
116         inl     %dx, %eax
117
118         /* our device ? */
119         cmpl    %edi, %eax
120         je      pfd_found_one
121 pfd_next_dev:
122         /* check for multi function devices */
123         movw    %bx, %ax
124         andw    $3, %ax
125         jnz     pfd_function_not_zero
126         movw    $0x000c, %ax
127         call    __pci_bios_select_register
128         movw    $0xcfe, %dx
129         inb     %dx, %al
130         andb    $0x80, %al
131         jz      pfd_not_multi_function
132 pfd_function_not_zero:
133         /* next function, overflows in to device number, then bus number */
134         incw    %bx
135         jmp     pfd_check_bus
136
137 pfd_not_multi_function:
138         /* remove function bits */
139         andw    $0xfff8, %bx
140
141         /* next device, overflows in to bus number */
142         addw    $0x0008, %bx
143 pfd_check_bus:
144 cs      movb    pci_last_bus, %ah
145         cmpb    %ah, %bh
146         ja      pfd_not_found
147         jmp     pfd_loop
148 pfd_found_one:
149         decw    %si
150         js      pfd_done
151         jmp     pfd_next_dev
152
153 pfd_done:
154 gs      movw    %bx, OFFS_BX(%bp)
155         jmp     clear_carry
156
157 pfd_not_found:
158         /* device not found */
159         movb    $0x86, %ah
160         jmp     set_carry
161
162 /*****************************************************************************/
163
164 pci_bios_find_class:
165 #ifdef PCI_BIOS_DEBUG
166 cs      incl    num_pci_bios_find_class
167 #endif
168 gs      movl    OFFS_ECX(%bp), %edi
169
170         /* edi now holds class-code in lower 24 bits */
171         andl    $0x00ffffff, %edi
172 gs      movw    OFFS_SI(%bp), %si
173
174         /* start at bus 0 dev 0 function 0 */
175         xorw    %bx, %bx
176 pfc_loop:
177         /* dword 8 is class-code high 24bits */
178         movw    $8, %ax
179         call    __pci_bios_select_register
180         movw    $0xcfc, %dx
181         inl     %dx, %eax
182         shrl    $8, %eax
183         andl    $0x00ffffff, %eax
184
185         /* our device ? */
186         cmpl    %edi, %eax
187         je      pfc_found_one
188 pfc_next_dev:
189         /* check for multi function devices */
190         andw    $3, %bx
191         jnz     pfc_function_not_zero
192         movw    $0x000c, %ax
193         call    __pci_bios_select_register
194         movw    $0xcfe, %dx
195         inb     %dx, %al
196         andb    $0x80, %al
197         jz      pfc_not_multi_function
198 pfc_function_not_zero:
199         /* next function, overflows in to device number, then bus number */
200         incw    %bx
201         jmp     pfc_check_bus
202
203 pfc_not_multi_function:
204         /* remove function bits */
205         andw    $0xfff8, %bx
206
207         /* next device, overflows in to bus number */
208         addw    $0x0008, %bx
209 pfc_check_bus:
210 cs      movb    pci_last_bus, %ah
211         cmpb    %ah, %bh
212         ja      pfc_not_found
213         jmp     pfc_loop
214 pfc_found_one:
215         decw    %si
216         js      pfc_done
217         jmp     pfc_next_dev
218
219 pfc_done:
220 gs      movw    %bx, OFFS_BX(%bp)
221         jmp     clear_carry
222
223 pfc_not_found:
224         /* device not found */
225         movb    $0x86, %ah
226         jmp     set_carry
227
228 /*****************************************************************************/
229
230 pci_bios_generate_special_cycle:
231 #ifdef PCI_BIOS_DEBUG
232 cs      incl    num_pci_bios_generate_special_cycle
233 #endif
234         /* function not supported */
235         movb    $0x81, %ah
236         jmp     set_carry
237
238 /*****************************************************************************/
239
240 pci_bios_read_cfg_byte:
241 #ifdef PCI_BIOS_DEBUG
242 cs      incl    num_pci_bios_read_cfg_byte
243 #endif
244         call    pci_bios_select_register
245 gs      movw    OFFS_DI(%bp), %dx
246         andw    $3, %dx
247         addw    $0xcfc, %dx
248         inb     %dx, %al
249 gs      movb    %al, OFFS_CL(%bp)
250         jmp     clear_carry
251
252 /*****************************************************************************/
253
254 pci_bios_read_cfg_word:
255 #ifdef PCI_BIOS_DEBUG
256 cs      incl    num_pci_bios_read_cfg_word
257 #endif
258         call    pci_bios_select_register
259 gs      movw    OFFS_DI(%bp), %dx
260         andw    $2, %dx
261         addw    $0xcfc, %dx
262         inw     %dx, %ax
263 gs      movw    %ax, OFFS_CX(%bp)
264         jmp     clear_carry
265
266
267 /*****************************************************************************/
268
269 pci_bios_read_cfg_dword:
270 #ifdef PCI_BIOS_DEBUG
271 cs      incl    num_pci_bios_read_cfg_dword
272 #endif
273         call    pci_bios_select_register
274         movw    $0xcfc, %dx
275         inl     %dx, %eax
276 gs      movl    %eax, OFFS_ECX(%bp)
277         jmp     clear_carry
278
279 /*****************************************************************************/
280
281 pci_bios_write_cfg_byte:
282 #ifdef PCI_BIOS_DEBUG
283 cs      incl    num_pci_bios_write_cfg_byte
284 #endif
285         call    pci_bios_select_register
286 gs      movw    OFFS_DI(%bp), %dx
287 gs      movb    OFFS_CL(%bp), %al
288         andw    $3, %dx
289         addw    $0xcfc, %dx
290         outb    %al, %dx
291         jmp     clear_carry
292
293 /*****************************************************************************/
294
295 pci_bios_write_cfg_word:
296 #ifdef PCI_BIOS_DEBUG
297 cs      incl    num_pci_bios_write_cfg_word
298 #endif
299         call    pci_bios_select_register
300 gs      movw    OFFS_DI(%bp), %dx
301 gs      movw    OFFS_CX(%bp), %ax
302         andw    $2, %dx
303         addw    $0xcfc, %dx
304         outw    %ax, %dx
305         jmp     clear_carry
306
307 /*****************************************************************************/
308
309 pci_bios_write_cfg_dword:
310 #ifdef PCI_BIOS_DEBUG
311 cs      incl    num_pci_bios_write_cfg_dword
312 #endif
313         call    pci_bios_select_register
314 gs      movl    OFFS_ECX(%bp), %eax
315         movw    $0xcfc, %dx
316         outl    %eax, %dx
317         jmp     clear_carry
318
319 /*****************************************************************************/
320
321 pci_bios_get_irq_routing:
322 #ifdef PCI_BIOS_DEBUG
323 cs      incl    num_pci_bios_get_irq_routing
324 #endif
325         /* function not supported */
326         movb    $0x81, %ah
327         jmp     set_carry
328
329 /*****************************************************************************/
330
331 pci_bios_set_irq:
332 #ifdef PCI_BIOS_DEBUG
333 cs      incl    num_pci_bios_set_irq
334 #endif
335         /* function not supported */
336         movb    $0x81, %ah
337         jmp     set_carry
338
339 /*****************************************************************************/
340
341 unknown_function:
342 #ifdef PCI_BIOS_DEBUG
343 cs      incl    num_pci_bios_unknown_function
344 #endif
345         /* function not supported */
346         movb    $0x81, %ah
347         jmp     set_carry
348
349 /*****************************************************************************/
350
351 pci_bios_select_register:
352 gs      movw    OFFS_BX(%bp), %bx
353 gs      movw    OFFS_DI(%bp), %ax
354 /* destroys eax, dx */
355 __pci_bios_select_register:
356         /* BX holds device id, AX holds register index */
357         pushl   %ebx
358         andl    $0xfc, %eax
359         andl    $0xffff, %ebx
360         shll    $8, %ebx
361         orl     %ebx, %eax
362         orl     $0x80000000, %eax
363         movw    $0xcf8, %dx
364         outl    %eax, %dx
365         popl    %ebx
366         ret
367
368
369 clear_carry:
370 gs      movw    OFFS_FLAGS(%bp), %ax
371
372         /* clear carry -- function succeeded */
373         andw    $0xfffe, %ax
374 gs      movw    %ax, OFFS_FLAGS(%bp)
375         xorw    %ax, %ax
376 gs      movb    %ah, OFFS_AH(%bp)
377         ret
378
379 set_carry:
380 gs      movb    %ah, OFFS_AH(%bp)
381 gs      movw    OFFS_FLAGS(%bp), %ax
382
383         /* return carry -- function not supported */
384         orw     $1, %ax
385 gs      movw    %ax, OFFS_FLAGS(%bp)
386         movw    $-1, %ax
387         ret
388
389 /*****************************************************************************/
390
391 .globl pci_last_bus
392 pci_last_bus:
393         .byte   0
394
395 #ifdef PCI_BIOS_DEBUG
396 .globl num_pci_bios_present
397 num_pci_bios_present:
398         .long   0
399
400 .globl num_pci_bios_find_device
401 num_pci_bios_find_device:
402         .long   0
403
404 .globl num_pci_bios_find_class
405 num_pci_bios_find_class:
406         .long   0
407
408 .globl num_pci_bios_generate_special_cycle
409 num_pci_bios_generate_special_cycle:
410         .long 0
411
412 .globl num_pci_bios_read_cfg_byte
413 num_pci_bios_read_cfg_byte:
414         .long   0
415
416 .globl num_pci_bios_read_cfg_word
417 num_pci_bios_read_cfg_word:
418         .long   0
419
420 .globl num_pci_bios_read_cfg_dword
421 num_pci_bios_read_cfg_dword:
422         .long   0
423
424 .globl num_pci_bios_write_cfg_byte
425 num_pci_bios_write_cfg_byte:
426         .long   0
427
428 .globl num_pci_bios_write_cfg_word
429 num_pci_bios_write_cfg_word:
430         .long   0
431
432 .globl num_pci_bios_write_cfg_dword
433 num_pci_bios_write_cfg_dword:
434         .long   0
435
436 .globl num_pci_bios_get_irq_routing
437 num_pci_bios_get_irq_routing:
438         .long   0
439
440 .globl num_pci_bios_set_irq
441 num_pci_bios_set_irq:
442         .long   0
443
444 .globl num_pci_bios_unknown_function
445 num_pci_bios_unknown_function:
446         .long   0
447 #endif