2f3a9ac0dcaec7d78cf4d9a9286232c250de2f0c
[gpxe.git] / src / arch / i386 / core / pci_io.c
1 /*
2 ** Support for NE2000 PCI clones added David Monro June 1997
3 ** Generalised to other NICs by Ken Yap July 1997
4 **
5 ** Most of this is taken from:
6 **
7 ** /usr/src/linux/drivers/pci/pci.c
8 ** /usr/src/linux/include/linux/pci.h
9 ** /usr/src/linux/arch/i386/bios32.c
10 ** /usr/src/linux/include/linux/bios32.h
11 ** /usr/src/linux/drivers/net/ne.c
12 */
13 #include "etherboot.h"
14 #include <gpxe/init.h>
15 #include <gpxe/pci.h>
16 #include "pci_io.h"
17 #ifdef KEEP_IT_REAL
18 #include "realmode.h"
19 #endif
20
21 /* Macros for direct PCI access */
22 #define CONFIG_ADDRESS  0xcf8
23 #define CONFIG_DATA     0xcfc
24 #define CONFIG_CMD( pci, where )                                        \
25         ( 0x80000000 | ( pci->bus << 16 ) | ( pci->devfn << 8 ) |       \
26           ( where & ~3 ) )
27
28 /* Signatures for PCI BIOS */
29 #define BIOS_SIG(a,b,c,d)       ( ( a<<0 ) + ( b<<8 ) + ( c<<16 ) + ( d<<24 ) )
30 #define PRINT_BIOS_SIG(x)       ( (x) & 0xff ), ( ( (x)>>8 ) & 0xff ), \
31                                 ( ( (x)>>16 ) & 0xff ),( ( (x)>>24 ) & 0xff )
32 #define BIOS32_SIGNATURE        BIOS_SIG ( '_', '3', '2', '_' )
33 #define PCI_SIGNATURE           BIOS_SIG ( 'P', 'C', 'I', ' ' )
34 #define PCI_SERVICE             BIOS_SIG ( '$', 'P', 'C', 'I' )
35
36 /* BIOS32 structure as found in PCI BIOS ROM */
37 struct bios32 {
38         unsigned long signature;        /* _32_ */
39         unsigned long entry;            /* 32 bit physical address */
40         unsigned char revision;         /* Revision level, 0 */
41         unsigned char length;           /* Length in paragraphs */
42         unsigned char checksum;         /* Should byte sum to zero */
43         unsigned char reserved[5];      /* Must be zero */
44 };
45
46 /* Values returned by BIOS32 service directory */
47 #define BIOS32_SERVICE_PRESENT          0x00
48 #define BIOS32_SERVICE_NOT_PRESENT      0x80
49 #define CF ( 1 << 0 )
50
51 /* PCI BIOS entry point */
52 #ifndef KEEP_IT_REAL
53 static unsigned long pcibios32_entry;
54 #endif
55 static int have_pcibios;
56
57 /* Macro for calling a 32-bit entry point with flat physical
58  * addresses.  Use in a statement such as
59  * __asm__ ( FLAT_FAR_CALL_ESI,
60  *           : "=S" ( discard, or real output ), <other output registers>
61  *           : "S" ( entry_point ), <other input registers> );
62  * "=S" *must* be specified as an output, otherwise the compiler will
63  * assume that it remains unaltered.
64  */
65 #define FLAT_FAR_CALL_ESI "call _virt_to_phys\n\t" \
66                           "pushl %%cs\n\t" \
67                           "call *%%esi\n\t" \
68                           "cli\n\t" \
69                           "cld\n\t" \
70                           "call _phys_to_virt\n\t"
71
72 /*
73  * Functions for accessing PCI configuration space directly with type
74  * 1 accesses.
75  *
76  */
77
78 static inline int pcidirect_read_config_byte ( struct pci_device *pci,
79                                                unsigned int where,
80                                                uint8_t *value ) {
81     outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
82     *value = inb ( CONFIG_DATA + ( where & 3 ) );
83     return 0;
84 }
85
86 static inline int pcidirect_read_config_word ( struct pci_device *pci,
87                                                unsigned int where,
88                                                uint16_t *value ) {
89     outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
90     *value = inw ( CONFIG_DATA + ( where & 2 ) );
91     return 0;
92 }
93
94 static inline int pcidirect_read_config_dword ( struct pci_device *pci,
95                                                 unsigned int where,
96                                                 uint32_t *value ) {
97     outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
98     *value = inl ( CONFIG_DATA );
99     return 0;
100 }
101
102 static inline int pcidirect_write_config_byte ( struct pci_device *pci,
103                                                 unsigned int where,
104                                                 uint8_t value ) {
105     outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
106     outb ( value, CONFIG_DATA + ( where & 3 ) );
107     return 0;
108 }
109
110 static inline int pcidirect_write_config_word ( struct pci_device *pci,
111                                                 unsigned int where,
112                                                 uint16_t value ) {
113     outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
114     outw ( value, CONFIG_DATA + ( where & 2 ) );
115     return 0;
116 }
117
118 static inline int pcidirect_write_config_dword ( struct pci_device *pci,
119                                                  unsigned int where,
120                                                  uint32_t value ) {
121     outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
122     outl ( value, CONFIG_DATA );
123     return 0;
124 }
125
126 /*
127  * Functions for accessing PCI configuration space directly via the
128  * PCI BIOS.
129  *
130  * Under -DKEEP_IT_REAL, we use INT 1A, otherwise we use the BIOS32
131  * interface.
132  */
133
134 #ifdef KEEP_IT_REAL
135
136 static void find_pcibios16 ( void ) {
137         uint16_t present;
138         uint32_t signature;
139         uint16_t flags;
140         uint16_t revision;
141         uint8_t max_bus;
142
143         /* PCI BIOS installation check */
144         REAL_EXEC ( rm_pcibios_check,
145                     "int $0x1a\n\t"
146                     "pushfw\n\t"
147                     "popw %%si\n\t",
148                     5,
149                     OUT_CONSTRAINTS ( "=a" ( present ), "=b" ( revision ),
150                                       "=c" ( max_bus ), "=d" ( signature ),
151                                       "=S" ( flags ) ),
152                     IN_CONSTRAINTS ( "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 ) +
153                                            PCIBIOS_PCI_BIOS_PRESENT ) ),
154                     CLOBBER ( "edi", "ebp" ) );
155
156         if ( ( flags & CF ) ||
157              ( ( present >> 8 ) != 0 ) ||
158              ( signature != PCI_SIGNATURE ) ) {
159                 DBG ( "PCI BIOS installation check failed\n" );
160                 return;
161         }
162
163         /* We have a PCI BIOS */
164         DBG ( "Found 16-bit PCI BIOS interface with %d buses\n", max_bus + 1 );
165         have_pcibios = 1;
166         pci_max_bus = max_bus;
167         return;
168 }
169
170 INIT_FN ( INIT_PCIBIOS, find_pcibios16, NULL, NULL );
171
172 #define pcibios16_read_write( command, pci, where, value )              \
173         ( {                                                             \
174                 uint32_t discard_b, discard_D;                          \
175                 uint16_t ret;                                           \
176                                                                         \
177                 REAL_EXEC ( 999, /* need a local label */               \
178                             "int $0x1a\n\t"                             \
179                             "jc 1f\n\t"                                 \
180                             "xorw %%ax, %%ax\n\t"                       \
181                             "\n1:\n\t",                                 \
182                             5,                                          \
183                             OUT_CONSTRAINTS ( "=a" ( ret ),             \
184                                               "=b" ( discard_b ),       \
185                                               "=c" ( value ),           \
186                                               "=D" ( discard_D ) ),     \
187                             IN_CONSTRAINTS ( "a" ( command +            \
188                                     ( PCIBIOS_PCI_FUNCTION_ID << 8 ) ), \
189                                              "b" ( pci->busdevfn ),     \
190                                              "c" ( value ),             \
191                                              "D" ( where ) ),           \
192                             CLOBBER ( "edx", "esi", "ebp" ) );          \
193                                                                         \
194                 ( ret >> 8 );                                           \
195         } )
196 #define pcibios_read_write pcibios16_read_write
197
198 #else /* KEEP_IT_REAL */
199
200 /*
201  * Locate the BIOS32 service directory by scanning for a valid BIOS32
202  * structure
203  *
204  */
205 static struct bios32 * find_bios32 ( void ) {
206         uint32_t address;
207
208         /*
209          * Follow the standard procedure for locating the BIOS32 Service
210          * directory by scanning the permissible address range from
211          * 0xe0000 through 0xfffff for a valid BIOS32 structure.
212          *
213          */
214         for ( address = 0xe0000 ; address < 0xffff0 ; address += 16 ) {
215                 struct bios32 * candidate = phys_to_virt ( address );
216                 unsigned int length, i;
217                 unsigned char sum;
218
219                 if ( candidate->signature != BIOS32_SIGNATURE )
220                         continue;
221
222                 length = candidate->length * 16;
223                 if ( ! length )
224                         continue;
225
226                 for ( sum = 0, i = 0 ; i < length ; i++ )
227                         sum += ( ( char * ) candidate ) [i];
228                 if ( sum != 0 )
229                         continue;
230
231                 if ( candidate->revision != 0 ) {
232                         DBG ( "unsupported BIOS32 revision %d at %#x\n",
233                               candidate->revision, address );
234                         continue;
235                 }
236
237                 DBG ( "BIOS32 Service Directory structure at %#x\n", address );
238
239                 return candidate;
240         }
241
242         return NULL;
243 }
244
245 /*
246  * Look up a service in the BIOS32 service directory
247  *
248  */
249 static unsigned long find_bios32_service ( struct bios32 * bios32,
250                                            unsigned long service ) {
251         uint8_t return_code;
252         uint32_t address;
253         uint32_t length;
254         uint32_t entry;
255         uint32_t discard;
256
257         __asm__ ( FLAT_FAR_CALL_ESI
258                   : "=a" ( return_code ), "=b" ( address ),
259                     "=c" ( length ), "=d" ( entry ), "=S" ( discard )
260                   : "a" ( service ), "b" ( 0 ), "S" ( bios32->entry )
261                   : "edi", "ebp" );
262
263         switch ( return_code ) {
264         case BIOS32_SERVICE_PRESENT:
265                 DBG ( "BIOS32 service %c%c%c%c present at %#x\n",
266                       PRINT_BIOS_SIG ( service ), ( address + entry ) );
267                 return ( address + entry );
268         case BIOS32_SERVICE_NOT_PRESENT:
269                 DBG ( "BIOS32 service %c%c%c%c : not present\n",
270                       PRINT_BIOS_SIG ( service ) );
271                 return 0;
272         default: /* Shouldn't happen */
273                 DBG ( "BIOS32 returned %#x for service %c%c%c%c!\n",
274                       return_code, PRINT_BIOS_SIG ( service ) );
275                 return 0;
276         }
277 }
278
279 /*
280  * Find the 32-bit PCI BIOS interface, if present.
281  *
282  */
283 static void find_pcibios32 ( void ) {
284         struct bios32 *bios32;
285         uint32_t signature;
286         uint16_t present;
287         uint32_t flags;
288         uint16_t revision;
289         uint8_t max_bus;
290
291         /* Locate BIOS32 service directory */
292         bios32 = find_bios32 ();
293         if ( ! bios32 ) {
294                 DBG ( "No BIOS32\n" );
295                 return;
296         }
297
298         /* Locate PCI BIOS service */
299         pcibios32_entry = find_bios32_service ( bios32, PCI_SERVICE );
300         if ( ! pcibios32_entry ) {
301                 DBG ( "No PCI BIOS\n" );
302                 return;
303         }
304         
305         /* PCI BIOS installation check */
306         __asm__ ( FLAT_FAR_CALL_ESI
307                   "pushfl\n\t"
308                   "popl %%esi\n\t"
309                   : "=a" ( present ), "=b" ( revision ), "=c" ( max_bus ),
310                     "=d" ( signature ), "=S" ( flags )
311                   : "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 )
312                           + PCIBIOS_PCI_BIOS_PRESENT ),
313                     "S" ( pcibios32_entry )
314                   : "edi", "ebp" );
315
316         if ( ( flags & CF ) ||
317              ( ( present >> 8 ) != 0 ) ||
318              ( signature != PCI_SIGNATURE ) ) {
319                 DBG ( "PCI BIOS installation check failed\n" );
320                 return;
321         }
322
323         /* We have a PCI BIOS */
324         DBG ( "Found 32-bit PCI BIOS interface at %#x with %d bus(es)\n",
325               pcibios32_entry, max_bus + 1 );
326         have_pcibios = 1;
327         pci_max_bus = max_bus;
328         return;
329 }
330
331 INIT_FN ( INIT_PCIBIOS, find_pcibios32, NULL, NULL );
332
333 #define pcibios32_read_write( command, pci, where, value )              \
334         ( {                                                             \
335                 uint32_t discard_b, discard_D, discard_S;               \
336                 uint16_t ret;                                           \
337                                                                         \
338                 __asm__ ( FLAT_FAR_CALL_ESI                             \
339                           "jc 1f\n\t"                                   \
340                           "xorl %%eax, %%eax\n\t"                       \
341                           "\n1:\n\t"                                    \
342                           : "=a" ( ret ), "=b" ( discard_b ),           \
343                             "=c" ( value ),                             \
344                             "=S" ( discard_S ), "=D" ( discard_D )      \
345                           : "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 )      \
346                                   + command ),                          \
347                             "b" ( ( pci->bus << 8 ) | pci->devfn ),     \
348                             "c" ( value ), "D" ( where ),               \
349                             "S" ( pcibios32_entry )                     \
350                           : "edx", "ebp" );                             \
351                                                                         \
352                 ( ret >> 8 );                                           \
353         } )
354 #define pcibios_read_write pcibios32_read_write
355
356 #endif /* KEEP_IT_REAL */
357
358 static inline int pcibios_read_config_byte ( struct pci_device *pci,
359                                              unsigned int where,
360                                              uint8_t *value ) {
361         return pcibios_read_write ( PCIBIOS_READ_CONFIG_BYTE,
362                                     pci, where, *value );
363 }
364
365 static inline int pcibios_read_config_word ( struct pci_device *pci,
366                                              unsigned int where,
367                                              uint16_t *value ) {
368         return pcibios_read_write ( PCIBIOS_READ_CONFIG_WORD,
369                                     pci, where, *value );
370 }
371
372 static inline int pcibios_read_config_dword ( struct pci_device *pci,
373                                               unsigned int where,
374                                               uint32_t *value ) {
375         return pcibios_read_write ( PCIBIOS_READ_CONFIG_DWORD,
376                                     pci, where, *value );
377 }
378
379 static inline int pcibios_write_config_byte ( struct pci_device *pci,
380                                               unsigned int where,
381                                               uint8_t value ) {
382         return pcibios_read_write ( PCIBIOS_WRITE_CONFIG_BYTE,
383                                     pci, where, value );
384 }
385
386 static inline int pcibios_write_config_word ( struct pci_device *pci,
387                                               unsigned int where,
388                                               uint16_t value ) {
389         return pcibios_read_write ( PCIBIOS_WRITE_CONFIG_WORD,
390                                     pci, where, value );
391 }
392
393 static inline int pcibios_write_config_dword ( struct pci_device *pci,
394                                                unsigned int where,
395                                                uint32_t value ) {
396         return pcibios_read_write ( PCIBIOS_WRITE_CONFIG_DWORD,
397                                     pci, where, value );
398 }
399
400 /*
401  * Functions for accessing PCI configuration space via the PCI BIOS if
402  * present, otherwise directly via type 1 accesses.
403  *
404  */
405
406 int pci_read_config_byte ( struct pci_device *pci, unsigned int where,
407                            uint8_t *value ) {
408         return have_pcibios ?
409                 pcibios_read_config_byte ( pci, where, value ) :
410                 pcidirect_read_config_byte ( pci, where, value );
411 }
412                 
413 int pci_read_config_word ( struct pci_device *pci, unsigned int where,
414                            uint16_t *value ) {
415         return have_pcibios ?
416                 pcibios_read_config_word ( pci, where, value ) :
417                 pcidirect_read_config_word ( pci, where, value );
418 }
419                 
420 int pci_read_config_dword ( struct pci_device *pci, unsigned int where,
421                             uint32_t *value ) {
422         return have_pcibios ?
423                 pcibios_read_config_dword ( pci, where, value ) :
424                 pcidirect_read_config_dword ( pci, where, value );
425 }
426                 
427 int pci_write_config_byte ( struct pci_device *pci, unsigned int where,
428                             uint8_t value ) {
429         return have_pcibios ?
430                 pcibios_write_config_byte ( pci, where, value ) :
431                 pcidirect_write_config_byte ( pci, where, value );
432 }
433                 
434 int pci_write_config_word ( struct pci_device *pci, unsigned int where,
435                             uint16_t value ) {
436         return have_pcibios ?
437                 pcibios_write_config_word ( pci, where, value ) :
438                 pcidirect_write_config_word ( pci, where, value );
439 }
440                 
441 int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
442                              uint32_t value ) {
443         return have_pcibios ?
444                 pcibios_write_config_dword ( pci, where, value ) :
445                 pcidirect_write_config_dword ( pci, where, value );
446 }
447
448 unsigned long pci_bus_base ( struct pci_device *pci __unused ) {
449         /* architecturally this must be 0 */
450         return 0;
451 }