⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interrupts.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 3 页
字号:
//=============================================================================
//
//      interrupts.c - Cyclone Diagnostics
//
//=============================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 2001 Red Hat, Inc.                             
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
// Contributors:
// Date:        2001-01-25
// Purpose:     
// Description: 
//
//####DESCRIPTIONEND####
//
//===========================================================================*/

/******************************************************************************/
/* interrupts.c - Interrupt dispatcher routines for IQ80310 Board			  */
/*																			  */
/* modification history														  */
/* --------------------														  */
/* 07sep00, ejb, Written for IQ80310 Cygmon diagnostics						  */
/* 11oct00, ejb, Switched FIQ and IRQ interrupt handlers					  */
/* 18dec00  snc and jwf                                                       */
/* 02feb01  jwf for snc                                                       */
/******************************************************************************/

#include "iq80310.h"
#include "pci_bios.h"
#include "7_segment_displays.h"

extern int(*board_fiq_handler)(void);
extern int(*board_irq_handler)(void);
extern long _cspr_enable_fiq_int();
extern long _cspr_enable_irq_int();
extern long _read_cpsr();
extern long _scrub_ecc();


#define AND_WORD(addr,val)   *addr = *addr & val


void error_print(char *fmt, int arg0, int arg1, int arg2, int arg3);


extern int nmi_verbose;	/* for NMI, only print NMI info if this is TRUE */
extern int pci_config_cycle; /* don't handle NMI if in a config cycle */
extern int pci_config_error;

typedef struct
{
	FUNCPTR	handler;
	int		arg;
	int		bus;
	int		device;
} INT_HANDLER;

extern UINT	secondary_busno;
extern UINT	primary_busno;

extern STATUS pci_to_xint(int device, int intpin, int *xint);
extern int isHost();
extern int off_ppci_bus (int busno);

#define MAX_SPURIOUS_CNT	5
#define NUM_PCI_XINTS		4		/* SINTA - SINTD */
#define MAX_PCI_HANDLERS	8		/* maximum handlers per PCI Xint */

/* 02/02/01 jwf */
int ecc_error_reported = FALSE;

static int isr_xint0_spurious = 0;
static int isr_xint1_spurious = 0;
static int isr_xint2_spurious = 0;
static int isr_xint3_spurious = 0;

/* Table where the interrupt handler addresses are stored. */
INT_HANDLER pci_int_handlers[4][MAX_PCI_HANDLERS];

/* Other User Interrupt Service Routines */

void (*usr_timer_isr)(int) = NULL;
int usr_timer_arg = 0;
void (*usr_enet_isr)(int) = NULL;
int usr_enet_arg = 0;
void (*usr_uart1_isr)(int) = NULL;
int usr_uart1_arg = 0;
void (*usr_uart2_isr)(int) = NULL;
int usr_uart2_arg = 0;
void (*usr_dma0_isr)(int) = NULL;
int usr_dma0_arg = 0;
void (*usr_dma1_isr)(int) = NULL;
int usr_dma1_arg = 0;
void (*usr_dma2_isr)(int) = NULL;
int usr_dma2_arg = 0;
void (*usr_pm_isr)(int) = NULL;
int usr_pm_arg = 0;
void (*usr_aa_isr)(int) = NULL;
int usr_aa_arg = 0;
void (*usr_i2c_isr)(int) = NULL;
int usr_i2c_arg = 0;
void (*usr_mu_isr)(int) = NULL;
int usr_mu_arg = 0;
void (*usr_patu_isr)(int) = NULL;
int usr_patu_arg = 0;

int ecc_int_handler();



/*********************************
* PCI interrupt wrappers 
*/
int sinta_handler()
{
    int x, serviced = 0;
	/* cycle through connected interrupt handlers to determine which caused int */
	for (x = 0; x < MAX_PCI_HANDLERS; x++) 
	{
		if (pci_int_handlers[0][x].handler != NULL)	/* Is a routine installed */
			if ((*pci_int_handlers[0][x].handler)(pci_int_handlers[0][x].arg) == 1)	
			{
				serviced = 1;
				break;
			}
	}
	if (serviced == 0)
	{
		isr_xint0_spurious++;

		if (isr_xint0_spurious > MAX_SPURIOUS_CNT)
			; 
	}
	else
		isr_xint0_spurious = 0;

	return (serviced);

}

int sintb_handler()
{
    int x, serviced = 0;
	
	/* cycle through connected interrupt handlers to determine which caused int */
	for (x = 0; x < MAX_PCI_HANDLERS; x++) 
	{
		if (pci_int_handlers[1][x].handler != NULL)	/* Is a routine installed */
			if ((*pci_int_handlers[1][x].handler)(pci_int_handlers[1][x].arg) == 1)	
			{
				serviced = 1;
				break;
			}
	}
	if (serviced == 0)
	{
		isr_xint1_spurious++;

		if (isr_xint1_spurious > MAX_SPURIOUS_CNT)
			;
	}
	else
		isr_xint1_spurious = 0;

	return (serviced);

}

int sintc_handler()
{

    int x, serviced = 0;

	/* cycle through connected interrupt handlers to determine which caused int */
	for (x = 0; x < MAX_PCI_HANDLERS; x++) 
	{
		if (pci_int_handlers[2][x].handler != NULL)	/* Is a routine installed */
			if ((*pci_int_handlers[2][x].handler)(pci_int_handlers[2][x].arg) == 1)	
			{
				serviced = 1;
				break;
			}
	}
	if (serviced == 0)
	{
		isr_xint2_spurious++;

		if (isr_xint2_spurious > MAX_SPURIOUS_CNT)
			;
	}
	else
		isr_xint2_spurious = 0;

	return (serviced);

}

int sintd_handler()
{

    int x, serviced = 0;

	/* cycle through connected interrupt handlers to determine which caused int */
	for (x = 0; x < MAX_PCI_HANDLERS; x++) 
	{
		if (pci_int_handlers[3][x].handler != NULL)	/* Is a routine installed */
			if ((*pci_int_handlers[3][x].handler)(pci_int_handlers[3][x].arg) == 1)	
			{
				serviced = 1;
				break;
			}
	}
	if (serviced == 0)
	{
		isr_xint3_spurious++;

		if (isr_xint3_spurious > MAX_SPURIOUS_CNT)
			;
	}
	else
		isr_xint3_spurious = 0;

	return (serviced);


}


/******************************************************************************
*
* Installs an interrupt handler in the PCI dispatch table, to be called
* by the appropriate PCI isr (above) when an interrupt occurs.
*
* Note: the intline parameter refers to which PCI interrupt INT A - INT D
*
*       device identifies the PCI device number
*
* Note: isrs connected with this function must return 1 if an interrupt is 
*	serviced in order to support the PCI interrupt sharing mechanism
*                                                   
*/
STATUS pci_isr_connect (int intline, int bus, int device, int (*handler)(int), int arg)
{
	int which_xint;
	int handler_index;

	/* check to see if we are attempting to connect to a PPCI interrupt and we are not
	   a host card */
	if ((isHost() == FALSE) && (off_ppci_bus(bus) == TRUE))
		return (ERROR);

	if ((intline < INTA) || (intline > INTD))
		return (ERROR);

    (void)pci_to_xint(device, intline, &which_xint);

	for (handler_index = 0; handler_index < MAX_PCI_HANDLERS; handler_index++)
	{
		if (pci_int_handlers[which_xint][handler_index].handler == NULL)
		{
			pci_int_handlers[which_xint][handler_index].handler = handler;
			pci_int_handlers[which_xint][handler_index].arg		= arg;
			pci_int_handlers[which_xint][handler_index].bus		= bus;
			pci_int_handlers[which_xint][handler_index].device	= device;
			break;
		}
	}

	/* if there is no more room in the table return an error */
	if (handler_index == MAX_PCI_HANDLERS)
		return (ERROR);

    return (OK);
}


/******************************************************************************
*
* Uninstalls an interrupt handler in the PCI dispatch table
*
* Note: the intline parameter refers to which PCI interrupt INTA - INTD
*
*       the device parameter refers to which SPCI device number is sourcing the
*       interrupt
*
*/
STATUS pci_isr_disconnect (int intline, int bus, int device)
{
	int which_xint;
	int handler_index;

	/* check to see if we are attempting to disconnect a PPCI interrupt and we are not
	   a host card */
	if ((isHost() == FALSE) && (off_ppci_bus(bus) == TRUE))
		return (ERROR);

	if ((intline < INTA) || (intline > INTD))
		return (ERROR);

    (void)pci_to_xint(device, intline, &which_xint);

	for (handler_index = 0; handler_index < MAX_PCI_HANDLERS; handler_index++)
	{
		if ((pci_int_handlers[which_xint][handler_index].bus == bus) &&
			(pci_int_handlers[which_xint][handler_index].device == device))
		{
			pci_int_handlers[which_xint][handler_index].handler = NULL;
			pci_int_handlers[which_xint][handler_index].arg		= (int)NULL;
			pci_int_handlers[which_xint][handler_index].bus		= (int)NULL;
			pci_int_handlers[which_xint][handler_index].device	= (int)NULL;
		}
	}

	/* if the handler was not found in the table return an error */
	if (handler_index == MAX_PCI_HANDLERS)
		return (ERROR);

    return (OK);
}


/**********************************************************************************
* iq80310_irq_handler - Interrupt dispatcher for IQ80310 IRQ Interrupts
*
* This function determines the source of the IRQ Interrupt, and calls the 
* corresponding interrupt service routine.  If multiple sources are interrupting
* the dispatcher will call all interrupt handles.  Users must clear the interrupt
* within the interrupt service routine before exiting.
*
* IRQ Interrupts are multiplexed from SPCI INTA - INTD, External Device Interrupts,
* and XINT6 and XINT7 Internal device interrupts.
*/
int iq80310_irq_handler()
{
UINT8* int_status_reg;
UINT8  int_status;	
int num_sources = 0;


/* 12/18/00 jwf */
unsigned char ri_state;
unsigned char board_rev;
unsigned char sint_status;						/* holds interrupt status for SINTA-SINTC */
	ri_state = *( unsigned char * ) 0xfe810006;	/* access uart u2 msr reg at addr fe810006 */
	ri_state &= RI_MASK;
	if(ri_state == RI_MASK)						/* RI# pin on UART2 is grounded */
	{
		board_rev = *BOARD_REV_REG_ADDR;		/* read Board Revision register */
		board_rev &= BOARD_REV_MASK;			/* isolate LSN */
		if (board_rev >= BOARD_REV_E)			/* Board Rev is at E or higher */
		{
			sint_status = *SINT_REG_ADDR;		/* read current secondary pci interrupt status */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -