|
|
@@ -17,27 +17,30 @@
|
|
|
|
|
|
#include <lwp_arch.h>
|
|
|
|
|
|
+#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM)
|
|
|
|
|
|
/**
|
|
|
* @brief from thread used interrupt context switch
|
|
|
*
|
|
|
*/
|
|
|
-volatile rt_ubase_t rt_interrupt_from_thread = 0;
|
|
|
+volatile rt_ubase_t rt_interrupt_from_thread = 0;
|
|
|
/**
|
|
|
* @brief to thread used interrupt context switch
|
|
|
*
|
|
|
*/
|
|
|
-volatile rt_ubase_t rt_interrupt_to_thread = 0;
|
|
|
+volatile rt_ubase_t rt_interrupt_to_thread = 0;
|
|
|
/**
|
|
|
* @brief flag to indicate context switch in interrupt or not
|
|
|
*
|
|
|
*/
|
|
|
volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0;
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
- * This function will initialize thread stack
|
|
|
+ * This function will initialize thread stack, we assuming
|
|
|
+ * when scheduler restore this new thread, context will restore
|
|
|
+ * an entry to user first application
|
|
|
*
|
|
|
+ * s0-s11, ra, sstatus, a0
|
|
|
* @param tentry the entry of thread
|
|
|
* @param parameter the parameter of entry
|
|
|
* @param stack_addr the beginning stack address
|
|
|
@@ -45,41 +48,38 @@ volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0;
|
|
|
*
|
|
|
* @return stack address
|
|
|
*/
|
|
|
-rt_uint8_t *rt_hw_stack_init(void *tentry,
|
|
|
- void *parameter,
|
|
|
+rt_uint8_t *rt_hw_stack_init(void *tentry,
|
|
|
+ void *parameter,
|
|
|
rt_uint8_t *stack_addr,
|
|
|
- void *texit)
|
|
|
+ void *texit)
|
|
|
{
|
|
|
- struct rt_hw_stack_frame *frame;
|
|
|
- rt_uint8_t *stk;
|
|
|
- int i;
|
|
|
- extern int __global_pointer$;
|
|
|
-
|
|
|
- stk = stack_addr + sizeof(rt_ubase_t);
|
|
|
- stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES);
|
|
|
- stk -= sizeof(struct rt_hw_stack_frame);
|
|
|
-
|
|
|
- frame = (struct rt_hw_stack_frame *)stk;
|
|
|
-
|
|
|
- for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++)
|
|
|
- {
|
|
|
- ((rt_ubase_t *)frame)[i] = 0xdeadbeef;
|
|
|
- }
|
|
|
-
|
|
|
- frame->ra = (rt_ubase_t)texit;
|
|
|
- frame->gp = (rt_ubase_t)&__global_pointer$;
|
|
|
- frame->a0 = (rt_ubase_t)parameter;
|
|
|
- frame->epc = (rt_ubase_t)tentry;
|
|
|
- frame->user_sp_exc_stack = (rt_ubase_t)(((rt_ubase_t)stk) + sizeof(struct rt_hw_stack_frame));
|
|
|
-
|
|
|
- /* force to supervisor mode(SPP=1) and set SPIE and SUM to 1 */
|
|
|
-#ifdef ENABLE_FPU
|
|
|
- frame->sstatus = 0x00046120; /* enable FPU */
|
|
|
-#else
|
|
|
- frame->sstatus = 0x00040120;
|
|
|
-#endif
|
|
|
-
|
|
|
- return stk;
|
|
|
+ rt_ubase_t *sp = (rt_ubase_t *)stack_addr;
|
|
|
+ // we use a strict alignment requirement for Q extension
|
|
|
+ sp = (rt_ubase_t *)RT_ALIGN_DOWN((rt_ubase_t)sp, 16);
|
|
|
+
|
|
|
+ (*--sp) = (rt_ubase_t)tentry;
|
|
|
+ (*--sp) = (rt_ubase_t)parameter;
|
|
|
+ (*--sp) = (rt_ubase_t)texit;
|
|
|
+
|
|
|
+ /* compatible to RESTORE_CONTEXT */
|
|
|
+ extern void _rt_thread_entry(void);
|
|
|
+ (*--sp) = 0; /* tp */
|
|
|
+ (*--sp) = (rt_ubase_t)_rt_thread_entry; /* ra */
|
|
|
+ (*--sp) = 0; /* s0(fp) */
|
|
|
+ (*--sp) = 0; /* s1 */
|
|
|
+ (*--sp) = 0; /* s2 */
|
|
|
+ (*--sp) = 0; /* s3 */
|
|
|
+ (*--sp) = 0; /* s4 */
|
|
|
+ (*--sp) = 0; /* s5 */
|
|
|
+ (*--sp) = 0; /* s6 */
|
|
|
+ (*--sp) = 0; /* s7 */
|
|
|
+ (*--sp) = 0; /* s8 */
|
|
|
+ (*--sp) = 0; /* s9 */
|
|
|
+ (*--sp) = 0; /* s10 */
|
|
|
+ (*--sp) = 0; /* s11 */
|
|
|
+ (*--sp) = K_SSTATUS_DEFAULT; /* sstatus */
|
|
|
+
|
|
|
+ return (rt_uint8_t *)sp;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -98,7 +98,7 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t
|
|
|
rt_interrupt_to_thread = to;
|
|
|
rt_thread_switch_interrupt_flag = 1;
|
|
|
|
|
|
- return ;
|
|
|
+ return;
|
|
|
}
|
|
|
#endif /* end of RT_USING_SMP */
|
|
|
|
|
|
@@ -117,6 +117,5 @@ void rt_hw_cpu_shutdown()
|
|
|
|
|
|
void rt_hw_set_process_id(int pid)
|
|
|
{
|
|
|
- //TODO
|
|
|
+ // TODO
|
|
|
}
|
|
|
-
|