--- /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 t\r
+\r
+ o 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
+ * The FreeRTOS kernel's RISC-V port is split between the the code that is\r
+ * common across all currently supported RISC-V chips (implementations of the\r
+ * RISC-V ISA), and code which tailors the port to a specific RISC-V chip:\r
+ *\r
+ * + The code that is common to all RISC-V chips is implemented in\r
+ * FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S. There is only one\r
+ * portASM.S file because the same file is used no matter which RISC-V chip is\r
+ * in use.\r
+ *\r
+ * + The code that tailors the kernel's RISC-V port to a specific RISC-V\r
+ * chip is implemented in freertos_risc_v_port_specific_extensions.h. There\r
+ * is one freertos_risc_v_port_specific_extensions.h that can be used with any\r
+ * RISC-V chip that both includes a standard CLINT and does not add to the\r
+ * base set of RISC-V registers. There are additional\r
+ * freertos_risc_v_port_specific_extensions.h files for RISC-V implementations\r
+ * that do not include a standard CLINT or do add to the base set of RISC-V\r
+ * regiters.\r
+ *\r
+ * CARE MUST BE TAKEN TO INCLDUE THE CORRECT\r
+ * freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP\r
+ * IN USE. To include the correct freertos_risc_v_port_specific_extensions.h\r
+ * header file ensure the path to the correct header file is in the assembler's\r
+ * include path.\r
+ *\r
+ * This freertos_risc_v_port_specific_extensions.h is for use on RISC-V chips\r
+ * that include a standard CLINT and do not add to the base set of RISC-V\r
+ * registers.\r
+ *\r
+ */\r
+\r
+#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__\r
+#define __FREERTOS_RISC_V_EXTENSIONS_H__\r
+\r
+.macro portSAVE_ADDITIONAL_REGISTERS\r
+ /* This file is for use with chips that do not add to the standard RISC-V\r
+ * register set, so there is nothing to do here. */\r
+ .endm\r
+\r
+.macro portRESTORE_ADDITIONAL_REGISTERS\r
+ /* This file is for use with chips that do not add to the standard RISC-V\r
+ * register set, so there is nothing to do here. */\r
+ .endm\r
+\r
+#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */\r
* 1 tab == 4 spaces!\r
*/\r
\r
+/*\r
+ * The FreeRTOS kernel's RISC-V port is split between the the code that is\r
+ * common across all currently supported RISC-V chips (implementations of the\r
+ * RISC-V ISA), and code which tailors the port to a specific RISC-V chip:\r
+ *\r
+ * + The code that is common to all RISC-V chips is implemented in\r
+ * FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S. There is only one\r
+ * portASM.S file because the same file is used no matter which RISC-V chip is\r
+ * in use.\r
+ *\r
+ * + The code that tailors the kernel's RISC-V port to a specific RISC-V\r
+ * chip is implemented in freertos_risc_v_port_specific_extensions.h. There\r
+ * is one freertos_risc_v_port_specific_extensions.h that can be used with any\r
+ * RISC-V chip that both includes a standard CLINT and does not add to the\r
+ * base set of RISC-V registers. There are additional\r
+ * freertos_risc_v_port_specific_extensions.h files for RISC-V implementations\r
+ * that do not include a standard CLINT or do add to the base set of RISC-V\r
+ * regiters.\r
+ *\r
+ * CARE MUST BE TAKEN TO INCLDUE THE CORRECT\r
+ * freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP\r
+ * IN USE. To include the correct freertos_risc_v_port_specific_extensions.h\r
+ * header file ensure the path to the correct header file is in the assembler's\r
+ * include path.\r
+ *\r
+ * This freertos_risc_v_port_specific_extensions.h is for use on RISC-V chips\r
+ * that include a standard CLINT and do not add to the base set of RISC-V\r
+ * registers.\r
+ *\r
+ */\r
+#include "freertos_risc_v_port_specific_extensions.h"\r
+\r
#if __riscv_xlen == 64\r
#error Not implemented yet - change lw to ld, and sw to sd.\r
#define WORD_SIZE 8\r
sw x30, 27 * WORD_SIZE( sp )\r
sw x31, 28 * WORD_SIZE( sp )\r
\r
+ portSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_port_specific_extensions.h to save any registers unique to the RISC-V implementation. */\r
+\r
csrr t0, mstatus /* Required for MPIE bit. */\r
sw t0, 29 * WORD_SIZE( sp )\r
\r
csrr a0, mcause\r
csrr a1, mepc\r
\r
-test_if_environment_call:\r
- li t0, 11 /* 11 == environment call when using qemu. */\r
- bne a0, t0, test_if_timer\r
- addi a1, a1, 4 /* Synchronous so return to the instruction after the environment call. */\r
- sw a1, 0( sp ) /* Save updated exception return address. */\r
- lw sp, xISRStackTop /* Switch to ISR stack before function call. */\r
- jal vTaskSwitchContext\r
- j processed_source\r
-\r
-\r
-test_if_timer:\r
- sw a1, 0( sp ) /* Asynch so save unmodified exception return address. */\r
+test_if_asynchronous:\r
+ srli a2, a0, 0x1f /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */\r
+ beq a2, x0, handle_synchronous /* Branch past interrupt handing if not asynchronous. */\r
+ sw a1, 0( sp ) /* Asynch so save unmodified exception return address. */\r
\r
+handle_asynchronous:\r
+test_if_mtimer:\r
lui t0, 0x80000\r
- addi t1,t0, 7 /* 0x80000007 == machine timer interrupt. */\r
+ addi t1, t0, 7 /* 0x80000007 == machine timer interrupt. */\r
bne a0, t1, test_if_external_interrupt\r
\r
- lw t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */\r
- lw t1, pullNextTime /* Load the address of ullNextTime into t1. */\r
+ lw t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */\r
+ lw t1, pullNextTime /* Load the address of ullNextTime into t1. */\r
lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */\r
lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */\r
sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */\r
j processed_source\r
\r
test_if_external_interrupt:\r
- addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */\r
- bne a0, t1, is_exception /* Only thing left it can be. */\r
+ addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */\r
+ bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */\r
jal vPortHandleInterrupt\r
j processed_source\r
\r
+handle_synchronous:\r
+ addi a1, a1, 4 /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */\r
+ sw a1, 0( sp ) /* Save updated exception return address. */\r
+\r
+test_if_environment_call:\r
+ li t0, 11 /* 11 == environment call. */\r
+ bne a0, t0, is_exception /* Not an M environment call, so some other exception. */\r
+ lw sp, xISRStackTop /* Switch to ISR stack before function call. */\r
+ jal vTaskSwitchContext\r
+ j processed_source\r
+\r
is_exception:\r
ebreak\r
j is_exception\r
\r
+as_yet_unhandled:\r
+ ebreak\r
+ j as_yet_unhandled\r
+\r
processed_source:\r
lw sp, pxCurrentTCB /* Load pxCurrentTCB. */\r
lw sp, 0( sp ) /* Read sp from first TCB member. */\r
lw t0, 29 * WORD_SIZE( sp )\r
csrw mstatus, t0 /* Required for MPIE bit. */\r
\r
+ portRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_port_specific_extensions.h to restore any registers unique to the RISC-V implementation. */\r
+\r
lw x1, 1 * WORD_SIZE( sp )\r
- lw x5, 2 * WORD_SIZE( sp ) /* t0 */\r
- lw x6, 3 * WORD_SIZE( sp ) /* t1 */\r
- lw x7, 4 * WORD_SIZE( sp ) /* t2 */\r
- lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */\r
- lw x9, 6 * WORD_SIZE( sp ) /* s1 */\r
+ lw x5, 2 * WORD_SIZE( sp ) /* t0 */\r
+ lw x6, 3 * WORD_SIZE( sp ) /* t1 */\r
+ lw x7, 4 * WORD_SIZE( sp ) /* t2 */\r
+ lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */\r
+ lw x9, 6 * WORD_SIZE( sp ) /* s1 */\r
lw x10, 7 * WORD_SIZE( sp ) /* a0 */\r
lw x11, 8 * WORD_SIZE( sp ) /* a1 */\r
lw x12, 9 * WORD_SIZE( sp ) /* a2 */\r
- lw x13, 10 * WORD_SIZE( sp ) /* a3 */\r
- lw x14, 11 * WORD_SIZE( sp ) /* a4 */\r
- lw x15, 12 * WORD_SIZE( sp ) /* a5 */\r
- lw x16, 13 * WORD_SIZE( sp ) /* a6 */\r
- lw x17, 14 * WORD_SIZE( sp ) /* a7 */\r
- lw x18, 15 * WORD_SIZE( sp ) /* s2 */\r
- lw x19, 16 * WORD_SIZE( sp ) /* s3 */\r
- lw x20, 17 * WORD_SIZE( sp ) /* s4 */\r
- lw x21, 18 * WORD_SIZE( sp ) /* s5 */\r
- lw x22, 19 * WORD_SIZE( sp ) /* s6 */\r
- lw x23, 20 * WORD_SIZE( sp ) /* s7 */\r
- lw x24, 21 * WORD_SIZE( sp ) /* s8 */\r
- lw x25, 22 * WORD_SIZE( sp ) /* s9 */\r
- lw x26, 23 * WORD_SIZE( sp ) /* s10 */\r
- lw x27, 24 * WORD_SIZE( sp ) /* s11 */\r
- lw x28, 25 * WORD_SIZE( sp ) /* t3 */\r
- lw x29, 26 * WORD_SIZE( sp ) /* t4 */\r
- lw x30, 27 * WORD_SIZE( sp ) /* t5 */\r
- lw x31, 28 * WORD_SIZE( sp ) /* t6 */\r
+ lw x13, 10 * WORD_SIZE( sp ) /* a3 */\r
+ lw x14, 11 * WORD_SIZE( sp ) /* a4 */\r
+ lw x15, 12 * WORD_SIZE( sp ) /* a5 */\r
+ lw x16, 13 * WORD_SIZE( sp ) /* a6 */\r
+ lw x17, 14 * WORD_SIZE( sp ) /* a7 */\r
+ lw x18, 15 * WORD_SIZE( sp ) /* s2 */\r
+ lw x19, 16 * WORD_SIZE( sp ) /* s3 */\r
+ lw x20, 17 * WORD_SIZE( sp ) /* s4 */\r
+ lw x21, 18 * WORD_SIZE( sp ) /* s5 */\r
+ lw x22, 19 * WORD_SIZE( sp ) /* s6 */\r
+ lw x23, 20 * WORD_SIZE( sp ) /* s7 */\r
+ lw x24, 21 * WORD_SIZE( sp ) /* s8 */\r
+ lw x25, 22 * WORD_SIZE( sp ) /* s9 */\r
+ lw x26, 23 * WORD_SIZE( sp ) /* s10 */\r
+ lw x27, 24 * WORD_SIZE( sp ) /* s11 */\r
+ lw x28, 25 * WORD_SIZE( sp ) /* t3 */\r
+ lw x29, 26 * WORD_SIZE( sp ) /* t4 */\r
+ lw x30, 27 * WORD_SIZE( sp ) /* t5 */\r
+ lw x31, 28 * WORD_SIZE( sp ) /* t6 */\r
addi sp, sp, CONTEXT_SIZE\r
\r
mret\r
lw sp, 0( sp ) /* Read sp from first TCB member. */\r
\r
lw x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */\r
- lw x5, 2 * WORD_SIZE( sp ) /* t0 */\r
- lw x6, 3 * WORD_SIZE( sp ) /* t1 */\r
- lw x7, 4 * WORD_SIZE( sp ) /* t2 */\r
- lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */\r
- lw x9, 6 * WORD_SIZE( sp ) /* s1 */\r
+ lw x5, 2 * WORD_SIZE( sp ) /* t0 */\r
+ lw x6, 3 * WORD_SIZE( sp ) /* t1 */\r
+ lw x7, 4 * WORD_SIZE( sp ) /* t2 */\r
+ lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */\r
+ lw x9, 6 * WORD_SIZE( sp ) /* s1 */\r
lw x10, 7 * WORD_SIZE( sp ) /* a0 */\r
lw x11, 8 * WORD_SIZE( sp ) /* a1 */\r
lw x12, 9 * WORD_SIZE( sp ) /* a2 */\r
- lw x13, 10 * WORD_SIZE( sp ) /* a3 */\r
- lw x14, 11 * WORD_SIZE( sp ) /* a4 */\r
- lw x15, 12 * WORD_SIZE( sp ) /* a5 */\r
- lw x16, 13 * WORD_SIZE( sp ) /* a6 */\r
- lw x17, 14 * WORD_SIZE( sp ) /* a7 */\r
- lw x18, 15 * WORD_SIZE( sp ) /* s2 */\r
- lw x19, 16 * WORD_SIZE( sp ) /* s3 */\r
- lw x20, 17 * WORD_SIZE( sp ) /* s4 */\r
- lw x21, 18 * WORD_SIZE( sp ) /* s5 */\r
- lw x22, 19 * WORD_SIZE( sp ) /* s6 */\r
- lw x23, 20 * WORD_SIZE( sp ) /* s7 */\r
- lw x24, 21 * WORD_SIZE( sp ) /* s8 */\r
- lw x25, 22 * WORD_SIZE( sp ) /* s9 */\r
- lw x26, 23 * WORD_SIZE( sp ) /* s10 */\r
- lw x27, 24 * WORD_SIZE( sp ) /* s11 */\r
- lw x28, 25 * WORD_SIZE( sp ) /* t3 */\r
- lw x29, 26 * WORD_SIZE( sp ) /* t4 */\r
- lw x30, 27 * WORD_SIZE( sp ) /* t5 */\r
- lw x31, 28 * WORD_SIZE( sp ) /* t6 */\r
+ lw x13, 10 * WORD_SIZE( sp ) /* a3 */\r
+ lw x14, 11 * WORD_SIZE( sp ) /* a4 */\r
+ lw x15, 12 * WORD_SIZE( sp ) /* a5 */\r
+ lw x16, 13 * WORD_SIZE( sp ) /* a6 */\r
+ lw x17, 14 * WORD_SIZE( sp ) /* a7 */\r
+ lw x18, 15 * WORD_SIZE( sp ) /* s2 */\r
+ lw x19, 16 * WORD_SIZE( sp ) /* s3 */\r
+ lw x20, 17 * WORD_SIZE( sp ) /* s4 */\r
+ lw x21, 18 * WORD_SIZE( sp ) /* s5 */\r
+ lw x22, 19 * WORD_SIZE( sp ) /* s6 */\r
+ lw x23, 20 * WORD_SIZE( sp ) /* s7 */\r
+ lw x24, 21 * WORD_SIZE( sp ) /* s8 */\r
+ lw x25, 22 * WORD_SIZE( sp ) /* s9 */\r
+ lw x26, 23 * WORD_SIZE( sp ) /* s10 */\r
+ lw x27, 24 * WORD_SIZE( sp ) /* s11 */\r
+ lw x28, 25 * WORD_SIZE( sp ) /* t3 */\r
+ lw x29, 26 * WORD_SIZE( sp ) /* t4 */\r
+ lw x30, 27 * WORD_SIZE( sp ) /* t5 */\r
+ lw x31, 28 * WORD_SIZE( sp ) /* t6 */\r
addi sp, sp, CONTEXT_SIZE\r
- csrs mstatus, 8 /* Enable machine interrupts. */\r
+ csrs mstatus, 8 /* Enable machine interrupts. */\r
ret\r
\r
/*-----------------------------------------------------------*/\r