#ifndef _IPXE_PCI_IO_H #define _IPXE_PCI_IO_H /** @file * * PCI I/O API * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include #include struct pci_device; struct pci_api; /** A PCI bus:dev.fn address range */ struct pci_range { /** Starting bus:dev.fn address */ uint32_t start; /** Number of bus:dev.fn addresses within this range */ unsigned int count; }; #define PCI_BUSDEVFN( segment, bus, slot, func ) \ ( ( (segment) << 16 ) | ( (bus) << 8 ) | \ ( (slot) << 3 ) | ( (func) << 0 ) ) /** * 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 #include #include /* Include all architecture-dependent I/O API headers */ #include /** * Find next PCI bus:dev.fn address range in system * * @v busdevfn Starting PCI bus:dev.fn address * @v range PCI bus:dev.fn address range to fill in */ void pci_discover ( uint32_t busdevfn, struct pci_range *range ); /** * 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 ); /** * Map PCI bus address as an I/O address * * @v bus_addr PCI bus address * @v len Length of region * @ret io_addr I/O address, or NULL on error */ void * pci_ioremap ( struct pci_device *pci, unsigned long bus_addr, size_t len ); /** A runtime selectable PCI I/O API */ struct pci_api { const char *name; typeof ( pci_discover ) ( * pci_discover ); typeof ( pci_read_config_byte ) ( * pci_read_config_byte ); typeof ( pci_read_config_word ) ( * pci_read_config_word ); typeof ( pci_read_config_dword ) ( * pci_read_config_dword ); typeof ( pci_write_config_byte ) ( * pci_write_config_byte ); typeof ( pci_write_config_word ) ( * pci_write_config_word ); typeof ( pci_write_config_dword ) ( * pci_write_config_dword ); typeof ( pci_ioremap ) ( * pci_ioremap ); }; /** Provide a runtime selectable PCI I/O API */ #define PCIAPI_RUNTIME( _subsys ) { \ .name = #_subsys, \ .pci_discover = PCIAPI_INLINE ( _subsys, pci_discover ), \ .pci_read_config_byte = \ PCIAPI_INLINE ( _subsys, pci_read_config_byte ), \ .pci_read_config_word = \ PCIAPI_INLINE ( _subsys, pci_read_config_word ), \ .pci_read_config_dword = \ PCIAPI_INLINE ( _subsys, pci_read_config_dword ), \ .pci_write_config_byte = \ PCIAPI_INLINE ( _subsys, pci_write_config_byte ), \ .pci_write_config_word = \ PCIAPI_INLINE ( _subsys, pci_write_config_word ), \ .pci_write_config_dword = \ PCIAPI_INLINE ( _subsys, pci_write_config_dword ), \ .pci_ioremap = PCIAPI_INLINE ( _subsys, pci_ioremap ), \ } #endif /* _IPXE_PCI_IO_H */