]> git.sur5r.net Git - freertos/commitdiff
Extend the exception handling functionality in the new MicroBlaze port.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 29 Jun 2011 08:50:13 +0000 (08:50 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 29 Jun 2011 08:50:13 +0000 (08:50 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1472 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port_exceptions.c
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portasm.S
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portmacro.h
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/main-full.c

index a92aedc9917b39170ffb1cbc86c2507ea7f76d3e..f963afd49a446d84351a0c6a85cca3413d8a6913 100644 (file)
 #define portexR12_STACK_OFFSET 13\r
 #define portexR15_STACK_OFFSET 16\r
 #define portexR18_STACK_OFFSET  18\r
+#define portexMSR_STACK_OFFSET 19\r
 #define portexR19_STACK_OFFSET  -1\r
 \r
 #define portexESR_DS_MASK              0x00001000UL\r
 \r
+#define portexASM_HANDLER_STACK_FRAME_SIZE 84UL\r
 \r
 /* Exclude the entire file if the MicroBlaze is not configured to handle\r
 exceptions, or the application defined configuration item \r
@@ -82,13 +84,22 @@ configINSTALL_EXCEPTION_HANDLERS is not set to 1. */
 #if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )\r
 \r
 /* These are global volatiles to allow their inspection by a debugger. */\r
-unsigned long *pulStackPointerOnFunctionEntry = NULL;\r
+unsigned long *pulStackPointerOnFunctionEntry = NULL, ulBTROnFunctionEntry = 0UL;\r
 \r
 static xPortRegisterDump xRegisterDump;\r
 \r
 void vPortExceptionHandler( void *pvExceptionID );\r
 extern void vPortExceptionHandlerEntry( void *pvExceptionID );\r
 \r
+/*-----------------------------------------------------------*/\r
+extern void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump ) __attribute__((weak));\r
+void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )\r
+{\r
+       for( ;; )\r
+       {\r
+               portNOP();\r
+       }\r
+}\r
 /*-----------------------------------------------------------*/\r
 \r
 void vPortExceptionHandler( void *pvExceptionID )\r
@@ -112,14 +123,14 @@ extern void *pxCurrentTCB;
        xRegisterDump.ulR10 = pulStackPointerOnFunctionEntry[ portexR10_STACK_OFFSET ];\r
        xRegisterDump.ulR11 = pulStackPointerOnFunctionEntry[ portexR11_STACK_OFFSET ];\r
        xRegisterDump.ulR12 = pulStackPointerOnFunctionEntry[ portexR12_STACK_OFFSET ];\r
+       xRegisterDump.ulR15_return_address_from_subroutine = pulStackPointerOnFunctionEntry[ portexR15_STACK_OFFSET ];\r
+       xRegisterDump.ulR18 = pulStackPointerOnFunctionEntry[ portexR18_STACK_OFFSET ];\r
        xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];\r
 \r
        /* Obtain the value of all other registers. */\r
-       //xRegisterDump.ulR1 =\r
        xRegisterDump.ulR2_small_data_area = mfgpr( R2 );\r
        xRegisterDump.ulR13_read_write_small_data_area = mfgpr( R13 );\r
        xRegisterDump.ulR14_return_address_from_interrupt = mfgpr( R14 );\r
-       xRegisterDump.ulR15_return_address_from_subroutine = mfgpr( R15 );\r
        xRegisterDump.ulR16_return_address_from_trap = mfgpr( R16 );\r
        xRegisterDump.ulR17_return_address_from_some_exceptions = mfgpr( R17 );\r
        xRegisterDump.ulR18 = mfgpr( R18 );\r
@@ -135,8 +146,15 @@ extern void *pxCurrentTCB;
        xRegisterDump.ulR29 = mfgpr( R29 );\r
        xRegisterDump.ulR30 = mfgpr( R30 );\r
        xRegisterDump.ulR31 = mfgpr( R31 );\r
-\r
+       xRegisterDump.ulR1_SP = ( ( unsigned long ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE;\r
+       xRegisterDump.ulBTR = ulBTROnFunctionEntry;\r
+       xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];\r
+       xRegisterDump.ulEAR = mfear();\r
        xRegisterDump.ulESR = mfesr();\r
+       xRegisterDump.ulEDR = mfedr();\r
+\r
+\r
+#ifdef THIS_IS_PROBABLY_INCORRECT\r
        if( ( xRegisterDump.ulESR * portexESR_DS_MASK ) != 0UL )\r
        {\r
                xRegisterDump.ulPC = mfbtr();\r
@@ -145,12 +163,20 @@ extern void *pxCurrentTCB;
        {\r
                xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;\r
        }\r
+#else\r
+       xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_some_exceptions - 4;\r
+#endif\r
 \r
-       // xRegisterDump.ulSP =;\r
 \r
-       // PC changes\r
-       // MSR changes\r
-       // BTR changes\r
+       #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
+       {\r
+               xRegisterDump.ulFSR = mffsr();\r
+       }\r
+       #else\r
+       {\r
+               xRegisterDump.ulFSR = 0UL;\r
+       }\r
+       #endif\r
 \r
        switch( ( unsigned long ) pvExceptionID )\r
        {\r
@@ -178,16 +204,22 @@ extern void *pxCurrentTCB;
                                xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_DIV_BY_ZERO";\r
                                break;\r
 \r
-               case XEXC_ID_FPU :\r
-                               /*_RB_ More decoding required here and in other exceptions. */\r
-                               xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FPU";\r
-                               break;\r
-\r
                case XEXC_ID_STACK_VIOLATION :\r
                                xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";\r
                                break;\r
+\r
+               #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
+\r
+                       case XEXC_ID_FPU :\r
+                                               /*_RB_ More decoding required here and in other exceptions. */\r
+                                               xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FPU see ulFSR value";\r
+                                               break;\r
+\r
+               #endif /* XPAR_MICROBLAZE_0_USE_FPU */\r
        }\r
 \r
+       vApplicationExceptionRegisterDump( &xRegisterDump );\r
+\r
        /* Must not attempt to leave this function! */\r
        for( ;; )\r
        {\r
@@ -198,43 +230,49 @@ extern void *pxCurrentTCB;
 \r
 void vPortExceptionsInstallHandlers( void )\r
 {\r
-       #if XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS == 1\r
-               microblaze_register_exception_handler( XEXC_ID_UNALIGNED_ACCESS, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_UNALIGNED_ACCESS );\r
-       #endif /* XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS*/\r
+static unsigned long ulHandlersAlreadyInstalled = pdFALSE;\r
+\r
+       if( ulHandlersAlreadyInstalled == pdFALSE )\r
+       {\r
+               ulHandlersAlreadyInstalled = pdTRUE;\r
 \r
-       #if XPAR_MICROBLAZE_0_ILL_OPCODE_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_ILLEGAL_OPCODE, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_ILLEGAL_OPCODE );\r
-       #endif /* XPAR_MICROBLAZE_0_ILL_OPCODE_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_UNALIGNED_ACCESS, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_UNALIGNED_ACCESS );\r
+               #endif /* XPAR_MICROBLAZE_0_UNALIGNED_EXCEPTIONS*/\r
 \r
-       #if XPAR_MICROBLAZE_0_M_AXI_I_BUS_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_M_AXI_I_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_I_EXCEPTION );\r
-       #endif /* XPAR_MICROBLAZE_0_M_AXI_I_BUS_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_ILL_OPCODE_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_ILLEGAL_OPCODE, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_ILLEGAL_OPCODE );\r
+               #endif /* XPAR_MICROBLAZE_0_ILL_OPCODE_EXCEPTION*/\r
 \r
-       #if XPAR_MICROBLAZE_0_M_AXI_D_BUS_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_M_AXI_D_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_D_EXCEPTION );\r
-       #endif /* XPAR_MICROBLAZE_0_M_AXI_D_BUS_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_M_AXI_I_BUS_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_M_AXI_I_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_I_EXCEPTION );\r
+               #endif /* XPAR_MICROBLAZE_0_M_AXI_I_BUS_EXCEPTION*/\r
 \r
-       #if XPAR_MICROBLAZE_0_IPLB_BUS_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_IPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_IPLB_EXCEPTION );\r
-       #endif /* XPAR_MICROBLAZE_0_IPLB_BUS_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_M_AXI_D_BUS_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_M_AXI_D_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_M_AXI_D_EXCEPTION );\r
+               #endif /* XPAR_MICROBLAZE_0_M_AXI_D_BUS_EXCEPTION*/\r
 \r
-       #if XPAR_MICROBLAZE_0_DPLB_BUS_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_DPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DPLB_EXCEPTION );\r
-       #endif /* XPAR_MICROBLAZE_0_DPLB_BUS_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_IPLB_BUS_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_IPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_IPLB_EXCEPTION );\r
+               #endif /* XPAR_MICROBLAZE_0_IPLB_BUS_EXCEPTION*/\r
 \r
-       #if XPAR_MICROBLAZE_0_DIV_ZERO_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_DIV_BY_ZERO, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DIV_BY_ZERO );\r
-       #endif /* XPAR_MICROBLAZE_0_DIV_ZERO_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_DPLB_BUS_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_DPLB_EXCEPTION, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DPLB_EXCEPTION );\r
+               #endif /* XPAR_MICROBLAZE_0_DPLB_BUS_EXCEPTION*/\r
 \r
-       #if XPAR_MICROBLAZE_0_FPU_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_FPU, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FPU );\r
-       #endif /* XPAR_MICROBLAZE_0_FPU_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_DIV_ZERO_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_DIV_BY_ZERO, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_DIV_BY_ZERO );\r
+               #endif /* XPAR_MICROBLAZE_0_DIV_ZERO_EXCEPTION*/\r
 \r
-       #if XPAR_MICROBLAZE_0_FSL_EXCEPTION == 1\r
-               microblaze_register_exception_handler( XEXC_ID_FSL, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FSL );\r
-       #endif /* XPAR_MICROBLAZE_0_FSL_EXCEPTION*/\r
+               #if XPAR_MICROBLAZE_0_FPU_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_FPU, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FPU );\r
+               #endif /* XPAR_MICROBLAZE_0_FPU_EXCEPTION*/\r
+\r
+               #if XPAR_MICROBLAZE_0_FSL_EXCEPTION == 1\r
+                       microblaze_register_exception_handler( XEXC_ID_FSL, vPortExceptionHandlerEntry, ( void * ) XEXC_ID_FSL );\r
+               #endif /* XPAR_MICROBLAZE_0_FSL_EXCEPTION*/\r
+       }\r
 }\r
-/*-----------------------------------------------------------*/\r
 \r
 /* Exclude the entire file if the MicroBlaze is not configured to handle\r
 exceptions, or the application defined configuration item \r
index a10c7319382e5f3be6c4c5628f2048305b034ac2..68908775545caa29439d128f2a09632bced079a4 100644 (file)
@@ -112,6 +112,7 @@ back into the caller stack. */
        .extern ulTaskSwitchRequested\r
        .extern vPortExceptionHandler\r
        .extern pulStackPointerOnFunctionEntry\r
+       .extern ulBTROnFunctionEntry\r
 \r
        .global _interrupt_handler\r
        .global VPortYieldASM\r
@@ -347,8 +348,9 @@ vPortExceptionHandlerEntry:
 \r
        /* Take a copy of the stack pointer before vPortExecptionHandler is called,\r
        storing its value prior to the function stack frame being created. */\r
-       lwi r18, r0, pulStackPointerOnFunctionEntry\r
        swi r1, r0, pulStackPointerOnFunctionEntry\r
+       mfs r18, RBTR\r
+       swi r18, r0, ulBTROnFunctionEntry\r
        bralid r15, vPortExceptionHandler\r
        or r0, r0, r0\r
 \r
index 015144bb9ba95ae3aecf6cc858edb97d7078bcac..c14bbc7bfc6a5347fd7862fab3c9be4d096a8e20 100644 (file)
@@ -148,7 +148,9 @@ extern volatile unsigned long ulTaskSwitchRequested;
 \r
 typedef struct PORT_REGISTER_DUMP\r
 {\r
-       unsigned long ulSP;\r
+       /* The following structure members hold the values of the MicroBlaze\r
+       registers at the time the exception was raised. */\r
+       unsigned long ulR1_SP;\r
        unsigned long ulR2_small_data_area;\r
        unsigned long ulR3;\r
        unsigned long ulR4;\r
@@ -181,12 +183,30 @@ typedef struct PORT_REGISTER_DUMP
        unsigned long ulR31;\r
        unsigned long ulPC;\r
        unsigned long ulESR;\r
+       unsigned long ulBTR;\r
+       unsigned long ulMSR;\r
+       unsigned long ulEAR;\r
+       unsigned long ulFSR;\r
+       unsigned long ulEDR;\r
+\r
+       /* A human readable description of the exception cause.  The strings used\r
+       are the same as the #define constant names found in the\r
+       microblaze_exceptions_i.h header file */\r
        signed char *pcExceptionCause;\r
+\r
+       /* The human readable name of the task that was running at the time the\r
+       exception occurred.  This is the name that was given to the task when the\r
+       task was created using the FreeRTOS xTaskCreate() API function. */\r
        signed char *pcCurrentTaskName;\r
+\r
+       /* The handle of the task that was running a the time the exception\r
+       occurred. */\r
        void * xCurrentTaskHandle;\r
+\r
 } xPortRegisterDump;\r
 \r
 void vPortExceptionsInstallHandlers( void );\r
+void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump );\r
 \r
 #ifdef __cplusplus\r
 }\r
index 301197736c8d3994fb3c5b600864725fb7a82e09..ab566c1494ccf393bd263aa98757d4a266e72cd1 100644 (file)
@@ -550,3 +550,11 @@ static void prvSetupHardware( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+void vApplicationExceptionRegisterDump( xPortRegisterDump *xRegisterDump )\r
+{\r
+       for( ;; )\r
+       {\r
+               portNOP();\r
+       }\r
+}\r
+\r