blob: c8b785ccb1aa341eb47ae0d7394a85940bc37374 [file] [log] [blame]
/*
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
#include <stdint.h>
#include <arch_helpers.h>
#include <timer.h>
#include <xlat_tables_v2.h>
#define PLAT_PSCI_DUMMY_STATE_ID 0xF
#define PWR_STATE_INIT_INDEX (-1)
#define INIT_PWR_LEVEL_INDEX(array_name) \
do { \
unsigned int var; \
assert(ARRAY_SIZE(array_name) == (PLAT_MAX_PWR_LEVEL + 1)); \
for (var = 0; var <= PLAT_MAX_PWR_LEVEL; var++) \
array_name[var] = PWR_STATE_INIT_INDEX; \
} while (0)
/*
* The platform structure to represent the valid local power state
* properties for a particular affinity level. The platform needs to
* export the array of valid local low power states for each affinity level
* it supports which can be queried by TFTF tests to construct the required
* composite power state.
*
* TODO: Currently the power levels are identity mapped to affinity level in
* TFTF which need to be decoupled.
*/
typedef struct plat_state_prop {
/*
* This field has a value in the increasing order of the suspend
* depth. Deeper the suspend state, higher the value.
*/
unsigned int suspend_depth;
/* The local state ID for the idle state at this level. */
unsigned int state_ID;
/* Flag which indicates whether is a retention or power down state */
unsigned int is_pwrdown;
} plat_state_prop_t;
void tftf_plat_arch_setup(void);
void tftf_early_platform_setup(void);
void tftf_platform_setup(void);
void tftf_plat_enable_mmu(void);
void tftf_plat_configure_mmu(void);
void tftf_platform_end(void);
void tftf_platform_watchdog_set(void);
void tftf_platform_watchdog_reset(void);
/* Helper that returns a linear core ID from a MPID */
unsigned int platform_get_core_pos(u_register_t mpid);
/* Crash console functions */
int plat_crash_console_init(void);
int plat_crash_console_putc(int c);
int plat_crash_console_flush(void);
/* Gets a handle for the initialised IO entity */
void plat_get_nvm_handle(uintptr_t *handle);
/*
* Returns the platform topology description array. The size of this
* array should be PLATFORM_NUM_AFFS - PLATFORM_CORE_COUNT + 1.
*/
const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void);
/*
* Function to query the MPIDR of a CPU identified by 'core_pos' which is
* the number returned by platform_get_core() API.
* In case the CPU is absent, then this API returns INVALID_MPID. This
* function will be queried only during topology setup in TFTF and thereafter
* the internal node data will be used to get the MPIDR corresponding
* to the 'core_pos'.
*/
uint64_t tftf_plat_get_mpidr(unsigned int core_pos);
/*
* Get the state property array for all the valid states from platform for
* a specified 'level'. The array is expected to be NULL terminated after the
* last entry.
*/
const plat_state_prop_t *plat_get_state_prop(unsigned int level);
/*
* Initialises state info data structures for generating various combinations
* of state ID's. It also calls tftf_detect_pstate_format() which detects the
* PSTATE format accepted by EL3 firmware.
* This function needs to be invoked once during cold boot prior to the
* invocation of any PSCI power state helper functions.
*/
void tftf_init_pstate_framework(void);
/*
* This function is used to generate all possible combinations of composite
* state ID's possible for a given set of power states at each level.
* Ex: If a system implements 4 levels and each level has 3 local power states.
* Then, the total combinations of composite power down states possible are:
* 3 * 3 * 3 * 3 = 81
*
* A single call to set_next_state_id_pointers(), sets pointer to pstate_id_idx
* at all levels for a possible combination out of 81.
*
* A caller can confirm when all combinations are completed by checking if
* pwr_lvel_state_indexes for power_level 0 is PWR_STATE_INIT_INDEX
*/
void tftf_set_next_state_id_idx(unsigned int power_level,
unsigned int pstate_id_idx[]);
/*
* This function sets the index for the next state ID of the given power level
*/
void tftf_set_next_local_state_id_idx(unsigned int power_level,
unsigned int pstate_id_idx[]);
/*
* This function sets the index corresponding to the deepest power state at
* a given power level.
*/
void tftf_set_deepest_pstate_idx(unsigned int power_level,
unsigned int pstate_id_idx[]);
/*
* Helper function to get the state ID, state type, power level in power_state
* parameter of CPU_SUSPEND. The generated values are based on the
* pstate_id_idx values of a core.
*
* This helper expects a valid pstate_id_idx till the max valid levels
* and it detects the max valid level to be terminated by PWR_STATE_INIT value
*
* It returns the expected PSCI return value of a suspend request
*/
int tftf_get_pstate_vars(unsigned int *test_power_level,
unsigned int *test_suspend_type,
unsigned int *suspend_state_id,
unsigned int pstate_id_idx[]);
/*
* This function gets the platform specific timer driver information and
* initialises platform specific drivers.
* Returns 0 on success.
*/
int plat_initialise_timer_ops(const plat_timer_t **timer_ops);
struct mem_region {
uintptr_t addr;
size_t size;
};
typedef struct mem_region mem_region_t;
/*******************************************************************************
* Optional functions. A default, weak implementation of those functions is
* provided, it may be overridden by platform code.
******************************************************************************/
unsigned long platform_get_stack(unsigned long mpidr);
/*
* plat_get_prot_regions: It returns a pointer to a
* set of regions used to test mem_protect_check.
* The number of elements are stored in the variable
* pointed by nelem.
*/
const mem_region_t *plat_get_prot_regions(int *nelem);
void tftf_plat_reset(void);
const mmap_region_t *tftf_platform_get_mmap(void);
/*
* Return an IO device handle and specification which can be used
* to access an image. Use this to enforce platform load policy.
*/
int plat_get_image_source(unsigned int image_id,
uintptr_t *dev_handle,
uintptr_t *image_spec);
void plat_fwu_io_setup(void);
/**
* Returns current executing core.
*/
static inline uint32_t get_current_core_id(void)
{
return platform_get_core_pos(read_mpidr_el1() & MPID_MASK);
}
#endif /* __PLATFORM_H__ */