]> git.sur5r.net Git - freertos/commitdiff
Carry on working on the Cortex-A/GCC port layer - still a work in progress.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 22 Jan 2014 15:39:58 +0000 (15:39 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 22 Jan 2014 15:39:58 +0000 (15:39 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2171 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Source/portable/GCC/ARM_CA9/port.c
FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S
FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.h [deleted file]

index 5a354b335bae695942c29dc830707727f237041f..84a6d1db9f872075dbe07525b5ee5f3e9576e734 100644 (file)
        #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )\r
 #endif\r
 \r
+#ifndef configINSTALL_FREERTOS_VECTOR_TABLE\r
+       #warning configINSTALL_FREERTOS_VECTOR_TABLE was undefined.  Defaulting configINSTALL_FREERTOS_VECTOR_TABLE to 0.\r
+#endif\r
+\r
 /* A critical section is exited when the critical section nesting count reaches\r
 this value. */\r
 #define portNO_CRITICAL_NESTING                        ( ( uint32_t ) 0 )\r
@@ -126,7 +130,8 @@ context. */
 #define portNO_FLOATING_POINT_CONTEXT  ( ( StackType_t ) 0 )\r
 \r
 /* Constants required to setup the initial task context. */\r
-#define portINITIAL_SPSR                               ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */\r
+#warning FIQ is disabled\r
+#define portINITIAL_SPSR                               ( ( StackType_t ) 0x5f ) /* System mode, ARM mode, IRQ enabled FIQ disabled.  1f is required to enable FIQ. */\r
 #define portTHUMB_MODE_BIT                             ( ( StackType_t ) 0x20 )\r
 #define portINTERRUPT_ENABLE_BIT               ( 0x80UL )\r
 #define portTHUMB_MODE_ADDRESS                 ( 0x01UL )\r
@@ -146,12 +151,20 @@ mode. */
 #define portCLEAR_INTERRUPT_MASK()                                                                                     \\r
 {                                                                                                                                                      \\r
        __asm volatile ( "cpsid i" );                                                                                   \\r
+       __asm volatile ( "dsb" );                                                                                               \\r
+       __asm volatile ( "isb" );                                                                                               \\r
        portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE;                                   \\r
        __asm(  "DSB            \n"                                                                                                     \\r
                        "ISB            \n" );                                                                                          \\r
        __asm volatile( "cpsie i" );                                                                                    \\r
+       __asm volatile ( "dsb" );                                                                                               \\r
+       __asm volatile ( "isb" );                                                                                               \\r
 }\r
 \r
+#define portINTERRUPT_PRIORITY_REGISTER_OFFSET         0x400UL\r
+#define portMAX_8_BIT_VALUE                                                    ( ( uint8_t ) 0xff )\r
+#define portBIT_0_SET                                                          ( ( uint8_t ) 0x01 )\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -182,6 +195,8 @@ uint32_t ulPortInterruptNesting = 0UL;
 \r
 __attribute__(( used )) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;\r
 __attribute__(( used )) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;\r
+__attribute__(( used )) const uint32_t ulICCPMR        = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;\r
+__attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -264,12 +279,54 @@ BaseType_t xPortStartScheduler( void )
 {\r
 uint32_t ulAPSR;\r
 \r
+       #if( configASSERT_DEFINED == 1 )\r
+       {\r
+               volatile uint32_t ulOriginalPriority;\r
+               volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );\r
+               volatile uint8_t ucMaxPriorityValue;\r
+\r
+               /* Determine how many priority bits are implemented in the GIC.\r
+\r
+               Save the interrupt priority value that is about to be clobbered. */\r
+               ulOriginalPriority = *pucFirstUserPriorityRegister;\r
+\r
+               /* Determine the number of priority bits available.  First write to\r
+               all possible bits. */\r
+               *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;\r
+\r
+               /* Read the value back to see how many bits stuck. */\r
+               ucMaxPriorityValue = *pucFirstUserPriorityRegister;\r
+\r
+               /* Shift to the least significant bits. */\r
+               while( ( ucMaxPriorityValue & portBIT_0_SET ) != portBIT_0_SET )\r
+               {\r
+                       ucMaxPriorityValue >>= ( uint8_t ) 0x01;\r
+               }\r
+\r
+               /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read\r
+               value. */\r
+               configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );\r
+\r
+               /* Restore the clobbered interrupt priority register to its original\r
+               value. */\r
+               *pucFirstUserPriorityRegister = ulOriginalPriority;\r
+       }\r
+       #endif /* conifgASSERT_DEFINED */\r
+\r
+\r
        /* Only continue if the CPU is not in User mode.  The CPU must be in a\r
        Privileged mode for the scheduler to start. */\r
        __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) );\r
        ulAPSR &= portAPSR_MODE_BITS_MASK;\r
        configASSERT( ulAPSR != portAPSR_USER_MODE );\r
 \r
+       #if configINSTALL_FREERTOS_VECTOR_TABLE == 1\r
+       {\r
+               vPortInstallFreeRTOSVectorTable();\r
+       }\r
+       #endif\r
+\r
+\r
        if( ulAPSR != portAPSR_USER_MODE )\r
        {\r
                /* Only continue if the binary point value is set to its lowest possible\r
@@ -282,7 +339,7 @@ uint32_t ulAPSR;
                        /* Start the timer that generates the tick ISR. */\r
                        configSETUP_TICK_INTERRUPT();\r
 \r
-                       __asm volatile( "cpsie i" );\r
+//                     __asm volatile( "cpsie i" );\r
                        vPortRestoreTaskContext();\r
                }\r
        }\r
@@ -340,10 +397,14 @@ void FreeRTOS_Tick_Handler( void )
        handler runs at the lowest priority, so interrupts cannot already be masked,\r
        so there is no need to save and restore the current mask value. */\r
        __asm volatile( "cpsid i" );\r
+       __asm volatile ( "dsb" );\r
+       __asm volatile ( "isb" );\r
        portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
        __asm(  "dsb            \n"\r
                        "isb            \n"\r
-                       "cpsie i          ");\r
+                       "cpsie i        \n"\r
+                       "dsb            \n"\r
+                       "isb" );\r
 \r
        /* Increment the RTOS tick. */\r
        if( xTaskIncrementTick() != pdFALSE )\r
@@ -383,6 +444,8 @@ uint32_t ulPortSetInterruptMask( void )
 uint32_t ulReturn;\r
 \r
        __asm volatile ( "cpsid i" );\r
+       __asm volatile ( "dsb" );\r
+       __asm volatile ( "isb" );\r
        if( portICCPMR_PRIORITY_MASK_REGISTER == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )\r
        {\r
                /* Interrupts were already masked. */\r
@@ -396,6 +459,8 @@ uint32_t ulReturn;
                                "isb            \n" );\r
        }\r
        __asm volatile ( "cpsie i" );\r
+       __asm volatile ( "dsb" );\r
+       __asm volatile ( "isb" );\r
 \r
        return ulReturn;\r
 }\r
@@ -441,13 +506,3 @@ uint32_t ulReturn;
 #endif /* configASSERT_DEFINED */\r
 /*-----------------------------------------------------------*/\r
 \r
-void vPortRestoreTaskContext( void )\r
-{\r
-}\r
-\r
-void vPortRestoreContext( void )\r
-{\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
index f0ecbf97dba28e53694fcfe0d434ca434081537f..072e45e5456b3ebc12983a1068c4e5bd88d550ef 100644 (file)
 */\r
 \r
 \r
-       .org 0\r
        .text\r
 \r
        .set SYS_MODE,  0x1f\r
        .set SVC_MODE,  0x13\r
        .set IRQ_MODE,  0x12\r
 \r
-       .extern _boot\r
-       .extern vTaskSwitchContext\r
        .extern ulICCIAR\r
        .extern ulICCEOIR\r
+       .extern ulMaxAPIPriorityMask\r
+       .extern ulICCPMR\r
+       .extern _freertos_vector_table\r
 \r
-       .global _vector_table\r
+       .global FreeRTOS_vector_table\r
        .global FIQInterrupt\r
        .global Undefined\r
        .global PrefetchAbortHandler\r
        .global DataAbortInterrupt\r
+\r
+       .extern pxCurrentTCB\r
+       .extern XIntc_DeviceInterruptHandler\r
+       .extern vTaskSwitchContext\r
+       .extern uxCriticalNesting\r
+       .extern pulISRStack\r
+       .extern ulTaskSwitchRequested\r
+       .extern vPortExceptionHandler\r
+       .extern pulStackPointerOnFunctionEntry\r
+\r
        .global FreeRTOS_IRQ_Handler\r
        .global FreeRTOS_SWI_Handler\r
+       .global vPortRestoreTaskContext\r
+       .global vPortInstallFreeRTOSVectorTable\r
+\r
+\r
+\r
+\r
+.macro portSAVE_CONTEXT\r
+\r
+       /* Save the LR and SPSR onto the system mode stack before switching to\r
+       system mode to save the remaining system mode registers. */\r
+       SRSDB   sp!, #SYS_MODE\r
+       CPS             #SYS_MODE\r
+       PUSH    {R0-R12, R14}\r
+\r
+       /* Push the critical nesting count. */\r
+       LDR             R2, =ulCriticalNesting\r
+       LDR             R1, [R2]\r
+       PUSH    {R1}\r
+\r
+       /* Does the task have a floating point context that needs saving?  If\r
+       ulPortTaskHasFPUContext is 0 then no. */\r
+       LDR             R2, =ulPortTaskHasFPUContext\r
+       LDR             R3, [R2]\r
+       CMP             R3, #0\r
+\r
+       /* Save the floating point context, if any. */\r
+       FMRXNE  R1,  FPSCR\r
+       VPUSHNE {D0-D15}\r
+       VPUSHNE {D16-D31}\r
+       PUSHNE  {R1}\r
+\r
+       /* Save ulPortTaskHasFPUContext itself. */\r
+       PUSH    {R3}\r
+\r
+       /* Save the stack pointer in the TCB. */\r
+       LDR             R0, =pxCurrentTCB\r
+       LDR             R1, [R0]\r
+       STR             SP, [R1]\r
+\r
+       .endm\r
+\r
+; /**********************************************************************/\r
+\r
+.macro portRESTORE_CONTEXT\r
+\r
+       /* Switch to system mode. */\r
+       CPS             #SYS_MODE\r
+\r
+       /* Set the SP to point to the stack of the task being restored. */\r
+       LDR             R0, =pxCurrentTCB\r
+       LDR             R1, [R0]\r
+       LDR             SP, [R1]\r
+\r
+       /* Is there a floating point context to restore?  If the restored\r
+       ulPortTaskHasFPUContext is zero then no. */\r
+       LDR             R0, =ulPortTaskHasFPUContext\r
+       POP             {R1}\r
+       STR             R1, [R0]\r
+       CMP             R1, #0\r
+\r
+       /* Restore the floating point context, if any. */\r
+       POPNE   {R0}\r
+       VPOPNE  {D16-D31}\r
+       VPOPNE  {D0-D15}\r
+       VMSRNE  FPSCR, R0\r
+\r
+       /* Restore the critical section nesting depth. */\r
+       LDR             R0, =ulCriticalNesting\r
+       POP             {R1}\r
+       STR             R1, [R0]\r
+\r
+       /* Ensure the priority mask is correct for the critical nesting depth. */\r
+       LDR             R2, =ulICCPMR\r
+       CMP             R1, #0\r
+       MOVEQ   R4, #255\r
+       LDRNE   R4, =ulMaxAPIPriorityMask\r
+       STR             R4, [r2]\r
+\r
+       /* Restore all system mode registers other than the SP (which is already\r
+       being used). */\r
+       POP             {R0-R12, R14}\r
+\r
+       /* Return to the task code, loading CPSR on the way. */\r
+       RFEIA   sp!\r
+\r
+       .endm\r
 \r
-       .section .vectors\r
 \r
-_vector_table:\r
-       B         _boot\r
-       B         Undefined\r
-       ldr   pc, _swi\r
-       B         PrefetchAbortHandler\r
-       B         DataAbortHandler\r
-       NOP       /* Placeholder for address exception vector*/\r
-       LDR   PC, _irq\r
-       B         FIQHandler\r
 \r
-_irq:   .word FreeRTOS_IRQ_Handler\r
-_swi:   .word FreeRTOS_SWI_Handler\r
 \r
 /******************************************************************************\r
  * SVC handler is used to start the scheduler and yield a task.\r
@@ -94,12 +178,42 @@ _swi:   .word FreeRTOS_SWI_Handler
 FreeRTOS_SWI_Handler:\r
 \r
        /* Save the context of the current task and select a new task to run. */\r
-//     portSAVE_CONTEXT\r
+       /* Save the LR and SPSR onto the system mode stack before switching to\r
+       system mode to save the remaining system mode registers. */\r
+       SRSDB   sp!, #SYS_MODE\r
+       CPS             #SYS_MODE\r
+       PUSH    {R0-R12, R14}\r
+\r
+       /* Push the critical nesting count. */\r
+       LDR             R2, =ulCriticalNesting\r
+       LDR             R1, [R2]\r
+       PUSH    {R1}\r
+\r
+       /* Does the task have a floating point context that needs saving?  If\r
+       ulPortTaskHasFPUContext is 0 then no. */\r
+       LDR             R2, =ulPortTaskHasFPUContext\r
+       LDR             R3, [R2]\r
+       CMP             R3, #0\r
+\r
+       /* Save the floating point context, if any. */\r
+       FMRXNE  R1,  FPSCR\r
+       VPUSHNE {D0-D15}\r
+       VPUSHNE {D16-D31}\r
+       PUSHNE  {R1}\r
+\r
+       /* Save ulPortTaskHasFPUContext itself. */\r
+       PUSH    {R3}\r
+\r
+       /* Save the stack pointer in the TCB. */\r
+       LDR             R0, =pxCurrentTCB\r
+       LDR             R1, [R0]\r
+       STR             SP, [R1]\r
+\r
        LDR R0, =vTaskSwitchContext\r
        BLX     R0\r
 \r
 vPortRestoreTaskContext:\r
-//     portRESTORE_CONTEXT\r
+       portRESTORE_CONTEXT\r
 \r
 FreeRTOS_IRQ_Handler:\r
        /* Return to the interrupted instruction. */\r
@@ -185,7 +299,7 @@ switch_before_exit:
        POP             {LR}\r
        MSR             SPSR_cxsf, LR\r
        POP             {LR}\r
-//     portSAVE_CONTEXT\r
+       portSAVE_CONTEXT\r
 \r
        /* Call the function that selects the new task to execute.\r
        vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD\r
@@ -195,23 +309,19 @@ switch_before_exit:
 \r
        /* Restore the context of, and branch to, the task selected to execute\r
        next. */\r
-//     portRESTORE_CONTEXT\r
+       portRESTORE_CONTEXT\r
 \r
 ulICCIARConst: .word ulICCIAR\r
 ulICCEOIRConst:        .word ulICCEOIR\r
 \r
+vPortInstallFreeRTOSVectorTable:\r
+       /* Set VBAR to the vector table that contains the FreeRTOS handlers. */\r
+       ldr     r0, =_freertos_vector_table\r
+       mcr     p15, 0, r0, c12, c0, 0\r
+       dsb\r
+       isb\r
+       bx lr\r
 \r
-Undefined:\r
-       B               .\r
-\r
-PrefetchAbortHandler:\r
-       B               .\r
-\r
-FIQHandler:\r
-       B               .\r
-\r
-DataAbortHandler:\r
-       B               .\r
 \r
 .end\r
 \r
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.h b/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.h
deleted file mode 100644 (file)
index b2d47c8..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-;/*\r
-;    FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
-;    All rights reserved\r
-;\r
-;\r
-;    ***************************************************************************\r
-;     *                                                                       *\r
-;     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
-;     *    Complete, revised, and edited pdf reference manuals are also       *\r
-;     *    available.                                                         *\r
-;     *                                                                       *\r
-;     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
-;     *    ensuring you get running as quickly as possible and with an        *\r
-;     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
-;     *    the FreeRTOS project to continue with its mission of providing     *\r
-;     *    professional grade, cross platform, de facto standard solutions    *\r
-;     *    for microcontrollers - completely free of charge!                  *\r
-;     *                                                                       *\r
-;     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
-;     *                                                                       *\r
-;     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
-;     *                                                                       *\r
-;    ***************************************************************************\r
-;\r
-;\r
-;    This file is part of the FreeRTOS distribution.\r
-;\r
-;    FreeRTOS is free software; you can redistribute it and/or modify it under\r
-;    the terms of the GNU General Public License (version 2) as published by the\r
-;    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
-;    >>>NOTE<<< The modification to the GPL is included to allow you to\r
-;    distribute a combined work that includes FreeRTOS without being obliged to\r
-;    provide the source code for proprietary components outside of the FreeRTOS\r
-;    kernel.  FreeRTOS is distributed in the hope that it will be useful, but\r
-;    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
-;    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
-;    more details. You should have received a copy of the GNU General Public\r
-;    License and the FreeRTOS license exception along with FreeRTOS; if not it\r
-;    can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
-;    by writing to Richard Barry, contact details for whom are available on the\r
-;    FreeRTOS WEB site.\r
-;\r
-;    1 tab == 4 spaces!\r
-;\r
-;    http://www.FreeRTOS.org - Documentation, latest information, license and\r
-;    contact details.\r
-;\r
-;    http://www.SafeRTOS.com - A version that is certified for use in safety\r
-;    critical systems.\r
-;\r
-;    http://www.OpenRTOS.com - Commercial support, development, porting,\r
-;    licensing and training services.\r
-;*/\r
-\r
-       EXTERN  vTaskSwitchContext\r
-       EXTERN  ulCriticalNesting\r
-       EXTERN  pxCurrentTCB\r
-       EXTERN  ulPortTaskHasFPUContext\r
-       EXTERN  ulAsmAPIPriorityMask\r
-\r
-portSAVE_CONTEXT macro\r
-\r
-       ; Save the LR and SPSR onto the system mode stack before switching to\r
-       ; system mode to save the remaining system mode registers\r
-       SRSDB   sp!, #SYS_MODE\r
-       CPS             #SYS_MODE\r
-       PUSH    {R0-R12, R14}\r
-\r
-       ; Push the critical nesting count\r
-       LDR             R2, =ulCriticalNesting\r
-       LDR             R1, [R2]\r
-       PUSH    {R1}\r
-\r
-       ; Does the task have a floating point context that needs saving?  If\r
-       ; ulPortTaskHasFPUContext is 0 then no.\r
-       LDR             R2, =ulPortTaskHasFPUContext\r
-       LDR             R3, [R2]\r
-       CMP             R3, #0\r
-\r
-       ; Save the floating point context, if any\r
-       FMRXNE  R1,  FPSCR\r
-       VPUSHNE {D0-D15}\r
-       VPUSHNE {D16-D31}\r
-       PUSHNE  {R1}\r
-\r
-       ; Save ulPortTaskHasFPUContext itself\r
-       PUSH    {R3}\r
-\r
-       ; Save the stack pointer in the TCB\r
-       LDR             R0, =pxCurrentTCB\r
-       LDR             R1, [R0]\r
-       STR             SP, [R1]\r
-\r
-       endm\r
-\r
-; /**********************************************************************/\r
-\r
-portRESTORE_CONTEXT macro\r
-\r
-       ; Switch to system mode\r
-       CPS             #SYS_MODE\r
-\r
-       ; Set the SP to point to the stack of the task being restored.\r
-       LDR             R0, =pxCurrentTCB\r
-       LDR             R1, [R0]\r
-       LDR             SP, [R1]\r
-\r
-       ; Is there a floating point context to restore?  If the restored\r
-       ; ulPortTaskHasFPUContext is zero then no.\r
-       LDR             R0, =ulPortTaskHasFPUContext\r
-       POP             {R1}\r
-       STR             R1, [R0]\r
-       CMP             R1, #0\r
-\r
-       ; Restore the floating point context, if any\r
-       LDMFDNE SP!, {R0}\r
-       VPOPNE  {D16-D31}\r
-       VPOPNE  {D0-D15}\r
-       VMSRNE  FPSCR, R0\r
-\r
-       ; Restore the critical section nesting depth\r
-       LDR             R0, =ulCriticalNesting\r
-       POP             {R1}\r
-       STR             R1, [R0]\r
-\r
-       ; Ensure the priority mask is correct for the critical nesting depth\r
-       LDR             R2, =portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS\r
-       CMP             R1, #0\r
-       MOVEQ   R4, #255\r
-       LDRNE   R4, =( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT )\r
-       STR             R4, [r2]\r
-\r
-       ; Restore all system mode registers other than the SP (which is already\r
-       ; being used)\r
-       POP             {R0-R12, R14}\r
-\r
-       ; Return to the task code, loading CPSR on the way.\r
-       RFEIA   sp!\r
-\r
-       endm\r
-\r
-\r
-\r
-\r
-\r