source: trunk/kernel/devices/dev_icu.h @ 1

Last change on this file since 1 was 1, checked in by alain, 7 years ago

First import

File size: 14.0 KB
Line 
1/*
2 * dev_icu.h - ICU (Interrupt Controler Unit) generic device API.
3 *
4 * Authors   Alain Greiner  (2016)
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-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#ifndef _DEV_ICU_H_
25#define _DEV_ICU_H_
26
27#include <almos_config.h>
28#include <hal_types.h>
29#include <spinlock.h>
30
31/*****************************************************************************************
32 *     Generic Internal Interrupt Controler definition
33 *
34 * The ICU (Interrupt Controller Unit) device describes an internal peripheral,
35 * acting in all clusters containing cores. He is in charge of concentrating all IRQs
36 * (interrupt requests) generated by peripherals to signal the completion of an I/O
37 * operation. Each IRQ should be routed to the core that started the I/O operation.
38 * The ICU device must also help the kernel to select the ISR (Interrupt Service Routine)
39 * that must be executed by the target core.
40 *
41 * This component can be implemented as a dedicated hardware, centralized or distributed
42 * in all clusters, or emulated in software, as long as it implements the specified API.
43 * For the TSAR architecture, this generic ICU device is implemented by the two hardware
44 * components soclib_xicu and and soclib_iopic, and their associated drivers.
45 *
46 * ALMOS-MKH defines three types of IRQs, that are handled iby this ICU device:
47 * - HWI : The HardWare Interrupts are generated by local internal peripherals.
48 *   They are connected to the local ICU, to be routed to a given local core.
49 * - WTI : The Write Triggered Interrupts are actually mailboxes implemented in the
50 *   local ICU. They are used to implement software IPIs (Inter-Processor-Interrupts),
51 *   or to route an IRQ generated by an external peripheral to a local core.
52 * - PTI : The Programmable Timer Interrupts are actually timers generating periodic
53 *   interrupts controled by softare and contained in the local ICU, and routed to
54 *   a local core.
55 *
56 * The max numbers of interrupts of each type in a given cluster are defined by the
57 * CONFIG_IRQ_HWI_MAX, CONFIG_IRQ_WTI_MAX, and CONFIG_IRQ_PTI_MAX parameters.
58 * The actual numbers (hwi_nr / wti_nr / pti_nr) for a given manycore architecture
59 * are defined in the boot_info file and stored in the ICU device extension.
60 *
61 * The generic ICU device 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 *    to the core that started the I/O operation core, as a given IRQ event should be
65 *    handled by only one core.
66 * 2) It makes a global OR between all enabled IRQs for a given core, to interrupt
67 *    the core when at least one enabled IRQ is active.
68 * 3) It is capable to return the highest priority active IRQ of each type. The priority
69 *    scheme depends on the ICU device implementation.
70 *
71 * To select the ISR to be executed for a given IRQ routed to a given core, ALMOS-MKH
72 * uses three interrupts vectors, implemented as three arrays (HWI/WTI/PTI),
73 * stored in the core descriptor. Each entry in one interrupt vector array contains
74 * an extended pointer on the device descriptor that is the "source" of the interrupt.
75 * This device descriptor contains a link to the ISR to be executed.
76 *
77 * The ICU peripheral does not execute I/O operations, but is just acting as a
78 * dynamically configurable interrupt router for another I/O operation.
79 * Therefore, ALMOS-MKH does not use the iCU device waiting queue, but calls directly
80 * the ICU driver blocking functions, using the device lock to get exclusive access to
81 * the ICU device state.
82 ****************************************************************************************/
83 
84/****  Forward declarations  ****/
85
86struct device_s;
87
88/*****************************************************************************************
89 * This defines the (implementation independant) extension for the generic ICU device.
90 ****************************************************************************************/
91
92typedef struct icu_extend_s
93{
94    uint32_t    hwi_nr;         /*! actual number of HWI IRQs in the ICU device         */
95    uint32_t    wti_nr;         /*! actual number of WTI IRQs in the ICU device         */
96    uint32_t    pti_nr;         /*! actual number of PTI IRQs in the ICU device         */
97    uint32_t    wti_bitmap;     /*! WTI mailbox allocator / 0 == free entry             */
98    spinlock_t  wti_lock;       /*! lock protecting WTI mailbox allocator               */
99}
100icu_extend_t;
101
102/*****************************************************************************************
103 * This enum defines the various implementations of the ICU internal interrupt controller.
104 * This array must be kept consistent with the define in arch_info.h file
105 ****************************************************************************************/
106
107enum icu_impl_e
108{
109    IMPL_ICU_XCU =   0,         /* vci_xicu component used in TSAR                      */
110    IMPL_ICU_I86 =   1          /* TBD                                                  */
111}
112icu_impl_t;
113
114/*****************************************************************************************
115 * This enum defines the three types of interrupts.
116 ****************************************************************************************/
117
118typedef enum irq_type
119{
120    HWI_TYPE,                   /*! Hardware Interrupt                                  */
121    WTI_TYPE,                   /*! Write Triggered Interrupt                           */
122    PTI_TYPE                    /*! Programmable Timer Interrupt                        */
123}
124irq_type_t;
125
126
127/*****************************************************************************************
128 * This function makes two initialisations:
129 * - It initialises the ICU specific fields of the device descriptor.
130 * - it initialises the implementation specific ICU hardware device and associated
131 *   data structures if required.
132 * It must be executed once in the cluster containing the ICU device descriptor.
133 *****************************************************************************************
134 * @ icu_xp     : extended pointer on ICU device descriptor.
135 * @ hwi_nr     : number of HWI irqs.
136 * @ wti_nr     : number of WTI irqs.
137 * @ pti_nr     : number of PTI irqs.
138 ****************************************************************************************/
139void dev_icu_init( xptr_t    icu_xp,
140                   uint32_t  hwi_nr,
141                   uint32_t  wti_nr,
142                   uint32_t  pti_nr );
143
144/*****************************************************************************************
145 * This function enables the routing of a given IRQ, to a given core in a remote cluster.
146 * This IRQ is identified by its type (HWI/WTI/PTI) and index in the remote ICU.
147 * The target core is identified by its local index.
148 * As it uses remote accesses, it can be executed by any thread in any cluster.
149 * - It unmask the selected IRQ in the remote ICU.
150 * - It registers the extended pointer on the "source" device descriptor in the
151 *   relevant interrupt vector of the selected core.
152 * - It register the IRQ type and index in the "source" device descriptor.
153 *****************************************************************************************
154 * @ cxy        : remote cluster identifier (can be the local custer).
155 * @ lid        : local index of selected core in remote cluster.
156 * @ irq_type   : HWI/WTI/PTI.
157 * @ irq_id     : IRQ index in remote ICU
158 * @ src_dev_xp : extended pointer on device descriptor source of IRQ.
159 ****************************************************************************************/
160void dev_icu_enable_irq( cxy_t      cxy,
161                         lid_t      lid,
162                         uint32_t   irq_type,
163                         uint32_t   irq_id,
164                         xptr_t     src_dev_xp );
165
166/*****************************************************************************************
167 * This function disables one given IRQ for a given core in a remote cluster.
168 * This IRQ is identified by its type (HWI/WTI/PTI) and index in the remote ICU.
169 * The core is identified by its local index.
170 * As it uses remote accesses, it can be executed by any thread in any cluster.
171 * - It mask the selected IRQ in the remote ICU.
172 * - It removes the extended pointer on the "source" device descriptor from the
173 *   relevant interrupt vector of the selected core.
174 * - The IRQ type and index fields are not modified in the "source" device descriptor.
175 *****************************************************************************************
176 * @ cxy       : remote cluster identifier (can be the local custer).
177 * @ lid       : local index of selected core in remote cluster.
178 * @ irq_type  : HWI/WTI/PTI.
179 * @ irq_id    : IRQ index.
180 ****************************************************************************************/
181void dev_icu_disable_irq( cxy_t      cxy,
182                          lid_t      lid,
183                          uint32_t   irq_type,
184                          uint32_t   irq_id );
185                       
186/*****************************************************************************************
187 * This function set the period value for a timer identified by the PTI index,
188 * in the local ICU device descriptor.
189 *****************************************************************************************
190 * @ pti_id    : PTI index.
191 * @ period    : number of cycles.
192 ****************************************************************************************/
193void dev_icu_set_period( uint32_t   pti_id,
194                         uint32_t   period );
195
196/*****************************************************************************************
197 * This function acknowledge a PTI IRQ for a timer identified by the PTI index,
198 * in the local ICU device descriptor.
199 *****************************************************************************************
200 * @ pti_id    : PTI index.
201 ****************************************************************************************/
202void dev_icu_ack_timer( uint32_t   pti_id );
203
204/*****************************************************************************************
205 * This function send an IPI (Inter Processor Interrupt) to a core identified by
206 * its cluster identifier and local index.
207 * This IPI force a context switch, and the handling of pending RPC(s).
208 *****************************************************************************************
209 * @ cxy      : destination cluster identifier.
210 * @ lid      : destination core local index.
211 * @ return 0 if success (IPI registered) / returns EINVAL if illegal cxy or lid.
212 ****************************************************************************************/
213void dev_icu_send_ipi( cxy_t    cxy,
214                       lid_t    lid );
215
216/*****************************************************************************************
217 * This function is called by a core when it receives an IRQ from the ICU device.
218 * It access the local ICU device descriptor to get the highest priority IRQ
219 * of each type (HWI / WTI / PTI).
220 * - If it is a WTI or an HWI, the function uses the calling core interrupt-vectors
221 *   to call the relevant ISR, registered in the source device descriptor.
222 * - If it is a PTI, the source device descriptor is the ICU device itself, and it
223 *   call the core_clock() function to execute all operations related to the TICK event.
224 ****************************************************************************************/
225void dev_icu_irq_handler();
226
227/*****************************************************************************************
228 * This function implements the WTI mailbox allocator. It is used by all I/O operations
229 * for completion signaling.
230 * If there is no mailbox available, the client thread must deschedule and retry later.
231 * If N is the total number of WTI mailboxes in a cluster, and NC the number of cores,
232 * the number of dynamically allocatable WTI mailboxes is (N-NC) because the first N
233 * WTI mailboxes are used by the IPIs (one IPI per core).
234 * It does not access the hardware device.
235 *****************************************************************************************
236 * @ return WTI index if success / returns 0xFFFFFFFF if no mailbox available.
237 ****************************************************************************************/
238uint32_t dev_icu_wti_alloc();
239
240/*****************************************************************************************
241 * This function releases a dynamically allocated WTI mailbox.
242 * It does not access the hardware device.
243 *****************************************************************************************
244 * @ wti_id   : WTI mailbox index.
245 ****************************************************************************************/
246void dev_icu_wti_release( uint32_t wti_id );
247
248/*****************************************************************************************
249 * This function returns an extended pointer on a WTI mailbox identified by its
250 * cluster identifier and local index in ICU.
251 * WARNING: we assume that all ICU hardware devices have the same local base address.
252 *****************************************************************************************
253 * @ cxy      : mailbox cluster identifier
254 * @ wti_id   : mailbox WTI index.
255 * @ returns extended pointer on mailbox register.
256 ****************************************************************************************/
257xptr_t  dev_icu_wti_xptr( cxy_t    cxy,
258                          uint32_t wti_id );
259
260#endif  /* _DEV_ICU_H_ */
Note: See TracBrowser for help on using the repository browser.