📄 xscugic.c
字号:
/******************************************************************************** (c) Copyright 2010-2011 Xilinx, Inc. All rights reserved.** This file contains confidential and proprietary information of Xilinx, Inc.* and is protected under U.S. and international copyright and other* intellectual property laws.** DISCLAIMER* This disclaimer is not a license and does not grant any rights to the* materials distributed herewith. Except as otherwise provided in a valid* license issued to you by Xilinx, and to the maximum extent permitted by* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;* and (2) Xilinx shall not be liable (whether in contract or tort, including* negligence, or under any other theory of liability) for any loss or damage* of any kind or nature related to, arising under or in connection with these* materials, including for any direct, or any indirect, special, incidental,* or consequential loss or damage (including loss of data, profits, goodwill,* or any type of loss or damage suffered as a result of any action brought by* a third party) even if such damage or loss was reasonably foreseeable or* Xilinx had been advised of the possibility of the same.** CRITICAL APPLICATIONS* Xilinx products are not designed or intended to be fail-safe, or for use in* any application requiring fail-safe performance, such as life-support or* safety devices or systems, Class III medical devices, nuclear facilities,* applications related to the deployment of airbags, or any other applications* that could lead to death, personal injury, or severe property or* environmental damage (individually and collectively, "Critical* Applications"). Customer assumes the sole risk and liability of any use of* Xilinx products in Critical Applications, subject only to applicable laws* and regulations governing limitations on product liability.** THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE* AT ALL TIMES.*******************************************************************************//*****************************************************************************//**** @file xscugic.c** 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.* </pre>*******************************************************************************//***************************** Include Files *********************************/#include "xil_types.h"#include "xil_assert.h"#include "xscugic.h"/************************** Constant Definitions *****************************//**************************** Type Definitions *******************************//***************** Macros (Inline Functions) Definitions *********************/#define XSCUGIC_INT_CFG_OFFSET_CALC(InterruptID) \ (XSCUGIC_INT_CFG_OFFSET + ((InterruptID/16) * 4))#define XSCUGIC_PRIORITY_OFFSET_CALC(InterruptID) \ (XSCUGIC_PRIORITY_OFFSET + ((InterruptID/4) * 4))#define XSCUGIC_SPI_TARGET_OFFSET_CALC(InterruptID) \ (XSCUGIC_SPI_TARGET_OFFSET + ((InterruptID/4) * 4))#define XSCUGIC_ENABLE_DISABLE_OFFSET_CALC(Register, InterruptID) \ (Register + ((InterruptID/32) * 4))/************************** Variable Definitions *****************************//************************** Function Prototypes ******************************/static void StubHandler(void *CallBackRef);/*****************************************************************************//**** 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 *InstancePtr, u32 CpuID){ u32 Int_Id;#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_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0UL); /* * 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 = 32; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id+=16) { /* * 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), 0UL); }#define DEFAULT_PRIORITY 0xa0a0a0a0UL for (Int_Id = 0; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id+=4) { /* * 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 = 32; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=4) { /* * 3. The CPU interface in the spi_target register * Only write to the SPI interrupts, so start at 32 */ CpuID |= CpuID << 8; CpuID |= CpuID << 16; XScuGic_DistWriteReg(InstancePtr, XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), CpuID); } for (Int_Id = 0; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=32) { /* * 4. Enable the SPI using the enable_set register. Leave all * disabled for now. */ XScuGic_DistWriteReg(InstancePtr, XSCUGIC_ENABLE_DISABLE_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, Int_Id), 0xFFFFFFFFUL); } XScuGic_DistWriteReg(InstancePtr, 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 InstancePtr is a pointer to the XScuGic instance.** @return None** @note None.*******************************************************************************/static void CPUInit(XScuGic *InstancePtr){ /* * Program the priority mask of the CPU using the Priority mask register */ XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CPU_PRIOR_OFFSET, 0xF0); /* * 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, 0x07);}/*****************************************************************************//**** 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.*******************************************************************************/int XScuGic_CfgInitialize(XScuGic *InstancePtr, XScuGic_Config *ConfigPtr, u32 EffectiveAddr){ u32 Int_Id; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(ConfigPtr != NULL); /* * Set some default values */ InstancePtr->IsReady = 0; InstancePtr->Config = ConfigPtr; for (Int_Id = 0; 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 == 0)) { InstancePtr->Config->HandlerTable[Int_Id].Handler = StubHandler; } InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr; } DistInit(InstancePtr, 0x01); CPUInit(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.*****************************************************************************/int 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -