diff options
Diffstat (limited to 'src/arch/i386/include')
| -rw-r--r-- | src/arch/i386/include/pci_io.h | 51 | ||||
| -rw-r--r-- | src/arch/i386/include/pcibios.h | 122 | ||||
| -rw-r--r-- | src/arch/i386/include/pcidirect.h | 126 |
3 files changed, 281 insertions, 18 deletions
diff --git a/src/arch/i386/include/pci_io.h b/src/arch/i386/include/pci_io.h index dce45b13f..4888d5574 100644 --- a/src/arch/i386/include/pci_io.h +++ b/src/arch/i386/include/pci_io.h @@ -1,20 +1,35 @@ -#ifndef PCI_IO_H -#define PCI_IO_H +#ifndef _PCI_IO_H +#define _PCI_IO_H -/* %ah */ -#define PCIBIOS_PCI_FUNCTION_ID ( 0xb1 ) -/* %al */ -#define PCIBIOS_PCI_BIOS_PRESENT ( 0x01 ) -#define PCIBIOS_FIND_PCI_DEVICE ( 0x02 ) -#define PCIBIOS_FIND_PCI_CLASS_CODE ( 0x03 ) -#define PCIBIOS_GENERATE_SPECIAL_CYCLE ( 0x06 ) -#define PCIBIOS_READ_CONFIG_BYTE ( 0x08 ) -#define PCIBIOS_READ_CONFIG_WORD ( 0x09 ) -#define PCIBIOS_READ_CONFIG_DWORD ( 0x0a ) -#define PCIBIOS_WRITE_CONFIG_BYTE ( 0x0b ) -#define PCIBIOS_WRITE_CONFIG_WORD ( 0x0c ) -#define PCIBIOS_WRITE_CONFIG_DWORD ( 0x0d ) -#define PCIBIOS_GET_IRQ_ROUTING_OPTIONS ( 0x0e ) -#define PCIBIOS_SET_PCI_IRQ ( 0x0f ) +#include <pcibios.h> +#include <pcidirect.h> -#endif /* PCI_IO_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 */ diff --git a/src/arch/i386/include/pcibios.h b/src/arch/i386/include/pcibios.h new file mode 100644 index 000000000..dcbffedce --- /dev/null +++ b/src/arch/i386/include/pcibios.h @@ -0,0 +1,122 @@ +#ifndef _PCIBIOS_H +#define _PCIBIOS_H + +#include <stdint.h> + +/** @file + * + * PCI configuration space access via PCI BIOS + * + */ + +struct pci_device; + +#define PCIBIOS_INSTALLATION_CHECK 0xb1010000 +#define PCIBIOS_READ_CONFIG_BYTE 0xb1080000 +#define PCIBIOS_READ_CONFIG_WORD 0xb1090000 +#define PCIBIOS_READ_CONFIG_DWORD 0xb10a0000 +#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b0000 +#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, + uint32_t value ); + +/** + * Read byte from PCI configuration space via PCI BIOS + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + uint32_t tmp; + int rc; + + rc = pcibios_read ( pci, PCIBIOS_READ_CONFIG_BYTE | where, &tmp ); + *value = tmp; + return rc; +} + +/** + * Read word from PCI configuration space via PCI BIOS + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + uint32_t tmp; + int rc; + + rc = pcibios_read ( pci, PCIBIOS_READ_CONFIG_WORD | where, &tmp ); + *value = tmp; + return rc; +} + +/** + * Read dword from PCI configuration space via PCI BIOS + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + return pcibios_read ( pci, PCIBIOS_READ_CONFIG_DWORD | where, value ); +} + +/** + * Write byte to PCI configuration space via PCI BIOS + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_BYTE | where, value ); +} + +/** + * Write word to PCI configuration space via PCI BIOS + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_BYTE | where, value ); +} + +/** + * Write dword to PCI configuration space via PCI BIOS + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_BYTE | where, value ); +} + +#endif /* _PCIBIOS_H */ diff --git a/src/arch/i386/include/pcidirect.h b/src/arch/i386/include/pcidirect.h new file mode 100644 index 000000000..80e140195 --- /dev/null +++ b/src/arch/i386/include/pcidirect.h @@ -0,0 +1,126 @@ +#ifndef _PCIDIRECT_H +#define _PCIDIRECT_H + +#include <stdint.h> +#include <io.h> + +/** @file + * + * PCI configuration space access via Type 1 accesses + * + */ + +#define PCIDIRECT_CONFIG_ADDRESS 0xcf8 +#define PCIDIRECT_CONFIG_DATA 0xcfc + +struct pci_device; + +extern void pcidirect_prepare ( struct pci_device *pci, int where ); + +/** + * Determine maximum PCI bus number within system + * + * @ret max_bus Maximum bus number + */ +static inline int pcidirect_max_bus ( void ) { + /* No way to work this out via Type 1 accesses */ + return 0xff; +} + +/** + * Read byte from PCI configuration space via Type 1 access + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + pcidirect_prepare ( pci, where ); + *value = inb ( PCIDIRECT_CONFIG_DATA + ( where & 3 ) ); + return 0; +} + +/** + * Read word from PCI configuration space via Type 1 access + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + pcidirect_prepare ( pci, where ); + *value = inw ( PCIDIRECT_CONFIG_DATA + ( where & 2 ) ); + return 0; +} + +/** + * Read dword from PCI configuration space via Type 1 access + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + pcidirect_prepare ( pci, where ); + *value = inl ( PCIDIRECT_CONFIG_DATA + where ); + return 0; +} + +/** + * Write byte to PCI configuration space via Type 1 access + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + pcidirect_prepare ( pci, where ); + outb ( value, PCIDIRECT_CONFIG_DATA + ( where & 3 ) ); + return 0; +} + +/** + * Write word to PCI configuration space via Type 1 access + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + pcidirect_prepare ( pci, where ); + outb ( value, PCIDIRECT_CONFIG_DATA + ( where & 2 ) ); + return 0; +} + +/** + * Write dword to PCI configuration space via Type 1 access + * + * @v pci PCI device + * @v where Location within PCI configuration space + * @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 ) { + pcidirect_prepare ( pci, where ); + outb ( value, PCIDIRECT_CONFIG_DATA + where ); + return 0; +} + +#endif /* _PCIDIRECT_H */ |
