mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-12 09:07:46 -04:00
ARM_CA53: add support for FIQ
FIQ is used in the context of ARM SCP firmware instead of IRQ. This patch adds FIQ support for this context. Signed-off-by: Nicolas Royer <nroyer@baylibre.com>
This commit is contained in:
parent
ef4c305244
commit
b6a112b850
3 changed files with 58 additions and 22 deletions
|
@ -353,7 +353,11 @@ void vPortEndScheduler( void )
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Mask interrupts up to the max syscall interrupt priority. */
|
/* Mask interrupts up to the max syscall interrupt priority. */
|
||||||
uxPortSetInterruptMask();
|
#if defined( configNO_INTERRUPT_MASK )
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
#else
|
||||||
|
uxPortSetInterruptMask();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||||
directly. Increment ullCriticalNesting to keep a count of how many times
|
directly. Increment ullCriticalNesting to keep a count of how many times
|
||||||
|
@ -386,7 +390,11 @@ void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
should be unmasked. */
|
should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
#if defined( configNO_INTERRUPT_MASK )
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
#else
|
||||||
|
portCLEAR_INTERRUPT_MASK();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,14 +419,18 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
#if !defined( configNO_INTERRUPT_MASK )
|
||||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
{
|
||||||
so there is no need to save and restore the current mask value. It is
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
updated. */
|
so there is no need to save and restore the current mask value. It is
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
__asm volatile ( "dsb sy \n"
|
updated. */
|
||||||
"isb sy \n" ::: "memory" );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
__asm volatile ( "dsb sy \n"
|
||||||
|
"isb sy \n" ::: "memory" );
|
||||||
|
}
|
||||||
|
#endif /* configNO_INTERRUPT_MASK */
|
||||||
|
|
||||||
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
||||||
configCLEAR_TICK_INTERRUPT();
|
configCLEAR_TICK_INTERRUPT();
|
||||||
|
|
|
@ -140,6 +140,7 @@
|
||||||
/* Set the PMR register to be correct for the current critical nesting
|
/* Set the PMR register to be correct for the current critical nesting
|
||||||
depth. */
|
depth. */
|
||||||
LDR X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */
|
LDR X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */
|
||||||
|
#if !defined( configNO_INTERRUPT_MASK )
|
||||||
MOV X1, #255 /* X1 holds the unmask value. */
|
MOV X1, #255 /* X1 holds the unmask value. */
|
||||||
LDR X4, ullICCPMRConst /* X4 holds the address of the ICCPMR constant. */
|
LDR X4, ullICCPMRConst /* X4 holds the address of the ICCPMR constant. */
|
||||||
CMP X3, #0
|
CMP X3, #0
|
||||||
|
@ -151,6 +152,7 @@
|
||||||
STR W1, [X5] /* Write the mask value to ICCPMR. */
|
STR W1, [X5] /* Write the mask value to ICCPMR. */
|
||||||
DSB SY /* _RB_Barriers probably not required here. */
|
DSB SY /* _RB_Barriers probably not required here. */
|
||||||
ISB SY
|
ISB SY
|
||||||
|
#endif
|
||||||
STR X3, [X0] /* Restore the task's critical nesting count. */
|
STR X3, [X0] /* Restore the task's critical nesting count. */
|
||||||
|
|
||||||
/* Restore the FPU context indicator. */
|
/* Restore the FPU context indicator. */
|
||||||
|
@ -232,7 +234,7 @@ FreeRTOS_SWI_Handler:
|
||||||
|
|
||||||
LSR X1, X0, #26
|
LSR X1, X0, #26
|
||||||
|
|
||||||
#if defined( GUEST )
|
#if defined( GUEST ) || defined( configUSE_SVC )
|
||||||
CMP X1, #0x15 /* 0x15 = SVC instruction. */
|
CMP X1, #0x15 /* 0x15 = SVC instruction. */
|
||||||
#else
|
#else
|
||||||
CMP X1, #0x17 /* 0x17 = SMC instruction. */
|
CMP X1, #0x17 /* 0x17 = SMC instruction. */
|
||||||
|
@ -306,6 +308,7 @@ FreeRTOS_IRQ_Handler:
|
||||||
/* Maintain the interrupt nesting information across the function call. */
|
/* Maintain the interrupt nesting information across the function call. */
|
||||||
STP X1, X5, [SP, #-0x10]!
|
STP X1, X5, [SP, #-0x10]!
|
||||||
|
|
||||||
|
#if !defined( configUSE_FIQ )
|
||||||
/* Read value from the interrupt acknowledge register, which is stored in W0
|
/* Read value from the interrupt acknowledge register, which is stored in W0
|
||||||
for future parameter and interrupt clearing use. */
|
for future parameter and interrupt clearing use. */
|
||||||
LDR X2, ullICCIARConst
|
LDR X2, ullICCIARConst
|
||||||
|
@ -314,15 +317,21 @@ FreeRTOS_IRQ_Handler:
|
||||||
|
|
||||||
/* Maintain the ICCIAR value across the function call. */
|
/* Maintain the ICCIAR value across the function call. */
|
||||||
STP X0, X1, [SP, #-0x10]!
|
STP X0, X1, [SP, #-0x10]!
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Call the C handler. */
|
/* Call the C handler. */
|
||||||
BL vApplicationIRQHandler
|
BL vApplicationIRQHandler
|
||||||
|
|
||||||
/* Disable interrupts. */
|
/* Disable interrupts. */
|
||||||
|
#if defined( configUSE_FIQ )
|
||||||
|
MSR DAIFSET, #1
|
||||||
|
#else
|
||||||
MSR DAIFSET, #2
|
MSR DAIFSET, #2
|
||||||
|
#endif
|
||||||
DSB SY
|
DSB SY
|
||||||
ISB SY
|
ISB SY
|
||||||
|
|
||||||
|
#if !defined( configUSE_FIQ )
|
||||||
/* Restore the ICCIAR value. */
|
/* Restore the ICCIAR value. */
|
||||||
LDP X0, X1, [SP], #0x10
|
LDP X0, X1, [SP], #0x10
|
||||||
|
|
||||||
|
@ -330,6 +339,7 @@ FreeRTOS_IRQ_Handler:
|
||||||
LDR X4, ullICCEOIRConst
|
LDR X4, ullICCEOIRConst
|
||||||
LDR X4, [X4]
|
LDR X4, [X4]
|
||||||
STR W0, [X4]
|
STR W0, [X4]
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Restore the critical nesting count. */
|
/* Restore the critical nesting count. */
|
||||||
LDP X1, X5, [SP], #0x10
|
LDP X1, X5, [SP], #0x10
|
||||||
|
@ -416,6 +426,7 @@ ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext
|
||||||
ullICCPMRConst: .dword ullICCPMR
|
ullICCPMRConst: .dword ullICCPMR
|
||||||
ullMaxAPIPriorityMaskConst: .dword ullMaxAPIPriorityMask
|
ullMaxAPIPriorityMaskConst: .dword ullMaxAPIPriorityMask
|
||||||
vApplicationIRQHandlerConst: .word vApplicationIRQHandler
|
vApplicationIRQHandlerConst: .word vApplicationIRQHandler
|
||||||
|
.word 0
|
||||||
ullPortInterruptNestingConst: .dword ullPortInterruptNesting
|
ullPortInterruptNestingConst: .dword ullPortInterruptNesting
|
||||||
ullPortYieldRequiredConst: .dword ullPortYieldRequired
|
ullPortYieldRequiredConst: .dword ullPortYieldRequired
|
||||||
ullICCIARConst: .dword ullICCIAR
|
ullICCIARConst: .dword ullICCIAR
|
||||||
|
|
|
@ -86,7 +86,7 @@ extern uint64_t ullPortYieldRequired; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#if defined( GUEST )
|
#if defined( GUEST ) || defined( configUSE_SVC )
|
||||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||||
#else
|
#else
|
||||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||||
|
@ -101,23 +101,36 @@ extern UBaseType_t uxPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#if defined( configUSE_FIQ )
|
||||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "MSR DAIFSET, #1" ::: "memory" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "DSB SY" ); \
|
||||||
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFCLR, #1" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
#else
|
||||||
|
#define portDISABLE_INTERRUPTS() \
|
||||||
|
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||||
|
__asm volatile ( "DSB SY" ); \
|
||||||
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
|
#define portENABLE_INTERRUPTS() \
|
||||||
|
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||||
|
__asm volatile ( "DSB SY" ); \
|
||||||
|
__asm volatile ( "ISB SY" );
|
||||||
|
#endif
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
#ifndef configNO_INTERRUPT_MASK
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue