📄 interrupts.c
字号:
/* interrupts.c
*
*------------------------------------------------------------
*
* I N T E L P R O P R I E T A R Y
*
* COPYRIGHT (c) 1998-1999 BY INTEL CORPORATION. ALL RIGHTS
* RESERVED. NO PART OF THIS PROGRAM OR PUBLICATION MAY
* BE REPRODUCED, TRANSMITTED, TRANSCRIBED, STORED IN A
* RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER
* LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,
* MAGNETIC, OPTICAL, CHEMICAL, MANUAL, OR OTHERWISE, WITHOUT
* THE PRIOR WRITTEN PERMISSION OF :
*
* INTEL CORPORATION
*
* 2200 MISSION COLLEGE BLVD
*
* SANTA CLARA, CALIFORNIA 95052-8119
*
*------------------------------------------------------------
* system: SA1200
* subsystem: SA1200 ARM Core
* author: Henry Qian 02/22/99
* revisions:
*
* 03/31/00 - Dan White - added Rev B0 UART change
*
*/
#include "platform.h"
#include "interrupts.h"
#include "os.h"
extern int IXP1200_SysCpuRev; // A board or B0?
#ifdef __cplusplus
extern "C"
{
#endif
extern int pciCsrWr(void *, unsigned int); // safely write to PCI CSR
#ifdef __cplusplus
}
#endif
int mSEC_1;
int mSEC_5;
int mSEC_10;
int mSEC_100;
int SEC_1;
int SEC_10;
// -----------------------
// Regular Interrupt (IRQ)
// -----------------------
IntHandler IRQ_Handlers[MAX_NUM_OF_SOURCES];
unsigned int orignal_IRQ_Vector;
#define INT_NOT_USED 0
/*
** void SA_InitIRQ()
**
** DESCRIPTION
** Disable IRQ.
** Initialize IRQ stack and install a IRQ
** interrupt vector.
**
** RETURNS
** None.
*/
void SA_InitIRQ(void)
{
int ii;
unsigned int origIntMask = SAr_DisableInt();
/* Initialize internal vector table */
for (ii = 0; ii < MAX_NUM_OF_SOURCES; ii++)
{
IRQ_Handlers[ii].func = 0;
IRQ_Handlers[ii].data = 0;
}
/* SAr_DisableAllIRQs(); */
/* Save the orignal in case we need to chain interrupt */
orignal_IRQ_Vector = *(unsigned int*)IRQ_VECTOR;
/* install IRQ Interrupt Service Routine */
*(unsigned int*)IRQ_VECTOR = (unsigned int)SAir_IRQTrapWrap;
SAr_EnableInt(origIntMask);
}
/*
** void SA_IRQ_Connect()
**
** DESCRIPTION
** Register ISR for IRQ interrupts.
**
** RETURNS
** success: original interrupt handler;
** error: IntHandler.func == -1.
*/
IntHandler SA_IRQ_Connect( IntSource intSource,
PFVI intServiceRoutine,
int userParam)
{
IntHandler retval;
unsigned int origIntMask = SAr_DisableInt();
if ((intSource >= 0) &&
(intSource < MAX_NUM_OF_SOURCES) &&
!((intSource == REAL_TIME_CLOCK) &&
(*(unsigned int*)RTC_DIV & ~RTC_IRQ_SELECT)))
{
/* Return old interrupt handler */
retval = IRQ_Handlers[intSource];
/* install the new handler */
IRQ_Handlers[intSource].func = intServiceRoutine;
IRQ_Handlers[intSource].data = userParam;
}
else
retval.func = (PFVI)-1;
SAr_EnableInt(origIntMask);
return(retval);
}
/*
** int SA_IRQ_Dispatcher()
**
** DESCRIPTION
** Sort out different IRQ interrupts.
** Read different interrupt sourse status registers
** to determine what interrupt(s) we have and call
** their ISR respectively.
**
** RETURNS
** determine pre-emption task reschedule
** 1: pre-emption; 0: non pre-emption.
*/
int SA_IRQ_Dispatcher(void)
{
int ii;
unsigned int IRQ_Status;
unsigned int PCI_IRQ_Status;
/* To determine if this interrupt would cause task re-scheduling */
taskReSched = 0;
IRQ_Status = *(unsigned int*)(IRQ);
// UART interrupt
//
if (((IRQ_Status == I_UART) && (0 < IXP1200_SysCpuRev)) ||
((IRQ_Status == I_UART_REV_A) && (0 == IXP1200_SysCpuRev))
)
{
if (IRQ_Handlers[SERIAL].func)
(IRQ_Handlers[SERIAL].func)(IRQ_Handlers[SERIAL].data);
#if 0
else
*(unsigned int*)UART_CR |= UART_INT_CLEAR;
#endif
}
// External C pin interrupt (MAC device interrupt)
//
if (IRQ_Status & I_CINT)
{
if (IRQ_Handlers[EXTERNAL_C_PIN].func)
(IRQ_Handlers[EXTERNAL_C_PIN].func)(IRQ_Handlers[EXTERNAL_C_PIN].data);
else
{
// Clear CINT interrupt, if driver is not there.
*(unsigned int*)IREG |= CINT_BIT;
}
}
// Real Time Clock Interrupt
//
if (IRQ_Status & I_RTC)
{
if (IRQ_Handlers[REAL_TIME_CLOCK].func)
(IRQ_Handlers[REAL_TIME_CLOCK].func)(IRQ_Handlers[REAL_TIME_CLOCK].data);
}
// Micro engine/thread interrupt
//
if (IRQ_Status & I_UENG)
{
if (IRQ_Handlers[MICRO_THREAD].func)
(IRQ_Handlers[MICRO_THREAD].func)(IRQ_Handlers[MICRO_THREAD].data);
else
{
// Clear UENG interrupt, if driver is not there.
// All interrupt bits are write 1 to clear.
// All enable bits are write 1 to keep enabled and
// write 0 to keep disabled.
*(unsigned int*)IREG = *(unsigned int*)IREG;
}
}
// SRAM Interrupt
//
if (IRQ_Status & I_SRAM)
{
if (IRQ_Handlers[SRAM_MEMORY].func)
(IRQ_Handlers[SRAM_MEMORY].func)(IRQ_Handlers[SRAM_MEMORY].data);
else
*(unsigned int*)SRAM_CSR &= ~(SRAM_RLRS | SRAM_RLS);
}
// SDRAM Interrupt
//
if (IRQ_Status & I_SDRAM)
{
if (IRQ_Handlers[SDRAM_MEMORY].func)
(IRQ_Handlers[SDRAM_MEMORY].func)(IRQ_Handlers[SDRAM_MEMORY].data);
}
// Interrupts generated by PCI unit
//
if (IRQ_Status & I_PCI)
{
PCI_IRQ_Status = *(unsigned int*)(CSR_BASE + IRQ_STATUS);
if (PCI_IRQ_Status & DOORBELL_INT)
{
if (IRQ_Handlers[PCI_DOORBELL].func)
(IRQ_Handlers[PCI_DOORBELL].func)(IRQ_Handlers[PCI_DOORBELL].data);
}
if (PCI_IRQ_Status & SOFT_INT)
{
if (IRQ_Handlers[SOFT].func)
(IRQ_Handlers[SOFT].func)(IRQ_Handlers[SOFT].data);
else
pciCsrWr((void *)(CSR_BASE + IRQ_SOFT),(unsigned int)0);
}
if (PCI_IRQ_Status & TIMER1_INT)
{
if (IRQ_Handlers[TIMER1].func)
(IRQ_Handlers[TIMER1].func)(IRQ_Handlers[TIMER1].data);
else
*(unsigned int*)(CSR_BASE + TIMER_1_CLEAR) = 0xFFFFFFFF;
}
if (PCI_IRQ_Status & TIMER2_INT)
{
if (IRQ_Handlers[TIMER2].func)
(IRQ_Handlers[TIMER2].func)(IRQ_Handlers[TIMER2].data);
else
*(unsigned int*)(CSR_BASE + TIMER_2_CLEAR) = 0xFFFFFFFF;
}
if (PCI_IRQ_Status & TIMER3_INT)
{
if (IRQ_Handlers[TIMER3].func)
(IRQ_Handlers[TIMER3].func)(IRQ_Handlers[TIMER3].data);
else
*(unsigned int*)(CSR_BASE + TIMER_3_CLEAR) = 0xFFFFFFFF;
}
if (PCI_IRQ_Status & TIMER4_INT)
{
if (IRQ_Handlers[TIMER4].func)
(IRQ_Handlers[TIMER4].func)(IRQ_Handlers[TIMER4].data);
else
*(unsigned int*)(CSR_BASE + TIMER_4_CLEAR) = 0xFFFFFFFF;
}
#if INT_NOT_USED
if (PCI_IRQ_Status & DMA1_INT)
{
if (IRQ_Handlers[DMA1].func)
(IRQ_Handlers[DMA1].func)(IRQ_Handlers[DMA1].data);
}
if (PCI_IRQ_Status & DMA2_INT)
{
if (IRQ_Handlers[DMA2].func)
(IRQ_Handlers[DMA2].func)(IRQ_Handlers[DMA2].data);
}
if (PCI_IRQ_Status & PCI_IRQ_L_INT)
{
if (IRQ_Handlers[PCI_IRQ_L].func)
(IRQ_Handlers[PCI_IRQ_L].func)(IRQ_Handlers[PCI_IRQ_L].data);
}
if (PCI_IRQ_Status & DMA1_NOT_BUSY_INT)
{
if (IRQ_Handlers[DMA1_NOT_BUSY].func)
(IRQ_Handlers[DMA1_NOT_BUSY].func)(IRQ_Handlers[DMA1_NOT_BUSY].data);
}
if (PCI_IRQ_Status & DMA2_NOT_BUSY_INT)
{
if (IRQ_Handlers[DMA2_NOT_BUSY].func)
(IRQ_Handlers[DMA2_NOT_BUSY].func)(IRQ_Handlers[DMA2_NOT_BUSY].data);
}
if (PCI_IRQ_Status & START_BIST_INT)
{
if (IRQ_Handlers[START_BIST].func)
(IRQ_Handlers[START_BIST].func)(IRQ_Handlers[START_BIST].data);
}
if (PCI_IRQ_Status & SERR_INT)
{
if (IRQ_Handlers[SERR].func)
(IRQ_Handlers[SERR].func)(IRQ_Handlers[SERR].data);
}
if (PCI_IRQ_Status & SDRAM_PARITY_INT)
{
if (IRQ_Handlers[SDRAM_PARITY].func)
(IRQ_Handlers[SDRAM_PARITY].func)(IRQ_Handlers[SDRAM_PARITY].data);
}
if (PCI_IRQ_Status & I2O_INPOST_INT)
{
if (IRQ_Handlers[I2O_INPOST].func)
(IRQ_Handlers[I2O_INPOST].func)(IRQ_Handlers[I2O_INPOST].data);
}
if (PCI_IRQ_Status & DISCARD_TIMER_INT)
{
if (IRQ_Handlers[DISCARD_TIMER].func)
(IRQ_Handlers[DISCARD_TIMER].func)(IRQ_Handlers[DISCARD_TIMER].data);
}
if (PCI_IRQ_Status & DATA_PARITY_INT)
{
if (IRQ_Handlers[DATA_PARITY].func)
(IRQ_Handlers[DATA_PARITY].func)(IRQ_Handlers[DATA_PARITY].data);
}
if (PCI_IRQ_Status & PCI_MASTER_ABORT_INT)
{
if (IRQ_Handlers[PCI_MASTER_ABORT].func)
(IRQ_Handlers[PCI_MASTER_ABORT].func)(IRQ_Handlers[PCI_MASTER_ABORT].data);
}
if (PCI_IRQ_Status & PCI_TARGET_ABORT_INT)
{
if (IRQ_Handlers[PCI_TARGET_ABORT].func)
(IRQ_Handlers[PCI_TARGET_ABORT].func)(IRQ_Handlers[PCI_TARGET_ABORT].data);
}
if (PCI_IRQ_Status & PCI_PARITY_INT)
{
if (IRQ_Handlers[PCI_PARITY].func)
(IRQ_Handlers[PCI_PARITY].func)(IRQ_Handlers[PCI_PARITY].data);
}
#endif // #if INT_NOT_USED
}
/* determine pre-emption task reschedule */
/* 1: pre-emption; 0: non pre-emption. */
return(taskReSched);
}
/*
** int SA_IRQ_Enable(IntSource intSource)
** int SA_IRQ_Disable(IntSource intSource)
**
** DESCRIPTION
** Enable/disable a IRQ interrupt.
**
** RETURNS
** success: SA_SUCCESS
** error: SA_FAIL
*/
int SA_IRQ_Enable(IntSource intSource)
{
int retval = SA_SUCCESS;
unsigned int origIntMask = SAr_DisableInt();
switch (intSource)
{
case MICRO_THREAD:
*(unsigned int*)IREG = (*(unsigned int*)IREG | UEIRQ_ENABLE) & 0xF0000000;
break;
case EXTERNAL_C_PIN:
*(unsigned int*)IREG = (*(unsigned int*)IREG | CINTIRQ_ENABLE) & 0xF0000000;
break;
case REAL_TIME_CLOCK:
*(unsigned int*)RTC_DIV |= (RTC_INT_ENABLE | RTC_WRITE_ENABLE);
break;
case SERIAL:
/* There are two interrupts, but we have only one entry here.
* So we don't do enable/disable in this API
*/
retval = SA_FAIL;
break;
case SRAM_MEMORY:
*(unsigned int*)SRAM_CSR =
(*(unsigned int*)SRAM_CSR | SRAM_IRQ) & 0xFFFFFFFC;
break;
case SDRAM_MEMORY:
*(unsigned int*)SDRAM_CSR |= (SDRAM_EN_INT | SDRAM_EN_IRQ);
break;
case PCI_DOORBELL:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)DOORBELL_INT);
break;
case SOFT:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)SOFT_INT);
break;
case TIMER1:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)TIMER1_INT);
break;
case TIMER2:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)TIMER2_INT);
break;
case TIMER3:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)TIMER3_INT);
break;
case TIMER4:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)TIMER4_INT);
break;
case DMA1:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)DMA1_INT);
break;
case DMA2:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)DMA2_INT);
break;
case PCI_IRQ_L:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)PCI_IRQ_L_INT);
break;
case DMA1_NOT_BUSY:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)DMA1_NOT_BUSY_INT);
break;
case DMA2_NOT_BUSY:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)DMA2_NOT_BUSY_INT);
break;
case START_BIST:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)START_BIST_INT);
break;
case SERR:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)SERR_INT);
break;
case SDRAM_PARITY:
pciCsrWr((void *)(CSR_BASE + IRQ_ENABLE_SET),(unsigned int)SDRAM_PARITY_INT);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -