📄 interrupts.c
字号:
//=============================================================================//// 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 & 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{ 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 + -