source: trunk/hal/tsar_mips32/drivers/soclib_pic.h @ 188

Last change on this file since 188 was 188, checked in by alain, 5 years ago

Redefine the PIC device API.

File size: 15.1 KB
Line 
1/*
2 * soclib_pic.c - soclib PIC driver definition.
3 *
4 * Author  Alain Greiner (2016,2017)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#ifndef _SOCLIB_PIC_H_
25#define _SOCLIB_PIC_H_
26
27#include <hal_types.h>
28
29/****  Forward declarations  ****/
30
31struct chdev_s;
32
33/*****************************************************************************************
34 * This file defines the driver for the SOCLIB PIC device.
35 *
36 * The SOCLIB PIC infrastructure contains two types of components:
37 *
38 * - The IOPIC external controller handles the external IRQs generated by the external
39 *   peripherals. The IOPIC controller provides two services:
40 *   1) It translate each IRQ hardware signal to a write transactions to a specific
41 *      mailbox, for a given core in a giveb cluster, as explained below.
42 *   2) It  allows the kernel to selectively enable/disable any external IRQ
43 *      identified by its index.
44 *
45 * - The XCU internal controller implement the generic local interrupt controller
46 *   (LAPIC), replicated in all clusters containing at  least one core.
47 *   In each cluster, it concentrates all IRQs destinated to one given core,
48 *   and helps the interrupt handler to select the ISR (Interrupt Service Routine)
49 *   that must be executed by the target core. It defines three types of IRQs:
50 *   1) HWI : The HardWare Interrupts are generated by local internal peripherals.
51 *      They are connected to the local XCU, to be routed to a given local core.
52 *   2) WTI : The Write Triggered Interrupts are actually mailboxes implemented in the
53 *      local XCU. They are used to implement software IPIs (Inter-Processor-Interrupts),
54 *      or to register the write transactions generated by the IOPIC controller.
55 *   3) PTI : The Programmable Timer Interrupts are actually timers generating periodic
56 *      interrupts controled by softare, contained in the local XCU, and routed to
57 *      a local core.
58 *   The numbers of interrupts of each type in a given cluster are defined in the
59 *   XCU_CONFIG register of the XCU component, and cannot be larger than the
60 *   SOCLIB_MAX_HWI, SOCLIB_MAX_WTI, SOCLIB_MAX_PTI constants defined below.
61 *   The XCU controller provides three main services:
62 *   1) It allows the kernel to selectively enable/disable any IRQ (identified by its type
63 *      and index) for a given core. It is the kernel responsibility to enable a given IRQ
64 *      for a single core as a given IRQ event should be handled by only one core.
65 *   2) It makes a global OR between all enabled IRQs for a given core, to interrupt
66 *      the core when at least one enabled IRQ is active.
67 *   3) It is capable to return the highest priority active IRQ of each type.
68 *      For each type, the lowest index have the highest priority.
69 *
70 * To select the ISR to be executed for a given HWI or WTI interrupt, the SOCLIB PIC
71 * infrastructure implements for each core two interrupts vectors, called hwi_vector[]
72 * and wti_vector[].  Each entry contains a pointer on the local chdev descriptor that
73 * is the "source" of the interrupt, and contains itself a link to the ISR to be executed.
74 * These interrupt vectors are stored in the core descriptor extension.
75 * For the PTI interrupts, there is one PTI per core, and the ISR is simply defined
76 * by the soclib_pic_timer_isr() function.
77 *
78 * There is no specific chdev to describe the current state of a given XCU controller.
79 * To store the informations attached to a given XCU (namely the WTI allocator), the
80 * SOCLIB PIC implementation attach a specific PIC extension to the cluster manager,
81 * called XCU descriptor.
82 *****************************************************************************************/
83
84#define SOCLIB_TYPE_HWI        0
85#define SOCLIB_TYPE_WTI        1
86#define SOCLIB_TYPE_PTI        2
87
88#define SOCLIB_MAX_HWI         16
89#define SOCLIB_MAX_WTI         16
90#define SOCLIB_MAX_PTI         16
91
92/******************************************************************************************
93 * This define the registers offsets for the  external SOCLIB_IOPIC component.
94 * There is 4 addressable registers for each external input IRQ.
95 *****************************************************************************************/
96
97#define IOPIC_ADDRESS          0
98#define IOPIC_EXTEND           1
99#define IOPIC_STATUS           2
100#define IOPIC_MASK             3
101
102#define IOPIC_SPAN             4
103
104/******************************************************************************************
105 * This define the registers offsets for the internal SOCLIB_XCU components.
106 * There is an XCU component in each cluster.
107 *****************************************************************************************/
108
109#define XCU_WTI_REG            0
110#define XCU_PTI_PER            1
111#define XCU_PTI_VAL            2
112#define XCU_PTI_ACK            3
113#define XCU_MSK_PTI            4
114#define XCU_MSK_PTI_ENABLE     5
115#define XCU_MSK_PTI_DISABLE    6
116#define XCU_PTI_ACTIVE         6
117#define XCU_MSK_HWI            8
118#define XCU_MSK_HWI_ENABLE     9
119#define XCU_MSK_HWI_DISABLE    10
120#define XCU_HWI_ACTIVE         10
121#define XCU_MSK_WTI            12
122#define XCU_MSK_WTI_ENABLE     13
123#define XCU_MSK_WTI_DISABLE    14
124#define XCU_WTI_ACTIVE         14
125#define XCU_PRIO               15
126#define XCU_CONFIG             16
127
128/******************************************************************************************
129 * This structure defines the core descriptor extension used by the SOCLIB PIC
130 * implementation to store the two HWI / WTI interrupts vectors in the core descriptor.
131 * Each entry contains a local pointer on the chdev that is the source of the IRQ.
132 * A non allocated entry contains the NULL value.
133 *****************************************************************************************/
134
135typedef struct soclib_pic_core_s
136{
137    struct chdev_s * hwi_vector[SOCLIB_MAX_HWI];
138    struct chdev_s * wti_vector[SOCLIB_MAX_WTI];
139}
140soclib_pic_core_t;
141
142/******************************************************************************************
143 * This structure defines the cluster manager extension used by the SOCLIB PIC
144 * implementation to register the local XCU base address, the number of HWI/WTI/PTI,
145 * and the WTI allocator. The WTI allocator is very simple, because an allocated WTI
146 * mailbox is never released.
147 *****************************************************************************************/
148
149typedef struct soclib_pic_cluster_s
150{
151    uint32_t * xcu_base;           /*! local pointer on xcu segment base                 */
152    uint32_t   hwi_nr;             /*! actual number of HWI inputs in XCU                */
153    uint32_t   wti_nr;             /*! actual number of HWI inputs in XCU                */
154    uint32_t   pti_nr;             /*! actual number of HWI inputs in XCU                */
155    uint32_t   first_free_wti;     /*! simple allocator : first free WTI slot index      */
156}
157soclib_pic_cluster_t;
158
159
160
161
162/******************************************************************************************
163 *                      Generic PIC API
164 *****************************************************************************************/
165
166/******************************************************************************************
167 * This blocking function disables all input IRQs in the IOPIC controller, and
168 * disables all HWIs, WTIs, and PTIs in the XCU (LAPIC) controllers, for all cores,
169 * in all clusters.
170 * It must be called by a thread running in the cluster containing the PIC chdev.
171******************************************************************************************
172 * @ chdev    : pointer on PIC chdev descriptor.
173 *****************************************************************************************/
174void   soclib_pic_init( chdev_t * pic );
175
176/*****************************************************************************************
177 * This function allocates memory from local cluster for the SOCLIB PIC core extensions
178 * of all cores contained in the cluster, initializes the two HWI, WTI interrupt vectors
179 * as empty, and registers - for each core - the pointer in core descriptor.
180 * Then it allocates memory from local cluster for the SOCLIB PIC cluster extension,
181 * to implement the XCU WTI allocator, and registers the pointer in cluster manager.
182 * It access the local XCU component to get actual number of HWI / WTI / PTI.
183 *****************************************************************************************
184 * @ xcu_base  : local pointer on XCU controller segment base.
185 ****************************************************************************************/
186void soclib_pic_extend_init( uint32_t * xcu_base );
187
188/******************************************************************************************
189 * This function configure the PIC device to route the IRQ generated by a local chdev,
190 * defined by the <src_chdev> argument, to a local core identified by the <lid> argument.
191 * If the source chdev is external (IOC, TXT, NIC, IOB):
192 * - it get a WTI mailbox from the XCU.
193 * - it enables this WTI in XCU.
194 * - it updates the target core WTI interrupt vector.
195 * - it link the WTI to the relevant input IRQ in IOPIC.
196 * If the source chdev is internal (MMC, DMA):
197 * - it enables the HWI in XCU.
198 * - it updates the target core HWI interrupt vector.
199 * It must be called by a thread running in local cluster.
200 ******************************************************************************************
201 * @ lid        : target core local index.
202 * @ src_chdev  : local pointer on source chdev descriptor.
203 *****************************************************************************************/
204void soclib_pic_bind_irq( lid_t     lid,
205                          chdev_t * src_chdev );
206
207/******************************************************************************************
208 * This function enable a HWI/WTI IRQ identified by the <src_chdev> argument,
209 * that contains information on the IRQ type (HWI/WTI), and IRQ index.
210 * It access the relevant XCU mask register, but does not access IOPIC.
211 ******************************************************************************************
212 * @ lid        : target core local index.
213 * @ src_chdev  : local pointer on source chdev descriptor.
214 *****************************************************************************************/
215void soclib_pic_enable_irq( lid_t     lid,
216                            chdev_t * src_chdev );
217
218/******************************************************************************************
219 * This function disable a HWI/WTI IRQ identified by the <src_chdev> argument,
220 * that contains information on the IRQ type (HWI/WTI), and IRQ index.
221 * It access the relevant XCU mask register, but does not access IOPIC.
222 ******************************************************************************************
223 * @ lid        : target core local index.
224 * @ src_chdev  : local pointer on source chdev descriptor.
225 *****************************************************************************************/
226void soclib_pic_disable_irq( lid_t     lid,
227                             chdev_t * src_chdev );
228
229/******************************************************************************************
230 * This function activates the TICK timer for the calling core.
231 * The <period> argument define the number of cycles between IRQs.
232 ******************************************************************************************
233 * @ period      : number of cycles between IRQs.
234 *****************************************************************************************/
235void soclib_pic_enable_timer( uint32_t period );
236
237/******************************************************************************************
238 * This function allows the calling thread to send an IPI to any core in any cluster.
239 * It can be called by any thread running on any cluster.
240 ******************************************************************************************
241 * @ cxy        : target core cluster.
242 * @ lid        : target core local index.
243 *****************************************************************************************/
244void soclib_pic_send_ipi( cxy_t    cxy,
245                          lid_t    lid );
246
247
248
249
250
251
252/******************************************************************************************
253 *                    Private PIC API for TSAR.
254 *****************************************************************************************/
255
256/******************************************************************************************
257 * This function returns the first free WTI mailbox from the XCU descriptor.
258 * cluster extension containing the current XCU state. It does not access the
259 * hardware XCU component. This WTI allocator is very simple, because an allocated
260 * WTI is never released. The first WTIs are preallocated for IPI (wpi_id == lid).
261 * This allocator does not use a lock, because there is no risk of concurrent access.
262 * If there is no free slot, it means that the total number of external IRQs is too
263 * large for the number of cores in the architecture, and the core goes to sleep.
264 *****************************************************************************************/
265uint32_t soclib_pic_wti_alloc();
266
267/******************************************************************************************
268 * This function returns a local pointer on the local XCU base segment.
269 *****************************************************************************************/
270uint32_t * soclib_pic_xcu_base();
271
272/******************************************************************************************
273 * This function acknowledge a PTI IRQ generated by the local XCU for a core
274 * identified by the <lid> argument.
275 *****************************************************************************************/
276uint32_t soclib_pic_ack_timer( lid_t lid );
277
278/******************************************************************************************
279 * This function returns in the <hwi_status>, <wti_status>, <pti_status> buffers
280 * the local XCU status for a given core identidied by the <lid> argument.
281 *****************************************************************************************/
282void soclib_pic_xcu_status( lid_t      lid,
283                            uint32_t * hwi_status,
284                            uint32_t * wti_status,
285                            uint32_t * pti_status );
286
287/******************************************************************************************
288 * This SOCLIB PIC specific is the call-back function is the interrupt handler.
289 *****************************************************************************************/
290void soclip_pic_irq_handler();
291
292
293
294
295
296
297
298#endif  /* _SOCLIB_PIC_H_ */
Note: See TracBrowser for help on using the repository browser.