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. --- c/src/lib/libbsp/i386/pc386/Makefile.am | 4 +- c/src/lib/libbsp/i386/shared/pci/pci_io.c | 213 ---- c/src/lib/libbsp/i386/shared/pci/pcibios.c | 479 --------- c/src/lib/libbsp/mips/malta/Makefile.am | 2 +- c/src/lib/libbsp/mips/malta/pci/pci.c | 1102 -------------------- c/src/lib/libbsp/powerpc/beatnik/Makefile.am | 10 +- c/src/lib/libbsp/powerpc/beatnik/pci/gt_pci_init.c | 270 ----- .../lib/libbsp/powerpc/beatnik/pci/motload_fixup.c | 180 ---- .../lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c | 203 ---- .../lib/libbsp/powerpc/beatnik/pci/pci_io_remap.h | 66 -- .../libbsp/powerpc/motorola_powerpc/Makefile.am | 8 +- c/src/lib/libbsp/powerpc/mvme3100/Makefile.am | 8 +- .../powerpc/mvme3100/pci/detect_host_bridge.c | 113 -- c/src/lib/libbsp/powerpc/mvme5500/Makefile.am | 6 +- .../powerpc/mvme5500/pci/detect_host_bridge.c | 72 -- c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c | 420 -------- .../libbsp/powerpc/mvme5500/pci/pci_interface.c | 100 -- .../powerpc/shared/pci/detect_raven_bridge.c | 197 ---- .../powerpc/shared/pci/generic_clear_hberrs.c | 63 -- c/src/lib/libbsp/powerpc/shared/pci/pci.c | 640 ------------ .../lib/libbsp/powerpc/shared/pci/pcifinddevice.c | 212 ---- 21 files changed, 19 insertions(+), 4349 deletions(-) delete mode 100644 c/src/lib/libbsp/i386/shared/pci/pci_io.c delete mode 100644 c/src/lib/libbsp/i386/shared/pci/pcibios.c delete mode 100644 c/src/lib/libbsp/mips/malta/pci/pci.c delete mode 100644 c/src/lib/libbsp/powerpc/beatnik/pci/gt_pci_init.c delete mode 100644 c/src/lib/libbsp/powerpc/beatnik/pci/motload_fixup.c delete mode 100644 c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c delete mode 100644 c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.h delete mode 100644 c/src/lib/libbsp/powerpc/mvme3100/pci/detect_host_bridge.c delete mode 100644 c/src/lib/libbsp/powerpc/mvme5500/pci/detect_host_bridge.c delete mode 100644 c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c delete mode 100644 c/src/lib/libbsp/powerpc/mvme5500/pci/pci_interface.c delete mode 100644 c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c delete mode 100644 c/src/lib/libbsp/powerpc/shared/pci/generic_clear_hberrs.c delete mode 100644 c/src/lib/libbsp/powerpc/shared/pci/pci.c delete mode 100644 c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c (limited to 'c') diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.am b/c/src/lib/libbsp/i386/pc386/Makefile.am index 70028f5e65..ed354460bd 100644 --- a/c/src/lib/libbsp/i386/pc386/Makefile.am +++ b/c/src/lib/libbsp/i386/pc386/Makefile.am @@ -98,8 +98,8 @@ librtemsbsp_a_SOURCES += ../shared/comm/gdb_glue.c # gnat # pci -librtemsbsp_a_SOURCES += ../shared/pci/pcibios.c -librtemsbsp_a_SOURCES += ../shared/pci/pci_io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/shared/pci/pcibios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/shared/pci/pci_io.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/pci/pci_bus_count.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/pci/pci_find_device.c diff --git a/c/src/lib/libbsp/i386/shared/pci/pci_io.c b/c/src/lib/libbsp/i386/shared/pci/pci_io.c deleted file mode 100644 index b6cd1005f0..0000000000 --- a/c/src/lib/libbsp/i386/shared/pci/pci_io.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @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 -}; diff --git a/c/src/lib/libbsp/i386/shared/pci/pcibios.c b/c/src/lib/libbsp/i386/shared/pci/pcibios.c deleted file mode 100644 index 173c89f3f8..0000000000 --- a/c/src/lib/libbsp/i386/shared/pci/pcibios.c +++ /dev/null @@ -1,479 +0,0 @@ -/** - * @file - * - * PCI Support when Configuration Space is accessed via BIOS - */ - -/* - * This software is Copyright (C) 1998 by T.sqware - all rights limited - * It is provided in to the public domain "as is", can be freely modified - * as far as this copyight notice is kept unchanged, but does not imply - * an endorsement by T.sqware of the product in which it is included. - */ - -#include -#include -#include - -#include /* memcpy */ - -/* - * This is simpliest possible PCI BIOS, it assumes that addressing - * is flat and that stack is big enough - */ -static int pcibInitialized = 0; -static unsigned int pcibEntry; - -/* - * Array to pass data between c and __asm__ parts, at the time of - * writing I am not yet that familiar with extended __asm__ feature - * of gcc. This code is not on performance path, so we can care - * relatively little about performance here - */ -static volatile unsigned int pcibExchg[5]; - -static int pcib_convert_err(int err); - -/** @brief - * Make device signature from bus number, device numebr and function - * number - */ -#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f)) - -/** @brief - * Extract valrous part from device signature - */ -#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff) -#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f) -#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7) - -/* - * Forward reference. Initialized at bottom. - */ -static const pci_config_access_functions pci_bios_indirect_functions; - -/* prototype before defining */ -const pci_config_access_functions *pci_bios_initialize(void); - -/* - * Detects presense of PCI BIOS, returns pointer to accessor methods. - */ -const pci_config_access_functions *pci_bios_initialize(void) -{ - unsigned char *ucp; - unsigned char sum; - int i; - - pcibInitialized = 0; - - /* First, we have to look for BIOS-32 */ - for (ucp = (unsigned char *)0xE0000; - ucp < (unsigned char *)0xFFFFF; - ucp += 0x10) { - if (memcmp(ucp, "_32_", 4) != 0) { - continue; - } - - /* Got signature, check length */ - if (*(ucp + 9) != 1) { - continue; - } - - /* Verify checksum */ - sum = 0; - for (i=0; i<16; i++) { - sum += *(ucp+i); - } - - if (sum == 0) { - /* found */ - break; - } - } - - if (ucp >= (unsigned char *)0xFFFFF) { - /* BIOS-32 not found */ - return NULL; - } - - /* BIOS-32 found, let us find PCI BIOS */ - ucp += 4; - - pcibExchg[0] = *(unsigned int *)ucp; - - __asm__ (" pusha"); /* Push all registers */ - __asm__ (" movl pcibExchg, %edi"); /* Move entry point to esi */ - __asm__ (" movl $0x49435024, %eax"); /* Move signature to eax */ - __asm__ (" xorl %ebx, %ebx"); /* Zero ebx */ - __asm__ (" pushl %cs"); - __asm__ (" call *%edi"); /* Call entry */ - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" movl %ebx, pcibExchg+4"); - __asm__ (" movl %ecx, pcibExchg+8"); - __asm__ (" movl %edx, pcibExchg+12"); - __asm__ (" popa"); - - if ((pcibExchg[0] & 0xff) != 0) { - /* Not found */ - return NULL; - } - - /* Found PCI entry point */ - pcibEntry = pcibExchg[1] + pcibExchg[3]; - - /* Let us check whether PCI bios is present */ - pcibExchg[0] = pcibEntry; - - __asm__ (" pusha"); - __asm__ (" movl pcibExchg, %edi"); - __asm__ (" movb $0xb1, %ah"); - __asm__ (" movb $0x01, %al"); - __asm__ (" pushl %cs"); - __asm__ (" call *%edi"); - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" movl %ebx, pcibExchg+4"); - __asm__ (" movl %ecx, pcibExchg+8"); - __asm__ (" movl %edx, pcibExchg+12"); - __asm__ (" popa"); - - if ((pcibExchg[0] & 0xff00) != 0) { - /* Not found */ - return NULL; - } - - if (pcibExchg[3] != 0x20494350) { - /* Signature does not match */ - return NULL; - } - - /* Success */ - pcibInitialized = 1; - - return &pci_bios_indirect_functions; -} - -/* - * Read byte from config space - */ -static int -pcib_conf_read8(int sig, int off, uint8_t *data) -{ - if (!pcibInitialized) { - return PCIB_ERR_UNINITIALIZED; - } - - pcibExchg[0] = pcibEntry; - pcibExchg[1] = sig; - pcibExchg[2] = off; - - __asm__ (" pusha"); - __asm__ (" movl pcibExchg, %esi"); - __asm__ (" movb $0xb1, %ah"); - __asm__ (" movb $0x08, %al"); - __asm__ (" movl pcibExchg+4, %ebx"); - __asm__ (" movl pcibExchg+8, %edi"); - __asm__ (" pushl %cs"); - __asm__ (" call *%esi"); - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" movl %ecx, pcibExchg+4"); - __asm__ (" popa"); - - if ((pcibExchg[0] & 0xff00) != 0) { - return pcib_convert_err((pcibExchg[0] >> 8) & 0xff); - } - - *data = (unsigned char)pcibExchg[1] & 0xff; - - return PCIB_ERR_SUCCESS; -} - - -/* - * Read word from config space - */ -static int -pcib_conf_read16(int sig, int off, uint16_t *data) -{ - if (!pcibInitialized) { - return PCIB_ERR_UNINITIALIZED; - } - - pcibExchg[0] = pcibEntry; - pcibExchg[1] = sig; - pcibExchg[2] = off; - - __asm__ (" pusha"); - __asm__ (" movl pcibExchg, %esi"); - __asm__ (" movb $0xb1, %ah"); - __asm__ (" movb $0x09, %al"); - __asm__ (" movl pcibExchg+4, %ebx"); - __asm__ (" movl pcibExchg+8, %edi"); - __asm__ (" pushl %cs"); - __asm__ (" call *%esi"); - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" movl %ecx, pcibExchg+4"); - __asm__ (" popa"); - - if ((pcibExchg[0] & 0xff00) != 0) { - return pcib_convert_err((pcibExchg[0] >> 8) & 0xff); - } - - *data = (unsigned short)pcibExchg[1] & 0xffff; - - return PCIB_ERR_SUCCESS; -} - - -/* - * Read dword from config space - */ -static int -pcib_conf_read32(int sig, int off, uint32_t *data) -{ - if (!pcibInitialized) { - return PCIB_ERR_UNINITIALIZED; - } - - pcibExchg[0] = pcibEntry; - pcibExchg[1] = sig; - pcibExchg[2] = off; - - __asm__ (" pusha"); - __asm__ (" movl pcibExchg, %esi"); - __asm__ (" movb $0xb1, %ah"); - __asm__ (" movb $0x0a, %al"); - __asm__ (" movl pcibExchg+4, %ebx"); - __asm__ (" movl pcibExchg+8, %edi"); - __asm__ (" pushl %cs"); - __asm__ (" call *%esi"); - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" movl %ecx, pcibExchg+4"); - __asm__ (" popa"); - - if ((pcibExchg[0] & 0xff00) != 0) { - return pcib_convert_err((pcibExchg[0] >> 8) & 0xff); - } - - *data = (unsigned int)pcibExchg[1]; - - return PCIB_ERR_SUCCESS; -} - - -/* - * Write byte into config space - */ -static int -pcib_conf_write8(int sig, int off, uint8_t data) -{ - if (!pcibInitialized) { - return PCIB_ERR_UNINITIALIZED; - } - - pcibExchg[0] = pcibEntry; - pcibExchg[1] = sig; - pcibExchg[2] = off; - pcibExchg[3] = data & 0xff; - - __asm__ (" pusha"); - __asm__ (" movl pcibExchg, %esi"); - __asm__ (" movb $0xb1, %ah"); - __asm__ (" movb $0x0b, %al"); - __asm__ (" movl pcibExchg+4, %ebx"); - __asm__ (" movl pcibExchg+8, %edi"); - __asm__ (" movl pcibExchg+12, %ecx"); - __asm__ (" pushl %cs"); - __asm__ (" call *%esi"); - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" popa"); - - return pcib_convert_err((pcibExchg[0] >> 8) & 0xff); -} - -/* - * Write word into config space - */ -static int -pcib_conf_write16(int sig, int off, uint16_t data) -{ - if (!pcibInitialized) { - return PCIB_ERR_UNINITIALIZED; - } - - pcibExchg[0] = pcibEntry; - pcibExchg[1] = sig; - pcibExchg[2] = off; - pcibExchg[3] = data & 0xffff; - - __asm__ (" pusha"); - __asm__ (" movl pcibExchg, %esi"); - __asm__ (" movb $0xb1, %ah"); - __asm__ (" movb $0x0c, %al"); - __asm__ (" movl pcibExchg+4, %ebx"); - __asm__ (" movl pcibExchg+8, %edi"); - __asm__ (" movl pcibExchg+12, %ecx"); - __asm__ (" pushl %cs"); - __asm__ (" call *%esi"); - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" popa"); - - return pcib_convert_err((pcibExchg[0] >> 8) & 0xff); -} - - - -/* - * Write dword into config space - */ -static int -pcib_conf_write32(int sig, int off, uint32_t data) -{ - if (!pcibInitialized){ - return PCIB_ERR_UNINITIALIZED; - } - - pcibExchg[0] = pcibEntry; - pcibExchg[1] = sig; - pcibExchg[2] = off; - pcibExchg[3] = data; - - __asm__ (" pusha"); - __asm__ (" movl pcibExchg, %esi"); - __asm__ (" movb $0xb1, %ah"); - __asm__ (" movb $0x0d, %al"); - __asm__ (" movl pcibExchg+4, %ebx"); - __asm__ (" movl pcibExchg+8, %edi"); - __asm__ (" movl pcibExchg+12, %ecx"); - __asm__ (" pushl %cs"); - __asm__ (" call *%esi"); - __asm__ (" movl %eax, pcibExchg"); - __asm__ (" popa"); - - return pcib_convert_err((pcibExchg[0] >> 8) & 0xff); -} - - -static int -pcib_convert_err(int err) -{ - switch(err & 0xff){ - case 0: - return PCIB_ERR_SUCCESS; - case 0x81: - return PCIB_ERR_NOFUNC; - case 0x83: - return PCIB_ERR_BADVENDOR; - case 0x86: - return PCIB_ERR_DEVNOTFOUND; - case 0x87: - return PCIB_ERR_BADREG; - default: - break; - } - return PCIB_ERR_NOFUNC; -} - -static int -BSP_pci_read_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char fun, - unsigned char offset, - unsigned char *val -) -{ - int sig; - - sig = PCIB_DEVSIG_MAKE(bus,slot,fun); - pcib_conf_read8(sig, offset, val); - return PCIBIOS_SUCCESSFUL; -} - -static int -BSP_pci_read_config_word( - unsigned char bus, - unsigned char slot, - unsigned char fun, - unsigned char offset, - unsigned short *val -) -{ - int sig; - - sig = PCIB_DEVSIG_MAKE(bus,slot,fun); - pcib_conf_read16(sig, offset, val); - return PCIBIOS_SUCCESSFUL; -} - -static int -BSP_pci_read_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char fun, - unsigned char offset, - uint32_t *val -) -{ - int sig; - - sig = PCIB_DEVSIG_MAKE(bus,slot,fun); - pcib_conf_read32(sig, offset, val); - return PCIBIOS_SUCCESSFUL; -} - -static int -BSP_pci_write_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char fun, - unsigned char offset, - unsigned char val -) -{ - int sig; - - sig = PCIB_DEVSIG_MAKE(bus,slot,fun); - pcib_conf_write8(sig, offset, val); - return PCIBIOS_SUCCESSFUL; -} - -static int -BSP_pci_write_config_word( - unsigned char bus, - unsigned char slot, - unsigned char fun, - unsigned char offset, - unsigned short val -) -{ - int sig; - - sig = PCIB_DEVSIG_MAKE(bus,slot,fun); - pcib_conf_write16(sig, offset, val); - return PCIBIOS_SUCCESSFUL; -} - -static int -BSP_pci_write_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char fun, - unsigned char offset, - uint32_t val -) -{ - int sig; - - sig = PCIB_DEVSIG_MAKE(bus,slot,fun); - pcib_conf_write32(sig, offset, val); - return PCIBIOS_SUCCESSFUL; -} - -static const pci_config_access_functions pci_bios_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 -}; diff --git a/c/src/lib/libbsp/mips/malta/Makefile.am b/c/src/lib/libbsp/mips/malta/Makefile.am index 3240ea9ea2..68567e3959 100644 --- a/c/src/lib/libbsp/mips/malta/Makefile.am +++ b/c/src/lib/libbsp/mips/malta/Makefile.am @@ -51,7 +51,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/shared/irq/installisrentrie librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/shared/irq/isr_entries.S # pci -librtemsbsp_a_SOURCES += pci/pci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/malta/pci/pci.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/pci/pci_find_device.c #isr diff --git a/c/src/lib/libbsp/mips/malta/pci/pci.c b/c/src/lib/libbsp/mips/malta/pci/pci.c deleted file mode 100644 index 0932f07d35..0000000000 --- a/c/src/lib/libbsp/mips/malta/pci/pci.c +++ /dev/null @@ -1,1102 +0,0 @@ -/** - * @file - * - * This file was based on the powerpc. - */ - -/* - * COPYRIGHT (c) 1989-2012. - * 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 -#include -#include -#include - -/* - * DEFINES - */ - -#undef SHOW_PCI_SETTING - -// #define DEBUG_PCI 1 - -/* allow for overriding these definitions */ -#ifndef PCI_CONFIG_ADDR -#define PCI_CONFIG_ADDR 0xcf8 -#endif -#ifndef PCI_CONFIG_DATA -#define PCI_CONFIG_DATA 0xcfc -#endif - -/* define a shortcut */ -#define pci BSP_pci_configuration - -#ifndef PCI_CONFIG_ADDR_VAL -#define PCI_CONFIG_ADDR_VAL(bus, slot, funcion, offset) \ - (0x80000000|((bus)<<16)|(PCI_DEVFN((slot),(function))<<8)|(((offset)&~3))) -#endif - -#ifdef DEBUG_PCI - #define JPRINTK(fmt, ...) printk("%s: " fmt, __FUNCTION__, ##__VA_ARGS__) -#else - #define JPRINTK(fmt, ...) -#endif - -#ifndef PCI_CONFIG_WR_ADDR -#define PCI_CONFIG_WR_ADDR( addr, val ) out_le32((uint32_t)(addr), (val)) -#endif - -/* Bit encode for PCI_CONFIG_HEADER_TYPE register */ -#define PCI_CONFIG_SET_ADDR(addr, bus, slot,function,offset) \ - PCI_CONFIG_WR_ADDR( \ - (addr), \ - PCI_CONFIG_ADDR_VAL((bus), (slot), (function), (offset))\ - ) - -#define PRINT_MSG() \ - printk("pci : Device %d:0x%02x:%d routed to interrupt_line %d\n", \ - pbus, pslot, pfun, int_name ) - -/* - * STRUCTURES - */ - -/* - * PROTOTYPES - */ -void print_bars( - unsigned char slot, - unsigned char func -); -int direct_pci_read_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t *val -); -int direct_pci_read_config_word( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint16_t *val -); -int direct_pci_read_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint32_t *val -); -int direct_pci_write_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t val -); -int direct_pci_write_config_word( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint16_t val -); -int direct_pci_write_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint32_t val -); -int test_intname( - const struct _int_map *row, - int pbus, - int pslot, - int pfun, - int int_pin, - int int_name -); -void pci_memory_enable( - unsigned char bus, - unsigned char slot, - unsigned char function -); -void pci_io_enable( - unsigned char bus, - unsigned char slot, - unsigned char function -); -void pci_busmaster_enable( - unsigned char bus, - unsigned char slot, - unsigned char function -); - -/* - * GLOBALS - */ -unsigned char ucMaxPCIBus; -const pci_config_access_functions pci_indirect_functions = { - indirect_pci_read_config_byte, - indirect_pci_read_config_word, - indirect_pci_read_config_dword, - indirect_pci_write_config_byte, - indirect_pci_write_config_word, - indirect_pci_write_config_dword -}; - -rtems_pci_config_t BSP_pci_configuration = { - (volatile unsigned char*)PCI_CONFIG_ADDR, - (volatile unsigned char*)PCI_CONFIG_DATA, - &pci_indirect_functions -}; - -const pci_config_access_functions pci_direct_functions = { - direct_pci_read_config_byte, - direct_pci_read_config_word, - direct_pci_read_config_dword, - direct_pci_write_config_byte, - direct_pci_write_config_word, - direct_pci_write_config_dword -}; - -/* - * PCI specific accesses. Note these are made on 32 bit - * boundries. - */ -void pci_out_32(uint32_t base, uint32_t addr, uint32_t val) -{ - volatile uint32_t *ptr; - - ptr = (volatile uint32_t *) (base + addr); - *ptr = val; - - JPRINTK( "%p data: 0x%x\n", ptr, val); -} - -void pci_out_le32(uint32_t base, uint32_t addr, uint32_t val) -{ - volatile uint32_t *ptr; - uint32_t data = 0; - - ptr = (volatile uint32_t *) (base + addr); - rtems_uint32_to_little_endian( val, (uint8_t *) &data); - *ptr = data; - - JPRINTK( "%p data: 0x%x\n", ptr, data); -} - -uint8_t pci_in_8( uint32_t base, uint32_t addr ) { - volatile uint32_t *ptr; - uint8_t val; - uint32_t data; - - data = addr/4; - ptr = (volatile uint32_t *) (base + (data*4)); - data = *ptr; - - switch ( addr%4 ) { - case 0: val = (data & 0x000000ff) >> 0; break; - case 1: val = (data & 0x0000ff00) >> 8; break; - case 2: val = (data & 0x00ff0000) >> 16; break; - case 3: val = (data & 0xff000000) >> 24; break; - } - - JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data); - - return val; -} - -int16_t pci_in_le16( uint32_t base, uint32_t addr ) { - volatile uint32_t *ptr; - uint16_t val; - uint16_t rval; - uint32_t data; - - data = addr/4; - ptr = (volatile uint32_t *) (base + (data*4)); - data = *ptr; - if ( addr%4 == 0 ) - val = data & 0xffff; - else - val = (data>>16) & 0xffff; - - rval = rtems_uint16_from_little_endian( (uint8_t *) &val); - JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, data); - return rval; -} - -int16_t pci_in_16( uint32_t base, uint32_t addr ) { - volatile uint32_t *ptr; - uint16_t val; - uint32_t data; - - data = addr/4; - ptr = (volatile uint32_t *) (base + (data*4)); - data = *ptr; - if ( addr%4 == 0 ) - val = data & 0xffff; - else - val = (data>>16) & 0xffff; - - JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data); - return val; -} - -uint32_t pci_in_32( uint32_t base, uint32_t addr ) { - volatile uint32_t *ptr; - uint32_t val; - - ptr = (volatile uint32_t *) (base + addr); - val = *ptr; - - JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, val); - return val; -} -uint32_t pci_in_le32( uint32_t base, uint32_t addr ) { - volatile uint32_t *ptr; - uint32_t val; - uint32_t rval; - - ptr = (volatile uint32_t *) (base + addr); - val = *ptr; - rval = rtems_uint32_from_little_endian( (uint8_t *) &val); - - JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, val); - return rval; -} - -void pci_out_8( uint32_t base, uint32_t addr, uint8_t val ) { - volatile uint32_t *ptr; - - ptr = (volatile uint32_t *) (base + addr); - JPRINTK("Address: %p\n", ptr); - *ptr = val; - JPRINTK( "%p data: 0x%x\n", ptr, val); -} - -void pci_out_le16( uint32_t base, uint32_t addr, uint16_t val ) { - volatile uint32_t *ptr; - uint32_t out_data; - uint32_t data; - - ptr = (volatile uint32_t *) (base + (addr & ~0x3)); - data = *ptr; - if ( addr%4 == 0 ) - out_data = (data & 0xffff0000) | val; - else - out_data = ((val << 16)&0xffff0000) | (data & 0xffff); - rtems_uint32_to_little_endian( out_data, (uint8_t *) &data); - *ptr = data; - - JPRINTK( "0x%x data: 0x%x\n", ptr, data); -} - -void pci_out_16( uint32_t base, uint32_t addr, uint16_t val ) { - volatile uint32_t *ptr; - uint32_t out_data; - uint32_t data; - - ptr = (volatile uint32_t *) (base + (addr & ~0x3)); - data = *ptr; - if ( addr%4 == 0 ) - out_data = (data & 0xffff0000) | val; - else - out_data = ((val << 16)&0xffff0000) | (data & 0xffff); - *ptr = out_data; - - JPRINTK( "0x%x data: 0x%x\n", ptr, out_data); -} - -/* - * INDIRECT PCI CONFIGURATION ACCESSES - */ -int indirect_pci_read_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t *val -) { - - JPRINTK("==>\n"); - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - *val = in_8((uint32_t) (pci.pci_config_data + (offset&3)) ); - JPRINTK("\n\n"); - - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pci_read_config_word( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint16_t *val -) { - - JPRINTK("==>\n"); - - *val = 0xffff; - if (offset&1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - *val = in_16((uint32_t)(pci.pci_config_data + (offset&3))); - - JPRINTK("\n\n"); - - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pci_read_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint32_t *val -) { - uint32_t v; - JPRINTK("==>\n"); - - *val = 0xffffffff; - if (offset&3) - return PCIBIOS_BAD_REGISTER_NUMBER; - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - v = in_32( (uint32_t) pci.pci_config_data ); - *val = v; - if ( offset == 0x0b ) - JPRINTK( "%x:%x %x ==> 0x%08x, 0x%08x\n", bus, slot, function, v, *val ); - - JPRINTK("\n\n"); - - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pci_write_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t val -) { - - JPRINTK("==>\n"); - - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - out_8( (uint32_t) (pci.pci_config_data + (offset&3)), val); - - JPRINTK("\n\n"); - - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pci_write_config_word( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint16_t val -) { - - JPRINTK("==>\n"); - - if (offset&1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - out_16((uint32_t)(pci.pci_config_data + (offset&3)), val); - - JPRINTK("\n\n"); - - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pci_write_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint32_t val -) { - - if (offset&3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - JPRINTK("==>\n"); - - /* - * The Base Address Registers get accessed big endian while the - * other registers are little endian. - */ - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - if ( bus == 0 && slot == 0x0b && - (offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) ) { - out_32((uint32_t)pci.pci_config_data, val); - } else { - out_le32((uint32_t)pci.pci_config_data, val); - } - - JPRINTK("\n\n"); - - return PCIBIOS_SUCCESSFUL; -} - -/* - * DIRECT CONFIGUREATION ACCESSES. - */ -int direct_pci_read_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t *val -) { - if (bus != 0 || (1<\n"); - - *val=in_8((uint32_t) (pci.pci_config_data + ((1<\n"); - - *val=in_le16((uint32_t) - (pci.pci_config_data + ((1<\n"); - - *val=in_le32((uint32_t)(pci.pci_config_data + - ((1<\n"); - - out_8((uint32_t) (pci.pci_config_data + ((1<\n"); - - out_le16((uint32_t)(pci.pci_config_data + ((1<\n"); - - out_le32((uint32_t) - (pci.pci_config_data + ((1<pin_route[j].pin > -1; j++) { - if ( row->pin_route[j].pin == int_pin ) { - _nopin = 0; - - for (k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ ) { - if ( row->pin_route[j].int_name[k] == int_name ) { - _noname=0; break; - } - } - break; - } - } - - if( _nopin ) - { - printk( - "pci : Device %d:0x%02x:%d supplied a bogus interrupt_pin %d\n", - pbus, - pslot, - pfun, - int_pin - ); - return -1; - } - else - { - if( _noname ) { - unsigned char v = row->pin_route[j].int_name[0]; - printk( - "pci : Device %d:0x%02x:%d supplied a suspicious interrupt_line %d, ", - pbus, - pslot, - pfun, - int_name - ); - if ((row->opts & PCI_FIXUP_OPT_OVERRIDE_NAME) && 255 != - (v = row->pin_route[j].int_name[0]) - ) { - printk("OVERRIDING with %d from fixup table\n", v); - pci_write_config_byte(pbus,pslot,pfun,PCI_INTERRUPT_LINE,v); - } else { - printk("using it anyway\n"); - } - } - } - return 0; -} - -int FindPCIbridge( int mybus, struct pcibridge *pb ) -{ - int pbus, pslot; - uint8_t bussec, buspri; - uint16_t devid, vendorid, dclass; - - for(pbus=0; pbus< pci_bus_count(); pbus++) { - for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++) { - pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid); - if ( devid == 0xffff ) continue; - - pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid); - if ( vendorid == 0xffff ) continue; - - pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass); - - if ( dclass == PCI_CLASS_BRIDGE_PCI ) { - pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS, &buspri); - pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS, &bussec); - - #ifdef SHOW_PCI_SETTING - JPRINTK( - "pci : Found bridge at %d:0x%02x, mybus %d, pribus %d, secbus %d ", - pbus, - pslot, - mybus, - buspri, - bussec - ); - #endif - if ( bussec == mybus ) { - #ifdef SHOW_PCI_SETTING - JPRINTK("match\n"); - #endif - /* found our nearest bridge going towards the root */ - pb->bus = pbus; - pb->slot = pslot; - return 0; - } - #ifdef SHOW_PCI_SETTING - JPRINTK("no match\n"); - #endif - } - - } - } - return -1; -} - -void FixupPCI( const struct _int_map *bspmap, int (*swizzler)(int,int) ) -{ - unsigned char cvalue; - uint16_t devid; - int ismatch, i, j, pbus, pslot, pfun, int_pin, int_name, nfuns; - - /* - * If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific - * INTERRUPT_NAME if one isn't already in place. Then, drivers can - * trivially use INTERRUPT_NAME to hook up with devices. - */ - - for (pbus=0; pbus< pci_bus_count(); pbus++) { - for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) { - pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid); - if ( devid == 0xffff ) continue; - - /* got a device */ - pci_read_config_byte(pbus, pslot, 0, PCI_HEADER_TYPE, &cvalue); - nfuns = cvalue & PCI_HEADER_TYPE_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1; - for (pfun=0; pfun< nfuns; pfun++) { - - pci_read_config_word(pbus, pslot, pfun, PCI_DEVICE_ID, &devid); - if( devid == 0xffff ) continue; - - pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_PIN, &cvalue); - int_pin = cvalue; - - pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_LINE, &cvalue); - int_name = cvalue; - - #ifdef SHOW_PCI_SETTING - { - unsigned short cmd,stat; - unsigned char lat, seclat, csize; - - pci_read_config_word(pbus,pslot,pfun,PCI_COMMAND, &cmd ); - pci_read_config_word(pbus,pslot,pfun,PCI_STATUS, &stat ); - pci_read_config_byte(pbus,pslot,pfun,PCI_LATENCY_TIMER, &lat ); - pci_read_config_byte(pbus,pslot,pfun,PCI_SEC_LATENCY_TIMER, &seclat); - pci_read_config_byte(pbus,pslot,pfun,PCI_CACHE_LINE_SIZE, &csize ); - - JPRINTK( - "pci : device %d:0x%02x:%d cmd %04X, stat %04X, latency %d, " - " sec_latency %d, clsize %d\n", - pbus, - pslot, - pfun, - cmd, - stat, - lat, - seclat, - csize - ); - } - #endif - - if ( int_pin > 0 ) { - ismatch = 0; - - /* - * first run thru the bspmap table and see if we have an - * explicit configuration - */ - for (i=0; bspmap[i].bus > -1; i++) { - if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) { - ismatch = -1; - - /* we have a record in the table that gives specific - * pins and interrupts for devices in this slot - */ - if ( int_name == 255 ) { - - /* find the vector associated with whatever pin the - * device gives us - */ - for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ){ - if ( bspmap[i].pin_route[j].pin == int_pin ) { - int_name = bspmap[i].pin_route[j].int_name[0]; - break; - } - } - - if ( int_name == -1 ) { - printk( - "pci : Unable to resolve device %d:0x%02x:%d w/ " - "swizzled int pin %i to an interrupt_line.\n", - pbus, - pslot, - pfun, - int_pin - ); - } else { - PRINT_MSG(); - pci_write_config_byte( - pbus, - pslot, - pfun, - PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue) - ); - } - } else { - test_intname( &bspmap[i],pbus,pslot,pfun,int_pin,int_name); - } - break; - } - } - - if ( !ismatch ) { - /* - * no match, which means we're on a bus someplace. Work - * backwards from it to one of our defined busses, - * swizzling thru each bridge on the way. - */ - - /* keep pbus, pslot pointed to the device being - * configured while we track down the bridges using - * tbus,tslot. We keep searching the routing table because - * we may end up finding our bridge in it - */ - - int tbus= pbus, tslot= pslot; - for (;;) { - for (i=0; bspmap[i].bus > -1; i++) { - if ( bspmap[i].bus == tbus && - (bspmap[i].slot == tslot || bspmap[i].slot == -1)) - { - ismatch = -1; - - /* found a record for this bus, so swizzle the - * int_pin which we then use to find the - * interrupt_name. - */ - if ( int_name == 255 ) { - /* - * FIXME. I can't believe this little hack - * is right. It does not yield an error in - * convienently simple situations. - */ - if ( tbus ) int_pin = (*swizzler)(tslot,int_pin); - - /* - * int_pin points to the interrupt channel - * this card ends up delivering interrupts - * on. Find the int_name servicing it. - */ - for (int_name=-1, j=0; - bspmap[i].pin_route[j].pin > -1; - j++) - { - if ( bspmap[i].pin_route[j].pin == int_pin ) { - int_name = bspmap[i].pin_route[j].int_name[0]; - break; - } - } - - if ( int_name == -1 ) { - printk( - "pci : Unable to resolve device %d:0x%02x:%d w/ " - "swizzled int pin %i to an interrupt_line.\n", - pbus, - pslot, - pfun, - int_pin - ); - } else { - PRINT_MSG(); - pci_write_config_byte(pbus,pslot,pfun, - PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue)); - } - } else { - test_intname( - &bspmap[i], - pbus, - pslot, - pfun, - int_pin, - int_name - ); - } - goto donesearch; - } - } - if ( !ismatch ) { - struct pcibridge pb; - - /* - * Haven't found our bus in the int map, so work - * upwards thru the bridges till we find it. - */ - if ( FindPCIbridge( tbus, &pb )== 0 ) { - int_pin = (*swizzler)(tslot,int_pin); - - /* our next bridge up is on pb.bus, pb.slot- now - * instead of pointing to the device we're - * trying to configure, we move from bridge to - * bridge. - */ - tbus = pb.bus; - tslot = pb.slot; - } else { - printk( - "pci : No bridge from bus %i towards root found\n", - tbus - ); - goto donesearch; - } - } - } - } - - donesearch: - if ( !ismatch && int_pin != 0 && int_name == 255 ) { - printk( - "pci : Unable to match device %d:0x%02x:%d with an int " - "routing table entry\n", - pbus, - pslot, - pfun - ); - } - } - } - } - } -} - -void print_bars( - unsigned char slot, - unsigned char func -) -{ - uint32_t addr; - - printk( "*** BARs for slot=%d func=%d\n", slot, func ); - pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_0, &addr); - printk("*** PCI DEVICE BAR0: 0x%lx\n", addr); - pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_1, &addr); - printk("*** PCI DEVICE BAR1: 0x%lx\n", addr); - pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_2, &addr); - printk("*** PCI DEVICE BAR2: 0x%lx\n", addr); - pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_3, &addr); - printk("*** PCI DEVICE BAR3: 0x%lx\n", addr); - pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_4, &addr); - printk("*** PCI DEVICE BAR4: 0x%lx\n", addr); - pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_5, &addr); - printk("*** PCI DEVICE BAR5: 0x%lx\n", addr); -} - -void pci_memory_enable( - unsigned char bus, - unsigned char slot, - unsigned char function -) -{ - uint16_t data; - - pci_read_config_word(0, slot, function, PCI_COMMAND, &data); - data |= PCI_COMMAND_MEMORY; - pci_write_config_word(0, slot, function, PCI_COMMAND, data ); - pci_read_config_word(0, slot, function, PCI_COMMAND, &data); -} - -void pci_io_enable( - unsigned char bus, - unsigned char slot, - unsigned char function -) -{ - uint16_t data; - - pci_read_config_word(0, slot, function, PCI_COMMAND, &data); - data |= PCI_COMMAND_IO; - pci_write_config_word(0, slot, function, PCI_COMMAND, data ); -} - -void pci_busmaster_enable( - unsigned char bus, - unsigned char slot, - unsigned char function -) -{ - uint16_t data; - - pci_read_config_word(0, slot, function, PCI_COMMAND, &data); - data |= PCI_COMMAND_MASTER; - pci_write_config_word(0, slot, function, PCI_COMMAND, data ); -} - -/* - * This routine determines the maximum bus number in the system - */ -int pci_initialize(void) -{ - unsigned char slot, func, ucNumFuncs; - unsigned char ucHeader; - uint32_t class; - uint32_t device; - uint32_t vendor; - - /* - * Initialize GT_PCI0IOREMAP - */ - pci_out_32( BSP_PCI_BASE_ADDRESS, 0xf0, 0 ); - - /* - * According to Linux and BSD sources, this is needed to cover up a bug - * in some versions of the hardware. - */ - out_le32( PCI_CONFIG_ADDR, 0x80000020 ); - out_le32( PCI_CONFIG_DATA, 0x1be00000 ); - - /* - * Scan PCI bus 0 looking for the known Network devices and - * initializing the PCI for them. - */ - for (slot=0;slot> 16; - - /* This slot/function has a device fitted. */ - pci_read_config_dword(0, slot, func, PCI_CLASS_REVISION, &class); - class >>= 16; - - // printk( "FOUND DEVICE 0x%04x/0x%04x class 0x%x\n", - // vendor, device, class ); - if (class == PCI_CLASS_NETWORK_ETHERNET) { - JPRINTK("FOUND ETHERNET\n"); - - pci_write_config_byte( - 0, slot, func, PCI_INTERRUPT_LINE, MALTA_IRQ_ETHERNET ); - - /* - * Rewrite BAR1 for RTL8139 - */ - if ( vendor == PCI_VENDOR_ID_REALTEK && - device == PCI_DEVICE_ID_REALTEK_8139 ) { - - pci_memory_enable(0, slot, func); - pci_io_enable(0, slot, func); - pci_busmaster_enable(0, slot, func); - - // BAR0: IO at 0x0000_1001 - pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001001); - - // BAR1: Memory at 0x1203_1000 - pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12031000); - - // print_bars( slot, func ); - } else if ( vendor == PCI_VENDOR_ID_AMD && - device == PCI_DEVICE_ID_AMD_LANCE ) { - print_bars( slot, func ); - pci_memory_enable(0, slot, func); - pci_io_enable(0, slot, func); - pci_busmaster_enable(0, slot, func); - - // BAR0: IO at 0x0000_1041 - pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001041); - - // BAR1: Memory at 0x1201_1020 - pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12011020); - print_bars( slot, func ); - } - - } - } - } - return PCIB_ERR_SUCCESS; -} - -/* - * Return the number of PCI busses in the system - */ -unsigned char pci_bus_count(void) -{ - return (ucMaxPCIBus+1); -} diff --git a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am index e49d9915a0..3b5689968b 100644 --- a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am +++ b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am @@ -76,11 +76,11 @@ librtemsbsp_a_SOURCES += ../shared/flash/intelFlash.c librtemsbsp_a_SOURCES += flash/flashcfg.c #pci -librtemsbsp_a_SOURCES += ../shared/pci/pci.c -librtemsbsp_a_SOURCES += pci/gt_pci_init.c -librtemsbsp_a_SOURCES += pci/pci_io_remap.c -librtemsbsp_a_SOURCES += pci/motload_fixup.c -librtemsbsp_a_SOURCES += ../shared/pci/pcifinddevice.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/pci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/pci/gt_pci_init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/pci/pci_io_remap.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/beatnik/pci/motload_fixup.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/pcifinddevice.c #network if HAS_NETWORKING diff --git a/c/src/lib/libbsp/powerpc/beatnik/pci/gt_pci_init.c b/c/src/lib/libbsp/powerpc/beatnik/pci/gt_pci_init.c deleted file mode 100644 index 68d7467b22..0000000000 --- a/c/src/lib/libbsp/powerpc/beatnik/pci/gt_pci_init.c +++ /dev/null @@ -1,270 +0,0 @@ -/* PCI configuration space access */ - -/* - * Acknowledgements: - * Valuable information was obtained from the following drivers - * netbsd: (C) Allegro Networks Inc; Wasabi Systems Inc. - * linux: (C) MontaVista, Software, Inc; Chris Zankel, Mark A. Greer. - * rtems: (C) Brookhaven National Laboratory; K. Feng - */ - -/* - * Original file header of libbsp/shared/pci.c where this file is based upon. - * - * Copyright (C) 1999 valette@crf.canon.fr - * - * This code is heavily inspired by the public specification of STREAM V2 - * that can be found at : - * - * by following - * the STREAM API Specification Document link. - * - * 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. - * - * Till Straumann, , 1/2002 - * - separated bridge detection code out of this file - */ - -#include -#include -#include -#include -#include -#include - -/* set to max so we get early access to hose 0 */ -unsigned BSP_pci_hose1_bus_base = (unsigned)-1; - -#define MV64x60_PCI0_CONFIG_ADDR (BSP_MV64x60_BASE + 0xcf8) -#define MV64x60_PCI0_CONFIG_DATA (BSP_MV64x60_BASE + 0xcfc) -#define MV64x60_PCI1_CONFIG_ADDR (BSP_MV64x60_BASE + 0xc78) -#define MV64x60_PCI1_CONFIG_DATA (BSP_MV64x60_BASE + 0xc7c) - -#define PCI_BUS2HOSE(bus) (bus 255 ) { - rtems_panic("Too many PCI busses in the system"); - } - /* readjust total number */ - ucMaxPCIBus+=BSP_pci_hose1_bus_base; - - /* install new access functions that can hide the hoses */ - BSP_pci_configuration.pci_config_addr = (volatile unsigned char *)0xdeadbeef; - BSP_pci_configuration.pci_config_data = (volatile unsigned char *)0xdeadbeef; - BSP_pci_configuration.pci_functions = &pci_hosed_indirect_functions; -} - -#define PCI_ERR_BITS 0xf900 -#define PCI_STATUS_OK(x) (!((x)&PCI_ERR_BITS)) - -/* For now, just clear errors in the PCI status reg. - * - * Returns: (for diagnostic purposes) - * original settings (i.e. before applying the clearing - * sequence) - * (pci_status(hose_1)&0xff00) | ((pci_status(hose_2)>>8)&0xff) - */ - -static unsigned long clear_hose_errors(int bus, int quiet) -{ -unsigned long rval; -uint16_t pcistat; -int count; -int hose = PCI_BUS2HOSE(bus); - - /* read error status for info return */ - pci_read_config_word(bus,0,0,PCI_STATUS,&pcistat); - rval = pcistat; - - count=10; - do { - /* clear error reporting registers */ - - /* clear PCI status register */ - pci_write_config_word(bus,0,0,PCI_STATUS, PCI_ERR_BITS); - - /* read new status */ - pci_read_config_word(bus,0,0,PCI_STATUS, &pcistat); - - } while ( ! PCI_STATUS_OK(pcistat) && count-- ); - - if ( !PCI_STATUS_OK(rval) && !quiet) { - printk("Cleared PCI errors at discovery (hose %i): pci_stat was 0x%04lx\n", hose, rval); - } - if ( !PCI_STATUS_OK(pcistat) ) { - printk("Unable to clear PCI errors at discovery (hose %i) still 0x%04x after 10 attempts\n",hose, pcistat); - } - return rval; -} - -unsigned short -(*_BSP_clear_vmebridge_errors)(int) = 0; - -unsigned long -_BSP_clear_hostbridge_errors(int enableMCP, int quiet) -{ -unsigned long rval; - - /* MCP is not connected */ - if ( enableMCP ) - return -1; - - rval = (clear_hose_errors(0, quiet) & PCI_ERR_BITS)>>8; - rval |= clear_hose_errors(BSP_pci_hose1_bus_base, quiet) & PCI_ERR_BITS; - - /* Tsi148 doesn't propagate VME bus errors to PCI status reg. */ - if ( _BSP_clear_vmebridge_errors ) - rval |= _BSP_clear_vmebridge_errors(quiet)<<16; - - return rval; -} diff --git a/c/src/lib/libbsp/powerpc/beatnik/pci/motload_fixup.c b/c/src/lib/libbsp/powerpc/beatnik/pci/motload_fixup.c deleted file mode 100644 index 21d55916cb..0000000000 --- a/c/src/lib/libbsp/powerpc/beatnik/pci/motload_fixup.c +++ /dev/null @@ -1,180 +0,0 @@ -/* remap the zero-based PCI IO spaces of both hoses to a single - * address space - * - * This must be called AFTER to BSP_pci_initialize() - */ - -/* - * Authorship - * ---------- - * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was - * created by Till Straumann , 2005-2007, - * Stanford Linear Accelerator Center, Stanford University. - * - * Acknowledgement of sponsorship - * ------------------------------ - * The 'beatnik' BSP was produced by - * the Stanford Linear Accelerator Center, Stanford University, - * under Contract DE-AC03-76SFO0515 with the Department of Energy. - * - * Government disclaimer of liability - * ---------------------------------- - * Neither the United States nor the United States Department of Energy, - * nor any of their employees, makes any warranty, express or implied, or - * assumes any legal liability or responsibility for the accuracy, - * completeness, or usefulness of any data, apparatus, product, or process - * disclosed, or represents that its use would not infringe privately owned - * rights. - * - * Stanford disclaimer of liability - * -------------------------------- - * Stanford University makes no representations or warranties, express or - * implied, nor assumes any liability for the use of this software. - * - * Stanford disclaimer of copyright - * -------------------------------- - * Stanford University, owner of the copyright, hereby disclaims its - * copyright and all other rights in this software. Hence, anyone may - * freely use it for any purpose without restriction. - * - * Maintenance of notices - * ---------------------- - * In the interest of clarity regarding the origin and status of this - * SLAC software, this and all the preceding Stanford University notices - * are to remain affixed to any copy or derivative of this software made - * or distributed by the recipient and are to be affixed to any copy of - * software made or distributed by the recipient that contains a copy or - * derivative of this software. - * - * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 - */ -#include -#include -#include -#include -#include -#include -#include -#include "pci_io_remap.h" - -static int -fixup_irq_line(int bus, int slot, int fun, void *uarg) -{ -unsigned char line; - pci_read_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, &line); - if ( line < BSP_IRQ_GPP_0 ) { - pci_write_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, line + BSP_IRQ_GPP_0 ); - } - - return 0; -} - -void BSP_motload_pci_fixup(void) -{ -uint32_t b0,b1,r0,r1,lim,dis; - - /* MotLoad on the mvme5500 and mvme6100 configures the PCI - * busses nicely, i.e., the values read from the memory address - * space BARs by means of PCI config cycles directly reflect the - * CPU memory map. Thus, the presence of two hoses is already hidden. - * - * Unfortunately, all PCI I/O addresses are 'zero-based' i.e., - * a hose-specific base address would have to be added to - * the values read from config space. - * - * We fix this here so I/O BARs also reflect the CPU memory map. - * - * Furthermore, the mvme5500 uses - * f000.0000 - * ..f07f.ffff for PCI-0 / hose0 - * - * and - * - * f080.0000 - * ..f0ff.0000 for PCI-1 / hose 0 - * - * whereas the mvme6100 does it the other way round... - */ - - b0 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Low_Decode) ); - b1 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Low_Decode) ); - - r0 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap) ); - r1 = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap) ); - - switch ( BSP_getDiscoveryVersion(0) ) { - case MV_64360: - /* In case of the MV64360 the 'limit' is actually a 'size'! - * Disable by setting special bits in the 'BAR disable reg'. - */ - dis = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL) ); - /* disable PCI0 I/O and PCI1 I/O */ - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis | (1<<9) | (1<<14) ); - /* remap busses on hose 0; if the remap register was already set, assume - * that someone else [such as the bootloader] already performed the fixup - */ - if ( (b0 & 0xffff) && 0 == (r0 & 0xffff) ) { - rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xffff)<<16 ); - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xffff) ); - } - - /* remap busses on hose 1 */ - if ( (b1 & 0xffff) && 0 == (r1 & 0xffff) ) { - rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xffff)<<16 ); - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xffff) ); - } - - /* re-enable */ - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis ); - break; - - case GT_64260_A: - case GT_64260_B: - - if ( (b0 & 0xfff) && 0 == (r0 & 0xfff) ) { /* base are only 12 bits */ - /* switch window off by setting the limit < base */ - lim = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode) ); - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), 0 ); - /* remap busses on hose 0 */ - rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xfff)<<20 ); - - /* BTW: it seems that writing the base register also copies the - * value into the 'remap' register automatically (??) - */ - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xfff) ); - - /* re-enable */ - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), lim ); - } - - if ( (b1 & 0xfff) && 0 == (r1 & 0xfff) ) { /* base are only 12 bits */ - /* switch window off by setting the limit < base */ - lim = in_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode) ); - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), 0 ); - - /* remap busses on hose 1 */ - rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xfff)<<20 ); - - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xfff) ); - - /* re-enable */ - out_le32( (volatile uint32_t*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), lim ); - } - break; - - default: - rtems_panic("Unknown discovery version; switch in file: "__FILE__" not implemented (yet)"); - break; /* never get here */ - } - - /* Fixup the IRQ lines; the mvme6100 maps them nicely into our scheme, i.e., GPP - * interrupts start at 64 upwards - * - * The mvme5500 is apparently initialized differently :-(. GPP interrupts start at 0 - * Since all PCI interrupts are wired to GPP we simply check for a value < 64 and - * reprogram the interrupt line register. - */ - BSP_pciScan(0, fixup_irq_line, 0); -} - - diff --git a/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c b/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c deleted file mode 100644 index 56118d01d5..0000000000 --- a/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Adjust a PCI bus range's I/O address space by adding an offset */ - -/* - * Authorship - * ---------- - * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was - * created by Till Straumann , 2005-2007, - * Stanford Linear Accelerator Center, Stanford University. - * - * Acknowledgement of sponsorship - * ------------------------------ - * The 'beatnik' BSP was produced by - * the Stanford Linear Accelerator Center, Stanford University, - * under Contract DE-AC03-76SFO0515 with the Department of Energy. - * - * Government disclaimer of liability - * ---------------------------------- - * Neither the United States nor the United States Department of Energy, - * nor any of their employees, makes any warranty, express or implied, or - * assumes any legal liability or responsibility for the accuracy, - * completeness, or usefulness of any data, apparatus, product, or process - * disclosed, or represents that its use would not infringe privately owned - * rights. - * - * Stanford disclaimer of liability - * -------------------------------- - * Stanford University makes no representations or warranties, express or - * implied, nor assumes any liability for the use of this software. - * - * Stanford disclaimer of copyright - * -------------------------------- - * Stanford University, owner of the copyright, hereby disclaims its - * copyright and all other rights in this software. Hence, anyone may - * freely use it for any purpose without restriction. - * - * Maintenance of notices - * ---------------------- - * In the interest of clarity regarding the origin and status of this - * SLAC software, this and all the preceding Stanford University notices - * are to remain affixed to any copy or derivative of this software made - * or distributed by the recipient and are to be affixed to any copy of - * software made or distributed by the recipient that contains a copy or - * derivative of this software. - * - * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 - */ - -#include -#include -#include -#include -#include "pci_io_remap.h" - -#ifndef PCI_MULTI_FUN -#define PCI_MULTI_FUN 0x80 -#endif - -#ifndef PCI_HEADER_TYPE_MSK -#define PCI_HEADER_TYPE_MSK 0x7f -#endif - -/* Reconfigure all I/O base address registers for a range of PCI busses - * (from and including 'bus_from' up to and not including 'bus_to'). - * adding an offset. This involves adjusting the base and limit registers - * of PCI-PCI bridges, too. - * - * RESTRICTIONS: 'offset' must be 4k aligned (PCI req.); no argument check - * on the bus numbers is done. - * - * RETURNS: 0 on success and a number > 0 indicating the number of - * non-32bit bridges found where the offset couldn't be added. - * Devices behind such a bridge are not accessible through I/O - * and should probably be switched off (not done by this code). - */ -int -rtems_pci_io_remap(int bus_from, int bus_to, uint32_t offset) -{ - int rval = 0; - int bus, dev, fun, maxf; - int bar, numBars = 0; - uint8_t b; - uint16_t s; - uint32_t d; - unsigned int bas, lim; - - if ( offset & ((1<<12)-1) ) { - rtems_panic("rtems_pci_io_remap(): offset must be 4k aligned"); - return -1; - } - - - for ( bus=bus_from; bus < bus_to; bus++ ) { - for ( dev = 0; dev 0xffff || lim > 0xffff ) { - printk("PCI I/O range type 1 (16bit) bridge (@%i/%i/%i) found:\n", bus, dev, fun); - printk("WARNING: base (0x%08x) or limit (0x%08x) exceed 16-bit;\n", bas, lim); - printk(" devices behind this bridge are NOT accessible!\n"); - - /* FIXME: should we disable devices behind this bridge ? */ - bas = lim = 0; - } - break; - - case PCI_IO_RANGE_TYPE_32: - break; - } - - b = (uint8_t)((bas>>8) & PCI_IO_RANGE_MASK); - pci_write_config_byte( bus, dev, fun, PCI_IO_BASE, b ); - - s = (uint16_t)((bas>>16)&0xffff); - pci_write_config_word( bus, dev, fun, PCI_IO_BASE_UPPER16, s); - - b = (uint8_t)((lim>>8) & PCI_IO_RANGE_MASK); - pci_write_config_byte( bus, dev, fun, PCI_IO_LIMIT, b ); - s = (uint16_t)((lim>>16)&0xffff); - pci_write_config_word( bus, dev, fun, PCI_IO_LIMIT_UPPER16, s ); - } - } - } - } - return rval; -} diff --git a/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.h b/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.h deleted file mode 100644 index 533519a2ae..0000000000 --- a/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef RTEMS_PCI_IO_REMAP_H -#define RTEMS_PCI_IO_REMAP_H -/* Reconfigure all I/O base address registers for a range of PCI busses - * (from and including 'bus_from' up to and not including 'bus_to'). - * adding an offset. This involves adjusting the base and limit registers - * of PCI-PCI bridges, too. - * - * RESTRICTIONS: 'offset' must be 4k aligned (PCI req.); no argument check - * on the bus numbers is done. - * - * RETURNS: 0 on success and a number > 0 indicating the number of - * non-32bit bridges found where the offset couldn't be added. - * Devices behind such a bridge are not accessible through I/O - * and should probably be switched off (not done by this code). - */ - -int -rtems_pci_io_remap(int bus_from, int bus_to, uint32_t offset); - -/* - * Authorship - * ---------- - * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was - * created by Till Straumann , 2005-2007, - * Stanford Linear Accelerator Center, Stanford University. - * - * Acknowledgement of sponsorship - * ------------------------------ - * The 'beatnik' BSP was produced by - * the Stanford Linear Accelerator Center, Stanford University, - * under Contract DE-AC03-76SFO0515 with the Department of Energy. - * - * Government disclaimer of liability - * ---------------------------------- - * Neither the United States nor the United States Department of Energy, - * nor any of their employees, makes any warranty, express or implied, or - * assumes any legal liability or responsibility for the accuracy, - * completeness, or usefulness of any data, apparatus, product, or process - * disclosed, or represents that its use would not infringe privately owned - * rights. - * - * Stanford disclaimer of liability - * -------------------------------- - * Stanford University makes no representations or warranties, express or - * implied, nor assumes any liability for the use of this software. - * - * Stanford disclaimer of copyright - * -------------------------------- - * Stanford University, owner of the copyright, hereby disclaims its - * copyright and all other rights in this software. Hence, anyone may - * freely use it for any purpose without restriction. - * - * Maintenance of notices - * ---------------------- - * In the interest of clarity regarding the origin and status of this - * SLAC software, this and all the preceding Stanford University notices - * are to remain affixed to any copy or derivative of this software made - * or distributed by the recipient and are to be affixed to any copy of - * software made or distributed by the recipient that contains a copy or - * derivative of this software. - * - * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 - */ - -#endif - diff --git a/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am b/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am index 0ebc88d088..fba8eefc01 100644 --- a/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am +++ b/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am @@ -70,10 +70,10 @@ librtemsbsp_a_SOURCES += ../shared/motorola/motorola.c librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/irq/openpic.c # pci -librtemsbsp_a_SOURCES += ../shared/pci/pci.c -librtemsbsp_a_SOURCES += ../shared/pci/detect_raven_bridge.c -librtemsbsp_a_SOURCES += ../shared/pci/generic_clear_hberrs.c -librtemsbsp_a_SOURCES += ../shared/pci/pcifinddevice.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/pci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/detect_raven_bridge.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/generic_clear_hberrs.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/pcifinddevice.c # residual librtemsbsp_a_SOURCES += ../shared/residual/residual.c diff --git a/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am b/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am index 1c3a18e51a..04673f89b3 100644 --- a/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am +++ b/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am @@ -63,10 +63,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/irq/openpic_i8259 librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/irq/openpic.c # pci -librtemsbsp_a_SOURCES += ../shared/pci/pci.c -librtemsbsp_a_SOURCES += pci/detect_host_bridge.c -librtemsbsp_a_SOURCES += ../shared/pci/generic_clear_hberrs.c -librtemsbsp_a_SOURCES += ../shared/pci/pcifinddevice.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/pci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mvme3100/pci/detect_host_bridge.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/generic_clear_hberrs.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/pci/pcifinddevice.c # flash librtemsbsp_a_SOURCES += ../shared/flash/flash.c diff --git a/c/src/lib/libbsp/powerpc/mvme3100/pci/detect_host_bridge.c b/c/src/lib/libbsp/powerpc/mvme3100/pci/detect_host_bridge.c deleted file mode 100644 index 8488c99dc5..0000000000 --- a/c/src/lib/libbsp/powerpc/mvme3100/pci/detect_host_bridge.c +++ /dev/null @@ -1,113 +0,0 @@ -/* PCI Initialization */ - -/* - * Authorship - * ---------- - * This software ('mvme3100' RTEMS BSP) was created by - * - * Till Straumann , 2005-2007, - * Stanford Linear Accelerator Center, Stanford University. - * - * Acknowledgement of sponsorship - * ------------------------------ - * The 'mvme3100' BSP was produced by - * the Stanford Linear Accelerator Center, Stanford University, - * under Contract DE-AC03-76SFO0515 with the Department of Energy. - * - * Government disclaimer of liability - * ---------------------------------- - * Neither the United States nor the United States Department of Energy, - * nor any of their employees, makes any warranty, express or implied, or - * assumes any legal liability or responsibility for the accuracy, - * completeness, or usefulness of any data, apparatus, product, or process - * disclosed, or represents that its use would not infringe privately owned - * rights. - * - * Stanford disclaimer of liability - * -------------------------------- - * Stanford University makes no representations or warranties, express or - * implied, nor assumes any liability for the use of this software. - * - * Stanford disclaimer of copyright - * -------------------------------- - * Stanford University, owner of the copyright, hereby disclaims its - * copyright and all other rights in this software. Hence, anyone may - * freely use it for any purpose without restriction. - * - * Maintenance of notices - * ---------------------- - * In the interest of clarity regarding the origin and status of this - * SLAC software, this and all the preceding Stanford University notices - * are to remain affixed to any copy or derivative of this software made - * or distributed by the recipient and are to be affixed to any copy of - * software made or distributed by the recipient that contains a copy or - * derivative of this software. - * - * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 - */ - -#include -#include -#include -#include -#include - -/* Motload configures PCI interrupts to start at 16 and up but - * we'd rather have them starting at 0. - * Use this callback to fix them up. - */ -static int -fixup_irq_line(int bus, int slot, int fun, void *uarg) -{ -unsigned char line; - pci_read_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, &line); - if ( line >= BSP_EXT_IRQ_NUMBER ) { - pci_write_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, line - BSP_EXT_IRQ_NUMBER ); - } - - return 0; -} - -void BSP_motload_pci_fixup(void) -{ - BSP_pciScan(0, fixup_irq_line, 0); -} - -void detect_host_bridge(void) -{ - OpenPIC = (volatile struct OpenPIC *) (BSP_8540_CCSR_BASE + BSP_OPEN_PIC_BASE_OFFSET); -} - -static int -dump_dev_cb( - int bus, - int dev, - int fun, - void *uarg -) -{ - uint16_t vi,di; - uint16_t cd,st; - uint32_t b1,b2; - uint8_t il,ip; - - pci_read_config_word (bus, dev, fun, PCI_VENDOR_ID, &vi); - pci_read_config_word (bus, dev, fun, PCI_DEVICE_ID, &di); - pci_read_config_word (bus, dev, fun, PCI_COMMAND, &cd); - pci_read_config_word (bus, dev, fun, PCI_STATUS, &st); - pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_0, &b1); - pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_1, &b2); - pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_LINE, &il); - pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_PIN, &ip); - - printk("%3d:0x%02x:%d 0x%04x-0x%04x: 0x%04x 0x%04x 0x%08" PRIx32 " 0x%08" PRIx32 " %d -> %3d (=0x%02x)\n", - bus, dev, fun, vi, di, cd, st, b1, b2, ip, il, il); - return 0; -} - -void -BSP_pciConfigDump_early(void) -{ - printk("BUS:SLOT:FUN VENDOR-DEV_ID: COMMAND STATUS BASE_ADDR0 BASE_ADDR1 IRQ_PIN -> IRQ_LINE\n"); - BSP_pciScan(0, dump_dev_cb, 0); -} diff --git a/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am b/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am index a3cfcfb7b5..e2e57d8345 100644 --- a/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am +++ b/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am @@ -33,9 +33,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/uart.c librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/console.c # pci -librtemsbsp_a_SOURCES += pci/pci.c -librtemsbsp_a_SOURCES += pci/pci_interface.c -librtemsbsp_a_SOURCES += pci/detect_host_bridge.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mvme5500/pci/pci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mvme5500/pci/pci_interface.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mvme5500/pci/detect_host_bridge.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/pci/pci_find_device.c # irq diff --git a/c/src/lib/libbsp/powerpc/mvme5500/pci/detect_host_bridge.c b/c/src/lib/libbsp/powerpc/mvme5500/pci/detect_host_bridge.c deleted file mode 100644 index 3bd5b00d7a..0000000000 --- a/c/src/lib/libbsp/powerpc/mvme5500/pci/detect_host_bridge.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * detect_host_bridge.c - * - * This code is inspired by detect_grackle_bridge.c of SVGM BSP - * written by Till Straumann - * Copyright (C) 2001, 2003 Till Straumann - * - * Copyright (C) 2004 S. Kate Feng, - * wrote it to support the MVME5500 board. - * - */ -#include -#include /* printk */ - -#include -#include -#include - -#include -#include -#include - -#define PCI_DEBUG 0 - -#define HOSTBRIDGET_ERROR 0xf0000000 - -unsigned long _BSP_clear_hostbridge_errors(int enableMCP, int quiet) -{ - uint32_t pcidata, pcidata1; - int PciLocal, busNumber=0; - - /* On the mvme5500 board, the GT64260B system controller had the MCP - * signal pulled up high. Thus, the MCP signal is not used as it is - * on other boards such as mvme2307. - */ - if (enableMCP) return(-1); - for (PciLocal=0; PciLocal<1; PciLocal++ ) { - pci_read_config_dword(busNumber, - 0, - 0, - PCI_COMMAND, - &pcidata); - - if (!quiet) - printk("Before _BSP_clear_hostbridge_errors(): 0x%" PRIx32 ", cause 0x%lx\n", - pcidata, inl(0x1d58)); - - outl(0,0x1d58); - - /* Clear the error on the host bridge */ - pcidata1= pcidata; - pcidata1 |= PCI_STATUS_CLRERR_MASK; - pcidata1 |= 0x140; - pci_write_config_dword(busNumber, - 0, - 0, - PCI_COMMAND, - pcidata1); - - pci_read_config_dword(busNumber, - 0, - 0, - PCI_COMMAND, - &pcidata1); - - if (!quiet) printk("After _BSP_clear_hostbridge_errors(): sts 0x%" PRIx32 "\n", - pcidata1); - if (pcidata1 & HOSTBRIDGET_ERROR) printk("BSP_clear_hostbridge_errors(): unable to clear pending hostbridge errors\n"); - busNumber += BSP_MAX_PCI_BUS_ON_PCI0; - } - return(pcidata & HOSTBRIDGET_ERROR); -} diff --git a/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c b/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c deleted file mode 100644 index 8ef5876047..0000000000 --- a/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * pci.c : this file contains basic PCI Io functions. - * - * CopyRight (C) 1999 valette@crf.canon.fr - * - * This code is heavilly inspired by the public specification of STREAM V2 - * that can be found at : - * - * by following - * the STREAM API Specification Document link. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/rtems/license.html. - * - * Copyright 2004, 2008 Brookhaven National Laboratory and - * Shuchen K. Feng, - * - * - to be consistent with the original pci.c written by Eric Valette - * - added 2nd PCI support for discovery based PCI bridge (e.g. mvme5500/mvme6100) - * - added bus support for the expansion of PMCSpan as per request by Peter - */ -#define PCI_MAIN - -#include -#include /* printk */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_DEBUG 0 -#define PCI_PRINT 1 - -/* allow for overriding these definitions */ -#ifndef PCI_CONFIG_ADDR -#define PCI_CONFIG_ADDR 0xcf8 -#endif -#ifndef PCI_CONFIG_DATA -#define PCI_CONFIG_DATA 0xcfc -#endif - -#ifndef PCI1_CONFIG_ADDR -#define PCI1_CONFIG_ADDR 0xc78 -#endif -#ifndef PCI1_CONFIG_DATA -#define PCI1_CONFIG_DATA 0xc7c -#endif - -#define HOSTBRIDGET_ERROR 0xf0000000 - -#define GT64x60_PCI_CONFIG_ADDR GT64x60_REG_BASE + PCI_CONFIG_ADDR -#define GT64x60_PCI_CONFIG_DATA GT64x60_REG_BASE + PCI_CONFIG_DATA - -#define GT64x60_PCI1_CONFIG_ADDR GT64x60_REG_BASE + PCI1_CONFIG_ADDR -#define GT64x60_PCI1_CONFIG_DATA GT64x60_REG_BASE + PCI1_CONFIG_DATA - -static int numPCIDevs=0; -static DiscoveryChipVersion BSP_sysControllerVersion = 0; -static BSP_VMEchipTypes BSP_VMEinterface = 0; -static rtems_pci_config_t BSP_pci[2]={ - {(volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR), - (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA), - 0 /* defined at BSP_pci_configuration */}, - {(volatile unsigned char*) (GT64x60_PCI1_CONFIG_ADDR), - (volatile unsigned char*) (GT64x60_PCI1_CONFIG_DATA), - 0 /* defined at BSP_pci_configuration */} -}; - -/* Pack RegNum,FuncNum,DevNum,BusNum,and ConfigEnable for - * PCI Configuration Address Register - */ -#define pciConfigPack(bus,dev,func,offset)\ -((offset&~3)<<24)|(PCI_DEVFN(dev,func)<<16)|(bus<<8)|0x80 - -/* - * Bit encode for PCI_CONFIG_HEADER_TYPE register - */ -static unsigned char ucMaxPCIBus=0; - -/* Please note that PCI0 and PCI1 does not correlate with the busNum 0 and 1. - */ -static int indirect_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func, -unsigned char offset, uint8_t *val) -{ - int n=0; - - if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { - bus-=BSP_MAX_PCI_BUS_ON_PCI0; - n=1; - } - - *val = 0xff; - if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER; -#if 0 - printk("addr %x, data %x, pack %x \n", BSP_pci[n].pci_config_addr), - BSP_pci[n].config_data,pciConfigPack(bus,dev,func,offset)); -#endif - - out_be32((volatile uint32_t *) BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); - *val = in_8(BSP_pci[n].pci_config_data + (offset&3)); - return PCIBIOS_SUCCESSFUL; -} - -static int indirect_pci_read_config_word(unsigned char bus, unsigned char dev, -unsigned char func, unsigned char offset, uint16_t *val) -{ - int n=0; - - if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { - bus-=BSP_MAX_PCI_BUS_ON_PCI0; - n=1; - } - - *val = 0xffff; - if ((offset&1)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER; -#if 0 - printk("addr %x, data %x, pack %x \n", config_addr, - config_data,pciConfigPack(bus,dev,func,offset)); -#endif - out_be32((volatile uint32_t *) BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); - *val = in_le16((volatile uint16_t *) (BSP_pci[n].pci_config_data + (offset&2))); - return PCIBIOS_SUCCESSFUL; -} - -static int indirect_pci_read_config_dword(unsigned char bus, unsigned char dev, -unsigned char func, unsigned char offset, uint32_t *val) -{ - int n=0; - - if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { - bus-=BSP_MAX_PCI_BUS_ON_PCI0; - n=1; - } - - *val = 0xffffffff; - if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER; - - out_be32((volatile uint32_t *)BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); - *val = in_le32((volatile uint32_t *)BSP_pci[n].pci_config_data); - return PCIBIOS_SUCCESSFUL; -} - -static int indirect_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, uint8_t val) -{ - int n=0; - - if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { - bus-=BSP_MAX_PCI_BUS_ON_PCI0; - n=1; - } - - if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER; - - out_be32((volatile uint32_t *)BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); - out_8((volatile uint8_t *) (BSP_pci[n].pci_config_data + (offset&3)), val); - return PCIBIOS_SUCCESSFUL; -} - -static int indirect_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, uint16_t val) -{ - int n=0; - - if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { - bus-=BSP_MAX_PCI_BUS_ON_PCI0; - n=1; - } - - if ((offset&1)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER; - - out_be32((volatile uint32_t *)BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); - out_le16((volatile uint16_t *)(BSP_pci[n].pci_config_data + (offset&3)), val); - return PCIBIOS_SUCCESSFUL; -} - -static int indirect_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, uint32_t val) -{ - int n=0; - - if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { - bus-=BSP_MAX_PCI_BUS_ON_PCI0; - n=1; - } - - if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER; - - out_be32((volatile uint32_t *)BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); - out_le32((volatile uint32_t *)BSP_pci[n].pci_config_data, val); - return PCIBIOS_SUCCESSFUL; -} - -const pci_config_access_functions pci_indirect_functions = { - indirect_pci_read_config_byte, - indirect_pci_read_config_word, - indirect_pci_read_config_dword, - indirect_pci_write_config_byte, - indirect_pci_write_config_word, - indirect_pci_write_config_dword -}; - - -rtems_pci_config_t BSP_pci_configuration = { - (volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR), - (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA), - &pci_indirect_functions}; - -DiscoveryChipVersion BSP_getDiscoveryChipVersion(void) -{ - return(BSP_sysControllerVersion); -} - -BSP_VMEchipTypes BSP_getVMEchipType(void) -{ - return(BSP_VMEinterface); -} - -/* - * This routine determines the maximum bus number in the system. - * The PCI_SUBORDINATE_BUS is not supported in GT6426xAB. Thus, - * it's not used. - * - */ -int pci_initialize(void) -{ - int deviceFound; - unsigned char ucBusNumber, ucSlotNumber, ucFnNumber, ucNumFuncs, data8; - uint32_t ulHeader, ulClass, ulDeviceID; -#if PCI_DEBUG - uint32_t pcidata; -#endif - - /* - * Scan PCI0 and PCI1 buses - */ - for (ucBusNumber=0; ucBusNumber PCI_MAX_DEVICES) { - rtems_panic("Too many PCI devices found; increase PCI_MAX_DEVICES in pci.h\n"); - } - - if (!deviceFound) deviceFound=1; - switch(ulDeviceID) { - case (PCI_VENDOR_ID_MARVELL+(PCI_DEVICE_ID_MARVELL_GT6426xAB<<16)): - pci_read_config_byte(0,0,0,PCI_REVISION_ID, &data8); - switch(data8) { - case 0x10: - BSP_sysControllerVersion = GT64260A; -#if PCI_PRINT - printk("Marvell GT64260A (Discovery I) hostbridge detected at bus%d slot%d\n", - ucBusNumber,ucSlotNumber); -#endif - break; - case 0x20: - BSP_sysControllerVersion = GT64260B; -#if PCI_PRINT - printk("Marvell GT64260B (Discovery I) hostbridge detected at bus%d slot%d\n", - ucBusNumber,ucSlotNumber); -#endif - break; - default: - printk("Undefined revsion of GT64260 chip\n"); - break; - } - break; - case PCI_VENDOR_ID_TUNDRA: -#if PCI_PRINT - printk("TUNDRA PCI-VME bridge detected at bus%d slot%d\n", - ucBusNumber,ucSlotNumber); -#endif - break; - case (PCI_VENDOR_ID_DEC+(PCI_DEVICE_ID_DEC_21150<<16)): -#if PCI_PRINT - printk("DEC21150 PCI-PCI bridge detected at bus%d slot%d\n", - ucBusNumber,ucSlotNumber); -#endif - break; - default : -#if PCI_PRINT - printk("BSP unlisted vendor, Bus%d Slot%d DeviceID 0x%" PRIx32 "\n", - ucBusNumber,ucSlotNumber, ulDeviceID); -#endif - /* Kate Feng : device not supported by BSP needs to remap the IRQ line on mvme5500/mvme6100 */ - pci_read_config_byte(ucBusNumber,ucSlotNumber,0,PCI_INTERRUPT_LINE,&data8); - if (data8 < BSP_GPP_IRQ_LOWEST_OFFSET) pci_write_config_byte(ucBusNumber, - ucSlotNumber,0,PCI_INTERRUPT_LINE,BSP_GPP_IRQ_LOWEST_OFFSET+data8); - - break; - } - -#if PCI_DEBUG - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_BASE_ADDRESS_0, - &data); - printk("Bus%d BASE_ADDRESS_0 0x%x \n",ucBusNumber, data); - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_BASE_ADDRESS_1, - &data); - printk("Bus%d BASE_ADDRESS_1 0x%x \n",ucBusNumber, data); - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_BASE_ADDRESS_2, - &data); - printk("Bus%d BASE_ADDRESS_2 0x%x \n", ucBusNumber, data); - - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_BASE_ADDRESS_3, - &data); - printk("Bus%d BASE_ADDRESS_3 0x%x \n", ucBusNumber, data); - - pci_read_config_word(ucBusNumber, - ucSlotNumber, - 0, - PCI_INTERRUPT_LINE, - &sdata); - printk("Bus%d INTERRUPT_LINE 0x%x \n", ucBusNumber, sdata); - - /* We always enable internal memory. */ - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_MEM_BASE_ADDR, - &pcidata); - printk("Bus%d MEM_BASE_ADDR 0x%x \n", ucBusNumber,pcidata); - - /* We always enable internal IO. */ - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_IO_BASE_ADDR, - &pcidata); - printk("Bus%d IO_BASE_ADDR 0x%x \n", ucBusNumber,pcidata); -#endif - - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_CACHE_LINE_SIZE, - &ulHeader); - if ((ulHeader>>16)&PCI_HEADER_TYPE_MULTI_FUNCTION) - ucNumFuncs=PCI_MAX_FUNCTIONS; - else - ucNumFuncs=1; - -#if PCI_DEBUG - printk("Bus%d Slot 0x%x HEADER/LAT/CACHE 0x%x \n", - ucBusNumber, ucSlotNumber, ulHeader); -#endif - - for (ucFnNumber=1;ucFnNumber - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution. - * - * 8/17/2006 : S. Kate Feng - * uses in_le32()/out_le32(), instead of inl()/outl() for compatibility. - * - * 11/2008 : Enable "PCI Read Agressive Prefetch", - * "PCI Read Line Agressive Prefetch", and - * "PCI Read Multiple Agressive Prefetch" to improve the - * performance of the PCI based applications (e.g. 1GHz NIC). - */ - -#include -#include /* printk */ - -#include -#include -#include -#include - -#include - -#define PCI_DEBUG 0 - -#if 0 -#define CPU2PCI_ORDER -#define PCI2CPU_ORDER -#endif - -/* PCI Read Agressive Prefetch Enable (1<<16 ), - * PCI Read Line Agressive Prefetch Enable( 1<<17), - * PCI Read Multiple Agressive Prefetch Enable (1<<18). - */ -#ifdef PCI2CPU_ORDER -#define PCI_ACCCTLBASEL_VALUE 0x01079000 -#else -#define PCI_ACCCTLBASEL_VALUE 0x01071000 -#endif - - -#define ConfSBDis 0x10000000 /* 1: disable, 0: enable */ -#define IOSBDis 0x20000000 /* 1: disable, 0: enable */ -#define ConfIOSBDis 0x30000000 -#define CpuPipeline 0x00002000 /* optional, 1:enable, 0:disable */ - -/* CPU to PCI ordering register */ -#define DLOCK_ORDER_REG 0x2D0 /* Deadlock and Ordering register */ -#define PCI0OrEn 0x00000001 -#define PCI1OrEn 0x00000020 -#define PCIOrEn 0x40000000 -#define PCIOrEnMASK 0x40000021 - -#define CNT_SYNC_REG 0x2E0 /* Counters and Sync Barrier register */ -#define L0SyncBar 0x00001000 -#define L1SyncBar 0x00002000 -#define DSyncBar 0x00004000 -#define SyncBarMode 0x00008000 -#define SyncBarMASK 0x0000f000 - -#define WRTBK_PRIO_BUFFER 0x2d8 /* writback priority and buffer depth */ - -#define ADDR_PIPELINE 0x00020000 - -void pciAccessInit(void); - -void pci_interface(void) -{ - -#ifdef CPU2PCI_ORDER - /* MOTLOad deafult : 0x07ff8600 */ - out_le32((volatile uint32_t *)(GT64x60_REG_BASE+CNT_SYNC_REG), 0x07fff600); -#endif - /* asserts SERR upon various detection */ - out_le32((volatile uint32_t *)(GT64x60_REG_BASE+0xc28), 0x3fffff); - pciAccessInit(); -} - -void pciAccessInit(void) -{ - unsigned int PciLocal, data; - - for (PciLocal=0; PciLocal < 2; PciLocal++) { - data = in_le32((volatile uint32_t *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80))); -#if 0 - printk("PCI%d_ACCESS_CNTL_BASE0_LOW was 0x%x\n",PciLocal,data); -#endif - data |= PCI_ACCCTLBASEL_VALUE; - data &= ~0x300000; - out_le32((volatile uint32_t *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)), data); -#if 0 - printf("PCI%d_ACCESS_CNTL_BASE0_LOW now 0x%" PRIx32 "\n",PciLocal,in_le32((volatile uint32_t *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)))); -#endif - } -} - diff --git a/c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c b/c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c deleted file mode 100644 index 0a1c04a2e2..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define SHOW_RAVEN_SETTINGS - -#define RAVEN_MPIC_IOSPACE_ENABLE 0x0001 -#define RAVEN_MPIC_MEMSPACE_ENABLE 0x0002 -#define RAVEN_MASTER_ENABLE 0x0004 -#define RAVEN_PARITY_CHECK_ENABLE 0x0040 -#define RAVEN_SYSTEM_ERROR_ENABLE 0x0100 -#define RAVEN_CLEAR_EVENTS_MASK 0xf9000000 - -#define RAVEN_MPIC_MEREN ((volatile unsigned *)0xfeff0020) -#define RAVEN_MPIC_MERST ((volatile unsigned *)0xfeff0024) -#define MEREN_VAL 0x2f00 - -#define pci BSP_pci_configuration - -extern const pci_config_access_functions pci_direct_functions; -extern const pci_config_access_functions pci_indirect_functions; - -#if defined(mvme2100) -/* FIXME - this should really be in a separate file - the 2100 doesn't - * have a raven chip so there is no point having 2100 code here - */ - -extern unsigned int EUMBBAR; - -void detect_host_bridge(void) -{ - /* - * If the processor is an 8240 or an 8245 then the PIC is built - * in instead of being on the PCI bus. The MVME2100 is using Processor - * Address Map B (CHRP) although the Programmer's Reference Guide says - * it defaults to Map A. - */ - /* We have an EPIC Interrupt Controller */ - OpenPIC = (volatile struct OpenPIC *) (EUMBBAR + BSP_OPEN_PIC_BASE_OFFSET); - pci.pci_functions = &pci_indirect_functions; - pci.pci_config_addr = (volatile unsigned char *) 0xfec00000; - pci.pci_config_data = (volatile unsigned char *) 0xfee00000; -} - -#else - -#if 0 -/* Unfortunately, PCI config space access to empty slots generates - * a 'signalled master abort' condition --> we can't really use - * the machine check interrupt for memory probing unless - * we use probing for PCI scanning also (which would make - * all that code either BSP dependent or requiring yet another - * API, sigh...). - * So for the moment, we just don't use MCP on all mvme2xxx - * boards (using the generic, hostbridge-independent 'clear' - * implementation [generic_clear_hberrs.c]). - */ -/* - * enableMCP: whether to enable MCP checkstop / machine check interrupts - * on the hostbridge and in HID0. - * - * NOTE: HID0 and MEREN are left alone if this flag is 0 - * - * quiet : be silent - * - * RETURNS : raven MERST register contents (lowermost 16 bits), 0 if - * there were no errors - */ -unsigned long -_BSP_clear_hostbridge_errors(int enableMCP, int quiet) -{ -unsigned merst; - - merst = in_be32(RAVEN_MPIC_MERST); - /* write back value to clear status */ - out_be32(RAVEN_MPIC_MERST, merst); - - if (enableMCP) { - if (!quiet) - printk("Enabling MCP generation on hostbridge errors\n"); - out_be32(RAVEN_MPIC_MEREN, MEREN_VAL); - } else { - out_be32(RAVEN_MPIC_MEREN, 0); - if ( !quiet && enableMCP ) { - printk("leaving MCP interrupt disabled\n"); - } - } - return (merst & 0xffff); -} -#endif - -void detect_host_bridge(void) -{ - PPC_DEVICE *hostbridge; - uint32_t id0; - uint32_t tmp; - - /* - * This code assumes that the host bridge is located at - * bus 0, dev 0, func 0 AND that the old pre PCI 2.1 - * standard devices detection mechanism that was used on PC - * (still used in BSD source code) works. - */ - hostbridge=residual_find_device(&residualCopy, PROCESSORDEVICE, NULL, - BridgeController, - PCIBridge, -1, 0); - if (hostbridge) { - if (hostbridge->DeviceId.Interface==PCIBridgeIndirect) { - pci.pci_functions=&pci_indirect_functions; - /* Should be extracted from residual data, - * indeed MPC106 in CHRP mode is different, - * but we should not use residual data in - * this case anyway. - */ - pci.pci_config_addr = ((volatile unsigned char *) - (ptr_mem_map->io_base+0xcf8)); - pci.pci_config_data = ptr_mem_map->io_base+0xcfc; - } else if(hostbridge->DeviceId.Interface==PCIBridgeDirect) { - pci.pci_functions=&pci_direct_functions; - pci.pci_config_data=(unsigned char *) 0x80800000; - } else { - } - } else { - /* Let us try by experimentation at our own risk! */ - pci.pci_functions = &pci_direct_functions; - /* On all direct bridges I know the host bridge itself - * appears as device 0 function 0. - */ - pci_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &id0); - if (id0==~0U) { - pci.pci_functions = &pci_indirect_functions; - pci.pci_config_addr = ((volatile unsigned char*) - (ptr_mem_map->io_base+0xcf8)); - pci.pci_config_data = ((volatile unsigned char*)ptr_mem_map->io_base+0xcfc); - } - /* Here we should check that the host bridge is actually - * present, but if it not, we are in such a desperate - * situation, that we probably can't even tell it. - */ - } - pci_read_config_dword(0, 0, 0, 0, &id0); -#ifdef SHOW_RAVEN_SETTINGS - printk("idreg 0 = 0x%" PRIu32 "\n",id0); -#endif - if((id0 == PCI_VENDOR_ID_MOTOROLA + - (PCI_DEVICE_ID_MOTOROLA_RAVEN<<16)) || - (id0 == PCI_VENDOR_ID_MOTOROLA + - (PCI_DEVICE_ID_MOTOROLA_HAWK<<16))) { - /* - * We have a Raven bridge. We will get information about its settings - */ - pci_read_config_dword(0, 0, 0, PCI_COMMAND, &id0); -#ifdef SHOW_RAVEN_SETTING - printk("RAVEN PCI command register = %x\n",id0); -#endif - id0 |= RAVEN_CLEAR_EVENTS_MASK; - pci_write_config_dword(0, 0, 0, PCI_COMMAND, id0); - pci_read_config_dword(0, 0, 0, PCI_COMMAND, &id0); -#ifdef SHOW_RAVEN_SETTING - printk("After error clearing RAVEN PCI command register = %x\n",id0); -#endif - - if (id0 & RAVEN_MPIC_IOSPACE_ENABLE) { - pci_read_config_dword(0, 0, 0,PCI_BASE_ADDRESS_0, &tmp); -#ifdef SHOW_RAVEN_SETTING - printk("Raven MPIC is accessed via IO Space Access at address : %x\n",(tmp & ~0x1)); -#endif - } - if (id0 & RAVEN_MPIC_MEMSPACE_ENABLE) { - pci_read_config_dword(0, 0, 0,PCI_BASE_ADDRESS_1, &tmp); -#ifdef SHOW_RAVEN_SETTING - printk("Raven MPIC is accessed via memory Space Access at address : %x\n", tmp); -#endif - OpenPIC=(volatile struct OpenPIC *) (tmp + PREP_ISA_MEM_BASE); - printk("OpenPIC found at %p.\n", OpenPIC); - } - } - -#if BSP_PCI_IRQ_NUMBER > 0 - if (OpenPIC == (volatile struct OpenPIC *)0) { - rtems_panic("OpenPic Not found\n"); - } -#endif - -} - -#endif diff --git a/c/src/lib/libbsp/powerpc/shared/pci/generic_clear_hberrs.c b/c/src/lib/libbsp/powerpc/shared/pci/generic_clear_hberrs.c deleted file mode 100644 index 1bc4009b15..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/pci/generic_clear_hberrs.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include - -#include -#include - -#include - -#define PCI_ERR_BITS 0xf900 -#define PCI_STATUS_OK(x) (!((x)&PCI_ERR_BITS)) - -/* For now, just clear errors in the PCI status reg. - * - * Returns: (for diagnostic purposes) - * original settings (i.e. before applying the clearing - * sequence) or the error bits or 0 if there were no errors. - * - */ - -unsigned short -(*_BSP_clear_vmebridge_errors)(int) = 0; - -unsigned long -_BSP_clear_hostbridge_errors(int enableMCP, int quiet) -{ -unsigned long rval; -unsigned short pcistat; -int count; - - if (enableMCP) - return -1; /* exceptions not supported / MCP not wired */ - - /* read error status for info return */ - pci_read_config_word(0,0,0,PCI_STATUS,&pcistat); - rval = pcistat; - - count=10; - do { - /* clear error reporting registers */ - - /* clear PCI status register */ - pci_write_config_word(0,0,0,PCI_STATUS, PCI_ERR_BITS); - - /* read new status */ - pci_read_config_word(0,0,0,PCI_STATUS, &pcistat); - - } while ( ! PCI_STATUS_OK(pcistat) && count-- ); - - if ( !PCI_STATUS_OK(rval) && !quiet) { - printk("Cleared PCI errors: pci_stat was 0x%04lx\n", rval); - } - if ( !PCI_STATUS_OK(pcistat) ) { - printk("Unable to clear PCI errors: still 0x%04x after 10 attempts\n", pcistat); - } - - rval &= PCI_ERR_BITS; - - /* Some VME bridges (Tsi148) don't propagate VME bus errors to PCI status reg. */ - if ( _BSP_clear_vmebridge_errors ) - rval |= _BSP_clear_vmebridge_errors(quiet)<<16; - - return rval; -} diff --git a/c/src/lib/libbsp/powerpc/shared/pci/pci.c b/c/src/lib/libbsp/powerpc/shared/pci/pci.c deleted file mode 100644 index f75151ad46..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/pci/pci.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * pci.c : this file contains basic PCI Io functions. - * - * Copyright (C) 1999 valette@crf.canon.fr - * - * This code is heavily inspired by the public specification of STREAM V2 - * that can be found at : - * - * by following - * the STREAM API Specification Document link. - * - * 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. - * - * Till Straumann, , 1/2002 - * - separated bridge detection code out of this file - */ - -#include -#include - -#include -#include -#include - -#undef SHOW_PCI_SETTING - -/* allow for overriding these definitions */ -#ifndef PCI_CONFIG_ADDR -#define PCI_CONFIG_ADDR 0xcf8 -#endif -#ifndef PCI_CONFIG_DATA -#define PCI_CONFIG_DATA 0xcfc -#endif - -/* define a shortcut */ -#define pci BSP_pci_configuration - -#ifndef PCI_CONFIG_ADDR_VAL -#define PCI_CONFIG_ADDR_VAL(bus, slot, funcion, offset) \ - (0x80<<24|((bus)<<16)|(PCI_DEVFN((slot),(function))<<8)|(((offset)&~3))) -#endif - -#ifndef PCI_CONFIG_WR_ADDR -#define PCI_CONFIG_WR_ADDR( addr, val ) out_le32((volatile uint32_t*)(addr), (val)) -#endif - -#define PCI_CONFIG_SET_ADDR(addr, bus, slot,function,offset) \ - PCI_CONFIG_WR_ADDR((addr), PCI_CONFIG_ADDR_VAL((bus), (slot), (function), (offset))) - - -extern void detect_host_bridge(void); - -/* - * Bit encode for PCI_CONFIG_HEADER_TYPE register - */ -unsigned char ucMaxPCIBus; - -static int -indirect_pci_read_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t *val -) { - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - *val = in_8(pci.pci_config_data + (offset&3)); - return PCIBIOS_SUCCESSFUL; -} - -static int -indirect_pci_read_config_word( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint16_t *val -) { - *val = 0xffff; - if (offset&1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - *val = in_le16((volatile uint16_t *)(pci.pci_config_data + (offset&3))); - return PCIBIOS_SUCCESSFUL; -} - -static int -indirect_pci_read_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint32_t *val -) { - *val = 0xffffffff; - if (offset&3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - *val = in_le32((volatile uint32_t *)pci.pci_config_data); - return PCIBIOS_SUCCESSFUL; -} - -static int -indirect_pci_write_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t val -) { - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - out_8(pci.pci_config_data + (offset&3), val); - return PCIBIOS_SUCCESSFUL; -} - -static int -indirect_pci_write_config_word( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint16_t val -) { - if (offset&1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - out_le16((volatile uint16_t *)(pci.pci_config_data + (offset&3)), val); - return PCIBIOS_SUCCESSFUL; -} - -static int -indirect_pci_write_config_dword( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint32_t val -) { - if (offset&3) - return PCIBIOS_BAD_REGISTER_NUMBER; - PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset); - out_le32((volatile uint32_t *)pci.pci_config_data, val); - return PCIBIOS_SUCCESSFUL; -} - -const pci_config_access_functions pci_indirect_functions = { - indirect_pci_read_config_byte, - indirect_pci_read_config_word, - indirect_pci_read_config_dword, - indirect_pci_write_config_byte, - indirect_pci_write_config_word, - indirect_pci_write_config_dword -}; - -rtems_pci_config_t BSP_pci_configuration = { - (volatile unsigned char*)PCI_CONFIG_ADDR, - (volatile unsigned char*)PCI_CONFIG_DATA, - &pci_indirect_functions -}; - -static int -direct_pci_read_config_byte( - unsigned char bus, - unsigned char slot, - unsigned char function, - unsigned char offset, - uint8_t *val -) { - if (bus != 0 || (1<pin_route[j].pin > -1; j++) { - if ( row->pin_route[j].pin == int_pin ) { - _nopin = 0; - - for (k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ ) { - if ( row->pin_route[j].int_name[k] == int_name ) { - _noname=0; break; - } - } - break; - } - } - - if( _nopin ) - { - printk("pci : Device %d:0x%02x:%d supplied a bogus interrupt_pin %d\n", pbus, pslot, pfun, int_pin ); - return -1; - } - else - { - if( _noname ) { - unsigned char v = row->pin_route[j].int_name[0]; - printk("pci : Device %d:0x%02x:%d supplied a suspicious interrupt_line %d, ", pbus, pslot, pfun, int_name ); - if ( (row->opts & PCI_FIXUP_OPT_OVERRIDE_NAME) && 255 != (v = row->pin_route[j].int_name[0]) ) { - printk("OVERRIDING with %d from fixup table\n", v); - pci_write_config_byte(pbus,pslot,pfun,PCI_INTERRUPT_LINE,v); - } else { - printk("using it anyway\n"); - } - } - } - return 0; -} - -struct pcibridge -{ - int bus; - int slot; -}; - -static int FindPCIbridge( int mybus, struct pcibridge *pb ) -{ - int pbus, pslot; - uint8_t bussec, buspri; - uint16_t devid, vendorid, dclass; - - for(pbus=0; pbus< pci_bus_count(); pbus++) { - for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++) { - pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid); - if ( devid == 0xffff ) continue; - - pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid); - if ( vendorid == 0xffff ) continue; - - pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass); - - if ( dclass == PCI_CLASS_BRIDGE_PCI ) { - pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS, &buspri); - pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS, &bussec); - -#ifdef SHOW_PCI_SETTING - printk("pci : Found bridge at %d:0x%02x, mybus %d, pribus %d, secbus %d ", - pbus, pslot, mybus, buspri, bussec ); -#endif - if ( bussec == mybus ) { -#ifdef SHOW_PCI_SETTING - printk("match\n"); -#endif - /* found our nearest bridge going towards the root */ - pb->bus = pbus; - pb->slot = pslot; - - return 0; - } -#ifdef SHOW_PCI_SETTING - printk("no match\n"); -#endif - } - - } - } - return -1; -} - -void FixupPCI( const struct _int_map *bspmap, int (*swizzler)(int,int) ) -{ - unsigned char cvalue; - uint16_t devid; - int ismatch, i, j, pbus, pslot, pfun, int_pin, int_name, nfuns; - - /* - * If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific - * INTERRUPT_NAME if one isn't already in place. Then, drivers can - * trivially use INTERRUPT_NAME to hook up with devices. - */ - - for (pbus=0; pbus< pci_bus_count(); pbus++) { - for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) { - pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid); - if ( devid == 0xffff ) continue; - - /* got a device */ - pci_read_config_byte(pbus, pslot, 0, PCI_HEADER_TYPE, &cvalue); - nfuns = cvalue & PCI_HEADER_TYPE_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1; - - for (pfun=0; pfun< nfuns; pfun++) { - pci_read_config_word(pbus, pslot, pfun, PCI_DEVICE_ID, &devid); - if( devid == 0xffff ) continue; - - pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_PIN, &cvalue); - int_pin = cvalue; - - pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_LINE, &cvalue); - int_name = cvalue; - - /* printk("pci : device %d:0x%02x:%i devid %04x, intpin %d, intline %d\n", - pbus, pslot, pfun, devid, int_pin, int_name ); */ - -#ifdef SHOW_PCI_SETTING - { - unsigned short cmd,stat; - unsigned char lat, seclat, csize; - - pci_read_config_word(pbus,pslot,pfun,PCI_COMMAND, &cmd ); - pci_read_config_word(pbus,pslot,pfun,PCI_STATUS, &stat ); - pci_read_config_byte(pbus,pslot,pfun,PCI_LATENCY_TIMER, &lat ); - pci_read_config_byte(pbus,pslot,pfun,PCI_SEC_LATENCY_TIMER, &seclat ); - pci_read_config_byte(pbus,pslot,pfun,PCI_CACHE_LINE_SIZE, &csize ); - - - printk("pci : device %d:0x%02x:%d cmd %04X, stat %04X, latency %d, " - " sec_latency %d, clsize %d\n", pbus, pslot, pfun, cmd, stat, - lat, seclat, csize); - } -#endif - - if ( int_pin > 0 ) { - ismatch = 0; - - /* - * first run thru the bspmap table and see if we have an - * explicit configuration - */ - for (i=0; bspmap[i].bus > -1; i++) { - if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) { - ismatch = -1; - /* we have a record in the table that gives specific - * pins and interrupts for devices in this slot */ - if ( int_name == 255 ) { - /* find the vector associated with whatever pin the - * device gives us - */ - for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ) { - if ( bspmap[i].pin_route[j].pin == int_pin ) { - int_name = bspmap[i].pin_route[j].int_name[0]; - break; - } - } - if ( int_name == -1 ) { - printk("pci : Unable to resolve device %d:0x%02x:%d w/ swizzled int " - "pin %i to an interrupt_line.\n", pbus, pslot, pfun, int_pin ); - } else { - PRINT_MSG(); - pci_write_config_byte( pbus,pslot,pfun, - PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue)); - } - } else { - test_intname( &bspmap[i],pbus,pslot,pfun,int_pin,int_name); - } - break; - } - } - - if ( !ismatch ) { - /* - * no match, which means we're on a bus someplace. Work - * backwards from it to one of our defined busses, - * swizzling thru each bridge on the way. - */ - - /* keep pbus, pslot pointed to the device being - * configured while we track down the bridges using - * tbus,tslot. We keep searching the routing table because - * we may end up finding our bridge in it - */ - - int tbus= pbus, tslot= pslot; - - for (;;) { - for (i=0; bspmap[i].bus > -1; i++) { - if ( bspmap[i].bus == tbus && - (bspmap[i].slot == tslot || bspmap[i].slot == -1) ) { - ismatch = -1; - /* found a record for this bus, so swizzle the - * int_pin which we then use to find the - * interrupt_name. - */ - - if ( int_name == 255 ) { - /* - * FIXME. I can't believe this little hack - * is right. It does not yield an error in - * convienently simple situations. - */ - if ( tbus ) int_pin = (*swizzler)(tslot,int_pin); - - /* - * int_pin points to the interrupt channel - * this card ends up delivering interrupts - * on. Find the int_name servicing it. - */ - for (int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++){ - if ( bspmap[i].pin_route[j].pin == int_pin ) { - int_name = bspmap[i].pin_route[j].int_name[0]; - break; - } - } - - if ( int_name == -1 ) { - printk("pci : Unable to resolve device %d:0x%02x:%d w/ swizzled " - "int pin %i to an interrupt_line.\n", - pbus, pslot, pfun, int_pin ); - } else { - PRINT_MSG(); - pci_write_config_byte(pbus,pslot,pfun, - PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue)); - } - } else { - test_intname(&bspmap[i],pbus,pslot,pfun,int_pin,int_name); - } - goto donesearch; - } - } - - if ( !ismatch ) { - struct pcibridge pb; - - /* - * Haven't found our bus in the int map, so work - * upwards thru the bridges till we find it. - */ - - if ( FindPCIbridge( tbus, &pb )== 0 ) { - int_pin = (*swizzler)(tslot,int_pin); - - /* our next bridge up is on pb.bus, pb.slot- now - * instead of pointing to the device we're - * trying to configure, we move from bridge to - * bridge. - */ - - tbus = pb.bus; - tslot = pb.slot; - } else { - printk("pci : No bridge from bus %i towards root found\n", - tbus ); - goto donesearch; - } - } - } - } -donesearch: - - if ( !ismatch && int_pin != 0 && int_name == 255 ) { - printk("pci : Unable to match device %d:0x%02x:%d with an int " - "routing table entry\n", pbus, pslot, pfun ); - } - } - } - } - } -} - -/* - * This routine determines the maximum bus number in the system - */ -int pci_initialize(void) -{ - unsigned char ucSlotNumber, ucFnNumber, ucNumFuncs; - unsigned char ucHeader; - unsigned char ucMaxSubordinate; - uint32_t ulClass; - uint32_t ulDeviceID; - - detect_host_bridge(); - - /* - * Scan PCI bus 0 looking for PCI-PCI bridges - */ - for (ucSlotNumber=0;ucSlotNumber>= 16; - if (ulClass == PCI_CLASS_BRIDGE_PCI) { - /* We have found a PCI-PCI bridge */ - pci_read_config_byte(0, ucSlotNumber, ucFnNumber, - PCI_SUBORDINATE_BUS, &ucMaxSubordinate); - if (ucMaxSubordinate>ucMaxPCIBus) { - ucMaxPCIBus=ucMaxSubordinate; - } - } - } - } - return PCIB_ERR_SUCCESS; -} - -/* - * Return the number of PCI busses in the system - */ -unsigned char pci_bus_count(void) -{ - return (ucMaxPCIBus+1); -} diff --git a/c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c b/c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c deleted file mode 100644 index 8aad50547a..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c +++ /dev/null @@ -1,212 +0,0 @@ -/* find a particular PCI device - * (we assume, the firmware configured the PCI bus[es] for us) - */ - -/* - * Authorship - * ---------- - * This software was created by - * Till Straumann , 2001, - * Stanford Linear Accelerator Center, Stanford University. - * - * Acknowledgement of sponsorship - * ------------------------------ - * This software was produced by - * the Stanford Linear Accelerator Center, Stanford University, - * under Contract DE-AC03-76SFO0515 with the Department of Energy. - * - * Government disclaimer of liability - * ---------------------------------- - * Neither the United States nor the United States Department of Energy, - * nor any of their employees, makes any warranty, express or implied, or - * assumes any legal liability or responsibility for the accuracy, - * completeness, or usefulness of any data, apparatus, product, or process - * disclosed, or represents that its use would not infringe privately owned - * rights. - * - * Stanford disclaimer of liability - * -------------------------------- - * Stanford University makes no representations or warranties, express or - * implied, nor assumes any liability for the use of this software. - * - * Stanford disclaimer of copyright - * -------------------------------- - * Stanford University, owner of the copyright, hereby disclaims its - * copyright and all other rights in this software. Hence, anyone may - * freely use it for any purpose without restriction. - * - * Maintenance of notices - * ---------------------- - * In the interest of clarity regarding the origin and status of this - * SLAC software, this and all the preceding Stanford University notices - * are to remain affixed to any copy or derivative of this software made - * or distributed by the recipient and are to be affixed to any copy of - * software made or distributed by the recipient that contains a copy or - * derivative of this software. - * - * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 - */ - -#include -#include -#include -#include - -/* Stolen from i386... */ - -/* - * Make device signature from bus number, device number and function - * number - */ -#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f)) - -/* - * Extract various parts from device signature - */ -#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff) -#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f) -#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7) - -typedef struct { - unsigned short vid,did; - int inst; -} fd_arg; - -static int -find_dev_cb( - int bus, - int dev, - int fun, - void *uarg -) { -fd_arg *a = uarg; -unsigned short s; - - pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s); - if (a->vid == s) { - pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s); - if (a->did == s && 0 == a->inst-- ) { - a->inst = PCIB_DEVSIG_MAKE( bus, dev, fun ); - return 1; - } - } - return 0; -} - -int -pci_find_device( - unsigned short vendorid, - unsigned short deviceid, - int instance, - int *pbus, - int *pdev, - int *pfun -) { -fd_arg a; -void *h; - a.vid = vendorid; - a.did = deviceid; - a.inst = instance; - - if ( (h = BSP_pciScan(0, find_dev_cb, (void*)&a)) ) { - *pbus = PCIB_DEVSIG_BUS( a.inst ); - *pdev = PCIB_DEVSIG_DEV( a.inst ); - *pfun = PCIB_DEVSIG_FUNC( a.inst ); - return 0; - } - return -1; -} - -static int -dump_dev_cb( - int bus, - int dev, - int fun, - void *uarg -) -{ - uint16_t vi,di; - uint16_t cd,st; - uint32_t b1,b2; - uint8_t il,ip; - FILE *f = uarg; - - pci_read_config_word (bus, dev, fun, PCI_VENDOR_ID, &vi); - pci_read_config_word (bus, dev, fun, PCI_DEVICE_ID, &di); - pci_read_config_word (bus, dev, fun, PCI_COMMAND, &cd); - pci_read_config_word (bus, dev, fun, PCI_STATUS, &st); - pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_0, &b1); - pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_1, &b2); - pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_LINE, &il); - pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_PIN, &ip); - - /* fprintf(f,"%3d:0x%02x:%d 0x%04x-0x%04x: 0x%04x 0x%04x 0x%08x 0x%08x %d -> %3d (=0x%02x)\n", */ - fprintf(f,"%3d:0x%02x:%d 0x%04x-0x%04x: 0x%04x 0x%04x 0x%08" PRIx32 " 0x%08" PRIx32 " %d -> %3d (=0x%02x)\n", - bus, dev, fun, vi, di, cd, st, b1, b2, ip, il, il); - return 0; -} - -void -BSP_pciConfigDump(FILE *f) -{ - if ( !f ) - f = stdout; - fprintf(f,"BUS:SLOT:FUN VENDOR-DEV_ID: COMMAND STATUS BASE_ADDR0 BASE_ADDR1 IRQ_PIN -> IRQ_LINE\n"); - BSP_pciScan(0, dump_dev_cb, f); -} - -BSP_PciScanHandle -BSP_pciScan( - BSP_PciScanHandle handle, - BSP_PciScannerCb cb, - void *uarg -) { - - uint32_t d; - unsigned char bus,dev,fun,hd; - - bus = PCIB_DEVSIG_BUS( (unsigned long)handle ); - dev = PCIB_DEVSIG_DEV( (unsigned long)handle ); - fun = PCIB_DEVSIG_FUNC( (unsigned long)handle ); - - hd = fun > 0 ? PCI_MAX_FUNCTIONS : 1; - - for (; bus 0 ) { - if ( ++fun >= hd ) { - fun = 0; - if ( ++dev >= PCI_MAX_DEVICES ) { - dev = 0; - bus++; - } - } - return (void*) PCIB_DEVSIG_MAKE(bus,dev,fun); - } - } - } - } - return 0; -} -- cgit v1.2.3