x28-31 t3-6 Temporaries Caller\r
*/\r
\r
+ /* To ensure alignment. */\r
+ //_RB_ pxTopOfStack--;\r
+ //_RB_ pxTopOfStack--;\r
+ //_RB_pxTopOfStack--;\r
+\r
+ /* Numbers correspond to the x register number. */\r
pxTopOfStack--;\r
*pxTopOfStack = ( StackType_t ) 31;\r
pxTopOfStack--;\r
ullNextTime += ullTimerIncrementsForOneTick;\r
\r
/* Enable timer interrupt */\r
- __asm volatile( "csrs mie, %0" :: "r"(0x80) );\r
+ __asm volatile( "csrs mie, %0" :: "r"(0x80) ); /* 1<<7 for timer interrupt. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
vTaskSwitchContext();\r
\r
/* Clear software interrupt. */\r
- *( ( uint32_t * ) configCTRL_BASE ) = 0UL;\r
+ *( ( uint32_t * ) configCTRL_BASE ) &= 0x08UL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
void Timer_IRQHandler( void )\r
{\r
+extern void vTaskSwitchContext( void );\r
+\r
/* Reload for the next timer interrupt. */\r
*pullMachineTimerCompareRegister = ullNextTime;\r
ullNextTime += ullTimerIncrementsForOneTick;\r
\r
if( xTaskIncrementTick() != pdFALSE )\r
{\r
- portYIELD();\r
+ vTaskSwitchContext();\r
}\r
}\r
/*-----------------------------------------------------------*/\r
{\r
extern void xPortStartFirstTask( void );\r
\r
+ #if( configASSERT_DEFINED == 1 )\r
+ {\r
+ volatile uint32_t mtvec = 0;\r
+\r
+ /* Check the least significant two bits of mtvec are 00 - indicating single\r
+ vector mode. */\r
+ __asm volatile( "csrr %0, mtvec" : "=r"( mtvec ) );\r
+ configASSERT( ( mtvec & 0x03UL ) == 0 );\r
+ }\r
+ #endif\r
+\r
vPortSetupTimerInterrupt();\r
xPortStartFirstTask();\r
\r
addi sp, sp, CONTEXT_SIZE\r
csrs mstatus, 8 /* Enable machine interrupts. */\r
csrs mie, 8 /* Enable soft interrupt. */\r
- ret\r
+ ret\r
\r
/*-----------------------------------------------------------*/\r
\r
.align 8\r
vPortTrapHandler:\r
addi sp, sp, -CONTEXT_SIZE\r
- sw x1, 1( sp )\r
+ sw x1, 1 * WORD_SIZE( sp )\r
sw x5, 2 * WORD_SIZE( sp )\r
sw x6, 3 * WORD_SIZE( sp )\r
sw x7, 4 * WORD_SIZE( sp )\r
sw x30, 27 * WORD_SIZE( sp )\r
sw x31, 28 * WORD_SIZE( sp )\r
\r
- /* Save exception return address. */\r
- csrr t0, mepc\r
- sw t0, 0( sp )\r
-\r
lw t0, pxCurrentTCB /* Load pxCurrentTCB. */\r
sw sp, 0( t0 ) /* Write sp from first TCB member. */\r
\r
mv a2, sp\r
jal handle_trap\r
csrw mepc, a0\r
+ /* Save exception return address. */\r
+ sw a0, 0( sp )\r
+\r
\r
# Remain in M-mode after mret\r
li t0, 0x00001800 /* MSTATUS MPP */\r
lw sp, pxCurrentTCB /* Load pxCurrentTCB. */\r
lw sp, 0( sp ) /* Read sp from first TCB member. */\r
\r
- /* Load mret with the address of the first task. */\r
+ /* Load mret with the address of the next task. */\r
lw t0, 0( sp )\r
csrw mepc, t0\r
\r
- lw x1, 1( sp )\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
\r
\r
/* Scheduler utilities. */\r
-#define portYIELD() *( ( uint32_t * ) configCTRL_BASE ) = 1UL\r
+#define portYIELD() __asm volatile( "ecall" ); // software interrupt alternative *( ( uint32_t * ) configCTRL_BASE ) |= 0x08UL\r
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYield()\r
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )\r
/*-----------------------------------------------------------*/\r