From: richardbarry Date: Thu, 6 Mar 2008 20:55:49 +0000 (+0000) Subject: Comment ready for release. X-Git-Tag: V4.8.0~44 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=08bc2fd412df36a7df0cfbb90078c8aa280f9a43;p=freertos Comment ready for release. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@237 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/Source/portable/GCC/PPC405_Xilinx/port.c b/Source/portable/GCC/PPC405_Xilinx/port.c index b97444b3c..d6f0d41f8 100644 --- a/Source/portable/GCC/PPC405_Xilinx/port.c +++ b/Source/portable/GCC/PPC405_Xilinx/port.c @@ -1,5 +1,5 @@ /* - FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry. + FreeRTOS.org V4.7.2 - Copyright (C) 2003-2008 Richard Barry. This file is part of the FreeRTOS.org distribution. @@ -54,28 +54,47 @@ #include "xintc.h" #include "xintc_i.h" -/* Standard includes. */ -#include - /*-----------------------------------------------------------*/ -#define portCRITICAL_INTERRUPT_ENABLE ( 0UL << 17UL ) +/* Definitions to set the initial MSR of each task. */ +#define portCRITICAL_INTERRUPT_ENABLE ( 1UL << 17UL ) #define portEXTERNAL_INTERRUPT_ENABLE ( 1UL << 15UL ) -#define portMACHINE_CHECK_ENABLE ( 0UL << 12UL ) +#define portMACHINE_CHECK_ENABLE ( 1UL << 12UL ) #define portINITIAL_MSR ( portCRITICAL_INTERRUPT_ENABLE | portEXTERNAL_INTERRUPT_ENABLE | portMACHINE_CHECK_ENABLE ) +/*-----------------------------------------------------------*/ + /* + * Setup the system timer to generate the tick interrupt. */ static void prvSetupTimerInterrupt( void ); + +/* + * The handler for the tick interrupt - defined in portasm.s. + */ extern void vPortTickISR( void ); + +/* + * The handler for the yield function - defined in portasm.s. + */ extern void vPortYield( void ); + +/* + * Function to start the scheduler running by starting the highest + * priority task that has thus far been created. + */ extern void vPortStartFirstTask( void ); +/*-----------------------------------------------------------*/ + +/* Structure used to hold the state of the interrupt controller. */ static XIntc xInterruptController; +/*-----------------------------------------------------------*/ + /* - * Initialise the stack of a task to look exactly as if a call to - * portSAVE_CONTEXT had been made. + * Initialise the stack of a task to look exactly as if the task had been + * interrupted. * * See the header file portable.h. */ @@ -165,7 +184,6 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE *pxTopOfStack = ( portSTACK_TYPE ) vPortStartFirstTask;/* Next LR. */ pxTopOfStack--; *pxTopOfStack = 0x00000000UL;;/* Backchain. */ -// pxTopOfStack--; return pxTopOfStack; } @@ -173,14 +191,8 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE portBASE_TYPE xPortStartScheduler( void ) { -extern void *pxCurrentTCB; - prvSetupTimerInterrupt(); - XExc_RegisterHandler( XEXC_ID_SYSTEM_CALL, ( XExceptionHandler ) vPortYield, ( void * ) 0 ); - -// XExc_mEnableExceptions( XEXC_NON_CRITICAL ); - vPortStartFirstTask(); /* Should not get here as the tasks are now running! */ @@ -197,7 +209,6 @@ void vPortEndScheduler( void ) /* * Hardware initialisation to generate the RTOS tick. */ -static void prvTickISR( void ); static void prvSetupTimerInterrupt( void ) { const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL ); @@ -216,69 +227,43 @@ const unsigned portLONG ulInterval = ( ( configCPU_CLOCK_HZ / configTICK_RATE_HZ } /*-----------------------------------------------------------*/ -static void prvTickISR( void ) -{ -static unsigned portLONG ulTicks = 0; - - ulTicks++; - if( ulTicks >= 1000 ) - { - vParTestToggleLED( 0 ); - ulTicks = 0; - } - XTime_PITClearInterrupt(); -} -/*-----------------------------------------------------------*/ - void vPortISRHandler( void *vNullDoNotUse ) { -Xuint32 IntrStatus; -Xuint32 IntrMask = 1; -int IntrNumber; -//extern XIntc xInterruptController; -XIntc_Config *CfgPtr;// = xInterruptController.CfgPtr; - - /* Get the configuration data using the device ID */ - //CfgPtr = &XIntc_ConfigTable[(Xuint32)DeviceId]; - CfgPtr = &XIntc_ConfigTable[(Xuint32)XPAR_OPB_INTC_0_DEVICE_ID]; +unsigned portLONG ulInterruptStatus, ulInterruptMask = 1UL; +portBASE_TYPE xInterruptNumber; +XIntc_Config *pxInterruptController; +XIntc_VectorTableEntry *pxTable; + + /* Get the configuration by using the device ID - in this case it is + assumed that only one interrupt controller is being used. */ + pxInterruptController = &XIntc_ConfigTable[ XPAR_OPB_INTC_0_DEVICE_ID ]; - /* Get the interrupts that are waiting to be serviced */ - IntrStatus = XIntc_mGetIntrStatus(CfgPtr->BaseAddress); + /* Which interrupts are pending? */ + ulInterruptStatus = XIntc_mGetIntrStatus( pxInterruptController->BaseAddress ); - /* Service each interrupt that is active and enabled by checking each - * bit in the register from LSB to MSB which corresponds to an interrupt - * intput signal - */ - for (IntrNumber = 0; IntrNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; - IntrNumber++) - { - if (IntrStatus & 1) - { - XIntc_VectorTableEntry *TablePtr; - - /* The interrupt is active and enabled, call the interrupt - * handler that was setup with the specified parameter - */ - TablePtr = &(CfgPtr->HandlerTable[IntrNumber]); - TablePtr->Handler(TablePtr->CallBackRef); - - /* Clear the interrupt. */ - XIntc_mAckIntr(CfgPtr->BaseAddress, IntrMask); + for( xInterruptNumber = 0; xInterruptNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; xInterruptNumber++ ) + { + if( ulInterruptStatus & 0x01UL ) + { + /* Call the registered handler. */ + pxTable = &( pxInterruptController->HandlerTable[ xInterruptNumber ] ); + pxTable->Handler( pxTable->CallBackRef ); + + /* Clear the pending interrupt. */ + XIntc_mAckIntr( pxInterruptController->BaseAddress, ulInterruptMask ); break; - } + } - /* Move to the next interrupt to check */ - IntrMask <<= 1; - IntrStatus >>= 1; - - /* If there are no other bits set indicating that all interrupts - * have been serviced, then exit the loop - */ - if (IntrStatus == 0) - { - break; - } - } + /* Check the next interrupt. */ + ulInterruptMask <<= 0x01UL; + ulInterruptStatus >>= 0x01UL; + + /* Have we serviced all interrupts? */ + if( ulInterruptStatus == 0UL ) + { + break; + } + } } /*-----------------------------------------------------------*/ @@ -286,9 +271,16 @@ void vPortSetupInterruptController( void ) { extern void vPortISRWrapper( void ); + /* Perform all library calls necessary to initialise the exception table + and interrupt controller. This assumes only one interrupt controller is in + use. */ XExc_mDisableExceptions( XEXC_NON_CRITICAL ); XExc_Init(); - XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, (XExceptionHandler)vPortISRWrapper, NULL ); + + /* The library functions save the context - we then jump to a wrapper to + save the stack into the TCB. The wrapper then calls the handler defined + above. */ + XExc_RegisterHandler( XEXC_ID_NON_CRITICAL_INT, ( XExceptionHandler ) vPortISRWrapper, NULL ); XIntc_Initialize( &xInterruptController, XPAR_OPB_INTC_0_DEVICE_ID ); XIntc_Start( &xInterruptController, XIN_REAL_MODE ); } @@ -298,6 +290,9 @@ portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XIn { portBASE_TYPE xReturn = pdFAIL; + /* This function is defined here so the scope of xInterruptController can + remain within this file. */ + if( XST_SUCCESS == XIntc_Connect( &xInterruptController, ucInterruptID, pxHandler, pvCallBackRef ) ) { XIntc_Enable( &xInterruptController, ucInterruptID ); diff --git a/Source/portable/GCC/PPC405_Xilinx/portasm.s b/Source/portable/GCC/PPC405_Xilinx/portasm.s index 64b511ed8..2957b45e5 100644 --- a/Source/portable/GCC/PPC405_Xilinx/portasm.s +++ b/Source/portable/GCC/PPC405_Xilinx/portasm.s @@ -10,18 +10,6 @@ .global vPortTickISR .global vPortISRWrapper -.set portCONTEXT_SIZE, 156 -.set portR0_OFFSET, 152 -.set portGPR_OFFSET, 32 -.set portCR_OFFSET, 28 -.set portXER_OFFSET, 24 -.set portLR_OFFSET, 16 -.set portCTR_OFFSET, 16 -.set portUSPRG0_OFFSET, 12 -.set portSRR0_OFFSET, 8 -.set portSRR1_OFFSET, 4 - - .set BChainField, 0 .set NextLRField, BChainField + 4 .set MSRField, NextLRField + 4 @@ -37,81 +25,46 @@ .set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4 -.macro portRESTORE_CONTEXT +.macro portSAVE_STACK_POINTER_AND_LR - # Get the address of the TCB. + # Get the address of the TCB. xor R0, R0, R0 - addis SP, R0, pxCurrentTCB@ha - lwz SP, pxCurrentTCB@l( SP ) - - # Get the task stack pointer from the TCB. - lwz SP, 0( SP ) + addis R2, R0, pxCurrentTCB@ha + lwz R2, pxCurrentTCB@l( R2 ) - # Pop the special purpose registers - lwz R0, portSRR1_OFFSET( SP ) - mtspr SRR1, R0 - lwz R0, portSRR0_OFFSET( SP ) - mtspr SRR0, R0 - lwz R0, portUSPRG0_OFFSET( SP ) - mtspr 256, R0 #USPRG0 - lwz R0, portCTR_OFFSET( SP ) - mtspr CTR, R0 - lwz R0, portLR_OFFSET( SP ) - mtspr LR, R0 - lwz R0, portXER_OFFSET( SP ) - mtspr XER, R0 - lwz R0, portCR_OFFSET( SP ) - mtcr R0 + # Store the stack pointer into the TCB + stw SP, 0( R2 ) - # Pop GPRs - lmw R2, portGPR_OFFSET( SP ) + # Save the link register + stwu R1, -24( R1 ) + mflr R0 + stw R31, 20( R1 ) + stw R0, 28( R1 ) + mr R31, r1 - # Finally pop R0 and correct the stack pointer - lwz R0, portR0_OFFSET( SP ) - addi R1, R1, portCONTEXT_SIZE +.endm - # Start the task running - rfi +.macro portRESTORE_STACK_POINTER_AND_LR - .endm - -.macro portSAVE_CONTEXT - - # Make room on the stack. - subi R1, R1, portCONTEXT_SIZE - - # Push R0, then the GPRs - stw R0, portR0_OFFSET( SP ) - stm R2, portGPR_OFFSET( SP ) - - # Push the SFRs - mfcr R0 - stw R0, portCR_OFFSET( SP ) - mfspr R0, XER - stw R0, portXER_OFFSET( SP ) - mfspr R0, LR - stw R0, portLR_OFFSET( SP ) - mfspr R0, CTR - stw R0, portCTR_OFFSET( SP ) - mfspr R0, 256 #USPRG0 - stw R0, portUSPRG0_OFFSET( SP ) - mfspr R0, SRR0 - stw R0, portSRR0_OFFSET( SP ) - mfspr R0, SRR1 - stw R0, portSRR1_OFFSET( SP ) + # Restore the link register + lwz R11, 0( R1 ) + lwz R0, 4( R11 ) + mtlr R0 + lwz R31, -4( R11 ) + mr R1, R11 # Get the address of the TCB. xor R0, R0, R0 - addis R2, R0, pxCurrentTCB@ha - lwz R2, pxCurrentTCB@l( R2 ) + addis SP, R0, pxCurrentTCB@ha + lwz SP, pxCurrentTCB@l( R1 ) - # Store the stack pointer into the TCB - stw SP, 0( R2 ) + # Get the task stack pointer from the TCB. + lwz SP, 0( SP ) - .endm +.endm -.macro int_epilogue +vPortStartFirstTask: # Get the address of the TCB. xor R0, R0, R0 @@ -122,105 +75,58 @@ lwz SP, 0( SP ) # Restore MSR register to SRR1. - lwz R0,MSRField(R1) + lwz R0, MSRField(R1) mtsrr1 R0 # Restore current PC location to SRR0. - lwz R0,PCField(R1) + lwz R0, PCField(R1) mtsrr0 R0 - # Save USPRG0 register - lwz R0,USPRG0Field(R1) + # Save USPRG0 register + lwz R0, USPRG0Field(R1) mtspr 0x100,R0 # Restore Condition register - lwz R0,CRField(R1) + lwz R0, CRField(R1) mtcr R0 # Restore Fixed Point Exception register - lwz R0,XERField(R1) + lwz R0, XERField(R1) mtxer R0 # Restore Counter register - lwz R0,CTRField(R1) + lwz R0, CTRField(R1) mtctr R0 # Restore Link register - lwz R0,LRField(R1) + lwz R0, LRField(R1) mtlr R0 # Restore remaining GPR registers. lmw R3,r3r31Field(R1) # Restore r0 and r2. - lwz R0,r0Field(R1) - lwz R2,r2Field(R1) + lwz R0, r0Field(R1) + lwz R2, r2Field(R1) # Remove frame from stack addi R1,R1,IFrameSize - -.endm -.macro portENTER_SWITCHING_ISR - - # Get the address of the TCB. - xor R0, R0, R0 - addis R2, R0, pxCurrentTCB@ha - lwz R2, pxCurrentTCB@l( R2 ) - - # Store the stack pointer into the TCB - stw SP, 0( R2 ) - - # Save the link register - stwu R1, -24( R1 ) - mflr R0 - stw R31, 20( R1 ) - stw R0, 28( R1 ) - mr R31, r1 - -.endm - -.macro portEXIT_SWITCHING_ISR - - # Restore the link register - lwz R11, 0( R1 ) - lwz R0, 4( R11 ) - mtlr R0 - lwz R31, -4( R11 ) - mr R1, R11 - - # Get the address of the TCB. - xor R0, R0, R0 - addis SP, R0, pxCurrentTCB@ha - lwz SP, pxCurrentTCB@l( R1 ) - - # Get the task stack pointer from the TCB. - lwz SP, 0( SP ) - -.endm - - -vPortStartFirstTask: - - int_epilogue + # Return into the first task rfi -#vPortStartFirstTask: -# portRESTORE_CONTEXT -# rfi - vPortYield: - portENTER_SWITCHING_ISR + portSAVE_STACK_POINTER_AND_LR bl vTaskSwitchContext - portEXIT_SWITCHING_ISR + portRESTORE_STACK_POINTER_AND_LR blr vPortTickISR: - portENTER_SWITCHING_ISR + portSAVE_STACK_POINTER_AND_LR bl vTaskIncrementTick #if configUSE_PREEMPTION == 1 bl vTaskSwitchContext @@ -230,12 +136,12 @@ vPortTickISR: lis R0, 2048 mttsr R0 - portEXIT_SWITCHING_ISR + portRESTORE_STACK_POINTER_AND_LR blr vPortISRWrapper: - portENTER_SWITCHING_ISR + portSAVE_STACK_POINTER_AND_LR bl vPortISRHandler - portEXIT_SWITCHING_ISR + portRESTORE_STACK_POINTER_AND_LR blr diff --git a/Source/portable/GCC/PPC405_Xilinx/portmacro.h b/Source/portable/GCC/PPC405_Xilinx/portmacro.h index 6ba2c7f08..84fe0540b 100644 --- a/Source/portable/GCC/PPC405_Xilinx/portmacro.h +++ b/Source/portable/GCC/PPC405_Xilinx/portmacro.h @@ -77,6 +77,8 @@ extern "C" { #endif /*-----------------------------------------------------------*/ +/* This port uses the critical nesting count from the TCB rather than +maintaining a separate value and then saving this value in the task stack. */ #define portCRITICAL_NESTING_IN_TCB 1 /* Interrupt control macros. */ @@ -97,6 +99,7 @@ void vTaskExitCritical( void ); void vPortYield( void ); #define portYIELD() asm volatile ( "SC \n\t NOP" ) #define portYIELD_FROM_ISR() vTaskSwitchContext() + /*-----------------------------------------------------------*/ /* Hardware specifics. */ @@ -110,7 +113,7 @@ void vPortYield( void ); #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) -/* Port specific initialisation function. */ +/* Port specific interrupt handling functions. */ void vPortSetupInterruptController( void ); portBASE_TYPE xPortInstallInterruptHandler( unsigned portCHAR ucInterruptID, XInterruptHandler pxHandler, void *pvCallBackRef );