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

📄 xsintctrl.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 2 页
字号:
    
} // End XsIcDisableIrqDeviceInt() 


/*
*******************************************************************************
*******************************************************************************
    Private functions
*******************************************************************************
*******************************************************************************
*/

/*
*******************************************************************************
*
* FUNCTION:         XsIcInstallInterruptVectors
*
* DESCRIPTION:      Installs DM's direct IRQ interrupt handler.  There is no
*                   support for chaining the IRQ interrrupt.
*
*                   Note: The FIQ handler is not installed because the DM does
*                   not use the FIQ interrupt; however, the code to install it
*                   is present but commented out.  The FIQ section also shows
*                   a method to "chain" a predecessor interrupt handler that
*                   is already installed in the target vector location.
*
* INPUT PARAMETERS: None
*
* RETURNS:          Success: 0 (ERR_NONE)
*                   ERR_T_NO_HANDLER: No appropriate code already located
*                                     at the IRQ vector address.
*
* GLOBAL EFFECTS:   Logs detected errors.
*
* ASSUMPTIONS:      DM only uses IRQ, but owns that.
*                   IRQ interrupts are disabled.
*                   (If the FIQ vector were being modified, FIQ interrupts
*                       would have to be disabled.)
* CALLS:            
*
* CALLED BY:        XsIcHWSetup ()
*
* PROTOTYPE:        UINT32 XsIcInstallInterruptVectors (void)
*
*******************************************************************************
*/

static
UINT32 XsIcInstallInterruptVectors (void)
{
    UINT32 status = ERR_NONE;
    UINT32 physicalAddr;
    UINT32 *vectorP;
    UINT32 *vectorHandlerP;

    UINT32 *vectorHandlerP2;

    XsIntCtrlContext.loggedError = 0;

// Note: the following FIQ-related code segment is present only for example 
//  purposes.  The FIQ is not used by the DM, but is rather treated as reserved
//  for Angel* and other debug monitors; therefore this segment is commented
//  out.
//
//    /*
//    ***************************************************************************
//      First, install new FIQ vector
//      For FIQ, this implementation only worries about chaining Angel and
//       other predecessors that install the LDR PC, #x.
//    **************************************************************************
//    */
//
//    /*
//      Assuming the use of the LDR pc, #x instruction in the vector location 
//      (this is used by Angel and the DM), chain the reference to the existing  
//      handler and install the reference to the DM handler.
//
//      The effect of this instruction, which uses the "Load and Store Word or 
//      Unsigned Byte - Immediate Offset" addressing mode, is as follows:
//        - A code-area word-size data element is created by the assembler to 
//          hold the constant value "x."   Call it "xWord."
//        - The low-order 12 bits of the executable binary assembled from the
//          instruction are an offset from the address of the Program Counter 
//          to the location of xWord (that is, a pointer to a pointer).  
//          Call it "xWordOffset".
//        - The high-order 24 bits of the executable binary assembled from the
//          instruction define the operation that is to be taken relative to 
//          location xWord.  In this case, it is:
//              Load the PC register with the 32 bits found at address (PC +
//              xWordOffset).
//
//      The chaining logic of the DM contains the instruction 
//      "LDR pc, XsIcFiqChain", which provides the address of the pointer used
//      in the loading operation, but is otherwise the same as LDR pc, #x.
//
//      So, the operations performed here will be:
//        - Find the location of xWord.
//            * Derive xWordOffset from the binary found at the target vector 
//              location.  This is done by isolating the low order 8 bits.
//            * Add 8 to xWordOffset.  See the note "Use of R15" that appears
//              in many addressing mode descriptions in the ARM* architecture
//              specification.
//            * Add the address of the target vector location to (xWordOffset+8)
//        - Copy the address found in xWord into XsIcFiqChain
//        - Insert the address of DM's FIQ handler into xWord.
//    /*
//
//    vectorP = (UINT32 *) FIQ_EXCEPTION;
//    
//    /* Verify that the vector location contains an instruction of the form
//        LDR pc, #x (used by Angel) before proceeding.
//     */
//
//    if ((*vectorP & 0xfffff000) == 0xe59ff000)  // Verify instruction at vector
//    {
//        //  Add vector address to xWordOffset plus PC adjustment for addressing
//        //  to get the address containing the predecessor FIQ handler.
//        vectorHandlerP = (UINT32 *) ((*vectorP & 0xfff) + (UINT32) vectorP + 8);
//
//        // Record old handler address in chain pointer.
//        *(UINT32 *) &XsIcFiqChain = *vectorHandlerP;  
//        // Install DM handler for direct execution on FIQ interrupt.
//        *vectorHandlerP = (UINT32) XsIcFiqWrapper;
//    /*
//        Flush data cache for pointer location used by the LDR instructions
//        Instruction cache will be flushed once, later in function.
//    */
//        XsInvalidateDCacheLine (vectorHandlerP);
//        XsCpWait();
//    }
//    else
//    {
//        // Error handling not defined yet
//        status = ERR_T_NO_HANDLER;
//        LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC, ERR_S_XSIC_IIV_FIQ
//                  status, 0, 0, 0)
//        return (status); // Don't normally do multiple returns.
//    }
//

    /*
    ***************************************************************************
    Now, install the DM IRQ handler.

    IRQ for the DM will not be linked to a predecessor.  However, since we
    already have the method and shall assume that there is already a LDR pc, #x
    instruction at the vector location, we'll use a subset of the FIQ approach.
    ***************************************************************************
    */
    
    vectorP = (UINT32 *) IRQ_EXCEPTION;

    if ((*vectorP & 0xfffff000) == 0xe59ff000)  // Verify instruction at vector
    {
        //  Add vector address to xWordOffset plus PC adjustment for addressing
        //  to get the address of the function pointer for the handler.
        vectorHandlerP = (UINT32 *) ((*vectorP & 0xfff) + (UINT32) vectorP + 8);



        XsIntCtrlContext.oldVectorContent = *vectorP;
        XsIntCtrlContext.oldVectorHandlerPointerAddress = 
                                                      (VUINT32)vectorHandlerP;
        XsIntCtrlContext.oldVectorHandlerPointer = *vectorHandlerP;


        XsIntCtrlContext.desiredHandlerAddress = (UINT32) XsIcIrqWrapper;

        // Install DM handler for direct execution on IRQ interrupt.
        *vectorHandlerP = (UINT32) XsIcIrqWrapper;

        XsIntCtrlContext.newVectorContent = (VUINT32) *vectorP;
        XsIntCtrlContext.newVectorHandlerPointerAddress = 
                                                       (VUINT32)vectorHandlerP;
        XsIntCtrlContext.newVectorHandlerPointer = (VUINT32) *vectorHandlerP;

        /*
         Flush the Instruction cache to remove old vectors
         Also flush data cache for pointer location used by the LDR instruction
        */
        XsInvalidateICacheAndBTB ();
        XsInvalidateDCacheLine ((UINT32) vectorHandlerP);
        XsCpWait();

//@@@ Don't know why a write to uncached memory is needed.  Probably need to  
//  improve the forcing procedure just above.

        // And now write through a virtual address with uncached attribute

        (void) VirtualToPhysical (vectorHandlerP, &physicalAddr);
        (void) PhysicalToVirtual (physicalAddr, 0,
                                                   (PVOID*)&vectorHandlerP2);
        *vectorHandlerP2 = (UINT32) XsIcIrqWrapper;

        XsIntCtrlContext.oldVectorContent = 0xDeaddeadL;
        XsIntCtrlContext.oldVectorHandlerPointerAddress = 
                                                      (VUINT32)vectorHandlerP2;
        XsIntCtrlContext.oldVectorHandlerPointer = *vectorHandlerP2;


        XsInvalidateICacheAndBTB ();
        XsInvalidateDCacheLine ((UINT32) vectorHandlerP2);
        XsCpWait();

    }
    else
    {
        status = ERR_T_NO_HANDLER;
        LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC, ERR_S_XSIC_IIV_IRQ,
                  status, 0, 0, 0)
    }



    return (XsIntCtrlContext.loggedError);

} // End xsIcInstallInterruptVectors()



/*
*******************************************************************************
*
* FUNCTION:         XsIcEnableIrqDeviceInt
*
* DESCRIPTION:      Enable IRQ interrupts for the specified first level 
*                   interrupt signal.  This takes effect only while IRQ 
*                   interrupts are globally enabled in the CPSR.
*
* INPUT PARAMETERS: sourceID: Identifier of the first level source signal for
*                               which to enable IRQ interrupts.
*
* RETURNS:  XSIC_ALL_HANDLED: All active and enabled IRQ signals had 
*                             registered handlers
*           XSIC_SOME_UNHANDLED (Theoretical only): 
*                             There was at least one active IRQ signal that
*                             did not have a registered handler.  If IRQ
*                             chaining were supported, this would be used as
*                             an indicator to XsIcIrqWrapper() that the 
*                             predecessor ISR should be invoked.
*
* GLOBAL EFFECTS:   Logs fact of unregistered handler for active signal.
*                   Also, in that case, goes into infinite loop sending an
*                   LED error code.  That sort of bug shouldn't get past
*                   testing, and would prevent any non-interrupt code from
*                   executing.
*
* ASSUMPTIONS:      
*
* CALLS:            PlatformLedsDisplayInterrupt()
*
* CALLED BY:        XsIcIrqWrapper()
*
* PROTOTYPE:        UINT32 XsIcInterruptHandlerCIrq (void) ;
*
*******************************************************************************
*/
/*----------------------------------------------------------------------
 * Local interrupt handler (first level sources only).  Other devices may
 *  need to supply similar capabilities.
 */

UINT32 XsIcInterruptHandlerCIrq (void)  
{
    UINT32 irq_processed = XSIC_ALL_HANDLED;     // Assume chaining not needed
     // Get active, mask-enabled signals from IRQ level sources
    UINT32 activeIrqInterruptSignals = XsIntCtrlRegsP->ICIP;
    UINT32 i;

    // Indicate entry into interrupt handling for system
//    PlatformLedsDisplayInterrupt (1);   // Need manifest constant and real function name here.

    // Only check interrupt signals that are supported in Cotulla
    for (i = XSIC_MIN_SGNL; i <= XSIC_MAX_SGNL; i++)
    {
        if (activeIrqInterruptSignals & (1 << i))
        {
            if (XsIcIrqHandlerTable[i])
                XsIcIrqHandlerTable[i] (XsIcIrqHandlerParamTable[i]);
            else
            {
                // There is an unhandled interrupt.  Baaad.
                // Handle error here via some notice and an 
                //  LCD indication infinite loop.

                LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC, 
                            ERR_S_XSIC_IH_C_IRQ,  ERR_T_NO_HANDLER, i, 0, 0)

                // DM2:  DM_ErrPrintf("Unhandled interrupt %d\n", i);
                // DM2:  DisableInterrupt(i);

//                // If chaining were implemented and there was something to
//                // chain to, we could pass this indicator back to the master
//                // ISR and let the predecessor deal with it instead of
//                // treating it as an error.
//                irq_processed = XSIC_SOME_UNHANDLED;
//                return irq_processed;
            }
        }
    }

    // Indicate exit from interrupt handling for system
//    PlatformLedsDisplayInterrupt (0);   // Need manifest constant and real function name here.

    return irq_processed;

} // End xsIcInterruptHandlerCIrq()


/*
*******************************************************************************
*
* FUNCTION:         XsIcRangeCheckSource
*
* DESCRIPTION:      Range checks the value of its parameter.
*
* INPUT PARAMETERS: sourceID: Identifier of the first level source signal
*                               for checking.
*
* RETURNS:          Success: 0 (ERR_NONE)
*                   ERR_T_ILLPARAM:   sourceID out of range.
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      None
*
* CALLS:            None
*
* CALLED BY:        
*
* PROTOTYPE:        UINT32 XsIcUnRegisterHandler (XsIcInterruptSignalsT sourceID);
*
*******************************************************************************
*/

static
UINT32 XsIcRangeCheckSource (XsIcInterruptSignalsT sourceID)
{  
    UINT32 status = ERR_NONE;
    if ((sourceID < XSIC_MIN_SGNL)|| (sourceID > XSIC_MAX_SGNL))
    {
        status = ERR_T_ILLPARAM;
    }
    return(status);
}    





//----------------- Debug ------------------

void XsIcDbgPrintCurrentState (void)
{
    VUINT32 cpsrTmp;
    UINT32 *vectorP;
    UINT32 *vectorHandlerP;

    if(DM_ControlWordsDebugPrintGetBit(DM_CW_XS_INT_CTRL))
    {
        vectorP = (UINT32 *) IRQ_EXCEPTION;
        vectorHandlerP = (UINT32 *) ((*vectorP & 0xfff) + (UINT32) vectorP + 8);
        cpsrTmp = XsIcGetCpsr();

        DM_CwDbgPrintf (DM_CW_XS_INT_CTRL, 
                 "Some current values of the Main Interrupt Controller\n");

        DM_CwDbgPrintf (DM_CW_XS_INT_CTRL, 
                "   Current Status Word: %X; I-mask: %X; F-mask: %X\n",
                                cpsrTmp, CPSR_I_Bit, CPSR_F_Bit);

        DM_CwDbgPrintf (DM_CW_XS_INT_CTRL, 
                "   IC registers: ICIP  %X; ICMR  %X; ICLR  %X\n",
                                 *((PVUINT*) 0x40D00000),
                                 *((PVUINT*) 0x40D00004),
                                 *((PVUINT*) 0x40D00008));

        DM_CwDbgPrintf (DM_CW_XS_INT_CTRL, 
                "   IC registers: ICFP  %X; ICPR  %X; ICCR  %X\n",
                                 *((PVUINT*) 0x40D0000C),
                                 *((PVUINT*) 0x40D00010),
                                 *((PVUINT*) 0x40D00014));


//        DM_CwDbgPrintf(DM_CW_AC97_CODEC, 
        DM_CwDbgPrintf(DM_CW_XS_INT_CTRL, 
              "   IRQ vector: Function Addr %08X installed at virtual addr %08X\n",
                                *vectorHandlerP,
                                vectorHandlerP);
    }
} // XsIcDbgPrintCurrentState()

 

void XsIcDoVecs (void)
{
    XsIcInstallInterruptVectors();    
}    
 
 
 
 




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -