]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/portable/GCC/RISC-V/portASM.S
Replace portasmHAS_CLINT with configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRES...
[freertos] / FreeRTOS / Source / portable / GCC / RISC-V / portASM.S
index 4f3e5a8bbd1b12c3e7b1a4ef725747fc21102a58..a5756f9786b53fb50e92f7202ca8938c49395cf4 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
- * FreeRTOS Kernel V10.1.1\r
- * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ * FreeRTOS Kernel V10.2.1\r
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
  * this software and associated documentation files (the "Software"), to deal in\r
  * 1 tab == 4 spaces!\r
  */\r
 \r
-#if __riscv_xlen == 64\r
-       #error Not implemented yet - change lw to ld, and sw to sd.\r
-       #define portWORD_SIZE 8\r
-#elif __riscv_xlen == 32\r
-       #define portWORD_SIZE 4\r
-#else\r
-       #error Assembler did not define __riscv_xlen\r
-#endif\r
-\r
 /*\r
  * The FreeRTOS kernel's RISC-V port is split between the the code that is\r
  * common across all currently supported RISC-V chips (implementations of the\r
  * registers.\r
  *\r
  */\r
+#if __riscv_xlen == 64\r
+       #define portWORD_SIZE 8\r
+       #define store_x sd\r
+       #define load_x ld\r
+#elif __riscv_xlen == 32\r
+       #define store_x sw\r
+       #define load_x lw\r
+       #define portWORD_SIZE 4\r
+#else\r
+       #error Assembler did not define __riscv_xlen\r
+#endif\r
+\r
 #include "freertos_risc_v_chip_specific_extensions.h"\r
 \r
 /* Check the freertos_risc_v_chip_specific_extensions.h and/or command line\r
 definitions. */\r
-#ifndef portasmHAS_CLINT\r
-       #error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_CLINT to either 1 (CLINT present) or 0 (clint not present).\r
+#if defined( portasmHAS_CLINT ) && defined( portasmHAS_MTIME )\r
+       #error The portasmHAS_CLINT constant has been depracted.  Please replace it with portasmHAS_CLINT.  portasmHAS_CLINT and portasmHAS_MTIME cannot both be defined at once.\r
+#endif\r
+\r
+#ifdef portasmHAS_CLINT\r
+       #warning The portasmHAS_CLINT constant has been depracted.  Please replace it with portasmHAS_CLINT.  For now portasmHAS_MTIME is derived from portasmHAS_CLINT.\r
+       #define portasmHAS_MTIME portasmHAS_CLINT\r
+#endif\r
+\r
+#ifndef portasmHAS_MTIME\r
+       #error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_MTIME to either 1 (MTIME clock present) or 0 (MTIME clock not present).\r
 #endif\r
 \r
 #ifndef portasmHANDLE_INTERRUPT\r
@@ -89,11 +101,13 @@ at the top of this file. */
 .extern pxCurrentTCB\r
 .extern ulPortTrapHandler\r
 .extern vTaskSwitchContext\r
+.extern xTaskIncrementTick\r
 .extern Timer_IRQHandler\r
 .extern pullMachineTimerCompareRegister\r
 .extern pullNextTime\r
-.extern ulTimerIncrementsForOneTick\r
+.extern uxTimerIncrementsForOneTick /* size_t type so 32-bit on 32-bit core and 64-bits on 64-bit core. */\r
 .extern xISRStackTop\r
+.extern portasmHANDLE_INTERRUPT\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -101,75 +115,98 @@ at the top of this file. */
 .func\r
 freertos_risc_v_trap_handler:\r
        addi sp, sp, -portCONTEXT_SIZE\r
-       sw x1, 1 * portWORD_SIZE( sp )\r
-       sw x5, 2 * portWORD_SIZE( sp )\r
-       sw x6, 3 * portWORD_SIZE( sp )\r
-       sw x7, 4 * portWORD_SIZE( sp )\r
-       sw x8, 5 * portWORD_SIZE( sp )\r
-       sw x9, 6 * portWORD_SIZE( sp )\r
-       sw x10, 7 * portWORD_SIZE( sp )\r
-       sw x11, 8 * portWORD_SIZE( sp )\r
-       sw x12, 9 * portWORD_SIZE( sp )\r
-       sw x13, 10 * portWORD_SIZE( sp )\r
-       sw x14, 11 * portWORD_SIZE( sp )\r
-       sw x15, 12 * portWORD_SIZE( sp )\r
-       sw x16, 13 * portWORD_SIZE( sp )\r
-       sw x17, 14 * portWORD_SIZE( sp )\r
-       sw x18, 15 * portWORD_SIZE( sp )\r
-       sw x19, 16 * portWORD_SIZE( sp )\r
-       sw x20, 17 * portWORD_SIZE( sp )\r
-       sw x21, 18 * portWORD_SIZE( sp )\r
-       sw x22, 19 * portWORD_SIZE( sp )\r
-       sw x23, 20 * portWORD_SIZE( sp )\r
-       sw x24, 21 * portWORD_SIZE( sp )\r
-       sw x25, 22 * portWORD_SIZE( sp )\r
-       sw x26, 23 * portWORD_SIZE( sp )\r
-       sw x27, 24 * portWORD_SIZE( sp )\r
-       sw x28, 25 * portWORD_SIZE( sp )\r
-       sw x29, 26 * portWORD_SIZE( sp )\r
-       sw x30, 27 * portWORD_SIZE( sp )\r
-       sw x31, 28 * portWORD_SIZE( sp )\r
+       store_x x1, 1 * portWORD_SIZE( sp )\r
+       store_x x5, 2 * portWORD_SIZE( sp )\r
+       store_x x6, 3 * portWORD_SIZE( sp )\r
+       store_x x7, 4 * portWORD_SIZE( sp )\r
+       store_x x8, 5 * portWORD_SIZE( sp )\r
+       store_x x9, 6 * portWORD_SIZE( sp )\r
+       store_x x10, 7 * portWORD_SIZE( sp )\r
+       store_x x11, 8 * portWORD_SIZE( sp )\r
+       store_x x12, 9 * portWORD_SIZE( sp )\r
+       store_x x13, 10 * portWORD_SIZE( sp )\r
+       store_x x14, 11 * portWORD_SIZE( sp )\r
+       store_x x15, 12 * portWORD_SIZE( sp )\r
+       store_x x16, 13 * portWORD_SIZE( sp )\r
+       store_x x17, 14 * portWORD_SIZE( sp )\r
+       store_x x18, 15 * portWORD_SIZE( sp )\r
+       store_x x19, 16 * portWORD_SIZE( sp )\r
+       store_x x20, 17 * portWORD_SIZE( sp )\r
+       store_x x21, 18 * portWORD_SIZE( sp )\r
+       store_x x22, 19 * portWORD_SIZE( sp )\r
+       store_x x23, 20 * portWORD_SIZE( sp )\r
+       store_x x24, 21 * portWORD_SIZE( sp )\r
+       store_x x25, 22 * portWORD_SIZE( sp )\r
+       store_x x26, 23 * portWORD_SIZE( sp )\r
+       store_x x27, 24 * portWORD_SIZE( sp )\r
+       store_x x28, 25 * portWORD_SIZE( sp )\r
+       store_x x29, 26 * portWORD_SIZE( sp )\r
+       store_x x30, 27 * portWORD_SIZE( sp )\r
+       store_x x31, 28 * portWORD_SIZE( sp )\r
 \r
        csrr t0, mstatus                                        /* Required for MPIE bit. */\r
-       sw t0, 29 * portWORD_SIZE( sp )\r
+       store_x t0, 29 * portWORD_SIZE( sp )\r
 \r
        portasmSAVE_ADDITIONAL_REGISTERS        /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */\r
 \r
-       lw  t0, pxCurrentTCB                            /* Load pxCurrentTCB. */\r
-       sw  sp, 0( t0 )                                         /* Write sp to first TCB member. */\r
+       load_x  t0, pxCurrentTCB                        /* Load pxCurrentTCB. */\r
+       store_x  sp, 0( t0 )                            /* Write sp to first TCB member. */\r
 \r
        csrr a0, mcause\r
        csrr a1, mepc\r
 \r
 test_if_asynchronous:\r
-       srli a2, a0, 0x1f                                       /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */\r
+       srli a2, a0, __riscv_xlen - 1           /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */\r
        beq a2, x0, handle_synchronous          /* Branch past interrupt handing if not asynchronous. */\r
-       sw a1, 0( sp )                                          /* Asynch so save unmodified exception return address. */\r
+       store_x a1, 0( sp )                                     /* Asynch so save unmodified exception return address. */\r
 \r
 handle_asynchronous:\r
 \r
-#if( portasmHAS_CLINT != 0 )\r
+#if( portasmHAS_MTIME != 0 )\r
+\r
+       test_if_mtimer:                                         /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */\r
+\r
+               addi t0, x0, 1\r
 \r
-       test_if_mtimer:                                                 /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */\r
-               lui t0, 0x80000\r
-               addi t1, t0, 7                                          /* 0x80000007 == machine timer interrupt. */\r
+               slli t0, t0, __riscv_xlen - 1   /* LSB is already set, shift into MSB.  Shift 31 on 32-bit or 63 on 64-bit cores. */\r
+               addi t1, t0, 7                                  /* 0x8000[]0007 == machine timer interrupt. */\r
                bne a0, t1, test_if_external_interrupt\r
 \r
-               lw t0, pullMachineTimerCompareRegister  /* Load address of compare register into t0. */\r
-               lw t1, pullNextTime                                     /* Load the address of ullNextTime into t1. */\r
-               lw t2, 0(t1)                                            /* Load the low word of ullNextTime into t2. */\r
-               lw t3, 4(t1)                                            /* Load the high word of ullNextTime into t3. */\r
-               sw t2, 0(t0)                                            /* Store low word of ullNextTime into compare register. */\r
-               sw t3, 4(t0)                                            /* Store high word of ullNextTime into compare register. */\r
-               lw t0, ulTimerIncrementsForOneTick      /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */\r
-               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. */\r
-               sltu t5, t4, t2                                         /* See if the sum of low words overflowed (what about the zero case?). */\r
-               add t6, t3, t5                                          /* Add overflow to high word of ullNextTime. */\r
-               sw t4, 0(t1)                                            /* Store new low word of ullNextTime. */\r
-               sw t6, 4(t1)                                            /* Store new high word of ullNextTime. */\r
-               lw sp, xISRStackTop                                     /* Switch to ISR stack before function call. */\r
+               load_x t0, pullMachineTimerCompareRegister  /* Load address of compare register into t0. */\r
+               load_x t1, pullNextTime                 /* Load the address of ullNextTime into t1. */\r
+\r
+               #if( __riscv_xlen == 32 )\r
+\r
+                       /* Update the 64-bit mtimer compare match value in two 32-bit writes. */\r
+                       li t4, -1\r
+                       lw t2, 0(t1)                            /* Load the low word of ullNextTime into t2. */\r
+                       lw t3, 4(t1)                            /* Load the high word of ullNextTime into t3. */\r
+                       sw t4, 0(t0)                            /* Low word no smaller than old value to start with - will be overwritten below. */\r
+                       sw t3, 4(t0)                            /* Store high word of ullNextTime into compare register.  No smaller than new value. */\r
+                       sw t2, 0(t0)                            /* Store low word of ullNextTime into compare register. */\r
+                       lw t0, uxTimerIncrementsForOneTick      /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */\r
+                       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). */\r
+                       sltu t5, t4, t2                         /* See if the sum of low words overflowed (what about the zero case?). */\r
+                       add t6, t3, t5                          /* Add overflow to high word of ullNextTime. */\r
+                       sw t4, 0(t1)                            /* Store new low word of ullNextTime. */\r
+                       sw t6, 4(t1)                            /* Store new high word of ullNextTime. */\r
+\r
+               #endif /* __riscv_xlen == 32 */\r
+\r
+               #if( __riscv_xlen == 64 )\r
+\r
+                       /* Update the 64-bit mtimer compare match value. */\r
+                       ld t2, 0(t1)                            /* Load ullNextTime into t2. */\r
+                       sd t2, 0(t0)                            /* Store ullNextTime into compare register. */\r
+                       ld t0, uxTimerIncrementsForOneTick  /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */\r
+                       add t4, t0, t2                          /* Add ullNextTime to the timer increments for one tick. */\r
+                       sd t4, 0(t1)                            /* Store ullNextTime. */\r
+\r
+               #endif /* __riscv_xlen == 64 */\r
+\r
+               load_x sp, xISRStackTop                 /* Switch to ISR stack before function call. */\r
                jal xTaskIncrementTick\r
-               beqz a0, processed_source                       /* Don't switch context if incrementing tick didn't unblock a task. */\r
+               beqz a0, processed_source               /* Don't switch context if incrementing tick didn't unblock a task. */\r
                jal vTaskSwitchContext\r
                j processed_source\r
 \r
@@ -177,73 +214,75 @@ handle_asynchronous:
                addi t1, t1, 4                                  /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */\r
                bne a0, t1, as_yet_unhandled    /* Something as yet unhandled. */\r
 \r
-#endif /* portasmHAS_CLINT */\r
+#endif /* portasmHAS_MTIME */\r
 \r
-       lw sp, xISRStackTop                                     /* Switch to ISR stack before function call. */\r
+       load_x sp, xISRStackTop                         /* Switch to ISR stack before function call. */\r
        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. */\r
        j processed_source\r
 \r
 handle_synchronous:\r
        addi a1, a1, 4                                          /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */\r
-       sw a1, 0( sp )                                          /* Save updated exception return address. */\r
+       store_x a1, 0( sp )                                     /* Save updated exception return address. */\r
 \r
 test_if_environment_call:\r
        li t0, 11                                                       /* 11 == environment call. */\r
        bne a0, t0, is_exception                        /* Not an M environment call, so some other exception. */\r
-       lw sp, xISRStackTop                                     /* Switch to ISR stack before function call. */\r
+       load_x sp, xISRStackTop                         /* Switch to ISR stack before function call. */\r
        jal vTaskSwitchContext\r
        j processed_source\r
 \r
 is_exception:\r
-       ebreak\r
-       j is_exception\r
+       csrr t0, mcause                                         /* For viewing in the debugger only. */\r
+       csrr t1, mepc                                           /* For viewing in the debugger only */\r
+       csrr t2, mstatus\r
+       j is_exception                                          /* No other exceptions handled yet. */\r
 \r
 as_yet_unhandled:\r
-       ebreak\r
+       csrr t0, mcause                                         /* For viewing in the debugger only. */\r
        j as_yet_unhandled\r
 \r
 processed_source:\r
-       lw  sp, pxCurrentTCB                            /* Load pxCurrentTCB. */\r
-       lw  sp, 0( sp )                                         /* Read sp from first TCB member. */\r
+       load_x  t1, pxCurrentTCB                        /* Load pxCurrentTCB. */\r
+       load_x  sp, 0( t1 )                                     /* Read sp from first TCB member. */\r
 \r
        /* Load mret with the address of the next instruction in the task to run next. */\r
-       lw t0, 0( sp )\r
+       load_x t0, 0( sp )\r
        csrw mepc, t0\r
 \r
        portasmRESTORE_ADDITIONAL_REGISTERS     /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */\r
 \r
        /* Load mstatus with the interrupt enable bits used by the task. */\r
-       lw  t0, 29 * portWORD_SIZE( sp )\r
-       csrw mstatus, t0                                        /* Required for MPIE bit. */\r
-\r
-       lw  x1, 1 * portWORD_SIZE( sp )\r
-       lw  x5, 2 * portWORD_SIZE( sp )         /* t0 */\r
-       lw  x6, 3 * portWORD_SIZE( sp )         /* t1 */\r
-       lw  x7, 4 * portWORD_SIZE( sp )         /* t2 */\r
-       lw  x8, 5 * portWORD_SIZE( sp )         /* s0/fp */\r
-       lw  x9, 6 * portWORD_SIZE( sp )         /* s1 */\r
-       lw  x10, 7 * portWORD_SIZE( sp )        /* a0 */\r
-       lw  x11, 8 * portWORD_SIZE( sp )        /* a1 */\r
-       lw  x12, 9 * portWORD_SIZE( sp )        /* a2 */\r
-       lw  x13, 10 * portWORD_SIZE( sp )       /* a3 */\r
-       lw  x14, 11 * portWORD_SIZE( sp )       /* a4 */\r
-       lw  x15, 12 * portWORD_SIZE( sp )       /* a5 */\r
-       lw  x16, 13 * portWORD_SIZE( sp )       /* a6 */\r
-       lw  x17, 14 * portWORD_SIZE( sp )       /* a7 */\r
-       lw  x18, 15 * portWORD_SIZE( sp )       /* s2 */\r
-       lw  x19, 16 * portWORD_SIZE( sp )       /* s3 */\r
-       lw  x20, 17 * portWORD_SIZE( sp )       /* s4 */\r
-       lw  x21, 18 * portWORD_SIZE( sp )       /* s5 */\r
-       lw  x22, 19 * portWORD_SIZE( sp )       /* s6 */\r
-       lw  x23, 20 * portWORD_SIZE( sp )       /* s7 */\r
-       lw  x24, 21 * portWORD_SIZE( sp )       /* s8 */\r
-       lw  x25, 22 * portWORD_SIZE( sp )       /* s9 */\r
-       lw  x26, 23 * portWORD_SIZE( sp )       /* s10 */\r
-       lw  x27, 24 * portWORD_SIZE( sp )       /* s11 */\r
-       lw  x28, 25 * portWORD_SIZE( sp )       /* t3 */\r
-       lw  x29, 26 * portWORD_SIZE( sp )       /* t4 */\r
-       lw  x30, 27 * portWORD_SIZE( sp )       /* t5 */\r
-       lw  x31, 28 * portWORD_SIZE( sp )       /* t6 */\r
+       load_x  t0, 29 * portWORD_SIZE( sp )\r
+       csrw mstatus, t0                                                /* Required for MPIE bit. */\r
+\r
+       load_x  x1, 1 * portWORD_SIZE( sp )\r
+       load_x  x5, 2 * portWORD_SIZE( sp )             /* t0 */\r
+       load_x  x6, 3 * portWORD_SIZE( sp )             /* t1 */\r
+       load_x  x7, 4 * portWORD_SIZE( sp )             /* t2 */\r
+       load_x  x8, 5 * portWORD_SIZE( sp )             /* s0/fp */\r
+       load_x  x9, 6 * portWORD_SIZE( sp )             /* s1 */\r
+       load_x  x10, 7 * portWORD_SIZE( sp )    /* a0 */\r
+       load_x  x11, 8 * portWORD_SIZE( sp )    /* a1 */\r
+       load_x  x12, 9 * portWORD_SIZE( sp )    /* a2 */\r
+       load_x  x13, 10 * portWORD_SIZE( sp )   /* a3 */\r
+       load_x  x14, 11 * portWORD_SIZE( sp )   /* a4 */\r
+       load_x  x15, 12 * portWORD_SIZE( sp )   /* a5 */\r
+       load_x  x16, 13 * portWORD_SIZE( sp )   /* a6 */\r
+       load_x  x17, 14 * portWORD_SIZE( sp )   /* a7 */\r
+       load_x  x18, 15 * portWORD_SIZE( sp )   /* s2 */\r
+       load_x  x19, 16 * portWORD_SIZE( sp )   /* s3 */\r
+       load_x  x20, 17 * portWORD_SIZE( sp )   /* s4 */\r
+       load_x  x21, 18 * portWORD_SIZE( sp )   /* s5 */\r
+       load_x  x22, 19 * portWORD_SIZE( sp )   /* s6 */\r
+       load_x  x23, 20 * portWORD_SIZE( sp )   /* s7 */\r
+       load_x  x24, 21 * portWORD_SIZE( sp )   /* s8 */\r
+       load_x  x25, 22 * portWORD_SIZE( sp )   /* s9 */\r
+       load_x  x26, 23 * portWORD_SIZE( sp )   /* s10 */\r
+       load_x  x27, 24 * portWORD_SIZE( sp )   /* s11 */\r
+       load_x  x28, 25 * portWORD_SIZE( sp )   /* t3 */\r
+       load_x  x29, 26 * portWORD_SIZE( sp )   /* t4 */\r
+       load_x  x30, 27 * portWORD_SIZE( sp )   /* t5 */\r
+       load_x  x31, 28 * portWORD_SIZE( sp )   /* t6 */\r
        addi sp, sp, portCONTEXT_SIZE\r
 \r
        mret\r
@@ -254,7 +293,7 @@ processed_source:
 .func\r
 xPortStartFirstTask:\r
 \r
-#if( portasmHAS_CLINT != 0 )\r
+#if( portasmHAS_MTIME != 0 )\r
        /* If there is a clint then interrupts can branch directly to the FreeRTOS\r
        trap handler.  Otherwise the interrupt controller will need to be configured\r
        outside of this file. */\r
@@ -262,43 +301,44 @@ xPortStartFirstTask:
        csrw mtvec, t0\r
 #endif /* portasmHAS_CLILNT */\r
 \r
-       lw  sp, pxCurrentTCB                    /* Load pxCurrentTCB. */\r
-       lw  sp, 0( sp )                                 /* Read sp from first TCB member. */\r
+       load_x  sp, pxCurrentTCB                        /* Load pxCurrentTCB. */\r
+       load_x  sp, 0( sp )                                     /* Read sp from first TCB member. */\r
 \r
-       lw  x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */\r
+       load_x  x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */\r
 \r
        portasmRESTORE_ADDITIONAL_REGISTERS     /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */\r
 \r
-    lw  t0, 29 * portWORD_SIZE( sp )    /* mstatus */\r
-    csrrw  x0, mstatus, t0              /* Interrupts enabled from here! */\r
-\r
-       lw  x5, 2 * portWORD_SIZE( sp )         /* t0 */\r
-       lw  x6, 3 * portWORD_SIZE( sp )         /* t1 */\r
-       lw  x7, 4 * portWORD_SIZE( sp )         /* t2 */\r
-       lw  x8, 5 * portWORD_SIZE( sp )         /* s0/fp */\r
-       lw  x9, 6 * portWORD_SIZE( sp )         /* s1 */\r
-       lw  x10, 7 * portWORD_SIZE( sp )        /* a0 */\r
-       lw  x11, 8 * portWORD_SIZE( sp )        /* a1 */\r
-       lw  x12, 9 * portWORD_SIZE( sp )        /* a2 */\r
-       lw  x13, 10 * portWORD_SIZE( sp )       /* a3 */\r
-       lw  x14, 11 * portWORD_SIZE( sp )       /* a4 */\r
-       lw  x15, 12 * portWORD_SIZE( sp )       /* a5 */\r
-       lw  x16, 13 * portWORD_SIZE( sp )       /* a6 */\r
-       lw  x17, 14 * portWORD_SIZE( sp )       /* a7 */\r
-       lw  x18, 15 * portWORD_SIZE( sp )       /* s2 */\r
-       lw  x19, 16 * portWORD_SIZE( sp )       /* s3 */\r
-       lw  x20, 17 * portWORD_SIZE( sp )       /* s4 */\r
-       lw  x21, 18 * portWORD_SIZE( sp )       /* s5 */\r
-       lw  x22, 19 * portWORD_SIZE( sp )       /* s6 */\r
-       lw  x23, 20 * portWORD_SIZE( sp )       /* s7 */\r
-       lw  x24, 21 * portWORD_SIZE( sp )       /* s8 */\r
-       lw  x25, 22 * portWORD_SIZE( sp )       /* s9 */\r
-       lw  x26, 23 * portWORD_SIZE( sp )       /* s10 */\r
-       lw  x27, 24 * portWORD_SIZE( sp )       /* s11 */\r
-       lw  x28, 25 * portWORD_SIZE( sp )       /* t3 */\r
-       lw  x29, 26 * portWORD_SIZE( sp )       /* t4 */\r
-       lw  x30, 27 * portWORD_SIZE( sp )       /* t5 */\r
-       lw  x31, 28 * portWORD_SIZE( sp )       /* t6 */\r
+       load_x  t0, 29 * portWORD_SIZE( sp )    /* mstatus */\r
+       addi t0, t0, 0x08                                               /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */\r
+       csrrw  x0, mstatus, t0                                  /* Interrupts enabled from here! */\r
+\r
+       load_x  x5, 2 * portWORD_SIZE( sp )             /* t0 */\r
+       load_x  x6, 3 * portWORD_SIZE( sp )             /* t1 */\r
+       load_x  x7, 4 * portWORD_SIZE( sp )             /* t2 */\r
+       load_x  x8, 5 * portWORD_SIZE( sp )             /* s0/fp */\r
+       load_x  x9, 6 * portWORD_SIZE( sp )             /* s1 */\r
+       load_x  x10, 7 * portWORD_SIZE( sp )    /* a0 */\r
+       load_x  x11, 8 * portWORD_SIZE( sp )    /* a1 */\r
+       load_x  x12, 9 * portWORD_SIZE( sp )    /* a2 */\r
+       load_x  x13, 10 * portWORD_SIZE( sp )   /* a3 */\r
+       load_x  x14, 11 * portWORD_SIZE( sp )   /* a4 */\r
+       load_x  x15, 12 * portWORD_SIZE( sp )   /* a5 */\r
+       load_x  x16, 13 * portWORD_SIZE( sp )   /* a6 */\r
+       load_x  x17, 14 * portWORD_SIZE( sp )   /* a7 */\r
+       load_x  x18, 15 * portWORD_SIZE( sp )   /* s2 */\r
+       load_x  x19, 16 * portWORD_SIZE( sp )   /* s3 */\r
+       load_x  x20, 17 * portWORD_SIZE( sp )   /* s4 */\r
+       load_x  x21, 18 * portWORD_SIZE( sp )   /* s5 */\r
+       load_x  x22, 19 * portWORD_SIZE( sp )   /* s6 */\r
+       load_x  x23, 20 * portWORD_SIZE( sp )   /* s7 */\r
+       load_x  x24, 21 * portWORD_SIZE( sp )   /* s8 */\r
+       load_x  x25, 22 * portWORD_SIZE( sp )   /* s9 */\r
+       load_x  x26, 23 * portWORD_SIZE( sp )   /* s10 */\r
+       load_x  x27, 24 * portWORD_SIZE( sp )   /* s11 */\r
+       load_x  x28, 25 * portWORD_SIZE( sp )   /* t3 */\r
+       load_x  x29, 26 * portWORD_SIZE( sp )   /* t4 */\r
+       load_x  x30, 27 * portWORD_SIZE( sp )   /* t5 */\r
+       load_x  x31, 28 * portWORD_SIZE( sp )   /* t6 */\r
        addi    sp, sp, portCONTEXT_SIZE\r
        ret\r
        .endfunc\r
@@ -376,21 +416,21 @@ pxPortInitialiseStack:
        or t0, t0, t1                                           /* Set MPIE and MPP bits in mstatus value. */\r
 \r
        addi a0, a0, -portWORD_SIZE\r
-       sw t0, 0(a0)                                            /* mstatus onto the stack. */\r
+       store_x t0, 0(a0)                                       /* mstatus onto the stack. */\r
        addi a0, a0, -(22 * portWORD_SIZE)      /* Space for registers x11-x31. */\r
-       sw a2, 0(a0)                                            /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */\r
+       store_x a2, 0(a0)                                       /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */\r
        addi a0, a0, -(6 * portWORD_SIZE)       /* Space for registers x5-x9. */\r
-       sw x0, 0(a0)                                            /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */\r
+       store_x x0, 0(a0)                                       /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */\r
        addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */\r
 chip_specific_stack_frame:                             /* First add any chip specific registers to the stack frame being created. */\r
        beq t0, x0, 1f                                          /* No more chip specific registers to save. */\r
        addi a0, a0, -portWORD_SIZE                     /* Make space for chip specific register. */\r
-       sw x0, 0(a0)                                            /* Give the chip specific register an initial value of zero. */\r
+       store_x x0, 0(a0)                                       /* Give the chip specific register an initial value of zero. */\r
        addi t0, t0, -1                                         /* Decrement the count of chip specific registers remaining. */\r
        j chip_specific_stack_frame                     /* Until no more chip specific registers. */\r
 1:\r
        addi a0, a0, -portWORD_SIZE\r
-       sw a1, 0(a0)                                            /* mret value (pxCode parameter) onto the stack. */\r
+       store_x a1, 0(a0)                                       /* mret value (pxCode parameter) onto the stack. */\r
        ret\r
        .endfunc\r
 /*-----------------------------------------------------------*/\r