mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-12 00:57:44 -04:00
merge #1 :: enable MMU and supervisor mode switch support
* Supervisor mode related code. * Update to fix type mismatch in debugging code. * Smode switch worked with command loop. * Wip, turn off debugging and not used code. * Delte debugging code and add compile flag for priviledge related functions. * delete debugging code * use smode scratch register for ecall index * delete unused code. * The first code worked with mmu and smode. * The code updates such that mmu and s-mode switching working. * Use compile flag to enable/disable MMU. Code clean up.
This commit is contained in:
parent
021e86659d
commit
37f2fa5db7
4 changed files with 184 additions and 9 deletions
|
@ -166,7 +166,11 @@ void vPortSetupTimerInterrupt(void)
|
|||
BaseType_t xPortStartScheduler(void)
|
||||
{
|
||||
extern void xPortStartFirstTask(void);
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE == 1 )
|
||||
{
|
||||
vRaisePriviledge();
|
||||
}
|
||||
#endif
|
||||
#if (configASSERT_DEFINED == 1)
|
||||
{
|
||||
volatile uint32_t mtvec = 0;
|
||||
|
|
|
@ -100,9 +100,16 @@ 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 )
|
||||
|
||||
#ifdef DISABLE_PRIVILEDGE_MODE
|
||||
#define USE_PRIVILEDGE_MODE 0
|
||||
#else
|
||||
#define USE_PRIVILEDGE_MODE 1
|
||||
#endif
|
||||
|
||||
.global xPortStartFirstTask
|
||||
.global freertos_risc_v_trap_handler
|
||||
.global pxPortInitialiseStack
|
||||
|
||||
.extern pxCurrentTCB
|
||||
.extern ulPortTrapHandler
|
||||
.extern vTaskSwitchContext
|
||||
|
@ -114,11 +121,103 @@ at the top of this file. */
|
|||
.extern xISRStackTop
|
||||
.extern portasmHANDLE_INTERRUPT
|
||||
|
||||
#if 0
|
||||
.extern int_record //the variable used for debugging utility
|
||||
#endif
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE != 0 )
|
||||
.extern priviledge_status
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 8
|
||||
.func
|
||||
freertos_risc_v_trap_handler:
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE != 0 )
|
||||
//csrw mscratch, t0
|
||||
csrr t0, mcause
|
||||
blt t0, x0, handle_other_traps
|
||||
|
||||
addi t0, t0, -8
|
||||
blt t0, x0, is_exception /* mcause < 8, not ecall */
|
||||
addi t0, t0, -3
|
||||
bgt t0, x0, is_exception
|
||||
|
||||
environment_switch:
|
||||
csrr t5, sscratch
|
||||
csrw mscratch, t5
|
||||
csrwi sscratch, 1
|
||||
beq t5, x0, handle_other_traps
|
||||
la t0, 1f
|
||||
slli t5, t5, 2
|
||||
add t0, t0, t5
|
||||
jr t0
|
||||
1:
|
||||
jal x0, ecall_yield
|
||||
jal x0, ecall_disable_interrupt
|
||||
jal x0, ecall_enable_interrupt
|
||||
jal x0, ecall_switch_to_machine
|
||||
jal x0, ecall_switch_to_supervisor
|
||||
|
||||
ecall_disable_interrupt:
|
||||
/* Clear mpie */
|
||||
li t6, 0x880
|
||||
csrc mie, t6
|
||||
j ecall_mret
|
||||
|
||||
ecall_enable_interrupt:
|
||||
/* Set mpie */
|
||||
li t6, 0x880
|
||||
csrs mie, t6
|
||||
j ecall_mret
|
||||
|
||||
ecall_switch_to_machine:
|
||||
/* Set mpp */
|
||||
li t6, 0x1800
|
||||
csrs mstatus, t6
|
||||
j ecall_mret
|
||||
|
||||
ecall_switch_to_supervisor:
|
||||
/* Clear mpp */
|
||||
li t6, 0x1800
|
||||
csrc mstatus, t6
|
||||
li t6, 0x800
|
||||
csrs mstatus, t6
|
||||
j ecall_mret
|
||||
|
||||
ecall_mret:
|
||||
csrr t0, mstatus
|
||||
li t6, 0x1800
|
||||
and t0, t0, t6
|
||||
srli t0, t0, 11
|
||||
|
||||
//for debug
|
||||
#if 0
|
||||
csrr t1, mie
|
||||
la t6, int_record
|
||||
sw t1, 0(t6)
|
||||
add t0, t0, t1
|
||||
slli t0, t0, 4
|
||||
csrr t1, mscratch
|
||||
add t0, t0, t1
|
||||
#endif
|
||||
|
||||
la t6, priviledge_status
|
||||
sw t0, 0(t6)
|
||||
|
||||
csrr t0, mepc
|
||||
addi t0, t0, 4
|
||||
csrw mepc, t0
|
||||
/* restore t0 */
|
||||
//csrr t0, mscratch
|
||||
mret
|
||||
|
||||
ecall_yield:
|
||||
|
||||
handle_other_traps:
|
||||
#endif
|
||||
|
||||
addi sp, sp, -portCONTEXT_SIZE
|
||||
store_x x1, 1 * portWORD_SIZE( sp )
|
||||
store_x x5, 2 * portWORD_SIZE( sp )
|
||||
|
@ -149,8 +248,10 @@ freertos_risc_v_trap_handler:
|
|||
store_x x30, 27 * portWORD_SIZE( sp )
|
||||
store_x x31, 28 * portWORD_SIZE( sp )
|
||||
|
||||
#if ( USE_PRIVILEDGE_MODE == 0 )
|
||||
csrr t0, mstatus /* Required for MPIE bit. */
|
||||
store_x t0, 29 * portWORD_SIZE( sp )
|
||||
#endif
|
||||
|
||||
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||
|
||||
|
@ -172,11 +273,9 @@ handle_asynchronous:
|
|||
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
|
||||
|
||||
addi t0, x0, 1
|
||||
|
||||
slli t0, t0, __riscv_xlen - 1 /* LSB is already set, shift into MSB. Shift 31 on 32-bit or 63 on 64-bit cores. */
|
||||
addi t1, t0, 7 /* 0x8000[]0007 == machine timer interrupt. */
|
||||
bne a0, t1, test_if_external_interrupt
|
||||
|
||||
load_x t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */
|
||||
load_x t1, pullNextTime /* Load the address of ullNextTime into t1. */
|
||||
|
||||
|
@ -230,8 +329,16 @@ handle_synchronous:
|
|||
store_x a1, 0( sp ) /* Save updated exception return address. */
|
||||
|
||||
test_if_environment_call:
|
||||
#if( USE_PRIVILEDGE_MODE == 0 )
|
||||
li t0, 11 /* 11 == environment call. */
|
||||
#else
|
||||
li t0, 9 /* 9 == environment call. */
|
||||
#endif
|
||||
|
||||
beq a0, t0, next
|
||||
li t0, 11
|
||||
bne a0, t0, is_exception /* Not an M environment call, so some other exception. */
|
||||
next:
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal vTaskSwitchContext
|
||||
j processed_source
|
||||
|
@ -257,8 +364,38 @@ processed_source:
|
|||
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. */
|
||||
#if ( USE_PRIVILEDGE_MODE == 0 )
|
||||
load_x t0, 29 * portWORD_SIZE( sp )
|
||||
csrw mstatus, t0 /* Required for MPIE bit. */
|
||||
#endif
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE != 0 )
|
||||
li a0, 0x1000
|
||||
csrc mstatus, a0
|
||||
li a0, 0x800
|
||||
csrs mstatus, a0
|
||||
|
||||
csrr t0, mstatus
|
||||
li a0, 0x1800
|
||||
and t0, t0, a0
|
||||
srli t0, t0, 11
|
||||
|
||||
#if 0 //for debug
|
||||
csrr t1, mie
|
||||
la t6, int_record
|
||||
sw t1, 0(t6)
|
||||
add t0, t0, t1
|
||||
slli t0, t0, 4
|
||||
csrr t1, mscratch
|
||||
add t0, t0, t1
|
||||
#endif
|
||||
|
||||
la t6, priviledge_status
|
||||
sw t0, 0(t6)
|
||||
|
||||
li t0, 0x880
|
||||
csrw mie, t0
|
||||
#endif
|
||||
|
||||
load_x x1, 1 * portWORD_SIZE( sp )
|
||||
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
||||
|
@ -312,10 +449,15 @@ xPortStartFirstTask:
|
|||
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. */
|
||||
|
||||
#if ( USE_PRIVILEDGE_MODE == 0 )
|
||||
load_x t0, 29 * portWORD_SIZE( sp ) /* mstatus */
|
||||
addi t0, t0, 0x08 /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */
|
||||
csrrw x0, mstatus, t0 /* Interrupts enabled from here! */
|
||||
#endif
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE != 0 )
|
||||
csrwi sscratch, 4
|
||||
#endif
|
||||
|
||||
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
||||
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
||||
|
@ -345,6 +487,11 @@ xPortStartFirstTask:
|
|||
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
||||
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE != 0 )
|
||||
ecall
|
||||
#endif
|
||||
|
||||
ret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -416,7 +563,11 @@ xPortStartFirstTask:
|
|||
pxPortInitialiseStack:
|
||||
|
||||
csrr t0, mstatus /* Obtain current mstatus value. */
|
||||
#if ( USE_PRIVILEDGE_MODE == 0 )
|
||||
addi t1, x0, 0x188 /* Generate the value 0x1880, which are the MPIE and MPP bits to set in mstatus. */
|
||||
#else
|
||||
addi t1, x0, 0x180
|
||||
#endif
|
||||
slli t1, t1, 4
|
||||
or t0, t0, t1 /* Set MPIE and MPP bits in mstatus value. */
|
||||
|
||||
|
@ -436,6 +587,7 @@ chip_specific_stack_frame: /* First add any chip specific registers to the st
|
|||
1:
|
||||
addi a0, a0, -portWORD_SIZE
|
||||
store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */
|
||||
|
||||
ret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#include "../../../../../src/scpu/hal/drivers/recogni_priviledge.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
@ -90,7 +92,12 @@ not need to be guarded with a critical section. */
|
|||
|
||||
/* Scheduler utilities. */
|
||||
extern void vTaskSwitchContext(void);
|
||||
#define portYIELD() __asm volatile("ecall");
|
||||
#if( USE_PRIVILEDGE_MODE != 1 )
|
||||
#define portYIELD() __asm volatile( "ecall" );
|
||||
#else
|
||||
#define portYIELD() vPortSyscall()
|
||||
#endif
|
||||
|
||||
#define portEND_SWITCHING_ISR(xSwitchRequired) \
|
||||
if (xSwitchRequired) vTaskSwitchContext()
|
||||
#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x)
|
||||
|
@ -104,8 +111,14 @@ not need to be guarded with a critical section. */
|
|||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) \
|
||||
(void)uxSavedStatusValue
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE != 1 )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile("csrc mstatus, 8")
|
||||
#define portENABLE_INTERRUPTS() __asm volatile("csrs mstatus, 8")
|
||||
#else
|
||||
#define portDISABLE_INTERRUPTS() vDisableInterrupt()
|
||||
#define portENABLE_INTERRUPTS() vEnableInterrupt()
|
||||
#endif
|
||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||
|
||||
|
|
14
tasks.c
14
tasks.c
|
@ -1013,6 +1013,11 @@ UBaseType_t x;
|
|||
but had been interrupted by the scheduler. The return address is set
|
||||
to the start of the task function. Once the stack has been initialised
|
||||
the top of stack variable is updated. */
|
||||
#if( USE_PRIVILEDGE_MODE == 1 )
|
||||
{
|
||||
vRaisePriviledge();
|
||||
}
|
||||
#endif
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
{
|
||||
/* If the port has capability to detect stack overflow,
|
||||
|
@ -1061,6 +1066,11 @@ UBaseType_t x;
|
|||
}
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
#if( USE_PRIVILEDGE_MODE == 1 )
|
||||
{
|
||||
vResetPriviledge();
|
||||
}
|
||||
#endif
|
||||
if( pxCreatedTask != NULL )
|
||||
{
|
||||
/* Pass the handle out in an anonymous way. The handle can be used to
|
||||
|
@ -1156,7 +1166,6 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
|
|||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_vTaskDelete == 1 )
|
||||
|
||||
void vTaskDelete( TaskHandle_t xTaskToDelete )
|
||||
|
@ -1251,7 +1260,6 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
|
|||
|
||||
#endif /* INCLUDE_vTaskDelete */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_vTaskDelayUntil == 1 )
|
||||
|
||||
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
|
||||
|
@ -1947,7 +1955,6 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
|
|||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
|
||||
prvAddTaskToReadyList( pxTCB );
|
||||
}
|
||||
|
@ -3134,7 +3141,6 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xIte
|
|||
|
||||
#endif /* configUSE_TIMERS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
|
||||
{
|
||||
TCB_t *pxUnblockedTCB;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue