1 /*
2  * Copyright (c) 2016 Cadence Design Systems, Inc.
3  * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_
9 #define ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_
10 
11 #ifndef _ASMLANGUAGE
12 
13 #include <zephyr/kernel_structs.h>
14 #include <zephyr/zsr.h>
15 
16 /**
17  * @brief Read a special register.
18  *
19  * @param sr Name of special register.
20  *
21  * @return Value of special register.
22  */
23 #define XTENSA_RSR(sr) \
24 	({uint32_t v; \
25 	 __asm__ volatile ("rsr." sr " %0" : "=a"(v)); \
26 	 v; })
27 
28 /**
29  * @brief Write to a special register.
30  *
31  * @param sr Name of special register.
32  * @param v Value to be written to special register.
33  */
34 #define XTENSA_WSR(sr, v) \
35 	do { \
36 		__asm__ volatile ("wsr." sr " %0" : : "r"(v)); \
37 	} while (false)
38 
39 /**
40  * @brief Read a user register.
41  *
42  * @param ur Name of user register.
43  *
44  * @return Value of user register.
45  */
46 #define XTENSA_RUR(ur) \
47 	({uint32_t v; \
48 	 __asm__ volatile ("rur." ur " %0" : "=a"(v)); \
49 	 v; })
50 
51 /**
52  * @brief Write to a user register.
53  *
54  * @param ur Name of user register.
55  * @param v Value to be written to user register.
56  */
57 #define XTENSA_WUR(ur, v) \
58 	do { \
59 		__asm__ volatile ("wur." ur " %0" : : "r"(v)); \
60 	} while (false)
61 
62 /** Implementation of @ref arch_curr_cpu. */
arch_curr_cpu(void)63 static ALWAYS_INLINE _cpu_t *arch_curr_cpu(void)
64 {
65 	_cpu_t *cpu;
66 
67 	cpu = (_cpu_t *)XTENSA_RSR(ZSR_CPU_STR);
68 
69 	return cpu;
70 }
71 
72 /** Implementation of @ref arch_proc_id. */
arch_proc_id(void)73 static ALWAYS_INLINE uint32_t arch_proc_id(void)
74 {
75 	uint32_t prid;
76 
77 	__asm__ volatile("rsr %0, PRID" : "=r"(prid));
78 	return prid;
79 }
80 
81 #ifdef CONFIG_SOC_HAS_RUNTIME_NUM_CPUS
82 extern unsigned int soc_num_cpus;
83 #endif
84 
85 /** Implementation of @ref arch_num_cpus. */
arch_num_cpus(void)86 static ALWAYS_INLINE unsigned int arch_num_cpus(void)
87 {
88 #ifdef CONFIG_SOC_HAS_RUNTIME_NUM_CPUS
89 	return soc_num_cpus;
90 #else
91 	return CONFIG_MP_MAX_NUM_CPUS;
92 #endif
93 }
94 
95 #endif /* !_ASMLANGUAGE */
96 
97 #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_ */
98