+/*\r
+ * Unlike other ports pxPortInitialiseStack() is written in assembly code as it\r
+ * needs access to the portasmADDITIONAL_CONTEXT_SIZE constant. The prototype\r
+ * for the function is as per the other ports:\r
+ * StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters );\r
+ *\r
+ * As per the standard RISC-V ABI pxTopcOfStack is passed in in a0, pxCode in\r
+ * a1, and pvParameters in a2. The new top of stack is passed out in a0.\r
+ *\r
+ * RISC-V maps registers to ABI names as follows (X1 to X31 integer registers\r
+ * for the 'I' profile, X1 to X15 for the 'E' profile, currently I assumed).\r
+ *\r
+ * Register ABI Name Description Saver\r
+ * x0 zero Hard-wired zero -\r
+ * x1 ra Return address Caller\r
+ * x2 sp Stack pointer Callee\r
+ * x3 gp Global pointer -\r
+ * x4 tp Thread pointer -\r
+ * x5-7 t0-2 Temporaries Caller\r
+ * x8 s0/fp Saved register/Frame pointer Callee\r
+ * x9 s1 Saved register Callee\r
+ * x10-11 a0-1 Function Arguments/return values Caller\r
+ * x12-17 a2-7 Function arguments Caller\r
+ * x18-27 s2-11 Saved registers Callee\r
+ * x28-31 t3-6 Temporaries Caller\r
+ *\r
+ * The RISC-V context is saved t FreeRTOS tasks in the following stack frame,\r
+ * where the global and thread pointers are currently assumed to be constant so\r
+ * are not saved:\r
+ *\r
+ * mstatus\r
+ * x31\r
+ * x30\r
+ * x29\r
+ * x28\r
+ * x27\r
+ * x26\r
+ * x25\r
+ * x24\r
+ * x23\r
+ * x22\r
+ * x21\r
+ * x20\r
+ * x19\r
+ * x18\r
+ * x17\r
+ * x16\r
+ * x15\r
+ * x14\r
+ * x13\r
+ * x12\r
+ * x11\r
+ * pvParameters\r
+ * x9\r
+ * x8\r
+ * x7\r
+ * x6\r
+ * x5\r
+ * portTASK_RETURN_ADDRESS\r
+ * pxCode\r
+ */\r
+.align 8\r
+.func\r
+pxPortInitialiseStack:\r
+\r
+ addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */\r
+\r
+chip_specific_stack_frame: /* First add any chip specific registers to the stack frame being created. */\r
+ beq t0, x0, standard_stack_frame /* 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
+ 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
+\r
+standard_stack_frame: /* Now create the stack frame for the standard registers. */\r
+ csrr t0, mstatus /* Obtain current mstatus value. */\r
+ addi t1, x0, 0x188 /* Generate the value 0x1880, which are the MPIE and MPP bits to set in mstatus. */\r
+ slli t1, t1, 4\r
+ 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
+ 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
+ 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
+ addi a0, a0, -portWORD_SIZE\r
+ sw a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */\r
+ ret\r
+ .endfunc\r
+/*-----------------------------------------------------------*/\r