1 /*
2  * Copyright (c) 2018, Synopsys, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <rtthread.h>
7 
8 #include "arc/arc_exception.h"
9 
10 #if ARC_FEATURE_STACK_CHECK
11 #define ARC_INIT_STATUS ((1 << AUX_STATUS_BIT_SC) | AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE)
12 #else
13 #define ARC_INIT_STATUS (AUX_STATUS_MASK_IE | ((-1 - INT_PRI_MIN) << 1) | STATUS32_RESET_VALUE)
14 #endif
15 
16 extern void start_r(void);
17 
18 
19 rt_uint32_t rt_thread_switch_interrupt_flag;
20 rt_uint32_t rt_interrupt_from_thread;
21 rt_uint32_t rt_interrupt_to_thread;
22 rt_uint32_t exc_nest_count;
23 
24 struct init_stack_frame {
25     rt_uint32_t pc;
26     rt_uint32_t blink;
27     rt_uint32_t task;
28     rt_uint32_t status32;
29     rt_uint32_t r0;
30 };
31 
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)32 rt_uint8_t *rt_hw_stack_init(void       *tentry,
33                              void       *parameter,
34                              rt_uint8_t *stack_addr,
35                              void       *texit)
36 {
37     struct init_stack_frame *stack_frame;
38     rt_uint8_t         *stk;
39 
40     stk  = stack_addr + sizeof(rt_uint32_t);
41     stk  = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
42     stk -= sizeof(struct init_stack_frame);
43 
44     stack_frame = (struct init_stack_frame *)stk;
45 
46     stack_frame->pc = (rt_uint32_t)start_r;
47     stack_frame->blink = (rt_uint32_t)texit;
48     stack_frame->task = (rt_uint32_t)tentry;
49     stack_frame->status32 = ARC_INIT_STATUS;
50     stack_frame->r0 = (rt_uint32_t)parameter;
51 
52     return stk;
53 }
54 
55 
56 /**
57  * This function set the hook, which is invoked on fault exception handling.
58  *
59  * @param exception_handle the exception handling hook function.
60  */
rt_hw_exception_install(rt_err_t (* exception_handle)(void * context))61 void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
62 {
63     exception_handle = exception_handle;
64 }
65 
set_hw_stack_check(rt_uint32_t * from,rt_uint32_t * to)66 void set_hw_stack_check(rt_uint32_t *from, rt_uint32_t *to)
67 {
68     struct rt_thread *rt_thread_to;
69     if (to != NULL) {
70         rt_thread_to = rt_container_of(to, struct rt_thread, sp);
71 #if ARC_FEATURE_SEC_PRESENT
72         arc_aux_write(AUX_S_KSTACK_TOP, (uint32_t)(rt_thread_to->stack_addr));
73         arc_aux_write(AUX_S_KSTACK_BASE, (uint32_t)(rt_thread_to->stack_addr)+rt_thread_to->stack_size);
74 #else
75         arc_aux_write(AUX_KSTACK_TOP, (uint32_t)(rt_thread_to->stack_addr));
76         arc_aux_write(AUX_KSTACK_BASE, (uint32_t)(rt_thread_to->stack_addr)+rt_thread_to->stack_size);
77 #endif
78     }
79 }
80