Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / i386 / interface / pcbios / pcibios.c
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdint.h>
23 #include <ipxe/pci.h>
24 #include <realmode.h>
25
26 /** @file
27  *
28  * PCI configuration space access via PCI BIOS
29  *
30  */
31
32 /**
33  * Determine number of PCI buses within system
34  *
35  * @ret num_bus         Number of buses
36  */
37 static int pcibios_num_bus ( void ) {
38         int discard_a, discard_D;
39         uint8_t max_bus;
40
41         __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
42                                            "int $0x1a\n\t"
43                                            "jnc 1f\n\t"
44                                            "xorw %%cx, %%cx\n\t"
45                                            "\n1:\n\t" )
46                                : "=c" ( max_bus ), "=a" ( discard_a ),
47                                  "=D" ( discard_D )
48                                : "a" ( PCIBIOS_INSTALLATION_CHECK >> 16 ),
49                                  "D" ( 0 )
50                                : "ebx", "edx" );
51
52         return ( max_bus + 1 );
53 }
54
55 /**
56  * Read configuration space via PCI BIOS
57  *
58  * @v pci       PCI device
59  * @v command   PCI BIOS command
60  * @v value     Value read
61  * @ret rc      Return status code
62  */
63 int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){
64         int discard_b, discard_D;
65         int status;
66
67         __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
68                                            "int $0x1a\n\t"
69                                            "jnc 1f\n\t"
70                                            "xorl %%eax, %%eax\n\t"
71                                            "decl %%eax\n\t"
72                                            "movl %%eax, %%ecx\n\t"
73                                            "\n1:\n\t" )
74                                : "=a" ( status ), "=b" ( discard_b ),
75                                  "=c" ( *value ), "=D" ( discard_D )
76                                : "a" ( command >> 16 ), "D" ( command ),
77                                  "b" ( pci->busdevfn )
78                                : "edx" );
79
80         return ( ( status >> 8 ) & 0xff );
81 }
82
83 /**
84  * Write configuration space via PCI BIOS
85  *
86  * @v pci       PCI device
87  * @v command   PCI BIOS command
88  * @v value     Value to be written
89  * @ret rc      Return status code
90  */
91 int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
92         int discard_b, discard_c, discard_D;
93         int status;
94
95         __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
96                                            "int $0x1a\n\t"
97                                            "jnc 1f\n\t"
98                                            "movb $0xff, %%ah\n\t"
99                                            "\n1:\n\t" )
100                                : "=a" ( status ), "=b" ( discard_b ),
101                                  "=c" ( discard_c ), "=D" ( discard_D )
102                                : "a" ( command >> 16 ), "D" ( command ),
103                                  "b" ( pci->busdevfn ), "c" ( value )
104                                : "edx" );
105         
106         return ( ( status >> 8 ) & 0xff );
107 }
108
109 PROVIDE_PCIAPI ( pcbios, pci_num_bus, pcibios_num_bus );
110 PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte );
111 PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word );
112 PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_dword );
113 PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte );
114 PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word );
115 PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );