diff options
Diffstat (limited to 'embeddedsw/XilinxProcessorIPLib/drivers/scugic/src/xscugic.h')
-rw-r--r-- | embeddedsw/XilinxProcessorIPLib/drivers/scugic/src/xscugic.h | 601 |
1 files changed, 601 insertions, 0 deletions
diff --git a/embeddedsw/XilinxProcessorIPLib/drivers/scugic/src/xscugic.h b/embeddedsw/XilinxProcessorIPLib/drivers/scugic/src/xscugic.h new file mode 100644 index 0000000..28043f6 --- /dev/null +++ b/embeddedsw/XilinxProcessorIPLib/drivers/scugic/src/xscugic.h @@ -0,0 +1,601 @@ +/****************************************************************************** +* Copyright (C) 2010 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xscugic.h +* @addtogroup scugic_v4_7 +* @{ +* @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. +* 3.2 asa 02/29/16 Modified DistributorInit function for Zynq AMP case. The +* distributor is left uninitialized for Zynq AMP. It is assumed +* that the distributor will be initialized by Linux master. However +* for CortexR5 case, the earlier code is left unchanged where the +* the interrupt processor target registers in the distributor is +* initialized with the corresponding CPU ID on which the application +* built over the scugic driver runs. +* These changes fix CR#937243. +* +* 3.4 asa 04/07/16 Created a new static function DoDistributorInit to simplify +* the flow and avoid code duplication. Changes are made for +* USE_AMP use case for R5. In a scenario (in R5 split mode) when +* one R5 is operating with A53 in open amp config and other +* R5 running baremetal app, the existing code +* had the potential to stop the whole AMP solution to work (if +* for some reason the R5 running the baremetal app tasked to +* initialize the Distributor hangs or crashes before initializing). +* Changes are made so that the R5 under AMP first checks if +* the distributor is enabled or not and if not, it does the +* standard Distributor initialization. +* This fixes the CR#952962. +* 3.6 ms 01/23/17 Modified xil_printf statement in main function for all +* examples to ensure that "Successfully ran" and "Failed" +* strings are available in all examples. This is a fix +* for CR-965028. +* kvn 02/17/17 Add support for changing GIC CPU master at run time. +* kvn 02/28/17 Make the CpuId as static variable and Added new +* XScugiC_GetCpuId to access CpuId. +* ms 03/17/17 Added readme.txt file in examples folder for doxygen +* generation. +* 3.7 ms 04/11/17 Modified tcl file to add suffix U for all macro +* definitions of scugic in xparameters.h +* 3.8 mus 07/05/17 Updated scugic.tcl to add support for interrupts connected +* through util_reduced_vector IP(OR gate) +* mus 07/05/17 Updated xdefine_zynq_canonical_xpars proc to initialize +* the HandlerTable in XScuGic_ConfigTable to 0, it removes +* the compilation warning in xscugic_g.c. Fix for CR#978736. +* mus 07/25/17 Updated xdefine_gic_params proc to export correct canonical +* definitions for pl to ps interrupts.Fix for CR#980534 +* 3.9 mus 02/21/18 Added new API's XScuGic_UnmapAllInterruptsFromCpu and +* XScuGic_InterruptUnmapFromCpu, These API's can be used +* by applications to unmap specific/all interrupts from +* target CPU. +* 3.10 aru 08/23/18 Resolved MISRA-C:2012 compliance mandatory violations +* 4.0 mus 11/22/18 Fixed bugs in software interrupt generation through +* XScuGic_SoftwareIntr API +* 4.1 asa 03/30/19 Made changes not to direct each interrupt to all +* available CPUs by default. This was breaking AMP +* behavior. Instead every time an interrupt enable +* request is received, the interrupt was mapped to +* the respective CPU. There were several other changes +* made to implement this. This set of changes was to +* fix CR-1024716. +* 4.1 mus 06/19/19 Added API's XScuGic_MarkCoreAsleep and +* XScuGic_MarkCoreAwake to mark processor core as +* asleep or awake. Fix for CR#1027220. +* 4.5 asa 03/07/21 Included a header file xil_spinlock.h to ensure that +* GIC driver can use newly introduced spinlock +* functionality. +* 4.6 sk 08/05/21 Fix scugic misrac violations. +* 4.7 dp 11/22/21 Added new API XScuGic_IsInitialized() to check and return +* the GIC initialization status. +* +* </pre> +* +******************************************************************************/ + +#ifndef XSCUGIC_H /* prevent circular inclusions */ +#define XSCUGIC_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + +#include "xstatus.h" +#include "xil_io.h" +#include "xscugic_hw.h" +#include "xil_exception.h" +#include "xil_spinlock.h" + +/************************** Constant Definitions *****************************/ + +#define EFUSE_STATUS_OFFSET 0x10 +#define EFUSE_STATUS_CPU_MASK 0x80 + +#if !defined (ARMR5) && !defined (__aarch64__) && !defined (ARMA53_32) +#define ARMA9 +#endif + +#define XSCUGIC500_DCTLR_ARE_NS_ENABLE 0x20 +#define XSCUGIC500_DCTLR_ARE_S_ENABLE 0x10 +/**************************** 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; + +/************************** Variable Definitions *****************************/ + +extern XScuGic_Config XScuGic_ConfigTable[]; /**< Config table */ + +/***************** 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))) + +/****************************************************************************/ +/** +* +* Write the given ReDistributor 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_ReDistWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_OFFSET, (RegOffset), ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given ReDistributor 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_ReDistReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg((((InstancePtr)->Config->DistBaseAddress)+ \ +XSCUGIC_RDIST_OFFSET), (RegOffset))) + +/****************************************************************************/ +/** +* +* Write the given ReDistributor SGI PPI 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_ReDistSGIPPIWriteReg(InstancePtr, RegOffset, Data) \ +(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_SGI_PPI_OFFSET, (RegOffset), ((u32)(Data)))) + +/****************************************************************************/ +/** +* +* Read the given ReDistributor SGI PPI 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_ReDistSGIPPIReadReg(InstancePtr, RegOffset) \ +(XScuGic_ReadReg((((InstancePtr)->Config->DistBaseAddress)+ \ + XSCUGIC_RDIST_SGI_PPI_OFFSET), (RegOffset))) + +/****************************************************************************/ +/** +* This function enables system register interface for GIC CPU Interface +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Enable_SystemReg_CPU_Interface_EL3() mtcp(S3_6_C12_C12_5, 0xF); +#define XScuGic_Enable_SystemReg_CPU_Interface_EL1() mtcp(S3_0_C12_C12_5, 0xF); +/****************************************************************************/ +/** +* This function enables Grou0 interrupts +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Enable_Group0_Interrupts() mtcp(S3_0_C12_C12_6,0x1); +/****************************************************************************/ +/** +* This function enables Group1 interrupts +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL1_NONSECURE +#define XScuGic_Enable_Group1_Interrupts() \ + mtcp (S3_0_C12_C12_7, 0x1 | mfcp(S3_0_C12_C12_7) ); +#else +#define XScuGic_Enable_Group1_Interrupts() \ + mtcp (S3_6_C12_C12_7, 0x1 | mfcp(S3_6_C12_C12_7) ); +#endif +#endif +/****************************************************************************/ +/** +* This function writes to ICC_SGI0R_EL1 +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_WriteICC_SGI0R_EL1(val) mtcp(S3_0_C12_C11_7,val) + +/****************************************************************************/ +/** +* This function writes to ICC_SGI1R_EL1 +* +* @param value to be written +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_WriteICC_SGI1R_EL1(val) mtcp(S3_0_C12_C11_5,val) + +/****************************************************************************/ +/** +* This function reads ICC_SGI1R_EL1 register +* +* @param None +* +* @return Value of ICC_SGI1R_EL1 register +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_ReadICC_SGI1R_EL1() mfcp(S3_0_C12_C11_5) +/****************************************************************************/ +/** +* This function sets interrupt priority filter +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_set_priority_filter(val) __asm__ __volatile__("msr S3_0_C4_C6_0,%0" : : "r" (val)) +/****************************************************************************/ +/** +* This function returns interrupt id of highest priority pending interrupt +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL3 +#define XScuGic_get_IntID() mfcp(S3_0_C12_C8_0) +#else +#define XScuGic_get_IntID() mfcp(S3_0_C12_C12_0) +#endif +#endif +/****************************************************************************/ +/** +* This function acks the interrupt +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#if defined (__aarch64__) +#if EL3 +#define XScuGic_ack_Int(val) mtcp(S3_0_C12_C8_1,val) +#else +#define XScuGic_ack_Int(val) mtcp(S3_0_C12_C12_1,val) +#endif +#endif +/****************************************************************************/ +/** +* This macro returns bit position for the specific interrupt's trigger type +* configuration within GICR_ICFGR0/GICR_ICFGR1 register +* +* @param None. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +#define XScuGic_Get_Rdist_Int_Trigger_Index(IntrId) (((Int_Id%16) & 0x1f) << 2) +1 +/************************** 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_Identifier); + +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_Identifier, u32 Int_Id); +void XScuGic_InterruptUnmapFromCpu(XScuGic *InstancePtr, u8 Cpu_Identifier, u32 Int_Id); +void XScuGic_UnmapAllInterruptsFromCpu(XScuGic *InstancePtr, u8 Cpu_Identifier); +void XScuGic_Stop(XScuGic *InstancePtr); +void XScuGic_SetCpuID(u32 CpuCoreId); +u32 XScuGic_GetCpuID(void); +u8 XScuGic_IsInitialized(u32 DeviceId); +/* + * Initialization functions in xscugic_sinit.c + */ +XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId); +XScuGic_Config *XScuGic_LookupConfigBaseAddr(UINTPTR BaseAddress); + +/* + * Interrupt functions in xscugic_intr.c + */ +void XScuGic_InterruptHandler(XScuGic *InstancePtr); + +/* + * Self-test functions in xscugic_selftest.c + */ +s32 XScuGic_SelfTest(XScuGic *InstancePtr); + +#if defined (GICv3) +void XScuGic_MarkCoreAsleep(XScuGic *InstancePtr); +void XScuGic_MarkCoreAwake(XScuGic *InstancePtr); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** @} */ |