From 5a4e3dc0a5af631b1723858bc50a9af1545392fb Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 23 Apr 2018 12:50:58 +0200 Subject: bsps: Move PCI drivers to bsps This patch is a part of the BSP source reorganization. Update #3285. --- bsps/i386/shared/pci/pci_io.c | 213 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 bsps/i386/shared/pci/pci_io.c (limited to 'bsps/i386/shared/pci/pci_io.c') diff --git a/bsps/i386/shared/pci/pci_io.c b/bsps/i386/shared/pci/pci_io.c new file mode 100644 index 0000000000..b6cd1005f0 --- /dev/null +++ b/bsps/i386/shared/pci/pci_io.c @@ -0,0 +1,213 @@ +/** + * @file + * + * PCI Support when Configuration Space is in I/O + */ + +/* + * COPYRIGHT (c) 2016. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +static int pci_io_initialized = 0; + +/* + * Forward reference. Initialized at bottom. + */ +static const pci_config_access_functions pci_io_indirect_functions; + +/* + * Detects presense of PCI Configuration is in I/O space. If so, return + * pointer to accessor methods. + * + * NOTE: TBD to determine if (a) PCI Bus exists and (b) this is the + * access method. + */ +const pci_config_access_functions *pci_io_initialize(void) +{ + pci_io_initialized = 1; + + printk( "PCI I/O Support Initialized\n" ); + + return &pci_io_indirect_functions; +} + +/* + * Build PCI Address + */ +static inline uint32_t pci_io_build_address( + uint16_t bus, + uint16_t slot, + uint16_t function, + uint16_t offset +) +{ + uint32_t bus_u32 = (uint32_t)bus; + uint32_t slot_u32 = (uint32_t)slot; + uint32_t function_u32 = (uint32_t)function; + uint32_t address; + + /* + * create configuration address as per figure at + * http://wiki.osdev.org/PCI#Configuration_Space_Access_Mechanism_.231 + */ + address = (uint32_t) 0x80000000; /* Bit 31 - Enable Bit */ + /* Bits 30-24 - Reserved */ + address |= bus_u32 << 16; /* Bits 23-16 - Bus Number */ + address |= slot_u32 << 11; /* Bits 15-11 - Device/Slot Number */ + address |= function_u32 << 8; /* Bits 10-8 - Function Number */ + address |= offset & 0xfc; /* Bits 7-2 - Offset/Register Number */ + /* Bits 1-0 - Reserved 0 */ + return address; +} + +static int BSP_pci_read_config_byte( + unsigned char bus, + unsigned char slot, + unsigned char function, + unsigned char offset, + unsigned char *value +) +{ + uint32_t address; + uint32_t tmp; + + address = pci_io_build_address( bus, slot, function, offset ); + + /* write out the address */ + outport_long(0xCF8, address); + + /* read in the data */ + inport_long(0xCFC, tmp); + + /* (offset & 3) * 8) = 0 will choose the first byte of the 32 bits register */ + *value = (uint16_t)(tmp >> ((offset & 3) * 8)) & 0xff; + return PCIBIOS_SUCCESSFUL; +} + +static int BSP_pci_read_config_word( + unsigned char bus, + unsigned char slot, + unsigned char function, + unsigned char offset, + unsigned short *value +) +{ + uint32_t address; + uint32_t tmp; + + address = pci_io_build_address( bus, slot, function, offset ); + + /* write out the address */ + outport_long(0xCF8, address); + + /* read in the data */ + inport_long(0xCFC, tmp); + + /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register */ + *value = (uint16_t)(tmp >> ((offset & 2) * 8)) & 0xffff; + return PCIBIOS_SUCCESSFUL; +} + +static int BSP_pci_read_config_dword( + unsigned char bus, + unsigned char slot, + unsigned char function, + unsigned char offset, + uint32_t *value +) +{ + uint32_t address; + uint32_t tmp; + + address = pci_io_build_address( bus, slot, function, offset ); + + /* write out the address */ + outport_long(0xCF8, address); + + /* read in the data */ + inport_long(0xCFC, tmp); + + *value = tmp; + return PCIBIOS_SUCCESSFUL; +} + +static int BSP_pci_write_config_byte( + unsigned char bus, + unsigned char slot, + unsigned char function, + unsigned char offset, + unsigned char value +) +{ + uint32_t address; + + address = pci_io_build_address( bus, slot, function, offset ); + + /* write out the address */ + outport_long(0xCF8, address); + + /* read in the data */ + outport_byte(0xCFC, value); + + return PCIBIOS_SUCCESSFUL; +} + +static int BSP_pci_write_config_word( + unsigned char bus, + unsigned char slot, + unsigned char function, + unsigned char offset, + unsigned short value +) +{ + uint32_t address; + + address = pci_io_build_address( bus, slot, function, offset ); + + /* write out the address */ + outport_long(0xCF8, address); + + /* read in the data */ + outport_word(0xCFC, value); + + return PCIBIOS_SUCCESSFUL; +} + +static int BSP_pci_write_config_dword( + unsigned char bus, + unsigned char slot, + unsigned char function, + unsigned char offset, + uint32_t value +) +{ + uint32_t address; + + address = pci_io_build_address( bus, slot, function, offset ); + + /* write out the address */ + outport_long(0xCF8, address); + + /* read in the data */ + outport_long(0xCFC, value); + + return PCIBIOS_SUCCESSFUL; +} + +static const pci_config_access_functions pci_io_indirect_functions = { + BSP_pci_read_config_byte, + BSP_pci_read_config_word, + BSP_pci_read_config_dword, + BSP_pci_write_config_byte, + BSP_pci_write_config_word, + BSP_pci_write_config_dword +}; -- cgit v1.2.3