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., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
17 | */ |
---|
18 | |
---|
19 | FILE_LICENCE ( GPL2_OR_LATER ); |
---|
20 | |
---|
21 | #include <stdint.h> |
---|
22 | #include <gpxe/pci.h> |
---|
23 | #include <realmode.h> |
---|
24 | |
---|
25 | /** @file |
---|
26 | * |
---|
27 | * PCI configuration space access via PCI BIOS |
---|
28 | * |
---|
29 | */ |
---|
30 | |
---|
31 | /** |
---|
32 | * Determine maximum PCI bus number within system |
---|
33 | * |
---|
34 | * @ret max_bus Maximum bus number |
---|
35 | */ |
---|
36 | static int pcibios_max_bus ( void ) { |
---|
37 | int discard_a, discard_D; |
---|
38 | uint8_t max_bus; |
---|
39 | |
---|
40 | __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" |
---|
41 | "int $0x1a\n\t" |
---|
42 | "jnc 1f\n\t" |
---|
43 | "xorw %%cx, %%cx\n\t" |
---|
44 | "\n1:\n\t" ) |
---|
45 | : "=c" ( max_bus ), "=a" ( discard_a ), |
---|
46 | "=D" ( discard_D ) |
---|
47 | : "a" ( PCIBIOS_INSTALLATION_CHECK >> 16 ), |
---|
48 | "D" ( 0 ) |
---|
49 | : "ebx", "edx" ); |
---|
50 | |
---|
51 | return max_bus; |
---|
52 | } |
---|
53 | |
---|
54 | /** |
---|
55 | * Read configuration space via PCI BIOS |
---|
56 | * |
---|
57 | * @v pci PCI device |
---|
58 | * @v command PCI BIOS command |
---|
59 | * @v value Value read |
---|
60 | * @ret rc Return status code |
---|
61 | */ |
---|
62 | int pcibios_read ( struct pci_device *pci, uint32_t command, uint32_t *value ){ |
---|
63 | int discard_b, discard_D; |
---|
64 | int status; |
---|
65 | |
---|
66 | __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" |
---|
67 | "int $0x1a\n\t" |
---|
68 | "jnc 1f\n\t" |
---|
69 | "xorl %%eax, %%eax\n\t" |
---|
70 | "decl %%eax\n\t" |
---|
71 | "movl %%eax, %%ecx\n\t" |
---|
72 | "\n1:\n\t" ) |
---|
73 | : "=a" ( status ), "=b" ( discard_b ), |
---|
74 | "=c" ( *value ), "=D" ( discard_D ) |
---|
75 | : "a" ( command >> 16 ), "D" ( command ), |
---|
76 | "b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) ) |
---|
77 | : "edx" ); |
---|
78 | |
---|
79 | return ( ( status >> 8 ) & 0xff ); |
---|
80 | } |
---|
81 | |
---|
82 | /** |
---|
83 | * Write configuration space via PCI BIOS |
---|
84 | * |
---|
85 | * @v pci PCI device |
---|
86 | * @v command PCI BIOS command |
---|
87 | * @v value Value to be written |
---|
88 | * @ret rc Return status code |
---|
89 | */ |
---|
90 | int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){ |
---|
91 | int discard_b, discard_c, discard_D; |
---|
92 | int status; |
---|
93 | |
---|
94 | __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" |
---|
95 | "int $0x1a\n\t" |
---|
96 | "jnc 1f\n\t" |
---|
97 | "movb $0xff, %%ah\n\t" |
---|
98 | "\n1:\n\t" ) |
---|
99 | : "=a" ( status ), "=b" ( discard_b ), |
---|
100 | "=c" ( discard_c ), "=D" ( discard_D ) |
---|
101 | : "a" ( command >> 16 ), "D" ( command ), |
---|
102 | "b" ( PCI_BUSDEVFN ( pci->bus, pci->devfn ) ), |
---|
103 | "c" ( value ) |
---|
104 | : "edx" ); |
---|
105 | |
---|
106 | return ( ( status >> 8 ) & 0xff ); |
---|
107 | } |
---|
108 | |
---|
109 | PROVIDE_PCIAPI ( pcbios, pci_max_bus, pcibios_max_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 ); |
---|