xref: /nrf52832-nimble/rt-thread/libcpu/rx/cpuport.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * File      : cpuport.c
3*10465441SEvalZero  * This file is part of RT-Thread RTOS
4*10465441SEvalZero  * COPYRIGHT (C) 2009 - 2011, RT-Thread Development Team
5*10465441SEvalZero  *
6*10465441SEvalZero  * The license and distribution terms for this file may be
7*10465441SEvalZero  * found in the file LICENSE in this distribution or at
8*10465441SEvalZero  * http://www.rt-thread.org/license/LICENSE
9*10465441SEvalZero  *
10*10465441SEvalZero  * Change Logs:
11*10465441SEvalZero  * Date           Author       Notes
12*10465441SEvalZero  * 2011-02-23     Bernard      the first version
13*10465441SEvalZero  * 2012-03-03     xuzhenglim   modify for rx62N
14*10465441SEvalZero  */
15*10465441SEvalZero #include <rthw.h>
16*10465441SEvalZero #include <rtthread.h>
17*10465441SEvalZero 
18*10465441SEvalZero #include "cpuconfig.h"
19*10465441SEvalZero 
20*10465441SEvalZero #include "machine.h"
21*10465441SEvalZero #include "iorx62n.h"
22*10465441SEvalZero 
23*10465441SEvalZero #define ENTER_INTERRUPT()  ICU.SWINTR.BIT.SWINT = 1;
24*10465441SEvalZero 
25*10465441SEvalZero extern volatile rt_uint8_t rt_interrupt_nest;
26*10465441SEvalZero 
27*10465441SEvalZero 
28*10465441SEvalZero /* switch flag on interrupt and thread pointer to save switch record */
29*10465441SEvalZero rt_uint32_t rt_interrupt_from_thread;
30*10465441SEvalZero rt_uint32_t rt_interrupt_to_thread;
31*10465441SEvalZero rt_uint32_t rt_thread_switch_interrupt_flag;
32*10465441SEvalZero 
33*10465441SEvalZero 
34*10465441SEvalZero /* stack frame*/
35*10465441SEvalZero struct stack_frame
36*10465441SEvalZero {
37*10465441SEvalZero     rt_uint32_t ACCLO;
38*10465441SEvalZero     rt_uint32_t ACCHI;
39*10465441SEvalZero     rt_uint32_t FPSW;
40*10465441SEvalZero     rt_uint32_t R1;
41*10465441SEvalZero     rt_uint32_t R2;
42*10465441SEvalZero     rt_uint32_t R3;
43*10465441SEvalZero     rt_uint32_t R4;
44*10465441SEvalZero     rt_uint32_t R5;
45*10465441SEvalZero     rt_uint32_t R6;
46*10465441SEvalZero     rt_uint32_t R7;
47*10465441SEvalZero     rt_uint32_t R8;
48*10465441SEvalZero     rt_uint32_t R9;
49*10465441SEvalZero     rt_uint32_t R10;
50*10465441SEvalZero     rt_uint32_t R11;
51*10465441SEvalZero     rt_uint32_t R12;
52*10465441SEvalZero     rt_uint32_t R13;
53*10465441SEvalZero     rt_uint32_t R14;
54*10465441SEvalZero     rt_uint32_t R15;
55*10465441SEvalZero     //there is not R0 register,it is special for stack pointer
56*10465441SEvalZero     rt_uint32_t PC;
57*10465441SEvalZero     rt_uint32_t PSW;
58*10465441SEvalZero };
59*10465441SEvalZero 
60*10465441SEvalZero /**
61*10465441SEvalZero  * Initilial the threah stack.
62*10465441SEvalZero  *
63*10465441SEvalZero  * @author LXZ (2014/11/8)
64*10465441SEvalZero  *
65*10465441SEvalZero  * @param void* tentry
66*10465441SEvalZero  * @param void* parameter
67*10465441SEvalZero  * @param rt_uint8_t* stack_addr
68*10465441SEvalZero  * @param void* texit
69*10465441SEvalZero  *
70*10465441SEvalZero  * @return rt_uint8_t*
71*10465441SEvalZero  */
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)72*10465441SEvalZero rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
73*10465441SEvalZero                              rt_uint8_t *stack_addr, void *texit)
74*10465441SEvalZero {
75*10465441SEvalZero     unsigned long *stk;
76*10465441SEvalZero     struct stack_frame *stack_frame;
77*10465441SEvalZero     unsigned long       i;
78*10465441SEvalZero 
79*10465441SEvalZero     stk      = (unsigned long *)stack_addr;
80*10465441SEvalZero     *(stk)   = (unsigned long)texit;
81*10465441SEvalZero     stack_frame = (struct stack_frame *)(stack_addr - sizeof(struct stack_frame)) ;
82*10465441SEvalZero 
83*10465441SEvalZero     //Initilial all register
84*10465441SEvalZero     for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
85*10465441SEvalZero     {
86*10465441SEvalZero         ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
87*10465441SEvalZero     }
88*10465441SEvalZero 
89*10465441SEvalZero     stack_frame->PSW = (unsigned long)0x00030000 ;   /* psw */
90*10465441SEvalZero     stack_frame->PC = (unsigned long)tentry;        /* thread entery*/
91*10465441SEvalZero     stack_frame->R1 = (unsigned long )parameter;   /* r1 : parameter */
92*10465441SEvalZero     stack_frame->FPSW = 0x00000100;                  /* fpsw */
93*10465441SEvalZero 
94*10465441SEvalZero     return(rt_uint8_t *)stack_frame;
95*10465441SEvalZero }
96*10465441SEvalZero 
97*10465441SEvalZero #ifdef RT_USING_FINSH
98*10465441SEvalZero extern void list_thread(void);
99*10465441SEvalZero #endif
100*10465441SEvalZero extern rt_thread_t rt_current_thread;
101*10465441SEvalZero /**
102*10465441SEvalZero  * deal exception
103*10465441SEvalZero  *
104*10465441SEvalZero  * @author LXZ (2014/11/8)
105*10465441SEvalZero  *
106*10465441SEvalZero  * @param struct stack_frame* exception_contex
107*10465441SEvalZero  */
rt_hw_hard_fault_exception(struct stack_frame * exception_contex)108*10465441SEvalZero void rt_hw_hard_fault_exception(struct stack_frame* exception_contex)
109*10465441SEvalZero {
110*10465441SEvalZero     if (exception_contex != RT_NULL) {
111*10465441SEvalZero         rt_kprintf("psw: 0x%08x\n", exception_contex->PSW);
112*10465441SEvalZero         rt_kprintf("pc: 0x%08x\n", exception_contex->PC);
113*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R1);
114*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R2);
115*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R3);
116*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R4);
117*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R5);
118*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R6);
119*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R7);
120*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R8);
121*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R9);
122*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R10);
123*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R11);
124*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R12);
125*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R13);
126*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R14);
127*10465441SEvalZero         rt_kprintf("r0: 0x%08x\n", exception_contex->R15);
128*10465441SEvalZero         rt_kprintf("fpsw: 0x%08x\n", exception_contex->FPSW);
129*10465441SEvalZero         rt_kprintf("acchi: 0x%08x\n", exception_contex->ACCHI);
130*10465441SEvalZero         rt_kprintf("acclo: 0x%08x\n", exception_contex->ACCLO);
131*10465441SEvalZero     }
132*10465441SEvalZero         rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
133*10465441SEvalZero     #ifdef RT_USING_FINSH
134*10465441SEvalZero         list_thread();
135*10465441SEvalZero     #endif
136*10465441SEvalZero         while (1);
137*10465441SEvalZero 
138*10465441SEvalZero }
139*10465441SEvalZero 
140*10465441SEvalZero 
141*10465441SEvalZero /**
142*10465441SEvalZero  * switch thread in interrupt
143*10465441SEvalZero  *
144*10465441SEvalZero  * @author LXZ (2014/11/8)
145*10465441SEvalZero  *
146*10465441SEvalZero  * @param rt_uint32_t from
147*10465441SEvalZero  * @param rt_uint32_t to
148*10465441SEvalZero  */
rt_hw_context_switch(rt_uint32_t from,rt_uint32_t to)149*10465441SEvalZero void rt_hw_context_switch(rt_uint32_t from, rt_uint32_t to)
150*10465441SEvalZero {
151*10465441SEvalZero     if (rt_thread_switch_interrupt_flag == 0)
152*10465441SEvalZero     {
153*10465441SEvalZero         rt_thread_switch_interrupt_flag = 1;
154*10465441SEvalZero         rt_interrupt_from_thread = from;
155*10465441SEvalZero     }
156*10465441SEvalZero 
157*10465441SEvalZero     rt_interrupt_to_thread = to;
158*10465441SEvalZero     ENTER_INTERRUPT();
159*10465441SEvalZero }
160*10465441SEvalZero /**
161*10465441SEvalZero  * swithc thread out the interrupt
162*10465441SEvalZero  *
163*10465441SEvalZero  * @author LXZ (2014/11/8)
164*10465441SEvalZero  *
165*10465441SEvalZero  * @param rt_uint32_t from
166*10465441SEvalZero  * @param rt_uint32_t to
167*10465441SEvalZero  */
rt_hw_context_switch_interrupt(rt_uint32_t from,rt_uint32_t to)168*10465441SEvalZero void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to)
169*10465441SEvalZero {
170*10465441SEvalZero     if (rt_thread_switch_interrupt_flag == 0)
171*10465441SEvalZero     {
172*10465441SEvalZero         rt_thread_switch_interrupt_flag = 1;
173*10465441SEvalZero         rt_interrupt_from_thread = from;
174*10465441SEvalZero     }
175*10465441SEvalZero 
176*10465441SEvalZero     rt_interrupt_to_thread = to;
177*10465441SEvalZero     ENTER_INTERRUPT();
178*10465441SEvalZero }
179*10465441SEvalZero 
180*10465441SEvalZero /**
181*10465441SEvalZero  * shut down the chip
182*10465441SEvalZero  *
183*10465441SEvalZero  * @author LXZ (2014/11/8)
184*10465441SEvalZero  */
rt_hw_cpu_shutdown(void)185*10465441SEvalZero void rt_hw_cpu_shutdown(void)
186*10465441SEvalZero {
187*10465441SEvalZero     rt_kprintf("shutdown...\n");
188*10465441SEvalZero 
189*10465441SEvalZero     RT_ASSERT(0);
190*10465441SEvalZero }
191*10465441SEvalZero /**
192*10465441SEvalZero  * switch to the first thread,it just call one time
193*10465441SEvalZero  *
194*10465441SEvalZero  * @author LXZ (2014/11/8)
195*10465441SEvalZero  *
196*10465441SEvalZero  * @param rt_uint32_t to
197*10465441SEvalZero  */
rt_hw_context_switch_to(rt_uint32_t to)198*10465441SEvalZero void rt_hw_context_switch_to(rt_uint32_t to)
199*10465441SEvalZero {
200*10465441SEvalZero 
201*10465441SEvalZero     rt_interrupt_from_thread = 0;
202*10465441SEvalZero     rt_interrupt_to_thread = to;
203*10465441SEvalZero     rt_thread_switch_interrupt_flag = 1;
204*10465441SEvalZero     /* enable interrupt*/
205*10465441SEvalZero     _IEN( _ICU_SWINT ) = 1;
206*10465441SEvalZero 
207*10465441SEvalZero     /*clear the interrupt flag*/
208*10465441SEvalZero     _IR( _ICU_SWINT ) = 0;
209*10465441SEvalZero     _IPR( _ICU_SWINT ) = MAX_SYSCALL_INTERRUPT_PRIORITY + 1;
210*10465441SEvalZero 
211*10465441SEvalZero     /*touch the software interrupt*/
212*10465441SEvalZero     ENTER_INTERRUPT();
213*10465441SEvalZero     /*wait for first thread start up*/
214*10465441SEvalZero     while(1);
215*10465441SEvalZero }
216*10465441SEvalZero 
217