blob: 077ccb30869e3a6e06bd0ce72d6c1614de6b6da8 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
AlexeiFedorov718fd792024-11-08 14:55:20 +00002 * Copyright (c) 2018-2025, 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/*
AlexeiFedorov718fd792024-11-08 14:55:20 +000028 * Represents whether a device memory location is within the system coherent
29 * memory space.
30 */
31#define DEV_MEM_NON_COHERENT 0
32#define DEV_MEM_COHERENT 1
33
34/*
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020035 * The platform structure to represent the valid local power state
36 * properties for a particular affinity level. The platform needs to
37 * export the array of valid local low power states for each affinity level
38 * it supports which can be queried by TFTF tests to construct the required
39 * composite power state.
40 *
41 * TODO: Currently the power levels are identity mapped to affinity level in
42 * TFTF which need to be decoupled.
43 */
44typedef struct plat_state_prop {
45 /*
46 * This field has a value in the increasing order of the suspend
47 * depth. Deeper the suspend state, higher the value.
48 */
49 unsigned int suspend_depth;
50 /* The local state ID for the idle state at this level. */
51 unsigned int state_ID;
52 /* Flag which indicates whether is a retention or power down state */
53 unsigned int is_pwrdown;
54} plat_state_prop_t;
55
56void tftf_plat_arch_setup(void);
57void tftf_early_platform_setup(void);
58void tftf_platform_setup(void);
59
60void tftf_plat_enable_mmu(void);
61void tftf_plat_configure_mmu(void);
62
63void tftf_platform_end(void);
64void tftf_platform_watchdog_set(void);
65void tftf_platform_watchdog_reset(void);
66
Antonio Nino Diaz1cf45c92018-10-15 09:03:43 +010067/* Helper that returns a linear core ID from a MPID */
68unsigned int platform_get_core_pos(u_register_t mpid);
69
70/* Crash console functions */
71int plat_crash_console_init(void);
72int plat_crash_console_putc(int c);
73int plat_crash_console_flush(void);
74
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020075/* Gets a handle for the initialised IO entity */
76void plat_get_nvm_handle(uintptr_t *handle);
77
78/*
79 * Returns the platform topology description array. The size of this
80 * array should be PLATFORM_NUM_AFFS - PLATFORM_CORE_COUNT + 1.
81 */
82const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void);
83
84/*
85 * Function to query the MPIDR of a CPU identified by 'core_pos' which is
86 * the number returned by platform_get_core() API.
87 * In case the CPU is absent, then this API returns INVALID_MPID. This
88 * function will be queried only during topology setup in TFTF and thereafter
89 * the internal node data will be used to get the MPIDR corresponding
90 * to the 'core_pos'.
91 */
92uint64_t tftf_plat_get_mpidr(unsigned int core_pos);
93
94/*
95 * Get the state property array for all the valid states from platform for
96 * a specified 'level'. The array is expected to be NULL terminated after the
97 * last entry.
98 */
99const plat_state_prop_t *plat_get_state_prop(unsigned int level);
100
101/*
102 * Initialises state info data structures for generating various combinations
103 * of state ID's. It also calls tftf_detect_pstate_format() which detects the
104 * PSTATE format accepted by EL3 firmware.
105 * This function needs to be invoked once during cold boot prior to the
106 * invocation of any PSCI power state helper functions.
107 */
108void tftf_init_pstate_framework(void);
109
110/*
111 * This function is used to generate all possible combinations of composite
112 * state ID's possible for a given set of power states at each level.
113 * Ex: If a system implements 4 levels and each level has 3 local power states.
114 * Then, the total combinations of composite power down states possible are:
115 * 3 * 3 * 3 * 3 = 81
116 *
117 * A single call to set_next_state_id_pointers(), sets pointer to pstate_id_idx
118 * at all levels for a possible combination out of 81.
119 *
120 * A caller can confirm when all combinations are completed by checking if
121 * pwr_lvel_state_indexes for power_level 0 is PWR_STATE_INIT_INDEX
122 */
123void tftf_set_next_state_id_idx(unsigned int power_level,
124 unsigned int pstate_id_idx[]);
125
126/*
127 * This function sets the index for the next state ID of the given power level
128 */
129void tftf_set_next_local_state_id_idx(unsigned int power_level,
130 unsigned int pstate_id_idx[]);
131
132/*
133 * This function sets the index corresponding to the deepest power state at
134 * a given power level.
135 */
136void tftf_set_deepest_pstate_idx(unsigned int power_level,
137 unsigned int pstate_id_idx[]);
138
139/*
140 * Helper function to get the state ID, state type, power level in power_state
141 * parameter of CPU_SUSPEND. The generated values are based on the
142 * pstate_id_idx values of a core.
143 *
144 * This helper expects a valid pstate_id_idx till the max valid levels
145 * and it detects the max valid level to be terminated by PWR_STATE_INIT value
146 *
147 * It returns the expected PSCI return value of a suspend request
148 */
149int tftf_get_pstate_vars(unsigned int *test_power_level,
150 unsigned int *test_suspend_type,
151 unsigned int *suspend_state_id,
152 unsigned int pstate_id_idx[]);
153
154/*
155 * This function gets the platform specific timer driver information and
156 * initialises platform specific drivers.
157 * Returns 0 on success.
158 */
159int plat_initialise_timer_ops(const plat_timer_t **timer_ops);
160
161struct mem_region {
162 uintptr_t addr;
163 size_t size;
164};
165
166typedef struct mem_region mem_region_t;
167
168/*******************************************************************************
169 * Optional functions. A default, weak implementation of those functions is
170 * provided, it may be overridden by platform code.
171 ******************************************************************************/
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200172unsigned long platform_get_stack(unsigned long mpidr);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200173/*
174 * plat_get_prot_regions: It returns a pointer to a
175 * set of regions used to test mem_protect_check.
176 * The number of elements are stored in the variable
177 * pointed by nelem.
178 */
179const mem_region_t *plat_get_prot_regions(int *nelem);
180
181void tftf_plat_reset(void);
182
183const mmap_region_t *tftf_platform_get_mmap(void);
184
185/*
186 * Return an IO device handle and specification which can be used
187 * to access an image. Use this to enforce platform load policy.
188 */
189int plat_get_image_source(unsigned int image_id,
190 uintptr_t *dev_handle,
191 uintptr_t *image_spec);
192
193void plat_fwu_io_setup(void);
194
J-Alves79c08f12021-10-27 15:15:16 +0100195/**
196 * Returns current executing core.
197 */
198static inline uint32_t get_current_core_id(void)
199{
200 return platform_get_core_pos(read_mpidr_el1() & MPID_MASK);
201}
202
Soby Mathew2c2810f2024-11-15 17:11:24 +0000203/* Forward declaration */
204struct pcie_info_table;
205
206/*
207 * Retrieve platform PCIe information.
208 */
209const struct pcie_info_table *plat_pcie_get_info_table(void);
210
Arunachalam Ganapathy503b89a2025-06-19 10:34:11 +0100211/* Retrieve platform PCIe bar config values */
212int plat_pcie_get_bar_config(uint64_t *bar64_val, uint64_t *rp_bar64_val,
213 uint32_t *bar32np_val, uint32_t *bar32p_val,
214 uint32_t *rp_bar32_val);
215
Maheedhar Bollapalli1e4f7a02025-02-14 10:40:56 +0530216/*
217 * This function provides an address that is recognized as invalid for use
218 * as an entry point in the CPU_ON and CPU_SUSPEND calls on this platform.
219 * To be considered invalid, the address must fall within a range that is
220 * not accessible to the caller.
221 *
222 * Typically, most platforms designate address 0 for this purpose. However,
223 * on platforms where address 0 is a valid entry point, this function can
224 * be designed to return an alternative address.
225 */
226uintptr_t plat_get_invalid_addr(void);
227
AlexeiFedorov718fd792024-11-08 14:55:20 +0000228/*
229 * Retrieve platform PCIe memory region
230 */
231int plat_get_dev_region(uint64_t *dev_base, size_t *dev_size,
232 uint32_t dev_type, uint32_t dev_idx);
233
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200234#endif /* __PLATFORM_H__ */