RTX5: ignoring CPUID field in GIC implementation

updated interrupt handler for GCC and IAR
pull/7032/head
Vladimir Umek 2018-04-09 08:11:37 +02:00 committed by TomoYamanaka
parent 0226b11b67
commit b6c4139328
3 changed files with 46 additions and 14 deletions

View File

@ -1,8 +1,8 @@
/**************************************************************************//** /**************************************************************************//**
* @file irq_ctrl_gic.c * @file irq_ctrl_gic.c
* @brief Interrupt controller handling implementation for GIC * @brief Interrupt controller handling implementation for GIC
* @version V1.0.0 * @version V1.0.1
* @date 30. June 2017 * @date 9. April 2018
******************************************************************************/ ******************************************************************************/
/* /*
* Copyright (c) 2017 ARM Limited. All rights reserved. * Copyright (c) 2017 ARM Limited. All rights reserved.
@ -37,7 +37,7 @@
#endif #endif
static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U }; static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U };
static uint32_t IRQ_ID0; static uint32_t IRQ_ID0;
/// Initialize interrupt controller. /// Initialize interrupt controller.
__WEAK int32_t IRQ_Initialize (void) { __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) { __WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) {
IRQHandler_t h; IRQHandler_t h;
// Ignore CPUID field (software generated interrupts)
irqn &= 0x3FFU;
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
h = IRQTable[irqn]; h = IRQTable[irqn];
} else { } else {
@ -271,9 +274,12 @@ __WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) {
/// Signal end of interrupt processing. /// Signal end of interrupt processing.
__WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) { __WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) {
int32_t status; int32_t status;
IRQn_Type irq = (IRQn_Type)irqn;
irqn &= 0x3FFU;
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
GIC_EndInterrupt ((IRQn_Type)irqn); GIC_EndInterrupt (irq);
if (irqn == 0) { if (irqn == 0) {
IRQ_ID0 = 0U; IRQ_ID0 = 0U;

View File

@ -218,22 +218,35 @@ IRQ_End:
LDR R0, =SVC_Active LDR R0, =SVC_Active
LDRB R0, [R0] // Load SVC_Active flag LDRB R0, [R0] // Load SVC_Active flag
CMP R0, #0 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 // 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 PUSH {R5, R6} // Save user R5 and R6
MOV R6, #0 // Disable OS Tick
LDR R5, =IRQ_PendSV // Load address of IRQ_PendSV flag 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 B IRQ_PendCheck
IRQ_PendExec: IRQ_PendExec:
STRB R6, [R5] // Clear PendSV flag STRB R6, [R4] // Clear PendSV flag
CPSIE i // Re-enable interrupts CPSIE i // Re-enable interrupts
BLX osRtxPendSV_Handler // Post process pending objects BLX osRtxPendSV_Handler // Post process pending objects
CPSID i // Disable interrupts CPSID i // Disable interrupts
IRQ_PendCheck: IRQ_PendCheck:
LDRB R0, [R5] // Load PendSV flag LDRB R0, [R4] // Load PendSV flag
CMP R0, #1 // Compare PendSV value CMP R0, #1 // Compare PendSV value
BEQ IRQ_PendExec // Branch to IRQ_PendExec if PendSV is set 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 POP {R5, R6} // Restore user R5 and R6
IRQ_SwitchCheck: IRQ_SwitchCheck:

View File

@ -203,22 +203,35 @@ IRQ_End
LDR R0, =SVC_Active LDR R0, =SVC_Active
LDRB R0, [R0] ; Load SVC_Active flag LDRB R0, [R0] ; Load SVC_Active flag
CMP R0, #0 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 ; 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 PUSH {R5, R6} ; Save user R5 and R6
MOV R6, #0 ; Disable OS Tick
LDR R5, =IRQ_PendSV ; Load address of IRQ_PendSV flag 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 B IRQ_PendCheck
IRQ_PendExec IRQ_PendExec
STRB R6, [R5] ; Clear PendSV flag STRB R6, [R4] ; Clear PendSV flag
CPSIE i ; Re-enable interrupts CPSIE i ; Re-enable interrupts
BLX osRtxPendSV_Handler ; Post process pending objects BLX osRtxPendSV_Handler ; Post process pending objects
CPSID i ; Disable interrupts CPSID i ; Disable interrupts
IRQ_PendCheck IRQ_PendCheck
LDRB R0, [R5] ; Load PendSV flag LDRB R0, [R4] ; Load PendSV flag
CMP R0, #1 ; Compare PendSV value CMP R0, #1 ; Compare PendSV value
BEQ IRQ_PendExec ; Branch to IRQ_PendExec if PendSV is set 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 POP {R5, R6} ; Restore user R5 and R6
IRQ_SwitchCheck IRQ_SwitchCheck