Skip to content

Commit b13e269

Browse files
authored
Work around SysTick bug for QEMU ARMv8-M (#724)
* Set SysTick CLKSOURCE bit before enabling SysTick * Use portNVIC_SYSTICK_CLK_BIT_CONFIG The workaround now uses portNVIC_SYSTICK_CLK_BIT_CONFIG instead of portNVIC_SYSTICK_CLK_BIT, which saves us from having to explain in the comments why it's OK to temporarily set the CLKSOURCE bit even if the user's FreeRTOS configuration clears the CLKSOURCE bit. Using portNVIC_SYSTICK_CLK_BIT_CONFIG here still correctly prevents the firmware from triggering the QEMU bug.
1 parent d02ab77 commit b13e269

File tree

21 files changed

+189
-42
lines changed

21 files changed

+189
-42
lines changed

portable/ARMv8M/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM23/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM23_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM33/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM33_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM35P/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM35P_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM55/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM55_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM85/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/GCC/ARM_CM85_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM23/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM23_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM33/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM33_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM35P/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM35P_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM55/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM55_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM85/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

portable/IAR/ARM_CM85_NTZ/non_secure/port.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FU
754754
}
755755
#endif /* configUSE_TICKLESS_IDLE */
756756

757-
/* Stop and reset the SysTick. */
758-
portNVIC_SYSTICK_CTRL_REG = 0UL;
757+
/* Stop and reset SysTick.
758+
*
759+
* QEMU versions older than 7.0.0 contain a bug which causes an error if we
760+
* enable SysTick without first selecting a valid clock source. We trigger
761+
* the bug if we change clock sources from a clock with a zero clock period
762+
* to one with a nonzero clock period and enable Systick at the same time.
763+
* So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
764+
* This workaround avoids the bug in QEMU versions older than 7.0.0. */
765+
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
759766
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
760767

761768
/* Configure SysTick to interrupt at the requested rate. */

0 commit comments

Comments
 (0)