blob: c8b785ccb1aa341eb47ae0d7394a85940bc37374 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +00002 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef __PLATFORM_H__
8#define __PLATFORM_H__
9
10#include <stdint.h>
J-Alves79c08f12021-10-27 15:15:16 +010011#include <arch_helpers.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020012#include <timer.h>
13#include <xlat_tables_v2.h>
14
15#define PLAT_PSCI_DUMMY_STATE_ID 0xF
16
17#define PWR_STATE_INIT_INDEX (-1)
18
19#define INIT_PWR_LEVEL_INDEX(array_name) \
20 do { \
21 unsigned int var; \
22 assert(ARRAY_SIZE(array_name) == (PLAT_MAX_PWR_LEVEL + 1)); \
23 for (var = 0; var <= PLAT_MAX_PWR_LEVEL; var++) \
24 array_name[var] = PWR_STATE_INIT_INDEX; \
25 } while (0)
26
27/*
28 * The platform structure to represent the valid local power state
29 * properties for a particular affinity level. The platform needs to
30 * export the array of valid local low power states for each affinity level
31 * it supports which can be queried by TFTF tests to construct the required
32 * composite power state.
33 *
34 * TODO: Currently the power levels are identity mapped to affinity level in
35 * TFTF which need to be decoupled.
36 */
37typedef struct plat_state_prop {
38 /*
39 * This field has a value in the increasing order of the suspend
40 * depth. Deeper the suspend state, higher the value.
41 */
42 unsigned int suspend_depth;
43 /* The local state ID for the idle state at this level. */
44 unsigned int state_ID;
45 /* Flag which indicates whether is a retention or power down state */
46 unsigned int is_pwrdown;
47} plat_state_prop_t;
48
49void tftf_plat_arch_setup(void);
50void tftf_early_platform_setup(void);
51void tftf_platform_setup(void);
52
53void tftf_plat_enable_mmu(void);
54void tftf_plat_configure_mmu(void);
55
56void tftf_platform_end(void);
57void tftf_platform_watchdog_set(void);
58void tftf_platform_watchdog_reset(void);
59
Antonio Nino Diaz1cf45c92018-10-15 09:03:43 +010060/* Helper that returns a linear core ID from a MPID */
61unsigned int platform_get_core_pos(u_register_t mpid);
62
63/* Crash console functions */
64int plat_crash_console_init(void);
65int plat_crash_console_putc(int c);
66int plat_crash_console_flush(void);
67
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020068/* Gets a handle for the initialised IO entity */
69void plat_get_nvm_handle(uintptr_t *handle);
70
71/*
72 * Returns the platform topology description array. The size of this
73 * array should be PLATFORM_NUM_AFFS - PLATFORM_CORE_COUNT + 1.
74 */
75const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void);
76
77/*
78 * Function to query the MPIDR of a CPU identified by 'core_pos' which is
79 * the number returned by platform_get_core() API.
80 * In case the CPU is absent, then this API returns INVALID_MPID. This
81 * function will be queried only during topology setup in TFTF and thereafter
82 * the internal node data will be used to get the MPIDR corresponding
83 * to the 'core_pos'.
84 */
85uint64_t tftf_plat_get_mpidr(unsigned int core_pos);
86
87/*
88 * Get the state property array for all the valid states from platform for
89 * a specified 'level'. The array is expected to be NULL terminated after the
90 * last entry.
91 */
92const plat_state_prop_t *plat_get_state_prop(unsigned int level);
93
94/*
95 * Initialises state info data structures for generating various combinations
96 * of state ID's. It also calls tftf_detect_pstate_format() which detects the
97 * PSTATE format accepted by EL3 firmware.
98 * This function needs to be invoked once during cold boot prior to the
99 * invocation of any PSCI power state helper functions.
100 */
101void tftf_init_pstate_framework(void);
102
103/*
104 * This function is used to generate all possible combinations of composite
105 * state ID's possible for a given set of power states at each level.
106 * Ex: If a system implements 4 levels and each level has 3 local power states.
107 * Then, the total combinations of composite power down states possible are:
108 * 3 * 3 * 3 * 3 = 81
109 *
110 * A single call to set_next_state_id_pointers(), sets pointer to pstate_id_idx
111 * at all levels for a possible combination out of 81.
112 *
113 * A caller can confirm when all combinations are completed by checking if
114 * pwr_lvel_state_indexes for power_level 0 is PWR_STATE_INIT_INDEX
115 */
116void tftf_set_next_state_id_idx(unsigned int power_level,
117 unsigned int pstate_id_idx[]);
118
119/*
120 * This function sets the index for the next state ID of the given power level
121 */
122void tftf_set_next_local_state_id_idx(unsigned int power_level,
123 unsigned int pstate_id_idx[]);
124
125/*
126 * This function sets the index corresponding to the deepest power state at
127 * a given power level.
128 */
129void tftf_set_deepest_pstate_idx(unsigned int power_level,
130 unsigned int pstate_id_idx[]);
131
132/*
133 * Helper function to get the state ID, state type, power level in power_state
134 * parameter of CPU_SUSPEND. The generated values are based on the
135 * pstate_id_idx values of a core.
136 *
137 * This helper expects a valid pstate_id_idx till the max valid levels
138 * and it detects the max valid level to be terminated by PWR_STATE_INIT value
139 *
140 * It returns the expected PSCI return value of a suspend request
141 */
142int tftf_get_pstate_vars(unsigned int *test_power_level,
143 unsigned int *test_suspend_type,
144 unsigned int *suspend_state_id,
145 unsigned int pstate_id_idx[]);
146
147/*
148 * This function gets the platform specific timer driver information and
149 * initialises platform specific drivers.
150 * Returns 0 on success.
151 */
152int plat_initialise_timer_ops(const plat_timer_t **timer_ops);
153
154struct mem_region {
155 uintptr_t addr;
156 size_t size;
157};
158
159typedef struct mem_region mem_region_t;
160
161/*******************************************************************************
162 * Optional functions. A default, weak implementation of those functions is
163 * provided, it may be overridden by platform code.
164 ******************************************************************************/
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200165unsigned long platform_get_stack(unsigned long mpidr);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200166/*
167 * plat_get_prot_regions: It returns a pointer to a
168 * set of regions used to test mem_protect_check.
169 * The number of elements are stored in the variable
170 * pointed by nelem.
171 */
172const mem_region_t *plat_get_prot_regions(int *nelem);
173
174void tftf_plat_reset(void);
175
176const mmap_region_t *tftf_platform_get_mmap(void);
177
178/*
179 * Return an IO device handle and specification which can be used
180 * to access an image. Use this to enforce platform load policy.
181 */
182int plat_get_image_source(unsigned int image_id,
183 uintptr_t *dev_handle,
184 uintptr_t *image_spec);
185
186void plat_fwu_io_setup(void);
187
J-Alves79c08f12021-10-27 15:15:16 +0100188/**
189 * Returns current executing core.
190 */
191static inline uint32_t get_current_core_id(void)
192{
193 return platform_get_core_pos(read_mpidr_el1() & MPID_MASK);
194}
195
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200196#endif /* __PLATFORM_H__ */