]> git.sur5r.net Git - freertos/commitdiff
Add optional FPU support to the MicroBlaze code.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 15 Jun 2011 16:42:04 +0000 (16:42 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 15 Jun 2011 16:42:04 +0000 (16:42 +0000)
Rearrange the order in which registers are saved to the stack in an interrupt to make it more logical, and introduce #defines for the offset from the stack pointer for each variable.

git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1459 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/port.c
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/FreeRTOS_Source/portable/GCC/MicroBlaze/portasm.S

index 38d271c55d1998e1015ccfd5795d02c8d2b5085f..11dc1aedcecbb70ba1dc78798ccba72f0c360882 100644 (file)
@@ -64,6 +64,7 @@
 #include <string.h>\r
 \r
 /* Hardware includes. */\r
+#include <xparameters.h>\r
 #include <xintc.h>\r
 #include <xintc_i.h>\r
 #include <xtmrctr.h>\r
@@ -78,6 +79,7 @@ to reach zero, so it is initialised to a high value. */
 /* The bit within the MSR register that enabled/disables interrupts. */\r
 #define portMSR_IE                                     ( 0x02U )\r
 \r
+#define portINITIAL_FSR                                ( 0U )\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -138,6 +140,18 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;\r
        pxTopOfStack--;\r
 \r
+       #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
+               /* The FSR value placed in the initial task context is just 0. */\r
+               *pxTopOfStack = portINITIAL_FSR;\r
+               pxTopOfStack--;\r
+       #endif\r
+\r
+       /* The MSR value placed in the initial task context should have interrupts\r
+       disabled.  Each task will enable interrupts automatically when it enters\r
+       the running state for the first time. */\r
+       *pxTopOfStack = mfmsr() & ~portMSR_IE;\r
+       pxTopOfStack--;\r
+\r
        /* First stack an initial value for the critical section nesting.  This\r
        is initialised to zero. */\r
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00;\r
@@ -205,13 +219,6 @@ const unsigned long ulR13 = ( unsigned long ) &_SDA_BASE_;
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) 0x1e;        /* R30 - must be saved across function calls. Callee-save. */\r
        pxTopOfStack--;\r
-\r
-       /* The MSR is stacked between R30 and R31.  This should have interrupts\r
-       disabled.  Each task will enable interrupts automatically when it enters\r
-       the running state for the first time. */\r
-       *pxTopOfStack = mfmsr() & ~portMSR_IE;\r
-       pxTopOfStack--;\r
-\r
        *pxTopOfStack = ( portSTACK_TYPE ) 0x1f;        /* R31 - must be saved across function calls. Callee-save. */\r
        pxTopOfStack--;\r
 \r
@@ -230,12 +237,8 @@ extern unsigned long _stack[];
        this function is called. */\r
        vApplicationSetupTimerInterrupt();\r
 \r
-       /* Reuse the stack from main as the stack for the interrupts/exceptions.\r
-       The value is adjusted slightly to allow functions called from the\r
-       interrupts/exceptions to write back into the stack of the interrupt/\r
-       exception function itself. */\r
+       /* Reuse the stack from main as the stack for the interrupts/exceptions. */\r
        pulISRStack = ( unsigned long * ) _stack;\r
-       pulISRStack -= 2;\r
 \r
        /* Restore the context of the first task that is going to run.  From here\r
        on, the created tasks will be executing. */\r
index ed32a5b2855cac490785615812c12f4b8ac1f688..2621c6ead74c29c7d951ec9754bf14407dfef156 100644 (file)
 */\r
 \r
 #include "FreeRTOSConfig.h"\r
+#include "xparameters.h"\r
+\r
+/* The context is oversized to allow functions called from the ISR to write\r
+back into the caller stack. */\r
+#if XPAR_MICROBLAZE_0_USE_FPU == 1\r
+       #define portCONTEXT_SIZE 136\r
+#else\r
+       #define portCONTEXT_SIZE 132\r
+#endif\r
+\r
+/* Offsets from the stack pointer at which saved registers are placed. */\r
+#define portR31_OFFSET 4\r
+#define portR30_OFFSET 8\r
+#define portR29_OFFSET 12\r
+#define portR28_OFFSET 16\r
+#define portR27_OFFSET 20\r
+#define portR26_OFFSET 24\r
+#define portR25_OFFSET 28\r
+#define portR24_OFFSET 32\r
+#define portR23_OFFSET 36\r
+#define portR22_OFFSET 40\r
+#define portR21_OFFSET 44\r
+#define portR20_OFFSET 48\r
+#define portR19_OFFSET 52\r
+#define portR18_OFFSET 56\r
+#define portR17_OFFSET 60\r
+#define portR16_OFFSET 64\r
+#define portR15_OFFSET 68\r
+#define portR14_OFFSET 72\r
+#define portR13_OFFSET 76\r
+#define portR12_OFFSET 80\r
+#define portR11_OFFSET 84\r
+#define portR10_OFFSET 88\r
+#define portR9_OFFSET  92\r
+#define portR8_OFFSET  96\r
+#define portR7_OFFSET  100\r
+#define portR6_OFFSET  104\r
+#define portR5_OFFSET  108\r
+#define portR4_OFFSET  112\r
+#define portR3_OFFSET  116\r
+#define portR2_OFFSET  120\r
+#define portCRITICAL_NESTING_OFFSET 124\r
+#define portMSR_OFFSET 128\r
+#define portFSR_OFFSET 132\r
 \r
        .extern pxCurrentTCB\r
        .extern XIntc_DeviceInterruptHandler\r
 .macro portSAVE_CONTEXT\r
 \r
        /* Make room for the context on the stack. */\r
-       addik r1, r1, -132\r
-\r
-       /* Save r31 so it can then be used as a temporary. */\r
-       swi r31, r1, 4\r
-\r
-       /* Copy the msr into r31 - this is stacked later. */\r
-       mfs r31, rmsr\r
+       addik r1, r1, -portCONTEXT_SIZE\r
 \r
        /* Stack general registers. */\r
-       swi r30, r1, 12\r
-       swi r29, r1, 16\r
-       swi r28, r1, 20\r
-       swi r27, r1, 24\r
-       swi r26, r1, 28\r
-       swi r25, r1, 32\r
-       swi r24, r1, 36\r
-       swi r23, r1, 40\r
-       swi r22, r1, 44\r
-       swi r21, r1, 48\r
-       swi r20, r1, 52\r
-       swi r19, r1, 56\r
-       swi r18, r1, 60\r
-       swi r17, r1, 64\r
-       swi r16, r1, 68\r
-       swi r15, r1, 72\r
-       swi r13, r1, 80\r
-       swi r12, r1, 84\r
-       swi r11, r1, 88\r
-       swi r10, r1, 92\r
-       swi r9, r1, 96\r
-       swi r8, r1, 100\r
-       swi r7, r1, 104\r
-       swi r6, r1, 108\r
-       swi r5, r1, 112\r
-       swi r4, r1, 116\r
-       swi r3, r1, 120\r
-       swi r2, r1, 124\r
+       swi r31, r1, portR31_OFFSET\r
+       swi r30, r1, portR30_OFFSET\r
+       swi r29, r1, portR29_OFFSET\r
+       swi r28, r1, portR28_OFFSET\r
+       swi r27, r1, portR27_OFFSET\r
+       swi r26, r1, portR26_OFFSET\r
+       swi r25, r1, portR25_OFFSET\r
+       swi r24, r1, portR24_OFFSET\r
+       swi r23, r1, portR23_OFFSET\r
+       swi r22, r1, portR22_OFFSET\r
+       swi r21, r1, portR21_OFFSET\r
+       swi r20, r1, portR20_OFFSET\r
+       swi r19, r1, portR19_OFFSET\r
+       swi r18, r1, portR18_OFFSET\r
+       swi r17, r1, portR17_OFFSET\r
+       swi r16, r1, portR16_OFFSET\r
+       swi r15, r1, portR15_OFFSET\r
+       /* R14 is saved later as it needs adjustment if a yield is performed. */\r
+       swi r13, r1, portR13_OFFSET\r
+       swi r12, r1, portR12_OFFSET\r
+       swi r11, r1, portR11_OFFSET\r
+       swi r10, r1, portR10_OFFSET\r
+       swi r9, r1, portR9_OFFSET\r
+       swi r8, r1, portR8_OFFSET\r
+       swi r7, r1, portR7_OFFSET\r
+       swi r6, r1, portR6_OFFSET\r
+       swi r5, r1, portR5_OFFSET\r
+       swi r4, r1, portR4_OFFSET\r
+       swi r3, r1, portR3_OFFSET\r
+       swi r2, r1, portR2_OFFSET\r
 \r
        /* Stack the critical section nesting value. */\r
-       lwi r3, r0, uxCriticalNesting\r
-       swi r3, r1, 128\r
+       lwi r18, r0, uxCriticalNesting\r
+       swi r18, r1, portCRITICAL_NESTING_OFFSET\r
+\r
+       /* Stack MSR. */\r
+       mfs r18, rmsr\r
+       swi r18, r1, portMSR_OFFSET\r
+\r
+       #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
+               /* Stack FSR. */\r
+               mfs r18, rfsr\r
+               swi r18, r1, portFSR_OFFSET\r
+       #endif\r
 \r
        /* Save the top of stack value to the TCB. */\r
        lwi r3, r0, pxCurrentTCB\r
 .macro portRESTORE_CONTEXT\r
 \r
        /* Load the top of stack value from the TCB. */\r
-       lwi r3, r0, pxCurrentTCB\r
-       lw      r1, r0, r3      \r
+       lwi r18, r0, pxCurrentTCB\r
+       lw      r1, r0, r18\r
 \r
        /* Restore the general registers. */\r
-       lwi r31, r1, 4          \r
-       lwi r30, r1, 12         \r
-       lwi r29, r1, 16 \r
-       lwi r28, r1, 20 \r
-       lwi r27, r1, 24 \r
-       lwi r26, r1, 28 \r
-       lwi r25, r1, 32 \r
-       lwi r24, r1, 36 \r
-       lwi r23, r1, 40 \r
-       lwi r22, r1, 44 \r
-       lwi r21, r1, 48 \r
-       lwi r20, r1, 52 \r
-       lwi r19, r1, 56 \r
-       lwi r18, r1, 60 \r
-       lwi r17, r1, 64 \r
-       lwi r16, r1, 68 \r
-       lwi r15, r1, 72 \r
-       lwi r14, r1, 76 \r
-       lwi r13, r1, 80 \r
-       lwi r12, r1, 84 \r
-       lwi r11, r1, 88 \r
-       lwi r10, r1, 92 \r
-       lwi r9, r1, 96  \r
-       lwi r8, r1, 100 \r
-       lwi r7, r1, 104\r
-       lwi r6, r1, 108\r
-       lwi r5, r1, 112\r
-       lwi r4, r1, 116\r
-       lwi r2, r1, 124\r
+       lwi r31, r1, portR31_OFFSET\r
+       lwi r30, r1, portR30_OFFSET\r
+       lwi r29, r1, portR29_OFFSET\r
+       lwi r28, r1, portR28_OFFSET\r
+       lwi r27, r1, portR27_OFFSET\r
+       lwi r26, r1, portR26_OFFSET\r
+       lwi r25, r1, portR25_OFFSET\r
+       lwi r24, r1, portR24_OFFSET\r
+       lwi r23, r1, portR23_OFFSET\r
+       lwi r22, r1, portR22_OFFSET\r
+       lwi r21, r1, portR21_OFFSET\r
+       lwi r20, r1, portR20_OFFSET\r
+       lwi r19, r1, portR19_OFFSET\r
+       lwi r17, r1, portR17_OFFSET\r
+       lwi r16, r1, portR16_OFFSET\r
+       lwi r15, r1, portR15_OFFSET\r
+       lwi r14, r1, portR14_OFFSET\r
+       lwi r13, r1, portR13_OFFSET\r
+       lwi r12, r1, portR12_OFFSET\r
+       lwi r11, r1, portR11_OFFSET\r
+       lwi r10, r1, portR10_OFFSET\r
+       lwi r9, r1, portR9_OFFSET\r
+       lwi r8, r1, portR8_OFFSET\r
+       lwi r7, r1, portR7_OFFSET\r
+       lwi r6, r1, portR6_OFFSET\r
+       lwi r5, r1, portR5_OFFSET\r
+       lwi r4, r1, portR4_OFFSET\r
+       lwi r3, r1, portR3_OFFSET\r
+       lwi r2, r1, portR2_OFFSET\r
 \r
        /* Reload the rmsr from the stack. */\r
-       lwi r3, r1, 8\r
-       mts rmsr, r3\r
+       lwi r18, r1, portMSR_OFFSET\r
+       mts rmsr, r18\r
+\r
+       #if XPAR_MICROBLAZE_0_USE_FPU == 1\r
+               /* Reload the FSR from the stack. */\r
+               lwi r18, r1, portFSR_OFFSET\r
+               mts rfsr, r18\r
+       #endif\r
 \r
        /* Load the critical nesting value. */\r
-       lwi r3, r1, 128\r
-       swi r3, r0, uxCriticalNesting\r
+       lwi r18, r1, portCRITICAL_NESTING_OFFSET\r
+       swi r18, r0, uxCriticalNesting\r
 \r
        /* Test the critical nesting value.  If it is non zero then the task last\r
        exited the running state using a yield.  If it is zero, then the task\r
        last exited the running state through an interrupt. */\r
-       xori r3, r3, 0\r
-       bnei r3, exit_from_yield\r
+       xori r18, r18, 0\r
+       bnei r18, exit_from_yield\r
 \r
-       /* r3 was being used as a temporary.  Now restore its true value from the\r
+       /* r18 was being used as a temporary.  Now restore its true value from the\r
        stack. */\r
-       lwi r3, r1, 120\r
+       lwi r18, r1, portR18_OFFSET\r
 \r
        /* Remove the stack frame. */\r
-       addik r1, r1, 132\r
+       addik r1, r1, portCONTEXT_SIZE\r
 \r
        /* Return using rtid so interrupts are re-enabled as this function is\r
        exited. */\r
 \r
        .endm\r
 \r
-       .text\r
-       .align  2\r
-\r
 /* This function is used to exit portRESTORE_CONTEXT() if the task being\r
 returned to last left the Running state by calling taskYIELD() (rather than\r
 being preempted by an interrupt. */\r
+       .text\r
+       .align  2\r
 exit_from_yield:\r
 \r
-       /* r3 was being used as a temporary.  Now restore its true value from the\r
+       /* r18 was being used as a temporary.  Now restore its true value from the\r
        stack. */\r
-       lwi r3, r1, 120\r
+       lwi r18, r1, portR18_OFFSET\r
 \r
        /* Remove the stack frame. */\r
-       addik r1, r1, 132\r
+       addik r1, r1, portCONTEXT_SIZE\r
 \r
        /* Return to the task. */\r
        rtsd r14, 0\r
        or r0, r0, r0\r
 \r
 \r
+       .text\r
+       .align  2\r
 _interrupt_handler:\r
 \r
        portSAVE_CONTEXT\r
 \r
-       /* Stack msr. */\r
-       swi r31, r1, 8\r
-\r
        /* Stack the return address. */\r
-       swi r14, r1, 76\r
+       swi r14, r1, portR14_OFFSET\r
 \r
        /* Switch to the ISR stack.  The pulISRStack value has already been set to\r
        leave space for the caller function to write back into the stack of this\r
@@ -232,17 +286,16 @@ _interrupt_handler:
        portRESTORE_CONTEXT\r
 \r
 \r
+       .text\r
+       .align  2\r
 VPortYieldASM:\r
 \r
        portSAVE_CONTEXT\r
 \r
-       /* Stack msr. */\r
-       swi r31, r1, 8\r
-\r
        /* Modify the return address so a return is done to the instruction after\r
        the call to VPortYieldASM. */\r
        addi r14, r14, 8\r
-       swi r14, r1, 76\r
+       swi r14, r1, portR14_OFFSET\r
 \r
        /* Switch to use the ISR stack. */\r
        lwi r1, r0, pulISRStack\r
@@ -254,6 +307,8 @@ VPortYieldASM:
        /* Restore the context of the next task scheduled to execute. */\r
        portRESTORE_CONTEXT\r
 \r
+       .text\r
+       .align  2\r
 vPortStartFirstTask:\r
 \r
        portRESTORE_CONTEXT\r