From 633d9d1eaec29cbc2185203acdb30bd01ec9ac73 Mon Sep 17 00:00:00 2001 From: jzlv Date: Wed, 21 Dec 2022 19:47:44 +0800 Subject: [PATCH] [refactor][freertos] split port into common and c906 --- components/freertos/CMakeLists.txt | 17 +- components/freertos/include/portable.h | 4 +- .../GCC/RISC-V/c906/Documentation.url | 5 + ...freertos_risc_v_chip_specific_extensions.h | 69 ++ .../freertos/portable/GCC/RISC-V/c906/port.c | 412 ++++++++++++ .../portable/GCC/RISC-V/c906/portASM.S | 625 ++++++++++++++++++ .../portable/GCC/RISC-V/c906/portmacro.h | 195 ++++++ ...freertos_risc_v_chip_specific_extensions.h | 0 ...freertos_risc_v_chip_specific_extensions.h | 0 ...freertos_risc_v_chip_specific_extensions.h | 0 .../chip_specific_extensions/readme.txt | 0 .../portable/GCC/RISC-V/{ => common}/port.c | 0 .../GCC/RISC-V/{ => common}/portASM.S | 146 +++- .../GCC/RISC-V/{ => common}/portmacro.h | 0 examples/freertos/FreeRTOSConfig.h | 13 +- examples/freertos/main.c | 3 +- 16 files changed, 1476 insertions(+), 13 deletions(-) create mode 100644 components/freertos/portable/GCC/RISC-V/c906/Documentation.url create mode 100644 components/freertos/portable/GCC/RISC-V/c906/chip_specific_extensions/Thead_E906FD_RV32IMAFDC/freertos_risc_v_chip_specific_extensions.h create mode 100644 components/freertos/portable/GCC/RISC-V/c906/port.c create mode 100644 components/freertos/portable/GCC/RISC-V/c906/portASM.S create mode 100644 components/freertos/portable/GCC/RISC-V/c906/portmacro.h rename components/freertos/portable/GCC/RISC-V/{ => common}/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h (100%) rename components/freertos/portable/GCC/RISC-V/{ => common}/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h (100%) rename components/freertos/portable/GCC/RISC-V/{ => common}/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h (100%) rename components/freertos/portable/GCC/RISC-V/{ => common}/chip_specific_extensions/readme.txt (100%) rename components/freertos/portable/GCC/RISC-V/{ => common}/port.c (100%) rename components/freertos/portable/GCC/RISC-V/{ => common}/portASM.S (79%) rename components/freertos/portable/GCC/RISC-V/{ => common}/portmacro.h (100%) diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index ce142dce..686f771f 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -9,10 +9,19 @@ sdk_library_add_sources(timers.c) sdk_library_add_sources(freertos_port.c) sdk_library_add_sources(portable/MemMang/heap_5.c) -sdk_library_add_sources(portable/GCC/RISC-V/port.c) -sdk_library_add_sources(portable/GCC/RISC-V/portASM.S) -sdk_add_include_directories(portable/GCC/RISC-V) -sdk_add_include_directories(portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions) sdk_add_include_directories(include) +if(("${CHIP}" STREQUAL "bl808") AND ("${CPU_ID}" STREQUAL "d0")) +sdk_library_add_sources(portable/GCC/RISC-V/c906/port.c) +sdk_library_add_sources(portable/GCC/RISC-V/c906/portASM.S) +sdk_add_include_directories(portable/GCC/RISC-V/c906) +sdk_add_include_directories(portable/GCC/RISC-V/c906/chip_specific_extensions/Thead_E906FD_RV32IMAFDC) +sdk_add_compile_definitions(-D__OS_FREERTOS__) +else() +sdk_library_add_sources(portable/GCC/RISC-V/common/port.c) +sdk_library_add_sources(portable/GCC/RISC-V/common/portASM.S) +sdk_add_include_directories(portable/GCC/RISC-V/common) +sdk_add_include_directories(portable/GCC/RISC-V/common/chip_specific_extensions/RV32I_CLINT_no_extensions) sdk_add_compile_definitions(-DportasmHANDLE_INTERRUPT=interrupt_entry -Ddefault_interrupt_handler=freertos_risc_v_trap_handler) + +endif() diff --git a/components/freertos/include/portable.h b/components/freertos/include/portable.h index 0ec6416a..1247fb7e 100644 --- a/components/freertos/include/portable.h +++ b/components/freertos/include/portable.h @@ -53,7 +53,9 @@ #include "portmacro.h" #endif -#if portBYTE_ALIGNMENT == 32 +#if portBYTE_ALIGNMENT == 128 + #define portBYTE_ALIGNMENT_MASK ( 0x007f ) +#elif portBYTE_ALIGNMENT == 32 #define portBYTE_ALIGNMENT_MASK ( 0x001f ) #elif portBYTE_ALIGNMENT == 16 #define portBYTE_ALIGNMENT_MASK ( 0x000f ) diff --git a/components/freertos/portable/GCC/RISC-V/c906/Documentation.url b/components/freertos/portable/GCC/RISC-V/c906/Documentation.url new file mode 100644 index 00000000..6d32fd88 --- /dev/null +++ b/components/freertos/portable/GCC/RISC-V/c906/Documentation.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 +[InternetShortcut] +IDList= +URL=https://freertos.org/Using-FreeRTOS-on-RISC-V.html diff --git a/components/freertos/portable/GCC/RISC-V/c906/chip_specific_extensions/Thead_E906FD_RV32IMAFDC/freertos_risc_v_chip_specific_extensions.h b/components/freertos/portable/GCC/RISC-V/c906/chip_specific_extensions/Thead_E906FD_RV32IMAFDC/freertos_risc_v_chip_specific_extensions.h new file mode 100644 index 00000000..10ed6319 --- /dev/null +++ b/components/freertos/portable/GCC/RISC-V/c906/chip_specific_extensions/Thead_E906FD_RV32IMAFDC/freertos_risc_v_chip_specific_extensions.h @@ -0,0 +1,69 @@ +/* + * FreeRTOS Kernel V10.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * The FreeRTOS kernel's RISC-V port is split between the the code that is + * common across all currently supported RISC-V chips (implementations of the + * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: + * + * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that + * is common to all currently supported RISC-V chips. There is only one + * portASM.S file because the same file is built for all RISC-V target chips. + * + * + Header files called freertos_risc_v_chip_specific_extensions.h contain the + * code that tailors the FreeRTOS kernel's RISC-V port to a specific RISC-V + * chip. There are multiple freertos_risc_v_chip_specific_extensions.h files + * as there are multiple RISC-V chip implementations. + * + * !!!NOTE!!! + * TAKE CARE TO INCLUDE THE CORRECT freertos_risc_v_chip_specific_extensions.h + * HEADER FILE FOR THE CHIP IN USE. This is done using the assembler's (not the + * compiler's!) include path. For example, if the chip in use includes a core + * local interrupter (CLINT) and does not include any chip specific register + * extensions then add the path below to the assembler's include path: + * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions + * + */ + + +#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__ +#define __FREERTOS_RISC_V_EXTENSIONS_H__ + +#define portasmHAS_SIFIVE_CLINT 1 +#define portasmHAS_MTIME 1 +#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */ +#define portasmHANDLE_INTERRUPT Default_IRQHandler + +.macro portasmSAVE_ADDITIONAL_REGISTERS + /* No additional registers to save, so this macro does nothing. */ + .endm + +.macro portasmRESTORE_ADDITIONAL_REGISTERS + /* No additional registers to restore, so this macro does nothing. */ + .endm + +#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */ diff --git a/components/freertos/portable/GCC/RISC-V/c906/port.c b/components/freertos/portable/GCC/RISC-V/c906/port.c new file mode 100644 index 00000000..9d96340d --- /dev/null +++ b/components/freertos/portable/GCC/RISC-V/c906/port.c @@ -0,0 +1,412 @@ +/* + * FreeRTOS Kernel V10.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the RISC-V RV32 port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "portmacro.h" + +/* Standard includes. */ +#include "string.h" + +#ifdef configCLINT_BASE_ADDRESS + #warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html +#endif + +#ifndef configMTIME_BASE_ADDRESS + #warning configMTIME_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtime register then set configMTIME_BASE_ADDRESS to the mapped address. Otherwise set configMTIME_BASE_ADDRESS to 0. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html +#endif + +#ifndef configMTIMECMP_BASE_ADDRESS + #warning configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtimecmp register then set configMTIMECMP_BASE_ADDRESS to the mapped address. Otherwise set configMTIMECMP_BASE_ADDRESS to 0. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html +#endif + +/* Let the user override the pre-loading of the initial LR with the address of +prvTaskExitError() in case it messes up unwinding of the stack in the +debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* The stack used by interrupt service routines. Set configISR_STACK_SIZE_WORDS +to use a statically allocated array as the interrupt stack. Alternative leave +configISR_STACK_SIZE_WORDS undefined and update the linker script so that a +linker variable names __freertos_irq_stack_top has the same value as the top +of the stack used by main. Using the linker script method will repurpose the +stack that was used by main before the scheduler was started for use as the +interrupt stack after the scheduler has started. */ +#ifdef configISR_STACK_SIZE_WORDS + static __attribute__ ((aligned(16))) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 }; + const StackType_t xISRStackTop = ( StackType_t ) &( xISRStack[ configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK ] ); + + /* Don't use 0xa5 as the stack fill bytes as that is used by the kernerl for + the task stacks, and so will legitimately appear in many positions within + the ISR stack. */ + #define portISR_STACK_FILL_BYTE 0xee +#else + extern const uint32_t __freertos_irq_stack_top[]; + const StackType_t xISRStackTop = ( StackType_t ) __freertos_irq_stack_top; +#endif + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ) __attribute__(( weak )); + +/*-----------------------------------------------------------*/ + +/* Used to program the machine timer compare register. */ +uint64_t ullNextTime = 0ULL; +const uint64_t *pullNextTime = &ullNextTime; +const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */ +uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS; +volatile uint32_t * pullMachineTimerCompareRegister = NULL; + +/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task +stack checking. A problem in the ISR stack will trigger an assert, not call the +stack overflow hook function (because the stack overflow hook is specific to a +task stack, not the ISR stack). */ +#if defined( configISR_STACK_SIZE_WORDS ) && ( configCHECK_FOR_STACK_OVERFLOW > 2 ) + #warning This path not tested, or even compiled yet. + + static const uint8_t ucExpectedStackBytes[] = { + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, \ + portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE }; \ + + #define portCHECK_ISR_STACK() configASSERT( ( memcmp( ( void * ) xISRStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) == 0 ) ) +#else + /* Define the function away. */ + #define portCHECK_ISR_STACK() +#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */ + +/*-----------------------------------------------------------*/ + +#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) + + void vPortSetupTimerInterrupt( void ) + { + uint32_t ulCurrentTimeHigh, ulCurrentTimeLow; + volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( ( configMTIME_BASE_ADDRESS ) + 4UL ); /* 8-byte typer so high 32-bit word is 4 bytes up. */ + volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configMTIME_BASE_ADDRESS ); + volatile uint32_t ulHartId; + + __asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) ); + pullMachineTimerCompareRegister = ( volatile uint32_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) ); + + do + { + ulCurrentTimeHigh = *pulTimeHigh; + ulCurrentTimeLow = *pulTimeLow; + } while( ulCurrentTimeHigh != *pulTimeHigh ); + + ullNextTime = ( uint64_t ) ulCurrentTimeHigh; + ullNextTime <<= 32ULL; /* High 4-byte word is 32-bits up. */ + ullNextTime |= ( uint64_t ) ulCurrentTimeLow; + ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; + pullMachineTimerCompareRegister[0] = (uint32_t)ullNextTime; + pullMachineTimerCompareRegister[1] = (uint32_t)(ullNextTime >> 32); + + /* Prepare the time to use after the next tick interrupt. */ + ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; + } +#else + void vPortSetupTimerInterrupt( void ) + { + uint64_t ulCurrentTime; + volatile uint32_t ulHartId; + + __asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) ); + __asm volatile( "csrr %0, time" : "=r"( ulCurrentTime ) ); + pullMachineTimerCompareRegister = ( volatile uint32_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) ); + + ullNextTime = ( uint64_t ) ulCurrentTime; + ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; + pullMachineTimerCompareRegister[0] = (uint32_t)ullNextTime; + pullMachineTimerCompareRegister[1] = (uint32_t)(ullNextTime >> 32); + + /* Prepare the time to use after the next tick interrupt. */ + ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; + } +#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIME_BASE_ADDRESS != 0 ) */ +/*-----------------------------------------------------------*/ + +/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This +will be set to 0 prior to the first task being started. */ +portLONG ulCriticalNesting = 0x9999UL; + +/* Used to record one tack want to swtich task after enter critical area, we need know it + * and implement task switch after exit critical area */ +portLONG pendsvflag = 0; + + +StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + StackType_t *stk = NULL; + register int *gp __asm("x3"); + uintptr_t temp = (uintptr_t)pxTopOfStack; + + temp &= 0xFFFFFFF8UL; + stk = (StackType_t *)temp; + +#ifndef __riscv_32e + *(--stk) = (uintptr_t)0x1234567812345678L; /* F31 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F30 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F29 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F28 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F27 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F26 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F25 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F24 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F23 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F22 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F21 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F20 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F19 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F18 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F17 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F16 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F15 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F14 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F13 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F12 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F11 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F10 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F9 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F8 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F7 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F6 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F5 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F4 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F3 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F2 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F1 */ + *(--stk) = (uintptr_t)0x1234567812345678L; /* F0 */ +#endif + + *(--stk) = (uintptr_t)pxCode; /* Entry Point */ + +#ifndef __riscv_32e + *(--stk) = (uintptr_t)0x3131313131313131L; /* X31 */ + *(--stk) = (uintptr_t)0x3030303030303030L; /* X30 */ + *(--stk) = (uintptr_t)0x2929292929292929L; /* X29 */ + *(--stk) = (uintptr_t)0x2828282828282828L; /* X28 */ + *(--stk) = (uintptr_t)0x2727272727272727L; /* X27 */ + *(--stk) = (uintptr_t)0x2626262626262626L; /* X26 */ + *(--stk) = (uintptr_t)0x2525252525252525L; /* X25 */ + *(--stk) = (uintptr_t)0x2424242424242424L; /* X24 */ + *(--stk) = (uintptr_t)0x2323232323232323L; /* X23 */ + *(--stk) = (uintptr_t)0x2222222222222222L; /* X22 */ + *(--stk) = (uintptr_t)0x2121212121212121L; /* X21 */ + *(--stk) = (uintptr_t)0x2020202020202020L; /* X20 */ + *(--stk) = (uintptr_t)0x1919191919191919L; /* X19 */ + *(--stk) = (uintptr_t)0x1818181818181818L; /* X18 */ + *(--stk) = (uintptr_t)0x1717171717171717L; /* X17 */ + *(--stk) = (uintptr_t)0x1616161616161616L; /* X16 */ +#endif + *(--stk) = (uintptr_t)0x1515151515151515L; /* X15 */ + *(--stk) = (uintptr_t)0x1414141414141414L; /* X14 */ + *(--stk) = (uintptr_t)0x1313131313131313L; /* X13 */ + *(--stk) = (uintptr_t)0x1212121212121212L; /* X12 */ + *(--stk) = (uintptr_t)0x1111111111111111L; /* X11 */ + *(--stk) = (uintptr_t)pvParameters; /* X10 */ + *(--stk) = (uintptr_t)0x0909090909090909L; /* X9 */ + *(--stk) = (uintptr_t)0x0808080808080808L; /* X8 */ + *(--stk) = (uintptr_t)0x0707070707070707L; /* X7 */ + *(--stk) = (uintptr_t)0x0606060606060606L; /* X6 */ + *(--stk) = (uintptr_t)0x0505050505050505L; /* X5 */ + *(--stk) = (uintptr_t)0x0404040404040404L; /* X4 */ + *(--stk) = (uintptr_t)gp; /* X3 */ + *(--stk) = (uintptr_t)0xFFFFFFFFFFFFFFFEL; /* X1 */ + + return stk; +} + +BaseType_t xPortStartScheduler( void ) +{ + ulCriticalNesting = 0UL; +extern void xPortStartFirstTask( void ); + + #if( configASSERT_DEFINED == 1 ) + { + // volatile uint32_t mtvec = 0; + + // /* Check the least significant two bits of mtvec are 00 - indicating + // single vector mode. */ + // __asm volatile( "csrr %0, mtvec" : "=r"( mtvec ) ); + // configASSERT( ( mtvec & 0x03UL ) == 0 ); + + /* Check alignment of the interrupt stack - which is the same as the + stack that was being used by main() prior to the scheduler being + started. */ + configASSERT( ( xISRStackTop & portBYTE_ALIGNMENT_MASK ) == 0 ); + + #ifdef configISR_STACK_SIZE_WORDS + { + memset( ( void * ) xISRStack, portISR_STACK_FILL_BYTE, sizeof( xISRStack ) ); + } + #endif /* configISR_STACK_SIZE_WORDS */ + } + #endif /* configASSERT_DEFINED */ + + /* If there is a CLINT then it is ok to use the default implementation + in this file, otherwise vPortSetupTimerInterrupt() must be implemented to + configure whichever clock is to be used to generate the tick interrupt. */ + //vPortSetupTimerInterrupt(); + + #if( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) ) + { + /* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11 + for external interrupt. _RB_ What happens here when mtime is not present as + with pulpino? */ + __asm volatile( "csrs mie, %0" :: "r"(0x880) ); + + /* enable M-mode soft IRQ in CLIC, TODO: priority 2 */ + *(volatile uint8_t *)(0xe0801001 + 3 * 4) = 1; + *(volatile uint8_t *)(0xe0801003 + 3 * 4) = 0x1f; + + /* enable M-mode timer IRQ in CLIC,TODO: priority 1 */ + *(volatile uint8_t *)(0xe0801001 + 7 * 4) = 1; + *(volatile uint8_t *)(0xe0801003 + 7 * 4) = 0x2f; + extern void CORET_IRQHandler(void); + void Interrupt_Handler_Register(int,void(*)(void)); + Interrupt_Handler_Register(7, CORET_IRQHandler); + + /* TODO: start clock of the mtimer */ + #ifndef __riscv_32e + *(volatile uint32_t *)0x20009014 = 0x80000001; + #else + *(volatile uint32_t *)0x2000E130 = 0x80000001; + #endif + } + #elif( ( configMTIME_BASE_ADDRESS == 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) ) + { + /* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11 + for external interrupt. _RB_ What happens here when mtime is not present as + with pulpino? */ + __asm volatile( "csrs mie, %0" :: "r"(0x888) ); + /* TODO: start clock of the mtimer */ + } + #else + { + /* Enable external interrupts. */ + __asm volatile( "csrs mie, %0" :: "r"(0x800) ); + } + #endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */ + + vPortSetupTimerInterrupt(); + xPortStartFirstTask(); + + /* Should not get here as after calling xPortStartFirstTask() only tasks + should be executing. */ + return pdFAIL; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented. */ + for( ;; ); +} + +void vTaskEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting ++; +} + +void vTaskExitCritical( void ) +{ + if (ulCriticalNesting == 0) { + while(1); + } + + ulCriticalNesting --; + if (ulCriticalNesting == 0) + { + portENABLE_INTERRUPTS(); + + if (pendsvflag) + { + pendsvflag = 0; + portYIELD(); + } + } +} + +#if configUSE_PREEMPTION == 0 +void xPortSysTickHandler( void ) +{ + portLONG ulDummy; + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + xTaskIncrementTick(); + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} + +#else +void xPortSysTickHandler( void ) +{ + portLONG ulDummy; + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if (xTaskIncrementTick() != pdFALSE) + { + portYIELD_FROM_ISR(pdTRUE); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} +#endif + +void vPortYieldHandler( void ) +{ + uint32_t ulSavedInterruptMask; + + ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR(); + + vTaskSwitchContext(); + + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); +} + +void CORET_IRQHandler(void) +{ + vPortSetupTimerInterrupt(); + xPortSysTickHandler(); +} diff --git a/components/freertos/portable/GCC/RISC-V/c906/portASM.S b/components/freertos/portable/GCC/RISC-V/c906/portASM.S new file mode 100644 index 00000000..7aa27c85 --- /dev/null +++ b/components/freertos/portable/GCC/RISC-V/c906/portASM.S @@ -0,0 +1,625 @@ +/* + * FreeRTOS Kernel V10.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * The FreeRTOS kernel's RISC-V port is split between the the code that is + * common across all currently supported RISC-V chips (implementations of the + * RISC-V ISA), and code which tailors the port to a specific RISC-V chip: + * + * + The code that is common to all RISC-V chips is implemented in + * FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S. There is only one + * portASM.S file because the same file is used no matter which RISC-V chip is + * in use. + * + * + The code that tailors the kernel's RISC-V port to a specific RISC-V + * chip is implemented in freertos_risc_v_chip_specific_extensions.h. There + * is one freertos_risc_v_chip_specific_extensions.h that can be used with any + * RISC-V chip that both includes a standard CLINT and does not add to the + * base set of RISC-V registers. There are additional + * freertos_risc_v_chip_specific_extensions.h files for RISC-V implementations + * that do not include a standard CLINT or do add to the base set of RISC-V + * registers. + * + * CARE MUST BE TAKEN TO INCLDUE THE CORRECT + * freertos_risc_v_chip_specific_extensions.h HEADER FILE FOR THE CHIP + * IN USE. To include the correct freertos_risc_v_chip_specific_extensions.h + * header file ensure the path to the correct header file is in the assembler's + * include path. + * + * This freertos_risc_v_chip_specific_extensions.h is for use on RISC-V chips + * that include a standard CLINT and do not add to the base set of RISC-V + * registers. + * + */ +#if __riscv_xlen == 64 + #define portWORD_SIZE 8 + #define store_x sd + #define load_x ld + #define store_f fsd + #define load_f fld +#elif __riscv_xlen == 32 + #define store_x sw + #define load_x lw + #define store_f fsw + #define load_f flw + #define portWORD_SIZE 4 +#else + #error Assembler did not define __riscv_xlen +#endif + +#include "freertos_risc_v_chip_specific_extensions.h" + +/* Check the freertos_risc_v_chip_specific_extensions.h and/or command line +definitions. */ +#if defined( portasmHAS_CLINT ) && defined( portasmHAS_MTIME ) + #error The portasmHAS_CLINT constant has been deprecated. Please replace it with portasmHAS_MTIME. portasmHAS_CLINT and portasmHAS_MTIME cannot both be defined at once. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html +#endif + +#ifdef portasmHAS_CLINT + #warning The portasmHAS_CLINT constant has been deprecated. Please replace it with portasmHAS_MTIME and portasmHAS_SIFIVE_CLINT. For now portasmHAS_MTIME and portasmHAS_SIFIVE_CLINT are derived from portasmHAS_CLINT. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html + #define portasmHAS_MTIME portasmHAS_CLINT + #define portasmHAS_SIFIVE_CLINT portasmHAS_CLINT +#endif + +#ifndef portasmHAS_MTIME + #error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_MTIME to either 1 (MTIME clock present) or 0 (MTIME clock not present). See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html +#endif + +#ifndef portasmHANDLE_INTERRUPT + #error portasmHANDLE_INTERRUPT must be defined to the function to be called to handle external/peripheral interrupts. portasmHANDLE_INTERRUPT can be defined on the assembler command line or in the appropriate freertos_risc_v_chip_specific_extensions.h header file. https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html +#endif + +#ifndef portasmHAS_SIFIVE_CLINT + #define portasmHAS_SIFIVE_CLINT 0 +#endif + +/* Only the standard core registers are stored by default. Any additional +registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and +portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip +specific version of freertos_risc_v_chip_specific_extensions.h. See the notes +at the top of this file. */ +#define portCONTEXT_SIZE ( 30 * portWORD_SIZE ) + +.global xPortStartFirstTask +.global freertos_risc_v_trap_handler +.global Mtspend_Handler +.global pxPortInitialiseStack +.extern pxCurrentTCB +.extern ulPortTrapHandler +.extern vTaskSwitchContext +.extern xTaskIncrementTick +.extern Timer_IRQHandler +.extern pullMachineTimerCompareRegister +.extern pullNextTime +.extern uxTimerIncrementsForOneTick /* size_t type so 32-bit on 32-bit core and 64-bits on 64-bit core. */ +.extern xISRStackTop +.extern portasmHANDLE_INTERRUPT + +/*-----------------------------------------------------------*/ +/* Enable interrupts when returning from the handler */ +#define MSTATUS_PRV1 0x1880 + +/******************************************************************** + * Functions: vPortYield + * + ********************************************************************/ +.global vPortYield +.type vPortYield, %function +vPortYield: +#if __riscv_xlen == 64 + li t0, 0xe4000000 +#else + li t0, 0xe0000000 +#endif + li t2, 0x1 + sw t2, 0(t0) + nop + nop + + ret + + +.align 8 +.func +freertos_risc_v_trap_handler: +Mtspend_Handler: +// csrrw sp, mscratch, sp +#ifndef __riscv_float_abi_soft + addi sp, sp, -(portWORD_SIZE * 32) + store_f f31, (portWORD_SIZE * 0)(sp) + store_f f30, (portWORD_SIZE * 1)(sp) + store_f f29, (portWORD_SIZE * 2)(sp) + store_f f28, (portWORD_SIZE * 3)(sp) + store_f f27, (portWORD_SIZE * 4)(sp) + store_f f26, (portWORD_SIZE * 5)(sp) + store_f f25, (portWORD_SIZE * 6)(sp) + store_f f24, (portWORD_SIZE * 7)(sp) + store_f f23, (portWORD_SIZE * 8)(sp) + store_f f22, (portWORD_SIZE * 9)(sp) + store_f f21, (portWORD_SIZE * 10)(sp) + store_f f20, (portWORD_SIZE * 11)(sp) + store_f f19, (portWORD_SIZE * 12)(sp) + store_f f18, (portWORD_SIZE * 13)(sp) + store_f f17, (portWORD_SIZE * 14)(sp) + store_f f16, (portWORD_SIZE * 15)(sp) + store_f f15, (portWORD_SIZE * 16)(sp) + store_f f14, (portWORD_SIZE * 17)(sp) + store_f f13, (portWORD_SIZE * 18)(sp) + store_f f12, (portWORD_SIZE * 19)(sp) + store_f f11, (portWORD_SIZE * 20)(sp) + store_f f10, (portWORD_SIZE * 21)(sp) + store_f f9, (portWORD_SIZE * 22)(sp) + store_f f8, (portWORD_SIZE * 23)(sp) + store_f f7, (portWORD_SIZE * 24)(sp) + store_f f6, (portWORD_SIZE * 25)(sp) + store_f f5, (portWORD_SIZE * 26)(sp) + store_f f4, (portWORD_SIZE * 27)(sp) + store_f f3, (portWORD_SIZE * 28)(sp) + store_f f2, (portWORD_SIZE * 29)(sp) + store_f f1, (portWORD_SIZE * 30)(sp) + store_f f0, (portWORD_SIZE * 31)(sp) +#endif + +#ifndef __riscv_32e + addi sp, sp, -(portWORD_SIZE * 31) +#else + addi sp, sp, -(portWORD_SIZE * 15) +#endif + + store_x x1, (portWORD_SIZE * 0)(sp) + store_x x3, (portWORD_SIZE * 1)(sp) + store_x x4, (portWORD_SIZE * 2)(sp) + store_x x5, (portWORD_SIZE * 3)(sp) + store_x x6, (portWORD_SIZE * 4)(sp) + store_x x7, (portWORD_SIZE * 5)(sp) + store_x x8, (portWORD_SIZE * 6)(sp) + store_x x9, (portWORD_SIZE * 7)(sp) + store_x x10, (portWORD_SIZE * 8)(sp) + store_x x11, (portWORD_SIZE * 9)(sp) + store_x x12, (portWORD_SIZE * 10)(sp) + store_x x13, (portWORD_SIZE * 11)(sp) + store_x x14, (portWORD_SIZE * 12)(sp) + store_x x15, (portWORD_SIZE * 13)(sp) +#ifndef __riscv_32e + store_x x16, (portWORD_SIZE * 14)(sp) + store_x x17, (portWORD_SIZE * 15)(sp) + store_x x18, (portWORD_SIZE * 16)(sp) + store_x x19, (portWORD_SIZE * 17)(sp) + store_x x20, (portWORD_SIZE * 18)(sp) + store_x x21, (portWORD_SIZE * 19)(sp) + store_x x22, (portWORD_SIZE * 20)(sp) + store_x x23, (portWORD_SIZE * 21)(sp) + store_x x24, (portWORD_SIZE * 22)(sp) + store_x x25, (portWORD_SIZE * 23)(sp) + store_x x26, (portWORD_SIZE * 24)(sp) + store_x x27, (portWORD_SIZE * 25)(sp) + store_x x28, (portWORD_SIZE * 26)(sp) + store_x x29, (portWORD_SIZE * 27)(sp) + store_x x30, (portWORD_SIZE * 28)(sp) + store_x x31, (portWORD_SIZE * 29)(sp) +#endif + csrr t0, mepc +#ifndef __riscv_32e + store_x t0, (portWORD_SIZE * 30)(sp) +#else + store_x t0, (portWORD_SIZE * 14)(sp) +#endif + la a1, pxCurrentTCB + load_x a1, (a1) + store_x sp, (a1) + + jal vTaskSwitchContext + + la a1, pxCurrentTCB + load_x a1, (a1) + load_x sp, (a1) + +#if __riscv_xlen == 64 + li t0, 0xe4000000 +#else + li t0, 0xe0000000 +#endif + li t2, 0x0 + sw t2, 0(t0) + + /* Run in machine mode */ + li t0, MSTATUS_PRV1 + csrs mstatus, t0 + +#ifndef __riscv_32e + load_x t0, (portWORD_SIZE * 30)(sp) +#else + load_x t0, (portWORD_SIZE * 14)(sp) +#endif + csrw mepc, t0 + + load_x x1, (portWORD_SIZE * 0)(sp) + load_x x3, (portWORD_SIZE * 1)(sp) + load_x x4, (portWORD_SIZE * 2)(sp) + load_x x5, (portWORD_SIZE * 3)(sp) + load_x x6, (portWORD_SIZE * 4)(sp) + load_x x7, (portWORD_SIZE * 5)(sp) + load_x x8, (portWORD_SIZE * 6)(sp) + load_x x9, (portWORD_SIZE * 7)(sp) + load_x x10, (portWORD_SIZE * 8)(sp) + load_x x11, (portWORD_SIZE * 9)(sp) + load_x x12, (portWORD_SIZE * 10)(sp) + load_x x13, (portWORD_SIZE * 11)(sp) + load_x x14, (portWORD_SIZE * 12)(sp) + load_x x15, (portWORD_SIZE * 13)(sp) +#ifndef __riscv_32e + load_x x16, (portWORD_SIZE * 14)(sp) + load_x x17, (portWORD_SIZE * 15)(sp) + load_x x18, (portWORD_SIZE * 16)(sp) + load_x x19, (portWORD_SIZE * 17)(sp) + load_x x20, (portWORD_SIZE * 18)(sp) + load_x x21, (portWORD_SIZE * 19)(sp) + load_x x22, (portWORD_SIZE * 20)(sp) + load_x x23, (portWORD_SIZE * 21)(sp) + load_x x24, (portWORD_SIZE * 22)(sp) + load_x x25, (portWORD_SIZE * 23)(sp) + load_x x26, (portWORD_SIZE * 24)(sp) + load_x x27, (portWORD_SIZE * 25)(sp) + load_x x28, (portWORD_SIZE * 26)(sp) + load_x x29, (portWORD_SIZE * 27)(sp) + load_x x30, (portWORD_SIZE * 28)(sp) + load_x x31, (portWORD_SIZE * 29)(sp) +#endif + +#ifndef __riscv_32e + addi sp, sp, (portWORD_SIZE * 31) +#else + addi sp, sp, (portWORD_SIZE * 15) +#endif + +#ifndef __riscv_float_abi_soft + load_f f31,(portWORD_SIZE * 0)(sp) + load_f f30,(portWORD_SIZE * 1)(sp) + load_f f29,(portWORD_SIZE * 2)(sp) + load_f f28,(portWORD_SIZE * 3)(sp) + load_f f27,(portWORD_SIZE * 4)(sp) + load_f f26,(portWORD_SIZE * 5)(sp) + load_f f25,(portWORD_SIZE * 6)(sp) + load_f f24,(portWORD_SIZE * 7)(sp) + load_f f23,(portWORD_SIZE * 8)(sp) + load_f f22,(portWORD_SIZE * 9)(sp) + load_f f21,(portWORD_SIZE * 10)(sp) + load_f f20,(portWORD_SIZE * 11)(sp) + load_f f19,(portWORD_SIZE * 12)(sp) + load_f f18,(portWORD_SIZE * 13)(sp) + load_f f17,(portWORD_SIZE * 14)(sp) + load_f f16,(portWORD_SIZE * 15)(sp) + load_f f15,(portWORD_SIZE * 16)(sp) + load_f f14,(portWORD_SIZE * 17)(sp) + load_f f13,(portWORD_SIZE * 18)(sp) + load_f f12,(portWORD_SIZE * 19)(sp) + load_f f11,(portWORD_SIZE * 20)(sp) + load_f f10,(portWORD_SIZE * 21)(sp) + load_f f9, (portWORD_SIZE * 22)(sp) + load_f f8, (portWORD_SIZE * 23)(sp) + load_f f7, (portWORD_SIZE * 24)(sp) + load_f f6, (portWORD_SIZE * 25)(sp) + load_f f5, (portWORD_SIZE * 26)(sp) + load_f f4, (portWORD_SIZE * 27)(sp) + load_f f3, (portWORD_SIZE * 28)(sp) + load_f f2, (portWORD_SIZE * 29)(sp) + load_f f1, (portWORD_SIZE * 30)(sp) + load_f f0, (portWORD_SIZE * 31)(sp) + + addi sp, sp, (portWORD_SIZE * 32) +#endif +// csrrw sp, mscratch, sp + + mret + .endfunc + +#if 0 +.align 8 +.func +freertos_risc_v_trap_handler: + addi sp, sp, -portCONTEXT_SIZE + store_x x1, 1 * portWORD_SIZE( sp ) + store_x x5, 2 * portWORD_SIZE( sp ) + store_x x6, 3 * portWORD_SIZE( sp ) + store_x x7, 4 * portWORD_SIZE( sp ) + store_x x8, 5 * portWORD_SIZE( sp ) + store_x x9, 6 * portWORD_SIZE( sp ) + store_x x10, 7 * portWORD_SIZE( sp ) + store_x x11, 8 * portWORD_SIZE( sp ) + store_x x12, 9 * portWORD_SIZE( sp ) + store_x x13, 10 * portWORD_SIZE( sp ) + store_x x14, 11 * portWORD_SIZE( sp ) + store_x x15, 12 * portWORD_SIZE( sp ) + store_x x16, 13 * portWORD_SIZE( sp ) + store_x x17, 14 * portWORD_SIZE( sp ) + store_x x18, 15 * portWORD_SIZE( sp ) + store_x x19, 16 * portWORD_SIZE( sp ) + store_x x20, 17 * portWORD_SIZE( sp ) + store_x x21, 18 * portWORD_SIZE( sp ) + store_x x22, 19 * portWORD_SIZE( sp ) + store_x x23, 20 * portWORD_SIZE( sp ) + store_x x24, 21 * portWORD_SIZE( sp ) + store_x x25, 22 * portWORD_SIZE( sp ) + store_x x26, 23 * portWORD_SIZE( sp ) + store_x x27, 24 * portWORD_SIZE( sp ) + store_x x28, 25 * portWORD_SIZE( sp ) + store_x x29, 26 * portWORD_SIZE( sp ) + store_x x30, 27 * portWORD_SIZE( sp ) + store_x x31, 28 * portWORD_SIZE( sp ) + + csrr t0, mstatus /* Required for MPIE bit. */ + store_x t0, 29 * portWORD_SIZE( sp ) + + portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */ + + load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */ + store_x sp, 0( t0 ) /* Write sp to first TCB member. */ + + csrr a0, mcause + csrr a1, mepc + andi a2, a0, 0x3FF +handle_synchronous: + addi a1, a1, 4 /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */ + store_x a1, 0( sp ) /* Save updated exception return address. */ + +test_if_environment_call: + li t0, 11 /* 11 == environment call. */ + bne a2, t0, trap_c /* Not an M environment call, so some other exception. */ + load_x sp, xISRStackTop /* Switch to ISR stack before function call. */ + jal vTaskSwitchContext + j processed_source + +is_exception: + csrr t0, mcause /* For viewing in the debugger only. */ + csrr t1, mepc /* For viewing in the debugger only */ + csrr t2, mstatus + j is_exception /* No other exceptions handled yet. */ + +as_yet_unhandled: + csrr t0, mcause /* For viewing in the debugger only. */ + j as_yet_unhandled + +processed_source: + load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */ + load_x sp, 0( t1 ) /* Read sp from first TCB member. */ + + /* Load mret with the address of the next instruction in the task to run next. */ + load_x t0, 0( sp ) + csrw mepc, t0 + + portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */ + + /* Load mstatus with the interrupt enable bits used by the task. */ + load_x t0, 29 * portWORD_SIZE( sp ) + csrw mstatus, t0 /* Required for MPIE bit. */ + + load_x x1, 1 * portWORD_SIZE( sp ) + load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */ + load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */ + load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */ + load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */ + load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */ + load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */ + load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */ + load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */ + load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */ + load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */ + load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */ + load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */ + load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */ + load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */ + load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */ + load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */ + load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */ + load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */ + load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */ + load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */ + load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */ + load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */ + load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */ + load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */ + load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */ + load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */ + load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */ + addi sp, sp, portCONTEXT_SIZE + + mret + .endfunc +/*-----------------------------------------------------------*/ +#endif + +.align 8 +.func +xPortStartFirstTask: + +#if( portasmHAS_SIFIVE_CLINT != 0 ) + /* If there is a clint then interrupts can branch directly to the FreeRTOS + trap handler. Otherwise the interrupt controller will need to be configured + outside of this file. */ +// la t0, freertos_risc_v_trap_handler +// csrw mtvec, t0 +#endif /* portasmHAS_CLILNT */ + + la a0, pxCurrentTCB + load_x a0, (a0) + load_x sp, (a0) + + /* Run in machine mode */ + li t0, MSTATUS_PRV1 + csrs mstatus, t0 + +#ifndef __riscv_32e + load_x t0, (portWORD_SIZE * 30)(sp) +#else + load_x t0, (portWORD_SIZE * 14)(sp) +#endif + csrw mepc, t0 + + load_x x1, (portWORD_SIZE * 0)(sp) + load_x x3, (portWORD_SIZE * 1)(sp) + load_x x4, (portWORD_SIZE * 2)(sp) + load_x x5, (portWORD_SIZE * 3)(sp) + load_x x6, (portWORD_SIZE * 4)(sp) + load_x x7, (portWORD_SIZE * 5)(sp) + load_x x8, (portWORD_SIZE * 6)(sp) + load_x x9, (portWORD_SIZE * 7)(sp) + load_x x10, (portWORD_SIZE * 8)(sp) + load_x x11, (portWORD_SIZE * 9)(sp) + load_x x12, (portWORD_SIZE * 10)(sp) + load_x x13, (portWORD_SIZE * 11)(sp) + load_x x14, (portWORD_SIZE * 12)(sp) + load_x x15, (portWORD_SIZE * 13)(sp) +#ifndef __riscv_32e + load_x x16, (portWORD_SIZE * 14)(sp) + load_x x17, (portWORD_SIZE * 15)(sp) + load_x x18, (portWORD_SIZE * 16)(sp) + load_x x19, (portWORD_SIZE * 17)(sp) + load_x x20, (portWORD_SIZE * 18)(sp) + load_x x21, (portWORD_SIZE * 19)(sp) + load_x x22, (portWORD_SIZE * 20)(sp) + load_x x23, (portWORD_SIZE * 21)(sp) + load_x x24, (portWORD_SIZE * 22)(sp) + load_x x25, (portWORD_SIZE * 23)(sp) + load_x x26, (portWORD_SIZE * 24)(sp) + load_x x27, (portWORD_SIZE * 25)(sp) + load_x x28, (portWORD_SIZE * 26)(sp) + load_x x29, (portWORD_SIZE * 27)(sp) + load_x x30, (portWORD_SIZE * 28)(sp) + load_x x31, (portWORD_SIZE * 29)(sp) +#endif + +#ifndef __riscv_32e + addi sp, sp, (portWORD_SIZE * 31) +#else + addi sp, sp, (portWORD_SIZE * 15) +#endif + +#ifndef __riscv_float_abi_soft + load_f f31, (portWORD_SIZE * 0)(sp) + load_f f30, (portWORD_SIZE * 1)(sp) + load_f f29, (portWORD_SIZE * 2)(sp) + load_f f28, (portWORD_SIZE * 3)(sp) + load_f f27, (portWORD_SIZE * 4)(sp) + load_f f26, (portWORD_SIZE * 5)(sp) + load_f f25, (portWORD_SIZE * 6)(sp) + load_f f24, (portWORD_SIZE * 7)(sp) + load_f f23, (portWORD_SIZE * 8)(sp) + load_f f22, (portWORD_SIZE * 9)(sp) + load_f f21, (portWORD_SIZE * 10)(sp) + load_f f20, (portWORD_SIZE * 11)(sp) + load_f f19, (portWORD_SIZE * 12)(sp) + load_f f18, (portWORD_SIZE * 13)(sp) + load_f f17, (portWORD_SIZE * 14)(sp) + load_f f16, (portWORD_SIZE * 15)(sp) + load_f f15, (portWORD_SIZE * 16)(sp) + load_f f14, (portWORD_SIZE * 17)(sp) + load_f f13, (portWORD_SIZE * 18)(sp) + load_f f12, (portWORD_SIZE * 19)(sp) + load_f f11, (portWORD_SIZE * 20)(sp) + load_f f10, (portWORD_SIZE * 21)(sp) + load_f f9, (portWORD_SIZE * 22)(sp) + load_f f8, (portWORD_SIZE * 23)(sp) + load_f f7, (portWORD_SIZE * 24)(sp) + load_f f6, (portWORD_SIZE * 25)(sp) + load_f f5, (portWORD_SIZE * 26)(sp) + load_f f4, (portWORD_SIZE * 27)(sp) + load_f f3, (portWORD_SIZE * 28)(sp) + load_f f2, (portWORD_SIZE * 29)(sp) + load_f f1, (portWORD_SIZE * 30)(sp) + load_f f0, (portWORD_SIZE * 31)(sp) + + addi sp, sp, (portWORD_SIZE * 32) +#endif + + mret + .endfunc +/*-----------------------------------------------------------*/ + +/* + * Unlike other ports pxPortInitialiseStack() is written in assembly code as it + * needs access to the portasmADDITIONAL_CONTEXT_SIZE constant. The prototype + * for the function is as per the other ports: + * StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ); + * + * As per the standard RISC-V ABI pxTopcOfStack is passed in in a0, pxCode in + * a1, and pvParameters in a2. The new top of stack is passed out in a0. + * + * RISC-V maps registers to ABI names as follows (X1 to X31 integer registers + * for the 'I' profile, X1 to X15 for the 'E' profile, currently I assumed). + * + * Register ABI Name Description Saver + * x0 zero Hard-wired zero - + * x1 ra Return address Caller + * x2 sp Stack pointer Callee + * x3 gp Global pointer - + * x4 tp Thread pointer - + * x5-7 t0-2 Temporaries Caller + * x8 s0/fp Saved register/Frame pointer Callee + * x9 s1 Saved register Callee + * x10-11 a0-1 Function Arguments/return values Caller + * x12-17 a2-7 Function arguments Caller + * x18-27 s2-11 Saved registers Callee + * x28-31 t3-6 Temporaries Caller + * + * The RISC-V context is saved t FreeRTOS tasks in the following stack frame, + * where the global and thread pointers are currently assumed to be constant so + * are not saved: + * + * mstatus + * x31 + * x30 + * x29 + * x28 + * x27 + * x26 + * x25 + * x24 + * x23 + * x22 + * x21 + * x20 + * x19 + * x18 + * x17 + * x16 + * x15 + * x14 + * x13 + * x12 + * x11 + * pvParameters + * x9 + * x8 + * x7 + * x6 + * x5 + * portTASK_RETURN_ADDRESS + * [chip specific registers go here] + * pxCode + */ + +/*-----------------------------------------------------------*/ diff --git a/components/freertos/portable/GCC/RISC-V/c906/portmacro.h b/components/freertos/portable/GCC/RISC-V/c906/portmacro.h new file mode 100644 index 00000000..b6d1fec7 --- /dev/null +++ b/components/freertos/portable/GCC/RISC-V/c906/portmacro.h @@ -0,0 +1,195 @@ +/* + * FreeRTOS Kernel V10.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#if __riscv_xlen == 64 + #define portSTACK_TYPE uint64_t + #define portBASE_TYPE long long + #define portUBASE_TYPE uint64_t + #define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffUL + #define portPOINTER_SIZE_TYPE uint64_t +#elif __riscv_xlen == 32 + #define portSTACK_TYPE uint32_t + #define portBASE_TYPE int + #define portUBASE_TYPE uint32_t + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#else + #error Assembler did not define __riscv_xlen +#endif + + +typedef portSTACK_TYPE StackType_t; +typedef portBASE_TYPE BaseType_t; +typedef portUBASE_TYPE UBaseType_t; +typedef portUBASE_TYPE TickType_t; + +/* Legacy type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do +not need to be guarded with a critical section. */ +#define portTICK_TYPE_IS_ATOMIC 1 +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#ifdef __riscv64 + #error This is the RV32 port that has not yet been adapted for 64. + #define portBYTE_ALIGNMENT 16 +#else + #define portBYTE_ALIGNMENT 128 +#endif +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +extern void vPortYield( void ); +#define portYIELD() vPortYield(); + +/* Scheduler utilities. */ +extern void vTaskSwitchContext( void ); +//#define portYIELD() __asm volatile( "ecall" ); +//#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portYIELD() +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + + +/* Critical section management. */ +//#define portCRITICAL_NESTING_IN_TCB 1 +extern void vTaskEnterCritical( void ); +extern void vTaskExitCritical( void ); + +#define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#define portDISABLE_INTERRUPTS() __asm volatile( "csrc mstatus, 8" ) +#define portENABLE_INTERRUPTS() __asm volatile( "csrs mstatus, 8" ) +#define portENTER_CRITICAL() vTaskEnterCritical() +#define portEXIT_CRITICAL() vTaskExitCritical() + +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - __builtin_clz( uxReadyPriorities ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +/*-----------------------------------------------------------*/ + +#define portNOP() __asm volatile ( " nop " ) + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +#define portMEMORY_BARRIER() __asm volatile( "fence" ::: "memory" ) +/*-----------------------------------------------------------*/ + + +/* configCLINT_BASE_ADDRESS is a legacy definition that was replaced by the +configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For +backward compatibility derive the newer definitions from the old if the old +definition is found. */ +#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 ) + /* Legacy case where configCLINT_BASE_ADDRESS was defined as 0 to indicate + there was no CLINT. Equivalent now is to set the MTIME and MTIMECMP + addresses to 0. */ + #define configMTIME_BASE_ADDRESS ( 0 ) + #define configMTIMECMP_BASE_ADDRESS ( 0 ) +#elif defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) + /* Legacy case where configCLINT_BASE_ADDRESS was set to the base address of + the CLINT. Equivalent now is to derive the MTIME and MTIMECMP addresses + from the CLINT address. */ + #define configMTIME_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0xBFF8UL ) + #define configMTIMECMP_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0x4000UL ) +#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS ) + #error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. Set them to zero if there is no MTIME (machine time) clock. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html +#endif + + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ + extern uint64_t g_irq_nested_level; + return g_irq_nested_level ? 1 : 0; +} + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/components/freertos/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h b/components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h similarity index 100% rename from components/freertos/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h rename to components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h diff --git a/components/freertos/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h similarity index 100% rename from components/freertos/portable/GCC/RISC-V/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h rename to components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/RISCV_MTIME_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h diff --git a/components/freertos/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h b/components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h similarity index 100% rename from components/freertos/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h rename to components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/RV32I_CLINT_no_extensions/freertos_risc_v_chip_specific_extensions.h diff --git a/components/freertos/portable/GCC/RISC-V/chip_specific_extensions/readme.txt b/components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/readme.txt similarity index 100% rename from components/freertos/portable/GCC/RISC-V/chip_specific_extensions/readme.txt rename to components/freertos/portable/GCC/RISC-V/common/chip_specific_extensions/readme.txt diff --git a/components/freertos/portable/GCC/RISC-V/port.c b/components/freertos/portable/GCC/RISC-V/common/port.c similarity index 100% rename from components/freertos/portable/GCC/RISC-V/port.c rename to components/freertos/portable/GCC/RISC-V/common/port.c diff --git a/components/freertos/portable/GCC/RISC-V/portASM.S b/components/freertos/portable/GCC/RISC-V/common/portASM.S similarity index 79% rename from components/freertos/portable/GCC/RISC-V/portASM.S rename to components/freertos/portable/GCC/RISC-V/common/portASM.S index 40f88cc5..ac10892e 100644 --- a/components/freertos/portable/GCC/RISC-V/portASM.S +++ b/components/freertos/portable/GCC/RISC-V/common/portASM.S @@ -94,6 +94,10 @@ definitions. */ #define portasmHAS_SIFIVE_CLINT 0 #endif +#ifndef portasmHAS_F_EXTENSION + #define portasmHAS_F_EXTENSION 0 +#endif + /* Only the standard core registers are stored by default. Any additional registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip @@ -101,6 +105,11 @@ specific version of freertos_risc_v_chip_specific_extensions.h. See the notes at the top of this file. */ #define portCONTEXT_SIZE ( 30 * portWORD_SIZE ) + +#define portFLOAT_CONTEXT_SIZE ( 34 * portWORD_SIZE ) + + + .global xPortStartFirstTask .global freertos_risc_v_trap_handler .global pxPortInitialiseStack @@ -155,6 +164,50 @@ freertos_risc_v_trap_handler: csrr t0, mstatus /* Required for MPIE bit. */ store_x t0, 29 * portWORD_SIZE( sp ) +#if( portasmHAS_F_EXTENSION != 0 ) + addi sp, sp, -portFLOAT_CONTEXT_SIZE + csrr t1, mstatus + sw t1, 34 * portWORD_SIZE( sp ) + srli t2, t1, 13 + andi t2, t2, 0x3 + li t0, 0x3 + bne t2, t0, f_reg_skip_save + + fsw f0, 1 * portWORD_SIZE( sp ) + fsw f1, 2 * portWORD_SIZE( sp ) + fsw f2, 3 * portWORD_SIZE( sp ) + fsw f3, 4 * portWORD_SIZE( sp ) + fsw f4, 5 * portWORD_SIZE( sp ) + fsw f5, 6 * portWORD_SIZE( sp ) + fsw f6, 7 * portWORD_SIZE( sp ) + fsw f7, 8 * portWORD_SIZE( sp ) + fsw f8, 9 * portWORD_SIZE( sp ) + fsw f9, 10 * portWORD_SIZE( sp ) + fsw f10, 11 * portWORD_SIZE( sp ) + fsw f11, 12 * portWORD_SIZE( sp ) + fsw f12, 13 * portWORD_SIZE( sp ) + fsw f13, 14 * portWORD_SIZE( sp ) + fsw f14, 15 * portWORD_SIZE( sp ) + fsw f15, 16 * portWORD_SIZE( sp ) + fsw f16, 17 * portWORD_SIZE( sp ) + fsw f17, 18 * portWORD_SIZE( sp ) + fsw f18, 19 * portWORD_SIZE( sp ) + fsw f19, 20 * portWORD_SIZE( sp ) + fsw f20, 21 * portWORD_SIZE( sp ) + fsw f21, 22 * portWORD_SIZE( sp ) + fsw f22, 23 * portWORD_SIZE( sp ) + fsw f23, 24 * portWORD_SIZE( sp ) + fsw f24, 25 * portWORD_SIZE( sp ) + fsw f25, 26 * portWORD_SIZE( sp ) + fsw f26, 27 * portWORD_SIZE( sp ) + fsw f27, 28 * portWORD_SIZE( sp ) + fsw f28, 29 * portWORD_SIZE( sp ) + fsw f29, 30 * portWORD_SIZE( sp ) + fsw f30, 31 * portWORD_SIZE( sp ) + fsw f31, 32 * portWORD_SIZE( sp ) +f_reg_skip_save: +#endif + portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */ load_x t0, pTrapNetCounter @@ -250,8 +303,8 @@ is_exception: csrr t0, mcause /* For viewing in the debugger only. */ csrr t1, mepc /* For viewing in the debugger only */ csrr t2, mstatus - jal exception_entry /* No other exceptions handled yet. */ - j is_exception /* No other exceptions handled yet. */ + j exception_entry /* No other exceptions handled yet. */ + # j is_exception /* No other exceptions handled yet. */ as_yet_unhandled: csrr t0, mcause /* For viewing in the debugger only. */ @@ -272,6 +325,48 @@ processed_source: portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */ +#if( portasmHAS_F_EXTENSION != 0 ) + lw t1, 34 * portWORD_SIZE( sp ) + srli t2, t1, 13 + andi t2, t2, 0x3 + li t0, 0x3 + bne t2, t0, f_reg_skip_restore1 + flw f0, 1 * portWORD_SIZE( sp ) + flw f1, 2 * portWORD_SIZE( sp ) + flw f2, 3 * portWORD_SIZE( sp ) + flw f3, 4 * portWORD_SIZE( sp ) + flw f4, 5 * portWORD_SIZE( sp ) + flw f5, 6 * portWORD_SIZE( sp ) + flw f6, 7 * portWORD_SIZE( sp ) + flw f7, 8 * portWORD_SIZE( sp ) + flw f8, 9 * portWORD_SIZE( sp ) + flw f9, 10 * portWORD_SIZE( sp ) + flw f10, 11 * portWORD_SIZE( sp ) + flw f11, 12 * portWORD_SIZE( sp ) + flw f12, 13 * portWORD_SIZE( sp ) + flw f13, 14 * portWORD_SIZE( sp ) + flw f14, 15 * portWORD_SIZE( sp ) + flw f15, 16 * portWORD_SIZE( sp ) + flw f16, 17 * portWORD_SIZE( sp ) + flw f17, 18 * portWORD_SIZE( sp ) + flw f18, 19 * portWORD_SIZE( sp ) + flw f19, 20 * portWORD_SIZE( sp ) + flw f20, 21 * portWORD_SIZE( sp ) + flw f21, 22 * portWORD_SIZE( sp ) + flw f22, 23 * portWORD_SIZE( sp ) + flw f23, 24 * portWORD_SIZE( sp ) + flw f24, 25 * portWORD_SIZE( sp ) + flw f25, 26 * portWORD_SIZE( sp ) + flw f26, 27 * portWORD_SIZE( sp ) + flw f27, 28 * portWORD_SIZE( sp ) + flw f28, 29 * portWORD_SIZE( sp ) + flw f29, 30 * portWORD_SIZE( sp ) + flw f30, 31 * portWORD_SIZE( sp ) + flw f31, 32 * portWORD_SIZE( sp ) +f_reg_skip_restore1: + addi sp, sp, portFLOAT_CONTEXT_SIZE +#endif + /* Load mstatus with the interrupt enable bits used by the task. */ load_x t0, 29 * portWORD_SIZE( sp ) csrw mstatus, t0 /* Required for MPIE bit. */ @@ -330,6 +425,48 @@ xPortStartFirstTask: portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */ +#if( portasmHAS_F_EXTENSION != 0 ) + lw t1, 34 * portWORD_SIZE( sp ) + srli t2, t1, 13 + andi t2, t2, 0x3 + li t0, 0x3 + bne t2, t0, f_reg_skip_restore2 + flw f0, 1 * portWORD_SIZE( sp ) + flw f1, 2 * portWORD_SIZE( sp ) + flw f2, 3 * portWORD_SIZE( sp ) + flw f3, 4 * portWORD_SIZE( sp ) + flw f4, 5 * portWORD_SIZE( sp ) + flw f5, 6 * portWORD_SIZE( sp ) + flw f6, 7 * portWORD_SIZE( sp ) + flw f7, 8 * portWORD_SIZE( sp ) + flw f8, 9 * portWORD_SIZE( sp ) + flw f9, 10 * portWORD_SIZE( sp ) + flw f10, 11 * portWORD_SIZE( sp ) + flw f11, 12 * portWORD_SIZE( sp ) + flw f12, 13 * portWORD_SIZE( sp ) + flw f13, 14 * portWORD_SIZE( sp ) + flw f14, 15 * portWORD_SIZE( sp ) + flw f15, 16 * portWORD_SIZE( sp ) + flw f16, 17 * portWORD_SIZE( sp ) + flw f17, 18 * portWORD_SIZE( sp ) + flw f18, 19 * portWORD_SIZE( sp ) + flw f19, 20 * portWORD_SIZE( sp ) + flw f20, 21 * portWORD_SIZE( sp ) + flw f21, 22 * portWORD_SIZE( sp ) + flw f22, 23 * portWORD_SIZE( sp ) + flw f23, 24 * portWORD_SIZE( sp ) + flw f24, 25 * portWORD_SIZE( sp ) + flw f25, 26 * portWORD_SIZE( sp ) + flw f26, 27 * portWORD_SIZE( sp ) + flw f27, 28 * portWORD_SIZE( sp ) + flw f28, 29 * portWORD_SIZE( sp ) + flw f29, 30 * portWORD_SIZE( sp ) + flw f30, 31 * portWORD_SIZE( sp ) + flw f31, 32 * portWORD_SIZE( sp ) +f_reg_skip_restore2: + addi sp, sp, portFLOAT_CONTEXT_SIZE +#endif + load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */ load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */ load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */ @@ -445,7 +582,12 @@ pxPortInitialiseStack: store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */ addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9. */ store_x x0, 0(a0) /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */ +#if( portasmHAS_F_EXTENSION != 0 ) + addi t0, x0, 34 /* Space for float register */ + addi t0, t0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */ +#else addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */ +#endif chip_specific_stack_frame: /* First add any chip specific registers to the stack frame being created. */ beq t0, x0, 1f /* No more chip specific registers to save. */ addi a0, a0, -portWORD_SIZE /* Make space for chip specific register. */ diff --git a/components/freertos/portable/GCC/RISC-V/portmacro.h b/components/freertos/portable/GCC/RISC-V/common/portmacro.h similarity index 100% rename from components/freertos/portable/GCC/RISC-V/portmacro.h rename to components/freertos/portable/GCC/RISC-V/common/portmacro.h diff --git a/examples/freertos/FreeRTOSConfig.h b/examples/freertos/FreeRTOSConfig.h index 6b521a6a..ed82d3e5 100644 --- a/examples/freertos/FreeRTOSConfig.h +++ b/examples/freertos/FreeRTOSConfig.h @@ -41,12 +41,17 @@ *----------------------------------------------------------*/ #include "stdio.h" -#ifdef BL702 +#if defined(BL602) || defined(BL702) || defined(BL702L) #define configMTIME_BASE_ADDRESS (0x02000000UL + 0xBFF8UL) #define configMTIMECMP_BASE_ADDRESS (0x02000000UL + 0x4000UL) #else -#define configMTIME_BASE_ADDRESS (0xE0000000UL + 0xBFF8UL) -#define configMTIMECMP_BASE_ADDRESS (0xE0000000UL + 0x4000UL) +#if __riscv_xlen == 64 +#define configMTIME_BASE_ADDRESS (0) +#define configMTIMECMP_BASE_ADDRESS ((0xE4000000UL) + 0x4000UL) +#else +#define configMTIME_BASE_ADDRESS ((0xE0000000UL) + 0xBFF8UL) +#define configMTIMECMP_BASE_ADDRESS ((0xE0000000UL) + 0x4000UL) +#endif #endif // #define configSUPPORT_STATIC_ALLOCATION 1 @@ -57,7 +62,7 @@ #define configTICK_RATE_HZ ((TickType_t)1000) #define configMAX_PRIORITIES (7) #define configMINIMAL_STACK_SIZE ((unsigned short)128) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */ -#define configTOTAL_HEAP_SIZE ((size_t)12 * 1024) +#define configTOTAL_HEAP_SIZE ((size_t)24 * 1024) #define configMAX_TASK_NAME_LEN (16) #define configUSE_TRACE_FACILITY 1 #define configUSE_STATS_FORMATTING_FUNCTIONS 1 diff --git a/examples/freertos/main.c b/examples/freertos/main.c index 8d1b4b7f..93ad0ac7 100644 --- a/examples/freertos/main.c +++ b/examples/freertos/main.c @@ -2,8 +2,7 @@ #include #include "semphr.h" #include "log.h" - -extern void board_init(void); +#include "board.h" static uint8_t freertos_heap[configTOTAL_HEAP_SIZE];