mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Extend the exception handling functionality in the new MicroBlaze port.
This commit is contained in:
parent
71b359154b
commit
832bbd38e1
|
@ -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…
Reference in a new issue