mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:32:42 -05:00 
			
		
		
		
	Extend the exception handling functionality in the new MicroBlaze port.
This commit is contained in:
		
							parent
							
								
									71b359154b
								
							
						
					
					
						commit
						832bbd38e1
					
				
					 4 changed files with 111 additions and 43 deletions
				
			
		| 
						 | 
					@ -71,10 +71,12 @@
 | 
				
			||||||
#define portexR12_STACK_OFFSET	13
 | 
					#define portexR12_STACK_OFFSET	13
 | 
				
			||||||
#define portexR15_STACK_OFFSET	16
 | 
					#define portexR15_STACK_OFFSET	16
 | 
				
			||||||
#define portexR18_STACK_OFFSET  18
 | 
					#define portexR18_STACK_OFFSET  18
 | 
				
			||||||
 | 
					#define portexMSR_STACK_OFFSET	19
 | 
				
			||||||
#define portexR19_STACK_OFFSET  -1
 | 
					#define portexR19_STACK_OFFSET  -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define portexESR_DS_MASK		0x00001000UL
 | 
					#define portexESR_DS_MASK		0x00001000UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Exclude the entire file if the MicroBlaze is not configured to handle
 | 
					/* Exclude the entire file if the MicroBlaze is not configured to handle
 | 
				
			||||||
exceptions, or the application defined configuration item 
 | 
					exceptions, or the application defined configuration item 
 | 
				
			||||||
| 
						 | 
					@ -82,13 +84,22 @@ configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
 | 
				
			||||||
#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
 | 
					#if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* These are global volatiles to allow their inspection by a debugger. */
 | 
					/* These are global volatiles to allow their inspection by a debugger. */
 | 
				
			||||||
unsigned long *pulStackPointerOnFunctionEntry = NULL;
 | 
					unsigned long *pulStackPointerOnFunctionEntry = NULL, ulBTROnFunctionEntry = 0UL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static xPortRegisterDump xRegisterDump;
 | 
					static xPortRegisterDump xRegisterDump;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vPortExceptionHandler( void *pvExceptionID );
 | 
					void vPortExceptionHandler( void *pvExceptionID );
 | 
				
			||||||
extern void vPortExceptionHandlerEntry( void *pvExceptionID );
 | 
					extern void vPortExceptionHandlerEntry( void *pvExceptionID );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*-----------------------------------------------------------*/
 | 
				
			||||||
 | 
					extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));
 | 
				
			||||||
 | 
					void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for( ;; )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							portNOP();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
/*-----------------------------------------------------------*/
 | 
					/*-----------------------------------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vPortExceptionHandler( void *pvExceptionID )
 | 
					void vPortExceptionHandler( void *pvExceptionID )
 | 
				
			||||||
| 
						 | 
					@ -112,14 +123,14 @@ extern void *pxCurrentTCB;
 | 
				
			||||||
	xRegisterDump.ulR10 = pulStackPointerOnFunctionEntry[ portexR10_STACK_OFFSET ];
 | 
						xRegisterDump.ulR10 = pulStackPointerOnFunctionEntry[ portexR10_STACK_OFFSET ];
 | 
				
			||||||
	xRegisterDump.ulR11 = pulStackPointerOnFunctionEntry[ portexR11_STACK_OFFSET ];
 | 
						xRegisterDump.ulR11 = pulStackPointerOnFunctionEntry[ portexR11_STACK_OFFSET ];
 | 
				
			||||||
	xRegisterDump.ulR12 = pulStackPointerOnFunctionEntry[ portexR12_STACK_OFFSET ];
 | 
						xRegisterDump.ulR12 = pulStackPointerOnFunctionEntry[ portexR12_STACK_OFFSET ];
 | 
				
			||||||
 | 
						xRegisterDump.ulR15_return_address_from_subroutine = pulStackPointerOnFunctionEntry[ portexR15_STACK_OFFSET ];
 | 
				
			||||||
 | 
						xRegisterDump.ulR18 = pulStackPointerOnFunctionEntry[ portexR18_STACK_OFFSET ];
 | 
				
			||||||
	xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];
 | 
						xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Obtain the value of all other registers. */
 | 
						/* Obtain the value of all other registers. */
 | 
				
			||||||
	//xRegisterDump.ulR1 =
 | 
					 | 
				
			||||||
	xRegisterDump.ulR2_small_data_area = mfgpr( R2 );
 | 
						xRegisterDump.ulR2_small_data_area = mfgpr( R2 );
 | 
				
			||||||
	xRegisterDump.ulR13_read_write_small_data_area = mfgpr( R13 );
 | 
						xRegisterDump.ulR13_read_write_small_data_area = mfgpr( R13 );
 | 
				
			||||||
	xRegisterDump.ulR14_return_address_from_interrupt = mfgpr( R14 );
 | 
						xRegisterDump.ulR14_return_address_from_interrupt = mfgpr( R14 );
 | 
				
			||||||
	xRegisterDump.ulR15_return_address_from_subroutine = mfgpr( R15 );
 | 
					 | 
				
			||||||
	xRegisterDump.ulR16_return_address_from_trap = mfgpr( R16 );
 | 
						xRegisterDump.ulR16_return_address_from_trap = mfgpr( R16 );
 | 
				
			||||||
	xRegisterDump.ulR17_return_address_from_some_exceptions = mfgpr( R17 );
 | 
						xRegisterDump.ulR17_return_address_from_some_exceptions = mfgpr( R17 );
 | 
				
			||||||
	xRegisterDump.ulR18 = mfgpr( R18 );
 | 
						xRegisterDump.ulR18 = mfgpr( R18 );
 | 
				
			||||||
| 
						 | 
					@ -135,8 +146,15 @@ extern void *pxCurrentTCB;
 | 
				
			||||||
	xRegisterDump.ulR29 = mfgpr( R29 );
 | 
						xRegisterDump.ulR29 = mfgpr( R29 );
 | 
				
			||||||
	xRegisterDump.ulR30 = mfgpr( R30 );
 | 
						xRegisterDump.ulR30 = mfgpr( R30 );
 | 
				
			||||||
	xRegisterDump.ulR31 = mfgpr( R31 );
 | 
						xRegisterDump.ulR31 = mfgpr( R31 );
 | 
				
			||||||
 | 
						xRegisterDump.ulR1_SP = ( ( unsigned long ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE;
 | 
				
			||||||
 | 
						xRegisterDump.ulBTR = ulBTROnFunctionEntry;
 | 
				
			||||||
 | 
						xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];
 | 
				
			||||||
 | 
						xRegisterDump.ulEAR = mfear();
 | 
				
			||||||
	xRegisterDump.ulESR = mfesr();
 | 
						xRegisterDump.ulESR = mfesr();
 | 
				
			||||||
 | 
						xRegisterDump.ulEDR = mfedr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef THIS_IS_PROBABLY_INCORRECT
 | 
				
			||||||
	if( ( xRegisterDump.ulESR * portexESR_DS_MASK ) != 0UL )
 | 
						if( ( xRegisterDump.ulESR * portexESR_DS_MASK ) != 0UL )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		xRegisterDump.ulPC = mfbtr();
 | 
							xRegisterDump.ulPC = mfbtr();
 | 
				
			||||||
| 
						 | 
					@ -145,12 +163,20 @@ extern void *pxCurrentTCB;
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;
 | 
							xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// xRegisterDump.ulSP =;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// PC changes
 | 
						#if XPAR_MICROBLAZE_0_USE_FPU == 1
 | 
				
			||||||
	// MSR changes
 | 
						{
 | 
				
			||||||
	// BTR changes
 | 
							xRegisterDump.ulFSR = mffsr();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							xRegisterDump.ulFSR = 0UL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch( ( unsigned long ) pvExceptionID )
 | 
						switch( ( unsigned long ) pvExceptionID )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -178,16 +204,22 @@ extern void *pxCurrentTCB;
 | 
				
			||||||
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_DIV_BY_ZERO";
 | 
									xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_DIV_BY_ZERO";
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case XEXC_ID_FPU :
 | 
					 | 
				
			||||||
				/*_RB_ More decoding required here and in other exceptions. */
 | 
					 | 
				
			||||||
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FPU";
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case XEXC_ID_STACK_VIOLATION :
 | 
							case XEXC_ID_STACK_VIOLATION :
 | 
				
			||||||
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
 | 
									xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#if XPAR_MICROBLAZE_0_USE_FPU == 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case XEXC_ID_FPU :
 | 
				
			||||||
 | 
											/*_RB_ More decoding required here and in other exceptions. */
 | 
				
			||||||
 | 
											xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FPU see ulFSR value";
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#endif /* XPAR_MICROBLAZE_0_USE_FPU */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vApplicationExceptionRegisterDump( &xRegisterDump );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Must not attempt to leave this function! */
 | 
						/* Must not attempt to leave this function! */
 | 
				
			||||||
	for( ;; )
 | 
						for( ;; )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -198,6 +230,12 @@ extern void *pxCurrentTCB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vPortExceptionsInstallHandlers( void )
 | 
					void vPortExceptionsInstallHandlers( void )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					static unsigned long ulHandlersAlreadyInstalled = pdFALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if( ulHandlersAlreadyInstalled == pdFALSE )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ulHandlersAlreadyInstalled = pdTRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#if XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS == 1
 | 
							#if XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS == 1
 | 
				
			||||||
			microblaze_register_exception_handler( XEXC_ID_UNALIGNED_ACCESS, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_UNALIGNED_ACCESS );
 | 
								microblaze_register_exception_handler( XEXC_ID_UNALIGNED_ACCESS, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_UNALIGNED_ACCESS );
 | 
				
			||||||
		#endif /* XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS*/
 | 
							#endif /* XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS*/
 | 
				
			||||||
| 
						 | 
					@ -233,8 +271,8 @@ void vPortExceptionsInstallHandlers( void )
 | 
				
			||||||
		#if XPAR_MICROBLAZE_0_FSL_EXCEPTION == 1
 | 
							#if XPAR_MICROBLAZE_0_FSL_EXCEPTION == 1
 | 
				
			||||||
			microblaze_register_exception_handler( XEXC_ID_FSL, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FSL );
 | 
								microblaze_register_exception_handler( XEXC_ID_FSL, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FSL );
 | 
				
			||||||
		#endif /* XPAR_MICROBLAZE_0_FSL_EXCEPTION*/
 | 
							#endif /* XPAR_MICROBLAZE_0_FSL_EXCEPTION*/
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/*-----------------------------------------------------------*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Exclude the entire file if the MicroBlaze is not configured to handle
 | 
					/* Exclude the entire file if the MicroBlaze is not configured to handle
 | 
				
			||||||
exceptions, or the application defined configuration item 
 | 
					exceptions, or the application defined configuration item 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,6 +112,7 @@ back into the caller stack. */
 | 
				
			||||||
	.extern ulTaskSwitchRequested
 | 
						.extern ulTaskSwitchRequested
 | 
				
			||||||
	.extern vPortExceptionHandler
 | 
						.extern vPortExceptionHandler
 | 
				
			||||||
	.extern pulStackPointerOnFunctionEntry
 | 
						.extern pulStackPointerOnFunctionEntry
 | 
				
			||||||
 | 
						.extern ulBTROnFunctionEntry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.global _interrupt_handler
 | 
						.global _interrupt_handler
 | 
				
			||||||
	.global VPortYieldASM
 | 
						.global VPortYieldASM
 | 
				
			||||||
| 
						 | 
					@ -347,8 +348,9 @@ vPortExceptionHandlerEntry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Take a copy of the stack pointer before vPortExecptionHandler is called,
 | 
						/* Take a copy of the stack pointer before vPortExecptionHandler is called,
 | 
				
			||||||
	storing its value prior to the function stack frame being created. */
 | 
						storing its value prior to the function stack frame being created. */
 | 
				
			||||||
	lwi r18, r0, pulStackPointerOnFunctionEntry
 | 
					 | 
				
			||||||
	swi r1, r0, pulStackPointerOnFunctionEntry
 | 
						swi r1, r0, pulStackPointerOnFunctionEntry
 | 
				
			||||||
 | 
						mfs r18, RBTR
 | 
				
			||||||
 | 
						swi r18, r0, ulBTROnFunctionEntry
 | 
				
			||||||
	bralid r15, vPortExceptionHandler
 | 
						bralid r15, vPortExceptionHandler
 | 
				
			||||||
	or r0, r0, r0
 | 
						or r0, r0, r0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,7 +148,9 @@ extern volatile unsigned long ulTaskSwitchRequested;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct PORT_REGISTER_DUMP
 | 
					typedef struct PORT_REGISTER_DUMP
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long ulSP;
 | 
						/* The following structure members hold the values of the MicroBlaze
 | 
				
			||||||
 | 
						registers at the time the exception was raised. */
 | 
				
			||||||
 | 
						unsigned long ulR1_SP;
 | 
				
			||||||
	unsigned long ulR2_small_data_area;
 | 
						unsigned long ulR2_small_data_area;
 | 
				
			||||||
	unsigned long ulR3;
 | 
						unsigned long ulR3;
 | 
				
			||||||
	unsigned long ulR4;
 | 
						unsigned long ulR4;
 | 
				
			||||||
| 
						 | 
					@ -181,12 +183,30 @@ typedef struct PORT_REGISTER_DUMP
 | 
				
			||||||
	unsigned long ulR31;
 | 
						unsigned long ulR31;
 | 
				
			||||||
	unsigned long ulPC;
 | 
						unsigned long ulPC;
 | 
				
			||||||
	unsigned long ulESR;
 | 
						unsigned long ulESR;
 | 
				
			||||||
 | 
						unsigned long ulBTR;
 | 
				
			||||||
 | 
						unsigned long ulMSR;
 | 
				
			||||||
 | 
						unsigned long ulEAR;
 | 
				
			||||||
 | 
						unsigned long ulFSR;
 | 
				
			||||||
 | 
						unsigned long ulEDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* A human readable description of the exception cause.  The strings used
 | 
				
			||||||
 | 
						are the same as the #define constant names found in the
 | 
				
			||||||
 | 
						microblaze_exceptions_i.h header file */
 | 
				
			||||||
	signed char *pcExceptionCause;
 | 
						signed char *pcExceptionCause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The human readable name of the task that was running at the time the
 | 
				
			||||||
 | 
						exception occurred.  This is the name that was given to the task when the
 | 
				
			||||||
 | 
						task was created using the FreeRTOS xTaskCreate() API function. */
 | 
				
			||||||
	signed char *pcCurrentTaskName;
 | 
						signed char *pcCurrentTaskName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The handle of the task that was running a the time the exception
 | 
				
			||||||
 | 
						occurred. */
 | 
				
			||||||
	void * xCurrentTaskHandle;
 | 
						void * xCurrentTaskHandle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} xPortRegisterDump;
 | 
					} xPortRegisterDump;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vPortExceptionsInstallHandlers( void );
 | 
					void vPortExceptionsInstallHandlers( void );
 | 
				
			||||||
 | 
					void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -550,3 +550,11 @@ static void prvSetupHardware( void )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/*-----------------------------------------------------------*/
 | 
					/*-----------------------------------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for( ;; )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							portNOP();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue