PR 405/bsps
	* bootloader/pci.c: Added support for configuring devices for pci
	busses > 0
	* pci/pci.c, pci/pci.h: Added FixupPCI() to store vectors in the
	INTERRUPT_LINE register of pci devices any # of hops away
	from the host processor.
	* motorola/motorola.c, motorola/motorola.h: Added interrupt
	routing tables in support of FixupPCI.  This is board-specific,
	each board will have to supply information for FixupPCI() to do
	anything for it.
	* startup/bspstart.c: Extended bat2 to cover entire PCI address space.
	* irq/irq.c, irq/irq.h: Added support for shared interrupts.
	Existing single hander vectors are undisturbed, a new function
	added to allow adding/removing handlers from a vector.
This commit is contained in:
Joel Sherrill
2003-06-13 17:39:46 +00:00
parent 9274ea760f
commit 3a3e0b0e7d
11 changed files with 1951 additions and 746 deletions

View File

@@ -1,3 +1,20 @@
2003-06-13 Greg Menke <gregory.menke@gsfc.nasa.gov>
PR 405/bsps
* bootloader/pci.c: Added support for configuring devices for pci
busses > 0
* pci/pci.c, pci/pci.h: Added FixupPCI() to store vectors in the
INTERRUPT_LINE register of pci devices any # of hops away
from the host processor.
* motorola/motorola.c, motorola/motorola.h: Added interrupt
routing tables in support of FixupPCI. This is board-specific,
each board will have to supply information for FixupPCI() to do
anything for it.
* startup/bspstart.c: Extended bat2 to cover entire PCI address space.
* irq/irq.c, irq/irq.h: Added support for shared interrupts.
Existing single hander vectors are undisturbed, a new function
added to allow adding/removing handlers from a vector.
2003-06-13 Till Straumann <strauman@slac.stanford.edu>
PR 415/bsps

View File

@@ -39,3 +39,11 @@ initialization (e.g printk, ...).
Eric Valette (valette@crf.canon.fr)
**************************************************
2003/5/7, Greg Menke, gregory.menke@gsfc.nasa.gov
Reworked the pci bus 0 initialization a little and added support for
configuring an arbitrary number of other busses & their respective
bridges. Also added support for configuring IO ranges below 0x10000,
which I think is reasonable given this is a PowerPC bsp.

View File

@@ -22,8 +22,11 @@
#include "bootldr.h"
#include "pci.h"
#include <libcpu/io.h>
#include <libcpu/page.h>
#include <bsp/consoleIo.h>
typedef unsigned int u32;
/*#define DEBUG*/
@@ -95,6 +98,7 @@ print_pci_resources(const char *s) {
pci_resource *p;
printk("%s", s);
for (p=pci->resources; p; p=p->next) {
/*
printk(" %p:%p %06x %08lx %08lx %d\n",
p, p->next,
(p->dev->devfn<<8)+(p->dev->bus->number<<16)
@@ -102,6 +106,16 @@ print_pci_resources(const char *s) {
p->base,
p->size,
p->type);
*/
printk(" %p:%p %d:%02x (%04x:%04x) %08lx %08lx %d\n",
p, p->next,
p->dev->bus->number, PCI_SLOT(p->dev->devfn),
p->dev->vendor, p->dev->device,
p->base,
p->size,
p->type);
}
}
@@ -156,6 +170,8 @@ static struct blacklist_entry blacklist[] = {
((r->type&PCI_BASE_ADDRESS_MEM_PREFETCH) ? PCI_AREA_PREFETCHABLE :\
PCI_AREA_MEMORY))
static int insert_before(pci_resource *e, pci_resource *t) {
if (e->dev->bus->number != t->dev->bus->number)
return e->dev->bus->number > t->dev->bus->number;
@@ -163,6 +179,10 @@ static int insert_before(pci_resource *e, pci_resource *t) {
return (e->size > t->size);
}
static void insert_resource(pci_resource *r) {
struct blacklist_entry *b;
pci_resource *p;
@@ -195,12 +215,14 @@ static void insert_resource(pci_resource *r) {
* limits have hopefully been set high enough to avoid problems.
*/
#if 0
if ((r->type==PCI_BASE_ADDRESS_SPACE_IO)
? (r->base && r->base <0x10000)
: (r->base && r->base <0x1000000)) {
sfree(r);
return;
}
#endif
if ((r->type==PCI_BASE_ADDRESS_SPACE_IO)
? (r->size >= 0x10000)
@@ -226,6 +248,10 @@ static void insert_resource(pci_resource *r) {
}
}
/* This version only works for bus 0. I don't have any P2P bridges to test
* a more sophisticated version which has therefore not been implemented.
* Prefetchable memory is not yet handled correctly either.
@@ -240,17 +266,22 @@ static u_long find_range(u_char bus, u_char type,
u_long total=0;
u_int fl=0;
for (p=pci->resources; p; p=p->next) {
for (p=pci->resources; p; p=p->next)
{
if ((p->dev->bus->number == bus) &&
AREA(p)==type) break;
}
*first = p;
for (; p; p=p->next) {
for (; p; p=p->next)
{
if ((p->dev->bus->number != bus) ||
AREA(p)!=type || p->size == 0) break;
total = total+p->size;
fl |= 1<<p->type;
}
*past = p;
/* This will be used later to tell whether there are any 32 bit
* devices in an area which could be mapped higher than 4Gb
@@ -260,6 +291,11 @@ static u_long find_range(u_char bus, u_char type,
return total;
}
static inline void init_free_area(pci_area_head *h, u_long start,
u_long end, u_int mask, int high) {
pci_area *p;
@@ -274,6 +310,11 @@ static inline void init_free_area(pci_area_head *h, u_long start,
h->high = high;
}
static void insert_area(pci_area_head *h, pci_area *p) {
pci_area *q = h->head;
if (!p) return;
@@ -298,12 +339,18 @@ static void insert_area(pci_area_head *h, pci_area *p) {
}
}
static
void remove_area(pci_area_head *h, pci_area *p) {
void remove_area(pci_area_head *h, pci_area *p)
{
pci_area *q = h->head;
if (!p || !q) return;
if (q==p) {
if (q==p)
{
h->head = q->next;
return;
}
@@ -311,13 +358,19 @@ void remove_area(pci_area_head *h, pci_area *p) {
if (q) q->next=p->next;
}
static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus,
u_long required, u_long mask, u_int flags) {
pci_area *p;
pci_area *from, *split, *new;
required = (required+h->mask) & ~h->mask;
for (p=h->head, from=NULL; p; p=p->next) {
for (p=h->head, from=NULL; p; p=p->next)
{
u_long l1 = ((p->start+required+mask)&~mask)-1;
u_long l2 = ((p->start+mask)&~mask)+required-1;
/* Allocated areas point to the bus to which they pertain */
@@ -339,7 +392,8 @@ static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus,
new->bus = bus;
new->flags = flags;
/* Now allocate pci_space taking alignment into account ! */
if (h->high) {
if (h->high)
{
u_long l1 = ((from->end+1)&~mask)-required;
u_long l2 = (from->end+1-required)&~mask;
new->start = (l1>l2) ? l1 : l2;
@@ -347,7 +401,9 @@ static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus,
from->end = new->start-1;
split->start = new->start+required;
new->end = new->start+required-1;
} else {
}
else
{
u_long l1 = ((from->start+mask)&~mask)+required-1;
u_long l2 = ((from->start+required+mask)&~mask)-1;
new->end = (l1<l2) ? l1 : l2;
@@ -358,10 +414,13 @@ static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus,
}
if (from->end+1 == from->start) remove_area(h, from);
if (split->end+1 != split->start) {
if (split->end+1 != split->start)
{
split->bus = NULL;
insert_area(h, split);
} else {
}
else
{
sfree(split);
}
insert_area(h, new);
@@ -369,8 +428,13 @@ static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus,
return new;
}
static inline
void alloc_space(pci_area *p, pci_resource *r) {
void alloc_space(pci_area *p, pci_resource *r)
{
if (p->start & (r->size-1)) {
r->base = p->end+1-r->size;
p->end -= r->size;
@@ -380,29 +444,65 @@ void alloc_space(pci_area *p, pci_resource *r) {
}
}
static void reconfigure_bus_space(u_char bus, u_char type, pci_area_head *h) {
static void reconfigure_bus_space(u_char bus, u_char type, pci_area_head *h)
{
pci_resource *first, *past, *r;
pci_area *area, tmp;
u_int flags;
u_int required = find_range(bus, type, &first, &past, &flags);
if (required==0) return;
area = alloc_area(h, first->dev->bus, required, first->size-1, flags);
if (!area) return;
tmp = *area;
for (r=first; r!=past; r=r->next) {
for (r=first; r!=past; r=r->next)
{
alloc_space(&tmp, r);
}
}
#define BUS0_IO_START 0x10000
#define BUS0_IO_END 0x1ffff
#define BUS0_MEM_START 0x1000000
#define BUS0_MEM_END 0xaffffff
#define BUSREST_IO_START 0x20000
#define BUSREST_IO_END 0x7ffff
#define BUSREST_MEM_START 0xb000000
#define BUSREST_MEM_END 0x30000000
static void reconfigure_pci(void) {
pci_resource *r;
struct pci_dev *dev;
/* FIXME: for now memory is relocated from low, it's better
* to start from higher addresses.
*/
/*
init_free_area(&pci->io, 0x10000, 0x7fffff, 0xfff, 0);
init_free_area(&pci->mem, 0x1000000, 0x3cffffff, 0xfffff, 0);
*/
init_free_area(&pci->io, BUS0_IO_START, BUS0_IO_END, 0xfff, 0);
init_free_area(&pci->mem, BUS0_MEM_START, BUS0_MEM_END, 0xfffff, 0);
/* First reconfigure the I/O space, this will be more
* complex when there is more than 1 bus. And 64 bits
@@ -454,6 +554,11 @@ static void reconfigure_pci(void) {
}
}
static int
indirect_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
unsigned char offset, unsigned char *val) {
@@ -614,16 +719,24 @@ static const struct pci_config_access_functions direct_functions = {
};
void pci_read_bases(struct pci_dev *dev, unsigned int howmany)
{
unsigned int reg, nextreg;
#define REG (PCI_BASE_ADDRESS_0 + (reg<<2))
u_short cmd;
u32 l, ml;
pci_read_config_word(dev, PCI_COMMAND, &cmd);
for(reg=0; reg<howmany; reg=nextreg) {
for(reg=0; reg<howmany; reg=nextreg)
{
pci_resource *r;
nextreg=reg+1;
pci_read_config_dword(dev, REG, &l);
#if 0
@@ -679,6 +792,10 @@ void pci_read_bases(struct pci_dev *dev, unsigned int howmany)
u_int pci_scan_bus(struct pci_bus *bus)
{
unsigned int devfn, l, max, class;
@@ -686,6 +803,10 @@ u_int pci_scan_bus(struct pci_bus *bus)
struct pci_dev *dev, **bus_last;
struct pci_bus *child;
#if 0
printk("scanning pci bus %d\n", bus->number );
#endif
bus_last = &bus->devices;
max = bus->secondary;
for (devfn = 0; devfn < 0xff; ++devfn) {
@@ -750,10 +871,10 @@ u_int pci_scan_bus(struct pci_bus *bus)
goto bad;
pci_read_bases(dev, 1);
break;
default: /* unknown header */
bad:
printk("PCI device with unknown "
"header type %d ignored.\n",
printk("PCI device with unknown header type %d ignored.\n",
hdr_type&0x7f);
continue;
}
@@ -852,7 +973,7 @@ u_int pci_scan_bus(struct pci_bus *bus)
| ((unsigned int)(child->subordinate) << 16);
pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
}
pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr);
pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr );
}
/*
@@ -865,18 +986,373 @@ u_int pci_scan_bus(struct pci_bus *bus)
return max;
}
#if 0
void
pci_fixup(void) {
pci_fixup(void)
{
struct pci_dev *p;
struct pci_bus *bus;
for (bus = &pci_root; bus; bus=bus->next) {
for (p=bus->devices; p; p=p->sibling) {
for (bus = &pci_root; bus; bus=bus->next)
{
for (p=bus->devices; p; p=p->sibling)
{
}
}
}
void pci_init(void) {
static void print_pci_info()
{
pci_resource *r;
struct pci_bus *pb = &pci_root;
printk("\n");
printk("PCI busses:\n");
for(pb= &pci_root; pb; pb=pb->children )
{
printk(" number %d, primary %d, secondary %d, subordinate %d\n",
pb->number,
pb->primary,
pb->secondary,
pb->subordinate );
printk(" bridge; vendor %04x, device %04x\n",
pb->self->vendor,
pb->self->device );
{
struct pci_dev *pd;
for(pd= pb->devices; pd; pd=pd->sibling )
{
printk(" vendor %04x, device %04x, irq %d\n",
pd->vendor,
pd->device,
pd->irq );
}
printk("\n");
}
}
printk("\n");
printk("PCI resources:\n");
for (r=pci->resources; r; r= r->next)
{
printk(" bus %d, vendor %04x, device %04x, base %08x, size %08x, type %d\n",
r->dev->bus->number,
r->dev->vendor,
r->dev->device,
r->base,
r->size,
r->type );
}
printk("\n");
return;
}
#endif
static struct _addr_start
{
unsigned32 start_pcimem;
unsigned32 start_pciio;
unsigned32 start_prefetch;
} astart;
static pci_resource *enum_device_resources( struct pci_dev *pdev, int i )
{
pci_resource *r;
for(r= pci->resources; r; r= r->next )
{
if( r->dev == pdev )
{
if( i-- == 0 ) break;
}
}
return r;
}
#define MEMORY_IO_GRANULARITY 256
static void recursive_bus_reconfigure( struct pci_bus *pbus )
{
struct pci_dev *pdev;
struct pci_bus *childbus;
int isroot = 0;
if( !pbus )
{
/* start with the root bus */
astart.start_pcimem = BUSREST_MEM_START;
astart.start_pciio = BUSREST_IO_START;
astart.start_prefetch = ((BUSREST_MEM_END >> 16) << 16);
pbus = &pci_root;
isroot = -1;
}
#define WRITE_BRIDGE_IO
#define WRITE_BRIDGE_MEM
#define WRITE_BRIDGE_PF
#define WRITE_BRIDGE_ENABLE
/*
** Run thru the p2p bridges on this bus and recurse into subordinate busses
*/
for( childbus= pbus->children; childbus; childbus= childbus->next )
{
pdev= childbus->self;
{
struct _addr_start addrhold;
unsigned8 base8, limit8;
unsigned16 base16, limit16, ubase16, ulimit16;
/* save the base address values */
memcpy( &addrhold, &astart, sizeof(struct _addr_start));
recursive_bus_reconfigure( childbus );
#ifdef PCI_DEBUG
printk("pci: configuring bus %d bridge (%04x:%04x), bus %d : (%d-%d)\n",
pdev->bus->number,
pdev->vendor,
pdev->device,
childbus->primary,
childbus->secondary,
childbus->subordinate );
#endif
/*
**use the current values & the saved ones to figure out
** the address spaces for the bridge
*/
if( addrhold.start_pciio == astart.start_pciio )
{
base8 = limit8 = 0xff;
ubase16 = ulimit16 = 0xffff;
}
else
{
base8 = (unsigned8) ((addrhold.start_pciio >> 8) & 0xf0);
ubase16 = (unsigned16)(addrhold.start_pciio >> 16);
limit8 = (unsigned8) ((astart.start_pciio >> 8 ) & 0xf0);
ulimit16 = (unsigned16)(astart.start_pciio >> 16);
astart.start_pciio += 0x1000;
}
#ifdef PCI_DEBUG
printk("pci: io base %08x limit %08x\n", (base8<<8)+(ubase16<<16), (limit8<<8)+(ulimit16<<16));
#endif
#ifdef WRITE_BRIDGE_IO
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_BASE_UPPER16, ubase16 );
pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_BASE, base8 );
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT_UPPER16, ulimit16 );
pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT, limit8 );
#endif
if( addrhold.start_pcimem == astart.start_pcimem )
{
limit16 = 0;
base16 = 0xffff;
}
else
{
limit16= (unsigned16)((astart.start_pcimem >> 16) & 0xfff0);
base16 = (unsigned16)((addrhold.start_pcimem >> 16) & 0xfff0);
astart.start_pcimem += 0x100000;
}
#ifdef PCI_DEBUG
printk("pci: memory %04x, limit %04x\n", base16, limit16);
#endif
#ifdef WRITE_BRIDGE_MEM
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_BASE, base16 );
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_LIMIT, limit16 );
#endif
if( astart.start_prefetch == addrhold.start_prefetch )
{
limit16 = 0;
base16 = 0xffff;
}
else
{
limit16= (unsigned16)((addrhold.start_prefetch >> 16) & 0xfff0);
base16 = (unsigned16)((astart.start_prefetch >> 16) & 0xfff0);
astart.start_prefetch -= 0x100000;
}
#ifdef PCI_DEBUG
printk("pci: pf memory %04x, limit %04x\n", base16, limit16);
#endif
#ifdef WRITE_BRIDGE_PF
pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_BASE_UPPER32, 0);
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_BASE, base16 );
pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_LIMIT_UPPER32, 0);
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_LIMIT, limit16 );
#endif
#ifdef WRITE_BRIDGE_ENABLE
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_BRIDGE_CONTROL, (unsigned16)( PCI_BRIDGE_CTL_PARITY |
PCI_BRIDGE_CTL_SERR |
PCI_BRIDGE_CTL_FAST_BACK));
pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_COMMAND, (unsigned16)( PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER |
PCI_COMMAND_PARITY |
PCI_COMMAND_WAIT |
PCI_COMMAND_SERR |
PCI_COMMAND_FAST_BACK ));
#endif
}
}
if( !isroot )
{
#ifdef PCI_DEBUG
printk("pci: Configuring devices on bus %d\n", pbus->number);
#endif
/*
** Run thru this bus and set up addresses for all the non-bridge devices
*/
for( pdev = pbus->devices; pdev; pdev= pdev->sibling )
{
if( (pdev->class >> 8) != PCI_CLASS_BRIDGE_PCI )
{
pci_resource *r;
int i = 0;
unsigned alloc;
/* enumerate all the resources defined by this device & reserve space
** for each of their defined regions.
*/
#ifdef PCI_DEBUG
printk("pci: configuring; vendor %04x, device %04x\n", pdev->vendor, pdev->device );
#endif
while( (r= enum_device_resources( pdev, i++ )) )
{
if( r->type & PCI_BASE_ADDRESS_MEM_PREFETCH )
{
/* prefetchable space */
/* shift base pointer down to an integer multiple of the size of the desired region */
astart.start_prefetch -= (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE);
/* shift base pointer down to an integer multiple of the size of the desired region */
astart.start_prefetch = (astart.start_prefetch / r->size) * r->size;
r->base = astart.start_prefetch;
#ifdef PCI_DEBUG
printk("pci: pf %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
#endif
}
else if( r->type & PCI_BASE_ADDRESS_SPACE_IO )
{
/* io space */
/* shift base pointer up to an integer multiple of the size of the desired region */
if( astart.start_pciio % r->size )
astart.start_pciio = (((astart.start_pciio / r->size) + 1) * r->size);
r->base = astart.start_pciio;
astart.start_pciio += (alloc= ((r->size / MEMORY_IO_GRANULARITY) + 1) * MEMORY_IO_GRANULARITY);
#ifdef PCI_DEBUG
printk("pci: io %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
#endif
}
else
{
/* memory space */
/* shift base pointer up to an integer multiple of the size of the desired region */
if( astart.start_pcimem % r->size )
astart.start_pcimem = (((astart.start_pcimem / r->size) + 1) * r->size);
r->base = astart.start_pcimem;
astart.start_pcimem += (alloc= ((r->size / MEMORY_IO_GRANULARITY) + 1) * MEMORY_IO_GRANULARITY);
#ifdef PCI_DEBUG
printk("pci: mem %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
#endif
}
}
}
}
}
}
void pci_init(void)
{
PPC_DEVICE *hostbridge;
if (pci->last_dev_p) {
@@ -925,8 +1401,14 @@ void pci_init(void) {
/* Now build a small database of all found PCI devices */
printk("\nPCI: Probing PCI hardware\n");
pci_root.subordinate=pci_scan_bus(&pci_root);
print_pci_resources("Configurable PCI resources:\n");
print_pci_resources("Installed PCI resources:\n");
recursive_bus_reconfigure(NULL);
reconfigure_pci();
print_pci_resources("Allocated PCI resources:\n");
}
/* eof */

View File

@@ -118,6 +118,70 @@ static int isValidInterrupt(int irq)
return 1;
}
/*
* ------------------------ RTEMS Shared Irq Handler Mngt Routines ----------------
*/
int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq)
{
unsigned int level;
rtems_irq_connect_data* vchain;
if (!isValidInterrupt(irq->name)) {
printk("Invalid interrupt vector %i\n",irq->name);
return 0;
}
if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) {
printk("IRQ vector %i already connected to an unshared handler\n",irq->name);
return 0;
}
_CPU_ISR_Disable(level);
vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
/* save off topmost handler */
vchain[0]= rtems_hdl_tbl[irq->name];
/*
* store the data provided by user
*/
rtems_hdl_tbl[irq->name] = *irq;
/* link chain to new topmost handler */
rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
if (is_isa_irq(irq->name)) {
/*
* Enable interrupt at PIC level
*/
BSP_irq_enable_at_i8259s (irq->name);
}
if (is_pci_irq(irq->name)) {
/*
* Enable interrupt at OPENPIC level
*/
openpic_enable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET);
}
if (is_processor_irq(irq->name)) {
/*
* Enable exception at processor level
*/
}
/*
* Enable interrupt on device
*/
irq->on(irq);
_CPU_ISR_Enable(level);
return 1;
}
/*
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
@@ -147,6 +211,7 @@ int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
* store the data provided by user
*/
rtems_hdl_tbl[irq->name] = *irq;
rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
if (is_isa_irq(irq->name)) {
/*
@@ -189,6 +254,7 @@ int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
unsigned int level;
if (!isValidInterrupt(irq->name)) {
@@ -206,6 +272,35 @@ int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
}
_CPU_ISR_Disable(level);
if( (int)rtems_hdl_tbl[irq->name].next_handler != -1 )
{
int found = 0;
for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
(vchain->hdl != default_rtems_entry.hdl);
(pchain= vchain, vchain = (rtems_irq_connect_data*)vchain->next_handler) )
{
if( vchain->hdl == irq->hdl )
{
found= -1; break;
}
}
if( !found )
{
_CPU_ISR_Enable(level);
return 0;
}
}
else
{
if (rtems_hdl_tbl[irq->name].hdl != irq->hdl)
{
_CPU_ISR_Enable(level);
return 0;
}
}
if (is_isa_irq(irq->name)) {
/*
* disable interrupt at PIC level
@@ -232,7 +327,27 @@ int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
/*
* restore the default irq value
*/
if( !vchain )
{
/* single handler vector... */
rtems_hdl_tbl[irq->name] = default_rtems_entry;
}
else
{
if( pchain )
{
/* non-first handler being removed */
pchain->next_handler = vchain->next_handler;
}
else
{
/* first handler isn't malloc'ed, so just overwrite it. Since
the contents of vchain are being struct copied, vchain itself
goes away */
rtems_hdl_tbl[irq->name]= *vchain;
}
free(vchain);
}
_CPU_ISR_Enable(level);
@@ -266,10 +381,29 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
BSP_irq_enable_at_i8259s (i);
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
/* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[i];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->on(vchain);
}
}
}
else {
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
/* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[i];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->off(vchain);
}
}
BSP_irq_disable_at_i8259s (i);
}
}
@@ -288,10 +422,30 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
internal_config->irqPrioTbl[i]);
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
/* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[i];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->on(vchain);
}
}
}
else {
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
/* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[i];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->off(vchain);
}
}
openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
}
}
@@ -304,10 +458,30 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
*/
for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) {
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
/* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[i];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->on(vchain);
}
}
}
else {
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
/* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[i];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->off(vchain);
}
}
}
}
_CPU_ISR_Enable(level);
@@ -373,7 +547,17 @@ void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
new_msr = msr | MSR_EE;
_CPU_MSR_SET(new_msr);
rtems_hdl_tbl[irq].hdl();
/* rtems_hdl_tbl[irq].hdl(); */
{
rtems_irq_connect_data* vchain;
for( vchain = &rtems_hdl_tbl[irq];
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
vchain = (rtems_irq_connect_data*)vchain->next_handler )
{
vchain->hdl();
}
}
_CPU_MSR_SET(msr);

View File

@@ -175,6 +175,11 @@ typedef struct __rtems_irq_connect_data__ {
* if someone manipulates the i8259s interrupt mask without care...
*/
rtems_irq_is_enabled isOn;
/*
* Set to -1 for vectors forced to have only 1 handler
*/
void *next_handler;
}rtems_irq_connect_data;
typedef struct {
@@ -276,6 +281,10 @@ int BSP_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine);
*
*/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data*);
#define BSP_SHARED_HANDLER_SUPPORT 1
/*
* function to get the current RTEMS irq handler for ptr->name. It enables to
* define hanlder chain...

View File

@@ -18,6 +18,137 @@
#include <libcpu/io.h>
#include <string.h>
/*
** Board-specific table that maps interrupt names to onboard pci
** peripherals as well as local pci busses. This table is used at
** bspstart() to configure the interrupt name & pin for all devices that
** do not have it already specified. If the device is already
** configured, we leave it alone but sanity check & print a warning if
** we don't know about the pin/line the card gives us.
**
** bus = the bus number of the slot/device in question
**
** slot :
**
** If slot != -1, it indicates a device on the given bus in that slot
** is to use one of the listed interrupt names given an interrupt pin.
**
** If slot == -1, it means devices on this bus can occupy any slot-
** and for pci, this means the particular interrupt pin that the
** device signals is therefore dependent on the particular slot. To
** work from the slot to the interrupt pin, the swizzle table is used.
** Once the bus and interrupt pin is known, the correct interrupt name
** can be pulled from the table. The swizzle table relates the
** interrupt pin from the device to the particular interrupt
** controller interrupt pin- so it is quite reasonable for a device on
** bus 1 signalling interrupt pin 1 to show up at the interrupt
** controller as pin 4- this is why the int pin field varies for
** bridged pci busses.
**
**
** opts = bitmap of options that control the configuration of this
** slot/bus.
**
** pin_routes[] = array of pin & vectors that may serve this slot;
**
** pin = the pin # which delivers an interrupt on this route, A=1,
** B=2, C=3, D=4
**
** int_name[4] = an array of up to 4 bsp-specific interrupt name
** that can be used by this route. Unused entries should be -1.
** The array is of primary use for slots that can be vectored thru
** multiple interrupt lines over the interrupt pin supplied by the
** record. If more than one entry is present, the most preferable
** should supplied first.
**
*/
#define NULL_PINMAP {-1,{-1,-1,-1,-1}}
#define NULL_INTMAP {-1,-1,-1,{}}
static struct _int_map mcp750_intmap[] = {
{ 0, 16, 0, {{1, {5, 19,-1,-1}}, /* pmc slot */
NULL_PINMAP}},
{ 0, 14, 0, {{1, {10,18,-1,-1}}, /* onboard ethernet */
NULL_PINMAP}},
{ 1, -1, 0, {{1, {24,-1,-1,-1}},
{2, {25,-1,-1,-1}},
{3, {26,-1,-1,-1}},
{4, {27,-1,-1,-1}},
NULL_PINMAP}},
NULL_INTMAP };
static struct _int_map mtx603_intmap[] = {
{0, 14, 0, {{1, {10,16,-1,-1}}, /* onboard ethernet */
NULL_PINMAP}},
{0, 12, 0, {{1, {14,18,-1,-1}}, /* onboard scsi */
NULL_PINMAP}},
{0, 16, 0, {{1, {25,-1,-1,-1}}, /* pci/pmc slot 1 */
{2, {26,-1,-1,-1}},
{3, {27,-1,-1,-1}},
{4, {28,-1,-1,-1}},
NULL_PINMAP}},
{0, 17, 0, {{1, {26,-1,-1,-1}}, /* pci/pmc slot 2 */
{2, {27,-1,-1,-1}},
{3, {28,-1,-1,-1}},
{4, {25,-1,-1,-1}},
NULL_PINMAP}},
{0, 18, 0, {{1, {27,-1,-1,-1}}, /* pci slot 3 */
{2, {28,-1,-1,-1}},
{3, {25,-1,-1,-1}},
{4, {26,-1,-1,-1}},
NULL_PINMAP}},
NULL_INTMAP };
/*
* This table represents the standard PCI swizzle defined in the
* PCI bus specification. Table taken from Linux 2.4.18, prep_pci.c,
* the values in this table are interrupt_pin values (1 based).
*/
static unsigned char prep_pci_intpins[4][4] =
{
{ 1, 2, 3, 4 }, /* Buses 0, 4, 8, ... */
{ 2, 3, 4, 1 }, /* Buses 1, 5, 9, ... */
{ 3, 4, 1, 2 }, /* Buses 2, 6, 10 ... */
{ 4, 1, 2, 3 }, /* Buses 3, 7, 11 ... */
};
static int prep_pci_swizzle(int slot, int pin)
{
return prep_pci_intpins[ slot % 4 ][ pin-1 ];
}
typedef struct {
/*
* 0x100 mask assumes for Raven and Hawk boards
@@ -27,33 +158,38 @@ typedef struct {
int cpu_type;
int base_type;
const char *name;
struct _int_map *intmap;
int (*swizzler)(int, int);
} mot_info_t;
static const mot_info_t mot_boards[] = {
{0x300, 0x00, "MVME 2400"},
{0x010, 0x00, "Genesis"},
{0x020, 0x00, "Powerstack (Series E)"},
{0x040, 0x00, "Blackhawk (Powerstack)"},
{0x050, 0x00, "Omaha (PowerStack II Pro3000)"},
{0x060, 0x00, "Utah (Powerstack II Pro4000)"},
{0x0A0, 0x00, "Powerstack (Series EX)"},
{0x1E0, 0xE0, "Mesquite cPCI (MCP750)"},
{0x1E0, 0xE1, "Sitka cPCI (MCPN750)"},
{0x1E0, 0xE2, "Mesquite cPCI (MCP750) w/ HAC"},
{0x1E0, 0xF6, "MTX Plus"},
{0x1E0, 0xF7, "MTX w/o Parallel Port"},
{0x1E0, 0xF8, "MTX w/ Parallel Port"},
{0x1E0, 0xF9, "MVME 2300"},
{0x1E0, 0xFA, "MVME 2300SC/2600"},
{0x1E0, 0xFB, "MVME 2600 with MVME712M"},
{0x1E0, 0xFC, "MVME 2600/2700 with MVME761"},
{0x1E0, 0xFD, "MVME 3600 with MVME712M"},
{0x1E0, 0xFE, "MVME 3600 with MVME761"},
{0x1E0, 0xFF, "MVME 1600-001 or 1600-011"},
{0x300, 0x00, "MVME 2400", NULL, NULL},
{0x010, 0x00, "Genesis", NULL, NULL},
{0x020, 0x00, "Powerstack (Series E)", NULL, NULL},
{0x040, 0x00, "Blackhawk (Powerstack)", NULL, NULL},
{0x050, 0x00, "Omaha (PowerStack II Pro3000)", NULL, NULL},
{0x060, 0x00, "Utah (Powerstack II Pro4000)", NULL, NULL},
{0x0A0, 0x00, "Powerstack (Series EX)", NULL, NULL},
{0x1E0, 0xE0, "Mesquite cPCI (MCP750)", mcp750_intmap, prep_pci_swizzle},
{0x1E0, 0xE1, "Sitka cPCI (MCPN750)", mcp750_intmap, prep_pci_swizzle},
{0x1E0, 0xE2, "Mesquite cPCI (MCP750) w/ HAC", mcp750_intmap, prep_pci_swizzle},
{0x1E0, 0xF6, "MTX Plus", NULL, NULL},
{0x1E0, 0xF7, "MTX w/o Parallel Port", mtx603_intmap, prep_pci_swizzle},
{0x1E0, 0xF8, "MTX w/ Parallel Port", mtx603_intmap, prep_pci_swizzle},
{0x1E0, 0xF9, "MVME 2300", NULL, NULL},
{0x1E0, 0xFA, "MVME 2300SC/2600", NULL, NULL},
{0x1E0, 0xFB, "MVME 2600 with MVME712M", NULL, NULL},
{0x1E0, 0xFC, "MVME 2600/2700 with MVME761", NULL, NULL},
{0x1E0, 0xFD, "MVME 3600 with MVME712M", NULL, NULL},
{0x1E0, 0xFE, "MVME 3600 with MVME761", NULL, NULL},
{0x1E0, 0xFF, "MVME 1600-001 or 1600-011", NULL, NULL},
{0x000, 0x00, ""}
};
prep_t currentPrepType;
motorolaBoard currentBoard;
prep_t checkPrepBoardType(RESIDUAL *res)
@@ -114,9 +250,24 @@ motorolaBoard getMotorolaBoard()
return currentBoard;
}
const char* motorolaBoardToString(motorolaBoard board)
{
if (board == MOTOROLA_UNKNOWN) return "Unknown motorola board";
return (mot_boards[board].name);
}
const struct _int_map *motorolaIntMap(motorolaBoard board)
{
if (board == MOTOROLA_UNKNOWN) return NULL;
return mot_boards[board].intmap;
}
const void *motorolaIntSwizzle(motorolaBoard board)
{
if (board == MOTOROLA_UNKNOWN) return NULL;
return (void *)mot_boards[board].swizzler;
}

View File

@@ -16,6 +16,14 @@
#define LIBBSP_POWERPC_SHARED_MOTOROLA_MOTOROLA_H
#include <bsp/residual.h>
#include <bsp/pci.h>
typedef enum {
PREP_IBM = 0,
@@ -61,6 +69,8 @@ extern prep_t currentPrepType;
extern motorolaBoard getMotorolaBoard();
extern motorolaBoard currentBoard;
extern const char* motorolaBoardToString(motorolaBoard);
extern const struct _int_map *motorolaIntMap(motorolaBoard board);
extern const void *motorolaIntSwizzle(motorolaBoard board);
#endif /* LIBBSP_POWERPC_SHARED_MOTOROLA_MOTOROLA_H */

View File

@@ -216,6 +216,320 @@ const pci_config_access_functions pci_direct_functions = {
};
#define PRINT_MSG() \
printk("pci : Device %d:%02x routed to interrupt_line %d\n", pbus, pslot, int_name )
/*
** Validate a test interrupt name and print a warning if its not one of
** the names defined in the routing record.
*/
static int test_intname( struct _int_map *row, int pbus, int pslot, int int_pin, int int_name )
{
int j,k;
int _nopin= -1, _noname= -1;
for(j=0; row->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:%02x supplied a bogus interrupt_pin %d\n", pbus, pslot, int_pin );
return -1;
}
else
{
if( _noname )
printk("pci : Device %d:%02x supplied a suspicious interrupt_line %d, using it anyway\n", pbus, pslot, int_name );
}
return 0;
}
struct pcibridge
{
int bus,slot;
};
static int FindPCIbridge( int mybus, struct pcibridge *pb )
{
int pbus, pslot;
unsigned8 bussec, buspri;
unsigned16 devid, vendorid, dclass;
for(pbus=0; pbus< BusCountPCI(); 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);
#if 0
printk("pci : Found bridge at %d:%d, mybus %d, pribus %d, secbus %d ", pbus, pslot, mybus, buspri, bussec );
#endif
if( bussec == mybus )
{
#if 0
printk("match\n");
#endif
/* found our nearest bridge going towards the root */
pb->bus = pbus;
pb->slot = pslot;
return 0;
}
#if 0
printk("no match\n");
#endif
}
}
}
return -1;
}
void FixupPCI( struct _int_map *bspmap, int (*swizzler)(int,int) )
{
unsigned char cvalue;
unsigned16 devid;
int ismatch, i, j, pbus, pslot, int_pin, int_name;
/*
** 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< BusCountPCI(); 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_INTERRUPT_PIN, &cvalue);
int_pin = cvalue;
pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_LINE, &cvalue);
int_name = cvalue;
/* printk("pci : device %d:%02x devid %04x, intpin %d, intline %d\n", pbus, pslot, devid, int_pin, int_name ); */
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:%d w/ swizzled int pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
}
else
{
PRINT_MSG();
pci_write_config_byte(pbus,pslot,0,PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
}
}
else
{
test_intname( &bspmap[i],pbus,pslot,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:%d w/ swizzled int pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
}
else
{
PRINT_MSG();
pci_write_config_byte(pbus,pslot,0,PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
}
}
else
{
test_intname(&bspmap[i],pbus,pslot,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:%d with an int routing table entry\n", pbus, pslot );
}
}
}
}
}
/*
* This routine determines the maximum bus number in the system
*/
@@ -228,6 +542,7 @@ void InitializePCI()
unsigned int ulClass, ulDeviceID;
detect_host_bridge();
/*
* Scan PCI bus 0 looking for PCI-PCI bridges
*/

View File

@@ -1153,6 +1153,20 @@ pci_write_config_dword(unsigned char bus, unsigned char slot, unsigned char func
extern unsigned char BusCountPCI();
extern void InitializePCI();
struct _pin_routes
{
int pin, int_name[4];
};
struct _int_map
{
int bus, slot, opts;
struct _pin_routes pin_route[5];
};
void FixupPCI( struct _int_map *, int (*swizzler)(int,int) );
/* scan for a specific device */
/* find a particular PCI device
* (currently, only bus0 is scanned for device/fun0)

View File

@@ -37,7 +37,7 @@ unsigned char bus,dev,fun,hd;
if (PCI_INVALID_VENDORDEVICEID == d)
continue;
#ifdef PCI_DEBUG
printk("BSP_pciFindDevice: found 0x%08x at %i/%i/%i\n",d,bus,dev,fun);
printk("BSP_pciFindDevice: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
#endif
(void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
if (vendorid != s)

View File

@@ -253,7 +253,7 @@ void bsp_start( void )
* provided by the RAVEN
*/
/* T. Straumann: give more PCI address space */
setdbat(2, PCI_MEM_BASE, PCI_MEM_BASE, 0x10000000, IO_PAGE);
setdbat(2, PCI_MEM_BASE, PCI_MEM_BASE, 0x30000000, IO_PAGE);
/*
* Must have acces to open pic PCI ACK registers
* provided by the RAVEN
@@ -300,6 +300,21 @@ void bsp_start( void )
printk("Going to start PCI buses scanning and initialization\n");
#endif
InitializePCI();
{
struct _int_map *bspmap = motorolaIntMap(currentBoard);
if( bspmap )
{
printk("pci : Configuring interrupt routing for '%s'\n", motorolaBoardToString(currentBoard));
FixupPCI(bspmap, motorolaIntSwizzle(currentBoard) );
}
else
printk("pci : Interrupt routing not available for this bsp\n");
}
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Number of PCI buses found is : %d\n", BusCountPCI());
#endif