mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c@180:96ed750bd169, 2018-01-17 (annotated)
- Committer:
- Anna Bridge
- Date:
- Wed Jan 17 15:23:54 2018 +0000
- Revision:
- 180:96ed750bd169
- Child:
- 186:707f6e361f3e
mbed-dev libray. Release version 158
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anna Bridge |
180:96ed750bd169 | 1 | /**************************************************************************//** |
Anna Bridge |
180:96ed750bd169 | 2 | * @file irq_ctrl_gic.c |
Anna Bridge |
180:96ed750bd169 | 3 | * @brief Interrupt controller handling implementation for GIC |
Anna Bridge |
180:96ed750bd169 | 4 | * @version V1.0.0 |
Anna Bridge |
180:96ed750bd169 | 5 | * @date 30. June 2017 |
Anna Bridge |
180:96ed750bd169 | 6 | ******************************************************************************/ |
Anna Bridge |
180:96ed750bd169 | 7 | /* |
Anna Bridge |
180:96ed750bd169 | 8 | * Copyright (c) 2017 ARM Limited. All rights reserved. |
Anna Bridge |
180:96ed750bd169 | 9 | * |
Anna Bridge |
180:96ed750bd169 | 10 | * SPDX-License-Identifier: Apache-2.0 |
Anna Bridge |
180:96ed750bd169 | 11 | * |
Anna Bridge |
180:96ed750bd169 | 12 | * Licensed under the Apache License, Version 2.0 (the License); you may |
Anna Bridge |
180:96ed750bd169 | 13 | * not use this file except in compliance with the License. |
Anna Bridge |
180:96ed750bd169 | 14 | * You may obtain a copy of the License at |
Anna Bridge |
180:96ed750bd169 | 15 | * |
Anna Bridge |
180:96ed750bd169 | 16 | * www.apache.org/licenses/LICENSE-2.0 |
Anna Bridge |
180:96ed750bd169 | 17 | * |
Anna Bridge |
180:96ed750bd169 | 18 | * Unless required by applicable law or agreed to in writing, software |
Anna Bridge |
180:96ed750bd169 | 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
Anna Bridge |
180:96ed750bd169 | 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Anna Bridge |
180:96ed750bd169 | 21 | * See the License for the specific language governing permissions and |
Anna Bridge |
180:96ed750bd169 | 22 | * limitations under the License. |
Anna Bridge |
180:96ed750bd169 | 23 | */ |
Anna Bridge |
180:96ed750bd169 | 24 | |
Anna Bridge |
180:96ed750bd169 | 25 | #include <stddef.h> |
Anna Bridge |
180:96ed750bd169 | 26 | |
Anna Bridge |
180:96ed750bd169 | 27 | #include <cmsis.h> |
Anna Bridge |
180:96ed750bd169 | 28 | |
Anna Bridge |
180:96ed750bd169 | 29 | #include "irq_ctrl.h" |
Anna Bridge |
180:96ed750bd169 | 30 | |
Anna Bridge |
180:96ed750bd169 | 31 | #if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U) |
Anna Bridge |
180:96ed750bd169 | 32 | |
Anna Bridge |
180:96ed750bd169 | 33 | /// Number of implemented interrupt lines |
Anna Bridge |
180:96ed750bd169 | 34 | #ifndef IRQ_GIC_LINE_COUNT |
Anna Bridge |
180:96ed750bd169 | 35 | #define IRQ_GIC_LINE_COUNT (1020U) |
Anna Bridge |
180:96ed750bd169 | 36 | #endif |
Anna Bridge |
180:96ed750bd169 | 37 | |
Anna Bridge |
180:96ed750bd169 | 38 | static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U }; |
Anna Bridge |
180:96ed750bd169 | 39 | static uint32_t IRQ_ID0; |
Anna Bridge |
180:96ed750bd169 | 40 | |
Anna Bridge |
180:96ed750bd169 | 41 | /// Initialize interrupt controller. |
Anna Bridge |
180:96ed750bd169 | 42 | __WEAK int32_t IRQ_Initialize (void) { |
Anna Bridge |
180:96ed750bd169 | 43 | uint32_t i; |
Anna Bridge |
180:96ed750bd169 | 44 | |
Anna Bridge |
180:96ed750bd169 | 45 | for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) { |
Anna Bridge |
180:96ed750bd169 | 46 | IRQTable[i] = (IRQHandler_t)NULL; |
Anna Bridge |
180:96ed750bd169 | 47 | } |
Anna Bridge |
180:96ed750bd169 | 48 | GIC_Enable(); |
Anna Bridge |
180:96ed750bd169 | 49 | return (0); |
Anna Bridge |
180:96ed750bd169 | 50 | } |
Anna Bridge |
180:96ed750bd169 | 51 | |
Anna Bridge |
180:96ed750bd169 | 52 | |
Anna Bridge |
180:96ed750bd169 | 53 | /// Register interrupt handler. |
Anna Bridge |
180:96ed750bd169 | 54 | __WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) { |
Anna Bridge |
180:96ed750bd169 | 55 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 56 | |
Anna Bridge |
180:96ed750bd169 | 57 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 58 | IRQTable[irqn] = handler; |
Anna Bridge |
180:96ed750bd169 | 59 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 60 | } else { |
Anna Bridge |
180:96ed750bd169 | 61 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 62 | } |
Anna Bridge |
180:96ed750bd169 | 63 | |
Anna Bridge |
180:96ed750bd169 | 64 | return (status); |
Anna Bridge |
180:96ed750bd169 | 65 | } |
Anna Bridge |
180:96ed750bd169 | 66 | |
Anna Bridge |
180:96ed750bd169 | 67 | |
Anna Bridge |
180:96ed750bd169 | 68 | /// Get the registered interrupt handler. |
Anna Bridge |
180:96ed750bd169 | 69 | __WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 70 | IRQHandler_t h; |
Anna Bridge |
180:96ed750bd169 | 71 | |
Anna Bridge |
180:96ed750bd169 | 72 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 73 | h = IRQTable[irqn]; |
Anna Bridge |
180:96ed750bd169 | 74 | } else { |
Anna Bridge |
180:96ed750bd169 | 75 | h = (IRQHandler_t)0; |
Anna Bridge |
180:96ed750bd169 | 76 | } |
Anna Bridge |
180:96ed750bd169 | 77 | |
Anna Bridge |
180:96ed750bd169 | 78 | return (h); |
Anna Bridge |
180:96ed750bd169 | 79 | } |
Anna Bridge |
180:96ed750bd169 | 80 | |
Anna Bridge |
180:96ed750bd169 | 81 | |
Anna Bridge |
180:96ed750bd169 | 82 | /// Enable interrupt. |
Anna Bridge |
180:96ed750bd169 | 83 | __WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 84 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 85 | |
Anna Bridge |
180:96ed750bd169 | 86 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 87 | GIC_EnableIRQ ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 88 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 89 | } else { |
Anna Bridge |
180:96ed750bd169 | 90 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 91 | } |
Anna Bridge |
180:96ed750bd169 | 92 | |
Anna Bridge |
180:96ed750bd169 | 93 | return (status); |
Anna Bridge |
180:96ed750bd169 | 94 | } |
Anna Bridge |
180:96ed750bd169 | 95 | |
Anna Bridge |
180:96ed750bd169 | 96 | |
Anna Bridge |
180:96ed750bd169 | 97 | /// Disable interrupt. |
Anna Bridge |
180:96ed750bd169 | 98 | __WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 99 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 100 | |
Anna Bridge |
180:96ed750bd169 | 101 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 102 | GIC_DisableIRQ ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 103 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 104 | } else { |
Anna Bridge |
180:96ed750bd169 | 105 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 106 | } |
Anna Bridge |
180:96ed750bd169 | 107 | |
Anna Bridge |
180:96ed750bd169 | 108 | return (status); |
Anna Bridge |
180:96ed750bd169 | 109 | } |
Anna Bridge |
180:96ed750bd169 | 110 | |
Anna Bridge |
180:96ed750bd169 | 111 | |
Anna Bridge |
180:96ed750bd169 | 112 | /// Get interrupt enable state. |
Anna Bridge |
180:96ed750bd169 | 113 | __WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 114 | uint32_t enable; |
Anna Bridge |
180:96ed750bd169 | 115 | |
Anna Bridge |
180:96ed750bd169 | 116 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 117 | enable = GIC_GetEnableIRQ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 118 | } else { |
Anna Bridge |
180:96ed750bd169 | 119 | enable = 0U; |
Anna Bridge |
180:96ed750bd169 | 120 | } |
Anna Bridge |
180:96ed750bd169 | 121 | |
Anna Bridge |
180:96ed750bd169 | 122 | return (enable); |
Anna Bridge |
180:96ed750bd169 | 123 | } |
Anna Bridge |
180:96ed750bd169 | 124 | |
Anna Bridge |
180:96ed750bd169 | 125 | |
Anna Bridge |
180:96ed750bd169 | 126 | /// Configure interrupt request mode. |
Anna Bridge |
180:96ed750bd169 | 127 | __WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) { |
Anna Bridge |
180:96ed750bd169 | 128 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 129 | uint32_t val; |
Anna Bridge |
180:96ed750bd169 | 130 | uint8_t cfg; |
Anna Bridge |
180:96ed750bd169 | 131 | uint8_t secure; |
Anna Bridge |
180:96ed750bd169 | 132 | uint8_t cpu; |
Anna Bridge |
180:96ed750bd169 | 133 | |
Anna Bridge |
180:96ed750bd169 | 134 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 135 | |
Anna Bridge |
180:96ed750bd169 | 136 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 137 | // Check triggering mode |
Anna Bridge |
180:96ed750bd169 | 138 | val = (mode & IRQ_MODE_TRIG_Msk); |
Anna Bridge |
180:96ed750bd169 | 139 | |
Anna Bridge |
180:96ed750bd169 | 140 | if (val == IRQ_MODE_TRIG_LEVEL) { |
Anna Bridge |
180:96ed750bd169 | 141 | cfg = 0x00U; |
Anna Bridge |
180:96ed750bd169 | 142 | } else if (val == IRQ_MODE_TRIG_EDGE) { |
Anna Bridge |
180:96ed750bd169 | 143 | cfg = 0x02U; |
Anna Bridge |
180:96ed750bd169 | 144 | } else { |
Anna Bridge |
180:96ed750bd169 | 145 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 146 | } |
Anna Bridge |
180:96ed750bd169 | 147 | |
Anna Bridge |
180:96ed750bd169 | 148 | // Check interrupt type |
Anna Bridge |
180:96ed750bd169 | 149 | val = mode & IRQ_MODE_TYPE_Msk; |
Anna Bridge |
180:96ed750bd169 | 150 | |
Anna Bridge |
180:96ed750bd169 | 151 | if (val != IRQ_MODE_TYPE_IRQ) { |
Anna Bridge |
180:96ed750bd169 | 152 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 153 | } |
Anna Bridge |
180:96ed750bd169 | 154 | |
Anna Bridge |
180:96ed750bd169 | 155 | // Check interrupt domain |
Anna Bridge |
180:96ed750bd169 | 156 | val = mode & IRQ_MODE_DOMAIN_Msk; |
Anna Bridge |
180:96ed750bd169 | 157 | |
Anna Bridge |
180:96ed750bd169 | 158 | if (val == IRQ_MODE_DOMAIN_NONSECURE) { |
Anna Bridge |
180:96ed750bd169 | 159 | secure = 0; |
Anna Bridge |
180:96ed750bd169 | 160 | } else { |
Anna Bridge |
180:96ed750bd169 | 161 | // Check security extensions support |
Anna Bridge |
180:96ed750bd169 | 162 | val = GIC_DistributorInfo() & (1UL << 10U); |
Anna Bridge |
180:96ed750bd169 | 163 | |
Anna Bridge |
180:96ed750bd169 | 164 | if (val != 0U) { |
Anna Bridge |
180:96ed750bd169 | 165 | // Security extensions are supported |
Anna Bridge |
180:96ed750bd169 | 166 | secure = 1; |
Anna Bridge |
180:96ed750bd169 | 167 | } else { |
Anna Bridge |
180:96ed750bd169 | 168 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 169 | } |
Anna Bridge |
180:96ed750bd169 | 170 | } |
Anna Bridge |
180:96ed750bd169 | 171 | |
Anna Bridge |
180:96ed750bd169 | 172 | // Check interrupt CPU targets |
Anna Bridge |
180:96ed750bd169 | 173 | val = mode & IRQ_MODE_CPU_Msk; |
Anna Bridge |
180:96ed750bd169 | 174 | |
Anna Bridge |
180:96ed750bd169 | 175 | if (val == IRQ_MODE_CPU_ALL) { |
Anna Bridge |
180:96ed750bd169 | 176 | cpu = 0xFF; |
Anna Bridge |
180:96ed750bd169 | 177 | } else { |
Anna Bridge |
180:96ed750bd169 | 178 | cpu = val >> IRQ_MODE_CPU_Pos; |
Anna Bridge |
180:96ed750bd169 | 179 | } |
Anna Bridge |
180:96ed750bd169 | 180 | |
Anna Bridge |
180:96ed750bd169 | 181 | // Apply configuration if no mode error |
Anna Bridge |
180:96ed750bd169 | 182 | if (status == 0) { |
Anna Bridge |
180:96ed750bd169 | 183 | GIC_SetConfiguration((IRQn_Type)irqn, cfg); |
Anna Bridge |
180:96ed750bd169 | 184 | GIC_SetTarget ((IRQn_Type)irqn, cpu); |
Anna Bridge |
180:96ed750bd169 | 185 | |
Anna Bridge |
180:96ed750bd169 | 186 | if (secure != 0U) { |
Anna Bridge |
180:96ed750bd169 | 187 | GIC_SetGroup ((IRQn_Type)irqn, secure); |
Anna Bridge |
180:96ed750bd169 | 188 | } |
Anna Bridge |
180:96ed750bd169 | 189 | } |
Anna Bridge |
180:96ed750bd169 | 190 | } |
Anna Bridge |
180:96ed750bd169 | 191 | |
Anna Bridge |
180:96ed750bd169 | 192 | return (status); |
Anna Bridge |
180:96ed750bd169 | 193 | } |
Anna Bridge |
180:96ed750bd169 | 194 | |
Anna Bridge |
180:96ed750bd169 | 195 | |
Anna Bridge |
180:96ed750bd169 | 196 | /// Get interrupt mode configuration. |
Anna Bridge |
180:96ed750bd169 | 197 | __WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 198 | uint32_t mode; |
Anna Bridge |
180:96ed750bd169 | 199 | uint32_t val; |
Anna Bridge |
180:96ed750bd169 | 200 | |
Anna Bridge |
180:96ed750bd169 | 201 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 202 | mode = IRQ_MODE_TYPE_IRQ; |
Anna Bridge |
180:96ed750bd169 | 203 | |
Anna Bridge |
180:96ed750bd169 | 204 | // Get trigger mode |
Anna Bridge |
180:96ed750bd169 | 205 | val = GIC_GetConfiguration((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 206 | |
Anna Bridge |
180:96ed750bd169 | 207 | if ((val & 2U) != 0U) { |
Anna Bridge |
180:96ed750bd169 | 208 | // Corresponding interrupt is edge triggered |
Anna Bridge |
180:96ed750bd169 | 209 | mode |= IRQ_MODE_TRIG_EDGE; |
Anna Bridge |
180:96ed750bd169 | 210 | } else { |
Anna Bridge |
180:96ed750bd169 | 211 | // Corresponding interrupt is level triggered |
Anna Bridge |
180:96ed750bd169 | 212 | mode |= IRQ_MODE_TRIG_LEVEL; |
Anna Bridge |
180:96ed750bd169 | 213 | } |
Anna Bridge |
180:96ed750bd169 | 214 | |
Anna Bridge |
180:96ed750bd169 | 215 | // Get interrupt CPU targets |
Anna Bridge |
180:96ed750bd169 | 216 | mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos; |
Anna Bridge |
180:96ed750bd169 | 217 | |
Anna Bridge |
180:96ed750bd169 | 218 | } else { |
Anna Bridge |
180:96ed750bd169 | 219 | mode = IRQ_MODE_ERROR; |
Anna Bridge |
180:96ed750bd169 | 220 | } |
Anna Bridge |
180:96ed750bd169 | 221 | |
Anna Bridge |
180:96ed750bd169 | 222 | return (mode); |
Anna Bridge |
180:96ed750bd169 | 223 | } |
Anna Bridge |
180:96ed750bd169 | 224 | |
Anna Bridge |
180:96ed750bd169 | 225 | |
Anna Bridge |
180:96ed750bd169 | 226 | /// Get ID number of current interrupt request (IRQ). |
Anna Bridge |
180:96ed750bd169 | 227 | __WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) { |
Anna Bridge |
180:96ed750bd169 | 228 | IRQn_ID_t irqn; |
Anna Bridge |
180:96ed750bd169 | 229 | uint32_t prio; |
Anna Bridge |
180:96ed750bd169 | 230 | |
Anna Bridge |
180:96ed750bd169 | 231 | /* Dummy read to avoid GIC 390 errata 801120 */ |
Anna Bridge |
180:96ed750bd169 | 232 | GIC_GetHighPendingIRQ(); |
Anna Bridge |
180:96ed750bd169 | 233 | |
Anna Bridge |
180:96ed750bd169 | 234 | irqn = GIC_AcknowledgePending(); |
Anna Bridge |
180:96ed750bd169 | 235 | |
Anna Bridge |
180:96ed750bd169 | 236 | __DSB(); |
Anna Bridge |
180:96ed750bd169 | 237 | |
Anna Bridge |
180:96ed750bd169 | 238 | /* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014) */ |
Anna Bridge |
180:96ed750bd169 | 239 | /* The following workaround code is for a single-core system. It would be */ |
Anna Bridge |
180:96ed750bd169 | 240 | /* different in a multi-core system. */ |
Anna Bridge |
180:96ed750bd169 | 241 | /* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */ |
Anna Bridge |
180:96ed750bd169 | 242 | /* so unlock it, otherwise service the interrupt as normal. */ |
Anna Bridge |
180:96ed750bd169 | 243 | /* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 */ |
Anna Bridge |
180:96ed750bd169 | 244 | /* so will not occur here. */ |
Anna Bridge |
180:96ed750bd169 | 245 | |
Anna Bridge |
180:96ed750bd169 | 246 | if ((irqn == 0) || (irqn >= 0x3FE)) { |
Anna Bridge |
180:96ed750bd169 | 247 | /* Unlock the CPU interface with a dummy write to Interrupt Priority Register */ |
Anna Bridge |
180:96ed750bd169 | 248 | prio = GIC_GetPriority((IRQn_Type)0); |
Anna Bridge |
180:96ed750bd169 | 249 | GIC_SetPriority ((IRQn_Type)0, prio); |
Anna Bridge |
180:96ed750bd169 | 250 | |
Anna Bridge |
180:96ed750bd169 | 251 | __DSB(); |
Anna Bridge |
180:96ed750bd169 | 252 | |
Anna Bridge |
180:96ed750bd169 | 253 | if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) { |
Anna Bridge |
180:96ed750bd169 | 254 | /* If the ID is 0, is active and has not been seen before */ |
Anna Bridge |
180:96ed750bd169 | 255 | IRQ_ID0 = 1U; |
Anna Bridge |
180:96ed750bd169 | 256 | } |
Anna Bridge |
180:96ed750bd169 | 257 | /* End of Workaround GIC 390 errata 733075 */ |
Anna Bridge |
180:96ed750bd169 | 258 | } |
Anna Bridge |
180:96ed750bd169 | 259 | |
Anna Bridge |
180:96ed750bd169 | 260 | return (irqn); |
Anna Bridge |
180:96ed750bd169 | 261 | } |
Anna Bridge |
180:96ed750bd169 | 262 | |
Anna Bridge |
180:96ed750bd169 | 263 | |
Anna Bridge |
180:96ed750bd169 | 264 | /// Get ID number of current fast interrupt request (FIQ). |
Anna Bridge |
180:96ed750bd169 | 265 | __WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) { |
Anna Bridge |
180:96ed750bd169 | 266 | return ((IRQn_ID_t)-1); |
Anna Bridge |
180:96ed750bd169 | 267 | } |
Anna Bridge |
180:96ed750bd169 | 268 | |
Anna Bridge |
180:96ed750bd169 | 269 | |
Anna Bridge |
180:96ed750bd169 | 270 | /// Signal end of interrupt processing. |
Anna Bridge |
180:96ed750bd169 | 271 | __WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 272 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 273 | |
Anna Bridge |
180:96ed750bd169 | 274 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 275 | GIC_EndInterrupt ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 276 | |
Anna Bridge |
180:96ed750bd169 | 277 | if (irqn == 0) { |
Anna Bridge |
180:96ed750bd169 | 278 | IRQ_ID0 = 0U; |
Anna Bridge |
180:96ed750bd169 | 279 | } |
Anna Bridge |
180:96ed750bd169 | 280 | |
Anna Bridge |
180:96ed750bd169 | 281 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 282 | } else { |
Anna Bridge |
180:96ed750bd169 | 283 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 284 | } |
Anna Bridge |
180:96ed750bd169 | 285 | |
Anna Bridge |
180:96ed750bd169 | 286 | return (status); |
Anna Bridge |
180:96ed750bd169 | 287 | } |
Anna Bridge |
180:96ed750bd169 | 288 | |
Anna Bridge |
180:96ed750bd169 | 289 | |
Anna Bridge |
180:96ed750bd169 | 290 | /// Set interrupt pending flag. |
Anna Bridge |
180:96ed750bd169 | 291 | __WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 292 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 293 | |
Anna Bridge |
180:96ed750bd169 | 294 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 295 | GIC_SetPendingIRQ ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 296 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 297 | } else { |
Anna Bridge |
180:96ed750bd169 | 298 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 299 | } |
Anna Bridge |
180:96ed750bd169 | 300 | |
Anna Bridge |
180:96ed750bd169 | 301 | return (status); |
Anna Bridge |
180:96ed750bd169 | 302 | } |
Anna Bridge |
180:96ed750bd169 | 303 | |
Anna Bridge |
180:96ed750bd169 | 304 | /// Get interrupt pending flag. |
Anna Bridge |
180:96ed750bd169 | 305 | __WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 306 | uint32_t pending; |
Anna Bridge |
180:96ed750bd169 | 307 | |
Anna Bridge |
180:96ed750bd169 | 308 | if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 309 | pending = GIC_GetPendingIRQ ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 310 | } else { |
Anna Bridge |
180:96ed750bd169 | 311 | pending = 0U; |
Anna Bridge |
180:96ed750bd169 | 312 | } |
Anna Bridge |
180:96ed750bd169 | 313 | |
Anna Bridge |
180:96ed750bd169 | 314 | return (pending & 1U); |
Anna Bridge |
180:96ed750bd169 | 315 | } |
Anna Bridge |
180:96ed750bd169 | 316 | |
Anna Bridge |
180:96ed750bd169 | 317 | |
Anna Bridge |
180:96ed750bd169 | 318 | /// Clear interrupt pending flag. |
Anna Bridge |
180:96ed750bd169 | 319 | __WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 320 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 321 | |
Anna Bridge |
180:96ed750bd169 | 322 | if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 323 | GIC_ClearPendingIRQ ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 324 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 325 | } else { |
Anna Bridge |
180:96ed750bd169 | 326 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 327 | } |
Anna Bridge |
180:96ed750bd169 | 328 | |
Anna Bridge |
180:96ed750bd169 | 329 | return (status); |
Anna Bridge |
180:96ed750bd169 | 330 | } |
Anna Bridge |
180:96ed750bd169 | 331 | |
Anna Bridge |
180:96ed750bd169 | 332 | |
Anna Bridge |
180:96ed750bd169 | 333 | /// Set interrupt priority value. |
Anna Bridge |
180:96ed750bd169 | 334 | __WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) { |
Anna Bridge |
180:96ed750bd169 | 335 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 336 | |
Anna Bridge |
180:96ed750bd169 | 337 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 338 | GIC_SetPriority ((IRQn_Type)irqn, priority); |
Anna Bridge |
180:96ed750bd169 | 339 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 340 | } else { |
Anna Bridge |
180:96ed750bd169 | 341 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 342 | } |
Anna Bridge |
180:96ed750bd169 | 343 | |
Anna Bridge |
180:96ed750bd169 | 344 | return (status); |
Anna Bridge |
180:96ed750bd169 | 345 | } |
Anna Bridge |
180:96ed750bd169 | 346 | |
Anna Bridge |
180:96ed750bd169 | 347 | |
Anna Bridge |
180:96ed750bd169 | 348 | /// Get interrupt priority. |
Anna Bridge |
180:96ed750bd169 | 349 | __WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) { |
Anna Bridge |
180:96ed750bd169 | 350 | uint32_t priority; |
Anna Bridge |
180:96ed750bd169 | 351 | |
Anna Bridge |
180:96ed750bd169 | 352 | if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { |
Anna Bridge |
180:96ed750bd169 | 353 | priority = GIC_GetPriority ((IRQn_Type)irqn); |
Anna Bridge |
180:96ed750bd169 | 354 | } else { |
Anna Bridge |
180:96ed750bd169 | 355 | priority = IRQ_PRIORITY_ERROR; |
Anna Bridge |
180:96ed750bd169 | 356 | } |
Anna Bridge |
180:96ed750bd169 | 357 | |
Anna Bridge |
180:96ed750bd169 | 358 | return (priority); |
Anna Bridge |
180:96ed750bd169 | 359 | } |
Anna Bridge |
180:96ed750bd169 | 360 | |
Anna Bridge |
180:96ed750bd169 | 361 | |
Anna Bridge |
180:96ed750bd169 | 362 | /// Set priority masking threshold. |
Anna Bridge |
180:96ed750bd169 | 363 | __WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) { |
Anna Bridge |
180:96ed750bd169 | 364 | GIC_SetInterfacePriorityMask (priority); |
Anna Bridge |
180:96ed750bd169 | 365 | return (0); |
Anna Bridge |
180:96ed750bd169 | 366 | } |
Anna Bridge |
180:96ed750bd169 | 367 | |
Anna Bridge |
180:96ed750bd169 | 368 | |
Anna Bridge |
180:96ed750bd169 | 369 | /// Get priority masking threshold |
Anna Bridge |
180:96ed750bd169 | 370 | __WEAK uint32_t IRQ_GetPriorityMask (void) { |
Anna Bridge |
180:96ed750bd169 | 371 | return GIC_GetInterfacePriorityMask(); |
Anna Bridge |
180:96ed750bd169 | 372 | } |
Anna Bridge |
180:96ed750bd169 | 373 | |
Anna Bridge |
180:96ed750bd169 | 374 | |
Anna Bridge |
180:96ed750bd169 | 375 | /// Set priority grouping field split point |
Anna Bridge |
180:96ed750bd169 | 376 | __WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) { |
Anna Bridge |
180:96ed750bd169 | 377 | int32_t status; |
Anna Bridge |
180:96ed750bd169 | 378 | |
Anna Bridge |
180:96ed750bd169 | 379 | if (bits == IRQ_PRIORITY_Msk) { |
Anna Bridge |
180:96ed750bd169 | 380 | bits = 7U; |
Anna Bridge |
180:96ed750bd169 | 381 | } |
Anna Bridge |
180:96ed750bd169 | 382 | |
Anna Bridge |
180:96ed750bd169 | 383 | if (bits < 8U) { |
Anna Bridge |
180:96ed750bd169 | 384 | GIC_SetBinaryPoint (7U - bits); |
Anna Bridge |
180:96ed750bd169 | 385 | status = 0; |
Anna Bridge |
180:96ed750bd169 | 386 | } else { |
Anna Bridge |
180:96ed750bd169 | 387 | status = -1; |
Anna Bridge |
180:96ed750bd169 | 388 | } |
Anna Bridge |
180:96ed750bd169 | 389 | |
Anna Bridge |
180:96ed750bd169 | 390 | return (status); |
Anna Bridge |
180:96ed750bd169 | 391 | } |
Anna Bridge |
180:96ed750bd169 | 392 | |
Anna Bridge |
180:96ed750bd169 | 393 | |
Anna Bridge |
180:96ed750bd169 | 394 | /// Get priority grouping field split point |
Anna Bridge |
180:96ed750bd169 | 395 | __WEAK uint32_t IRQ_GetPriorityGroupBits (void) { |
Anna Bridge |
180:96ed750bd169 | 396 | uint32_t bp; |
Anna Bridge |
180:96ed750bd169 | 397 | |
Anna Bridge |
180:96ed750bd169 | 398 | bp = GIC_GetBinaryPoint() & 0x07U; |
Anna Bridge |
180:96ed750bd169 | 399 | |
Anna Bridge |
180:96ed750bd169 | 400 | return (7U - bp); |
Anna Bridge |
180:96ed750bd169 | 401 | } |
Anna Bridge |
180:96ed750bd169 | 402 | |
Anna Bridge |
180:96ed750bd169 | 403 | #endif |