📄 xsintctrl.c
字号:
// Still a mystery to solve in XsIcInstallInterruptVectors(), although
// it works.
/******************************************************************************
**
** COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: XsIntCtrl.c
**
** PURPOSE: Driver for the Cotulla processor's on-board first level
** Interrupt Controller. Includes initialization, API and
** support functions.
**
**
** Valid for : Cotulla processor
** EAS VERSION : 2.1
**
** $Modtime: 7/17/03 1:01p $
******************************************************************************/
#define _DEFINING_XSINTCTRLAPI
#include "string.h"
#include "systypes.h"
#include "dm_errors.h"
#include "XsCp15.h"
#include "XsIntCtrlApi.h"
#include "XsIntCtrl.h"
#include "platform.h"
#include "cotulla.h"
#include "DM_Debug.h"
/*
*******************************************************************************
*******************************************************************************
API functions
*******************************************************************************
*******************************************************************************
*/
/*
*******************************************************************************
*
* FUNCTION: XsIcSWInit
*
* DESCRIPTION: Init context structure and private tables.
*
* INPUT PARAMETERS: None
*
* RETURNS: None
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: DM only uses IRQ, but owns that
*
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsIcSWInit (void);
*
*******************************************************************************
*/
void XsIcSWInit (void)
{
// Zero IRQ tables and context structure
memset (&XsIcIrqHandlerTable[0], 0, sizeof(XsIcIrqHandlerTable));
memset (&XsIcIrqHandlerParamTable[0], 0, sizeof(XsIcIrqHandlerParamTable));
memset (&XsIntCtrlContext, 0, sizeof(XsIntCtrlContext));
} // End XsIcSWInit()
/*
*******************************************************************************
*
* FUNCTION: XsIcHWSetup
*
* DESCRIPTION: Invoke xsIcInstallInterruptVectors() to give DM control of
* the IRQ interrupts when they occur. (The FIQ is not used
* by the DM, but treated as reserved for debug monitor use.)
* Verify that there is already appropriate code installed
* at the vector address and that no IRQ interrupts are
* enabled (which would indicate that the DM does not "own"
* the IRQ interrupt.
*
* INPUT PARAMETERS: None
*
* RETURNS: Success: 0 (ERR_NONE)
* ERR_T_ALREADY_IN_USE: if any IRQ ints are mask-enabled.
* 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
*
* CALLS: xsIcInstallInterruptVectors()
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsIcHWSetup (void);
*
*******************************************************************************
*/
UINT32 XsIcHWSetup (void)
{
UINT32 status = ERR_NONE;
UINT32 copyOfICLR = XsIntCtrlRegsP->ICLR;
UINT32 copyOfICMR = XsIntCtrlRegsP->ICMR;
XsIntCtrlContext.loggedError = 0;
// If any IRQ level interrupts are enabled, someone else is using them
// and a basic assumption of the DM is violated.
if ((~copyOfICLR) & (copyOfICMR)) // IRQ level if bit clear in ICLR.
{
status = ERR_T_ALREADY_IN_USE;
}
else
{
// IRQ vector seems to be available. Now try to install our handler.
status = XsIcInstallInterruptVectors();
}
if (ERR_NONE == status)
{
XsIntCtrlContext.hwInitSucceeded = TRUE;
// Safe to turn on application interrupts now.
XsIcEnableInterruptsIrq();
IRQ_EnableInterrupts (CPSR_I_Bit|CPSR_F_Bit);
}
else
{
LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC,
ERR_S_XSIC_HWSETUP, status, 0, 0, 0)
}
return (XsIntCtrlContext.loggedError);
} // End XsIcHWSetup ()
/*
*******************************************************************************
*
* FUNCTION: XsIcRegisterHandler
*
* DESCRIPTION: Record, for the specified first level interrupt signal,
* a handler and parameter to be passed to that handler.
* The handler will be invoked with that parameter when
* an IRQ occurs with the specified signal being mask-enabled
* and active.
*
* Typical users: main DMA or GPIO driver, but not users
* of those drivers.
*
* INPUT PARAMETERS: sourceID: Identifier of the first level source signal for
* which the handler is to be registered.
* handler: Interrupt handler for the specified source signal.
* param: Parameter that will be passed to handler.
*
* RETURNS: Success: 0 (ERR_NONE)
* ERR_T_ILLPARAM: sourceID out of range.
* ERR_T_ALREADY_IN_USE: A handler is already registered.
* ERR_T_NOT_AVAIL: This signal is configured as FIQ level,
* which indicates that the debug monitor is using it.
*
* GLOBAL EFFECTS: Logs detected errors.
*
* ASSUMPTIONS: DM only uses IRQ, but owns that
* Not suitable for calling from interrupts
*
* CALLS: XsIcRangeCheckSource()
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsIcRegisterHandler (
* XsIcInterruptSignalsT sourceID,
* XsIcL1IntHandlerFnPT handler,
* void *param);
*
*******************************************************************************
*/
UINT32 XsIcRegisterHandler (XsIcInterruptSignalsT sourceID,
XsIcL1IntHandlerFnPT handler,
void *param)
{
UINT32 status;
XsIntCtrlContext.loggedError = 0;
status = XsIcRangeCheckSource(sourceID);
if (ERR_NONE == status)
{
// Did Angel claim this as an FIQ interrupt?
if (XsIntCtrlRegsP->ICLR & (1u << sourceID))
{
status = ERR_T_NOT_AVAIL; // This src is not available for DM use.
}
// Is an interrupt handler currently registered for this signal?
if (0 != XsIcIrqHandlerTable [sourceID])
{
status = ERR_T_ALREADY_IN_USE;
}
}
// Finished checking conditions
if (ERR_NONE != status)
{
LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC,
ERR_S_XSIC_REG, status, sourceID, 0, 0)
}
else
{
// All conditions OK, do the job.
XsIcIrqHandlerTable [sourceID] = handler;
XsIcIrqHandlerParamTable [sourceID] = param;
}
return(XsIntCtrlContext.loggedError);
} // End XsIcRegisterHandler ()
/*
*******************************************************************************
*
* FUNCTION: XsIcUnRegisterHandler
*
* DESCRIPTION: Disable IRQ interrupts for the specified first level
* interrupt signal. Then clear the registration of any
* handler and parameter for that signal.
*
* Does not affect any other IRQ signal.
*
* INPUT PARAMETERS: sourceID: Identifier of the first level source signal whose
* handler is to be unregistered.
*
* RETURNS: Success: 0 (ERR_NONE)
* ERR_T_ILLPARAM: sourceID out of range.
*
* GLOBAL EFFECTS: Logs detected errors.
*
* ASSUMPTIONS: Not suitable for calling from interrupts
*
* CALLS: XsIcDisableIrqDeviceInt()
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsIcUnRegisterHandler (XsIcInterruptSignalsT sourceID)
*
*******************************************************************************
*/
UINT32 XsIcUnRegisterHandler (XsIcInterruptSignalsT sourceID)
{
UINT32 status;
XsIntCtrlContext.loggedError = 0;
// Range check ID and disable this signal's interrupt
status = XsIcDisableIrqDeviceInt (sourceID);
if (ERR_NONE != status)
{
LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC,
ERR_S_XSIC_UNREG, status, sourceID, 0, 0)
}
else
{
// Range OK and interrupt off, clear table entries.
XsIcIrqHandlerTable [(INT) sourceID] = 0;
XsIcIrqHandlerParamTable [(INT) sourceID] = 0;
}
return(XsIntCtrlContext.loggedError);
} // End XsIcUnRegisterHandler ()
/*
*******************************************************************************
*
* 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: Success: 0 (ERR_NONE)
* ERR_T_ILLPARAM: sourceID out of range.
* ERR_T_NO_HANDLER: No handler is registered for this signal
*
* GLOBAL EFFECTS: Logs detected errors.
*
* ASSUMPTIONS: Not suitable for calling from interrupts
*
* CALLS: XsIcRangeCheckSource()
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsIcEnableIrqDeviceInt (XsIcInterruptSignalsT sourceID);
*
*******************************************************************************
*/
UINT32 XsIcEnableIrqDeviceInt (XsIcInterruptSignalsT sourceID)
{
UINT32 status;
XsIntCtrlContext.loggedError = 0;
status = XsIcRangeCheckSource(sourceID);
if (ERR_NONE == status)
{
if (0 == XsIcIrqHandlerTable [sourceID])
{
status = ERR_T_NO_HANDLER;
}
}
// Finished checking conditions
if (ERR_NONE != status)
{
LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC,
ERR_S_XSIC_EN_IRQ_DEV, status, sourceID, 0, 0)
}
else
{
// All conditions OK. Do the job.
XsIntCtrlRegsP->ICMR |= (1u << sourceID); // Enable int signal
}
return(XsIntCtrlContext.loggedError);
} // End XsIcEnableIrqDeviceInt ()
/*
*******************************************************************************
*
* FUNCTION: XsIcDisableIrqDeviceInt
*
* DESCRIPTION: Disable IRQ interrupts for the specified first level
* interrupt signal. This does not affect the interruptible
* state of other signals.
*
* INPUT PARAMETERS: sourceID: Identifier of the first level source signal for
* which to disable IRQ interrupts.
*
* RETURNS: Success: 0 (ERR_NONE)
* ERR_T_ILLPARAM: sourceID out of range.
*
* GLOBAL EFFECTS: Logs detected errors.
*
* ASSUMPTIONS: May be called from IRQ interrupts. Provides IRQ interrupt
* protection.
*
* CALLS: XsIcRangeCheckSource()
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsIcDisableIrqDeviceInt (XsIcInterruptSignalsT sourceID);
*
*******************************************************************************
*/
UINT32 XsIcDisableIrqDeviceInt (XsIcInterruptSignalsT sourceID)
{
UINT32 status;
UINT32 irqIntState;
XsIntCtrlContext.loggedError = 0;
status = XsIcRangeCheckSource(sourceID);
if (status)
{
LOGERROR (XsIntCtrlContext.loggedError, ERR_L_XSIC,
ERR_S_XSIC_DIS_IRQ_DEV, status, sourceID, 0, 0)
}
else
{
// Provide interrupt protection around critical area to permit use
// in IRQ ISRs.
irqIntState = XsIcDisableInterruptsIrq();
XsIntCtrlRegsP->ICMR &= ~(1u << sourceID); // Disable int signal
XsIcRestoreInterruptsIrq (irqIntState);
}
return(XsIntCtrlContext.loggedError);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -