1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2012-02-13 mojingxian first version
9 */
10
11 #include <rtthread.h>
12
13 /* flag in interrupt handling */
14 rt_uint32_t rt_interrupt_from_thread;
15 rt_uint32_t rt_interrupt_to_thread;
16 rt_uint32_t rt_thread_switch_interrupt_flag;
17
18 /**
19 * initializes stack of thread
20 */
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)21 rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
22 rt_uint8_t *stack_addr, void *texit)
23 {
24 unsigned char i;
25 unsigned long *stk;
26
27 stk = (unsigned long *)stack_addr; /* Load stack pointer */
28
29 /* Simulate a function call to the task with an argument */
30 stk -= 3; /* 3 words assigned for incoming args (R0, R1, R2) */
31
32 /* Now simulating vectoring to an ISR */
33 *--stk = (unsigned long)parameter; /* R0 value - caller's incoming argument #1 */
34 *--stk = (unsigned long)0; /* P1 value - value irrelevant */
35
36 *--stk = (unsigned long)texit; /* RETS value - NO task should return with RTS. */
37 /* however OS_CPU_Invalid_Task_Return is a safety */
38 /* catch-allfor tasks that return with an RTS */
39
40 *--stk = (unsigned long)parameter; /* R1 value - caller's incoming argument #2 */
41 /* (not relevant in current test example) */
42 *--stk = (unsigned long)parameter; /* R2 value - caller's incoming argument #3 */
43 /* (not relevant in current test example) */
44 *--stk = (unsigned long)0; /* P0 value - value irrelevant */
45 *--stk = (unsigned long)0; /* P2 value - value irrelevant */
46 *--stk = (unsigned long)0; /* ASTAT value - caller's ASTAT value - value */
47 /* irrelevant */
48
49 *--stk = (unsigned long)tentry; /* RETI value- pushing the start address of the task */
50
51 for (i = 0; i < 35; i++) /* remaining reg values - R7:3, P5:3, */
52 { /* 4 words of A1:0(.W,.X), LT0, LT1, */
53 *--stk = (unsigned long)0; /* LC0, LC1, LB0, LB1,I3:0, M3:0, L3:0, B3:0, */
54 } /* All values irrelevant */
55
56 return (rt_uint8_t *)stk; /* Return top-of-stack */
57 }
58
rt_hw_context_switch(rt_uint32_t from,rt_uint32_t to)59 void rt_hw_context_switch(rt_uint32_t from, rt_uint32_t to)
60 {
61 if (rt_thread_switch_interrupt_flag != 1)
62 {
63 rt_thread_switch_interrupt_flag = 1;
64 rt_interrupt_from_thread = from;
65 }
66
67 rt_interrupt_to_thread = to;
68 asm("raise 14;"); // Raise Interrupt 14 (trap)
69 }
70
rt_hw_context_switch_interrupt(rt_uint32_t from,rt_uint32_t to)71 void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to)
72 {
73 if (rt_thread_switch_interrupt_flag != 1)
74 {
75 rt_thread_switch_interrupt_flag = 1;
76 rt_interrupt_from_thread = from;
77 }
78
79 rt_interrupt_to_thread = to;
80 asm("raise 14;"); // Raise Interrupt 14 (trap)
81 }
82
rt_hw_context_switch_to(rt_uint32_t to)83 void rt_hw_context_switch_to(rt_uint32_t to)
84 {
85 rt_thread_switch_interrupt_flag = 1;
86 rt_interrupt_from_thread = 0;
87 rt_interrupt_to_thread = to;
88 asm("raise 14;"); // Raise Interrupt 14 (trap)
89 }
90