forked from epagris/FreeRTOS-Kernel
		
	Some efficiency improvements in Risc-V port.
This commit is contained in:
		
							parent
							
								
									dc99300fa9
								
							
						
					
					
						commit
						e85ea96f78
					
				@ -49,9 +49,10 @@ static void prvTaskExitError( void );
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Used to program the machine timer compare register. */
 | 
			
		||||
static uint64_t ullNextTime = 0ULL;
 | 
			
		||||
static const uint64_t ullTimerIncrementsForOneTick = ( uint64_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
 | 
			
		||||
static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 );
 | 
			
		||||
uint64_t ullNextTime = 0ULL;
 | 
			
		||||
const uint64_t *pullNextTime = &ullNextTime;
 | 
			
		||||
const uint32_t ulTimerIncrementsForOneTick = ( uint32_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ); /* Assumes increment won't go over 32-bits. */
 | 
			
		||||
volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 );
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
@ -187,11 +188,11 @@ volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLI
 | 
			
		||||
	ullNextTime = ( uint64_t ) ulCurrentTimeHigh;
 | 
			
		||||
	ullNextTime <<= 32ULL;
 | 
			
		||||
	ullNextTime |= ( uint64_t ) ulCurrentTimeLow;
 | 
			
		||||
	ullNextTime += ullTimerIncrementsForOneTick;
 | 
			
		||||
	ullNextTime += ( uint64_t ) ulTimerIncrementsForOneTick;
 | 
			
		||||
	*pullMachineTimerCompareRegister = ullNextTime;
 | 
			
		||||
 | 
			
		||||
	/* Prepare the time to use after the next tick interrupt. */
 | 
			
		||||
	ullNextTime += ullTimerIncrementsForOneTick;
 | 
			
		||||
	ullNextTime += ( uint64_t ) ulTimerIncrementsForOneTick;
 | 
			
		||||
 | 
			
		||||
	/* Enable timer interrupt */
 | 
			
		||||
	__asm volatile( "csrs mie, %0" :: "r"(0x80) ); /* 1<<7 for timer interrupt. */
 | 
			
		||||
@ -209,21 +210,6 @@ volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCLINT_BASE_ADDR
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void Timer_IRQHandler( void )
 | 
			
		||||
{
 | 
			
		||||
extern void vTaskSwitchContext( void );
 | 
			
		||||
 | 
			
		||||
	/* Reload for the next timer interrupt. */
 | 
			
		||||
	*pullMachineTimerCompareRegister = ullNextTime;
 | 
			
		||||
	ullNextTime += ullTimerIncrementsForOneTick;
 | 
			
		||||
 | 
			
		||||
	if( xTaskIncrementTick() != pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		vTaskSwitchContext();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
BaseType_t xPortStartScheduler( void )
 | 
			
		||||
{
 | 
			
		||||
extern void xPortStartFirstTask( void );
 | 
			
		||||
 | 
			
		||||
@ -28,12 +28,12 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if __riscv_xlen == 64
 | 
			
		||||
    #error Not implemented yet - change lw to ld, and sw to sd.
 | 
			
		||||
    #define WORD_SIZE 8
 | 
			
		||||
	#error Not implemented yet - change lw to ld, and sw to sd.
 | 
			
		||||
	#define WORD_SIZE 8
 | 
			
		||||
#elif __riscv_xlen == 32
 | 
			
		||||
    #define WORD_SIZE 4
 | 
			
		||||
	#define WORD_SIZE 4
 | 
			
		||||
#else
 | 
			
		||||
    #error Assembler has not defined __riscv_xlen
 | 
			
		||||
	#error Assembler has not defined __riscv_xlen
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CONTEXT_SIZE ( 30 * WORD_SIZE )
 | 
			
		||||
@ -42,6 +42,14 @@
 | 
			
		||||
.global vPortTrapHandler
 | 
			
		||||
.extern pxCurrentTCB
 | 
			
		||||
.extern ulPortTrapHandler
 | 
			
		||||
.extern vTaskSwitchContext
 | 
			
		||||
.extern Timer_IRQHandler
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.extern pullMachineTimerCompareRegister
 | 
			
		||||
.extern pullNextTime
 | 
			
		||||
.extern ulTimerIncrementsForOneTick
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
@ -51,18 +59,18 @@ xPortStartFirstTask:
 | 
			
		||||
	la t0, vPortTrapHandler
 | 
			
		||||
	csrw mtvec, t0
 | 
			
		||||
 | 
			
		||||
	lw  sp, pxCurrentTCB            /* Load pxCurrentTCB. */
 | 
			
		||||
	lw  sp, 0( sp )                 /* Read sp from first TCB member. */
 | 
			
		||||
	lw  sp, pxCurrentTCB			/* Load pxCurrentTCB. */
 | 
			
		||||
	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  x5, 2 * WORD_SIZE( sp )     /* t0 */
 | 
			
		||||
	lw  x6, 3 * WORD_SIZE( sp )     /* t1 */
 | 
			
		||||
	lw  x7, 4 * WORD_SIZE( sp )     /* t2 */
 | 
			
		||||
	lw  x8, 5 * WORD_SIZE( sp )     /* s0/fp */
 | 
			
		||||
	lw  x9, 6 * WORD_SIZE( sp )     /* s1 */
 | 
			
		||||
	lw  x10, 7 * WORD_SIZE( sp )    /* a0 */
 | 
			
		||||
	lw  x11, 8 * WORD_SIZE( sp )    /* a1 */
 | 
			
		||||
	lw  x12, 9 * WORD_SIZE( sp )    /* a2 */
 | 
			
		||||
	lw  x5, 2 * WORD_SIZE( sp )	 	/* t0 */
 | 
			
		||||
	lw  x6, 3 * WORD_SIZE( sp )	 	/* t1 */
 | 
			
		||||
	lw  x7, 4 * WORD_SIZE( sp )	 	/* t2 */
 | 
			
		||||
	lw  x8, 5 * WORD_SIZE( sp )	 	/* s0/fp */
 | 
			
		||||
	lw  x9, 6 * WORD_SIZE( sp )	 	/* s1 */
 | 
			
		||||
	lw  x10, 7 * WORD_SIZE( sp )	/* a0 */
 | 
			
		||||
	lw  x11, 8 * WORD_SIZE( sp )	/* a1 */
 | 
			
		||||
	lw  x12, 9 * WORD_SIZE( sp )	/* a2 */
 | 
			
		||||
	lw  x13, 10 * WORD_SIZE( sp )   /* a3 */
 | 
			
		||||
	lw  x14, 11 * WORD_SIZE( sp )   /* a4 */
 | 
			
		||||
	lw  x15, 12 * WORD_SIZE( sp )   /* a5 */
 | 
			
		||||
@ -82,8 +90,8 @@ xPortStartFirstTask:
 | 
			
		||||
	lw  x29, 26 * WORD_SIZE( sp )   /* t4 */
 | 
			
		||||
	lw  x30, 27 * WORD_SIZE( sp )   /* t5 */
 | 
			
		||||
	lw  x31, 28 * WORD_SIZE( sp )   /* t6 */
 | 
			
		||||
	addi    sp, sp, CONTEXT_SIZE
 | 
			
		||||
	csrs    mstatus, 8              /* Enable machine interrupts. */
 | 
			
		||||
	addi	sp, sp, CONTEXT_SIZE
 | 
			
		||||
	csrs	mstatus, 8			  /* Enable machine interrupts. */
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -120,24 +128,56 @@ vPortTrapHandler:
 | 
			
		||||
	sw x30, 27 * WORD_SIZE( sp )
 | 
			
		||||
	sw x31, 28 * WORD_SIZE( sp )
 | 
			
		||||
 | 
			
		||||
	csrr t0, mstatus                /* Required for MPIE bit. */
 | 
			
		||||
	csrr t0, mstatus						/* Required for MPIE bit. */
 | 
			
		||||
	sw t0, 29 * WORD_SIZE( sp )
 | 
			
		||||
 | 
			
		||||
	lw  t0, pxCurrentTCB            /* Load pxCurrentTCB. */
 | 
			
		||||
	sw  sp, 0( t0 )                 /* Write sp to first TCB member. */
 | 
			
		||||
	lw  t0, pxCurrentTCB					/* Load pxCurrentTCB. */
 | 
			
		||||
	sw  sp, 0( t0 )				 			/* Write sp to first TCB member. */
 | 
			
		||||
 | 
			
		||||
	csrr a0, mcause
 | 
			
		||||
	csrr a1, mepc
 | 
			
		||||
	mv a2, sp
 | 
			
		||||
 | 
			
		||||
test_if_environment_call:
 | 
			
		||||
	li t0, 11 								/* 11 == environment call when using qemu. */
 | 
			
		||||
	bne a0, t0, test_if_timer
 | 
			
		||||
	addi a1, a1, 4 							/* Synchronous so return to the instruction after the environment call. */
 | 
			
		||||
	sw a1, 0( sp ) 							/* Save updated exception return address. */
 | 
			
		||||
/*_RB_ Does stack need aligning here? */
 | 
			
		||||
	jal ulPortTrapHandler
 | 
			
		||||
	csrw mepc, a0
 | 
			
		||||
	/* Save exception return address. */
 | 
			
		||||
	sw a0, 0( sp )
 | 
			
		||||
	jal vTaskSwitchContext
 | 
			
		||||
	j processed_source
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	lw  sp, pxCurrentTCB            /* Load pxCurrentTCB. */
 | 
			
		||||
	lw  sp, 0( sp )                 /* Read sp from first TCB member. */
 | 
			
		||||
test_if_timer:
 | 
			
		||||
	sw a1, 0( sp ) 							/* Asynch so save unmodified exception return address. */
 | 
			
		||||
 | 
			
		||||
	lui t0, 0x80000
 | 
			
		||||
	addi t1,t0, 7 							/* 0x80000007 == machine timer interrupt. */
 | 
			
		||||
	bne a0, t1, as_yet_unhandled
 | 
			
		||||
 | 
			
		||||
	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. */
 | 
			
		||||
	jal xTaskIncrementTick
 | 
			
		||||
	beqz a0, processed_source				/* Don't switch context if incrementing tick didn't unblock a task. */
 | 
			
		||||
	jal vTaskSwitchContext
 | 
			
		||||
	j processed_source
 | 
			
		||||
 | 
			
		||||
as_yet_unhandled:
 | 
			
		||||
	j as_yet_unhandled 						/* External interrupt? */
 | 
			
		||||
 | 
			
		||||
processed_source:
 | 
			
		||||
	lw  sp, pxCurrentTCB					/* Load pxCurrentTCB. */
 | 
			
		||||
	lw  sp, 0( sp )				 			/* Read sp from first TCB member. */
 | 
			
		||||
 | 
			
		||||
	/* Load mret with the address of the next task. */
 | 
			
		||||
	lw t0, 0( sp )
 | 
			
		||||
@ -145,37 +185,37 @@ vPortTrapHandler:
 | 
			
		||||
 | 
			
		||||
	/* Load mstatus with the interrupt enable bits used by the task. */
 | 
			
		||||
	lw  t0, 29 * WORD_SIZE( sp )
 | 
			
		||||
	csrw mstatus, t0                /* Required for MPIE bit. */
 | 
			
		||||
	csrw mstatus, t0						/* Required for MPIE bit. */
 | 
			
		||||
 | 
			
		||||
	lw  x1, 1 * WORD_SIZE( sp )
 | 
			
		||||
	lw  x5, 2 * WORD_SIZE( sp )     /* t0 */
 | 
			
		||||
	lw  x6, 3 * WORD_SIZE( sp )     /* t1 */
 | 
			
		||||
	lw  x7, 4 * WORD_SIZE( sp )     /* t2 */
 | 
			
		||||
	lw  x8, 5 * WORD_SIZE( sp )     /* s0/fp */
 | 
			
		||||
	lw  x9, 6 * WORD_SIZE( sp )     /* s1 */
 | 
			
		||||
	lw  x10, 7 * WORD_SIZE( sp )    /* a0 */
 | 
			
		||||
	lw  x11, 8 * WORD_SIZE( sp )    /* a1 */
 | 
			
		||||
	lw  x12, 9 * WORD_SIZE( sp )    /* a2 */
 | 
			
		||||
	lw  x13, 10 * WORD_SIZE( sp )   /* a3 */
 | 
			
		||||
	lw  x14, 11 * WORD_SIZE( sp )   /* a4 */
 | 
			
		||||
	lw  x15, 12 * WORD_SIZE( sp )   /* a5 */
 | 
			
		||||
	lw  x16, 13 * WORD_SIZE( sp )   /* a6 */
 | 
			
		||||
	lw  x17, 14 * WORD_SIZE( sp )   /* a7 */
 | 
			
		||||
	lw  x18, 15 * WORD_SIZE( sp )   /* s2 */
 | 
			
		||||
	lw  x19, 16 * WORD_SIZE( sp )   /* s3 */
 | 
			
		||||
	lw  x20, 17 * WORD_SIZE( sp )   /* s4 */
 | 
			
		||||
	lw  x21, 18 * WORD_SIZE( sp )   /* s5 */
 | 
			
		||||
	lw  x22, 19 * WORD_SIZE( sp )   /* s6 */
 | 
			
		||||
	lw  x23, 20 * WORD_SIZE( sp )   /* s7 */
 | 
			
		||||
	lw  x24, 21 * WORD_SIZE( sp )   /* s8 */
 | 
			
		||||
	lw  x25, 22 * WORD_SIZE( sp )   /* s9 */
 | 
			
		||||
	lw  x26, 23 * WORD_SIZE( sp )   /* s10 */
 | 
			
		||||
	lw  x27, 24 * WORD_SIZE( sp )   /* s11 */
 | 
			
		||||
	lw  x28, 25 * WORD_SIZE( sp )   /* t3 */
 | 
			
		||||
	lw  x29, 26 * WORD_SIZE( sp )   /* t4 */
 | 
			
		||||
	lw  x30, 27 * WORD_SIZE( sp )   /* t5 */
 | 
			
		||||
	lw  x31, 28 * WORD_SIZE( sp )   /* t6 */
 | 
			
		||||
	addi    sp, sp, CONTEXT_SIZE
 | 
			
		||||
	lw  x5, 2 * WORD_SIZE( sp )	 			/* t0 */
 | 
			
		||||
	lw  x6, 3 * WORD_SIZE( sp )	 			/* t1 */
 | 
			
		||||
	lw  x7, 4 * WORD_SIZE( sp )	 			/* t2 */
 | 
			
		||||
	lw  x8, 5 * WORD_SIZE( sp )	 			/* s0/fp */
 | 
			
		||||
	lw  x9, 6 * WORD_SIZE( sp )	 			/* s1 */
 | 
			
		||||
	lw  x10, 7 * WORD_SIZE( sp )			/* a0 */
 | 
			
		||||
	lw  x11, 8 * WORD_SIZE( sp )			/* a1 */
 | 
			
		||||
	lw  x12, 9 * WORD_SIZE( sp )			/* a2 */
 | 
			
		||||
	lw  x13, 10 * WORD_SIZE( sp )   		/* a3 */
 | 
			
		||||
	lw  x14, 11 * WORD_SIZE( sp )   		/* a4 */
 | 
			
		||||
	lw  x15, 12 * WORD_SIZE( sp )   		/* a5 */
 | 
			
		||||
	lw  x16, 13 * WORD_SIZE( sp )   		/* a6 */
 | 
			
		||||
	lw  x17, 14 * WORD_SIZE( sp )   		/* a7 */
 | 
			
		||||
	lw  x18, 15 * WORD_SIZE( sp )   		/* s2 */
 | 
			
		||||
	lw  x19, 16 * WORD_SIZE( sp )   		/* s3 */
 | 
			
		||||
	lw  x20, 17 * WORD_SIZE( sp )   		/* s4 */
 | 
			
		||||
	lw  x21, 18 * WORD_SIZE( sp )   		/* s5 */
 | 
			
		||||
	lw  x22, 19 * WORD_SIZE( sp )   		/* s6 */
 | 
			
		||||
	lw  x23, 20 * WORD_SIZE( sp )   		/* s7 */
 | 
			
		||||
	lw  x24, 21 * WORD_SIZE( sp )   		/* s8 */
 | 
			
		||||
	lw  x25, 22 * WORD_SIZE( sp )   		/* s9 */
 | 
			
		||||
	lw  x26, 23 * WORD_SIZE( sp )   		/* s10 */
 | 
			
		||||
	lw  x27, 24 * WORD_SIZE( sp )   		/* s11 */
 | 
			
		||||
	lw  x28, 25 * WORD_SIZE( sp )   		/* t3 */
 | 
			
		||||
	lw  x29, 26 * WORD_SIZE( sp )   		/* t4 */
 | 
			
		||||
	lw  x30, 27 * WORD_SIZE( sp )   		/* t5 */
 | 
			
		||||
	lw  x31, 28 * WORD_SIZE( sp )   		/* t6 */
 | 
			
		||||
	addi	sp, sp, CONTEXT_SIZE
 | 
			
		||||
 | 
			
		||||
	mret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user