mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Move the RISC-V pxPortInitialiseStack() implementation to the assembly port file from the C port file so it can have access to the number of chip specific registers it needs to save space for on the stack.
This commit is contained in:
parent
911a1de273
commit
60b133b2c6
|
@ -107,6 +107,7 @@
|
||||||
#define configUSE_APPLICATION_TASK_TAG 0
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
#define configUSE_COUNTING_SEMAPHORES 1
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
#define configGENERATE_RUN_TIME_STATS 0
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
|
||||||
/* Co-routine definitions. */
|
/* Co-routine definitions. */
|
||||||
#define configUSE_CO_ROUTINES 0
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
@ -142,7 +143,4 @@ to exclude the API function. */
|
||||||
header file. */
|
header file. */
|
||||||
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); }
|
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); }
|
||||||
|
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* FREERTOS_CONFIG_H */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
|
@ -57,6 +57,6 @@
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||||
<listEntry value="4"/>
|
<listEntry value="4"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"> <memoryBlockExpression address="2147525816" label="0x8000a4b8"/> </memoryBlockExpressionList> "/>
|
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"> <memoryBlockExpression address="2147504144" label="0x80005010"/> </memoryBlockExpressionList> "/>
|
||||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
* base set of RISC-V registers. There are additional
|
* base set of RISC-V registers. There are additional
|
||||||
* freertos_risc_v_port_specific_extensions.h files for RISC-V implementations
|
* freertos_risc_v_port_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
|
* that do not include a standard CLINT or do add to the base set of RISC-V
|
||||||
* regiters.
|
* registers.
|
||||||
*
|
*
|
||||||
* CARE MUST BE TAKEN TO INCLDUE THE CORRECT
|
* CARE MUST BE TAKEN TO INCLDUE THE CORRECT
|
||||||
* freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP
|
* freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP
|
||||||
|
@ -62,5 +62,15 @@
|
||||||
#define __FREERTOS_RISC_V_EXTENSIONS_H__
|
#define __FREERTOS_RISC_V_EXTENSIONS_H__
|
||||||
|
|
||||||
#define portasmHAS_CLINT 1
|
#define portasmHAS_CLINT 1
|
||||||
|
#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */
|
||||||
|
|
||||||
|
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
||||||
|
/* No additional registers to save, so this macro does nothing. */
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/* Restore the additional registers found on the Pulpino. */
|
||||||
|
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
||||||
|
/* No additional registers to restore, so this macro does nothing. */
|
||||||
|
.endm
|
||||||
|
|
||||||
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
* base set of RISC-V registers. There are additional
|
* base set of RISC-V registers. There are additional
|
||||||
* freertos_risc_v_port_specific_extensions.h files for RISC-V implementations
|
* freertos_risc_v_port_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
|
* that do not include a standard CLINT or do add to the base set of RISC-V
|
||||||
* regiters.
|
* registers.
|
||||||
*
|
*
|
||||||
* CARE MUST BE TAKEN TO INCLDUE THE CORRECT
|
* CARE MUST BE TAKEN TO INCLDUE THE CORRECT
|
||||||
* freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP
|
* freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP
|
||||||
|
@ -62,12 +62,49 @@
|
||||||
|
|
||||||
#define portasmHAS_CLINT 0
|
#define portasmHAS_CLINT 0
|
||||||
|
|
||||||
|
/* Constants to define the additional registers found on the Pulpino RI5KY. */
|
||||||
|
#define lpstart0 0x7b0
|
||||||
|
#define lpend0 0x7b1
|
||||||
|
#define lpcount0 0x7b2
|
||||||
|
#define lpstart1 0x7b4
|
||||||
|
#define lpend1 0x7b5
|
||||||
|
#define lpcount1 0x7b6
|
||||||
|
|
||||||
|
/* Six additional registers to save and restore, as per the #defines above. */
|
||||||
|
#define portasmADDITIONAL_CONTEXT_SIZE 6 /* Must be even number on 32-bit cores. */
|
||||||
|
|
||||||
|
/* Save additional registers found on the Pulpino. */
|
||||||
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
||||||
|
addi sp, sp, -portasmADDITIONAL_CONTEXT_SIZE /* Make room for the additional registers. */
|
||||||
|
csrr t0, lpstart0 /* Load additional registers into accessable temporary registers. */
|
||||||
|
csrr t1, lpend0
|
||||||
|
csrr t2, lpcount0
|
||||||
|
csrr t3, lpstart1
|
||||||
|
csrr t4, lpend1
|
||||||
|
csrr t5, lpcount1
|
||||||
|
sw t0, 1 * portWORD_SIZE( sp )
|
||||||
|
sw t1, 2 * portWORD_SIZE( sp )
|
||||||
|
sw t2, 3 * portWORD_SIZE( sp )
|
||||||
|
sw t3, 4 * portWORD_SIZE( sp )
|
||||||
|
sw t4, 5 * portWORD_SIZE( sp )
|
||||||
|
sw t5, 6 * portWORD_SIZE( sp )
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
/* Restore the additional registers found on the Pulpino. */
|
||||||
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
||||||
/* This file is for use with chips that do not add to the standard RISC-V
|
lw t0, 1 * portWORD_SIZE( sp ) /* Load additional registers into accessable temporary registers. */
|
||||||
* register set, so there is nothing to do here. */
|
lw t1, 2 * portWORD_SIZE( sp )
|
||||||
|
lw t2, 3 * portWORD_SIZE( sp )
|
||||||
|
lw t3, 4 * portWORD_SIZE( sp )
|
||||||
|
lw t4, 5 * portWORD_SIZE( sp )
|
||||||
|
lw t5, 6 * portWORD_SIZE( sp )
|
||||||
|
csrw lpstart0, t0
|
||||||
|
csrw lpend0, t1
|
||||||
|
csrw lpcount0, t2
|
||||||
|
csrw lpstart1, t3
|
||||||
|
csrw lpend1, t4
|
||||||
|
csrw lpcount1, t5
|
||||||
|
addi sp, sp, -portasmADDITIONAL_CONTEXT_SIZE /* Remove space added for additional registers. */
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
||||||
|
|
|
@ -34,13 +34,28 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "portmacro.h"
|
#include "portmacro.h"
|
||||||
|
|
||||||
#ifdef configISR_STACK_SIZE
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
/* The stack used by interrupt service routines. */
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
static __attribute__ ((aligned(16))) StackType_t xISRStack[ configISR_STACK_SIZE ] = { 0 };
|
debugger. */
|
||||||
const StackType_t * const xISRStackTop = &( xISRStack[ ( configISR_STACK_SIZE & ~portBYTE_ALIGNMENT_MASK ) - 1 ] );
|
#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 ) - 1 ] );
|
||||||
#else
|
#else
|
||||||
extern const uint32_t __freertos_irq_stack_top[];
|
extern const uint32_t __freertos_irq_stack_top[];
|
||||||
const uint32_t xISRStackTop = ( uint32_t ) __freertos_irq_stack_top;
|
const StackType_t xISRStackTop = ( StackType_t ) __freertos_irq_stack_top;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -89,10 +104,10 @@ task stack, not the ISR stack). */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulx = 0;
|
volatile uint32_t ulx = 0;
|
||||||
|
#warning Not currently used
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
|
@ -105,107 +120,6 @@ volatile uint32_t ulx = 0;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
|
||||||
* See header file for description.
|
|
||||||
*/
|
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
|
||||||
{
|
|
||||||
uint32_t mstatus;
|
|
||||||
const uint32_t ulMPIE_Bit = 0x80, ulMPP_Bits = 0x1800;
|
|
||||||
/*
|
|
||||||
X1 to X31 integer registers for the 'I' profile, X1 to X15 for the 'E' profile.
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Start task with interrupt enabled. */
|
|
||||||
__asm volatile ("csrr %0, mstatus" : "=r"(mstatus));
|
|
||||||
mstatus |= ulMPIE_Bit | ulMPP_Bits;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = mstatus;
|
|
||||||
|
|
||||||
/* Numbers correspond to the x register number. */
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 31;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 30;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 29;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 28;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 27;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 26;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 25;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 24;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 23;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 22;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 21;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 20;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 19;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 18;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 17;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 16;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 15;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 14;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 13;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 12;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 11;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 9;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 8;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 7;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 6;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) 5;
|
|
||||||
pxTopOfStack--;
|
|
||||||
// *pxTopOfStack = ( StackType_t ) 4; /* Thread pointer. */
|
|
||||||
// pxTopOfStack--;
|
|
||||||
// *pxTopOfStack = ( StackType_t ) 3; /* Global pointer. */
|
|
||||||
// pxTopOfStack--;
|
|
||||||
// *pxTopOfStack = ( StackType_t ) 2; /* Stack pointer. */
|
|
||||||
// pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) prvTaskExitError;
|
|
||||||
pxTopOfStack--;
|
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode;
|
|
||||||
|
|
||||||
return pxTopOfStack;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if( configCLINT_BASE_ADDRESS != 0 )
|
#if( configCLINT_BASE_ADDRESS != 0 )
|
||||||
|
|
||||||
void vPortSetupTimerInterrupt( void )
|
void vPortSetupTimerInterrupt( void )
|
||||||
|
|
|
@ -25,6 +25,15 @@
|
||||||
* 1 tab == 4 spaces!
|
* 1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
#error Not implemented yet - change lw to ld, and sw to sd.
|
||||||
|
#define portWORD_SIZE 8
|
||||||
|
#elif __riscv_xlen == 32
|
||||||
|
#define portWORD_SIZE 4
|
||||||
|
#else
|
||||||
|
#error Assembler did not define __riscv_xlen
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The FreeRTOS kernel's RISC-V port is split between the the code that is
|
* 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
|
* common across all currently supported RISC-V chips (implementations of the
|
||||||
|
@ -42,7 +51,7 @@
|
||||||
* base set of RISC-V registers. There are additional
|
* base set of RISC-V registers. There are additional
|
||||||
* freertos_risc_v_port_specific_extensions.h files for RISC-V implementations
|
* freertos_risc_v_port_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
|
* that do not include a standard CLINT or do add to the base set of RISC-V
|
||||||
* regiters.
|
* registers.
|
||||||
*
|
*
|
||||||
* CARE MUST BE TAKEN TO INCLDUE THE CORRECT
|
* CARE MUST BE TAKEN TO INCLDUE THE CORRECT
|
||||||
* freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP
|
* freertos_risc_v_port_specific_extensions.h HEADER FILE FOR THE CHIP
|
||||||
|
@ -67,27 +76,6 @@ definitions. */
|
||||||
#error portasmHANDLE_INTERRUPT must be defined to the function to be called to handle external/peripheral interrupts. portasmHANDLE_INTERRUPT can be defined on the assmbler command line or in the appropriate freertos_risc_v_port_specific_extensions.h header file.
|
#error portasmHANDLE_INTERRUPT must be defined to the function to be called to handle external/peripheral interrupts. portasmHANDLE_INTERRUPT can be defined on the assmbler command line or in the appropriate freertos_risc_v_port_specific_extensions.h header file.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portasmSAVE_ADDITIONAL_REGISTERS
|
|
||||||
/* portasmSAVE_ADDITIONAL_REGISTERS is not defined so assume no additional
|
|
||||||
registers need to be saved. */
|
|
||||||
#define portasmSAVE_ADDITIONAL_REGISTERS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef portasmRESTORE_ADDITIONAL_REGISTERS
|
|
||||||
/* portasmRESTORE_ADDITIONAL_REGISTERS is not defined so assume no
|
|
||||||
additional registers need to be restored. */
|
|
||||||
#define portasmRESTORE_ADDITIONAL_REGISTERS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __riscv_xlen == 64
|
|
||||||
#error Not implemented yet - change lw to ld, and sw to sd.
|
|
||||||
#define portWORD_SIZE 8
|
|
||||||
#elif __riscv_xlen == 32
|
|
||||||
#define portWORD_SIZE 4
|
|
||||||
#else
|
|
||||||
#error Assembler did not define __riscv_xlen
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Only the standard core registers are stored by default. Any additional
|
/* Only the standard core registers are stored by default. Any additional
|
||||||
registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and
|
registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and
|
||||||
portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
|
portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
|
||||||
|
@ -97,6 +85,7 @@ at the top of this file. */
|
||||||
|
|
||||||
.global xPortStartFirstTask
|
.global xPortStartFirstTask
|
||||||
.global vFreeRTOSPortTrapHandler
|
.global vFreeRTOSPortTrapHandler
|
||||||
|
.global pxPortInitialiseStack
|
||||||
.extern pxCurrentTCB
|
.extern pxCurrentTCB
|
||||||
.extern ulPortTrapHandler
|
.extern ulPortTrapHandler
|
||||||
.extern vTaskSwitchContext
|
.extern vTaskSwitchContext
|
||||||
|
@ -105,11 +94,11 @@ at the top of this file. */
|
||||||
.extern pullNextTime
|
.extern pullNextTime
|
||||||
.extern ulTimerIncrementsForOneTick
|
.extern ulTimerIncrementsForOneTick
|
||||||
.extern xISRStackTop
|
.extern xISRStackTop
|
||||||
.extern vPortHandleInterrupt
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
.align 16
|
.align 8
|
||||||
|
.func
|
||||||
vFreeRTOSPortTrapHandler:
|
vFreeRTOSPortTrapHandler:
|
||||||
addi sp, sp, -portCONTEXT_SIZE
|
addi sp, sp, -portCONTEXT_SIZE
|
||||||
sw x1, 1 * portWORD_SIZE( sp )
|
sw x1, 1 * portWORD_SIZE( sp )
|
||||||
|
@ -141,11 +130,11 @@ vFreeRTOSPortTrapHandler:
|
||||||
sw x30, 27 * portWORD_SIZE( sp )
|
sw x30, 27 * portWORD_SIZE( sp )
|
||||||
sw x31, 28 * portWORD_SIZE( sp )
|
sw x31, 28 * portWORD_SIZE( sp )
|
||||||
|
|
||||||
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_port_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
|
||||||
|
|
||||||
csrr t0, mstatus /* Required for MPIE bit. */
|
csrr t0, mstatus /* Required for MPIE bit. */
|
||||||
sw t0, 29 * portWORD_SIZE( sp )
|
sw t0, 29 * portWORD_SIZE( sp )
|
||||||
|
|
||||||
|
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_port_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||||
|
|
||||||
lw t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
lw t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||||
sw sp, 0( t0 ) /* Write sp to first TCB member. */
|
sw sp, 0( t0 ) /* Write sp to first TCB member. */
|
||||||
|
|
||||||
|
@ -217,16 +206,16 @@ processed_source:
|
||||||
lw sp, pxCurrentTCB /* Load pxCurrentTCB. */
|
lw sp, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||||
lw sp, 0( sp ) /* Read sp from first TCB member. */
|
lw sp, 0( sp ) /* Read sp from first TCB member. */
|
||||||
|
|
||||||
/* Load mret with the address of the next task. */
|
/* Load mret with the address of the next instruction in the task to run next. */
|
||||||
lw t0, 0( sp )
|
lw t0, 0( sp )
|
||||||
csrw mepc, t0
|
csrw mepc, t0
|
||||||
|
|
||||||
|
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_port_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 mstatus with the interrupt enable bits used by the task. */
|
||||||
lw t0, 29 * portWORD_SIZE( sp )
|
lw t0, 29 * portWORD_SIZE( sp )
|
||||||
csrw mstatus, t0 /* Required for MPIE bit. */
|
csrw mstatus, t0 /* Required for MPIE bit. */
|
||||||
|
|
||||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_port_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
|
||||||
|
|
||||||
lw x1, 1 * portWORD_SIZE( sp )
|
lw x1, 1 * portWORD_SIZE( sp )
|
||||||
lw x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
lw x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
||||||
lw x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
lw x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
||||||
|
@ -258,9 +247,11 @@ processed_source:
|
||||||
addi sp, sp, portCONTEXT_SIZE
|
addi sp, sp, portCONTEXT_SIZE
|
||||||
|
|
||||||
mret
|
mret
|
||||||
|
.endfunc
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
.align 16
|
.align 8
|
||||||
|
.func
|
||||||
xPortStartFirstTask:
|
xPortStartFirstTask:
|
||||||
|
|
||||||
#if( portasmHAS_CLINT != 0 )
|
#if( portasmHAS_CLINT != 0 )
|
||||||
|
@ -275,6 +266,12 @@ xPortStartFirstTask:
|
||||||
lw sp, 0( sp ) /* Read sp from first TCB member. */
|
lw 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. */
|
lw 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_port_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 x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
||||||
lw x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
lw x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
||||||
lw x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
lw x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
||||||
|
@ -303,8 +300,98 @@ xPortStartFirstTask:
|
||||||
lw x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
lw x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
||||||
lw x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
lw x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
||||||
addi sp, sp, portCONTEXT_SIZE
|
addi sp, sp, portCONTEXT_SIZE
|
||||||
csrs mstatus, 8 /* Enable machine interrupts. */
|
|
||||||
ret
|
ret
|
||||||
|
.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
|
||||||
|
* pxCode
|
||||||
|
*/
|
||||||
|
.align 8
|
||||||
|
.func
|
||||||
|
pxPortInitialiseStack:
|
||||||
|
|
||||||
|
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, standard_stack_frame /* 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. */
|
||||||
|
addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */
|
||||||
|
j chip_specific_stack_frame /* Until no more chip specific registers. */
|
||||||
|
|
||||||
|
standard_stack_frame: /* Now create the stack frame for the standard registers. */
|
||||||
|
csrr t0, mstatus /* Obtain current mstatus value. */
|
||||||
|
addi t1, x0, 0x188 /* Generate the value 0x1880, which are the MPIE and MPP bits to set in mstatus. */
|
||||||
|
slli t1, t1, 4
|
||||||
|
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. */
|
||||||
|
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. */
|
||||||
|
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 */
|
||||||
|
addi a0, a0, -portWORD_SIZE
|
||||||
|
sw a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */
|
||||||
|
ret
|
||||||
|
.endfunc
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in a new issue