forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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>
|
2003-06-13 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
PR 415/bsps
|
PR 415/bsps
|
||||||
|
|||||||
@@ -39,3 +39,11 @@ initialization (e.g printk, ...).
|
|||||||
Eric Valette (valette@crf.canon.fr)
|
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.
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -118,6 +118,70 @@ static int isValidInterrupt(int irq)
|
|||||||
return 1;
|
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 ----------------
|
* ------------------------ 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
|
* store the data provided by user
|
||||||
*/
|
*/
|
||||||
rtems_hdl_tbl[irq->name] = *irq;
|
rtems_hdl_tbl[irq->name] = *irq;
|
||||||
|
rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
|
||||||
|
|
||||||
if (is_isa_irq(irq->name)) {
|
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)
|
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
||||||
{
|
{
|
||||||
|
rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
|
||||||
unsigned int level;
|
unsigned int level;
|
||||||
|
|
||||||
if (!isValidInterrupt(irq->name)) {
|
if (!isValidInterrupt(irq->name)) {
|
||||||
@@ -206,6 +272,35 @@ int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
|||||||
}
|
}
|
||||||
_CPU_ISR_Disable(level);
|
_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)) {
|
if (is_isa_irq(irq->name)) {
|
||||||
/*
|
/*
|
||||||
* disable interrupt at PIC level
|
* 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
|
* restore the default irq value
|
||||||
*/
|
*/
|
||||||
rtems_hdl_tbl[irq->name] = default_rtems_entry;
|
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);
|
_CPU_ISR_Enable(level);
|
||||||
|
|
||||||
@@ -265,12 +380,31 @@ 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++) {
|
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) {
|
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
||||||
BSP_irq_enable_at_i8259s (i);
|
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 {
|
else {
|
||||||
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
|
/* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
|
||||||
BSP_irq_disable_at_i8259s (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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -287,12 +421,32 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
|
|||||||
openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET,
|
openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET,
|
||||||
internal_config->irqPrioTbl[i]);
|
internal_config->irqPrioTbl[i]);
|
||||||
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
||||||
openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
|
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 {
|
else {
|
||||||
rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
|
/* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
|
||||||
openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
|
{
|
||||||
|
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++) {
|
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) {
|
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 {
|
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);
|
_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;
|
new_msr = msr | MSR_EE;
|
||||||
_CPU_MSR_SET(new_msr);
|
_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);
|
_CPU_MSR_SET(msr);
|
||||||
|
|
||||||
|
|||||||
@@ -143,38 +143,43 @@ typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
|
|||||||
typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
|
typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
|
||||||
|
|
||||||
typedef struct __rtems_irq_connect_data__ {
|
typedef struct __rtems_irq_connect_data__ {
|
||||||
/*
|
/*
|
||||||
* IRQ line
|
* IRQ line
|
||||||
*/
|
*/
|
||||||
rtems_irq_symbolic_name name;
|
rtems_irq_symbolic_name name;
|
||||||
/*
|
/*
|
||||||
* handler. See comment on handler properties below in function prototype.
|
* handler. See comment on handler properties below in function prototype.
|
||||||
*/
|
*/
|
||||||
rtems_irq_hdl hdl;
|
rtems_irq_hdl hdl;
|
||||||
/*
|
/*
|
||||||
* function for enabling interrupts at device level (ONLY!).
|
* function for enabling interrupts at device level (ONLY!).
|
||||||
* The BSP code will automatically enable it at i8259s level and openpic level.
|
* The BSP code will automatically enable it at i8259s level and openpic level.
|
||||||
* RATIONALE : anyway such code has to exist in current driver code.
|
* RATIONALE : anyway such code has to exist in current driver code.
|
||||||
* It is usually called immediately AFTER connecting the interrupt handler.
|
* It is usually called immediately AFTER connecting the interrupt handler.
|
||||||
* RTEMS may well need such a function when restoring normal interrupt
|
* RTEMS may well need such a function when restoring normal interrupt
|
||||||
* processing after a debug session.
|
* processing after a debug session.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
rtems_irq_enable on;
|
rtems_irq_enable on;
|
||||||
/*
|
/*
|
||||||
* function for disabling interrupts at device level (ONLY!).
|
* function for disabling interrupts at device level (ONLY!).
|
||||||
* The code will disable it at i8259s level. RATIONALE : anyway
|
* The code will disable it at i8259s level. RATIONALE : anyway
|
||||||
* such code has to exist for clean shutdown. It is usually called
|
* such code has to exist for clean shutdown. It is usually called
|
||||||
* BEFORE disconnecting the interrupt. RTEMS may well need such
|
* BEFORE disconnecting the interrupt. RTEMS may well need such
|
||||||
* a function when disabling normal interrupt processing for
|
* a function when disabling normal interrupt processing for
|
||||||
* a debug session. May well be a NOP function.
|
* a debug session. May well be a NOP function.
|
||||||
*/
|
*/
|
||||||
rtems_irq_disable off;
|
rtems_irq_disable off;
|
||||||
/*
|
/*
|
||||||
* function enabling to know what interrupt may currently occur
|
* function enabling to know what interrupt may currently occur
|
||||||
* if someone manipulates the i8259s interrupt mask without care...
|
* if someone manipulates the i8259s interrupt mask without care...
|
||||||
*/
|
*/
|
||||||
rtems_irq_is_enabled isOn;
|
rtems_irq_is_enabled isOn;
|
||||||
|
/*
|
||||||
|
* Set to -1 for vectors forced to have only 1 handler
|
||||||
|
*/
|
||||||
|
void *next_handler;
|
||||||
|
|
||||||
}rtems_irq_connect_data;
|
}rtems_irq_connect_data;
|
||||||
|
|
||||||
typedef struct {
|
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_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
|
* function to get the current RTEMS irq handler for ptr->name. It enables to
|
||||||
* define hanlder chain...
|
* define hanlder chain...
|
||||||
|
|||||||
@@ -18,42 +18,178 @@
|
|||||||
#include <libcpu/io.h>
|
#include <libcpu/io.h>
|
||||||
#include <string.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 {
|
typedef struct {
|
||||||
/*
|
/*
|
||||||
* 0x100 mask assumes for Raven and Hawk boards
|
* 0x100 mask assumes for Raven and Hawk boards
|
||||||
* that the level/edge are set.
|
* that the level/edge are set.
|
||||||
* 0x200 if this board has a Hawk chip.
|
* 0x200 if this board has a Hawk chip.
|
||||||
*/
|
*/
|
||||||
int cpu_type;
|
int cpu_type;
|
||||||
int base_type;
|
int base_type;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
struct _int_map *intmap;
|
||||||
|
int (*swizzler)(int, int);
|
||||||
} mot_info_t;
|
} mot_info_t;
|
||||||
|
|
||||||
|
|
||||||
static const mot_info_t mot_boards[] = {
|
static const mot_info_t mot_boards[] = {
|
||||||
{0x300, 0x00, "MVME 2400"},
|
{0x300, 0x00, "MVME 2400", NULL, NULL},
|
||||||
{0x010, 0x00, "Genesis"},
|
{0x010, 0x00, "Genesis", NULL, NULL},
|
||||||
{0x020, 0x00, "Powerstack (Series E)"},
|
{0x020, 0x00, "Powerstack (Series E)", NULL, NULL},
|
||||||
{0x040, 0x00, "Blackhawk (Powerstack)"},
|
{0x040, 0x00, "Blackhawk (Powerstack)", NULL, NULL},
|
||||||
{0x050, 0x00, "Omaha (PowerStack II Pro3000)"},
|
{0x050, 0x00, "Omaha (PowerStack II Pro3000)", NULL, NULL},
|
||||||
{0x060, 0x00, "Utah (Powerstack II Pro4000)"},
|
{0x060, 0x00, "Utah (Powerstack II Pro4000)", NULL, NULL},
|
||||||
{0x0A0, 0x00, "Powerstack (Series EX)"},
|
{0x0A0, 0x00, "Powerstack (Series EX)", NULL, NULL},
|
||||||
{0x1E0, 0xE0, "Mesquite cPCI (MCP750)"},
|
{0x1E0, 0xE0, "Mesquite cPCI (MCP750)", mcp750_intmap, prep_pci_swizzle},
|
||||||
{0x1E0, 0xE1, "Sitka cPCI (MCPN750)"},
|
{0x1E0, 0xE1, "Sitka cPCI (MCPN750)", mcp750_intmap, prep_pci_swizzle},
|
||||||
{0x1E0, 0xE2, "Mesquite cPCI (MCP750) w/ HAC"},
|
{0x1E0, 0xE2, "Mesquite cPCI (MCP750) w/ HAC", mcp750_intmap, prep_pci_swizzle},
|
||||||
{0x1E0, 0xF6, "MTX Plus"},
|
{0x1E0, 0xF6, "MTX Plus", NULL, NULL},
|
||||||
{0x1E0, 0xF7, "MTX w/o Parallel Port"},
|
{0x1E0, 0xF7, "MTX w/o Parallel Port", mtx603_intmap, prep_pci_swizzle},
|
||||||
{0x1E0, 0xF8, "MTX w/ Parallel Port"},
|
{0x1E0, 0xF8, "MTX w/ Parallel Port", mtx603_intmap, prep_pci_swizzle},
|
||||||
{0x1E0, 0xF9, "MVME 2300"},
|
{0x1E0, 0xF9, "MVME 2300", NULL, NULL},
|
||||||
{0x1E0, 0xFA, "MVME 2300SC/2600"},
|
{0x1E0, 0xFA, "MVME 2300SC/2600", NULL, NULL},
|
||||||
{0x1E0, 0xFB, "MVME 2600 with MVME712M"},
|
{0x1E0, 0xFB, "MVME 2600 with MVME712M", NULL, NULL},
|
||||||
{0x1E0, 0xFC, "MVME 2600/2700 with MVME761"},
|
{0x1E0, 0xFC, "MVME 2600/2700 with MVME761", NULL, NULL},
|
||||||
{0x1E0, 0xFD, "MVME 3600 with MVME712M"},
|
{0x1E0, 0xFD, "MVME 3600 with MVME712M", NULL, NULL},
|
||||||
{0x1E0, 0xFE, "MVME 3600 with MVME761"},
|
{0x1E0, 0xFE, "MVME 3600 with MVME761", NULL, NULL},
|
||||||
{0x1E0, 0xFF, "MVME 1600-001 or 1600-011"},
|
{0x1E0, 0xFF, "MVME 1600-001 or 1600-011", NULL, NULL},
|
||||||
{0x000, 0x00, ""}
|
{0x000, 0x00, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
prep_t currentPrepType;
|
prep_t currentPrepType;
|
||||||
motorolaBoard currentBoard;
|
motorolaBoard currentBoard;
|
||||||
prep_t checkPrepBoardType(RESIDUAL *res)
|
prep_t checkPrepBoardType(RESIDUAL *res)
|
||||||
@@ -114,9 +250,24 @@ motorolaBoard getMotorolaBoard()
|
|||||||
return currentBoard;
|
return currentBoard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* motorolaBoardToString(motorolaBoard board)
|
const char* motorolaBoardToString(motorolaBoard board)
|
||||||
{
|
{
|
||||||
if (board == MOTOROLA_UNKNOWN) return "Unknown motorola board";
|
if (board == MOTOROLA_UNKNOWN) return "Unknown motorola board";
|
||||||
return (mot_boards[board].name);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,14 @@
|
|||||||
#define LIBBSP_POWERPC_SHARED_MOTOROLA_MOTOROLA_H
|
#define LIBBSP_POWERPC_SHARED_MOTOROLA_MOTOROLA_H
|
||||||
|
|
||||||
#include <bsp/residual.h>
|
#include <bsp/residual.h>
|
||||||
|
#include <bsp/pci.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PREP_IBM = 0,
|
PREP_IBM = 0,
|
||||||
@@ -61,6 +69,8 @@ extern prep_t currentPrepType;
|
|||||||
extern motorolaBoard getMotorolaBoard();
|
extern motorolaBoard getMotorolaBoard();
|
||||||
extern motorolaBoard currentBoard;
|
extern motorolaBoard currentBoard;
|
||||||
extern const char* motorolaBoardToString(motorolaBoard);
|
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 */
|
#endif /* LIBBSP_POWERPC_SHARED_MOTOROLA_MOTOROLA_H */
|
||||||
|
|||||||
@@ -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
|
* This routine determines the maximum bus number in the system
|
||||||
*/
|
*/
|
||||||
@@ -228,6 +542,7 @@ void InitializePCI()
|
|||||||
unsigned int ulClass, ulDeviceID;
|
unsigned int ulClass, ulDeviceID;
|
||||||
|
|
||||||
detect_host_bridge();
|
detect_host_bridge();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan PCI bus 0 looking for PCI-PCI bridges
|
* Scan PCI bus 0 looking for PCI-PCI bridges
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1153,6 +1153,20 @@ pci_write_config_dword(unsigned char bus, unsigned char slot, unsigned char func
|
|||||||
extern unsigned char BusCountPCI();
|
extern unsigned char BusCountPCI();
|
||||||
extern void InitializePCI();
|
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 */
|
/* scan for a specific device */
|
||||||
/* find a particular PCI device
|
/* find a particular PCI device
|
||||||
* (currently, only bus0 is scanned for device/fun0)
|
* (currently, only bus0 is scanned for device/fun0)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ unsigned char bus,dev,fun,hd;
|
|||||||
if (PCI_INVALID_VENDORDEVICEID == d)
|
if (PCI_INVALID_VENDORDEVICEID == d)
|
||||||
continue;
|
continue;
|
||||||
#ifdef PCI_DEBUG
|
#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
|
#endif
|
||||||
(void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
|
(void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
|
||||||
if (vendorid != s)
|
if (vendorid != s)
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ void bsp_start( void )
|
|||||||
* provided by the RAVEN
|
* provided by the RAVEN
|
||||||
*/
|
*/
|
||||||
/* T. Straumann: give more PCI address space */
|
/* 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
|
* Must have acces to open pic PCI ACK registers
|
||||||
* provided by the RAVEN
|
* provided by the RAVEN
|
||||||
@@ -300,6 +300,21 @@ void bsp_start( void )
|
|||||||
printk("Going to start PCI buses scanning and initialization\n");
|
printk("Going to start PCI buses scanning and initialization\n");
|
||||||
#endif
|
#endif
|
||||||
InitializePCI();
|
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
|
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||||
printk("Number of PCI buses found is : %d\n", BusCountPCI());
|
printk("Number of PCI buses found is : %d\n", BusCountPCI());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user