1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2018 Intel Corporation. All rights reserved.
4  *
5  * Author: Rander Wang <rander.wang@linux.intel.com>
6  */
7 
8 #ifdef __SOF_LIB_CPU_H__
9 
10 #ifndef __ARCH_LIB_CPU_H__
11 #define __ARCH_LIB_CPU_H__
12 
13 #include <xtensa/config/core-isa.h>
14 #include <stdint.h>
15 
16 #if CONFIG_MULTICORE
17 
18 /** \brief CPU power down available flags */
19 #define CPU_POWER_DOWN_MEMORY_ON	BIT(0) /**< Power down core with memory
20 						 *  enabled (required in d0ix
21 						 *  flow)
22 						 */
23 
24 void cpu_power_down_core(uint32_t flags);
25 
26 void cpu_alloc_core_context(int id);
27 
28 int arch_cpu_enable_core(int id);
29 
30 void arch_cpu_disable_core(int id);
31 
32 int arch_cpu_is_core_enabled(int id);
33 
34 int arch_cpu_enabled_cores(void);
35 
36 int arch_cpu_restore_secondary_cores(void);
37 
38 int arch_cpu_secondary_cores_prepare_d0ix(void);
39 
40 #else
41 
arch_cpu_enable_core(int id)42 static inline int arch_cpu_enable_core(int id) { return 0; }
43 
arch_cpu_disable_core(int id)44 static inline void arch_cpu_disable_core(int id) { }
45 
arch_cpu_is_core_enabled(int id)46 static inline int arch_cpu_is_core_enabled(int id) { return 1; }
47 
arch_cpu_enabled_cores(void)48 static inline int arch_cpu_enabled_cores(void) { return 1; }
49 
arch_cpu_restore_secondary_cores(void)50 static inline int arch_cpu_restore_secondary_cores(void) {return 0; }
51 
arch_cpu_secondary_cores_prepare_d0ix(void)52 static inline int arch_cpu_secondary_cores_prepare_d0ix(void) {return 0; }
53 
54 #endif
55 
arch_cpu_get_id(void)56 static inline int arch_cpu_get_id(void)
57 {
58 	int prid;
59 #if XCHAL_HAVE_PRID
60 	__asm__("rsr.prid %0" : "=a"(prid));
61 #else
62 	prid = PLATFORM_PRIMARY_CORE_ID;
63 #endif
64 	return prid;
65 }
66 
67 #if !XCHAL_HAVE_THREADPTR
68 extern unsigned int _virtual_thread_start;
69 static unsigned int *virtual_thread_ptr =
70 	(unsigned int *)&_virtual_thread_start;
71 #endif
72 
cpu_write_threadptr(int threadptr)73 static inline void cpu_write_threadptr(int threadptr)
74 {
75 #if XCHAL_HAVE_THREADPTR
76 	__asm__ __volatile__(
77 		"wur.threadptr %0" : : "a" (threadptr) : "memory");
78 #else
79 	*virtual_thread_ptr = threadptr;
80 #endif
81 }
82 
cpu_read_threadptr(void)83 static inline int cpu_read_threadptr(void)
84 {
85 	int threadptr;
86 #if XCHAL_HAVE_THREADPTR
87 	__asm__ __volatile__(
88 		"rur.threadptr %0" : "=a"(threadptr));
89 #else
90 	threadptr = *virtual_thread_ptr;
91 #endif
92 	return threadptr;
93 }
94 
cpu_read_vecbase(void)95 static inline int cpu_read_vecbase(void)
96 {
97 	int vecbase;
98 
99 	__asm__ __volatile__("rsr.vecbase %0"
100 		: "=a"(vecbase));
101 	return vecbase;
102 }
103 
cpu_read_excsave2(void)104 static inline int cpu_read_excsave2(void)
105 {
106 	int excsave2;
107 
108 	__asm__ __volatile__("rsr.excsave2 %0"
109 		: "=a"(excsave2));
110 	return excsave2;
111 }
112 
cpu_read_excsave3(void)113 static inline int cpu_read_excsave3(void)
114 {
115 	int excsave3;
116 
117 	__asm__ __volatile__("rsr.excsave3 %0"
118 		: "=a"(excsave3));
119 	return excsave3;
120 }
121 
cpu_read_excsave4(void)122 static inline int cpu_read_excsave4(void)
123 {
124 	int excsave4;
125 
126 	__asm__ __volatile__("rsr.excsave4 %0"
127 		: "=a"(excsave4));
128 	return excsave4;
129 }
130 
cpu_read_excsave5(void)131 static inline int cpu_read_excsave5(void)
132 {
133 	int excsave5;
134 
135 	__asm__ __volatile__("rsr.excsave5 %0"
136 		: "=a"(excsave5));
137 	return excsave5;
138 }
139 
140 #endif /* __ARCH_LIB_CPU_H__ */
141 
142 #else
143 
144 #error "This file shouldn't be included from outside of sof/lib/cpu.h"
145 
146 #endif /* __SOF_LIB_CPU_H__ */
147