# Cortex-A9 port: disable interrupts before writing to ICC\_PMR

**URL:** <https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952>\
**Category:** Kernel\
**Created:** [April 20, 2025, 7:16pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952 "2025-04-20T19:16:23Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 20, 2025, 7:16pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/1 "2025-04-20T19:16:23Z")

</div>

Hi, this topic comes right after I discovered that interrupts where enabled within `vTaskSwitchContext` in a [previous topic](https://forums.freertos.org/t/nested-context-switch/22949/5). The problem is present when `configNUMBER_OF_CORES` is higher than 1 and `configCHECK_FOR_STACK_OVERFLOW` is defined, either to 1 or 2. In this case, `pxCurrentTCB` is defined in `tasks.c` as `xTaskGetCurrentTaskHandle()` so, when it is used inside `taskCHECK_FOR_STACK_OVERFLOW`, it causes to enable the interrupts even though they where previously disabled. I also noticed this was [already reported](https://forums.freertos.org/t/portdisable-interrupts-question-on-smp/18292) so I do not know if it should be considered a problem of the multi-core port I am using or not. At this point I could just check if the interrupts are already disabled before disabling them in `ulPortSetInterruptMask` and `vPortClearInterruptMask` but is it really necessary to disable them? I know ARM recommends to keep an interrupt disabled if its configuration is going to be changed but I cannot find anything about disabling interrupts before modifying the Priority Mask Register.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [April 21, 2025, 3:00pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/2 "2025-04-21T15:00:49Z")

</div>

You are right. The stack macros should access TCB directly as the interrupts are already blocked. I’ll get back to you with a proposal.

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 22, 2025, 1:29pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/3 "2025-04-22T13:29:21Z")

</div>

I tried both the previously proposed approaches:

1. Check if the interrupt are already disabled and skip the execution of `portCPU_IRQ_DISABLE()` and `portCPU_IRQ_ENABLE()` before the modification of the PM Register.
2. Remove `portCPU_IRQ_DISABLE()` and `portCPU_IRQ_ENABLE()` from `vPortClearInterruptMask` and `ulPortSetInterruptMask`.

They both seems to work even though the second one may require more extensive testing. In case the second approach were considered reliable, it could also be applied to the single-core Cortex-A9 port.

---

<div class="post-metadata">

**Author:** ![RAc](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rac/32/1389_2.png) [@RAc](https://forums.freertos.org/u/RAc)\
**Post date:** [April 22, 2025, 1:41pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/4 "2025-04-22T13:41:36Z")

</div>

couldn’t your solution 1 be subject to race conditions where the condition changes in between its check and the follow up?

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 22, 2025, 5:23pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/5 "2025-04-22T17:23:44Z")

</div>

The code I am using is the following one:

```auto
#define portCPU_IRQ_DISABLE() \
    __asm volatile ( "CPSID i" ::: "memory" ); \
    __asm volatile ( "DSB" ); \
    __asm volatile ( "ISB" );

#define portCPU_IRQ_ENABLE() \
    __asm volatile ( "CPSIE i" ::: "memory" ); \
    __asm volatile ( "DSB" ); \
    __asm volatile ( "ISB" );

#define portCHECK_IF_INTERRUPTS_DISABLED() \
    ({ \
        uint32_t ulInterruptsDisabled; \
        __asm volatile ( \
            "MRS %[IntDisabled], cpsr \n\t" \
            "AND %[IntDisabled], %[IntDisabled], %[iMask] \n\t" \
        :[IntDisabled] "+r" (ulInterruptsDisabled) \
        :[iMask] "I" (1 << 7) \
        : \
        ); \
        ulInterruptsDisabled; \
    })

uint32_t ulPortSetInterruptMask( void )
{
    uint32_t ulSavedInterruptState;
    const uint32_t ulInterruptsEnabled = !portCHECK_IF_INTERRUPTS_DISABLED();
    
    /* Interrupts are disabled before the ICCPMR is updated */
    if( ulInterruptsEnabled )
    {
        portCPU_IRQ_DISABLE();
    }

    ulSavedInterruptState = portICCPMR_PRIORITY_MASK_REGISTER;
    portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t )
(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
    __asm volatile ( "DSB \n"               
                        "ISB \n" ::: "memory" );
    
    if( ulInterruptsEnabled )
    {
        portCPU_IRQ_ENABLE();
    }

    return ulSavedInterruptState;        
}

void vPortClearInterruptMask( uint32_t ulSavedInterruptState )
{
    const uint32_t ulInterruptsEnabled = !portCHECK_IF_INTERRUPTS_DISABLED();

    /* Interrupts are disabled before the ICCPMR is updated */
    if( ulInterruptsEnabled )
    {
        portCPU_IRQ_DISABLE();
    }

    portICCPMR_PRIORITY_MASK_REGISTER = ulSavedInterruptState;
    __asm volatile ( "DSB \n"        
                        "ISB \n" ::: "memory" );      
    
    if( ulInterruptsEnabled )
    {
        portCPU_IRQ_ENABLE();
    }
}

```

If the interrupts are disabled properly, so placing the appropriate barrier to disable them exactly when they should be, I don’t see how the condition could change within `ulPortSetInterruptMask` and `vPortClearInterruptMask`.

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 24, 2025, 10:30am UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/6 "2025-04-24T10:30:44Z")

</div>

Hi @aggarg, do you have any official news about this matter?

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [April 24, 2025, 2:58pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/7 "2025-04-24T14:58:08Z")

</div>

Hi @Matth9814, Apologies for the delay in response. Would you please try the following patch and see if it addresses your issue - [stack\_macros\_smp\_fix.patch](https://forums.freertos.org/uploads/short-url/9wFQCabDkSL4EbyFclrVWMcANvV.patch) (20.5 KB)?

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 24, 2025, 8:23pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/8 "2025-04-24T20:23:06Z")

</div>

Thank you for addressing this issue, the patched code works as expected.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [April 25, 2025, 10:23am UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/9 "2025-04-25T10:23:04Z")

</div>

Thank you for confirming! Would you like to raise a PR for this or would you like us to?

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 25, 2025, 1:02pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/10 "2025-04-25T13:02:32Z")

</div>

I am going to do it, thank you.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [April 30, 2025, 6:14am UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/11 "2025-04-30T06:14:46Z")

</div>

Thank you for raising the PR - [FreeRTOS SMP: direct access to current TCB inside stack macros by Matth9814 · Pull Request #1270 · FreeRTOS/FreeRTOS-Kernel · GitHub](https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/1270).

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 30, 2025, 12:05pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/12 "2025-04-30T12:05:30Z")

</div>

I want to report that the same problem is present in [Percepio View](https://forums.freertos.org/t/new-free-trace-tool-from-percepio/22678) 4.10.3 since the TCB retrieval on the traced core is performed by calling `pxCurrentTCB` (i.e. `xTaskGetCurrentTaskHandle()`). I am working with multiple cores so I have defined `TRC_CFG_RECORDER_MODE` as `TRC_RECORDER_MODE_STREAMING` inside `trcKernelPortConfig.h`. With this configuration, the FreeRTOS trace macros are defined inside `trcKernelPort.h`, starting at line 1952. I do not know the exact number of macros that can replicate the problem but `traceTASK_SWITCHED_IN()` is surely one of them. Using the code [reported above](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/5) prevents the issue.  
I have contacted ARM about the original question of this post and they confirmed that there is no architectural constraint to disable interrupts before modifying the ICC\_PMR when a Cortex-A9 is paired with a GICv1 (or GICv2), like in my case, so I could definitely solve the problem on my end by not disabling the interrupts. However, I know this is only one of the possible SoC configurations so it is not feasible to do so in general.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [April 30, 2025, 4:40pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/13 "2025-04-30T16:40:28Z")

</div>

> [@Matth9814](#):
>
> With this configuration, the FreeRTOS trace macros are defined inside `trcKernelPort.h`, starting at line 1952.

Is my understanding correct that the implementation of these macros need to be updated in the percepio library?

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [April 30, 2025, 4:50pm UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/14 "2025-04-30T16:50:02Z")

</div>

According to what has been done with FreeRTOS I suppose the macro in the Percepio View library should be updated. However, this is only a problem in multi-core and, according to my knowledge, it should not be a problem in any already contributed port that supports SMP. The issue is only present in the custom SMP Cortex-A9 port I am using, this is why I also suggested possible ways to fix it on my end.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [May 1, 2025, 6:51am UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/15 "2025-05-01T06:51:51Z")

</div>

> [@Matth9814](#):
>
> The issue is only present in the custom SMP Cortex-A9 port I am using, this is why I also suggested possible ways to fix it on my end.

You are right. If`portSET_INTERRUPT_MASK` and `portCLEAR_INTERRUPT_MASK` are implemented to support recursive calls, then this problem won’t happen. So I guess fixing it in your port is a better idea. If we do that, we can also revert the last PR we merged?

---

<div class="post-metadata">

**Author:** ![Matth9814](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/matth9814/32/5174_2.png) [@Matth9814](https://forums.freertos.org/u/Matth9814)\
**Post date:** [May 1, 2025, 10:32am UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/16 "2025-05-01T10:32:54Z")

</div>

Absolutely, I am already using [this implementation](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/5) so you can revert the merged [PR](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/11).

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [May 2, 2025, 2:18am UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/17 "2025-05-02T02:18:00Z")

</div>

Thank you for confirming @Matth9814 !

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [May 2, 2025, 4:27am UTC](https://forums.freertos.org/t/cortex-a9-port-disable-interrupts-before-writing-to-icc-pmr/22952/18 "2025-05-02T04:27:07Z")

</div>

Here is the PR to revert the change introduced in PR 1270 - [Revert PR 1270: Direct access to current TCB inside stack macros by aggarg · Pull Request #1272 · FreeRTOS/FreeRTOS-Kernel · GitHub](https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/1272).
