3 * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
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)
32 #define PCI_BIOS_DEBUG
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:
41 call realmode_pci_bios
46 .globl realmode_pci_bios
48 gs movw OFFS_AX(%bp), %ax
52 je pci_bios_find_device
54 je pci_bios_find_class
56 je pci_bios_generate_special_cycle
58 je pci_bios_read_cfg_byte
60 je pci_bios_read_cfg_word
62 je pci_bios_read_cfg_dword
64 je pci_bios_write_cfg_byte
66 je pci_bios_write_cfg_word
68 je pci_bios_write_cfg_dword
70 je pci_bios_get_irq_routing
75 /*****************************************************************************/
79 cs incl num_pci_bios_present
81 movl $0x20494350, %eax
82 gs movl %eax, OFFS_EDX(%bp)
84 /* We support cfg type 1 version 2.10 */
86 gs movb %al, OFFS_AL(%bp)
88 gs movw %ax, OFFS_BX(%bp)
91 cs movb pci_last_bus, %al
92 gs movb %al, OFFS_CL(%bp)
95 /*****************************************************************************/
97 /* device 0-31, function 0-7 */
100 cs incl num_pci_bios_find_device
102 gs movw OFFS_CX(%bp), %di
104 gs movw OFFS_DX(%bp), %di
105 /* edi now holds device in upper 16 bits and vendor in lower 16 bits */
107 gs movw OFFS_SI(%bp), %si
109 /* start at bus 0 dev 0 function 0 */
112 /* dword 0 is vendor/device */
114 call __pci_bios_select_register
122 /* check for multi function devices */
125 jnz pfd_function_not_zero
127 call __pci_bios_select_register
131 jz pfd_not_multi_function
132 pfd_function_not_zero:
133 /* next function, overflows in to device number, then bus number */
137 pfd_not_multi_function:
138 /* remove function bits */
141 /* next device, overflows in to bus number */
144 cs movb pci_last_bus, %ah
154 gs movw %bx, OFFS_BX(%bp)
158 /* device not found */
162 /*****************************************************************************/
165 #ifdef PCI_BIOS_DEBUG
166 cs incl num_pci_bios_find_class
168 gs movl OFFS_ECX(%bp), %edi
170 /* edi now holds class-code in lower 24 bits */
171 andl $0x00ffffff, %edi
172 gs movw OFFS_SI(%bp), %si
174 /* start at bus 0 dev 0 function 0 */
177 /* dword 8 is class-code high 24bits */
179 call __pci_bios_select_register
183 andl $0x00ffffff, %eax
189 /* check for multi function devices */
191 jnz pfc_function_not_zero
193 call __pci_bios_select_register
197 jz pfc_not_multi_function
198 pfc_function_not_zero:
199 /* next function, overflows in to device number, then bus number */
203 pfc_not_multi_function:
204 /* remove function bits */
207 /* next device, overflows in to bus number */
210 cs movb pci_last_bus, %ah
220 gs movw %bx, OFFS_BX(%bp)
224 /* device not found */
228 /*****************************************************************************/
230 pci_bios_generate_special_cycle:
231 #ifdef PCI_BIOS_DEBUG
232 cs incl num_pci_bios_generate_special_cycle
234 /* function not supported */
238 /*****************************************************************************/
240 pci_bios_read_cfg_byte:
241 #ifdef PCI_BIOS_DEBUG
242 cs incl num_pci_bios_read_cfg_byte
244 call pci_bios_select_register
245 gs movw OFFS_DI(%bp), %dx
249 gs movb %al, OFFS_CL(%bp)
252 /*****************************************************************************/
254 pci_bios_read_cfg_word:
255 #ifdef PCI_BIOS_DEBUG
256 cs incl num_pci_bios_read_cfg_word
258 call pci_bios_select_register
259 gs movw OFFS_DI(%bp), %dx
263 gs movw %ax, OFFS_CX(%bp)
267 /*****************************************************************************/
269 pci_bios_read_cfg_dword:
270 #ifdef PCI_BIOS_DEBUG
271 cs incl num_pci_bios_read_cfg_dword
273 call pci_bios_select_register
276 gs movl %eax, OFFS_ECX(%bp)
279 /*****************************************************************************/
281 pci_bios_write_cfg_byte:
282 #ifdef PCI_BIOS_DEBUG
283 cs incl num_pci_bios_write_cfg_byte
285 call pci_bios_select_register
286 gs movw OFFS_DI(%bp), %dx
287 gs movb OFFS_CL(%bp), %al
293 /*****************************************************************************/
295 pci_bios_write_cfg_word:
296 #ifdef PCI_BIOS_DEBUG
297 cs incl num_pci_bios_write_cfg_word
299 call pci_bios_select_register
300 gs movw OFFS_DI(%bp), %dx
301 gs movw OFFS_CX(%bp), %ax
307 /*****************************************************************************/
309 pci_bios_write_cfg_dword:
310 #ifdef PCI_BIOS_DEBUG
311 cs incl num_pci_bios_write_cfg_dword
313 call pci_bios_select_register
314 gs movl OFFS_ECX(%bp), %eax
319 /*****************************************************************************/
321 pci_bios_get_irq_routing:
322 #ifdef PCI_BIOS_DEBUG
323 cs incl num_pci_bios_get_irq_routing
325 /* function not supported */
329 /*****************************************************************************/
332 #ifdef PCI_BIOS_DEBUG
333 cs incl num_pci_bios_set_irq
335 /* function not supported */
339 /*****************************************************************************/
342 #ifdef PCI_BIOS_DEBUG
343 cs incl num_pci_bios_unknown_function
345 /* function not supported */
349 /*****************************************************************************/
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 */
362 orl $0x80000000, %eax
370 gs movw OFFS_FLAGS(%bp), %ax
372 /* clear carry -- function succeeded */
374 gs movw %ax, OFFS_FLAGS(%bp)
376 gs movb %ah, OFFS_AH(%bp)
380 gs movb %ah, OFFS_AH(%bp)
381 gs movw OFFS_FLAGS(%bp), %ax
383 /* return carry -- function not supported */
385 gs movw %ax, OFFS_FLAGS(%bp)
389 /*****************************************************************************/
395 #ifdef PCI_BIOS_DEBUG
396 .globl num_pci_bios_present
397 num_pci_bios_present:
400 .globl num_pci_bios_find_device
401 num_pci_bios_find_device:
404 .globl num_pci_bios_find_class
405 num_pci_bios_find_class:
408 .globl num_pci_bios_generate_special_cycle
409 num_pci_bios_generate_special_cycle:
412 .globl num_pci_bios_read_cfg_byte
413 num_pci_bios_read_cfg_byte:
416 .globl num_pci_bios_read_cfg_word
417 num_pci_bios_read_cfg_word:
420 .globl num_pci_bios_read_cfg_dword
421 num_pci_bios_read_cfg_dword:
424 .globl num_pci_bios_write_cfg_byte
425 num_pci_bios_write_cfg_byte:
428 .globl num_pci_bios_write_cfg_word
429 num_pci_bios_write_cfg_word:
432 .globl num_pci_bios_write_cfg_dword
433 num_pci_bios_write_cfg_dword:
436 .globl num_pci_bios_get_irq_routing
437 num_pci_bios_get_irq_routing:
440 .globl num_pci_bios_set_irq
441 num_pci_bios_set_irq:
444 .globl num_pci_bios_unknown_function
445 num_pci_bios_unknown_function: