[75] | 1 | /* |
---|
[407] | 2 | * soclib_pic.h - soclib PIC driver definition. |
---|
[75] | 3 | * |
---|
[188] | 4 | * Author Alain Greiner (2016,2017) |
---|
[75] | 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 | |
---|
[188] | 24 | #ifndef _SOCLIB_PIC_H_ |
---|
| 25 | #define _SOCLIB_PIC_H_ |
---|
[75] | 26 | |
---|
[451] | 27 | #include <hal_kernel_types.h> |
---|
[75] | 28 | |
---|
[188] | 29 | /**** Forward declarations ****/ |
---|
| 30 | |
---|
| 31 | struct 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 | |
---|
[407] | 92 | #define SOCLIB_CYCLES_PER_MS 60 // SystemC virtual prototype at 60 KHz |
---|
[380] | 93 | |
---|
[75] | 94 | /****************************************************************************************** |
---|
[188] | 95 | * This define the registers offsets for the external SOCLIB_IOPIC component. |
---|
| 96 | * There is 4 addressable registers for each external input IRQ. |
---|
[75] | 97 | *****************************************************************************************/ |
---|
| 98 | |
---|
[188] | 99 | #define IOPIC_ADDRESS 0 |
---|
| 100 | #define IOPIC_EXTEND 1 |
---|
| 101 | #define IOPIC_STATUS 2 |
---|
| 102 | #define IOPIC_MASK 3 |
---|
[75] | 103 | |
---|
[188] | 104 | #define IOPIC_SPAN 4 |
---|
| 105 | |
---|
[75] | 106 | /****************************************************************************************** |
---|
[188] | 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 | |
---|
| 137 | typedef struct soclib_pic_core_s |
---|
| 138 | { |
---|
[432] | 139 | struct chdev_s * hwi_vector[SOCLIB_MAX_HWI]; /* HWI interrupt vector */ |
---|
| 140 | struct chdev_s * wti_vector[SOCLIB_MAX_WTI]; /* WTI interrupt vector */ |
---|
[188] | 141 | } |
---|
| 142 | soclib_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 | |
---|
| 151 | typedef 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 | } |
---|
| 159 | soclib_pic_cluster_t; |
---|
| 160 | |
---|
| 161 | |
---|
| 162 | |
---|
| 163 | |
---|
| 164 | /****************************************************************************************** |
---|
| 165 | * Generic PIC API |
---|
| 166 | *****************************************************************************************/ |
---|
| 167 | |
---|
| 168 | /****************************************************************************************** |
---|
[451] | 169 | * This function disables all input IRQs in the external IOPIC controller. |
---|
[188] | 170 | * It must be called by a thread running in the cluster containing the PIC chdev. |
---|
| 171 | ****************************************************************************************** |
---|
[75] | 172 | * @ chdev : pointer on PIC chdev descriptor. |
---|
| 173 | *****************************************************************************************/ |
---|
[238] | 174 | void soclib_pic_init( struct chdev_s * pic ); |
---|
[75] | 175 | |
---|
[188] | 176 | /***************************************************************************************** |
---|
[451] | 177 | * This function allocates memory from local cluster for the local PIC core extensions |
---|
[188] | 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. |
---|
[451] | 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. |
---|
[188] | 185 | ***************************************************************************************** |
---|
| 186 | * @ xcu_base : local pointer on XCU controller segment base. |
---|
| 187 | ****************************************************************************************/ |
---|
| 188 | void soclib_pic_extend_init( uint32_t * xcu_base ); |
---|
| 189 | |
---|
[75] | 190 | /****************************************************************************************** |
---|
[188] | 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. |
---|
[75] | 202 | ****************************************************************************************** |
---|
[188] | 203 | * @ lid : target core local index. |
---|
| 204 | * @ src_chdev : local pointer on source chdev descriptor. |
---|
[75] | 205 | *****************************************************************************************/ |
---|
[238] | 206 | void soclib_pic_bind_irq( lid_t lid, |
---|
| 207 | struct chdev_s * src_chdev ); |
---|
[75] | 208 | |
---|
| 209 | /****************************************************************************************** |
---|
[205] | 210 | * This function enables a remote HWI/WTI IRQ, identified by the <src_chdev_xp> argument, |
---|
[188] | 211 | * that contains information on the IRQ type (HWI/WTI), and IRQ index. |
---|
[205] | 212 | * It access the remote XCU mask register, but does not access IOPIC. |
---|
[75] | 213 | ****************************************************************************************** |
---|
[205] | 214 | * @ lid : target core local index (in cluster containing the source chdev). |
---|
| 215 | * @ src_chdev_xp : extended pointer on source chdev descriptor. |
---|
[75] | 216 | *****************************************************************************************/ |
---|
[205] | 217 | void soclib_pic_enable_irq( lid_t lid, |
---|
| 218 | xptr_t src_chdev_xp ); |
---|
[75] | 219 | |
---|
| 220 | /****************************************************************************************** |
---|
[205] | 221 | * This function disables a remote HWI/WTI IRQ, identified by the <src_chdev_xp> argument, |
---|
[188] | 222 | * that contains information on the IRQ type (HWI/WTI), and IRQ index. |
---|
[205] | 223 | * It access the remote XCU mask register, but does not access IOPIC. |
---|
[188] | 224 | ****************************************************************************************** |
---|
[205] | 225 | * @ lid : target core local index (in cluster containing the source chdev). |
---|
| 226 | * @ src_chdev_xp : extended pointer on source chdev descriptor. |
---|
[188] | 227 | *****************************************************************************************/ |
---|
[205] | 228 | void soclib_pic_disable_irq( lid_t lid, |
---|
| 229 | xptr_t src_chdev_xp ); |
---|
[188] | 230 | |
---|
| 231 | /****************************************************************************************** |
---|
[279] | 232 | * This function activates the PTI timer for the calling core. |
---|
[188] | 233 | * The <period> argument define the number of cycles between IRQs. |
---|
| 234 | ****************************************************************************************** |
---|
[380] | 235 | * @ period : number of ticks between IRQs. |
---|
[188] | 236 | *****************************************************************************************/ |
---|
| 237 | void soclib_pic_enable_timer( uint32_t period ); |
---|
| 238 | |
---|
| 239 | /****************************************************************************************** |
---|
[407] | 240 | * This function activates the WTI[lid] in the local cluster, where lid is the calling |
---|
[279] | 241 | * core local index. |
---|
| 242 | *****************************************************************************************/ |
---|
[481] | 243 | void soclib_pic_enable_ipi( void ); |
---|
[279] | 244 | |
---|
| 245 | /****************************************************************************************** |
---|
[188] | 246 | * This function allows the calling thread to send an IPI to any core in any cluster. |
---|
[75] | 247 | * It can be called by any thread running on any cluster. |
---|
| 248 | ****************************************************************************************** |
---|
[188] | 249 | * @ cxy : target core cluster. |
---|
| 250 | * @ lid : target core local index. |
---|
[75] | 251 | *****************************************************************************************/ |
---|
[188] | 252 | void soclib_pic_send_ipi( cxy_t cxy, |
---|
| 253 | lid_t lid ); |
---|
[75] | 254 | |
---|
[407] | 255 | /****************************************************************************************** |
---|
| 256 | * This function acknowleges the WTI[lid] in the local cluster, where lid is the calling |
---|
| 257 | * core local index. |
---|
| 258 | *****************************************************************************************/ |
---|
[481] | 259 | void soclib_pic_ack_ipi( void ); |
---|
[75] | 260 | |
---|
[188] | 261 | |
---|
| 262 | |
---|
| 263 | |
---|
| 264 | |
---|
[407] | 265 | |
---|
[188] | 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 | *****************************************************************************************/ |
---|
[481] | 279 | uint32_t soclib_pic_wti_alloc( void ); |
---|
[188] | 280 | |
---|
| 281 | /****************************************************************************************** |
---|
[205] | 282 | * This function returns the local pointer on the local XCU base segment. |
---|
[188] | 283 | *****************************************************************************************/ |
---|
[481] | 284 | uint32_t * soclib_pic_xcu_base( void ); |
---|
[188] | 285 | |
---|
| 286 | /****************************************************************************************** |
---|
[205] | 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 | *****************************************************************************************/ |
---|
| 292 | uint32_t * soclib_pic_remote_xcu_base( cxy_t cxy ); |
---|
| 293 | |
---|
| 294 | /****************************************************************************************** |
---|
[188] | 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 | *****************************************************************************************/ |
---|
| 298 | void 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 | *****************************************************************************************/ |
---|
[481] | 306 | void soclib_pic_irq_handler( void ); |
---|
[188] | 307 | |
---|
| 308 | |
---|
| 309 | |
---|
| 310 | |
---|
| 311 | |
---|
| 312 | |
---|
| 313 | |
---|
| 314 | #endif /* _SOCLIB_PIC_H_ */ |
---|