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

📄 interrupts.c

📁 ucos on sa1200 from ixp1200 EB
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 + -