[pci] Formalise the PCI I/O API
authorMichael Brown <mcb30@etherboot.org>
Sun, 12 Oct 2008 11:50:44 +0000 (12:50 +0100)
committerMichael Brown <mcb30@etherboot.org>
Sun, 12 Oct 2008 11:54:12 +0000 (12:54 +0100)
src/arch/i386/core/pcidirect.c
src/arch/i386/include/bits/pci_io.h [new file with mode: 0644]
src/arch/i386/include/gpxe/pcibios.h [moved from src/arch/i386/include/pcibios.h with 66% similarity]
src/arch/i386/include/gpxe/pcidirect.h [moved from src/arch/i386/include/pcidirect.h with 66% similarity]
src/arch/i386/include/pci_io.h [deleted file]
src/arch/i386/interface/pcbios/pcibios.c [moved from src/arch/i386/core/pcibios.c with 86% similarity]
src/config/defaults/pcbios.h
src/config/ioapi.h
src/include/gpxe/pci.h
src/include/gpxe/pci_io.h [new file with mode: 0644]

index 2ed8c2a..fec2e3c 100644 (file)
@@ -17,7 +17,6 @@
  */
 
 #include <gpxe/pci.h>
-#include <pcidirect.h>
 
 /** @file
  *
@@ -36,3 +35,10 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) {
                 ( where & ~3 ) ), PCIDIRECT_CONFIG_ADDRESS );
 }
 
+PROVIDE_PCIAPI_INLINE ( direct, pci_max_bus );
+PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte );
+PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
+PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
+PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
+PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
+PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
diff --git a/src/arch/i386/include/bits/pci_io.h b/src/arch/i386/include/bits/pci_io.h
new file mode 100644 (file)
index 0000000..0fbb439
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _BITS_PCI_IO_H
+#define _BITS_PCI_IO_H
+
+/** @file
+ *
+ * i386-specific PCI I/O API implementations
+ *
+ */
+
+#include <gpxe/pcibios.h>
+#include <gpxe/pcidirect.h>
+
+#endif /* _BITS_PCI_IO_H */
similarity index 66%
rename from src/arch/i386/include/pcibios.h
rename to src/arch/i386/include/gpxe/pcibios.h
index 3d08d13..b86f5ab 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _PCIBIOS_H
-#define _PCIBIOS_H
+#ifndef _GPXE_PCIBIOS_H
+#define _GPXE_PCIBIOS_H
 
 #include <stdint.h>
 
@@ -9,6 +9,12 @@
  *
  */
 
+#ifdef PCIAPI_PCBIOS
+#define PCIAPI_PREFIX_pcbios
+#else
+#define PCIAPI_PREFIX_pcbios __pcbios_
+#endif
+
 struct pci_device;
 
 #define PCIBIOS_INSTALLATION_CHECK     0xb1010000
@@ -19,7 +25,6 @@ struct pci_device;
 #define PCIBIOS_WRITE_CONFIG_WORD      0xb10c0000
 #define PCIBIOS_WRITE_CONFIG_DWORD     0xb10d0000
 
-extern int pcibios_max_bus ( void );
 extern int pcibios_read ( struct pci_device *pci, uint32_t command,
                          uint32_t *value );
 extern int pcibios_write ( struct pci_device *pci, uint32_t command,
@@ -33,9 +38,10 @@ extern int pcibios_write ( struct pci_device *pci, uint32_t command,
  * @v value    Value read
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcibios_read_config_byte ( struct pci_device *pci, unsigned int where,
-                          uint8_t *value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_read_config_byte ) ( struct pci_device *pci,
+                                                unsigned int where,
+                                                uint8_t *value ) {
        uint32_t tmp;
        int rc;
 
@@ -52,9 +58,10 @@ pcibios_read_config_byte ( struct pci_device *pci, unsigned int where,
  * @v value    Value read
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcibios_read_config_word ( struct pci_device *pci, unsigned int where,
-                          uint16_t *value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_read_config_word ) ( struct pci_device *pci,
+                                                unsigned int where,
+                                                uint16_t *value ) {
        uint32_t tmp;
        int rc;
 
@@ -71,9 +78,10 @@ pcibios_read_config_word ( struct pci_device *pci, unsigned int where,
  * @v value    Value read
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcibios_read_config_dword ( struct pci_device *pci, unsigned int where,
-                           uint32_t *value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_read_config_dword ) ( struct pci_device *pci,
+                                                 unsigned int where,
+                                                 uint32_t *value ) {
        return pcibios_read ( pci, PCIBIOS_READ_CONFIG_DWORD | where, value );
 }
 
@@ -85,9 +93,10 @@ pcibios_read_config_dword ( struct pci_device *pci, unsigned int where,
  * @v value    Value to be written
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcibios_write_config_byte ( struct pci_device *pci, unsigned int where,
-                           uint8_t value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_write_config_byte ) ( struct pci_device *pci,
+                                                 unsigned int where,
+                                                 uint8_t value ) {
        return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_BYTE | where, value );
 }
 
@@ -99,9 +108,10 @@ pcibios_write_config_byte ( struct pci_device *pci, unsigned int where,
  * @v value    Value to be written
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcibios_write_config_word ( struct pci_device *pci, unsigned int where,
-                           uint16_t value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_write_config_word ) ( struct pci_device *pci,
+                                                 unsigned int where,
+                                                 uint16_t value ) {
        return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_WORD | where, value );
 }
 
@@ -113,10 +123,11 @@ pcibios_write_config_word ( struct pci_device *pci, unsigned int where,
  * @v value    Value to be written
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcibios_write_config_dword ( struct pci_device *pci, unsigned int where,
-                            uint32_t value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( pcbios, pci_write_config_dword ) ( struct pci_device *pci,
+                                                  unsigned int where,
+                                                  uint32_t value ) {
        return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_DWORD | where, value);
 }
 
-#endif /* _PCIBIOS_H */
+#endif /* _GPXE_PCIBIOS_H */
similarity index 66%
rename from src/arch/i386/include/pcidirect.h
rename to src/arch/i386/include/gpxe/pcidirect.h
index c333424..fe433c6 100644 (file)
@@ -4,6 +4,12 @@
 #include <stdint.h>
 #include <gpxe/io.h>
 
+#ifdef PCIAPI_DIRECT
+#define PCIAPI_PREFIX_direct
+#else
+#define PCIAPI_PREFIX_direct __direct_
+#endif
+
 /** @file
  *
  * PCI configuration space access via Type 1 accesses
@@ -22,7 +28,8 @@ extern void pcidirect_prepare ( struct pci_device *pci, int where );
  *
  * @ret max_bus                Maximum bus number
  */
-static inline int pcidirect_max_bus ( void ) {
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_max_bus ) ( void ) {
        /* No way to work this out via Type 1 accesses */
        return 0xff;
 }
@@ -35,9 +42,10 @@ static inline int pcidirect_max_bus ( void ) {
  * @v value    Value read
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcidirect_read_config_byte ( struct pci_device *pci, unsigned int where,
-                            uint8_t *value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_read_config_byte ) ( struct pci_device *pci,
+                                                unsigned int where,
+                                                uint8_t *value ) {
        pcidirect_prepare ( pci, where );
        *value = inb ( PCIDIRECT_CONFIG_DATA + ( where & 3 ) );
        return 0;
@@ -51,9 +59,10 @@ pcidirect_read_config_byte ( struct pci_device *pci, unsigned int where,
  * @v value    Value read
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcidirect_read_config_word ( struct pci_device *pci, unsigned int where,
-                            uint16_t *value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_read_config_word ) ( struct pci_device *pci,
+                                                unsigned int where,
+                                                uint16_t *value ) {
        pcidirect_prepare ( pci, where );
        *value = inw ( PCIDIRECT_CONFIG_DATA + ( where & 2 ) );
        return 0;
@@ -67,9 +76,10 @@ pcidirect_read_config_word ( struct pci_device *pci, unsigned int where,
  * @v value    Value read
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcidirect_read_config_dword ( struct pci_device *pci, unsigned int where,
-                             uint32_t *value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_read_config_dword ) ( struct pci_device *pci,
+                                                 unsigned int where,
+                                                 uint32_t *value ) {
        pcidirect_prepare ( pci, where );
        *value = inl ( PCIDIRECT_CONFIG_DATA );
        return 0;
@@ -83,9 +93,10 @@ pcidirect_read_config_dword ( struct pci_device *pci, unsigned int where,
  * @v value    Value to be written
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcidirect_write_config_byte ( struct pci_device *pci, unsigned int where,
-                             uint8_t value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_write_config_byte ) ( struct pci_device *pci,
+                                                 unsigned int where,
+                                                 uint8_t value ) {
        pcidirect_prepare ( pci, where );
        outb ( value, PCIDIRECT_CONFIG_DATA + ( where & 3 ) );
        return 0;
@@ -99,9 +110,10 @@ pcidirect_write_config_byte ( struct pci_device *pci, unsigned int where,
  * @v value    Value to be written
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcidirect_write_config_word ( struct pci_device *pci, unsigned int where,
-                             uint16_t value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_write_config_word ) ( struct pci_device *pci,
+                                                 unsigned int where,
+                                                 uint16_t value ) {
        pcidirect_prepare ( pci, where );
        outw ( value, PCIDIRECT_CONFIG_DATA + ( where & 2 ) );
        return 0;
@@ -115,9 +127,10 @@ pcidirect_write_config_word ( struct pci_device *pci, unsigned int where,
  * @v value    Value to be written
  * @ret rc     Return status code
  */
-static inline __attribute__ (( always_inline )) int
-pcidirect_write_config_dword ( struct pci_device *pci, unsigned int where,
-                              uint32_t value ) {
+static inline __always_inline int
+PCIAPI_INLINE ( direct, pci_write_config_dword ) ( struct pci_device *pci,
+                                                  unsigned int where,
+                                                  uint32_t value ) {
        pcidirect_prepare ( pci, where );
        outl ( value, PCIDIRECT_CONFIG_DATA );
        return 0;
diff --git a/src/arch/i386/include/pci_io.h b/src/arch/i386/include/pci_io.h
deleted file mode 100644 (file)
index 4888d55..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _PCI_IO_H
-#define _PCI_IO_H
-
-#include <pcibios.h>
-#include <pcidirect.h>
-
-/** @file
- *
- * i386 PCI configuration space access
- *
- * We have two methods of PCI configuration space access: the PCI BIOS
- * and direct Type 1 accesses.  Selecting between them is via the
- * compile-time switch -DCONFIG_PCI_DIRECT.
- *
- */
-
-#if CONFIG_PCI_DIRECT
-#define pci_max_bus            pcidirect_max_bus
-#define pci_read_config_byte   pcidirect_read_config_byte
-#define pci_read_config_word   pcidirect_read_config_word
-#define pci_read_config_dword  pcidirect_read_config_dword
-#define pci_write_config_byte  pcidirect_write_config_byte
-#define pci_write_config_word  pcidirect_write_config_word
-#define pci_write_config_dword pcidirect_write_config_dword
-#else /* CONFIG_PCI_DIRECT */
-#define pci_max_bus            pcibios_max_bus
-#define pci_read_config_byte   pcibios_read_config_byte
-#define pci_read_config_word   pcibios_read_config_word
-#define pci_read_config_dword  pcibios_read_config_dword
-#define pci_write_config_byte  pcibios_write_config_byte
-#define pci_write_config_word  pcibios_write_config_word
-#define pci_write_config_dword pcibios_write_config_dword
-#endif /* CONFIG_PCI_DIRECT */
-
-#endif /* _PCI_IO_H */
similarity index 86%
rename from src/arch/i386/core/pcibios.c
rename to src/arch/i386/interface/pcbios/pcibios.c
index 1c93e4b..81b4fd3 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <stdint.h>
 #include <gpxe/pci.h>
-#include <pcibios.h>
 #include <realmode.h>
 
 /** @file
@@ -32,7 +31,7 @@
  *
  * @ret max_bus                Maximum bus number
  */
-int pcibios_max_bus ( void ) {
+static int pcibios_max_bus ( void ) {
        int discard_a, discard_D;
        uint8_t max_bus;
 
@@ -104,3 +103,11 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
        
        return ( ( status >> 8 ) & 0xff );
 }
+
+PROVIDE_PCIAPI ( pcbios, pci_max_bus, pcibios_max_bus );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_dword );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
index 193871f..df6e93c 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #define IOAPI_X86
-
+#define PCIAPI_PCBIOS
 #define CONSOLE_PCBIOS
 
 #endif /* CONFIG_DEFAULTS_PCBIOS_H */
index 28c4f7b..7726a0f 100644 (file)
@@ -9,4 +9,7 @@
 
 #include <config/defaults.h>
 
+//#undef       PCIAPI_PCBIOS           /* Access via PCI BIOS */
+//#define      PCIAPI_DIRECT           /* Direct access via Type 1 accesses */
+
 #endif /* CONFIG_IOAPI_H */
index 9072157..1ccdb10 100644 (file)
@@ -19,7 +19,7 @@
 #include <stdint.h>
 #include <gpxe/device.h>
 #include <gpxe/tables.h>
-#include <pci_io.h>
+#include <gpxe/pci_io.h>
 #include "pci_ids.h"
 
 /*
diff --git a/src/include/gpxe/pci_io.h b/src/include/gpxe/pci_io.h
new file mode 100644 (file)
index 0000000..db50939
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef _GPXE_PCI_IO_H
+#define _GPXE_PCI_IO_H
+
+/** @file
+ *
+ * PCI I/O API
+ *
+ */
+
+#include <stdint.h>
+#include <gpxe/api.h>
+#include <config/ioapi.h>
+
+/**
+ * Calculate static inline PCI I/O API function name
+ *
+ * @v _prefix          Subsystem prefix
+ * @v _api_func                API function
+ * @ret _subsys_func   Subsystem API function
+ */
+#define PCIAPI_INLINE( _subsys, _api_func ) \
+       SINGLE_API_INLINE ( PCIAPI_PREFIX_ ## _subsys, _api_func )
+
+/**
+ * Provide a PCI I/O API implementation
+ *
+ * @v _prefix          Subsystem prefix
+ * @v _api_func                API function
+ * @v _func            Implementing function
+ */
+#define PROVIDE_PCIAPI( _subsys, _api_func, _func ) \
+       PROVIDE_SINGLE_API ( PCIAPI_PREFIX_ ## _subsys, _api_func, _func )
+
+/**
+ * Provide a static inline PCI I/O API implementation
+ *
+ * @v _prefix          Subsystem prefix
+ * @v _api_func                API function
+ */
+#define PROVIDE_PCIAPI_INLINE( _subsys, _api_func ) \
+       PROVIDE_SINGLE_API_INLINE ( PCIAPI_PREFIX_ ## _subsys, _api_func )
+
+/* Include all architecture-independent I/O API headers */
+
+/* Include all architecture-dependent I/O API headers */
+#include <bits/pci_io.h>
+
+/**
+ * Determine maximum PCI bus number within system
+ *
+ * @ret max_bus                Maximum bus number
+ */
+int pci_max_bus ( void );
+
+/**
+ * Read byte from PCI configuration space
+ *
+ * @v pci      PCI device
+ * @v where    Location within PCI configuration space
+ * @v value    Value read
+ * @ret rc     Return status code
+ */
+int pci_read_config_byte ( struct pci_device *pci, unsigned int where,
+                          uint8_t *value );
+
+/**
+ * Read 16-bit word from PCI configuration space
+ *
+ * @v pci      PCI device
+ * @v where    Location within PCI configuration space
+ * @v value    Value read
+ * @ret rc     Return status code
+ */
+int pci_read_config_word ( struct pci_device *pci, unsigned int where,
+                          uint16_t *value );
+
+/**
+ * Read 32-bit dword from PCI configuration space
+ *
+ * @v pci      PCI device
+ * @v where    Location within PCI configuration space
+ * @v value    Value read
+ * @ret rc     Return status code
+ */
+int pci_read_config_dword ( struct pci_device *pci, unsigned int where,
+                           uint32_t *value );
+
+/**
+ * Write byte to PCI configuration space
+ *
+ * @v pci      PCI device
+ * @v where    Location within PCI configuration space
+ * @v value    Value to be written
+ * @ret rc     Return status code
+ */
+int pci_write_config_byte ( struct pci_device *pci, unsigned int where,
+                           uint8_t value );
+
+/**
+ * Write 16-bit word to PCI configuration space
+ *
+ * @v pci      PCI device
+ * @v where    Location within PCI configuration space
+ * @v value    Value to be written
+ * @ret rc     Return status code
+ */
+int pci_write_config_word ( struct pci_device *pci, unsigned int where,
+                           uint16_t value );
+
+/**
+ * Write 32-bit dword to PCI configuration space
+ *
+ * @v pci      PCI device
+ * @v where    Location within PCI configuration space
+ * @v value    Value to be written
+ * @ret rc     Return status code
+ */
+int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
+                            uint32_t value );
+
+#endif /* _GPXE_PCI_IO_H */