[linux] Add support for accessing PCI configuration space via /proc/bus/pci

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2013-07-13 12:42:40 +02:00
parent 3dbcce51ea
commit d8392851d2
8 changed files with 332 additions and 0 deletions

View File

@@ -275,6 +275,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_efi_init ( ERRFILE_OTHER | 0x00390000 )
#define ERRFILE_efi_timer ( ERRFILE_OTHER | 0x003a0000 )
#define ERRFILE_efi_umalloc ( ERRFILE_OTHER | 0x003b0000 )
#define ERRFILE_linux_pci ( ERRFILE_OTHER | 0x003c0000 )
/** @} */

View File

@@ -30,6 +30,14 @@ FILE_LICENCE(GPL2_OR_LATER);
#include <ipxe/device.h>
#include <ipxe/settings.h>
/**
* Convert a Linux error number to an iPXE status code
*
* @v errno Linux error number
* @ret rc iPXE status code (before negation)
*/
#define ELINUX( errno ) EPLATFORM ( EINFO_EPLATFORM, errno )
/** A linux device */
struct linux_device {
/** Generic device */

View File

@@ -0,0 +1,130 @@
#ifndef _IPXE_LINUX_PCI_H
#define _IPXE_LINUX_PCI_H
/** @file
*
* iPXE PCI API for Linux
*
*/
FILE_LICENCE ( GPL2_OR_LATER );
#ifdef PCIAPI_LINUX
#define PCIAPI_PREFIX_linux
#else
#define PCIAPI_PREFIX_linux __linux_
#endif
struct pci_device;
extern int linux_pci_read ( struct pci_device *pci, unsigned long where,
unsigned long *value, size_t len );
extern int linux_pci_write ( struct pci_device *pci, unsigned long where,
unsigned long value, size_t len );
/**
* 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
*/
static inline __always_inline int
PCIAPI_INLINE ( linux, pci_read_config_byte ) ( struct pci_device *pci,
unsigned int where,
uint8_t *value ) {
int rc;
unsigned long tmp;
rc = linux_pci_read ( pci, where, &tmp, sizeof ( *value ) );
*value = tmp;
return rc;
}
/**
* Read 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
*/
static inline __always_inline int
PCIAPI_INLINE ( linux, pci_read_config_word ) ( struct pci_device *pci,
unsigned int where,
uint16_t *value ) {
int rc;
unsigned long tmp;
rc = linux_pci_read ( pci, where, &tmp, sizeof ( *value ) );
*value = tmp;
return rc;
}
/**
* Read 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
*/
static inline __always_inline int
PCIAPI_INLINE ( linux, pci_read_config_dword ) ( struct pci_device *pci,
unsigned int where,
uint32_t *value ) {
int rc;
unsigned long tmp;
rc = linux_pci_read ( pci, where, &tmp, sizeof ( *value ) );
*value = tmp;
return rc;
}
/**
* 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
*/
static inline __always_inline int
PCIAPI_INLINE ( linux, pci_write_config_byte ) ( struct pci_device *pci,
unsigned int where,
uint8_t value ) {
return linux_pci_write ( pci, where, value, sizeof ( value ) );
}
/**
* Write 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
*/
static inline __always_inline int
PCIAPI_INLINE ( linux, pci_write_config_word ) ( struct pci_device *pci,
unsigned int where,
uint16_t value ) {
return linux_pci_write ( pci, where, value, sizeof ( value ) );
}
/**
* Write 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
*/
static inline __always_inline int
PCIAPI_INLINE ( linux, pci_write_config_dword ) ( struct pci_device *pci,
unsigned int where,
uint32_t value ) {
return linux_pci_write ( pci, where, value, sizeof ( value ) );
}
#endif /* _IPXE_LINUX_PCI_H */

View File

@@ -44,6 +44,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
/* Include all architecture-independent I/O API headers */
#include <ipxe/efi/efi_pci_api.h>
#include <ipxe/linux/linux_pci.h>
/* Include all architecture-dependent I/O API headers */
#include <bits/pci_io.h>

View File

@@ -47,11 +47,13 @@ typedef __kernel_loff_t loff_t;
typedef unsigned long nfds_t;
typedef uint32_t useconds_t;
#define MAP_FAILED ( ( void * ) -1 )
#define SEEK_SET 0
extern long linux_syscall ( int number, ... );
extern int linux_open ( const char *pathname, int flags );
extern int linux_close ( int fd );
extern off_t linux_lseek ( int fd, off_t offset, int whence );
extern __kernel_ssize_t linux_read ( int fd, void *buf, __kernel_size_t count );
extern __kernel_ssize_t linux_write ( int fd, const void *buf,
__kernel_size_t count );