interrupts.c

来自「eCos操作系统源码」· C语言 代码 · 共 1,140 行 · 第 1/3 页

C
1,140
字号
//=============================================================================////      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 & valvoid 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 + =
减小字号Ctrl + -
显示快捷键?