--- /dev/null
+/*\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
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://aws.amazon.com/freertos\r
+ *\r
+ * 1 tab == 4 spaces!\r
+ */\r
+\r
+/*-----------------------------------------------------------\r
+ * Implementation of functions defined in portable.h for the RISC-V RV32 port.\r
+ *----------------------------------------------------------*/\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "portmacro.h"\r
+\r
+#ifndef configCLINT_BASE_ADDRESS\r
+ #warning configCLINT_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a Core Local Interrupter (CLINT) then set configCLINT_BASE_ADDRESS to the CLINT base address. Otherwise set configCLINT_BASE_ADDRESS to 0.\r
+#endif\r
+\r
+/* Let the user override the pre-loading of the initial LR with the address of\r
+prvTaskExitError() in case it messes up unwinding of the stack in the\r
+debugger. */\r
+#ifdef configTASK_RETURN_ADDRESS\r
+ #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS\r
+#else\r
+ #define portTASK_RETURN_ADDRESS prvTaskExitError\r
+#endif\r
+\r
+/* The stack used by interrupt service routines. Set configISR_STACK_SIZE_WORDS\r
+to use a statically allocated array as the interrupt stack. Alternative leave\r
+configISR_STACK_SIZE_WORDS undefined and update the linker script so that a\r
+linker variable names __freertos_irq_stack_top has the same value as the top\r
+of the stack used by main. Using the linker script method will repurpose the\r
+stack that was used by main before the scheduler was started for use as the\r
+interrupt stack after the scheduler has started. */\r
+#ifdef configISR_STACK_SIZE_WORDS\r
+ static __attribute__ ((aligned(16))) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 };\r
+ const StackType_t xISRStackTop = ( StackType_t ) &( xISRStack[ ( configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK ) - 1 ] );\r
+#else\r
+ extern const uint32_t __freertos_irq_stack_top[];\r
+ const StackType_t xISRStackTop = ( StackType_t ) __freertos_irq_stack_top;\r
+#endif\r
+\r
+/*\r
+ * Setup the timer to generate the tick interrupts. The implementation in this\r
+ * file is weak to allow application writers to change the timer used to\r
+ * generate the tick interrupt.\r
+ */\r
+void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Used to program the machine timer compare register. */\r
+uint64_t ullNextTime = 0ULL;\r
+const uint64_t *pullNextTime = &ullNextTime;\r
+const uint32_t ulTimerIncrementsForOneTick = ( uint32_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ); /* Assumes increment won't go over 32-bits. */\r
+volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 );\r
+\r
+/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task\r
+stack checking. A problem in the ISR stack will trigger an assert, not call the\r
+stack overflow hook function (because the stack overflow hook is specific to a\r
+task stack, not the ISR stack). */\r
+#if( configCHECK_FOR_STACK_OVERFLOW > 2 )\r
+ #warning This path not tested, or even compiled yet.\r
+ /* Don't use 0xa5 as the stack fill bytes as that is used by the kernerl for\r
+ the task stacks, and so will legitimately appear in many positions within\r
+ the ISR stack. */\r
+ #define portISR_STACK_FILL_BYTE 0xee\r
+\r
+ static const uint8_t ucExpectedStackBytes[] = {\r
+ portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \\r
+ portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \\r
+ portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \\r
+ portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \\r
+ portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE }; \\r
+\r
+ #define portCHECK_ISR_STACK() configASSERT( ( memcmp( ( void * ) xISRStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) == 0 ) )\r
+#else\r
+ /* Define the function away. */\r
+ #define portCHECK_ISR_STACK()\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configCLINT_BASE_ADDRESS != 0 )\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 += ( uint64_t ) ulTimerIncrementsForOneTick;\r
+ *pullMachineTimerCompareRegister = ullNextTime;\r
+\r
+ /* Prepare the time to use after the next tick interrupt. */\r
+ ullNextTime += ( uint64_t ) ulTimerIncrementsForOneTick;\r
+ }\r
+\r
+#endif /* ( configCLINT_BASE_ADDRESS != 0 ) */\r
+/*-----------------------------------------------------------*/\r
+\r
+BaseType_t xPortStartScheduler( void )\r
+{\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\r
+ single vector mode. */\r
+ __asm volatile( "csrr %0, mtvec" : "=r"( mtvec ) );\r
+ configASSERT( ( mtvec & 0x03UL ) == 0 );\r
+\r
+ /* Check alignment of the interrupt stack - which is the same as the\r
+ stack that was being used by main() prior to the scheduler being\r
+ started. */\r
+ configASSERT( ( xISRStackTop & portBYTE_ALIGNMENT_MASK ) == 0 );\r
+ }\r
+ #endif /* configASSERT_DEFINED */\r
+\r
+ /* If there is a CLINT then it is ok to use the default implementation\r
+ in this file, otherwise vPortSetupTimerInterrupt() must be implemented to\r
+ configure whichever clock is to be used to generate the tick interrupt. */\r
+ vPortSetupTimerInterrupt();\r
+\r
+ #if( configCLINT_BASE_ADDRESS != 0 )\r
+ {\r
+ /* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11\r
+ for external interrupt. _RB_ What happens here when mtime is not present as\r
+ with pulpino? */\r
+ __asm volatile( "csrs mie, %0" :: "r"(0x880) );\r
+ }\r
+ #else\r
+ {\r
+ /* Enable external interrupts. */\r
+ __asm volatile( "csrs mie, %0" :: "r"(0x800) );\r
+ }\r
+ #endif /* configCLINT_BASE_ADDRESS */\r
+\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
+\r