support zynq7000-zc702
This commit is contained in:
@@ -1,4 +1,16 @@
|
||||
|
||||
SRC_FILES := vector.S trampoline.S $(BOARD)/trap_common.c error_debug.c spinlock.c hard_spinlock.S
|
||||
|
||||
ifeq ($(BOARD), imx6q-sabrelite)
|
||||
SRC_DIR := gicv2
|
||||
SRC_FILES := vector.S trampoline.S trap_common.c error_debug.c spinlock.c hard_spinlock.S
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD), zynq7000-zc702)
|
||||
# SRC_DIR := gicv2
|
||||
SRC_DIR := gicv3
|
||||
SRC_FILES += $(BOARD)/xil_assert.c
|
||||
# SRC_FILES := vector.S trampoline.S imx6q-sabrelite/trap_common.c error_debug.c spinlock.c hard_spinlock.S
|
||||
endif
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,7 @@
|
||||
SRC_FILES := xscugic_g.c \
|
||||
xscugic_hw.c \
|
||||
xscugic_intr.c \
|
||||
xscugic_sinit.c \
|
||||
xscugic.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xil_exception.h
|
||||
*
|
||||
* This header file contains ARM Cortex A9 specific exception related APIs.
|
||||
* For exception related functions that can be used across all Xilinx supported
|
||||
* processors, please use xil_exception.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- -------- -------- -----------------------------------------------
|
||||
* 1.00a ecm/sdm 11/04/09 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIL_EXCEPTION_H /* prevent circular inclusions */
|
||||
#define XIL_EXCEPTION_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xpseudo_asm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/************************** Constant Definitions ****************************/
|
||||
|
||||
#define XIL_EXCEPTION_FIQ XREG_CPSR_FIQ_ENABLE
|
||||
#define XIL_EXCEPTION_IRQ XREG_CPSR_IRQ_ENABLE
|
||||
#define XIL_EXCEPTION_ALL (XREG_CPSR_FIQ_ENABLE | XREG_CPSR_IRQ_ENABLE)
|
||||
|
||||
#define XIL_EXCEPTION_ID_FIRST 0U
|
||||
#define XIL_EXCEPTION_ID_RESET 0U
|
||||
#define XIL_EXCEPTION_ID_UNDEFINED_INT 1U
|
||||
#define XIL_EXCEPTION_ID_SWI_INT 2U
|
||||
#define XIL_EXCEPTION_ID_PREFETCH_ABORT_INT 3U
|
||||
#define XIL_EXCEPTION_ID_DATA_ABORT_INT 4U
|
||||
#define XIL_EXCEPTION_ID_IRQ_INT 5U
|
||||
#define XIL_EXCEPTION_ID_FIQ_INT 6U
|
||||
#define XIL_EXCEPTION_ID_LAST 6U
|
||||
|
||||
/*
|
||||
* XIL_EXCEPTION_ID_INT is defined for all Xilinx processors.
|
||||
*/
|
||||
#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_IRQ_INT
|
||||
|
||||
/**************************** Type Definitions ******************************/
|
||||
|
||||
/**
|
||||
* This typedef is the exception handler function.
|
||||
*/
|
||||
typedef void (*Xil_ExceptionHandler)(void *data);
|
||||
typedef void (*Xil_InterruptHandler)(void *data);
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions ********************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Enable Exceptions.
|
||||
*
|
||||
* @param Mask for exceptions to be enabled.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note If bit is 0, exception is enabled.
|
||||
* C-Style signature: void Xil_ExceptionEnableMask(Mask)
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef __GNUC__
|
||||
#define Xil_ExceptionEnableMask(Mask) \
|
||||
mtcpsr(mfcpsr() & ~ ((Mask) & XIL_EXCEPTION_ALL))
|
||||
#elif defined (__ICCARM__)
|
||||
#define Xil_ExceptionEnableMask(Mask) \
|
||||
mtcpsr(mfcpsr() & ~ ((Mask) & XIL_EXCEPTION_ALL))
|
||||
#else
|
||||
#define Xil_ExceptionEnableMask(Mask) \
|
||||
{ \
|
||||
register u32 Reg __asm("cpsr"); \
|
||||
mtcpsr((Reg) & (~((Mask) & XIL_EXCEPTION_ALL))); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Enable the IRQ exception.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define Xil_ExceptionEnable() \
|
||||
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Disable Exceptions.
|
||||
*
|
||||
* @param Mask for exceptions to be enabled.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note If bit is 1, exception is disabled.
|
||||
* C-Style signature: Xil_ExceptionDisableMask(Mask)
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef __GNUC__
|
||||
#define Xil_ExceptionDisableMask(Mask) \
|
||||
mtcpsr(mfcpsr() | ((Mask) & XIL_EXCEPTION_ALL))
|
||||
#elif defined (__ICCARM__)
|
||||
#define Xil_ExceptionDisableMask(Mask) \
|
||||
mtcpsr(mfcpsr() | (Mask & XIL_EXCEPTION_ALL))
|
||||
#else
|
||||
#define Xil_ExceptionDisableMask(Mask) \
|
||||
{ \
|
||||
register u32 Reg __asm("cpsr"); \
|
||||
mtcpsr((Reg) | ((Mask) & XIL_EXCEPTION_ALL)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Disable the IRQ exception.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define Xil_ExceptionDisable() \
|
||||
Xil_ExceptionDisableMask(XIL_EXCEPTION_IRQ)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Enable nested interrupts by clearing the I and F bits it CPSR
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This macro is supposed to be used from interrupt handlers. In the
|
||||
* interrupt handler the interrupts are disabled by default (I and F
|
||||
* are 1). To allow nesting of interrupts, this macro should be
|
||||
* used. It clears the I and F bits by changing the ARM mode to
|
||||
* system mode. Once these bits are cleared and provided the
|
||||
* preemption of interrupt conditions are met in the GIC, nesting of
|
||||
* interrupts will start happening.
|
||||
* Caution: This macro must be used with caution. Before calling this
|
||||
* macro, the user must ensure that the source of the current IRQ
|
||||
* is appropriately cleared. Otherwise, as soon as we clear the I and
|
||||
* F bits, there can be an infinite loop of interrupts with an
|
||||
* eventual crash (all the stack space getting consumed).
|
||||
******************************************************************************/
|
||||
#define Xil_EnableNestedInterrupts() \
|
||||
__asm__ __volatile__ ("mrs lr, spsr"); \
|
||||
__asm__ __volatile__ ("stmfd sp!, {lr}"); \
|
||||
__asm__ __volatile__ ("msr cpsr_c, #0x1F"); \
|
||||
__asm__ __volatile__ ("stmfd sp!, {lr}");
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Disable the nested interrupts by setting the I and F bits.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This macro is meant to be called in the interrupt service routines.
|
||||
* This macro cannot be used independently. It can only be used when
|
||||
* nesting of interrupts have been enabled by using the macro
|
||||
* Xil_EnableNestedInterrupts(). In a typical flow, the user first
|
||||
* calls the Xil_EnableNestedInterrupts in the ISR at the appropriate
|
||||
* point. The user then must call this macro before exiting the interrupt
|
||||
* service routine. This macro puts the ARM back in IRQ/FIQ mode and
|
||||
* hence sets back the I and F bits.
|
||||
******************************************************************************/
|
||||
#define Xil_DisableNestedInterrupts() \
|
||||
__asm__ __volatile__ ("ldmfd sp!, {lr}"); \
|
||||
__asm__ __volatile__ ("msr cpsr_c, #0x92"); \
|
||||
__asm__ __volatile__ ("ldmfd sp!, {lr}"); \
|
||||
__asm__ __volatile__ ("msr spsr_cxsf, lr");
|
||||
|
||||
/************************** Variable Definitions ****************************/
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
extern void Xil_ExceptionRegisterHandler(u32 Exception_id,
|
||||
Xil_ExceptionHandler Handler,
|
||||
void *Data);
|
||||
|
||||
extern void Xil_ExceptionRemoveHandler(u32 Exception_id);
|
||||
|
||||
extern void Xil_ExceptionInit(void);
|
||||
extern void Xil_DataAbortHandler(void *CallBackRef);
|
||||
extern void Xil_PrefetchAbortHandler(void *CallBackRef);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XIL_EXCEPTION_H */
|
||||
+731
@@ -0,0 +1,731 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xscugic.c
|
||||
* @addtogroup scugic_v3_1
|
||||
* @{
|
||||
*
|
||||
* Contains required functions for the XScuGic driver for the Interrupt
|
||||
* Controller. See xscugic.h for a detailed description of the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- --------------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 1.01a sdm 11/09/11 Changes are made in function XScuGic_CfgInitialize. Since
|
||||
* "Config" entry is now made as pointer in the XScuGic
|
||||
* structure, necessary changes are made.
|
||||
* The HandlerTable can now be populated through the low
|
||||
* level routine XScuGic_RegisterHandler added in this
|
||||
* release. Hence necessary checks are added not to
|
||||
* overwrite the HandlerTable entriesin function
|
||||
* XScuGic_CfgInitialize.
|
||||
* 1.03a srt 02/27/13 Added APIs
|
||||
* - XScuGic_SetPriTrigTypeByDistAddr()
|
||||
* - XScuGic_GetPriTrigTypeByDistAddr()
|
||||
* Removed Offset calculation macros, defined in _hw.h
|
||||
* (CR 702687)
|
||||
* Added support to direct interrupts to the appropriate CPU. Earlier
|
||||
* interrupts were directed to CPU1 (hard coded). Now depending
|
||||
* upon the CPU selected by the user (xparameters.h), interrupts
|
||||
* will be directed to the relevant CPU. This fixes CR 699688.
|
||||
*
|
||||
* 1.04a hk 05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
|
||||
* XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
|
||||
* Moved functions XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
|
||||
* This is fix for CR#705621.
|
||||
* 1.06a asa 16/11/13 Fix for CR#749178. Assignment for EffectiveAddr
|
||||
* in function XScuGic_CfgInitialize is removed as it was
|
||||
* a bug.
|
||||
* 3.00 kvn 02/13/14 Modified code for MISRA-C:2012 compliance.
|
||||
* 3.01 pkp 06/19/15 Added XScuGic_InterruptMaptoCpu API for an interrupt
|
||||
* target CPU mapping
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xil_assert.h"
|
||||
#include "xil_types.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
#include "xscugic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void StubHandler(void* CallBackRef);
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* DistributorInit initializes the distributor of the GIC. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Write the trigger mode, priority and target CPU
|
||||
* - All interrupt sources are disabled
|
||||
* - Enable the distributor
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param CpuID is the Cpu ID to be initialized.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DistributorInit(XScuGic* InstancePtr, u32 CpuID)
|
||||
{
|
||||
u32 Int_Id;
|
||||
u32 LocalCpuID = CpuID;
|
||||
|
||||
#if USE_AMP == 1
|
||||
#warning "Building GIC for AMP"
|
||||
|
||||
/*
|
||||
* The distrubutor should not be initialized by FreeRTOS in the case of
|
||||
* AMP -- it is assumed that Linux is the master of this device in that
|
||||
* case.
|
||||
*/
|
||||
return;
|
||||
#endif
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0U);
|
||||
|
||||
/*
|
||||
* Set the security domains in the int_security registers for
|
||||
* non-secure interrupts
|
||||
* All are secure, so leave at the default. Set to 1 for non-secure
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. The trigger mode in the int_config register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 16U) {
|
||||
/*
|
||||
* Each INT_ID uses two bits, or 16 INT_ID per register
|
||||
* Set them all to be level sensitive, active HIGH.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
|
||||
0U);
|
||||
}
|
||||
|
||||
#define DEFAULT_PRIORITY 0xa0a0a0a0U
|
||||
for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 4U) {
|
||||
/*
|
||||
* 2. The priority using int the priority_level register
|
||||
* The priority_level and spi_target registers use one byte per
|
||||
* INT_ID.
|
||||
* Write a default value that can be changed elsewhere.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
DEFAULT_PRIORITY);
|
||||
}
|
||||
|
||||
for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 4U) {
|
||||
/*
|
||||
* 3. The CPU interface in the spi_target register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
LocalCpuID |= LocalCpuID << 8U;
|
||||
LocalCpuID |= LocalCpuID << 16U;
|
||||
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
|
||||
LocalCpuID);
|
||||
}
|
||||
|
||||
for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 32U) {
|
||||
/*
|
||||
* 4. Enable the SPI using the enable_set register. Leave all
|
||||
* disabled for now.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, Int_Id),
|
||||
0xFFFFFFFFU);
|
||||
}
|
||||
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET,
|
||||
XSCUGIC_EN_INT_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CPUInitialize initializes the CPU Interface of the GIC. The initialization entails:
|
||||
*
|
||||
* - Set the priority of the CPU
|
||||
* - Enable the CPU interface
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void CPUInitialize(XScuGic* InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Program the priority mask of the CPU using the Priority mask register
|
||||
*/
|
||||
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CPU_PRIOR_OFFSET, 0xF0U);
|
||||
|
||||
/*
|
||||
* If the CPU operates in both security domains, set parameters in the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1 to use FIQ for secure interrupts,
|
||||
* 2. Program the AckCtl bit
|
||||
* 3. Program the SBPR bit to select the binary pointer behavior
|
||||
* 4. Set EnableS = 1 to enable secure interrupts
|
||||
* 5. Set EnbleNS = 1 to enable non secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the CPU operates only in the secure domain, setup the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1,
|
||||
* 2. Set EnableS=1, to enable the CPU interface to signal secure interrupts.
|
||||
* Only enable the IRQ output unless secure interrupts are needed.
|
||||
*/
|
||||
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CONTROL_OFFSET, 0x07U);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CfgInitialize a specific interrupt controller instance/driver. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Initialize fields of the XScuGic structure
|
||||
* - Initial vector table with stub function calls
|
||||
* - All interrupt sources are disabled
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param ConfigPtr is a pointer to a config table for the particular
|
||||
* device this driver is associated with.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory
|
||||
* address space. The caller is responsible for keeping the address
|
||||
* mapping from EffectiveAddr to the device physical base address
|
||||
* unchanged once this function is invoked. Unexpected errors may
|
||||
* occur if the address mapping changes after this function is
|
||||
* called. If address translation is not used, use
|
||||
* Config->BaseAddress for this parameters, passing the physical
|
||||
* address instead.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
s32 XScuGic_CfgInitialize(XScuGic* InstancePtr,
|
||||
XScuGic_Config* ConfigPtr,
|
||||
u32 EffectiveAddr)
|
||||
{
|
||||
u32 Int_Id;
|
||||
u32 Cpu_Id = (u32)XPAR_CPU_ID + (u32)1;
|
||||
(void)EffectiveAddr;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(ConfigPtr != NULL);
|
||||
|
||||
if (InstancePtr->IsReady != XIL_COMPONENT_IS_READY) {
|
||||
|
||||
InstancePtr->IsReady = 0;
|
||||
InstancePtr->Config = ConfigPtr;
|
||||
|
||||
for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id++) {
|
||||
/*
|
||||
* Initalize the handler to point to a stub to handle an
|
||||
* interrupt which has not been connected to a handler. Only
|
||||
* initialize it if the handler is 0 which means it was not
|
||||
* initialized statically by the tools/user. Set the callback
|
||||
* reference to this instance so that unhandled interrupts
|
||||
* can be tracked.
|
||||
*/
|
||||
if ((InstancePtr->Config->HandlerTable[Int_Id].Handler == NULL)) {
|
||||
InstancePtr->Config->HandlerTable[Int_Id].Handler = StubHandler;
|
||||
}
|
||||
InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr;
|
||||
}
|
||||
|
||||
DistributorInit(InstancePtr, Cpu_Id);
|
||||
CPUInitialize(InstancePtr);
|
||||
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Makes the connection between the Int_Id of the interrupt source and the
|
||||
* associated handler that is to run when the interrupt is recognized. The
|
||||
* argument provided in this call as the Callbackref is used as the argument
|
||||
* for the handler when it is called.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id contains the ID of the interrupt source and should be
|
||||
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
* @param Handler to the handler for that interrupt.
|
||||
* @param CallBackRef is the callback reference, usually the instance
|
||||
* pointer of the connecting driver.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the handler was connected correctly.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* WARNING: The handler provided as an argument will overwrite any handler
|
||||
* that was previously connected.
|
||||
*
|
||||
****************************************************************************/
|
||||
s32 XScuGic_Connect(XScuGic* InstancePtr, u32 Int_Id,
|
||||
Xil_InterruptHandler Handler, void* CallBackRef)
|
||||
{
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertNonvoid(Handler != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used as an index into the table to select the proper
|
||||
* handler
|
||||
*/
|
||||
InstancePtr->Config->HandlerTable[Int_Id].Handler = Handler;
|
||||
InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Updates the interrupt table with the Null Handler and NULL arguments at the
|
||||
* location pointed at by the Int_Id. This effectively disconnects that interrupt
|
||||
* source from any handler. The interrupt is disabled also.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance to be worked on.
|
||||
* @param Int_Id contains the ID of the interrupt source and should
|
||||
* be in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XScuGic_Disconnect(XScuGic* InstancePtr, u32 Int_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired bit position. Int_Id currently limited to 0 - 31
|
||||
*/
|
||||
Mask = 0x00000001U << (Int_Id % 32U);
|
||||
|
||||
/*
|
||||
* Disable the interrupt such that it won't occur while disconnecting
|
||||
* the handler, only disable the specified interrupt id without modifying
|
||||
* the other interrupt ids
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET + ((Int_Id / 32U) * 4U), Mask);
|
||||
|
||||
/*
|
||||
* Disconnect the handler and connect a stub, the callback reference
|
||||
* must be set to this instance to allow unhandled interrupts to be
|
||||
* tracked
|
||||
*/
|
||||
InstancePtr->Config->HandlerTable[Int_Id].Handler = StubHandler;
|
||||
InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enables the interrupt source provided as the argument Int_Id. Any pending
|
||||
* interrupt condition for the specified Int_Id will occur after this function is
|
||||
* called.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id contains the ID of the interrupt source and should be
|
||||
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XScuGic_Enable(XScuGic* InstancePtr, u32 Int_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired bit position. Int_Id currently limited to 0 - 31
|
||||
*/
|
||||
Mask = 0x00000001U << (Int_Id % 32U);
|
||||
|
||||
/*
|
||||
* Enable the selected interrupt source by setting the
|
||||
* corresponding bit in the Enable Set register.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_ENABLE_SET_OFFSET + ((Int_Id / 32U) * 4U), Mask);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disables the interrupt source provided as the argument Int_Id such that the
|
||||
* interrupt controller will not cause interrupts for the specified Int_Id. The
|
||||
* interrupt controller will continue to hold an interrupt condition for the
|
||||
* Int_Id, but will not cause an interrupt.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id contains the ID of the interrupt source and should be
|
||||
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XScuGic_Disable(XScuGic* InstancePtr, u32 Int_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired bit position. Int_Id currently limited to 0 - 31
|
||||
*/
|
||||
Mask = 0x00000001U << (Int_Id % 32U);
|
||||
|
||||
/*
|
||||
* Disable the selected interrupt source by setting the
|
||||
* corresponding bit in the IDR.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET + ((Int_Id / 32U) * 4U), Mask);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Allows software to simulate an interrupt in the interrupt controller. This
|
||||
* function will only be successful when the interrupt controller has been
|
||||
* started in simulation mode. A simulated interrupt allows the interrupt
|
||||
* controller to be tested without any device to drive an interrupt input
|
||||
* signal into it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id is the software interrupt ID to simulate an interrupt.
|
||||
* @param Cpu_Id is the list of CPUs to send the interrupt.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* XST_SUCCESS if successful, or XST_FAILURE if the interrupt could not be
|
||||
* simulated
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
s32 XScuGic_SoftwareIntr(XScuGic* InstancePtr, u32 Int_Id, u32 Cpu_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(Int_Id <= 15U);
|
||||
Xil_AssertNonvoid(Cpu_Id <= 255U);
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired interrupt. Int_Id currently limited to 0 - 15
|
||||
* Use the target list for the Cpu ID.
|
||||
*/
|
||||
Mask = ((Cpu_Id << 16U) | Int_Id) & (XSCUGIC_SFI_TRIG_CPU_MASK | XSCUGIC_SFI_TRIG_INTID_MASK);
|
||||
|
||||
/*
|
||||
* Write to the Software interrupt trigger register. Use the appropriate
|
||||
* CPU Int_Id.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_SFI_TRIG_OFFSET, Mask);
|
||||
|
||||
/* Indicate the interrupt was successfully simulated */
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* A stub for the asynchronous callback. The stub is here in case the upper
|
||||
* layers forget to set the handler.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void StubHandler(void* CallBackRef)
|
||||
{
|
||||
/*
|
||||
* verify that the inputs are valid
|
||||
*/
|
||||
Xil_AssertVoid(CallBackRef != NULL);
|
||||
|
||||
/*
|
||||
* Indicate another unhandled interrupt for stats
|
||||
*/
|
||||
((XScuGic*)((void*)CallBackRef))->UnhandledInterrupts++;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Sets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is the new priority for the IRQ source. 0 is highest
|
||||
* priority, 0xF8 (248) is lowest. There are 32 priority levels
|
||||
* supported with a step of 8. Hence the supported priorities are
|
||||
* 0, 8, 16, 32, 40 ..., 248.
|
||||
* @param Trigger is the new trigger type for the IRQ source.
|
||||
* Each bit pair describes the configuration for an INT_ID.
|
||||
* SFI Read Only b10 always
|
||||
* PPI Read Only depending on how the PPIs are configured.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive
|
||||
* SPI LSB is read only.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive/
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_SetPriorityTriggerType(XScuGic* InstancePtr, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
u8 LocalPriority;
|
||||
LocalPriority = Priority;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Trigger <= (u8)XSCUGIC_INT_CFG_MASK);
|
||||
Xil_AssertVoid(LocalPriority <= (u8)XSCUGIC_MAX_INTR_PRIO_VAL);
|
||||
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* The priority bits are Bits 7 to 3 in GIC Priority Register. This
|
||||
* means the number of priority levels supported are 32 and they are
|
||||
* in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc.
|
||||
* The lower order 3 bits are masked before putting it in the register.
|
||||
*/
|
||||
LocalPriority = LocalPriority & (u8)XSCUGIC_INTR_PRIO_MASK;
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id % 4U) * 8U));
|
||||
RegValue |= (u32)LocalPriority << ((Int_Id % 4U) * 8U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id % 16U) * 2U));
|
||||
RegValue |= (u32)Trigger << ((Int_Id % 16U) * 2U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Gets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is a pointer to the value of the priority of the IRQ
|
||||
* source. This is a return value.
|
||||
* @param Trigger is pointer to the value of the trigger of the IRQ
|
||||
* source. This is a return value.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_GetPriorityTriggerType(XScuGic* InstancePtr, u32 Int_Id,
|
||||
u8* Priority, u8* Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Priority != NULL);
|
||||
Xil_AssertVoid(Trigger != NULL);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id % 4U) * 8U);
|
||||
*Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id % 16U) * 2U);
|
||||
|
||||
*Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Sets the target CPU for the interrupt of a peripheral
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Cpu_Id is a CPU number for which the interrupt has to be targeted
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_InterruptMaptoCpu(XScuGic* InstancePtr, u8 Cpu_Id, u32 Int_Id)
|
||||
{
|
||||
u32 RegValue, Offset;
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id));
|
||||
|
||||
Offset = (Int_Id & 0x3);
|
||||
|
||||
RegValue = (RegValue | (~(0xFF << (Offset * 8))));
|
||||
RegValue |= ((Cpu_Id) << (Offset * 8));
|
||||
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
}
|
||||
/** @} */
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xscugic.h
|
||||
* @addtogroup scugic_v3_1
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* The generic interrupt controller driver component.
|
||||
*
|
||||
* The interrupt controller driver uses the idea of priority for the various
|
||||
* handlers. Priority is an integer within the range of 1 and 31 inclusive with
|
||||
* default of 1 being the highest priority interrupt source. The priorities
|
||||
* of the various sources can be dynamically altered as needed through
|
||||
* hardware configuration.
|
||||
*
|
||||
* The generic interrupt controller supports the following
|
||||
* features:
|
||||
*
|
||||
* - specific individual interrupt enabling/disabling
|
||||
* - specific individual interrupt acknowledging
|
||||
* - attaching specific callback function to handle interrupt source
|
||||
* - assigning desired priority to interrupt source if default is not
|
||||
* acceptable.
|
||||
*
|
||||
* Details about connecting the interrupt handler of the driver are contained
|
||||
* in the source file specific to interrupt processing, xscugic_intr.c.
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works with
|
||||
* physical addresses only. Any needs for dynamic memory management, threads
|
||||
* or thread mutual exclusion, virtual memory, or cache control must be
|
||||
* satisfied by the layer above this driver.
|
||||
*
|
||||
* <b>Interrupt Vector Tables</b>
|
||||
*
|
||||
* The device ID of the interrupt controller device is used by the driver as a
|
||||
* direct index into the configuration data table. The user should populate the
|
||||
* vector table with handlers and callbacks at run-time using the
|
||||
* XScuGic_Connect() and XScuGic_Disconnect() functions.
|
||||
*
|
||||
* Each vector table entry corresponds to a device that can generate an
|
||||
* interrupt. Each entry contains an interrupt handler function and an
|
||||
* argument to be passed to the handler when an interrupt occurs. The
|
||||
* user must use XScuGic_Connect() when the interrupt handler takes an
|
||||
* argument other than the base address.
|
||||
*
|
||||
* <b>Nested Interrupts Processing</b>
|
||||
*
|
||||
* Nested interrupts are not supported by this driver.
|
||||
*
|
||||
* NOTE:
|
||||
* The generic interrupt controller is not a part of the snoop control unit
|
||||
* as indicated by the prefix "scu" in the name of the driver.
|
||||
* It is an independent module in APU.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00a drg 01/19/00 First release
|
||||
* 1.01a sdm 11/09/11 The XScuGic and XScuGic_Config structures have changed.
|
||||
* The HandlerTable (of type XScuGic_VectorTableEntry) is
|
||||
* moved to XScuGic_Config structure from XScuGic structure.
|
||||
*
|
||||
* The "Config" entry in XScuGic structure is made as
|
||||
* pointer for better efficiency.
|
||||
*
|
||||
* A new file named as xscugic_hw.c is now added. It is
|
||||
* to implement low level driver routines without using
|
||||
* any xscugic instance pointer. They are useful when the
|
||||
* user wants to use xscugic through device id or
|
||||
* base address. The driver routines provided are explained
|
||||
* below.
|
||||
* XScuGic_DeviceInitialize that takes device id as
|
||||
* argument and initializes the device (without calling
|
||||
* XScuGic_CfgInitialize).
|
||||
* XScuGic_DeviceInterruptHandler that takes device id
|
||||
* as argument and calls appropriate handlers from the
|
||||
* HandlerTable.
|
||||
* XScuGic_RegisterHandler that registers a new handler
|
||||
* by taking xscugic hardware base address as argument.
|
||||
* LookupConfigByBaseAddress is used to return the
|
||||
* corresponding config structure from XScuGic_ConfigTable
|
||||
* based on the scugic base address passed.
|
||||
* 1.02a sdm 12/20/11 Removed AckBeforeService from the XScuGic_Config
|
||||
* structure.
|
||||
* 1.03a srt 02/27/13 Moved Offset calculation macros from *.c and *_hw.c to
|
||||
* *_hw.h
|
||||
* Added APIs
|
||||
* - XScuGic_SetPriTrigTypeByDistAddr()
|
||||
* - XScuGic_GetPriTrigTypeByDistAddr()
|
||||
* (CR 702687)
|
||||
* Added support to direct interrupts to the appropriate CPU. Earlier
|
||||
* interrupts were directed to CPU1 (hard coded). Now depending
|
||||
* upon the CPU selected by the user (xparameters.h), interrupts
|
||||
* will be directed to the relevant CPU. This fixes CR 699688.
|
||||
* 1.04a hk 05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
|
||||
* XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
|
||||
* Moved functions XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
|
||||
* This is fix for CR#705621.
|
||||
* 1.05a hk 06/26/13 Modified tcl to export external interrupts correctly to
|
||||
* xparameters.h. Fix for CR's 690505, 708928 & 719359.
|
||||
* 2.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
* 2.1 adk 25/04/14 Fixed the CR:789373 changes are made in the driver tcl file.
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XSCUGIC_H /* prevent circular inclusions */
|
||||
#define XSCUGIC_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_exception.h"
|
||||
#include "xil_io.h"
|
||||
#include "xscugic_hw.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/* The following data type defines each entry in an interrupt vector table.
|
||||
* The callback reference is the base address of the interrupting device
|
||||
* for the low level driver and an instance pointer for the high level driver.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Xil_InterruptHandler Handler;
|
||||
void* CallBackRef;
|
||||
} XScuGic_VectorTableEntry;
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
u32 CpuBaseAddress; /**< CPU Interface Register base address */
|
||||
u32 DistBaseAddress; /**< Distributor Register base address */
|
||||
XScuGic_VectorTableEntry HandlerTable[XSCUGIC_MAX_NUM_INTR_INPUTS]; /**<
|
||||
Vector table of interrupt handlers */
|
||||
} XScuGic_Config;
|
||||
|
||||
/**
|
||||
* The XScuGic driver instance data. The user is required to allocate a
|
||||
* variable of this type for every intc device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
XScuGic_Config* Config; /**< Configuration table entry */
|
||||
u32 IsReady; /**< Device is initialized and ready */
|
||||
u32 UnhandledInterrupts; /**< Intc Statistics */
|
||||
} XScuGic;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given CPU Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XScuGic_CPUWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_CPUWriteReg(InstancePtr, RegOffset, Data) \
|
||||
(XScuGic_WriteReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset), \
|
||||
((u32)(Data))))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given CPU Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XScuGic_CPUReadReg(XScuGic *InstancePtr, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_CPUReadReg(InstancePtr, RegOffset) \
|
||||
(XScuGic_ReadReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset)))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given Distributor Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_DistWriteReg(InstancePtr, RegOffset, Data) \
|
||||
(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset), \
|
||||
((u32)(Data))))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given Distributor Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_DistReadReg(InstancePtr, RegOffset) \
|
||||
(XScuGic_ReadReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset)))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Required functions in xscugic.c
|
||||
*/
|
||||
|
||||
s32 XScuGic_Connect(XScuGic* InstancePtr, u32 Int_Id,
|
||||
Xil_InterruptHandler Handler, void* CallBackRef);
|
||||
void XScuGic_Disconnect(XScuGic* InstancePtr, u32 Int_Id);
|
||||
|
||||
void XScuGic_Enable(XScuGic* InstancePtr, u32 Int_Id);
|
||||
void XScuGic_Disable(XScuGic* InstancePtr, u32 Int_Id);
|
||||
|
||||
s32 XScuGic_CfgInitialize(XScuGic* InstancePtr, XScuGic_Config* ConfigPtr,
|
||||
u32 EffectiveAddr);
|
||||
|
||||
s32 XScuGic_SoftwareIntr(XScuGic* InstancePtr, u32 Int_Id, u32 Cpu_Id);
|
||||
|
||||
void XScuGic_GetPriorityTriggerType(XScuGic* InstancePtr, u32 Int_Id,
|
||||
u8* Priority, u8* Trigger);
|
||||
void XScuGic_SetPriorityTriggerType(XScuGic* InstancePtr, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger);
|
||||
void XScuGic_InterruptMaptoCpu(XScuGic* InstancePtr, u8 Cpu_Id, u32 Int_Id);
|
||||
/*
|
||||
* Initialization functions in xscugic_sinit.c
|
||||
*/
|
||||
XScuGic_Config* XScuGic_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Interrupt functions in xscugic_intr.c
|
||||
*/
|
||||
void XScuGic_InterruptHandler(XScuGic* InstancePtr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by HSI.
|
||||
* Version:
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Copyright (C) 2010-2024 Xilinx, Inc. All Rights Reserved.*
|
||||
*Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
*of this software and associated documentation files (the Software), to deal
|
||||
*in the Software without restriction, including without limitation the rights
|
||||
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
*copies of the Software, and to permit persons to whom the Software is
|
||||
*furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*The above copyright notice and this permission notice shall be included in
|
||||
*all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
*(a) running on a Xilinx device, or
|
||||
*(b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
*in advertising or otherwise to promote the sale, use or other dealings in
|
||||
*this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
|
||||
#include "mmio_access.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XScuGic_Config XScuGic_ConfigTable[] = {
|
||||
{ XPAR_PS7_SCUGIC_0_DEVICE_ID,
|
||||
MMIO_P2V_WO(XPAR_PS7_SCUGIC_0_BASEADDR),
|
||||
MMIO_P2V_WO(XPAR_PS7_SCUGIC_0_DIST_BASEADDR) }
|
||||
};
|
||||
+563
@@ -0,0 +1,563 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xscugic_hw.c
|
||||
* @addtogroup scugic_v3_1
|
||||
* @{
|
||||
*
|
||||
* This file contains low-level driver functions that can be used to access the
|
||||
* device. The user should refer to the hardware device specification for more
|
||||
* details of the device operation.
|
||||
* These routines are used when the user does not want to create an instance of
|
||||
* XScuGic structure but still wants to use the ScuGic device. Hence the
|
||||
* routines provided here take device id or scugic base address as arguments.
|
||||
* Separate static versions of DistInit and CPUInit are provided to implement
|
||||
* the low level driver routines.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.01a sdm 07/18/11 First release
|
||||
* 1.03a srt 02/27/13 Moved Offset calculation macros from *_hw.c (CR
|
||||
* 702687).
|
||||
* Added support to direct interrupts to the appropriate CPU.
|
||||
* Earlier interrupts were directed to CPU1 (hard coded). Now
|
||||
* depending upon the CPU selected by the user (xparameters.h),
|
||||
* interrupts will be directed to the relevant CPU.
|
||||
* This fixes CR 699688.
|
||||
* 1.04a hk 05/04/13 Fix for CR#705621. Moved functions
|
||||
* XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr here from xscugic.c
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_assert.h"
|
||||
#include "xil_types.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void DistInit(XScuGic_Config* Config, u32 CpuID);
|
||||
static void CPUInit(XScuGic_Config* Config);
|
||||
static XScuGic_Config* LookupConfigByBaseAddress(u32 CpuBaseAddress);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern XScuGic_Config XScuGic_ConfigTable[XPAR_XSCUGIC_NUM_INSTANCES];
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* DistInit initializes the distributor of the GIC. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Write the trigger mode, priority and target CPU
|
||||
* - All interrupt sources are disabled
|
||||
* - Enable the distributor
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param CpuID is the Cpu ID to be initialized.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DistInit(XScuGic_Config* Config, u32 CpuID)
|
||||
{
|
||||
u32 Int_Id;
|
||||
u32 LocalCpuID = CpuID;
|
||||
|
||||
#if USE_AMP == 1
|
||||
#warning "Building GIC for AMP"
|
||||
|
||||
/*
|
||||
* The distrubutor should not be initialized by FreeRTOS in the case of
|
||||
* AMP -- it is assumed that Linux is the master of this device in that
|
||||
* case.
|
||||
*/
|
||||
return;
|
||||
#endif
|
||||
|
||||
XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET, 0U);
|
||||
|
||||
/*
|
||||
* Set the security domains in the int_security registers for non-secure
|
||||
* interrupts. All are secure, so leave at the default. Set to 1 for
|
||||
* non-secure interrupts.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. The trigger mode in the int_config register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 16U) {
|
||||
/*
|
||||
* Each INT_ID uses two bits, or 16 INT_ID per register
|
||||
* Set them all to be level sensitive, active HIGH.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), 0U);
|
||||
}
|
||||
|
||||
#define DEFAULT_PRIORITY 0xa0a0a0a0U
|
||||
for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 4U) {
|
||||
/*
|
||||
* 2. The priority using int the priority_level register
|
||||
* The priority_level and spi_target registers use one byte per
|
||||
* INT_ID.
|
||||
* Write a default value that can be changed elsewhere.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
DEFAULT_PRIORITY);
|
||||
}
|
||||
|
||||
for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 4U) {
|
||||
/*
|
||||
* 3. The CPU interface in the spi_target register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
LocalCpuID |= LocalCpuID << 8U;
|
||||
LocalCpuID |= LocalCpuID << 16U;
|
||||
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), LocalCpuID);
|
||||
}
|
||||
|
||||
for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id = Int_Id + 32U) {
|
||||
/*
|
||||
* 4. Enable the SPI using the enable_set register. Leave all disabled
|
||||
* for now.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET,
|
||||
Int_Id),
|
||||
0xFFFFFFFFU);
|
||||
}
|
||||
|
||||
XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET,
|
||||
XSCUGIC_EN_INT_MASK);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CPUInit initializes the CPU Interface of the GIC. The initialization entails:
|
||||
*
|
||||
* - Set the priority of the CPU.
|
||||
* - Enable the CPU interface
|
||||
*
|
||||
* @param ConfigPtr is a pointer to a config table for the particular
|
||||
* device this driver is associated with.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void CPUInit(XScuGic_Config* Config)
|
||||
{
|
||||
/*
|
||||
* Program the priority mask of the CPU using the Priority mask
|
||||
* register
|
||||
*/
|
||||
XScuGic_WriteReg(Config->CpuBaseAddress, XSCUGIC_CPU_PRIOR_OFFSET,
|
||||
0xF0U);
|
||||
|
||||
/*
|
||||
* If the CPU operates in both security domains, set parameters in the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1 to use FIQ for secure interrupts,
|
||||
* 2. Program the AckCtl bit
|
||||
* 3. Program the SBPR bit to select the binary pointer behavior
|
||||
* 4. Set EnableS = 1 to enable secure interrupts
|
||||
* 5. Set EnbleNS = 1 to enable non secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the CPU operates only in the secure domain, setup the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1,
|
||||
* 2. Set EnableS=1, to enable the CPU interface to signal secure .
|
||||
* interrupts Only enable the IRQ output unless secure interrupts
|
||||
* are needed.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->CpuBaseAddress, XSCUGIC_CONTROL_OFFSET, 0x07U);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CfgInitialize a specific interrupt controller instance/driver. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Initialize fields of the XScuGic structure
|
||||
* - Initial vector table with stub function calls
|
||||
* - All interrupt sources are disabled
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance to be worked on.
|
||||
* @param ConfigPtr is a pointer to a config table for the particular device
|
||||
* this driver is associated with.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory address
|
||||
* space. The caller is responsible for keeping the address mapping
|
||||
* from EffectiveAddr to the device physical base address unchanged
|
||||
* once this function is invoked. Unexpected errors may occur if the
|
||||
* address mapping changes after this function is called. If address
|
||||
* translation is not used, use Config->BaseAddress for this parameters,
|
||||
* passing the physical address instead.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
s32 XScuGic_DeviceInitialize(u32 DeviceId)
|
||||
{
|
||||
XScuGic_Config* Config;
|
||||
u32 Cpu_Id = (u32)XPAR_CPU_ID + (u32)1;
|
||||
|
||||
Config = &XScuGic_ConfigTable[(u32)DeviceId];
|
||||
|
||||
DistInit(Config, Cpu_Id);
|
||||
|
||||
CPUInit(Config);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function is the primary interrupt handler for the driver. It must be
|
||||
* connected to the interrupt source such that it is called when an interrupt of
|
||||
* the interrupt controller is active. It will resolve which interrupts are
|
||||
* active and enabled and call the appropriate interrupt handler. It uses
|
||||
* the Interrupt Type information to determine when to acknowledge the
|
||||
* interrupt.Highest priority interrupts are serviced first.
|
||||
*
|
||||
* This function assumes that an interrupt vector table has been previously
|
||||
* initialized. It does not verify that entries in the table are valid before
|
||||
* calling an interrupt handler.
|
||||
*
|
||||
* @param DeviceId is the unique identifier for the ScuGic device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XScuGic_DeviceInterruptHandler(void* DeviceId)
|
||||
{
|
||||
|
||||
u32 InterruptID;
|
||||
u32 IntIDFull;
|
||||
XScuGic_VectorTableEntry* TablePtr;
|
||||
XScuGic_Config* CfgPtr;
|
||||
|
||||
CfgPtr = &XScuGic_ConfigTable[(INTPTR)DeviceId];
|
||||
|
||||
/*
|
||||
* Read the int_ack register to identify the highest priority
|
||||
* interrupt ID and make sure it is valid. Reading Int_Ack will
|
||||
* clear the interrupt in the GIC.
|
||||
*/
|
||||
IntIDFull = XScuGic_ReadReg(CfgPtr->CpuBaseAddress, XSCUGIC_INT_ACK_OFFSET);
|
||||
InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK;
|
||||
if (XSCUGIC_MAX_NUM_INTR_INPUTS < InterruptID) {
|
||||
goto IntrExit;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interrupt is shared, do some locking here if there are
|
||||
* multiple processors.
|
||||
*/
|
||||
/*
|
||||
* If pre-eption is required:
|
||||
* Re-enable pre-emption by setting the CPSR I bit for non-secure ,
|
||||
* interrupts or the F bit for secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If we need to change security domains, issue a SMC instruction here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Execute the ISR. Jump into the Interrupt service routine based on
|
||||
* the IRQSource. A software trigger is cleared by the ACK.
|
||||
*/
|
||||
TablePtr = &(CfgPtr->HandlerTable[InterruptID]);
|
||||
if (TablePtr != NULL) {
|
||||
TablePtr->Handler(TablePtr->CallBackRef);
|
||||
}
|
||||
|
||||
IntrExit:
|
||||
/*
|
||||
* Write to the EOI register, we are all done here.
|
||||
* Let this function return, the boot code will restore the stack.
|
||||
*/
|
||||
XScuGic_WriteReg(CfgPtr->CpuBaseAddress, XSCUGIC_EOI_OFFSET, IntIDFull);
|
||||
|
||||
/*
|
||||
* Return from the interrupt. Change security domains could happen
|
||||
* here.
|
||||
*/
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Register a handler function for a specific interrupt ID. The vector table
|
||||
* of the interrupt controller is updated, overwriting any previous handler.
|
||||
* The handler function will be called when an interrupt occurs for the given
|
||||
* interrupt ID.
|
||||
*
|
||||
* @param BaseAddress is the CPU Interface Register base address of the
|
||||
* interrupt controller whose vector table will be modified.
|
||||
* @param InterruptId is the interrupt ID to be associated with the input
|
||||
* handler.
|
||||
* @param Handler is the function pointer that will be added to
|
||||
* the vector table for the given interrupt ID.
|
||||
* @param CallBackRef is the argument that will be passed to the new
|
||||
* handler function when it is called. This is user-specific.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Note that this function has no effect if the input base address is invalid.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XScuGic_RegisterHandler(u32 BaseAddress, s32 InterruptID,
|
||||
Xil_InterruptHandler IntrHandler, void* CallBackRef)
|
||||
{
|
||||
XScuGic_Config* CfgPtr;
|
||||
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
|
||||
|
||||
if (CfgPtr != NULL) {
|
||||
if (IntrHandler != NULL) {
|
||||
CfgPtr->HandlerTable[InterruptID].Handler = IntrHandler;
|
||||
}
|
||||
if (CallBackRef != NULL) {
|
||||
CfgPtr->HandlerTable[InterruptID].CallBackRef = CallBackRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the CPU interface base address of
|
||||
* the device. A table contains the configuration info for each device in the
|
||||
* system.
|
||||
*
|
||||
* @param CpuBaseAddress is the CPU Interface Register base address.
|
||||
*
|
||||
* @return A pointer to the configuration structure for the specified
|
||||
* device, or NULL if the device was not found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static XScuGic_Config* LookupConfigByBaseAddress(u32 CpuBaseAddress)
|
||||
{
|
||||
XScuGic_Config* CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index = 0U; Index < XPAR_SCUGIC_NUM_INSTANCES; Index++) {
|
||||
if (XScuGic_ConfigTable[Index].CpuBaseAddress == CpuBaseAddress) {
|
||||
CfgPtr = &XScuGic_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (XScuGic_Config*)CfgPtr;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Sets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param BaseAddr is the device base address
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is the new priority for the IRQ source. 0 is highest
|
||||
* priority, 0xF8 (248) is lowest. There are 32 priority levels
|
||||
* supported with a step of 8. Hence the supported priorities are
|
||||
* 0, 8, 16, 32, 40 ..., 248.
|
||||
* @param Trigger is the new trigger type for the IRQ source.
|
||||
* Each bit pair describes the configuration for an INT_ID.
|
||||
* SFI Read Only b10 always
|
||||
* PPI Read Only depending on how the PPIs are configured.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive
|
||||
* SPI LSB is read only.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive/
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This API has the similar functionality of XScuGic_SetPriority
|
||||
* TriggerType() and should be used when there is no InstancePtr.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_SetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
u8 LocalPriority = Priority;
|
||||
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Trigger <= XSCUGIC_INT_CFG_MASK);
|
||||
Xil_AssertVoid(LocalPriority <= XSCUGIC_MAX_INTR_PRIO_VAL);
|
||||
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* The priority bits are Bits 7 to 3 in GIC Priority Register. This
|
||||
* means the number of priority levels supported are 32 and they are
|
||||
* in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc.
|
||||
* The lower order 3 bits are masked before putting it in the register.
|
||||
*/
|
||||
LocalPriority = LocalPriority & XSCUGIC_INTR_PRIO_MASK;
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id % 4U) * 8U));
|
||||
RegValue |= (u32)LocalPriority << ((Int_Id % 4U) * 8U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_WriteReg(DistBaseAddress, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id % 16U) * 2U));
|
||||
RegValue |= (u32)Trigger << ((Int_Id % 16U) * 2U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_WriteReg(DistBaseAddress, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Gets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param BaseAddr is the device base address
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is a pointer to the value of the priority of the IRQ
|
||||
* source. This is a return value.
|
||||
* @param Trigger is pointer to the value of the trigger of the IRQ
|
||||
* source. This is a return value.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This API has the similar functionality of XScuGic_GetPriority
|
||||
* TriggerType() and should be used when there is no InstancePtr.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_GetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8* Priority, u8* Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Priority != NULL);
|
||||
Xil_AssertVoid(Trigger != NULL);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id % 4U) * 8U);
|
||||
*Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id % 16U) * 2U);
|
||||
|
||||
*Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK);
|
||||
}
|
||||
/** @} */
|
||||
+635
@@ -0,0 +1,635 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xscugic_hw.h
|
||||
* @addtogroup scugic_v3_1
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and HW access functions (or
|
||||
* macros) that can be used to access the device. The user should refer to the
|
||||
* hardware device specification for more details of the device operation.
|
||||
* The driver functions/APIs are defined in xscugic.h.
|
||||
*
|
||||
* This GIC device has two parts, a distributor and CPU interface(s). Each part
|
||||
* has separate register definition sections.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 1.01a sdm 11/09/11 "xil_exception.h" added as include.
|
||||
* Macros XScuGic_EnableIntr and XScuGic_DisableIntr are
|
||||
* added to enable or disable interrupts based on
|
||||
* Distributor Register base address. Normally users use
|
||||
* XScuGic instance and call XScuGic_Enable or
|
||||
* XScuGic_Disable to enable/disable interrupts. These
|
||||
* new macros are provided when user does not want to
|
||||
* use an instance pointer but still wants to enable or
|
||||
* disable interrupts.
|
||||
* Function prototypes for functions (present in newly
|
||||
* added file xscugic_hw.c) are added.
|
||||
* 1.03a srt 02/27/13 Moved Offset calculation macros from *_hw.c (CR
|
||||
* 702687).
|
||||
* 1.04a hk 05/04/13 Fix for CR#705621. Moved function prototypes
|
||||
* XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr here from xscugic.h
|
||||
* 3.0 pkp 12/09/14 changed XSCUGIC_MAX_NUM_INTR_INPUTS for
|
||||
* Zynq Ultrascale Mp
|
||||
* 3.0 kvn 02/13/14 Modified code for MISRA-C:2012 compliance.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XSCUGIC_HW_H /* prevent circular inclusions */
|
||||
#define XSCUGIC_HW_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_exception.h"
|
||||
#include "xil_io.h"
|
||||
#include "xil_types.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The maximum number of interrupts supported by the hardware.
|
||||
*/
|
||||
#ifdef __ARM_NEON__
|
||||
#define XSCUGIC_MAX_NUM_INTR_INPUTS 95U /* Maximum number of interrupt defined by Zynq */
|
||||
#else
|
||||
#define XSCUGIC_MAX_NUM_INTR_INPUTS 195U /* Maximum number of interrupt defined by Zynq Ultrascale Mp */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The maximum priority value that can be used in the GIC.
|
||||
*/
|
||||
#define XSCUGIC_MAX_INTR_PRIO_VAL 248U
|
||||
#define XSCUGIC_INTR_PRIO_MASK 0x000000F8U
|
||||
|
||||
/** @name Distributor Interface Register Map
|
||||
*
|
||||
* Define the offsets from the base address for all Distributor registers of
|
||||
* the interrupt controller, some registers may be reserved in the hardware
|
||||
* device.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_DIST_EN_OFFSET 0x00000000U /**< Distributor Enable \
|
||||
Register */
|
||||
#define XSCUGIC_IC_TYPE_OFFSET 0x00000004U /**< Interrupt Controller \
|
||||
Type Register */
|
||||
#define XSCUGIC_DIST_IDENT_OFFSET 0x00000008U /**< Implementor ID \
|
||||
Register */
|
||||
#define XSCUGIC_SECURITY_OFFSET 0x00000080U /**< Interrupt Security \
|
||||
Register */
|
||||
#define XSCUGIC_ENABLE_SET_OFFSET 0x00000100U /**< Enable Set \
|
||||
Register */
|
||||
#define XSCUGIC_DISABLE_OFFSET 0x00000180U /**< Enable Clear Register */
|
||||
#define XSCUGIC_PENDING_SET_OFFSET 0x00000200U /**< Pending Set \
|
||||
Register */
|
||||
#define XSCUGIC_PENDING_CLR_OFFSET 0x00000280U /**< Pending Clear \
|
||||
Register */
|
||||
#define XSCUGIC_ACTIVE_OFFSET 0x00000300U /**< Active Status Register */
|
||||
#define XSCUGIC_PRIORITY_OFFSET 0x00000400U /**< Priority Level Register */
|
||||
#define XSCUGIC_SPI_TARGET_OFFSET 0x00000800U /**< SPI Target \
|
||||
Register 0x800-0x8FB */
|
||||
#define XSCUGIC_INT_CFG_OFFSET 0x00000C00U /**< Interrupt Configuration \
|
||||
Register 0xC00-0xCFC */
|
||||
#define XSCUGIC_PPI_STAT_OFFSET 0x00000D00U /**< PPI Status Register */
|
||||
#define XSCUGIC_SPI_STAT_OFFSET 0x00000D04U /**< SPI Status Register \
|
||||
0xd04-0xd7C */
|
||||
#define XSCUGIC_AHB_CONFIG_OFFSET 0x00000D80U /**< AHB Configuration \
|
||||
Register */
|
||||
#define XSCUGIC_SFI_TRIG_OFFSET 0x00000F00U /**< Software Triggered \
|
||||
Interrupt Register */
|
||||
#define XSCUGIC_PERPHID_OFFSET 0x00000FD0U /**< Peripheral ID Reg */
|
||||
#define XSCUGIC_PCELLID_OFFSET 0x00000FF0U /**< Pcell ID Register */
|
||||
/* @} */
|
||||
|
||||
/** @name Distributor Enable Register
|
||||
* Controls if the distributor response to external interrupt inputs.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_EN_INT_MASK 0x00000001U /**< Interrupt In Enable */
|
||||
/* @} */
|
||||
|
||||
/** @name Interrupt Controller Type Register
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_LSPI_MASK 0x0000F800U /**< Number of Lockable \
|
||||
Shared Peripheral \
|
||||
Interrupts*/
|
||||
#define XSCUGIC_DOMAIN_MASK 0x00000400U /**< Number os Security domains*/
|
||||
#define XSCUGIC_CPU_NUM_MASK 0x000000E0U /**< Number of CPU Interfaces */
|
||||
#define XSCUGIC_NUM_INT_MASK 0x0000001FU /**< Number of Interrupt IDs */
|
||||
/* @} */
|
||||
|
||||
/** @name Implementor ID Register
|
||||
* Implementor and revision information.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_REV_MASK 0x00FFF000U /**< Revision Number */
|
||||
#define XSCUGIC_IMPL_MASK 0x00000FFFU /**< Implementor */
|
||||
/* @} */
|
||||
|
||||
/** @name Interrupt Security Registers
|
||||
* Each bit controls the security level of an interrupt, either secure or non
|
||||
* secure. These registers can only be accessed using secure read and write.
|
||||
* There are registers for each of the CPU interfaces at offset 0x080. A
|
||||
* register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x084.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_NS_MASK 0x00000001U /**< Each bit corresponds to an \
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Enable Set Register
|
||||
* Each bit controls the enabling of an interrupt, a 0 is disabled, a 1 is
|
||||
* enabled. Writing a 0 has no effect. Use the ENABLE_CLR register to set a
|
||||
* bit to 0.
|
||||
* There are registers for each of the CPU interfaces at offset 0x100. With up
|
||||
* to 8 registers aliased to the same address. A register set for the SPI
|
||||
* interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x104.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_EN_MASK 0x00000001U /**< Each bit corresponds to an \
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Enable Clear Register
|
||||
* Each bit controls the disabling of an interrupt, a 0 is disabled, a 1 is
|
||||
* enabled. Writing a 0 has no effect. Writing a 1 disables an interrupt and
|
||||
* sets the corresponding bit to 0.
|
||||
* There are registers for each of the CPU interfaces at offset 0x180. With up
|
||||
* to 8 registers aliased to the same address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x184.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_CLR_MASK 0x00000001U /**< Each bit corresponds to an \
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Pending Set Register
|
||||
* Each bit controls the Pending or Active and Pending state of an interrupt, a
|
||||
* 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1 sets
|
||||
* an interrupt to the pending state.
|
||||
* There are registers for each of the CPU interfaces at offset 0x200. With up
|
||||
* to 8 registers aliased to the same address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x204.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PEND_SET_MASK 0x00000001U /**< Each bit corresponds to an \
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Pending Clear Register
|
||||
* Each bit can clear the Pending or Active and Pending state of an interrupt, a
|
||||
* 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1
|
||||
* clears the pending state of an interrupt.
|
||||
* There are registers for each of the CPU interfaces at offset 0x280. With up
|
||||
* to 8 registers aliased to the same address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x284.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PEND_CLR_MASK 0x00000001U /**< Each bit corresponds to an \
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Active Status Register
|
||||
* Each bit provides the Active status of an interrupt, a
|
||||
* 0 is not Active, a 1 is Active. This is a read only register.
|
||||
* There are registers for each of the CPU interfaces at offset 0x300. With up
|
||||
* to 8 registers aliased to each address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x380.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_ACTIVE_MASK 0x00000001U /**< Each bit corresponds to an \
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Priority Level Register
|
||||
* Each byte in a Priority Level Register sets the priority level of an
|
||||
* interrupt. Reading the register provides the priority level of an interrupt.
|
||||
* There are registers for each of the CPU interfaces at offset 0x400 through
|
||||
* 0x41C. With up to 8 registers aliased to each address.
|
||||
* 0 is highest priority, 0xFF is lowest.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 255 of these registers staring at location 0x420.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PRIORITY_MASK 0x000000FFU /**< Each Byte corresponds to an \
|
||||
INT_ID */
|
||||
#define XSCUGIC_PRIORITY_MAX 0x000000FFU /**< Highest value of a priority \
|
||||
actually the lowest priority*/
|
||||
/* @} */
|
||||
|
||||
/** @name SPI Target Register 0x800-0x8FB
|
||||
* Each byte references a separate SPI and programs which of the up to 8 CPU
|
||||
* interfaces are sent a Pending interrupt.
|
||||
* There are registers for each of the CPU interfaces at offset 0x800 through
|
||||
* 0x81C. With up to 8 registers aliased to each address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 255 of these registers staring at location 0x820.
|
||||
*
|
||||
* This driver does not support multiple CPU interfaces. These are included
|
||||
* for complete documentation.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_SPI_CPU7_MASK 0x00000080U /**< CPU 7 Mask*/
|
||||
#define XSCUGIC_SPI_CPU6_MASK 0x00000040U /**< CPU 6 Mask*/
|
||||
#define XSCUGIC_SPI_CPU5_MASK 0x00000020U /**< CPU 5 Mask*/
|
||||
#define XSCUGIC_SPI_CPU4_MASK 0x00000010U /**< CPU 4 Mask*/
|
||||
#define XSCUGIC_SPI_CPU3_MASK 0x00000008U /**< CPU 3 Mask*/
|
||||
#define XSCUGIC_SPI_CPU2_MASK 0x00000003U /**< CPU 2 Mask*/
|
||||
#define XSCUGIC_SPI_CPU1_MASK 0x00000002U /**< CPU 1 Mask*/
|
||||
#define XSCUGIC_SPI_CPU0_MASK 0x00000001U /**< CPU 0 Mask*/
|
||||
/* @} */
|
||||
|
||||
/** @name Interrupt Configuration Register 0xC00-0xCFC
|
||||
* The interrupt configuration registers program an SFI to be active HIGH level
|
||||
* sensitive or rising edge sensitive.
|
||||
* Each bit pair describes the configuration for an INT_ID.
|
||||
* SFI Read Only b10 always
|
||||
* PPI Read Only depending on how the PPIs are configured.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive
|
||||
* SPI LSB is read only.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive/
|
||||
* There are registers for each of the CPU interfaces at offset 0xC00 through
|
||||
* 0xC04. With up to 8 registers aliased to each address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 255 of these registers staring at location 0xC08.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_CFG_MASK 0x00000003U /**< */
|
||||
/* @} */
|
||||
|
||||
/** @name PPI Status Register
|
||||
* Enables an external AMBA master to access the status of the PPI inputs.
|
||||
* A CPU can only read the status of its local PPI signals and cannot read the
|
||||
* status for other CPUs.
|
||||
* This register is aliased for each CPU interface.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PPI_C15_MASK 0x00008000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C14_MASK 0x00004000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C13_MASK 0x00002000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C12_MASK 0x00001000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C11_MASK 0x00000800U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C10_MASK 0x00000400U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C09_MASK 0x00000200U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C08_MASK 0x00000100U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C07_MASK 0x00000080U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C06_MASK 0x00000040U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C05_MASK 0x00000020U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C04_MASK 0x00000010U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C03_MASK 0x00000008U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C02_MASK 0x00000004U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C01_MASK 0x00000002U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C00_MASK 0x00000001U /**< PPI Status */
|
||||
/* @} */
|
||||
|
||||
/** @name SPI Status Register 0xd04-0xd7C
|
||||
* Enables an external AMBA master to access the status of the SPI inputs.
|
||||
* There are up to 63 registers if the maximum number of SPI inputs are
|
||||
* configured.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_SPI_N_MASK 0x00000001U /**< Each bit corresponds to an SPI \
|
||||
input */
|
||||
/* @} */
|
||||
|
||||
/** @name AHB Configuration Register
|
||||
* Provides the status of the CFGBIGEND input signal and allows the endianess
|
||||
* of the GIC to be set.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_AHB_END_MASK 0x00000004U /**< 0-GIC uses little Endian, \
|
||||
1-GIC uses Big Endian */
|
||||
#define XSCUGIC_AHB_ENDOVR_MASK 0x00000002U /**< 0-Uses CFGBIGEND control, \
|
||||
1-use the AHB_END bit */
|
||||
#define XSCUGIC_AHB_TIE_OFF_MASK 0x00000001U /**< State of CFGBIGEND */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Software Triggered Interrupt Register
|
||||
* Controls issueing of software interrupts.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_SFI_SELFTRIG_MASK 0x02010000U
|
||||
#define XSCUGIC_SFI_TRIG_TRGFILT_MASK 0x03000000U /**< Target List filter \
|
||||
b00-Use the target List \
|
||||
b01-All CPUs except requester \
|
||||
b10-To Requester \
|
||||
b11-reserved */
|
||||
#define XSCUGIC_SFI_TRIG_CPU_MASK 0x00FF0000U /**< CPU Target list */
|
||||
#define XSCUGIC_SFI_TRIG_SATT_MASK 0x00008000U /**< 0= Use a secure interrupt */
|
||||
#define XSCUGIC_SFI_TRIG_INTID_MASK 0x0000000FU /**< Set to the INTID \
|
||||
signaled to the CPU*/
|
||||
/* @} */
|
||||
|
||||
/** @name CPU Interface Register Map
|
||||
*
|
||||
* Define the offsets from the base address for all CPU registers of the
|
||||
* interrupt controller, some registers may be reserved in the hardware device.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_CONTROL_OFFSET 0x00000000U /**< CPU Interface Control \
|
||||
Register */
|
||||
#define XSCUGIC_CPU_PRIOR_OFFSET 0x00000004U /**< Priority Mask Reg */
|
||||
#define XSCUGIC_BIN_PT_OFFSET 0x00000008U /**< Binary Point Register */
|
||||
#define XSCUGIC_INT_ACK_OFFSET 0x0000000CU /**< Interrupt ACK Reg */
|
||||
#define XSCUGIC_EOI_OFFSET 0x00000010U /**< End of Interrupt Reg */
|
||||
#define XSCUGIC_RUN_PRIOR_OFFSET 0x00000014U /**< Running Priority Reg */
|
||||
#define XSCUGIC_HI_PEND_OFFSET 0x00000018U /**< Highest Pending Interrupt \
|
||||
Register */
|
||||
#define XSCUGIC_ALIAS_BIN_PT_OFFSET 0x0000001CU /**< Aliased non-Secure \
|
||||
Binary Point Register */
|
||||
|
||||
/**< 0x00000020 to 0x00000FBC are reserved and should not be read or written
|
||||
* to. */
|
||||
/* @} */
|
||||
|
||||
/** @name Control Register
|
||||
* CPU Interface Control register definitions
|
||||
* All bits are defined here although some are not available in the non-secure
|
||||
* mode.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_CNTR_SBPR_MASK 0x00000010U /**< Secure Binary Pointer, \
|
||||
0=separate registers, \
|
||||
1=both use bin_pt_s */
|
||||
#define XSCUGIC_CNTR_FIQEN_MASK 0x00000008U /**< Use nFIQ_C for secure \
|
||||
interrupts, \
|
||||
0= use IRQ for both, \
|
||||
1=Use FIQ for secure, IRQ for non*/
|
||||
#define XSCUGIC_CNTR_ACKCTL_MASK 0x00000004U /**< Ack control for secure or non secure */
|
||||
#define XSCUGIC_CNTR_EN_NS_MASK 0x00000002U /**< Non Secure enable */
|
||||
#define XSCUGIC_CNTR_EN_S_MASK 0x00000001U /**< Secure enable, 0=Disabled, 1=Enabled */
|
||||
/* @} */
|
||||
|
||||
/** @name Priority Mask Register
|
||||
* Priority Mask register definitions
|
||||
* The CPU interface does not send interrupt if the level of the interrupt is
|
||||
* lower than the level of the register.
|
||||
* @{
|
||||
*/
|
||||
/*#define XSCUGIC_PRIORITY_MASK 0x000000FFU*/ /**< All interrupts */
|
||||
/* @} */
|
||||
|
||||
/** @name Binary Point Register
|
||||
* Binary Point register definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XSCUGIC_BIN_PT_MASK 0x00000007U /**< Binary point mask value \
|
||||
Value Secure Non-secure \
|
||||
b000 0xFE 0xFF \
|
||||
b001 0xFC 0xFE \
|
||||
b010 0xF8 0xFC \
|
||||
b011 0xF0 0xF8 \
|
||||
b100 0xE0 0xF0 \
|
||||
b101 0xC0 0xE0 \
|
||||
b110 0x80 0xC0 \
|
||||
b111 0x00 0x80 \
|
||||
*/
|
||||
/*@}*/
|
||||
|
||||
/** @name Interrupt Acknowledge Register
|
||||
* Interrupt Acknowledge register definitions
|
||||
* Identifies the current Pending interrupt, and the CPU ID for software
|
||||
* interrupts.
|
||||
*/
|
||||
#define XSCUGIC_ACK_INTID_MASK 0x000003FFU /**< Interrupt ID */
|
||||
#define XSCUGIC_CPUID_MASK 0x00000C00U /**< CPU ID */
|
||||
/* @} */
|
||||
|
||||
/** @name End of Interrupt Register
|
||||
* End of Interrupt register definitions
|
||||
* Allows the CPU to signal the GIC when it completes an interrupt service
|
||||
* routine.
|
||||
*/
|
||||
#define XSCUGIC_EOI_INTID_MASK 0x000003FFU /**< Interrupt ID */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Running Priority Register
|
||||
* Running Priority register definitions
|
||||
* Identifies the interrupt priority level of the highest priority active
|
||||
* interrupt.
|
||||
*/
|
||||
#define XSCUGIC_RUN_PRIORITY_MASK 0x000000FFU /**< Interrupt Priority */
|
||||
/* @} */
|
||||
|
||||
/*
|
||||
* Highest Pending Interrupt register definitions
|
||||
* Identifies the interrupt priority of the highest priority pending interupt
|
||||
*/
|
||||
#define XSCUGIC_PEND_INTID_MASK 0x000003FFU /**< Pending Interrupt ID */
|
||||
/*#define XSCUGIC_CPUID_MASK 0x00000C00U */ /**< CPU ID */
|
||||
/* @} */
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the Interrupt Configuration Register offset for an interrupt id.
|
||||
*
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_INT_CFG_OFFSET_CALC(InterruptID) \
|
||||
((u32)XSCUGIC_INT_CFG_OFFSET + (((InterruptID) / 16U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the Interrupt Priority Register offset for an interrupt id.
|
||||
*
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_PRIORITY_OFFSET_CALC(InterruptID) \
|
||||
((u32)XSCUGIC_PRIORITY_OFFSET + (((InterruptID) / 4U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the SPI Target Register offset for an interrupt id.
|
||||
*
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_SPI_TARGET_OFFSET_CALC(InterruptID) \
|
||||
((u32)XSCUGIC_SPI_TARGET_OFFSET + (((InterruptID) / 4U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the Interrupt Clear-Enable Register offset for an interrupt ID
|
||||
*
|
||||
* @param Register is the register offset for the clear/enable bank.
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_EN_DIS_OFFSET_CALC(Register, InterruptID) \
|
||||
((Register) + (((InterruptID) / 32U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given Intc register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XScuGic_ReadReg(u32 BaseAddress, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_ReadReg(BaseAddress, RegOffset) \
|
||||
(Xil_In32((BaseAddress) + (RegOffset)))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given Intc register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XScuGic_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_WriteReg(BaseAddress, RegOffset, Data) \
|
||||
(Xil_Out32(((BaseAddress) + (RegOffset)), ((u32)(Data))))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable specific interrupt(s) in the interrupt controller.
|
||||
*
|
||||
* @param DistBaseAddress is the Distributor Register base address of the
|
||||
* device
|
||||
* @param Int_Id is the ID of the interrupt source and should be in the
|
||||
* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XScuGic_EnableIntr(u32 DistBaseAddress, u32 Int_Id)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_EnableIntr(DistBaseAddress, Int_Id) \
|
||||
XScuGic_WriteReg((DistBaseAddress), \
|
||||
XSCUGIC_ENABLE_SET_OFFSET + (((Int_Id) / 32U) * 4U), \
|
||||
(0x00000001U << ((Int_Id) % 32U)))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable specific interrupt(s) in the interrupt controller.
|
||||
*
|
||||
* @param DistBaseAddress is the Distributor Register base address of the
|
||||
* device
|
||||
* @param Int_Id is the ID of the interrupt source and should be in the
|
||||
* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XScuGic_DisableIntr(u32 DistBaseAddress, u32 Int_Id)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_DisableIntr(DistBaseAddress, Int_Id) \
|
||||
XScuGic_WriteReg((DistBaseAddress), \
|
||||
XSCUGIC_DISABLE_OFFSET + (((Int_Id) / 32U) * 4U), \
|
||||
(0x00000001U << ((Int_Id) % 32U)))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XScuGic_DeviceInterruptHandler(void* DeviceId);
|
||||
s32 XScuGic_DeviceInitialize(u32 DeviceId);
|
||||
void XScuGic_RegisterHandler(u32 BaseAddress, s32 InterruptID,
|
||||
Xil_InterruptHandler Handler, void* CallBackRef);
|
||||
void XScuGic_SetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger);
|
||||
void XScuGic_GetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8* Priority, u8* Trigger);
|
||||
/************************** Variable Definitions *****************************/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xscugic_intr.c
|
||||
* @addtogroup scugic_v3_1
|
||||
* @{
|
||||
*
|
||||
* This file contains the interrupt processing for the driver for the Xilinx
|
||||
* Interrupt Controller. The interrupt processing is partitioned separately such
|
||||
* that users are not required to use the provided interrupt processing. This
|
||||
* file requires other files of the driver to be linked in also.
|
||||
*
|
||||
* The interrupt handler, XScuGic_InterruptHandler, uses an input argument which
|
||||
* is an instance pointer to an interrupt controller driver such that multiple
|
||||
* interrupt controllers can be supported. This handler requires the calling
|
||||
* function to pass it the appropriate argument, so another level of indirection
|
||||
* may be required.
|
||||
*
|
||||
* The interrupt processing may be used by connecting the interrupt handler to
|
||||
* the interrupt system. The handler does not save and restore the processor
|
||||
* context but only handles the processing of the Interrupt Controller. The user
|
||||
* is encouraged to supply their own interrupt handler when performance tuning is
|
||||
* deemed necessary.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 1.01a sdm 11/09/11 XScuGic_InterruptHandler has changed correspondingly
|
||||
* since the HandlerTable has now moved to XScuGic_Config.
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* This driver assumes that the context of the processor has been saved prior to
|
||||
* the calling of the Interrupt Controller interrupt handler and then restored
|
||||
* after the handler returns. This requires either the running RTOS to save the
|
||||
* state of the machine or that a wrapper be used as the destination of the
|
||||
* interrupt vector to save the state of the processor and restore the state
|
||||
* after the interrupt handler returns.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_assert.h"
|
||||
#include "xil_types.h"
|
||||
#include "xscugic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function is the primary interrupt handler for the driver. It must be
|
||||
* connected to the interrupt source such that it is called when an interrupt of
|
||||
* the interrupt controller is active. It will resolve which interrupts are
|
||||
* active and enabled and call the appropriate interrupt handler. It uses
|
||||
* the Interrupt Type information to determine when to acknowledge the interrupt.
|
||||
* Highest priority interrupts are serviced first.
|
||||
*
|
||||
* This function assumes that an interrupt vector table has been previously
|
||||
* initialized. It does not verify that entries in the table are valid before
|
||||
* calling an interrupt handler.
|
||||
*
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XScuGic_InterruptHandler(XScuGic* InstancePtr)
|
||||
{
|
||||
|
||||
u32 InterruptID;
|
||||
u32 IntIDFull;
|
||||
XScuGic_VectorTableEntry* TablePtr;
|
||||
|
||||
/* Assert that the pointer to the instance is valid
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Read the int_ack register to identify the highest priority interrupt ID
|
||||
* and make sure it is valid. Reading Int_Ack will clear the interrupt
|
||||
* in the GIC.
|
||||
*/
|
||||
IntIDFull = XScuGic_CPUReadReg(InstancePtr, XSCUGIC_INT_ACK_OFFSET);
|
||||
InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK;
|
||||
|
||||
if (XSCUGIC_MAX_NUM_INTR_INPUTS < InterruptID) {
|
||||
goto IntrExit;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interrupt is shared, do some locking here if there are multiple
|
||||
* processors.
|
||||
*/
|
||||
/*
|
||||
* If pre-eption is required:
|
||||
* Re-enable pre-emption by setting the CPSR I bit for non-secure ,
|
||||
* interrupts or the F bit for secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If we need to change security domains, issue a SMC instruction here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Execute the ISR. Jump into the Interrupt service routine based on the
|
||||
* IRQSource. A software trigger is cleared by the ACK.
|
||||
*/
|
||||
TablePtr = &(InstancePtr->Config->HandlerTable[InterruptID]);
|
||||
if (TablePtr != NULL) {
|
||||
TablePtr->Handler(TablePtr->CallBackRef);
|
||||
}
|
||||
|
||||
IntrExit:
|
||||
/*
|
||||
* Write to the EOI register, we are all done here.
|
||||
* Let this function return, the boot code will restore the stack.
|
||||
*/
|
||||
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_EOI_OFFSET, IntIDFull);
|
||||
|
||||
/*
|
||||
* Return from the interrupt. Change security domains could happen here.
|
||||
*/
|
||||
}
|
||||
/** @} */
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xscugic_sinit.c
|
||||
* @addtogroup scugic_v3_1
|
||||
* @{
|
||||
*
|
||||
* Contains static init functions for the XScuGic driver for the Interrupt
|
||||
* Controller. See xscugic.h for a detailed description of the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- --------------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern XScuGic_Config XScuGic_ConfigTable[XPAR_SCUGIC_NUM_INSTANCES];
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the unique device ID. A table
|
||||
* contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param DeviceId is the unique identifier for a device.
|
||||
*
|
||||
* @return A pointer to the XScuGic configuration structure for the
|
||||
* specified device, or NULL if the device was not found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XScuGic_Config *CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index=0U; Index < (u32)XPAR_SCUGIC_NUM_INSTANCES; Index++) {
|
||||
if (XScuGic_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XScuGic_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (XScuGic_Config *)CfgPtr;
|
||||
}
|
||||
/** @} */
|
||||
+430
@@ -0,0 +1,430 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xstatus.h
|
||||
*
|
||||
* This file contains Xilinx software status codes. Status codes have their
|
||||
* own data type called int. These codes are used throughout the Xilinx
|
||||
* device drivers.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XSTATUS_H /* prevent circular inclusions */
|
||||
#define XSTATUS_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*********************** Common statuses 0 - 500 *****************************/
|
||||
// clang-format off
|
||||
#define XST_SUCCESS 0L
|
||||
#define XST_FAILURE 1L
|
||||
#define XST_DEVICE_NOT_FOUND 2L
|
||||
#define XST_DEVICE_BLOCK_NOT_FOUND 3L
|
||||
#define XST_INVALID_VERSION 4L
|
||||
#define XST_DEVICE_IS_STARTED 5L
|
||||
#define XST_DEVICE_IS_STOPPED 6L
|
||||
#define XST_FIFO_ERROR 7L /* an error occurred during an
|
||||
operation with a FIFO such as
|
||||
an underrun or overrun, this
|
||||
error requires the device to
|
||||
be reset */
|
||||
#define XST_RESET_ERROR 8L /* an error occurred which requires
|
||||
the device to be reset */
|
||||
#define XST_DMA_ERROR 9L /* a DMA error occurred, this error
|
||||
typically requires the device
|
||||
using the DMA to be reset */
|
||||
#define XST_NOT_POLLED 10L /* the device is not configured for
|
||||
polled mode operation */
|
||||
#define XST_FIFO_NO_ROOM 11L /* a FIFO did not have room to put
|
||||
the specified data into */
|
||||
#define XST_BUFFER_TOO_SMALL 12L /* the buffer is not large enough
|
||||
to hold the expected data */
|
||||
#define XST_NO_DATA 13L /* there was no data available */
|
||||
#define XST_REGISTER_ERROR 14L /* a register did not contain the
|
||||
expected value */
|
||||
#define XST_INVALID_PARAM 15L /* an invalid parameter was passed
|
||||
into the function */
|
||||
#define XST_NOT_SGDMA 16L /* the device is not configured for
|
||||
scatter-gather DMA operation */
|
||||
#define XST_LOOPBACK_ERROR 17L /* a loopback test failed */
|
||||
#define XST_NO_CALLBACK 18L /* a callback has not yet been
|
||||
registered */
|
||||
#define XST_NO_FEATURE 19L /* device is not configured with
|
||||
the requested feature */
|
||||
#define XST_NOT_INTERRUPT 20L /* device is not configured for
|
||||
interrupt mode operation */
|
||||
#define XST_DEVICE_BUSY 21L /* device is busy */
|
||||
#define XST_ERROR_COUNT_MAX 22L /* the error counters of a device
|
||||
have maxed out */
|
||||
#define XST_IS_STARTED 23L /* used when part of device is
|
||||
already started i.e.
|
||||
sub channel */
|
||||
#define XST_IS_STOPPED 24L /* used when part of device is
|
||||
already stopped i.e.
|
||||
sub channel */
|
||||
#define XST_DATA_LOST 26L /* driver defined error */
|
||||
#define XST_RECV_ERROR 27L /* generic receive error */
|
||||
#define XST_SEND_ERROR 28L /* generic transmit error */
|
||||
#define XST_NOT_ENABLED 29L /* a requested service is not
|
||||
available because it has not
|
||||
been enabled */
|
||||
|
||||
/***************** Utility Component statuses 401 - 500 *********************/
|
||||
|
||||
#define XST_MEMTEST_FAILED 401L /* memory test failed */
|
||||
|
||||
|
||||
/***************** Common Components statuses 501 - 1000 *********************/
|
||||
|
||||
/********************* Packet Fifo statuses 501 - 510 ************************/
|
||||
|
||||
#define XST_PFIFO_LACK_OF_DATA 501L /* not enough data in FIFO */
|
||||
#define XST_PFIFO_NO_ROOM 502L /* not enough room in FIFO */
|
||||
#define XST_PFIFO_BAD_REG_VALUE 503L /* self test, a register value
|
||||
was invalid after reset */
|
||||
#define XST_PFIFO_ERROR 504L /* generic packet FIFO error */
|
||||
#define XST_PFIFO_DEADLOCK 505L /* packet FIFO is reporting
|
||||
* empty and full simultaneously
|
||||
*/
|
||||
|
||||
/************************** DMA statuses 511 - 530 ***************************/
|
||||
|
||||
#define XST_DMA_TRANSFER_ERROR 511L /* self test, DMA transfer
|
||||
failed */
|
||||
#define XST_DMA_RESET_REGISTER_ERROR 512L /* self test, a register value
|
||||
was invalid after reset */
|
||||
#define XST_DMA_SG_LIST_EMPTY 513L /* scatter gather list contains
|
||||
no buffer descriptors ready
|
||||
to be processed */
|
||||
#define XST_DMA_SG_IS_STARTED 514L /* scatter gather not stopped */
|
||||
#define XST_DMA_SG_IS_STOPPED 515L /* scatter gather not running */
|
||||
#define XST_DMA_SG_LIST_FULL 517L /* all the buffer desciptors of
|
||||
the scatter gather list are
|
||||
being used */
|
||||
#define XST_DMA_SG_BD_LOCKED 518L /* the scatter gather buffer
|
||||
descriptor which is to be
|
||||
copied over in the scatter
|
||||
list is locked */
|
||||
#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /* no buffer descriptors have been
|
||||
put into the scatter gather
|
||||
list to be commited */
|
||||
#define XST_DMA_SG_COUNT_EXCEEDED 521L /* the packet count threshold
|
||||
specified was larger than the
|
||||
total # of buffer descriptors
|
||||
in the scatter gather list */
|
||||
#define XST_DMA_SG_LIST_EXISTS 522L /* the scatter gather list has
|
||||
already been created */
|
||||
#define XST_DMA_SG_NO_LIST 523L /* no scatter gather list has
|
||||
been created */
|
||||
#define XST_DMA_SG_BD_NOT_COMMITTED 524L /* the buffer descriptor which was
|
||||
being started was not committed
|
||||
to the list */
|
||||
#define XST_DMA_SG_NO_DATA 525L /* the buffer descriptor to start
|
||||
has already been used by the
|
||||
hardware so it can't be reused
|
||||
*/
|
||||
#define XST_DMA_SG_LIST_ERROR 526L /* general purpose list access
|
||||
error */
|
||||
#define XST_DMA_BD_ERROR 527L /* general buffer descriptor
|
||||
error */
|
||||
|
||||
/************************** IPIF statuses 531 - 550 ***************************/
|
||||
|
||||
#define XST_IPIF_REG_WIDTH_ERROR 531L /* an invalid register width
|
||||
was passed into the function */
|
||||
#define XST_IPIF_RESET_REGISTER_ERROR 532L /* the value of a register at
|
||||
reset was not valid */
|
||||
#define XST_IPIF_DEVICE_STATUS_ERROR 533L /* a write to the device interrupt
|
||||
status register did not read
|
||||
back correctly */
|
||||
#define XST_IPIF_DEVICE_ACK_ERROR 534L /* the device interrupt status
|
||||
register did not reset when
|
||||
acked */
|
||||
#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /* the device interrupt enable
|
||||
register was not updated when
|
||||
other registers changed */
|
||||
#define XST_IPIF_IP_STATUS_ERROR 536L /* a write to the IP interrupt
|
||||
status register did not read
|
||||
back correctly */
|
||||
#define XST_IPIF_IP_ACK_ERROR 537L /* the IP interrupt status register
|
||||
did not reset when acked */
|
||||
#define XST_IPIF_IP_ENABLE_ERROR 538L /* IP interrupt enable register was
|
||||
not updated correctly when other
|
||||
registers changed */
|
||||
#define XST_IPIF_DEVICE_PENDING_ERROR 539L /* The device interrupt pending
|
||||
register did not indicate the
|
||||
expected value */
|
||||
#define XST_IPIF_DEVICE_ID_ERROR 540L /* The device interrupt ID register
|
||||
did not indicate the expected
|
||||
value */
|
||||
#define XST_IPIF_ERROR 541L /* generic ipif error */
|
||||
|
||||
/****************** Device specific statuses 1001 - 4095 *********************/
|
||||
|
||||
/********************* Ethernet statuses 1001 - 1050 *************************/
|
||||
|
||||
#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /* Memory space is not big enough
|
||||
* to hold the minimum number of
|
||||
* buffers or descriptors */
|
||||
#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /* Memory allocation failed */
|
||||
#define XST_EMAC_MII_READ_ERROR 1003L /* MII read error */
|
||||
#define XST_EMAC_MII_BUSY 1004L /* An MII operation is in progress */
|
||||
#define XST_EMAC_OUT_OF_BUFFERS 1005L /* Driver is out of buffers */
|
||||
#define XST_EMAC_PARSE_ERROR 1006L /* Invalid driver init string */
|
||||
#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late
|
||||
* collision on polled send */
|
||||
|
||||
/*********************** UART statuses 1051 - 1075 ***************************/
|
||||
#define XST_UART
|
||||
|
||||
#define XST_UART_INIT_ERROR 1051L
|
||||
#define XST_UART_START_ERROR 1052L
|
||||
#define XST_UART_CONFIG_ERROR 1053L
|
||||
#define XST_UART_TEST_FAIL 1054L
|
||||
#define XST_UART_BAUD_ERROR 1055L
|
||||
#define XST_UART_BAUD_RANGE 1056L
|
||||
|
||||
|
||||
/************************ IIC statuses 1076 - 1100 ***************************/
|
||||
|
||||
#define XST_IIC_SELFTEST_FAILED 1076 /* self test failed */
|
||||
#define XST_IIC_BUS_BUSY 1077 /* bus found busy */
|
||||
#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /* mastersend attempted with */
|
||||
/* general call address */
|
||||
#define XST_IIC_STAND_REG_RESET_ERROR 1079 /* A non parameterizable reg */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /* Tx fifo included in design */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /* Rx fifo included in design */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_TBA_REG_RESET_ERROR 1082 /* 10 bit addr incl in design */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_CR_READBACK_ERROR 1083 /* Read of the control register */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_DTR_READBACK_ERROR 1084 /* Read of the data Tx reg */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_DRR_READBACK_ERROR 1085 /* Read of the data Receive reg */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_ADR_READBACK_ERROR 1086 /* Read of the data Tx reg */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_TBA_READBACK_ERROR 1087 /* Read of the 10 bit addr reg */
|
||||
/* didn't return written value */
|
||||
#define XST_IIC_NOT_SLAVE 1088 /* The device isn't a slave */
|
||||
|
||||
/*********************** ATMC statuses 1101 - 1125 ***************************/
|
||||
|
||||
#define XST_ATMC_ERROR_COUNT_MAX 1101L /* the error counters in the ATM
|
||||
controller hit the max value
|
||||
which requires the statistics
|
||||
to be cleared */
|
||||
|
||||
/*********************** Flash statuses 1126 - 1150 **************************/
|
||||
|
||||
#define XST_FLASH_BUSY 1126L /* Flash is erasing or programming
|
||||
*/
|
||||
#define XST_FLASH_READY 1127L /* Flash is ready for commands */
|
||||
#define XST_FLASH_ERROR 1128L /* Flash had detected an internal
|
||||
error. Use XFlash_DeviceControl
|
||||
to retrieve device specific codes
|
||||
*/
|
||||
#define XST_FLASH_ERASE_SUSPENDED 1129L /* Flash is in suspended erase state
|
||||
*/
|
||||
#define XST_FLASH_WRITE_SUSPENDED 1130L /* Flash is in suspended write state
|
||||
*/
|
||||
#define XST_FLASH_PART_NOT_SUPPORTED 1131L /* Flash type not supported by
|
||||
driver */
|
||||
#define XST_FLASH_NOT_SUPPORTED 1132L /* Operation not supported */
|
||||
#define XST_FLASH_TOO_MANY_REGIONS 1133L /* Too many erase regions */
|
||||
#define XST_FLASH_TIMEOUT_ERROR 1134L /* Programming or erase operation
|
||||
aborted due to a timeout */
|
||||
#define XST_FLASH_ADDRESS_ERROR 1135L /* Accessed flash outside its
|
||||
addressible range */
|
||||
#define XST_FLASH_ALIGNMENT_ERROR 1136L /* Write alignment error */
|
||||
#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /* Couldn't return immediately from
|
||||
write/erase function with
|
||||
XFL_NON_BLOCKING_WRITE/ERASE
|
||||
option cleared */
|
||||
#define XST_FLASH_CFI_QUERY_ERROR 1138L /* Failed to query the device */
|
||||
|
||||
/*********************** SPI statuses 1151 - 1175 ****************************/
|
||||
|
||||
#define XST_SPI_MODE_FAULT 1151 /* master was selected as slave */
|
||||
#define XST_SPI_TRANSFER_DONE 1152 /* data transfer is complete */
|
||||
#define XST_SPI_TRANSMIT_UNDERRUN 1153 /* slave underruns transmit register */
|
||||
#define XST_SPI_RECEIVE_OVERRUN 1154 /* device overruns receive register */
|
||||
#define XST_SPI_NO_SLAVE 1155 /* no slave has been selected yet */
|
||||
#define XST_SPI_TOO_MANY_SLAVES 1156 /* more than one slave is being
|
||||
* selected */
|
||||
#define XST_SPI_NOT_MASTER 1157 /* operation is valid only as master */
|
||||
#define XST_SPI_SLAVE_ONLY 1158 /* device is configured as slave-only
|
||||
*/
|
||||
#define XST_SPI_SLAVE_MODE_FAULT 1159 /* slave was selected while disabled */
|
||||
#define XST_SPI_SLAVE_MODE 1160 /* device has been addressed as slave */
|
||||
#define XST_SPI_RECEIVE_NOT_EMPTY 1161 /* device received data in slave mode */
|
||||
|
||||
#define XST_SPI_COMMAND_ERROR 1162 /* unrecognised command - qspi only */
|
||||
|
||||
/********************** OPB Arbiter statuses 1176 - 1200 *********************/
|
||||
|
||||
#define XST_OPBARB_INVALID_PRIORITY 1176 /* the priority registers have either
|
||||
* one master assigned to two or more
|
||||
* priorities, or one master not
|
||||
* assigned to any priority
|
||||
*/
|
||||
#define XST_OPBARB_NOT_SUSPENDED 1177 /* an attempt was made to modify the
|
||||
* priority levels without first
|
||||
* suspending the use of priority
|
||||
* levels
|
||||
*/
|
||||
#define XST_OPBARB_PARK_NOT_ENABLED 1178 /* bus parking by id was enabled but
|
||||
* bus parking was not enabled
|
||||
*/
|
||||
#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /* the arbiter must be in fixed
|
||||
* priority mode to allow the
|
||||
* priorities to be changed
|
||||
*/
|
||||
|
||||
/************************ Intc statuses 1201 - 1225 **************************/
|
||||
|
||||
#define XST_INTC_FAIL_SELFTEST 1201 /* self test failed */
|
||||
#define XST_INTC_CONNECT_ERROR 1202 /* interrupt already in use */
|
||||
|
||||
/********************** TmrCtr statuses 1226 - 1250 **************************/
|
||||
|
||||
#define XST_TMRCTR_TIMER_FAILED 1226 /* self test failed */
|
||||
|
||||
/********************** WdtTb statuses 1251 - 1275 ***************************/
|
||||
|
||||
#define XST_WDTTB_TIMER_FAILED 1251L
|
||||
|
||||
/********************** PlbArb statuses 1276 - 1300 **************************/
|
||||
|
||||
#define XST_PLBARB_FAIL_SELFTEST 1276L
|
||||
|
||||
/********************** Plb2Opb statuses 1301 - 1325 *************************/
|
||||
|
||||
#define XST_PLB2OPB_FAIL_SELFTEST 1301L
|
||||
|
||||
/********************** Opb2Plb statuses 1326 - 1350 *************************/
|
||||
|
||||
#define XST_OPB2PLB_FAIL_SELFTEST 1326L
|
||||
|
||||
/********************** SysAce statuses 1351 - 1360 **************************/
|
||||
|
||||
#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted */
|
||||
|
||||
/********************** PCI Bridge statuses 1361 - 1375 **********************/
|
||||
|
||||
#define XST_PCI_INVALID_ADDRESS 1361L
|
||||
|
||||
/********************** FlexRay constants 1400 - 1409 *************************/
|
||||
|
||||
#define XST_FR_TX_ERROR 1400
|
||||
#define XST_FR_TX_BUSY 1401
|
||||
#define XST_FR_BUF_LOCKED 1402
|
||||
#define XST_FR_NO_BUF 1403
|
||||
|
||||
/****************** USB constants 1410 - 1420 *******************************/
|
||||
|
||||
#define XST_USB_ALREADY_CONFIGURED 1410
|
||||
#define XST_USB_BUF_ALIGN_ERROR 1411
|
||||
#define XST_USB_NO_DESC_AVAILABLE 1412
|
||||
#define XST_USB_BUF_TOO_BIG 1413
|
||||
#define XST_USB_NO_BUF 1414
|
||||
|
||||
/****************** HWICAP constants 1421 - 1429 *****************************/
|
||||
|
||||
#define XST_HWICAP_WRITE_DONE 1421
|
||||
|
||||
|
||||
/****************** AXI VDMA constants 1430 - 1440 *****************************/
|
||||
|
||||
#define XST_VDMA_MISMATCH_ERROR 1430
|
||||
|
||||
/*********************** NAND Flash statuses 1441 - 1459 *********************/
|
||||
|
||||
#define XST_NAND_BUSY 1441L /* Flash is erasing or
|
||||
* programming
|
||||
*/
|
||||
#define XST_NAND_READY 1442L /* Flash is ready for commands
|
||||
*/
|
||||
#define XST_NAND_ERROR 1443L /* Flash had detected an
|
||||
* internal error.
|
||||
*/
|
||||
#define XST_NAND_PART_NOT_SUPPORTED 1444L /* Flash type not supported by
|
||||
* driver
|
||||
*/
|
||||
#define XST_NAND_OPT_NOT_SUPPORTED 1445L /* Operation not supported
|
||||
*/
|
||||
#define XST_NAND_TIMEOUT_ERROR 1446L /* Programming or erase
|
||||
* operation aborted due to a
|
||||
* timeout
|
||||
*/
|
||||
#define XST_NAND_ADDRESS_ERROR 1447L /* Accessed flash outside its
|
||||
* addressible range
|
||||
*/
|
||||
#define XST_NAND_ALIGNMENT_ERROR 1448L /* Write alignment error
|
||||
*/
|
||||
#define XST_NAND_PARAM_PAGE_ERROR 1449L /* Failed to read parameter
|
||||
* page of the device
|
||||
*/
|
||||
#define XST_NAND_CACHE_ERROR 1450L /* Flash page buffer error
|
||||
*/
|
||||
|
||||
#define XST_NAND_WRITE_PROTECTED 1451L /* Flash is write protected
|
||||
*/
|
||||
|
||||
// clang-format on
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
typedef s32 XStatus;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
+2
-2
@@ -213,7 +213,7 @@ static int _is_interruptable(void)
|
||||
return !(val & DIS_INT);
|
||||
}
|
||||
|
||||
static struct XiziTrapDriver xizi_trap_driver = (struct XiziTrapDriver) {
|
||||
static struct XiziTrapDriver xizi_trap_driver = {
|
||||
.sys_irq_init = _sys_irq_init,
|
||||
|
||||
.cpu_irq_enable = _cpu_irq_enable,
|
||||
@@ -235,6 +235,6 @@ static struct XiziTrapDriver xizi_trap_driver = (struct XiziTrapDriver) {
|
||||
struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag)
|
||||
{
|
||||
xizi_trap_driver.sys_irq_init();
|
||||
xizi_trap_driver.cpu_irq_enable();
|
||||
xizi_trap_driver.cpu_irq_disable();
|
||||
return &xizi_trap_driver;
|
||||
}
|
||||
@@ -246,9 +246,9 @@ init_stack:
|
||||
bic r2, r2, #ARM_CPSR_MODE_MASK
|
||||
orr r2, r2, r0
|
||||
msr cpsr_cxsf, r2
|
||||
|
||||
# switch back to the SVC mode
|
||||
mov sp, r1
|
||||
|
||||
@ # switch back to the SVC mode
|
||||
bic r2, r2, #ARM_CPSR_MODE_MASK
|
||||
orr r2, r2, #ARM_MODE_SVC
|
||||
msr cpsr_cxsf, r2
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/**
|
||||
* @file irq_numbers.c
|
||||
* @brief irq numbers
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024.03.04
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: irq_numbers.c
|
||||
Description: irq numbers
|
||||
Others:
|
||||
History:
|
||||
1. Date: 2024-03-04
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. Add HW_NR_IRQS
|
||||
*************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "xparameters_ps.h"
|
||||
#include "xscugic_hw.h"
|
||||
|
||||
#define HW_NR_IRQS XSCUGIC_MAX_NUM_INTR_INPUTS
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/**
|
||||
* @file trap_common.c
|
||||
* @brief trap interface of hardkernel
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2023.08.25
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: trap_common.c
|
||||
Description: trap interface of hardkernel
|
||||
Others:
|
||||
History:
|
||||
1. Date: 2023-08-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. first version
|
||||
*************************************************/
|
||||
#include <string.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "trap_common.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
extern void init_stack(uint32_t, uint32_t);
|
||||
extern void user_trap_swi_enter(void);
|
||||
extern void trap_iabort(void);
|
||||
extern void trap_dabort(void);
|
||||
extern void trap_irq_enter(void);
|
||||
extern void trap_undefined_instruction(void);
|
||||
|
||||
static struct XiziTrapDriver xizi_trap_driver;
|
||||
|
||||
void panic(char* s)
|
||||
{
|
||||
xizi_trap_driver.cpu_irq_disable();
|
||||
KPrintf("panic: %s\n", s);
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
||||
/* stack for different mode*/
|
||||
static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE];
|
||||
|
||||
extern uint32_t _vector_jumper;
|
||||
extern uint32_t _vector_start;
|
||||
extern uint32_t _vector_end;
|
||||
|
||||
static XScuGic IntcInstance; /* Instance of the Interrupt Controller */
|
||||
|
||||
void init_cpu_mode_stacks(int cpu_id)
|
||||
{
|
||||
uint32_t modes[] = { ARM_MODE_FIQ, ARM_MODE_IRQ, ARM_MODE_ABT, ARM_MODE_UND };
|
||||
// initialize the stacks for different mode
|
||||
for (int i = 0; i < sizeof(modes) / sizeof(uint32_t); i++) {
|
||||
memset(mode_stack_pages[cpu_id][i], 0, MODE_STACK_SIZE);
|
||||
init_stack(modes[i], (uint32_t)mode_stack_pages[cpu_id][i]);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_reserved(void)
|
||||
{
|
||||
// unimplemented trap handler
|
||||
LOG("Unimplemented Reserved\n");
|
||||
panic("");
|
||||
}
|
||||
|
||||
void handle_fiq(void)
|
||||
{
|
||||
LOG("Unimplemented FIQ\n");
|
||||
panic("");
|
||||
}
|
||||
|
||||
static void _sys_irq_init()
|
||||
{
|
||||
/* load exception vectors */
|
||||
volatile uint32_t* vector_base = &_vector_start;
|
||||
|
||||
// Set Interrupt handler start address
|
||||
vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction
|
||||
vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt
|
||||
vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort
|
||||
vector_base[4] = (uint32_t)trap_dabort; // Data Abort
|
||||
vector_base[5] = (uint32_t)handle_reserved; // Reserved
|
||||
vector_base[6] = (uint32_t)trap_irq_enter; // IRQ
|
||||
vector_base[7] = (uint32_t)handle_fiq; // FIQ
|
||||
|
||||
init_cpu_mode_stacks(0);
|
||||
|
||||
/* active hardware irq responser */
|
||||
XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
|
||||
if (NULL == gic_config) {
|
||||
ERROR("Error while looking up gic config\n");
|
||||
return;
|
||||
}
|
||||
int gic_init_status = XScuGic_CfgInitialize(&IntcInstance, gic_config, gic_config->CpuBaseAddress);
|
||||
if (gic_init_status != XST_SUCCESS) {
|
||||
ERROR("Error initializing gic\n");
|
||||
return;
|
||||
}
|
||||
|
||||
xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper);
|
||||
}
|
||||
|
||||
static void _cpu_irq_enable(void)
|
||||
{
|
||||
// Xil_ExceptionEnable();
|
||||
arm_set_interrupt_state(true);
|
||||
}
|
||||
|
||||
static void _cpu_irq_disable(void)
|
||||
{
|
||||
// Xil_ExceptionDisable();
|
||||
arm_set_interrupt_state(false);
|
||||
}
|
||||
|
||||
static void _single_irq_enable(int irq, int cpu, int prio)
|
||||
{
|
||||
XScuGic_Enable(&IntcInstance, irq);
|
||||
}
|
||||
|
||||
static void _single_irq_disable(int irq, int cpu)
|
||||
{
|
||||
XScuGic_Disable(&IntcInstance, irq);
|
||||
}
|
||||
|
||||
#define VBAR
|
||||
static inline uint32_t* _switch_hw_irqtbl(uint32_t* new_tbl_base)
|
||||
{
|
||||
// get old irq table base addr
|
||||
uint32_t old_tbl_base = 0;
|
||||
_ARM_MRC(15, 0, old_tbl_base, 12, 0, 0);
|
||||
|
||||
// set new irq table base addr
|
||||
_ARM_MCR(15, 0, new_tbl_base, 12, 0, 0);
|
||||
|
||||
// set sctlr to use VBAR
|
||||
uint32_t sctlr = 0;
|
||||
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
|
||||
sctlr &= ~(1 << 13);
|
||||
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
|
||||
|
||||
return (uint32_t*)old_tbl_base;
|
||||
}
|
||||
|
||||
static void _bind_irq_handler(int irq, irq_handler_t handler)
|
||||
{
|
||||
xizi_trap_driver.sw_irqtbl[irq].handler = handler;
|
||||
}
|
||||
|
||||
static bool _send_sgi(uint32_t irq, uint32_t bitmask, enum SgiFilterType type)
|
||||
{
|
||||
if (bitmask > (1 << NR_CPU) - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int cpu_id = 0;
|
||||
while (bitmask != 0) {
|
||||
if ((bitmask & 0x1) != 0) {
|
||||
XScuGic_SoftwareIntr(&IntcInstance, irq, cpu_id);
|
||||
}
|
||||
cpu_id++;
|
||||
bitmask >>= 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t _hw_before_irq()
|
||||
{
|
||||
|
||||
uint32_t IntIDFull = XScuGic_CPUReadReg(&IntcInstance, XSCUGIC_INT_ACK_OFFSET);
|
||||
return IntIDFull;
|
||||
}
|
||||
|
||||
static uint32_t _hw_cur_int_num(uint32_t int_info)
|
||||
{
|
||||
return int_info & XSCUGIC_ACK_INTID_MASK;
|
||||
}
|
||||
|
||||
static uint32_t _hw_cur_int_cpu(uint32_t int_info)
|
||||
{
|
||||
return (int_info >> 5) & 0x3;
|
||||
}
|
||||
|
||||
static void _hw_after_irq(uint32_t int_info)
|
||||
{
|
||||
XScuGic_CPUWriteReg(&IntcInstance, XSCUGIC_EOI_OFFSET, int_info);
|
||||
}
|
||||
|
||||
static int _is_interruptable(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mrs %0, cpsr"
|
||||
: "=r"(val)
|
||||
:
|
||||
:);
|
||||
|
||||
return !(val & DIS_INT);
|
||||
}
|
||||
|
||||
static struct XiziTrapDriver xizi_trap_driver = {
|
||||
.sys_irq_init = _sys_irq_init,
|
||||
|
||||
.cpu_irq_enable = _cpu_irq_enable,
|
||||
.cpu_irq_disable = _cpu_irq_disable,
|
||||
.single_irq_enable = _single_irq_enable,
|
||||
.single_irq_disable = _single_irq_disable,
|
||||
.switch_hw_irqtbl = _switch_hw_irqtbl,
|
||||
|
||||
.bind_irq_handler = _bind_irq_handler,
|
||||
.send_sgi = _send_sgi,
|
||||
|
||||
.is_interruptable = _is_interruptable,
|
||||
.hw_before_irq = _hw_before_irq,
|
||||
.hw_cur_int_num = _hw_cur_int_num,
|
||||
.hw_cur_int_cpu = _hw_cur_int_cpu,
|
||||
.hw_after_irq = _hw_after_irq,
|
||||
};
|
||||
|
||||
struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag)
|
||||
{
|
||||
xizi_trap_driver.sys_irq_init();
|
||||
xizi_trap_driver.cpu_irq_enable();
|
||||
return &xizi_trap_driver;
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xil_assert.c
|
||||
*
|
||||
* This file contains basic assert related functions for Xilinx software IP.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a hbm 07/14/09 Initial release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_assert.h"
|
||||
#include "xil_types.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/**
|
||||
* This variable allows testing to be done easier with asserts. An assert
|
||||
* sets this variable such that a driver can evaluate this variable
|
||||
* to determine if an assert occurred.
|
||||
*/
|
||||
u32 Xil_AssertStatus;
|
||||
|
||||
/**
|
||||
* This variable allows the assert functionality to be changed for testing
|
||||
* such that it does not wait infinitely. Use the debugger to disable the
|
||||
* waiting during testing of asserts.
|
||||
*/
|
||||
/*s32 Xil_AssertWait = 1*/
|
||||
|
||||
/* The callback function to be invoked when an assert is taken */
|
||||
static Xil_AssertCallback Xil_AssertCallbackRoutine = NULL;
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Implement assert. Currently, it calls a user-defined callback function
|
||||
* if one has been set. Then, it potentially enters an infinite loop depending
|
||||
* on the value of the Xil_AssertWait variable.
|
||||
*
|
||||
* @param file is the name of the filename of the source
|
||||
* @param line is the linenumber within File
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void Xil_Assert(const char8* File, s32 Line)
|
||||
{
|
||||
s32 Xil_AssertWait = 1;
|
||||
/* if the callback has been set then invoke it */
|
||||
if (Xil_AssertCallbackRoutine != 0) {
|
||||
(*Xil_AssertCallbackRoutine)(File, Line);
|
||||
}
|
||||
|
||||
/* if specified, wait indefinitely such that the assert will show up
|
||||
* in testing
|
||||
*/
|
||||
while (Xil_AssertWait != 0) {
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set up a callback function to be invoked when an assert occurs. If there
|
||||
* was already a callback installed, then it is replaced.
|
||||
*
|
||||
* @param routine is the callback to be invoked when an assert is taken
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This function has no effect if NDEBUG is set
|
||||
*
|
||||
******************************************************************************/
|
||||
void Xil_AssertSetCallback(Xil_AssertCallback Routine)
|
||||
{
|
||||
Xil_AssertCallbackRoutine = Routine;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Null handler function. This follows the XInterruptHandler signature for
|
||||
* interrupt handlers. It can be used to assign a null handler (a stub) to an
|
||||
* interrupt controller vector table.
|
||||
*
|
||||
* @param NullParameter is an arbitrary void pointer and not used.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XNullHandler(void* NullParameter)
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user