From ed36590113fb846a2c38739e7d35bf46483f149b Mon Sep 17 00:00:00 2001 From: rtel Date: Fri, 8 Mar 2019 17:03:43 +0000 Subject: [PATCH] Prepare the RISC-V port layer for addition of 64-bit port. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2644 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- FreeRTOS/Source/portable/GCC/RISC-V/portASM.S | 262 +++++++++--------- 1 file changed, 136 insertions(+), 126 deletions(-) diff --git a/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S b/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S index 825bf44f2..0adde585d 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S +++ b/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S @@ -28,8 +28,12 @@ #if __riscv_xlen == 64 #error Not implemented yet - change lw to ld, and sw to sd. #define portWORD_SIZE 8 + #define store_x sd + #define load_x ld #elif __riscv_xlen == 32 #define portWORD_SIZE 4 + #define store_x sw + #define load_x lw #else #error Assembler did not define __riscv_xlen #endif @@ -101,42 +105,42 @@ at the top of this file. */ .func freertos_risc_v_trap_handler: addi sp, sp, -portCONTEXT_SIZE - sw x1, 1 * portWORD_SIZE( sp ) - sw x5, 2 * portWORD_SIZE( sp ) - sw x6, 3 * portWORD_SIZE( sp ) - sw x7, 4 * portWORD_SIZE( sp ) - sw x8, 5 * portWORD_SIZE( sp ) - sw x9, 6 * portWORD_SIZE( sp ) - sw x10, 7 * portWORD_SIZE( sp ) - sw x11, 8 * portWORD_SIZE( sp ) - sw x12, 9 * portWORD_SIZE( sp ) - sw x13, 10 * portWORD_SIZE( sp ) - sw x14, 11 * portWORD_SIZE( sp ) - sw x15, 12 * portWORD_SIZE( sp ) - sw x16, 13 * portWORD_SIZE( sp ) - sw x17, 14 * portWORD_SIZE( sp ) - sw x18, 15 * portWORD_SIZE( sp ) - sw x19, 16 * portWORD_SIZE( sp ) - sw x20, 17 * portWORD_SIZE( sp ) - sw x21, 18 * portWORD_SIZE( sp ) - sw x22, 19 * portWORD_SIZE( sp ) - sw x23, 20 * portWORD_SIZE( sp ) - sw x24, 21 * portWORD_SIZE( sp ) - sw x25, 22 * portWORD_SIZE( sp ) - sw x26, 23 * portWORD_SIZE( sp ) - sw x27, 24 * portWORD_SIZE( sp ) - sw x28, 25 * portWORD_SIZE( sp ) - sw x29, 26 * portWORD_SIZE( sp ) - sw x30, 27 * portWORD_SIZE( sp ) - sw x31, 28 * portWORD_SIZE( sp ) + 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. */ - sw t0, 29 * portWORD_SIZE( sp ) + 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. */ - lw t0, pxCurrentTCB /* Load pxCurrentTCB. */ - sw sp, 0( t0 ) /* Write sp to first TCB member. */ + load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */ + store_x sp, 0( t0 ) /* Write sp to first TCB member. */ csrr a0, mcause csrr a1, mepc @@ -144,32 +148,38 @@ freertos_risc_v_trap_handler: test_if_asynchronous: srli a2, a0, 0x1f /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */ beq a2, x0, handle_synchronous /* Branch past interrupt handing if not asynchronous. */ - sw a1, 0( sp ) /* Asynch so save unmodified exception return address. */ + store_x a1, 0( sp ) /* Asynch so save unmodified exception return address. */ handle_asynchronous: #if( portasmHAS_CLINT != 0 ) - test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */ - lui t0, 0x80000 - addi t1, t0, 7 /* 0x80000007 == machine timer interrupt. */ - bne a0, t1, test_if_external_interrupt - - lw t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */ - lw t1, pullNextTime /* Load the address of ullNextTime into t1. */ - lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */ - lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */ - sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */ - sw t3, 4(t0) /* Store high word of ullNextTime into compare register. */ - lw t0, ulTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */ - add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits. */ - sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */ - add t6, t3, t5 /* Add overflow to high word of ullNextTime. */ - sw t4, 0(t1) /* Store new low word of ullNextTime. */ - sw t6, 4(t1) /* Store new high word of ullNextTime. */ - lw sp, xISRStackTop /* Switch to ISR stack before function call. */ + test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */ + + addi t0, x0, 1 + + #if( __riscv_xlen == 32 ) + slli t0, t0, 31 /* LSB is already set, shift into MSB. */ + addi t1, t0, 7 /* 0x80000007 == machine timer interrupt. */ + bne a0, t1, test_if_external_interrupt + + lw t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */ + lw t1, pullNextTime /* Load the address of ullNextTime into t1. */ + lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */ + lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */ + sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */ + sw t3, 4(t0) /* Store high word of ullNextTime into compare register. */ + lw t0, ulTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */ + add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits. */ + sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */ + add t6, t3, t5 /* Add overflow to high word of ullNextTime. */ + sw t4, 0(t1) /* Store new low word of ullNextTime. */ + sw t6, 4(t1) /* Store new high word of ullNextTime. */ + #endif /* __riscv_xlen == 32 */ + + load_x sp, xISRStackTop /* Switch to ISR stack before function call. */ jal xTaskIncrementTick - beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */ + beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */ jal vTaskSwitchContext j processed_source @@ -179,18 +189,18 @@ handle_asynchronous: #endif /* portasmHAS_CLINT */ - lw sp, xISRStackTop /* Switch to ISR stack before function call. */ + load_x sp, xISRStackTop /* Switch to ISR stack before function call. */ jal portasmHANDLE_INTERRUPT /* Jump to the interrupt handler if there is no CLINT or if there is a CLINT and it has been determined that an external interrupt is pending. */ j processed_source handle_synchronous: addi a1, a1, 4 /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */ - sw a1, 0( sp ) /* Save updated exception return address. */ + store_x a1, 0( sp ) /* Save updated exception return address. */ test_if_environment_call: li t0, 11 /* 11 == environment call. */ bne a0, t0, is_exception /* Not an M environment call, so some other exception. */ - lw sp, xISRStackTop /* Switch to ISR stack before function call. */ + load_x sp, xISRStackTop /* Switch to ISR stack before function call. */ jal vTaskSwitchContext j processed_source @@ -203,47 +213,47 @@ as_yet_unhandled: j as_yet_unhandled processed_source: - lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ - lw sp, 0( sp ) /* Read sp from first TCB member. */ + load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */ + load_x sp, 0( sp ) /* Read sp from first TCB member. */ /* Load mret with the address of the next instruction in the task to run next. */ - lw t0, 0( sp ) + 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. */ - lw t0, 29 * portWORD_SIZE( sp ) - csrw mstatus, t0 /* Required for MPIE bit. */ - - lw x1, 1 * portWORD_SIZE( sp ) - lw x5, 2 * portWORD_SIZE( sp ) /* t0 */ - lw x6, 3 * portWORD_SIZE( sp ) /* t1 */ - lw x7, 4 * portWORD_SIZE( sp ) /* t2 */ - lw x8, 5 * portWORD_SIZE( sp ) /* s0/fp */ - lw x9, 6 * portWORD_SIZE( sp ) /* s1 */ - lw x10, 7 * portWORD_SIZE( sp ) /* a0 */ - lw x11, 8 * portWORD_SIZE( sp ) /* a1 */ - lw x12, 9 * portWORD_SIZE( sp ) /* a2 */ - lw x13, 10 * portWORD_SIZE( sp ) /* a3 */ - lw x14, 11 * portWORD_SIZE( sp ) /* a4 */ - lw x15, 12 * portWORD_SIZE( sp ) /* a5 */ - lw x16, 13 * portWORD_SIZE( sp ) /* a6 */ - lw x17, 14 * portWORD_SIZE( sp ) /* a7 */ - lw x18, 15 * portWORD_SIZE( sp ) /* s2 */ - lw x19, 16 * portWORD_SIZE( sp ) /* s3 */ - lw x20, 17 * portWORD_SIZE( sp ) /* s4 */ - lw x21, 18 * portWORD_SIZE( sp ) /* s5 */ - lw x22, 19 * portWORD_SIZE( sp ) /* s6 */ - lw x23, 20 * portWORD_SIZE( sp ) /* s7 */ - lw x24, 21 * portWORD_SIZE( sp ) /* s8 */ - lw x25, 22 * portWORD_SIZE( sp ) /* s9 */ - lw x26, 23 * portWORD_SIZE( sp ) /* s10 */ - lw x27, 24 * portWORD_SIZE( sp ) /* s11 */ - lw x28, 25 * portWORD_SIZE( sp ) /* t3 */ - lw x29, 26 * portWORD_SIZE( sp ) /* t4 */ - lw x30, 27 * portWORD_SIZE( sp ) /* t5 */ - lw x31, 28 * portWORD_SIZE( sp ) /* t6 */ + 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 @@ -262,43 +272,43 @@ xPortStartFirstTask: csrw mtvec, t0 #endif /* portasmHAS_CLILNT */ - lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ - lw sp, 0( sp ) /* Read sp from first TCB member. */ + load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */ + load_x sp, 0( sp ) /* Read sp from first TCB member. */ - lw x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */ + load_x x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */ portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */ - lw t0, 29 * portWORD_SIZE( sp ) /* mstatus */ - csrrw x0, mstatus, t0 /* Interrupts enabled from here! */ - - lw x5, 2 * portWORD_SIZE( sp ) /* t0 */ - lw x6, 3 * portWORD_SIZE( sp ) /* t1 */ - lw x7, 4 * portWORD_SIZE( sp ) /* t2 */ - lw x8, 5 * portWORD_SIZE( sp ) /* s0/fp */ - lw x9, 6 * portWORD_SIZE( sp ) /* s1 */ - lw x10, 7 * portWORD_SIZE( sp ) /* a0 */ - lw x11, 8 * portWORD_SIZE( sp ) /* a1 */ - lw x12, 9 * portWORD_SIZE( sp ) /* a2 */ - lw x13, 10 * portWORD_SIZE( sp ) /* a3 */ - lw x14, 11 * portWORD_SIZE( sp ) /* a4 */ - lw x15, 12 * portWORD_SIZE( sp ) /* a5 */ - lw x16, 13 * portWORD_SIZE( sp ) /* a6 */ - lw x17, 14 * portWORD_SIZE( sp ) /* a7 */ - lw x18, 15 * portWORD_SIZE( sp ) /* s2 */ - lw x19, 16 * portWORD_SIZE( sp ) /* s3 */ - lw x20, 17 * portWORD_SIZE( sp ) /* s4 */ - lw x21, 18 * portWORD_SIZE( sp ) /* s5 */ - lw x22, 19 * portWORD_SIZE( sp ) /* s6 */ - lw x23, 20 * portWORD_SIZE( sp ) /* s7 */ - lw x24, 21 * portWORD_SIZE( sp ) /* s8 */ - lw x25, 22 * portWORD_SIZE( sp ) /* s9 */ - lw x26, 23 * portWORD_SIZE( sp ) /* s10 */ - lw x27, 24 * portWORD_SIZE( sp ) /* s11 */ - lw x28, 25 * portWORD_SIZE( sp ) /* t3 */ - lw x29, 26 * portWORD_SIZE( sp ) /* t4 */ - lw x30, 27 * portWORD_SIZE( sp ) /* t5 */ - lw x31, 28 * portWORD_SIZE( sp ) /* t6 */ + load_x t0, 29 * portWORD_SIZE( sp ) /* mstatus */ + csrrw x0, mstatus, t0 /* Interrupts enabled from here! */ + + 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 ret .endfunc @@ -376,21 +386,21 @@ pxPortInitialiseStack: or t0, t0, t1 /* Set MPIE and MPP bits in mstatus value. */ addi a0, a0, -portWORD_SIZE - sw t0, 0(a0) /* mstatus onto the stack. */ + store_x t0, 0(a0) /* mstatus onto the stack. */ addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x11-x31. */ - sw a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */ + 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. */ - sw x0, 0(a0) /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */ + store_x x0, 0(a0) /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */ addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */ 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. */ - sw x0, 0(a0) /* Give the chip specific register an initial value of zero. */ + store_x x0, 0(a0) /* Give the chip specific register an initial value of zero. */ addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */ j chip_specific_stack_frame /* Until no more chip specific registers. */ 1: addi a0, a0, -portWORD_SIZE - sw a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */ + store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */ ret .endfunc /*-----------------------------------------------------------*/ -- 2.39.5