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 + -
显示快捷键?