/*\r
- * FreeRTOS Kernel V10.1.0\r
+ * FreeRTOS Kernel V10.1.1\r
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy of\r
* file is weak to allow application writers to change the timer used to\r
* generate the tick interrupt.\r
*/\r
-void vPortSetupTimerInterrupt( void );\r
+void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));\r
\r
/*\r
* Used to catch tasks that attempt to return from their implementing function.\r
\r
/*-----------------------------------------------------------*/\r
\r
+/* Used to program the machine timer compare register. */\r
+static uint64_t ullNextTime = 0ULL;\r
+static const uint64_t ullTimerIncrementsForOneTick = ( uint64_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );\r
+static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
void prvTaskExitError( void )\r
{\r
volatile uint32_t ulx = 0;\r
*/\r
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )\r
{\r
+uint32_t mstatus;\r
+const uint32_t ulMPIE_Bit = 0x80, ulMPP_Bits = 0x1800;\r
/*\r
X1 to X31 integer registers for the 'I' profile, X1 to X15 for the 'E' profile.\r
\r
x28-31 t3-6 Temporaries Caller\r
*/\r
\r
+ /* Start task with interrupt enabled. */\r
+ __asm volatile ("csrr %0, mstatus" : "=r"(mstatus));\r
+ mstatus |= ulMPIE_Bit | ulMPP_Bits;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = mstatus;\r
+\r
+ /* Numbers correspond to the x register number. */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 31;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 30;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 29;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 28;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 27;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 26;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 25;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 24;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 23;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 22;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 21;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 20;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 19;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 18;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 17;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 16;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 15;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 14;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 13;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 12;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 11;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) pvParameters;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 9;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 8;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 7;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) 6;\r
pxTopOfStack--;\r
- *pxTopOfStack = ( StackType_t ) pxCode; /* X1 */\r
+ *pxTopOfStack = ( StackType_t ) 5;\r
pxTopOfStack--;\r
- *pxTopOfStack =\r
+// *pxTopOfStack = ( StackType_t ) 4; /* Thread pointer. */\r
+// pxTopOfStack--;\r
+// *pxTopOfStack = ( StackType_t ) 3; /* Global pointer. */\r
+// pxTopOfStack--;\r
+// *pxTopOfStack = ( StackType_t ) 2; /* Stack pointer. */\r
+// pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) prvTaskExitError;\r
+ pxTopOfStack--;\r
+ *pxTopOfStack = ( StackType_t ) pxCode;\r
+\r
+ return pxTopOfStack;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSetupTimerInterrupt( void )\r
+{\r
+uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;\r
+volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFFC );\r
+volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFF8 );\r
+\r
+ do\r
+ {\r
+ ulCurrentTimeHigh = *pulTimeHigh;\r
+ ulCurrentTimeLow = *pulTimeLow;\r
+ } while( ulCurrentTimeHigh != *pulTimeHigh );\r
+\r
+ ullNextTime = ( uint64_t ) ulCurrentTimeHigh;\r
+ ullNextTime <<= 32ULL;\r
+ ullNextTime |= ( uint64_t ) ulCurrentTimeLow;\r
+ ullNextTime += ullTimerIncrementsForOneTick;\r
+ *pullMachineTimerCompareRegister = ullNextTime;\r
+\r
+ /* Prepare the time to use after the next tick interrupt. */\r
+ ullNextTime += ullTimerIncrementsForOneTick;\r
+\r
+ /* Enable timer interrupt */\r
+ __asm volatile( "csrs mie, %0" :: "r"(0x80) ); /* 1<<7 for timer interrupt. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void Software_IRQHandler( void )\r
+{\r
+volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCLINT_BASE_ADDRESS;\r
+\r
+ vTaskSwitchContext();\r
\r
+ /* Clear software interrupt. */\r
+ *( ( uint32_t * ) configCLINT_BASE_ADDRESS ) &= 0x08UL;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void Timer_IRQHandler( void )\r
+{\r
+extern void vTaskSwitchContext( void );\r
\r
- return pxTopOfStack;\r
+ /* Reload for the next timer interrupt. */\r
+ *pullMachineTimerCompareRegister = ullNextTime;\r
+ ullNextTime += ullTimerIncrementsForOneTick;\r
+\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ vTaskSwitchContext();\r
+ }\r
}\r
/*-----------------------------------------------------------*/\r
\r
BaseType_t xPortStartScheduler( void )\r
{\r
- /*Should not get here*/\r
- return pdFALSE;\r
+extern void xPortStartFirstTask( void );\r
+\r
+ #if( configASSERT_DEFINED == 1 )\r
+ {\r
+ volatile uint32_t mtvec = 0;\r
+\r
+ /* Check the least significant two bits of mtvec are 00 - indicating single\r
+ vector mode. */\r
+ __asm volatile( "csrr %0, mtvec" : "=r"( mtvec ) );\r
+ configASSERT( ( mtvec & 0x03UL ) == 0 );\r
+ }\r
+ #endif\r
+\r
+ vPortSetupTimerInterrupt();\r
+ xPortStartFirstTask();\r
+\r
+ /* Should not get here as after calling xPortStartFirstTask() only tasks\r
+ should be executing. */\r
+ return pdFAIL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
+void vPortEndScheduler( void )\r
+{\r
+ /* Not implemented. */\r
+ for( ;; );\r
+}\r
+\r
+\r
+\r
\r