blob: c0c3a199ba3e88024058e6b0e8a5d978d55f67aa [file] [log] [blame]
Andrew Thoelke8c28fe02014-06-02 11:40:35 +01001/*
Soby Mathewa0fedc42016-06-16 14:52:04 +01002 * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
Andrew Thoelke8c28fe02014-06-02 11:40:35 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Andrew Thoelke8c28fe02014-06-02 11:40:35 +01005 */
6
7#ifndef __CPU_DATA_H__
8#define __CPU_DATA_H__
9
Etienne Carriere97ad6ce2017-09-01 10:22:20 +020010#include <platform_def.h> /* CACHE_WRITEBACK_GRANULE required */
11
Soby Mathew748be1d2016-05-05 14:10:46 +010012#ifdef AARCH32
13
14#if CRASH_REPORTING
15#error "Crash reporting is not supported in AArch32"
16#endif
17#define CPU_DATA_CPU_OPS_PTR 0x0
Etienne Carriere97ad6ce2017-09-01 10:22:20 +020018#define CPU_DATA_CRASH_BUF_OFFSET 0x4
Soby Mathew748be1d2016-05-05 14:10:46 +010019
20#else /* AARCH32 */
21
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010022/* Offsets for the cpu_data structure */
Soby Mathew523d6332015-01-08 18:02:19 +000023#define CPU_DATA_CRASH_BUF_OFFSET 0x18
Soby Mathew748be1d2016-05-05 14:10:46 +010024/* need enough space in crash buffer to save 8 registers */
25#define CPU_DATA_CRASH_BUF_SIZE 64
26#define CPU_DATA_CPU_OPS_PTR 0x10
27
28#endif /* AARCH32 */
29
Soby Mathewc1adbbc2014-06-25 10:07:40 +010030#if CRASH_REPORTING
dp-arm3cac7862016-09-19 11:18:44 +010031#define CPU_DATA_CRASH_BUF_END (CPU_DATA_CRASH_BUF_OFFSET + \
32 CPU_DATA_CRASH_BUF_SIZE)
Soby Mathewc1adbbc2014-06-25 10:07:40 +010033#else
dp-arm3cac7862016-09-19 11:18:44 +010034#define CPU_DATA_CRASH_BUF_END CPU_DATA_CRASH_BUF_OFFSET
Soby Mathewc1adbbc2014-06-25 10:07:40 +010035#endif
Soby Mathewc704cbc2014-08-14 11:33:56 +010036
Etienne Carriere97ad6ce2017-09-01 10:22:20 +020037/* cpu_data size is the data size rounded up to the platform cache line size */
38#define CPU_DATA_SIZE (((CPU_DATA_CRASH_BUF_END + \
39 CACHE_WRITEBACK_GRANULE - 1) / \
40 CACHE_WRITEBACK_GRANULE) * \
41 CACHE_WRITEBACK_GRANULE)
42
dp-arm3cac7862016-09-19 11:18:44 +010043#if ENABLE_RUNTIME_INSTRUMENTATION
44/* Temporary space to store PMF timestamps from assembly code */
45#define CPU_DATA_PMF_TS_COUNT 1
46#define CPU_DATA_PMF_TS0_OFFSET CPU_DATA_CRASH_BUF_END
47#define CPU_DATA_PMF_TS0_IDX 0
48#endif
49
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010050#ifndef __ASSEMBLY__
51
52#include <arch_helpers.h>
Soby Mathew523d6332015-01-08 18:02:19 +000053#include <cassert.h>
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010054#include <platform_def.h>
Achin Guptaf3ccbab2014-07-25 14:52:47 +010055#include <psci.h>
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010056#include <stdint.h>
57
Soby Mathew523d6332015-01-08 18:02:19 +000058/* Offsets for the cpu_data structure */
59#define CPU_DATA_PSCI_LOCK_OFFSET __builtin_offsetof\
60 (cpu_data_t, psci_svc_cpu_data.pcpu_bakery_info)
61
62#if PLAT_PCPU_DATA_SIZE
63#define CPU_DATA_PLAT_PCPU_OFFSET __builtin_offsetof\
64 (cpu_data_t, platform_cpu_data)
65#endif
66
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010067/*******************************************************************************
68 * Function & variable prototypes
69 ******************************************************************************/
70
71/*******************************************************************************
72 * Cache of frequently used per-cpu data:
Andrew Thoelkec02dbd62014-06-02 10:00:25 +010073 * Pointers to non-secure and secure security state contexts
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010074 * Address of the crash stack
75 * It is aligned to the cache line boundary to allow efficient concurrent
76 * manipulation of these pointers on different cpus
77 *
78 * TODO: Add other commonly used variables to this (tf_issues#90)
79 *
80 * The data structure and the _cpu_data accessors should not be used directly
81 * by components that have per-cpu members. The member access macros should be
82 * used for this.
83 ******************************************************************************/
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010084typedef struct cpu_data {
Soby Mathew748be1d2016-05-05 14:10:46 +010085#ifndef AARCH32
Andrew Thoelkec02dbd62014-06-02 10:00:25 +010086 void *cpu_context[2];
Soby Mathew748be1d2016-05-05 14:10:46 +010087#endif
Soby Mathewa0fedc42016-06-16 14:52:04 +010088 uintptr_t cpu_ops_ptr;
Soby Mathewc1adbbc2014-06-25 10:07:40 +010089#if CRASH_REPORTING
Soby Mathewa0fedc42016-06-16 14:52:04 +010090 u_register_t crash_buf[CPU_DATA_CRASH_BUF_SIZE >> 3];
Soby Mathewc1adbbc2014-06-25 10:07:40 +010091#endif
dp-arm3cac7862016-09-19 11:18:44 +010092#if ENABLE_RUNTIME_INSTRUMENTATION
93 uint64_t cpu_data_pmf_ts[CPU_DATA_PMF_TS_COUNT];
94#endif
Soby Mathew523d6332015-01-08 18:02:19 +000095 struct psci_cpu_data psci_svc_cpu_data;
96#if PLAT_PCPU_DATA_SIZE
97 uint8_t platform_cpu_data[PLAT_PCPU_DATA_SIZE];
98#endif
Andrew Thoelke8c28fe02014-06-02 11:40:35 +010099} __aligned(CACHE_WRITEBACK_GRANULE) cpu_data_t;
100
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100101#if CRASH_REPORTING
102/* verify assembler offsets match data structures */
103CASSERT(CPU_DATA_CRASH_BUF_OFFSET == __builtin_offsetof
104 (cpu_data_t, crash_buf),
105 assert_cpu_data_crash_stack_offset_mismatch);
106#endif
107
Etienne Carriere97ad6ce2017-09-01 10:22:20 +0200108CASSERT(CPU_DATA_SIZE == sizeof(cpu_data_t),
109 assert_cpu_data_size_mismatch);
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100110
Soby Mathewc704cbc2014-08-14 11:33:56 +0100111CASSERT(CPU_DATA_CPU_OPS_PTR == __builtin_offsetof
112 (cpu_data_t, cpu_ops_ptr),
113 assert_cpu_data_cpu_ops_ptr_offset_mismatch);
114
dp-arm3cac7862016-09-19 11:18:44 +0100115#if ENABLE_RUNTIME_INSTRUMENTATION
116CASSERT(CPU_DATA_PMF_TS0_OFFSET == __builtin_offsetof
117 (cpu_data_t, cpu_data_pmf_ts[0]),
118 assert_cpu_data_pmf_ts0_offset_mismatch);
119#endif
120
Andrew Thoelke8c28fe02014-06-02 11:40:35 +0100121struct cpu_data *_cpu_data_by_index(uint32_t cpu_index);
Andrew Thoelke8c28fe02014-06-02 11:40:35 +0100122
Soby Mathew748be1d2016-05-05 14:10:46 +0100123#ifndef AARCH32
Andrew Thoelke8c28fe02014-06-02 11:40:35 +0100124/* Return the cpu_data structure for the current CPU. */
125static inline struct cpu_data *_cpu_data(void)
126{
127 return (cpu_data_t *)read_tpidr_el3();
128}
Soby Mathew748be1d2016-05-05 14:10:46 +0100129#else
130struct cpu_data *_cpu_data(void);
131#endif
Andrew Thoelke8c28fe02014-06-02 11:40:35 +0100132
133/**************************************************************************
134 * APIs for initialising and accessing per-cpu data
135 *************************************************************************/
136
137void init_cpu_data_ptr(void);
Vikram Kanigiri9b38fc82015-01-29 18:27:38 +0000138void init_cpu_ops(void);
Andrew Thoelke8c28fe02014-06-02 11:40:35 +0100139
140#define get_cpu_data(_m) _cpu_data()->_m
141#define set_cpu_data(_m, _v) _cpu_data()->_m = _v
142#define get_cpu_data_by_index(_ix, _m) _cpu_data_by_index(_ix)->_m
143#define set_cpu_data_by_index(_ix, _m, _v) _cpu_data_by_index(_ix)->_m = _v
Andrew Thoelke8c28fe02014-06-02 11:40:35 +0100144
Soby Mathew24ab34f2016-05-03 17:11:42 +0100145#define flush_cpu_data(_m) flush_dcache_range((uintptr_t) \
Achin Guptae4b9fa42014-07-25 14:47:05 +0100146 &(_cpu_data()->_m), \
147 sizeof(_cpu_data()->_m))
Soby Mathew24ab34f2016-05-03 17:11:42 +0100148#define inv_cpu_data(_m) inv_dcache_range((uintptr_t) \
Soby Mathew85dbf5a2015-04-07 12:16:56 +0100149 &(_cpu_data()->_m), \
150 sizeof(_cpu_data()->_m))
Soby Mathew7d861ea2014-11-18 10:14:14 +0000151#define flush_cpu_data_by_index(_ix, _m) \
Soby Mathewa0fedc42016-06-16 14:52:04 +0100152 flush_dcache_range((uintptr_t) \
Soby Mathew7d861ea2014-11-18 10:14:14 +0000153 &(_cpu_data_by_index(_ix)->_m), \
154 sizeof(_cpu_data_by_index(_ix)->_m))
Achin Guptae4b9fa42014-07-25 14:47:05 +0100155
Andrew Thoelke8c28fe02014-06-02 11:40:35 +0100156
157#endif /* __ASSEMBLY__ */
158#endif /* __CPU_DATA_H__ */