1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18 #ifndef CORE_H
19 #define CORE_H
20 #include "nds_intrinsic.h"
21 #include "sys.h"
22
23 #define read_csr(reg) __nds__csrr(reg)
24 #define write_csr(reg, val) __nds__csrw(val, reg)
25 #define swap_csr(reg, val) __nds__csrrw(val, reg)
26 #define set_csr(reg, bit) __nds__csrrs(bit, reg)
27 #define clear_csr(reg, bit) __nds__csrrc(bit, reg)
28
29 /*
30 * Inline nested interrupt entry/exit macros
31 */
32 /* Svae/Restore macro */
33 #define save_csr(r) long __##r = read_csr(r)
34 #define restore_csr(r) write_csr(r, __##r)
35 /* Support PowerBrake (Performance Throttling) feature */
36
37 #define save_mxstatus() save_csr(NDS_MXSTATUS)
38 #define restore_mxstatus() restore_csr(NDS_MXSTATUS)
39
40 /* Nested IRQ entry macro : Save CSRs and enable global interrupt. */
41 #define core_save_nested_context() \
42 save_csr(NDS_MEPC); save_csr(NDS_MSTATUS); save_mxstatus(); set_csr(NDS_MSTATUS, 1 << 3)
43
44 /* Nested IRQ exit macro : Restore CSRs */
45 #define core_restore_nested_context() \
46 clear_csr(NDS_MSTATUS, 1 << 3); \
47 restore_csr(NDS_MSTATUS); restore_csr(NDS_MEPC); restore_mxstatus()
48
49 #define fence_iorw __nds__fence(FENCE_IORW, FENCE_IORW)
50
51 typedef enum {
52 FLD_FEATURE_PREEMPT_PRIORITY_INT_EN = BIT(0),
53 FLD_FEATURE_VECTOR_MODE_EN = BIT(1),
54 } feature_e;
55
56 /**
57 * @brief Disable interrupts globally in the system.external, timer and software interrupts.
58 * @return r - the value of machine interrupt enable(MIE) register.
59 * @note this function must be used when the system wants to disable all the interrupt.
60 */
core_interrupt_disable(void)61 static inline unsigned int core_interrupt_disable(void)
62 {
63 unsigned int r = read_csr(NDS_MIE);
64 clear_csr(NDS_MIE, BIT(3) | BIT(7) | BIT(11));
65 return r;
66 }
67
68 /**
69 * @brief restore interrupts globally in the system. external,timer and software interrupts.
70 * @param[in] en - the value of machine interrupt enable(MIE) register before disable.
71 * @return 0
72 * @note this function must be used when the system wants to restore all the interrupt.
73 */
core_restore_interrupt(unsigned int en)74 static inline unsigned int core_restore_interrupt(unsigned int en)
75 {
76 set_csr(NDS_MIE, en);
77 return 0;
78 }
79
80 /**
81 * @brief enable interrupts globally in the system.
82 * @return none
83 */
core_interrupt_enable(void)84 static inline void core_interrupt_enable(void)
85 {
86 set_csr(NDS_MSTATUS, 1 << 3);
87 set_csr(NDS_MIE, (1 << 11) | (1 << 7) | (1 << 3));
88 }
89 #endif
90