138
138
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
139
139
140
140
/* The space on the stack required to hold the FPU registers.
141
- * There are 32 128-bit plus 2 64-bit status registers.*/
141
+ * There are 32 128-bit plus 2 64-bit status registers. */
142
142
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 2 )
143
143
144
144
/*-----------------------------------------------------------*/
@@ -173,7 +173,7 @@ extern void vGIC_EnableCPUInterface( void );
173
173
volatile uint64_t ullCriticalNestings [ configNUMBER_OF_CORES ] = { 0 };
174
174
175
175
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
176
- * then floating point context must be saved and restored for the task. */
176
+ * then floating point context must be saved and restored for the task. */
177
177
uint64_t ullPortTaskHasFPUContext [ configNUMBER_OF_CORES ] = { pdFALSE };
178
178
uint64_t ullPortYieldRequired [ configNUMBER_OF_CORES ] = { pdFALSE };
179
179
uint64_t ullPortInterruptNestings [ configNUMBER_OF_CORES ] = { 0 };
@@ -190,12 +190,12 @@ __attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API
190
190
/*
191
191
* See header file for description.
192
192
*/
193
- StackType_t * pxPortInitialiseStack ( StackType_t * pxTopOfStack ,
194
- TaskFunction_t pxCode ,
195
- void * pvParameters )
193
+ StackType_t * pxPortInitialiseStack ( StackType_t * pxTopOfStack ,
194
+ TaskFunction_t pxCode ,
195
+ void * pvParameters )
196
196
{
197
197
/* Setup the initial stack of the task. The stack is set exactly as
198
- * expected by the portRESTORE_CONTEXT() macro. */
198
+ * expected by the portRESTORE_CONTEXT() macro. */
199
199
200
200
/* First all the general purpose registers. */
201
201
pxTopOfStack -- ;
@@ -272,25 +272,25 @@ __attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API
272
272
#if ( configUSE_TASK_FPU_SUPPORT == portTASK_NO_FPU_CONTEXT_BY_DEFAULT )
273
273
{
274
274
/* The task will start with a critical nesting count of 0 as interrupts are
275
- * enabled. */
275
+ * enabled. */
276
276
pxTopOfStack -- ;
277
277
* pxTopOfStack = portNO_CRITICAL_NESTING ;
278
278
279
279
/* The task will start without a floating point context. A task that
280
- * uses the floating point hardware must call vPortTaskUsesFPU() before
281
- * executing any floating point instructions. */
280
+ * uses the floating point hardware must call vPortTaskUsesFPU() before
281
+ * executing any floating point instructions. */
282
282
pxTopOfStack -- ;
283
283
* pxTopOfStack = portNO_FLOATING_POINT_CONTEXT ;
284
284
}
285
285
#elif ( configUSE_TASK_FPU_SUPPORT == portTASK_HAVE_FPU_CONTEXT_BY_DEFAULT )
286
286
{
287
287
/* The task will start with a floating point context. Leave enough
288
- * space for the registers - and ensure they are initialised to 0. */
288
+ * space for the registers - and ensure they are initialised to 0. */
289
289
pxTopOfStack -= portFPU_REGISTER_WORDS ;
290
290
memset ( pxTopOfStack , 0x00 , portFPU_REGISTER_WORDS * sizeof ( StackType_t ) );
291
291
292
292
/* The task will start with a critical nesting count of 0 as interrupts are
293
- * enabled. */
293
+ * enabled. */
294
294
pxTopOfStack -- ;
295
295
* pxTopOfStack = portNO_CRITICAL_NESTING ;
296
296
@@ -321,18 +321,18 @@ BaseType_t xPortStartScheduler( void )
321
321
#if ( configASSERT_DEFINED == 1 )
322
322
{
323
323
if ( portGET_CORE_ID () == 0 )
324
- {
324
+ {
325
325
volatile uint8_t ucOriginalPriority ;
326
326
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
327
327
volatile uint8_t ucMaxPriorityValue ;
328
328
329
329
/* Determine how many priority bits are implemented in the GIC.
330
- *
331
- * Save the interrupt priority value that is about to be clobbered. */
330
+ *
331
+ * Save the interrupt priority value that is about to be clobbered. */
332
332
ucOriginalPriority = * pucFirstUserPriorityRegister ;
333
333
334
334
/* Determine the number of priority bits available. First write to
335
- * all possible bits. */
335
+ * all possible bits. */
336
336
* pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE ;
337
337
338
338
/* Read the value back to see how many bits stuck. */
@@ -345,13 +345,12 @@ BaseType_t xPortStartScheduler( void )
345
345
}
346
346
347
347
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
348
- * value. */
349
-
348
+ * value. */
350
349
configASSERT ( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
351
350
352
351
353
352
/* Restore the clobbered interrupt priority register to its original
354
- * value. */
353
+ * value. */
355
354
* pucFirstUserPriorityRegister = ucOriginalPriority ;
356
355
}
357
356
}
@@ -368,14 +367,14 @@ BaseType_t xPortStartScheduler( void )
368
367
* executing. */
369
368
portDISABLE_INTERRUPTS ();
370
369
#if ( configNUMBER_OF_CORES > 1 )
371
- if ( 0 == portGET_CORE_ID () )
370
+ if ( portGET_CORE_ID () == 0 )
372
371
{
373
372
/* Start the timer that generates the tick ISR. */
374
373
configSETUP_TICK_INTERRUPT ();
375
374
ucPortSchedulerRunning = pdTRUE ;
376
- __asm__ volatile ("dsb sy" );
377
- /* Start all other Cores and let them execute vPortRestoreTaskContext()*/
378
- __asm__ volatile ("sev" );
375
+ __asm__ volatile ( "dsb sy" );
376
+ /* Start all other Cores and let them execute vPortRestoreTaskContext(). */
377
+ __asm__ volatile ( "sev" );
379
378
}
380
379
else
381
380
{
@@ -385,6 +384,7 @@ BaseType_t xPortStartScheduler( void )
385
384
/* Start the timer that generates the tick ISR. */
386
385
configSETUP_TICK_INTERRUPT ();
387
386
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
387
+
388
388
/* Start the first task executing. */
389
389
vPortRestoreTaskContext ();
390
390
@@ -455,12 +455,13 @@ void FreeRTOS_Tick_Handler( void )
455
455
__asm volatile ( "MRS %0, ICC_RPR_EL1" : "=r" ( ullRunningInterruptPriority ) );
456
456
457
457
configASSERT ( ullRunningInterruptPriority == ( portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
458
+
458
459
/* Interrupts should not be enabled before this point. */
459
460
#if ( configASSERT_DEFINED == 1 )
460
461
{
461
462
uint64_t ullMaskBits ;
462
463
463
- __asm volatile ( "mrs %0, DAIF" : "=r" ( ullMaskBits )::"memory" );
464
+ __asm volatile ( "MRS %0, DAIF" : "=r" ( ullMaskBits )::"memory" );
464
465
configASSERT ( ( ullMaskBits & portDAIF_I ) != 0 );
465
466
}
466
467
#endif /* configASSERT_DEFINED */
@@ -482,6 +483,7 @@ void FreeRTOS_Tick_Handler( void )
482
483
#if ( configNUMBER_OF_CORES > 1 )
483
484
UBaseType_t x = portENTER_CRITICAL_FROM_ISR ();
484
485
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
486
+
485
487
/* Increment the RTOS tick. */
486
488
if ( xTaskIncrementTick () != pdFALSE )
487
489
{
@@ -494,6 +496,7 @@ void FreeRTOS_Tick_Handler( void )
494
496
#if ( configNUMBER_OF_CORES > 1 )
495
497
portEXIT_CRITICAL_FROM_ISR (x );
496
498
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
499
+
497
500
/* Ensure all interrupt priorities are active again. */
498
501
portCLEAR_INTERRUPT_PRIORITIES_MASK ();
499
502
}
@@ -613,25 +616,29 @@ UBaseType_t uxPortSetInterruptMask( void )
613
616
configASSERT ( ( volatile void * ) NULL );
614
617
}
615
618
619
+ /*-----------------------------------------------------------*/
620
+
616
621
#if ( configNUMBER_OF_CORES > 1 )
617
622
618
- /* Which core owns the lock */
623
+ /* Which core owns the lock? */
619
624
volatile uint64_t ucOwnedByCore [ portMAX_CORE_COUNT ];
620
- /* Lock count a core owns */
625
+ /* Lock count a core owns. */
621
626
volatile uint64_t ucRecursionCountByLock [ eLockCount ];
622
- /* Index 0 is used for ISR lock and Index 1 is used for task lock */
627
+ /* Index 0 is used for ISR lock and Index 1 is used for task lock. */
623
628
uint32_t ulGateWord [ eLockCount ];
624
629
625
- void vInterruptCore (uint32_t ulInterruptID , uint32_t ulCoreID )
630
+ void vInterruptCore ( uint32_t ulInterruptID , uint32_t ulCoreID )
626
631
{
627
632
uint64_t ulRegVal = 0 ;
628
- uint32_t ulCoreMask = (1UL << ulCoreID );
633
+ uint32_t ulCoreMask = ( 1UL << ulCoreID );
629
634
ulRegVal |= ( (ulCoreMask & 0xFFFF ) | ( ( ulInterruptID & 0xF ) << 24U ) );
630
635
__asm__ volatile ( "msr ICC_SGI1R_EL1, %0" : : "r" ( ulRegVal ) );
631
636
__asm__ volatile ( "dsb sy" );
632
637
__asm__ volatile ( "isb sy" );
633
638
}
634
639
640
+ /*-----------------------------------------------------------*/
641
+
635
642
static inline void prvSpinUnlock ( uint32_t * ulLock )
636
643
{
637
644
__asm volatile (
@@ -646,6 +653,8 @@ UBaseType_t uxPortSetInterruptMask( void )
646
653
);
647
654
}
648
655
656
+ /*-----------------------------------------------------------*/
657
+
649
658
static inline uint32_t prvSpinTrylock ( uint32_t * ulLock )
650
659
{
651
660
register uint32_t ulRet ;
@@ -669,26 +678,32 @@ UBaseType_t uxPortSetInterruptMask( void )
669
678
return ulRet ;
670
679
}
671
680
672
- /* Read 64b value shared between cores */
681
+ /*-----------------------------------------------------------*/
682
+
683
+ /* Read 64b value shared between cores. */
673
684
static inline uint64_t prvGet64 ( volatile uint64_t * x )
674
685
{
675
686
__asm( "dsb sy" );
676
687
return * x ;
677
688
}
678
689
679
- /* Write 64b value shared between cores */
690
+ /*-----------------------------------------------------------*/
691
+
692
+ /* Write 64b value shared between cores. */
680
693
static inline void prvSet64 ( volatile uint64_t * x ,
681
694
uint64_t value )
682
695
{
683
696
* x = value ;
684
697
__asm( "dsb sy" );
685
698
}
686
699
700
+ /*-----------------------------------------------------------*/
701
+
687
702
void vPortRecursiveLock ( BaseType_t xCoreID ,
688
703
ePortRTOSLock eLockNum ,
689
704
BaseType_t uxAcquire )
690
705
{
691
- /* Validate the core ID and lock number */
706
+ /* Validate the core ID and lock number. */
692
707
configASSERT ( xCoreID < portMAX_CORE_COUNT );
693
708
configASSERT ( eLockNum < eLockCount );
694
709
@@ -697,21 +712,21 @@ UBaseType_t uxPortSetInterruptMask( void )
697
712
/* Lock acquire */
698
713
if ( uxAcquire )
699
714
{
700
- /* Check if spinlock is available */
701
- /* If spinlock is not available check if the core owns the lock */
702
- /* If the core owns the lock wait increment the lock count by the core */
703
- /* If core does not own the lock wait for the spinlock */
715
+ /* Check if spinlock is available. */
716
+ /* If spinlock is not available check if the core owns the lock. */
717
+ /* If the core owns the lock wait increment the lock count by the core. */
718
+ /* If core does not own the lock wait for the spinlock. */
704
719
if ( prvSpinTrylock ( & ulGateWord [ eLockNum ] ) != 0 )
705
720
{
706
- /* Check if the core owns the spinlock */
721
+ /* Check if the core owns the spinlock. */
707
722
if ( prvGet64 ( & ucOwnedByCore [ xCoreID ] ) & ulLockBit )
708
723
{
709
724
configASSERT ( prvGet64 ( & ucRecursionCountByLock [ eLockNum ] ) != 255u );
710
725
prvSet64 ( & ucRecursionCountByLock [ eLockNum ], ( prvGet64 ( & ucRecursionCountByLock [ eLockNum ] ) + 1 ) );
711
726
return ;
712
727
}
713
728
714
- /* Preload the gate word into the cache */
729
+ /* Preload the gate word into the cache. */
715
730
uint32_t dummy = ulGateWord [ eLockNum ];
716
731
dummy ++ ;
717
732
@@ -721,37 +736,39 @@ UBaseType_t uxPortSetInterruptMask( void )
721
736
}
722
737
}
723
738
724
- /* Add barrier to ensure lock is taken before we proceed */
739
+ /* Add barrier to ensure lock is taken before we proceed. */
725
740
__asm__ __volatile__ ( "dmb sy" ::: "memory" );
726
741
727
- /* Assert the lock count is 0 when the spinlock is free and is acquired */
742
+ /* Assert the lock count is 0 when the spinlock is free and is acquired. */
728
743
configASSERT ( prvGet64 ( & ucRecursionCountByLock [ eLockNum ] ) == 0 );
729
744
730
- /* Set lock count as 1 */
745
+ /* Set lock count as 1. */
731
746
prvSet64 ( & ucRecursionCountByLock [ eLockNum ], 1 );
732
- /* Set ucOwnedByCore */
747
+ /* Set ucOwnedByCore. */
733
748
prvSet64 ( & ucOwnedByCore [ xCoreID ], ( prvGet64 ( & ucOwnedByCore [ xCoreID ] ) | ulLockBit ) );
734
749
}
735
- /* Lock release */
750
+ /* Lock release. */
736
751
else
737
752
{
738
- /* Assert the lock is not free already */
753
+ /* Assert the lock is not free already. */
739
754
configASSERT ( ( prvGet64 ( & ucOwnedByCore [ xCoreID ] ) & ulLockBit ) != 0 );
740
755
configASSERT ( prvGet64 ( & ucRecursionCountByLock [ eLockNum ] ) != 0 );
741
756
742
- /* Reduce ucRecursionCountByLock by 1 */
757
+ /* Reduce ucRecursionCountByLock by 1. */
743
758
prvSet64 ( & ucRecursionCountByLock [ eLockNum ], ( prvGet64 ( & ucRecursionCountByLock [ eLockNum ] ) - 1 ) );
744
759
745
760
if ( !prvGet64 ( & ucRecursionCountByLock [ eLockNum ] ) )
746
761
{
747
762
prvSet64 ( & ucOwnedByCore [ xCoreID ], ( prvGet64 ( & ucOwnedByCore [ xCoreID ] ) & ~ulLockBit ) );
748
763
prvSpinUnlock ( & ulGateWord [ eLockNum ] );
749
- /* Add barrier to ensure lock status is reflected before we proceed */
764
+ /* Add barrier to ensure lock status is reflected before we proceed. */
750
765
__asm__ __volatile__ ( "dmb sy" ::: "memory" );
751
766
}
752
767
}
753
768
}
754
769
770
+ /*-----------------------------------------------------------*/
771
+
755
772
BaseType_t xPortGetCoreID ( void )
756
773
{
757
774
register BaseType_t xCoreID ;
@@ -767,6 +784,8 @@ UBaseType_t uxPortSetInterruptMask( void )
767
784
return xCoreID ;
768
785
}
769
786
787
+ /*-----------------------------------------------------------*/
788
+
770
789
void FreeRTOS_SGI_Handler ( void )
771
790
{
772
791
/* Must be the lowest possible priority. */
@@ -785,10 +804,10 @@ UBaseType_t uxPortSetInterruptMask( void )
785
804
#endif /* configASSERT_DEFINED */
786
805
787
806
/* Set interrupt mask before altering scheduler structures. The SGI
788
- * handler runs at the lowest priority, so interrupts cannot already be masked,
789
- * so there is no need to save and restore the current mask value. It is
790
- * necessary to turn off interrupts in the CPU itself while the ICCPMR is being
791
- * updated. */
807
+ * handler runs at the lowest priority, so interrupts cannot already be masked,
808
+ * so there is no need to save and restore the current mask value. It is
809
+ * necessary to turn off interrupts in the CPU itself while the ICCPMR is being
810
+ * updated. */
792
811
__asm volatile ( "MSR ICC_PMR_EL1, %0 \n"
793
812
"DSB SY \n"
794
813
"ISB SY \n"
@@ -807,4 +826,6 @@ UBaseType_t uxPortSetInterruptMask( void )
807
826
portCLEAR_INTERRUPT_PRIORITIES_MASK ();
808
827
}
809
828
829
+ /*-----------------------------------------------------------*/
830
+
810
831
#endif /* if( configNUMBER_OF_CORES > 1 ) */
0 commit comments