From 8a4ccebec91717500bc0de867fc2ead7187657fa Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 12 Oct 2008 12:50:44 +0100 Subject: [PATCH] [pci] Formalise the PCI I/O API --- src/arch/i386/core/pcidirect.c | 8 +- src/arch/i386/include/bits/pci_io.h | 13 ++ src/arch/i386/include/{ => gpxe}/pcibios.h | 55 ++++---- src/arch/i386/include/{ => gpxe}/pcidirect.h | 51 +++++--- src/arch/i386/include/pci_io.h | 35 ----- .../i386/{core => interface/pcbios}/pcibios.c | 11 +- src/config/defaults/pcbios.h | 2 +- src/config/ioapi.h | 3 + src/include/gpxe/pci.h | 2 +- src/include/gpxe/pci_io.h | 121 ++++++++++++++++++ 10 files changed, 220 insertions(+), 81 deletions(-) create mode 100644 src/arch/i386/include/bits/pci_io.h rename src/arch/i386/include/{ => gpxe}/pcibios.h (66%) rename src/arch/i386/include/{ => gpxe}/pcidirect.h (66%) delete mode 100644 src/arch/i386/include/pci_io.h rename src/arch/i386/{core => interface/pcbios}/pcibios.c (86%) create mode 100644 src/include/gpxe/pci_io.h diff --git a/src/arch/i386/core/pcidirect.c b/src/arch/i386/core/pcidirect.c index 2ed8c2ad0..fec2e3c18 100644 --- a/src/arch/i386/core/pcidirect.c +++ b/src/arch/i386/core/pcidirect.c @@ -17,7 +17,6 @@ */ #include -#include /** @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 index 000000000..0fbb439db --- /dev/null +++ b/src/arch/i386/include/bits/pci_io.h @@ -0,0 +1,13 @@ +#ifndef _BITS_PCI_IO_H +#define _BITS_PCI_IO_H + +/** @file + * + * i386-specific PCI I/O API implementations + * + */ + +#include +#include + +#endif /* _BITS_PCI_IO_H */ diff --git a/src/arch/i386/include/pcibios.h b/src/arch/i386/include/gpxe/pcibios.h similarity index 66% rename from src/arch/i386/include/pcibios.h rename to src/arch/i386/include/gpxe/pcibios.h index 3d08d135b..b86f5abd4 100644 --- a/src/arch/i386/include/pcibios.h +++ b/src/arch/i386/include/gpxe/pcibios.h @@ -1,5 +1,5 @@ -#ifndef _PCIBIOS_H -#define _PCIBIOS_H +#ifndef _GPXE_PCIBIOS_H +#define _GPXE_PCIBIOS_H #include @@ -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 */ diff --git a/src/arch/i386/include/pcidirect.h b/src/arch/i386/include/gpxe/pcidirect.h similarity index 66% rename from src/arch/i386/include/pcidirect.h rename to src/arch/i386/include/gpxe/pcidirect.h index c333424df..fe433c6f2 100644 --- a/src/arch/i386/include/pcidirect.h +++ b/src/arch/i386/include/gpxe/pcidirect.h @@ -4,6 +4,12 @@ #include #include +#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 index 4888d5574..000000000 --- a/src/arch/i386/include/pci_io.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _PCI_IO_H -#define _PCI_IO_H - -#include -#include - -/** @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 */ diff --git a/src/arch/i386/core/pcibios.c b/src/arch/i386/interface/pcbios/pcibios.c similarity index 86% rename from src/arch/i386/core/pcibios.c rename to src/arch/i386/interface/pcbios/pcibios.c index 1c93e4be9..81b4fd3c0 100644 --- a/src/arch/i386/core/pcibios.c +++ b/src/arch/i386/interface/pcbios/pcibios.c @@ -18,7 +18,6 @@ #include #include -#include #include /** @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 ); diff --git a/src/config/defaults/pcbios.h b/src/config/defaults/pcbios.h index 193871f16..df6e93ce2 100644 --- a/src/config/defaults/pcbios.h +++ b/src/config/defaults/pcbios.h @@ -8,7 +8,7 @@ */ #define IOAPI_X86 - +#define PCIAPI_PCBIOS #define CONSOLE_PCBIOS #endif /* CONFIG_DEFAULTS_PCBIOS_H */ diff --git a/src/config/ioapi.h b/src/config/ioapi.h index 28c4f7bac..7726a0f01 100644 --- a/src/config/ioapi.h +++ b/src/config/ioapi.h @@ -9,4 +9,7 @@ #include +//#undef PCIAPI_PCBIOS /* Access via PCI BIOS */ +//#define PCIAPI_DIRECT /* Direct access via Type 1 accesses */ + #endif /* CONFIG_IOAPI_H */ diff --git a/src/include/gpxe/pci.h b/src/include/gpxe/pci.h index 907215748..1ccdb100b 100644 --- a/src/include/gpxe/pci.h +++ b/src/include/gpxe/pci.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "pci_ids.h" /* diff --git a/src/include/gpxe/pci_io.h b/src/include/gpxe/pci_io.h new file mode 100644 index 000000000..db50939df --- /dev/null +++ b/src/include/gpxe/pci_io.h @@ -0,0 +1,121 @@ +#ifndef _GPXE_PCI_IO_H +#define _GPXE_PCI_IO_H + +/** @file + * + * PCI I/O API + * + */ + +#include +#include +#include + +/** + * 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 + +/** + * 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 */