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

📄 interrupts.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
//=============================================================================
//
//      interrupts.c - Cyclone Diagnostics
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####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(void);
extern long _cspr_enable_irq_int(void);
extern long _read_cpsr(void);
extern long _scrub_ecc(unsigned);
extern void _flushICache(void);


#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
{
	INTFUNCPTR	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(void);
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(void);



/*********************************
* PCI interrupt wrappers 
*/
int sinta_handler(void)
{
    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(void)
{
    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(void)
{

    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(void)
{

    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(void)
{
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;

⌨️ 快捷键说明

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