From b352be2e23d83acfcc18a834bcd2e75d44c4be41 Mon Sep 17 00:00:00 2001
From: Richard Barry <ribarry@amazon.com>
Date: Fri, 24 Jan 2014 17:09:31 +0000
Subject: [PATCH] Tidy up GCC Cortex-A port layer - still a work in progress.

---
 FreeRTOS/Source/portable/GCC/ARM_CA9/port.c   | 23 +++--
 .../Source/portable/GCC/ARM_CA9/portASM.S     | 96 +++++++------------
 2 files changed, 48 insertions(+), 71 deletions(-)

diff --git a/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c b/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c
index 5c6c49b0b1..30eb3be117 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c
+++ b/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c
@@ -114,6 +114,10 @@
 	#warning configINSTALL_FREERTOS_VECTOR_TABLE was undefined.  Defaulting configINSTALL_FREERTOS_VECTOR_TABLE to 0.
 #endif
 
+#ifndef configCLEAR_TICK_INTERRUPT
+	#define configCLEAR_TICK_INTERRUPT()
+#endif
+
 /* A critical section is exited when the critical section nesting count reaches
 this value. */
 #define portNO_CRITICAL_NESTING			( ( uint32_t ) 0 )
@@ -151,23 +155,23 @@ mode. */
 determined priority level.  Sometimes it is necessary to turn interrupt off in
 the CPU itself before modifying certain hardware registers. */
 #define portCPU_IRQ_DISABLE()										\
-	__asm volatile ( "CPSID i" );											\
-	__asm volatile ( "DSB" );												\
+	__asm volatile ( "CPSID i" );									\
+	__asm volatile ( "DSB" );										\
 	__asm volatile ( "ISB" );
 
 #define portCPU_IRQ_ENABLE()										\
-	__asm volatile ( "CPSIE i" );											\
-	__asm volatile ( "DSB" );												\
+	__asm volatile ( "CPSIE i" );									\
+	__asm volatile ( "DSB" );										\
 	__asm volatile ( "ISB" );
 
 
 /* Macro to unmask all interrupt priorities. */
-#define portCLEAR_INTERRUPT_MASK()											\
-{																			\
+#define portCLEAR_INTERRUPT_MASK()									\
+{																	\
 	portCPU_IRQ_DISABLE();											\
-	portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE;					\
-	__asm(	"DSB		\n"													\
-			"ISB		\n" );												\
+	portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE;			\
+	__asm(	"DSB		\n"											\
+			"ISB		\n" );										\
 	portCPU_IRQ_ENABLE();											\
 }
 
@@ -426,6 +430,7 @@ void FreeRTOS_Tick_Handler( void )
 
 	/* Ensure all interrupt priorities are active again. */
 	portCLEAR_INTERRUPT_MASK();
+	configCLEAR_TICK_INTERRUPT();
 }
 /*-----------------------------------------------------------*/
 
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S b/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S
index 27cf67abdc..844a3f18ed 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S
+++ b/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S
@@ -58,26 +58,18 @@
 	.set SVC_MODE,	0x13
 	.set IRQ_MODE,	0x12
 
+	/* Hardware registers. */
 	.extern ulICCIAR
 	.extern ulICCEOIR
-	.extern ulMaxAPIPriorityMask
 	.extern ulICCPMR
+
+	/* Variables and functions. */
+	.extern ulMaxAPIPriorityMask
 	.extern _freertos_vector_table
-
-	.global FreeRTOS_vector_table
-	.global FIQInterrupt
-	.global Undefined
-	.global PrefetchAbortHandler
-	.global DataAbortInterrupt
-
 	.extern pxCurrentTCB
-	.extern XIntc_DeviceInterruptHandler
 	.extern vTaskSwitchContext
-	.extern uxCriticalNesting
-	.extern pulISRStack
-	.extern ulTaskSwitchRequested
-	.extern vPortExceptionHandler
-	.extern pulStackPointerOnFunctionEntry
+	.extern vApplicationIRQHandler
+	.extern ulPortInterruptNesting
 
 	.global FreeRTOS_IRQ_Handler
 	.global FreeRTOS_SWI_Handler
@@ -96,13 +88,13 @@
 	PUSH	{R0-R12, R14}
 
 	/* Push the critical nesting count. */
-	LDR		R2, =ulCriticalNesting
+	LDR		R2, ulCriticalNestingConst
 	LDR		R1, [R2]
 	PUSH	{R1}
 
 	/* Does the task have a floating point context that needs saving?  If
 	ulPortTaskHasFPUContext is 0 then no. */
-	LDR		R2, =ulPortTaskHasFPUContext
+	LDR		R2, ulPortTaskHasFPUContextConst
 	LDR		R3, [R2]
 	CMP		R3, #0
 
@@ -116,7 +108,7 @@
 	PUSH	{R3}
 
 	/* Save the stack pointer in the TCB. */
-	LDR		R0, =pxCurrentTCB
+	LDR		R0, pxCurrentTCBConst
 	LDR		R1, [R0]
 	STR		SP, [R1]
 
@@ -130,13 +122,13 @@
 	CPS		#SYS_MODE
 
 	/* Set the SP to point to the stack of the task being restored. */
-	LDR		R0, =pxCurrentTCB
+	LDR		R0, pxCurrentTCBConst
 	LDR		R1, [R0]
 	LDR		SP, [R1]
 
 	/* Is there a floating point context to restore?  If the restored
 	ulPortTaskHasFPUContext is zero then no. */
-	LDR		R0, =ulPortTaskHasFPUContext
+	LDR		R0, ulPortTaskHasFPUContextConst
 	POP		{R1}
 	STR		R1, [R0]
 	CMP		R1, #0
@@ -148,16 +140,18 @@
 	VMSRNE  FPSCR, R0
 
 	/* Restore the critical section nesting depth. */
-	LDR		R0, =ulCriticalNesting
+	LDR		R0, ulCriticalNestingConst
 	POP		{R1}
 	STR		R1, [R0]
 
 	/* Ensure the priority mask is correct for the critical nesting depth. */
-	LDR		R2, =ulICCPMR
+	LDR		R2, ulICCPMRConst
+	LDR		R2, [R2]
 	CMP		R1, #0
 	MOVEQ	R4, #255
-	LDRNE	R4, =ulMaxAPIPriorityMask
-	STR		R4, [r2]
+	LDRNE	R4, ulMaxAPIPriorityMaskConst
+	LDRNE	R4, [R4]
+	STR		R4, [R2]
 
 	/* Restore all system mode registers other than the SP (which is already
 	being used). */
@@ -175,40 +169,9 @@
  * SVC handler is used to start the scheduler and yield a task.
  *****************************************************************************/
 FreeRTOS_SWI_Handler:
-
 	/* Save the context of the current task and select a new task to run. */
-	/* Save the LR and SPSR onto the system mode stack before switching to
-	system mode to save the remaining system mode registers. */
-	SRSDB	sp!, #SYS_MODE
-	CPS		#SYS_MODE
-	PUSH	{R0-R12, R14}
-
-	/* Push the critical nesting count. */
-	LDR		R2, =ulCriticalNesting
-	LDR		R1, [R2]
-	PUSH	{R1}
-
-	/* Does the task have a floating point context that needs saving?  If
-	ulPortTaskHasFPUContext is 0 then no. */
-	LDR		R2, =ulPortTaskHasFPUContext
-	LDR		R3, [R2]
-	CMP		R3, #0
-
-	/* Save the floating point context, if any. */
-	FMRXNE  R1,  FPSCR
-	VPUSHNE {D0-D15}
-	VPUSHNE	{D16-D31}
-	PUSHNE	{R1}
-
-	/* Save ulPortTaskHasFPUContext itself. */
-	PUSH	{R3}
-
-	/* Save the stack pointer in the TCB. */
-	LDR		R0, =pxCurrentTCB
-	LDR		R1, [R0]
-	STR		SP, [R1]
-
-	LDR R0, =vTaskSwitchContext
+	portSAVE_CONTEXT
+	LDR R0, vTaskSwitchContextConst
 	BLX	R0
 
 vPortRestoreTaskContext:
@@ -232,7 +195,7 @@ FreeRTOS_IRQ_Handler:
 	/* Increment nesting count.  r3 holds the address of ulPortInterruptNesting
 	for future use.  r1 holds the original ulPortInterruptNesting value for
 	future use. */
-	LDR		r3, =ulPortInterruptNesting
+	LDR		r3, ulPortInterruptNestingConst
 	LDR		r1, [r3]
 	ADD		r4, r1, #1
 	STR		r4, [r3]
@@ -251,7 +214,8 @@ FreeRTOS_IRQ_Handler:
 
 	/* Call the interrupt handler. */
 	PUSH	{r0-r3, lr}
-	BL		vApplicationIRQHandler
+	LDR		r1, vApplicationIRQHandlerConst
+	BLX		r1
 	POP		{r0-r3, lr}
 	ADD		sp, sp, r2
 
@@ -308,15 +272,13 @@ switch_before_exit:
 	vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD
 	instructions, or 8 byte aligned stack allocated data.  LR does not need
 	saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */
-	BL		vTaskSwitchContext
+	LDR		R0, vTaskSwitchContextConst
+	BLX		R0
 
 	/* Restore the context of, and branch to, the task selected to execute
 	next. */
 	portRESTORE_CONTEXT
 
-ulICCIARConst:	.word ulICCIAR
-ulICCEOIRConst:	.word ulICCEOIR
-
 vPortInstallFreeRTOSVectorTable:
 	/* Set VBAR to the vector table that contains the FreeRTOS handlers. */
 	ldr	r0, =_freertos_vector_table
@@ -325,6 +287,16 @@ vPortInstallFreeRTOSVectorTable:
 	isb
 	bx lr
 
+ulICCIARConst:	.word ulICCIAR
+ulICCEOIRConst:	.word ulICCEOIR
+ulICCPMRConst: .word ulICCPMR
+pxCurrentTCBConst: .word pxCurrentTCB
+ulCriticalNestingConst: .word ulCriticalNesting
+ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext
+ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask
+vTaskSwitchContextConst: .word vTaskSwitchContext
+vApplicationIRQHandlerConst: .word vApplicationIRQHandler
+ulPortInterruptNestingConst: .word ulPortInterruptNesting
 
 .end