xref: /rk3399_ARM-atf/include/lib/el3_runtime/cpu_data.h (revision 937108a04a998c9e6d6ce5734bf62c7eb8c9d42c)
1 /*
2  * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef __CPU_DATA_H__
32 #define __CPU_DATA_H__
33 
34 #ifdef AARCH32
35 
36 #if CRASH_REPORTING
37 #error "Crash reporting is not supported in AArch32"
38 #endif
39 #define CPU_DATA_CPU_OPS_PTR		0x0
40 
41 #else /* AARCH32 */
42 
43 /* Offsets for the cpu_data structure */
44 #define CPU_DATA_CRASH_BUF_OFFSET	0x18
45 /* need enough space in crash buffer to save 8 registers */
46 #define CPU_DATA_CRASH_BUF_SIZE		64
47 #define CPU_DATA_CPU_OPS_PTR		0x10
48 
49 #endif /* AARCH32 */
50 
51 #if CRASH_REPORTING
52 #define CPU_DATA_LOG2SIZE		7
53 #else
54 #define CPU_DATA_LOG2SIZE		6
55 #endif
56 
57 #ifndef __ASSEMBLY__
58 
59 #include <arch_helpers.h>
60 #include <cassert.h>
61 #include <platform_def.h>
62 #include <psci.h>
63 #include <stdint.h>
64 
65 /* Offsets for the cpu_data structure */
66 #define CPU_DATA_PSCI_LOCK_OFFSET	__builtin_offsetof\
67 		(cpu_data_t, psci_svc_cpu_data.pcpu_bakery_info)
68 
69 #if PLAT_PCPU_DATA_SIZE
70 #define CPU_DATA_PLAT_PCPU_OFFSET	__builtin_offsetof\
71 		(cpu_data_t, platform_cpu_data)
72 #endif
73 
74 /*******************************************************************************
75  * Function & variable prototypes
76  ******************************************************************************/
77 
78 /*******************************************************************************
79  * Cache of frequently used per-cpu data:
80  *   Pointers to non-secure and secure security state contexts
81  *   Address of the crash stack
82  * It is aligned to the cache line boundary to allow efficient concurrent
83  * manipulation of these pointers on different cpus
84  *
85  * TODO: Add other commonly used variables to this (tf_issues#90)
86  *
87  * The data structure and the _cpu_data accessors should not be used directly
88  * by components that have per-cpu members. The member access macros should be
89  * used for this.
90  ******************************************************************************/
91 typedef struct cpu_data {
92 #ifndef AARCH32
93 	void *cpu_context[2];
94 #endif
95 	uintptr_t cpu_ops_ptr;
96 #if CRASH_REPORTING
97 	u_register_t crash_buf[CPU_DATA_CRASH_BUF_SIZE >> 3];
98 #endif
99 	struct psci_cpu_data psci_svc_cpu_data;
100 #if PLAT_PCPU_DATA_SIZE
101 	uint8_t platform_cpu_data[PLAT_PCPU_DATA_SIZE];
102 #endif
103 } __aligned(CACHE_WRITEBACK_GRANULE) cpu_data_t;
104 
105 #if CRASH_REPORTING
106 /* verify assembler offsets match data structures */
107 CASSERT(CPU_DATA_CRASH_BUF_OFFSET == __builtin_offsetof
108 	(cpu_data_t, crash_buf),
109 	assert_cpu_data_crash_stack_offset_mismatch);
110 #endif
111 
112 CASSERT((1 << CPU_DATA_LOG2SIZE) == sizeof(cpu_data_t),
113 	assert_cpu_data_log2size_mismatch);
114 
115 CASSERT(CPU_DATA_CPU_OPS_PTR == __builtin_offsetof
116 		(cpu_data_t, cpu_ops_ptr),
117 		assert_cpu_data_cpu_ops_ptr_offset_mismatch);
118 
119 struct cpu_data *_cpu_data_by_index(uint32_t cpu_index);
120 
121 #ifndef AARCH32
122 /* Return the cpu_data structure for the current CPU. */
123 static inline struct cpu_data *_cpu_data(void)
124 {
125 	return (cpu_data_t *)read_tpidr_el3();
126 }
127 #else
128 struct cpu_data *_cpu_data(void);
129 #endif
130 
131 /**************************************************************************
132  * APIs for initialising and accessing per-cpu data
133  *************************************************************************/
134 
135 void init_cpu_data_ptr(void);
136 void init_cpu_ops(void);
137 
138 #define get_cpu_data(_m)		   _cpu_data()->_m
139 #define set_cpu_data(_m, _v)		   _cpu_data()->_m = _v
140 #define get_cpu_data_by_index(_ix, _m)	   _cpu_data_by_index(_ix)->_m
141 #define set_cpu_data_by_index(_ix, _m, _v) _cpu_data_by_index(_ix)->_m = _v
142 
143 #define flush_cpu_data(_m)	   flush_dcache_range((uintptr_t)	  \
144 						      &(_cpu_data()->_m), \
145 						      sizeof(_cpu_data()->_m))
146 #define inv_cpu_data(_m)	   inv_dcache_range((uintptr_t)	  	  \
147 						      &(_cpu_data()->_m), \
148 						      sizeof(_cpu_data()->_m))
149 #define flush_cpu_data_by_index(_ix, _m)	\
150 				   flush_dcache_range((uintptr_t)	  \
151 					 &(_cpu_data_by_index(_ix)->_m),  \
152 					 sizeof(_cpu_data_by_index(_ix)->_m))
153 
154 
155 #endif /* __ASSEMBLY__ */
156 #endif /* __CPU_DATA_H__ */
157