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

Last change on this file since 451 was 451, checked in by alain, 3 years ago

Fix a bug in soclib_pic driver (bad separation between IOPIC an LAPIC initialisation)

File size: 16.2 KB
Line 
1/*
2 * soclib_pic.h - 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_kernel_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#define SOCLIB_CYCLES_PER_MS   60    // SystemC virtual prototype at 60 KHz
93
94/******************************************************************************************
95 * This define the registers offsets for the  external SOCLIB_IOPIC component.
96 * There is 4 addressable registers for each external input IRQ.
97 *****************************************************************************************/
98
99#define IOPIC_ADDRESS          0
100#define IOPIC_EXTEND           1
101#define IOPIC_STATUS           2
102#define IOPIC_MASK             3
103
104#define IOPIC_SPAN             4
105
106/******************************************************************************************
107 * This define the registers offsets for the internal SOCLIB_XCU components.
108 * There is an XCU component in each cluster.
109 *****************************************************************************************/
110
111#define XCU_WTI_REG            0
112#define XCU_PTI_PER            1
113#define XCU_PTI_VAL            2
114#define XCU_PTI_ACK            3
115#define XCU_MSK_PTI            4
116#define XCU_MSK_PTI_ENABLE     5
117#define XCU_MSK_PTI_DISABLE    6
118#define XCU_PTI_ACTIVE         6
119#define XCU_MSK_HWI            8
120#define XCU_MSK_HWI_ENABLE     9
121#define XCU_MSK_HWI_DISABLE    10
122#define XCU_HWI_ACTIVE         10
123#define XCU_MSK_WTI            12
124#define XCU_MSK_WTI_ENABLE     13
125#define XCU_MSK_WTI_DISABLE    14
126#define XCU_WTI_ACTIVE         14
127#define XCU_PRIO               15
128#define XCU_CONFIG             16
129
130/******************************************************************************************
131 * This structure defines the core descriptor extension used by the SOCLIB PIC
132 * implementation to store the two HWI / WTI interrupts vectors in the core descriptor.
133 * Each entry contains a local pointer on the chdev that is the source of the IRQ.
134 * A non allocated entry contains the NULL value.
135 *****************************************************************************************/
136
137typedef struct soclib_pic_core_s
138{
139    struct chdev_s * hwi_vector[SOCLIB_MAX_HWI];    /* HWI interrupt vector             */
140    struct chdev_s * wti_vector[SOCLIB_MAX_WTI];    /* WTI interrupt vector             */
141}
142soclib_pic_core_t;
143
144/******************************************************************************************
145 * This structure defines the cluster manager extension used by the SOCLIB PIC
146 * implementation to register the local XCU base address, the number of HWI/WTI/PTI,
147 * and the WTI allocator. The WTI allocator is very simple, because an allocated WTI
148 * mailbox is never released.
149 *****************************************************************************************/
150
151typedef struct soclib_pic_cluster_s
152{
153    uint32_t * xcu_base;           /*! local pointer on xcu segment base                 */
154    uint32_t   hwi_nr;             /*! actual number of HWI inputs in XCU                */
155    uint32_t   wti_nr;             /*! actual number of HWI inputs in XCU                */
156    uint32_t   pti_nr;             /*! actual number of HWI inputs in XCU                */
157    uint32_t   first_free_wti;     /*! simple allocator : first free WTI slot index      */
158}
159soclib_pic_cluster_t;
160
161
162
163
164/******************************************************************************************
165 *                      Generic PIC API
166 *****************************************************************************************/
167
168/******************************************************************************************
169 * This function disables all input IRQs in the external IOPIC controller.
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( struct chdev_s * pic );
175
176/*****************************************************************************************
177 * This function allocates memory from local cluster for the local 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 PIC cluster extension,
181 * and registers the pointer in cluster manager.
182 * It accesses the local XCU component to get actual number of HWI / WTI / PTI.
183 * Finally, it disables all HWI/WTI/PTI interrupts for all cores by writing in the
184 * relevant mask registers of the local XCU component.
185 *****************************************************************************************
186 * @ xcu_base  : local pointer on XCU controller segment base.
187 ****************************************************************************************/
188void soclib_pic_extend_init( uint32_t * xcu_base );
189
190/******************************************************************************************
191 * This function configure the PIC device to route the IRQ generated by a local chdev,
192 * defined by the <src_chdev> argument, to a local core identified by the <lid> argument.
193 * If the source chdev is external (IOC, TXT, NIC, IOB):
194 * - it get a WTI mailbox from the XCU.
195 * - it enables this WTI in XCU.
196 * - it updates the target core WTI interrupt vector.
197 * - it link the WTI to the relevant input IRQ in IOPIC.
198 * If the source chdev is internal (MMC, DMA):
199 * - it enables the HWI in XCU.
200 * - it updates the target core HWI interrupt vector.
201 * It must be called by a thread running in local cluster.
202 ******************************************************************************************
203 * @ lid        : target core local index.
204 * @ src_chdev  : local pointer on source chdev descriptor.
205 *****************************************************************************************/
206void soclib_pic_bind_irq( lid_t            lid,
207                          struct chdev_s * src_chdev );
208
209/******************************************************************************************
210 * This function enables a remote HWI/WTI IRQ, identified by the <src_chdev_xp> argument,
211 * that contains information on the IRQ type (HWI/WTI), and IRQ index.
212 * It access the remote XCU mask register, but does not access IOPIC.
213 ******************************************************************************************
214 * @ lid           : target core local index (in cluster containing the source chdev).
215 * @ src_chdev_xp  : extended pointer on source chdev descriptor.
216 *****************************************************************************************/
217void soclib_pic_enable_irq( lid_t   lid,
218                            xptr_t  src_chdev_xp );
219
220/******************************************************************************************
221 * This function disables a remote HWI/WTI IRQ, identified by the <src_chdev_xp> argument,
222 * that contains information on the IRQ type (HWI/WTI), and IRQ index.
223 * It access the remote XCU mask register, but does not access IOPIC.
224 ******************************************************************************************
225 * @ lid           : target core local index (in cluster containing the source chdev).
226 * @ src_chdev_xp  : extended pointer on source chdev descriptor.
227 *****************************************************************************************/
228void soclib_pic_disable_irq( lid_t   lid,
229                             xptr_t  src_chdev_xp );
230
231/******************************************************************************************
232 * This function activates the PTI timer for the calling core.
233 * The <period> argument define the number of cycles between IRQs.
234 ******************************************************************************************
235 * @ period      : number of ticks between IRQs.
236 *****************************************************************************************/
237void soclib_pic_enable_timer( uint32_t period );
238
239/******************************************************************************************
240 * This function activates the WTI[lid] in the local cluster, where lid is the calling
241 * core local index.
242 *****************************************************************************************/
243void soclib_pic_enable_ipi();
244
245/******************************************************************************************
246 * This function allows the calling thread to send an IPI to any core in any cluster.
247 * It can be called by any thread running on any cluster.
248 ******************************************************************************************
249 * @ cxy        : target core cluster.
250 * @ lid        : target core local index.
251 *****************************************************************************************/
252void soclib_pic_send_ipi( cxy_t    cxy,
253                          lid_t    lid );
254
255/******************************************************************************************
256 * This function acknowleges the WTI[lid] in the local cluster, where lid is the calling
257 * core local index.
258 *****************************************************************************************/
259void soclib_pic_ack_ipi();
260
261
262
263
264
265
266/******************************************************************************************
267 *                    Private PIC API for TSAR.
268 *****************************************************************************************/
269
270/******************************************************************************************
271 * This function returns the first free WTI mailbox from the XCU descriptor.
272 * cluster extension containing the current XCU state. It does not access the
273 * hardware XCU component. This WTI allocator is very simple, because an allocated
274 * WTI is never released. The first WTIs are preallocated for IPI (wpi_id == lid).
275 * This allocator does not use a lock, because there is no risk of concurrent access.
276 * If there is no free slot, it means that the total number of external IRQs is too
277 * large for the number of cores in the architecture, and the core goes to sleep.
278 *****************************************************************************************/
279uint32_t soclib_pic_wti_alloc();
280
281/******************************************************************************************
282 * This function returns the local pointer on the local XCU base segment.
283 *****************************************************************************************/
284uint32_t * soclib_pic_xcu_base();
285
286/******************************************************************************************
287 * This function returns the local pointer on a remote XCU base segment.
288 * It is used by the soclip_pic_enable_irq() and soclib_pic_disable_irq() functions.
289 ******************************************************************************************
290 * @ cxy  : target cluster identifier.
291 *****************************************************************************************/
292uint32_t * soclib_pic_remote_xcu_base( cxy_t cxy );
293
294/******************************************************************************************
295 * This function returns in the <hwi_status>, <wti_status>, <pti_status> buffers
296 * the local XCU status for a given core identidied by the <lid> argument.
297 *****************************************************************************************/
298void soclib_pic_xcu_status( lid_t      lid,
299                            uint32_t * hwi_status,
300                            uint32_t * wti_status,
301                            uint32_t * pti_status );
302
303/******************************************************************************************
304 * This SOCLIB PIC specific is the call-back function is the interrupt handler.
305 *****************************************************************************************/
306void soclib_pic_irq_handler();
307
308
309
310
311
312
313
314#endif  /* _SOCLIB_PIC_H_ */
Note: See TracBrowser for help on using the repository browser.