forked from epagris/FreeRTOS-Kernel
		
	This reverts commit 61635d5b8b7ae1e783026f37eb66757509010130.
This commit is contained in:
		
							parent
							
								
									ce39ebe45b
								
							
						
					
					
						commit
						58ffcb1a6d
					
				@ -146,20 +146,6 @@
 | 
			
		||||
    #define portTASK_RETURN_ADDRESS    prvTaskExitError
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Adding the necessary stuff in order to be able to determine from C code wheter or not the IRQs are enabled at the processor level (not interrupt controller level) */
 | 
			
		||||
#define GET_CPSR()             \
 | 
			
		||||
    ( { u32 rval = 0U;         \
 | 
			
		||||
        __asm__ __volatile__ ( \
 | 
			
		||||
            "mrs	%0, cpsr\n"\
 | 
			
		||||
            : "=r" ( rval )    \
 | 
			
		||||
            );                 \
 | 
			
		||||
        rval;                  \
 | 
			
		||||
      } )
 | 
			
		||||
 | 
			
		||||
#define CPSR_IRQ_ENABLE_MASK    0x80U
 | 
			
		||||
 | 
			
		||||
#define IS_IRQ_DISABLED()    ( { unsigned int val = 0; val = ( GET_CPSR() & CPSR_IRQ_ENABLE_MASK ) ? 1 : 0; val; } )
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@ -481,12 +467,6 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
 | 
			
		||||
uint32_t ulPortSetInterruptMask( void )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulReturn;
 | 
			
		||||
    uint32_t wasIRQDisabled;
 | 
			
		||||
 | 
			
		||||
    /* We keep track of if the IRQ are enabled in the CPU (as opposed to interrupts masked in the interrupt controller, like the intend of this function).
 | 
			
		||||
     * This is very important because when the CPU is interrupted, among other things, the hardware clears the IRQ Enable bit in the CPSR of the IRQ CPU Mode in which
 | 
			
		||||
     * we enter. */
 | 
			
		||||
    wasIRQDisabled = IS_IRQ_DISABLED();
 | 
			
		||||
 | 
			
		||||
    /* Interrupt in the CPU must be turned off while the ICCPMR is being
 | 
			
		||||
     * updated. */
 | 
			
		||||
@ -505,20 +485,7 @@ uint32_t ulPortSetInterruptMask( void )
 | 
			
		||||
                         "isb		\n"::: "memory" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Just like this function returns a value of wether or not the interrupts where masked in the interrupt controller in order to avoid race condition when
 | 
			
		||||
     * calling its matching vPortClearInterruptMask function, we needed a 'wasIRQDisabled' variable holding the state of the IRQ Enable bit in the CPSR in order
 | 
			
		||||
     * to leave that bit in it's original state. Like mentioned above, hardware automatically clear the IRQEnable bit upon trapping into IRQ Mode, so the programmer
 | 
			
		||||
     * cannot make assumption about it's state. Very rare, but very important race condition is avoided with this when this function is called in an ISR. The race
 | 
			
		||||
     * condition in question was discovered when integrating tracealyzer code. Inside the function 'void vTaskSwitchContext( void )' in tasks.c, there is a macro 'traceTASK_SWITCHED_IN();'
 | 
			
		||||
     * which gets replaced by something when using the tracing capabilities. That macro protects some critical section with matching calls to 'ulPortSetInterruptMask'
 | 
			
		||||
     * and 'vPortClearInterruptMask'. At the time of calling those functions, the interrupt mask is not set in the interrupt controller, thus the only protecting barrier
 | 
			
		||||
     * against the CPU traping into recursive interrupt was the IRQ Enable bit in the CPSR. By not taking it into acount, the very code that protects the CPU against
 | 
			
		||||
     * critical section violation just enabled it to happen : A SysTick was waiting to happen, and calling 'portCPU_IRQ_ENABLE' would enable it to occur... Thus triggering a
 | 
			
		||||
     * switch of context while already performing a switch context. */
 | 
			
		||||
    if( !wasIRQDisabled )
 | 
			
		||||
    {
 | 
			
		||||
        portCPU_IRQ_ENABLE();
 | 
			
		||||
    }
 | 
			
		||||
    portCPU_IRQ_ENABLE();
 | 
			
		||||
 | 
			
		||||
    return ulReturn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user