diff --git a/portable/GCC/ARM_CA53_64_BIT/port.c b/portable/GCC/ARM_CA53_64_BIT/port.c index 63ea94c4c..7b4aa98fe 100644 --- a/portable/GCC/ARM_CA53_64_BIT/port.c +++ b/portable/GCC/ARM_CA53_64_BIT/port.c @@ -353,7 +353,11 @@ void vPortEndScheduler( void ) void vPortEnterCritical( void ) { /* 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 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 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 */ - /* Set interrupt mask before altering scheduler structures. The tick - 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 - necessary to turn off interrupts in the CPU itself while the ICCPMR is being - updated. */ - portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); - __asm volatile ( "dsb sy \n" - "isb sy \n" ::: "memory" ); + #if !defined( configNO_INTERRUPT_MASK ) + { + /* Set interrupt mask before altering scheduler structures. The tick + 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 + necessary to turn off interrupts in the CPU itself while the ICCPMR is being + updated. */ + 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. */ configCLEAR_TICK_INTERRUPT(); diff --git a/portable/GCC/ARM_CA53_64_BIT/portASM.S b/portable/GCC/ARM_CA53_64_BIT/portASM.S index 80cb574f0..dc02f9ac5 100644 --- a/portable/GCC/ARM_CA53_64_BIT/portASM.S +++ b/portable/GCC/ARM_CA53_64_BIT/portASM.S @@ -140,6 +140,7 @@ /* Set the PMR register to be correct for the current critical nesting depth. */ LDR X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */ +#if !defined( configNO_INTERRUPT_MASK ) MOV X1, #255 /* X1 holds the unmask value. */ LDR X4, ullICCPMRConst /* X4 holds the address of the ICCPMR constant. */ CMP X3, #0 @@ -151,6 +152,7 @@ STR W1, [X5] /* Write the mask value to ICCPMR. */ DSB SY /* _RB_Barriers probably not required here. */ ISB SY +#endif STR X3, [X0] /* Restore the task's critical nesting count. */ /* Restore the FPU context indicator. */ @@ -232,7 +234,7 @@ FreeRTOS_SWI_Handler: LSR X1, X0, #26 -#if defined( GUEST ) +#if defined( GUEST ) || defined( configUSE_SVC ) CMP X1, #0x15 /* 0x15 = SVC instruction. */ #else CMP X1, #0x17 /* 0x17 = SMC instruction. */ @@ -306,6 +308,7 @@ FreeRTOS_IRQ_Handler: /* Maintain the interrupt nesting information across the function call. */ STP X1, X5, [SP, #-0x10]! +#if !defined( configUSE_FIQ ) /* Read value from the interrupt acknowledge register, which is stored in W0 for future parameter and interrupt clearing use. */ LDR X2, ullICCIARConst @@ -314,15 +317,21 @@ FreeRTOS_IRQ_Handler: /* Maintain the ICCIAR value across the function call. */ STP X0, X1, [SP, #-0x10]! +#endif /* Call the C handler. */ BL vApplicationIRQHandler /* Disable interrupts. */ +#if defined( configUSE_FIQ ) + MSR DAIFSET, #1 +#else MSR DAIFSET, #2 +#endif DSB SY ISB SY +#if !defined( configUSE_FIQ ) /* Restore the ICCIAR value. */ LDP X0, X1, [SP], #0x10 @@ -330,6 +339,7 @@ FreeRTOS_IRQ_Handler: LDR X4, ullICCEOIRConst LDR X4, [X4] STR W0, [X4] +#endif /* Restore the critical nesting count. */ LDP X1, X5, [SP], #0x10 @@ -416,6 +426,7 @@ ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext ullICCPMRConst: .dword ullICCPMR ullMaxAPIPriorityMaskConst: .dword ullMaxAPIPriorityMask vApplicationIRQHandlerConst: .word vApplicationIRQHandler + .word 0 ullPortInterruptNestingConst: .dword ullPortInterruptNesting ullPortYieldRequiredConst: .dword ullPortYieldRequired ullICCIARConst: .dword ullICCIAR diff --git a/portable/GCC/ARM_CA53_64_BIT/portmacro.h b/portable/GCC/ARM_CA53_64_BIT/portmacro.h index 8215504cb..a8b5c9c49 100644 --- a/portable/GCC/ARM_CA53_64_BIT/portmacro.h +++ b/portable/GCC/ARM_CA53_64_BIT/portmacro.h @@ -86,7 +86,7 @@ extern uint64_t ullPortYieldRequired; \ } #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" ) #else #define portYIELD() __asm volatile ( "SMC 0" ::: "memory" ) @@ -101,23 +101,36 @@ extern UBaseType_t uxPortSetInterruptMask( void ); extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ); extern void vPortInstallFreeRTOSVectorTable( void ); -#define portDISABLE_INTERRUPTS() \ - __asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \ - __asm volatile ( "DSB SY" ); \ - __asm volatile ( "ISB SY" ); +#if defined( configUSE_FIQ ) + #define portDISABLE_INTERRUPTS() \ + __asm volatile ( "MSR DAIFSET, #1" ::: "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" ); + #define portENABLE_INTERRUPTS() \ + __asm volatile ( "MSR DAIFCLR, #1" ::: "memory" ); \ + __asm volatile ( "DSB 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 interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); -#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) +#ifndef configNO_INTERRUPT_MASK + #define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) +#endif /*-----------------------------------------------------------*/