This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

在K2 STK DSP中的SRIO范例,interrupt void SRIO_Doorbell_ISR()是如何被唤醒的?



你好:

本论坛提供的Keystone II STK DSP 中的SRIO范例中使用了函数interrupt void SRIO_Doorbell_ISR()。当DSP接收到Doorbell以后,该function将会被执行,然而在范例中,并没有发现 SRIO_Doorbell_ISR()被提及或使用。

问题:该函数是如何被唤醒的?

谢谢!

于熙宁

相关的代码如下所示:

/*define the message convey by doorbell for this test*/
char * doorbell_msg_str[]=
{
    "doorbell for latency test.", 
    "doorbell which indicates NREAD operation done.",
    "doorbell which indicates NWRITE operation done.",
    "doorbell which indicates NWRITE_R operation done.",  
    "doorbell which indicates SWRITE operation done."
};
interrupt void SRIO_Doorbell_ISR()
{
    Uint32 doorbell;
    uiDoorbell_TSC= TSCL;

    //read doorbell. this test only use doorbell reg 0
    doorbell= gpSRIO_regs->DOORBELL_ICSR_ICCR[0].RIO_DOORBELL_ICSR;

    //clear doorbell interrupt
    gpSRIO_regs->DOORBELL_ICSR_ICCR[0].RIO_DOORBELL_ICCR= doorbell; 

    //printf doorbell message
    if(doorbell&1)
        printf("received %s\n", doorbell_msg_str[0]);
    if(doorbell&2)
        printf("received %s\n", doorbell_msg_str[1]);
    if(doorbell&4)
        printf("received %s\n", doorbell_msg_str[2]);
    if(doorbell&8)
        printf("received %s\n", doorbell_msg_str[3]);
    if(doorbell&16)
        printf("received %s\n", doorbell_msg_str[4]);
        
}

The below is the SRIO Interrupt initialization function used in the same example project. 

main()
{
......
......
SRIO_Interrupts_Init();
KeyStone_SRIO_Interrupt_init(srio_cfg->interrupt_cfg);
......
......
}

/*Word index of the Interrupt Routing Registers*/
typedef enum
{
    DOORBELL0_ICRR1    = (0x00/4),
    DOORBELL0_ICRR2    = (0x04/4),
    DOORBELL1_ICRR1    = (0x0C/4),
    DOORBELL1_ICRR2    = (0x10/4),
    DOORBELL2_ICRR1    = (0x18/4),
    DOORBELL2_ICRR2    = (0x1C/4),
    DOORBELL3_ICRR1    = (0x24/4),
    DOORBELL3_ICRR2    = (0x28/4),
    LSU_SRCID_ICRR1    = (0x30/4),
    LSU_SRCID_ICRR2    = (0x34/4),
    LSU_SRCID_ICRR3    = (0x38/4),
    LSU_SRCID_ICRR4    = (0x3C/4),
    LSU_ICRR1          = (0x40/4),
    ERR_RST_EVNT_ICRR1 = (0x50/4),
    ERR_RST_EVNT_ICRR2 = (0x54/4),
    ERR_RST_EVNT_ICRR3 = (0x58/4)
}SRIO_ICRR_Index;

typedef enum
{
    /* SRIO interrupt source constant, 
    high 16 bits is the ICRR register index, 
    lower 16 bits is the offset of the field in the register*/
    DOORBELL0_0_INT  = ((DOORBELL0_ICRR1 << 16) | 0x0000),
    DOORBELL0_1_INT  = ((DOORBELL0_ICRR1 << 16) | 0x0004),
    DOORBELL0_2_INT  = ((DOORBELL0_ICRR1 << 16) | 0x0008),
    DOORBELL0_3_INT  = ((DOORBELL0_ICRR1 << 16) | 0x000C),
    DOORBELL0_4_INT  = ((DOORBELL0_ICRR1 << 16) | 0x0010),
    DOORBELL0_5_INT  = ((DOORBELL0_ICRR1 << 16) | 0x0014),
    DOORBELL0_6_INT  = ((DOORBELL0_ICRR1 << 16) | 0x0018),
    DOORBELL0_7_INT  = ((DOORBELL0_ICRR1 << 16) | 0x001C),
    DOORBELL0_8_INT  = ((DOORBELL0_ICRR2 << 16) | 0x0000),
    DOORBELL0_9_INT  = ((DOORBELL0_ICRR2 << 16) | 0x0004),
    DOORBELL0_10_INT = ((DOORBELL0_ICRR2 << 16) | 0x0008),
    DOORBELL0_11_INT = ((DOORBELL0_ICRR2 << 16) | 0x000C),
    DOORBELL0_12_INT = ((DOORBELL0_ICRR2 << 16) | 0x0010),
    DOORBELL0_13_INT = ((DOORBELL0_ICRR2 << 16) | 0x0014),
    DOORBELL0_14_INT = ((DOORBELL0_ICRR2 << 16) | 0x0018),
    DOORBELL0_15_INT = ((DOORBELL0_ICRR2 << 16) | 0x001C),  
    .....
}SRIO_Interrupt_Source;

SRIO_Interrupt_Map interrupt_map[]=
{
/*interrupt_event*/ /*INTDST_number*/
{DOORBELL0_0_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_1_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_2_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_3_INT, INTDST_16}, /*route to core 0*/
{DOORBELL0_4_INT, INTDST_16} /*route to core 0*/
};
SRIO_Interrupt_Cfg interrupt_cfg;


void SRIO_Interrupts_Init(void)
{
    /* Disable Global host interrupts. */
    gpCIC0_regs->GLOBAL_ENABLE_HINT_REG= 0;

    uiLow_pri_Q_host_event_num= 18;
    /*map INTD1 low priority queue channel 0 interrupt event to CIC0 out 18*/
    KeyStone_CIC_event_map(gpCIC0_regs, CSL_CIC0_QMSS_INTD_1_LOW_0, uiLow_pri_Q_host_event_num);

    /* Enable Global host interrupts. */
    gpCIC0_regs->GLOBAL_ENABLE_HINT_REG= 1;

    /*map SRIO doorbell interrupts to INT4.
    map message descriptor accumulation low priority channel 0 interrupt 
    to INT5*/
    gpCGEM_regs->INTMUX1 =
        (CSL_C66X_COREPAC_SRIO_INTDST16_PLUS_N<<CSL_CGEM_INTMUX1_INTSEL4_SHIFT)|
        (CSL_C66X_COREPAC_CIC_OUT18<<CSL_CGEM_INTMUX1_INTSEL5_SHIFT);

    //enable INT4, 5
    CPU_interrupt_enable((1<<4)|(1<<5));

    interrupt_cfg.interrupt_map = interrupt_map;
    interrupt_cfg.uiNumInterruptMap = 
        sizeof(interrupt_map)/sizeof(SRIO_Interrupt_Map);

    /*interrupt rate control is not used in this test*/
    interrupt_cfg.interrupt_rate= NULL;
    interrupt_cfg.uiNumInterruptRateCfg= 0;

    interrupt_cfg.doorbell_route_ctl= SRIO_DOORBELL_ROUTE_TO_DEDICATE_INT;

    srio_cfg.interrupt_cfg = &interrupt_cfg;

}

void KeyStone_SRIO_Interrupt_init(
    SRIO_Interrupt_Cfg * interrupt_cfg)
{
    Uint32 i;
    Uint32 reg, shift;
    volatile Uint32 * ICRR= (volatile Uint32 *)gpSRIO_regs->DOORBELL_ICRR;

    if(NULL == interrupt_cfg)
        return;
        
    /* Clear all the interrupts */
    for(i=0; i<2; i++)
    {
        gpSRIO_regs->LSU_ICSR_ICCR[i].RIO_LSU_ICCR   = 0xFFFFFFFF ;  
    }
    for(i=0; i<4; i++)
    {
        gpSRIO_regs->DOORBELL_ICSR_ICCR[i].RIO_DOORBELL_ICCR = 0xFFFFFFFF;        
    }
    gpSRIO_regs->RIO_ERR_RST_EVNT_ICCR = 0xFFFFFFFF;

    if(NULL != interrupt_cfg->interrupt_map)
    {
        for(i=0; i<interrupt_cfg->uiNumInterruptMap; i++)
        {
            /* Get register index for the interrupt source*/
            reg = interrupt_cfg->interrupt_map[i].interrupt_event >> 16;

            /* Get shift value for the interrupt source*/
            shift = interrupt_cfg->interrupt_map[i].interrupt_event & 0x0000FFFF;

            ICRR[reg]= (ICRR[reg]&(~(0xF<<shift)))    /*clear the field*/
                |(interrupt_cfg->interrupt_map[i].INTDST_number<<shift);

        }
    }

    gpSRIO_regs->RIO_INTERRUPT_CTL = interrupt_cfg->doorbell_route_ctl;

    /*disable interrupt rate control*/
    gpSRIO_regs->RIO_INTDST_RATE_DIS= 0xFFFF;
    for(i= 0; i< 16; i++)
    {
        gpSRIO_regs->RIO_INTDST_RATE_CNT[i]= 0;
    }
    
    if(NULL != interrupt_cfg->interrupt_rate)
    {
        /*setup interrupt rate for specific INTDST*/
        for(i= 0; i<interrupt_cfg->uiNumInterruptRateCfg; i++)
        {
            /*enable rate control for this INTDST*/
            gpSRIO_regs->RIO_INTDST_RATE_DIS &= 
                ~(1<<interrupt_cfg->interrupt_rate[i].INTDST_number);

            /*set interrupt rate counter for this INTDST*/
            gpSRIO_regs->RIO_INTDST_RATE_CNT[i]= 
                interrupt_cfg->interrupt_rate[i].interrupt_rate_counter;
        }
    }
    
    return;
}