summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/i386/include')
-rw-r--r--src/arch/i386/include/pci_io.h51
-rw-r--r--src/arch/i386/include/pcibios.h122
-rw-r--r--src/arch/i386/include/pcidirect.h126
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 */