Line data Source code
1 1 : /*
2 : * Copyright (c) 2021 KT-Elektronik, Klaucke und Partner GmbH
3 : * Copyright (c) 2024 Renesas Electronics Corporation
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Renesas RX specific kernel interface header
10 : *
11 : * This header contains the Renesas RX specific kernel interface. It is
12 : * included by the kernel interface architecture-abstraction header
13 : * (include/zephyr/arch/cpu.h).
14 : */
15 :
16 : #ifndef ZEPHYR_INCLUDE_ARCH_RX_ARCH_H_
17 : #define ZEPHYR_INCLUDE_ARCH_RX_ARCH_H_
18 :
19 : /* Add include for DTS generated information */
20 : #include <zephyr/arch/exception.h>
21 : #include <zephyr/devicetree.h>
22 :
23 : #include <zephyr/arch/rx/thread.h>
24 : #include <zephyr/arch/rx/misc.h>
25 : #include <zephyr/arch/rx/arch_inlines.h>
26 : #include <zephyr/arch/rx/error.h>
27 : #include <zephyr/arch/common/sys_bitops.h>
28 : #include <zephyr/arch/common/sys_io.h>
29 : #include <zephyr/arch/common/ffs.h>
30 : #include <zephyr/sw_isr_table.h>
31 : #include <zephyr/kernel_structs.h>
32 : #include <zephyr/sys/__assert.h>
33 : #include <zephyr/sys/util.h>
34 : #include <zephyr/irq.h>
35 :
36 0 : #define ARCH_STACK_PTR_ALIGN 4
37 :
38 : #ifndef _ASMLANGUAGE
39 :
40 : #ifdef __cplusplus
41 : extern "C" {
42 : #endif
43 :
44 0 : #define REG(addr) *((uint8_t *)(addr))
45 :
46 : /* isr for undefined interrupts (results in a fatal error) */
47 : void z_irq_spurious(const void *unused);
48 : /* internal routine documented in C file, needed by IRQ_CONNECT() macro */
49 : extern void z_irq_priority_set(uint32_t irq, uint32_t prio, uint32_t flags);
50 :
51 : /* Z_ISR_DECLARE will populate the .intList section with the interrupt's
52 : * parameters, which will then be used by gen_irq_tables.py to create
53 : * the vector table and the software ISR table. This is all done at
54 : * build-time.
55 : *
56 : * We additionally set the priority in the interrupt controller at
57 : * runtime.
58 : */
59 0 : #define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
60 : { \
61 : Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
62 : z_irq_priority_set(irq_p, priority_p, flags_p); \
63 : }
64 :
65 : #if CONFIG_TRACING_ISR
66 : #define ARCH_ISR_DIRECT_HEADER() \
67 : { \
68 : _kernel.cpus[0].nested++; \
69 : sys_trace_isr_enter(); \
70 : }
71 : #else
72 0 : #define ARCH_ISR_DIRECT_HEADER() \
73 : { \
74 : _kernel.cpus[0].nested++; \
75 : }
76 : #endif
77 :
78 : #if CONFIG_TRACING_ISR
79 : #define ARCH_ISR_DIRECT_FOOTER(check_reschedule) \
80 : { \
81 : if (IS_ENABLED(CONFIG_STACK_SENTINEL)) { \
82 : z_check_stack_sentinel(); \
83 : } \
84 : sys_trace_isr_exit(); \
85 : irq_lock(); \
86 : if (check_reschedule && _kernel.cpus[0].nested == 1) { \
87 : if (_kernel.cpus->current->base.prio >= 0 || \
88 : CONFIG_NUM_METAIRQ_PRIORITIES > 0) { \
89 : if (_kernel.ready_q.cache != _kernel.cpus->current) { \
90 : z_rx_irq_exit(); \
91 : } \
92 : } \
93 : } \
94 : _kernel.cpus[0].nested--; \
95 : }
96 : #else
97 0 : #define ARCH_ISR_DIRECT_FOOTER(check_reschedule) \
98 : { \
99 : if (IS_ENABLED(CONFIG_STACK_SENTINEL)) { \
100 : z_check_stack_sentinel(); \
101 : } \
102 : irq_lock(); \
103 : if (check_reschedule && _kernel.cpus[0].nested == 1) { \
104 : if (_kernel.cpus->current->base.prio >= 0 || \
105 : CONFIG_NUM_METAIRQ_PRIORITIES > 0) { \
106 : if (_kernel.ready_q.cache != _kernel.cpus->current) { \
107 : z_rx_irq_exit(); \
108 : } \
109 : } \
110 : } \
111 : _kernel.cpus[0].nested--; \
112 : }
113 : #endif
114 :
115 0 : static ALWAYS_INLINE unsigned int arch_irq_lock(void)
116 : {
117 : uint32_t key;
118 : /* deactivate interrupts by clearing the PSW-i flag */
119 : __asm__ volatile("MVFC psw, %0\n"
120 : "CLRPSW i"
121 : : "=r"(key)
122 : :
123 : : "cc");
124 : /* return the value of the i-flag before clearing
125 : * if irqs were locked already, it was 0 and calling
126 : * arch_irq_unlock(key) will not actually unlock irqs, as this was a
127 : * nested irq lock
128 : */
129 : return key & BIT(16);
130 : }
131 :
132 0 : static inline void arch_irq_unlock(unsigned int key)
133 : {
134 : if (key != 0) {
135 : /* re-activate interrupts by setting the PSW i-flag*/
136 : __asm__ volatile("SETPSW i" ::: "cc");
137 : }
138 : }
139 :
140 0 : static inline bool arch_irq_unlocked(unsigned int key)
141 : {
142 : return key != 0;
143 : }
144 :
145 0 : static ALWAYS_INLINE _cpu_t *arch_curr_cpu(void)
146 : {
147 : return &_kernel.cpus[0];
148 : }
149 :
150 : #ifdef __cplusplus
151 : }
152 : #endif
153 :
154 : #endif /* !_ASMLANGUAGE */
155 :
156 : #endif /* ZEPHYR_INCLUDE_ARCH_RX_ARCH_H_ */
|