diff --git a/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c b/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c index 5fbe9dc654..25d1359159 100644 --- a/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c +++ b/cmsis/TARGET_CORTEX_A/irq_ctrl_gic.c @@ -1,8 +1,8 @@ /**************************************************************************//** * @file irq_ctrl_gic.c * @brief Interrupt controller handling implementation for GIC - * @version V1.0.0 - * @date 30. June 2017 + * @version V1.0.1 + * @date 9. April 2018 ******************************************************************************/ /* * Copyright (c) 2017 ARM Limited. All rights reserved. @@ -37,7 +37,7 @@ #endif static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U }; -static uint32_t IRQ_ID0; +static uint32_t IRQ_ID0; /// Initialize interrupt controller. __WEAK int32_t IRQ_Initialize (void) { @@ -70,6 +70,9 @@ __WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) { __WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) { IRQHandler_t h; + // Ignore CPUID field (software generated interrupts) + irqn &= 0x3FFU; + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { h = IRQTable[irqn]; } else { @@ -271,9 +274,12 @@ __WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) { /// Signal end of interrupt processing. __WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) { int32_t status; + IRQn_Type irq = (IRQn_Type)irqn; + + irqn &= 0x3FFU; if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { - GIC_EndInterrupt ((IRQn_Type)irqn); + GIC_EndInterrupt (irq); if (irqn == 0) { IRQ_ID0 = 0U; diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S index 92a527ec1d..b1c90cc321 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_GCC/TARGET_CORTEX_A/irq_ca.S @@ -218,22 +218,35 @@ IRQ_End: LDR R0, =SVC_Active LDRB R0, [R0] // Load SVC_Active flag CMP R0, #0 - BNE IRQ_SwitchCheck // Skip post processing when SVC active + BNE IRQ_Exit // SVC active, exit from IRQ handler // RTX IRQ post processing check + LDR R4, =IRQ_PendSV // Load address of IRQ_PendSV flag + LDRB R0, [R4] // Load PendSV flag + CMP R0, #1 // Compare PendSV value + BNE IRQ_SwitchCheck // Skip post processing if not pending + PUSH {R5, R6} // Save user R5 and R6 - MOV R6, #0 - LDR R5, =IRQ_PendSV // Load address of IRQ_PendSV flag + // Disable OS Tick + LDR R5, =osRtxInfo // Load address of osRtxInfo + LDR R5, [R5, #I_TICK_IRQN_OFS] // Load OS Tick irqn + MOV R0, R5 // Set it as function parameter + BLX IRQ_Disable // Disable OS Tick interrupt + MOV R6, #0 // Set PendSV clear value B IRQ_PendCheck IRQ_PendExec: - STRB R6, [R5] // Clear PendSV flag + STRB R6, [R4] // Clear PendSV flag CPSIE i // Re-enable interrupts BLX osRtxPendSV_Handler // Post process pending objects CPSID i // Disable interrupts IRQ_PendCheck: - LDRB R0, [R5] // Load PendSV flag + LDRB R0, [R4] // Load PendSV flag CMP R0, #1 // Compare PendSV value BEQ IRQ_PendExec // Branch to IRQ_PendExec if PendSV is set + + // Re-enable OS Tick + MOV R0, R5 // Restore irqn as function parameter + BLX IRQ_Enable // Enable OS Tick interrupt POP {R5, R6} // Restore user R5 and R6 IRQ_SwitchCheck: diff --git a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.S b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.S index cf1487a412..f3d0444ef8 100644 --- a/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.S +++ b/rtos/TARGET_CORTEX/rtx5/RTX/Source/TOOLCHAIN_IAR/TARGET_CORTEX_A/irq_ca.S @@ -203,22 +203,35 @@ IRQ_End LDR R0, =SVC_Active LDRB R0, [R0] ; Load SVC_Active flag CMP R0, #0 - BNE IRQ_SwitchCheck ; Skip post processing when SVC active + BNE IRQ_Exit ; SVC active, exit from IRQ handler ; RTX IRQ post processing check + LDR R4, =IRQ_PendSV ; Load address of IRQ_PendSV flag + LDRB R0, [R4] ; Load PendSV flag + CMP R0, #1 ; Compare PendSV value + BNE IRQ_SwitchCheck ; Skip post processing if not pending + PUSH {R5, R6} ; Save user R5 and R6 - MOV R6, #0 - LDR R5, =IRQ_PendSV ; Load address of IRQ_PendSV flag + ; Disable OS Tick + LDR R5, =osRtxInfo ; Load address of osRtxInfo + LDR R5, [R5, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + MOV R0, R5 ; Set it as function parameter + BLX IRQ_Disable ; Disable OS Tick interrupt + MOV R6, #0 ; Set PendSV clear value B IRQ_PendCheck IRQ_PendExec - STRB R6, [R5] ; Clear PendSV flag + STRB R6, [R4] ; Clear PendSV flag CPSIE i ; Re-enable interrupts BLX osRtxPendSV_Handler ; Post process pending objects CPSID i ; Disable interrupts IRQ_PendCheck - LDRB R0, [R5] ; Load PendSV flag + LDRB R0, [R4] ; Load PendSV flag CMP R0, #1 ; Compare PendSV value BEQ IRQ_PendExec ; Branch to IRQ_PendExec if PendSV is set + + ; Re-enable OS Tick + MOV R0, R5 ; Restore irqn as function parameter + BLX IRQ_Enable ; Enable OS Tick interrupt POP {R5, R6} ; Restore user R5 and R6 IRQ_SwitchCheck