summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@oarcorp.com>2014-10-16 13:12:21 -0500
committerJoel Sherrill <joel.sherrill@oarcorp.com>2014-10-19 17:00:56 -0500
commit2cb449d2f302d65aaa3358467fa2a8fb9b3263e9 (patch)
tree49744f047d75a6f2e239d78d95a97f6c36dfe8d7 /c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c
parentpowerpc/mvme3100: Fix warnings (diff)
downloadrtems-2cb449d2f302d65aaa3358467fa2a8fb9b3263e9.tar.bz2
powerpc/beatnik: Fix warnings
Diffstat (limited to 'c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c')
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c260
1 files changed, 129 insertions, 131 deletions
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
index 101b86bb69..79dd2976d0 100644
--- a/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c
+++ b/c/src/lib/libbsp/powerpc/beatnik/pci/pci_io_remap.c
@@ -5,13 +5,13 @@
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
- * Stanford Linear Accelerator Center, Stanford University.
+ * 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.
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
@@ -49,6 +49,7 @@
#include <rtems/bspIo.h>
#include <bsp/pci.h>
#include <stdint.h>
+#include "pci_io_remap.h"
#ifndef PCI_MULTI_FUN
#define PCI_MULTI_FUN 0x80
@@ -64,142 +65,139 @@
* of PCI-PCI bridges, too.
*
* RESTRICTIONS: 'offset' must be 4k aligned (PCI req.); no argument check
- * on the bus numbers is done.
+ * 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) ) {
- BSP_panic("rtems_pci_io_remap(): offset must be 4k aligned");
- return -1;
- }
-
-
- for ( bus=bus_from; bus < bus_to; bus++ ) {
- for ( dev = 0; dev<PCI_MAX_DEVICES; dev++ ) {
-
- maxf = 1;
-
- for ( fun = 0; fun < maxf; fun++ ) {
- pci_read_config_word( bus, dev, fun, PCI_VENDOR_ID, &s );
- if ( 0xffff == s )
- continue;
-
- pci_read_config_byte( bus, dev, fun, PCI_HEADER_TYPE, &b );
-
- /* readjust the max. function number to scan if this is a multi-function
- * device.
- */
- if ( 0 == fun && (PCI_MULTI_FUN & b) )
- maxf = PCI_MAX_FUNCTIONS;
-
- /* Check the header type; panic if unknown.
- * header type 0 has 6 bars, header type 1 (PCI-PCI bridge) has 2
- */
- b &= PCI_HEADER_TYPE_MSK;
- switch ( b ) {
- default:
- printk("PCI header type %i (@%i/%i/%i)\n", b, bus, dev, fun);
- BSP_panic("rtems_pci_io_remap(): unknown PCI header type");
- return -1; /* keep compiler happy */
-
- case PCI_HEADER_TYPE_CARDBUS:
- printk("PCI header type %i (@%i/%i/%i)\n", b, bus, dev, fun);
- BSP_panic("rtems_pci_io_remap(): don't know how to deal with Cardbus bridge");
- return -1;
-
- case PCI_HEADER_TYPE_NORMAL:
- numBars = 6*4; /* loop below counts reg. offset in bytes */
- break;
-
- case PCI_HEADER_TYPE_BRIDGE:
- numBars = 2*4; /* loop below counts reg. offset in bytes */
- break;
-
- }
-
- for ( bar = 0; bar < numBars; bar+=4 ) {
- pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0 + bar, &d );
- if ( PCI_BASE_ADDRESS_SPACE_IO & d ) {
- /* It's an I/O BAR; remap */
- d &= PCI_BASE_ADDRESS_IO_MASK;
- if ( d ) {
- /* IO bar was configured; add offset */
- d += offset;
- pci_write_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0 + bar, d );
- }
- } else {
- /* skip upper half of 64-bit window */
- d &= PCI_BASE_ADDRESS_MEM_TYPE_MASK;
- if ( PCI_BASE_ADDRESS_MEM_TYPE_64 == d )
- bar+=4;
- }
- }
-
- /* Now it's time to deal with bridges */
- if ( PCI_HEADER_TYPE_BRIDGE == b ) {
- /* must adjust the limit registers */
- pci_read_config_byte( bus, dev, fun, PCI_IO_LIMIT, &b );
- pci_read_config_word( bus, dev, fun, PCI_IO_LIMIT_UPPER16, &s );
- lim = (s<<16) + (( b & PCI_IO_RANGE_MASK ) << 8);
- lim += offset;
-
- pci_read_config_byte( bus, dev, fun, PCI_IO_BASE, &b );
- pci_read_config_word( bus, dev, fun, PCI_IO_BASE_UPPER16, &s );
- bas = (s<<16) + (( b & PCI_IO_RANGE_MASK ) << 8);
- bas += offset;
-
- b &= PCI_IO_RANGE_TYPE_MASK;
- switch ( b ) {
- default:
- printk("Unknown IO range type 0x%x (@%i/%i/%i)\n", b, bus, dev, fun);
- BSP_panic("rtems_pci_io_remap(): unknown IO range type");
- return -1;
-
- case PCI_IO_RANGE_TYPE_16:
- if ( bas > 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;
+ 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) ) {
+ BSP_panic("rtems_pci_io_remap(): offset must be 4k aligned");
+ return -1;
+ }
+
+
+ for ( bus=bus_from; bus < bus_to; bus++ ) {
+ for ( dev = 0; dev<PCI_MAX_DEVICES; dev++ ) {
+
+ maxf = 1;
+
+ for ( fun = 0; fun < maxf; fun++ ) {
+ pci_read_config_word( bus, dev, fun, PCI_VENDOR_ID, &s );
+ if ( 0xffff == s )
+ continue;
+
+ pci_read_config_byte( bus, dev, fun, PCI_HEADER_TYPE, &b );
+
+ /* readjust the max. function number to scan if this is a multi-function
+ * device.
+ */
+ if ( 0 == fun && (PCI_MULTI_FUN & b) )
+ maxf = PCI_MAX_FUNCTIONS;
+
+ /* Check the header type; panic if unknown.
+ * header type 0 has 6 bars, header type 1 (PCI-PCI bridge) has 2
+ */
+ b &= PCI_HEADER_TYPE_MSK;
+ switch ( b ) {
+ default:
+ printk("PCI header type %i (@%i/%i/%i)\n", b, bus, dev, fun);
+ BSP_panic("rtems_pci_io_remap(): unknown PCI header type");
+ return -1; /* keep compiler happy */
+
+ case PCI_HEADER_TYPE_CARDBUS:
+ printk("PCI header type %i (@%i/%i/%i)\n", b, bus, dev, fun);
+ BSP_panic("rtems_pci_io_remap(): don't know how to deal with Cardbus bridge");
+ return -1;
+
+ case PCI_HEADER_TYPE_NORMAL:
+ numBars = 6*4; /* loop below counts reg. offset in bytes */
+ break;
+
+ case PCI_HEADER_TYPE_BRIDGE:
+ numBars = 2*4; /* loop below counts reg. offset in bytes */
+ break;
+
+ }
+
+ for ( bar = 0; bar < numBars; bar+=4 ) {
+ pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0 + bar, &d );
+ if ( PCI_BASE_ADDRESS_SPACE_IO & d ) {
+ /* It's an I/O BAR; remap */
+ d &= PCI_BASE_ADDRESS_IO_MASK;
+ if ( d ) {
+ /* IO bar was configured; add offset */
+ d += offset;
+ pci_write_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0 + bar, d );
+ }
+ } else {
+ /* skip upper half of 64-bit window */
+ d &= PCI_BASE_ADDRESS_MEM_TYPE_MASK;
+ if ( PCI_BASE_ADDRESS_MEM_TYPE_64 == d )
+ bar+=4;
+ }
+ }
+
+ /* Now it's time to deal with bridges */
+ if ( PCI_HEADER_TYPE_BRIDGE == b ) {
+ /* must adjust the limit registers */
+ pci_read_config_byte( bus, dev, fun, PCI_IO_LIMIT, &b );
+ pci_read_config_word( bus, dev, fun, PCI_IO_LIMIT_UPPER16, &s );
+ lim = (s<<16) + (( b & PCI_IO_RANGE_MASK ) << 8);
+ lim += offset;
+
+ pci_read_config_byte( bus, dev, fun, PCI_IO_BASE, &b );
+ pci_read_config_word( bus, dev, fun, PCI_IO_BASE_UPPER16, &s );
+ bas = (s<<16) + (( b & PCI_IO_RANGE_MASK ) << 8);
+ bas += offset;
+
+ b &= PCI_IO_RANGE_TYPE_MASK;
+ switch ( b ) {
+ default:
+ printk("Unknown IO range type 0x%x (@%i/%i/%i)\n", b, bus, dev, fun);
+ BSP_panic("rtems_pci_io_remap(): unknown IO range type");
+ return -1;
+
+ case PCI_IO_RANGE_TYPE_16:
+ if ( bas > 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;
}