1 /******************************************************************************
3 * Copyright (C) 2015 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
35 * @addtogroup ipipsu_v1_0
39 * This is the header file for implementation of IPIPSU driver.
40 * Inter Processor Interrupt (IPI) is used for communication between
41 * different processors on ZynqMP SoC. Each IPI register set has Trigger, Status
42 * and Observation registers for communication between processors. Each IPI path
43 * has a 32 byte buffer associated with it and these buffers are located in the
44 * XPPU RAM. This driver supports the following operations:
46 * - Trigger IPIs to CPUs on the SoC
47 * - Write and Read Message buffers
48 * - Read the status of Observation Register to get status of Triggered IPI
49 * - Enable/Disable IPIs from selected Masters
50 * - Read the Status register to get the source of an incoming IPI
52 * <b>Initialization</b>
53 * The config data for the driver is loaded and is based on the HW build. The
54 * XIpiPsu_Config data structure contains all the data related to the
55 * IPI driver instance and also teh available Target CPUs.
57 * <b>Sending an IPI</b>
58 * The following steps can be followed to send an IPI:
59 * - Write the Message into Message Buffer using XIpiPsu_WriteMessage()
60 * - Trigger IPI using XIpiPsu_TriggerIpi()
61 * - Wait for Ack using XIpiPsu_PollForAck()
62 * - Read response using XIpiPsu_ReadMessage()
64 * @note XIpiPsu_GetObsStatus() before sending an IPI to ensure that the
65 * previous IPI was serviced by the target
67 * <b>Receiving an IPI</b>
68 * To receive an IPI, the following sequence can be followed:
69 * - Register an interrupt handler for the IPIs interrupt ID
70 * - Enable the required sources using XIpiPsu_InterruptEnable()
71 * - In the interrupt handler, Check for source using XIpiPsu_GetInterruptStatus
72 * - Read the message form source using XIpiPsu_ReadMessage()
73 * - Write the response using XIpiPsu_WriteMessage()
74 * - Ack the IPI using XIpiPsu_ClearInterruptStatus()
76 * @note XIpiPsu_Reset can be used at startup to clear the status and
80 /*****************************************************************************/
85 /***************************** Include Files *********************************/
88 #include "xipipsu_hw.h"
90 /************************** Constant Definitions *****************************/
91 #define XIPIPSU_BUF_TYPE_MSG (0x00000001U)
92 #define XIPIPSU_BUF_TYPE_RESP (0x00000002U)
93 #define XIPIPSU_MAX_MSG_LEN XIPIPSU_MSG_BUF_SIZE
94 /**************************** Type Definitions *******************************/
96 * Data structure used to refer IPI Targets
99 u32 Mask; /**< Bit Mask for the target */
100 u32 BufferIndex; /**< Buffer Index used for calculating buffer address */
104 * This typedef contains configuration information for the device.
107 u32 DeviceId; /**< Unique ID of device */
108 u32 BaseAddress; /**< Base address of the device */
109 u32 BitMask; /**< BitMask to be used to identify this CPU */
110 u32 BufferIndex; /**< Index of the IPI Message Buffer */
111 u32 IntId; /**< Interrupt ID on GIC **/
112 u32 TargetCount; /**< Number of available IPI Targets */
113 XIpiPsu_Target TargetList[XIPIPSU_MAX_TARGETS] ; /** < List of IPI Targets */
117 * The XIpiPsu driver instance data. The user is required to allocate a
118 * variable of this type for each IPI device in the system. A pointer
119 * to a variable of this type is then passed to the driver API functions.
122 XIpiPsu_Config Config; /**< Configuration structure */
123 u32 IsReady; /**< Device is initialized and ready */
124 u32 Options; /**< Options set in the device */
127 /***************** Macros (Inline Functions) Definitions *********************/
130 * Read the register specified by the base address and offset
132 * @param BaseAddress is the base address of the IPI instance
133 * @param RegOffset is the offset of the register relative to base
135 * @return Value of the specified register
138 * u32 XIpiPsu_ReadReg(u32 BaseAddress, u32 RegOffset)
140 *****************************************************************************/
142 #define XIpiPsu_ReadReg(BaseAddress, RegOffset) \
143 Xil_In32((BaseAddress) + (RegOffset))
145 /****************************************************************************/
148 * Write a value into a register specified by base address and offset
150 * @param BaseAddress is the base address of the IPI instance
151 * @param RegOffset is the offset of the register relative to base
152 * @param Data is a 32-bit value that is to be written into the specified register
156 * void XIpiPsu_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
158 *****************************************************************************/
160 #define XIpiPsu_WriteReg(BaseAddress, RegOffset, Data) \
161 Xil_Out32(((BaseAddress) + (RegOffset)), (Data))
163 /****************************************************************************/
166 * Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
167 * each bit set to 1 in <i>Mask</i>, will be enabled.
169 * @param InstancePtr is a pointer to the instance to be worked on.
170 * @param Mask contains a bit mask of interrupts to enable. The mask can
171 * be formed using a set of bitwise or'd values of individual CPU masks
175 * void XIpiPsu_InterruptEnable(XIpiPsu *InstancePtr, u32 Mask)
177 *****************************************************************************/
178 #define XIpiPsu_InterruptEnable(InstancePtr, Mask) \
179 XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
180 XIPIPSU_IER_OFFSET, \
181 ((Mask) & XIPIPSU_ALL_MASK));
183 /****************************************************************************/
186 * Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
187 * each bit set to 1 in <i>Mask</i>, will be disabled.
189 * @param InstancePtr is a pointer to the instance to be worked on.
190 * @param Mask contains a bit mask of interrupts to disable. The mask can
191 * be formed using a set of bitwise or'd values of individual CPU masks
195 * void XIpiPsu_InterruptDisable(XIpiPsu *InstancePtr, u32 Mask)
197 *****************************************************************************/
198 #define XIpiPsu_InterruptDisable(InstancePtr, Mask) \
199 XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
200 XIPIPSU_IDR_OFFSET, \
201 ((Mask) & XIPIPSU_ALL_MASK));
202 /****************************************************************************/
205 * Get the <i>STATUS REGISTER</i> of the current IPI instance.
207 * @param InstancePtr is a pointer to the instance to be worked on.
208 * @return Returns the Interrupt Status register(ISR) contents
209 * @note User needs to parse this 32-bit value to check the source CPU
211 * u32 XIpiPsu_GetInterruptStatus(XIpiPsu *InstancePtr)
213 *****************************************************************************/
214 #define XIpiPsu_GetInterruptStatus(InstancePtr) \
215 XIpiPsu_ReadReg((InstancePtr)->Config.BaseAddress, \
217 /****************************************************************************/
220 * Clear the <i>STATUS REGISTER</i> of the current IPI instance.
221 * The corresponding interrupt status for
222 * each bit set to 1 in <i>Mask</i>, will be cleared
224 * @param InstancePtr is a pointer to the instance to be worked on.
225 * @param Mask corresponding to the source CPU*
227 * @note This function should be used after handling the IPI.
228 * Clearing the status will automatically clear the corresponding bit in
229 * OBSERVATION register of Source CPU
231 * void XIpiPsu_ClearInterruptStatus(XIpiPsu *InstancePtr, u32 Mask)
233 *****************************************************************************/
235 #define XIpiPsu_ClearInterruptStatus(InstancePtr, Mask) \
236 XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
237 XIPIPSU_ISR_OFFSET, \
238 ((Mask) & XIPIPSU_ALL_MASK));
239 /****************************************************************************/
242 * Get the <i>OBSERVATION REGISTER</i> of the current IPI instance.
244 * @param InstancePtr is a pointer to the instance to be worked on.
245 * @return Returns the Observation register(OBS) contents
246 * @note User needs to parse this 32-bit value to check the status of
249 * u32 XIpiPsu_GetObsStatus(XIpiPsu *InstancePtr)
251 *****************************************************************************/
252 #define XIpiPsu_GetObsStatus(InstancePtr) \
253 XIpiPsu_ReadReg((InstancePtr)->Config.BaseAddress, \
255 /****************************************************************************/
256 /************************** Function Prototypes *****************************/
258 /* Static lookup function implemented in xipipsu_sinit.c */
260 XIpiPsu_Config *XIpiPsu_LookupConfig(u32 DeviceId);
262 /* Interface Functions implemented in xipipsu.c */
264 XStatus XIpiPsu_CfgInitialize(XIpiPsu *InstancePtr, XIpiPsu_Config * CfgPtr,
265 UINTPTR EffectiveAddress);
267 void XIpiPsu_Reset(XIpiPsu *InstancePtr);
269 XStatus XIpiPsu_TriggerIpi(XIpiPsu *InstancePtr, u32 DestCpuMask);
271 XStatus XIpiPsu_PollForAck(XIpiPsu *InstancePtr, u32 DestCpuMask,
274 XStatus XIpiPsu_ReadMessage(XIpiPsu *InstancePtr, u32 SrcCpuMask, u32 *MsgPtr,
275 u32 MsgLength, u8 BufType);
277 XStatus XIpiPsu_WriteMessage(XIpiPsu *InstancePtr, u32 DestCpuMask, u32 *MsgPtr,
278 u32 MsgLength, u8 BufType);
280 #endif /* XIPIPSU_H_ */