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