mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 18:14:24 +00:00
reset2: Add PSCI system_reset2 function
This patch implements PSCI_SYSTEM_RESET2 API as defined in PSCI v1.1 specification. The specification allows architectural and vendor-specific resets via this API. In the current specification, there is only one architectural reset, the warm reset. This reset is intended to provide a fast reboot path that guarantees not to reset system main memory. Change-Id: I057bb81a60cd0fe56465dbb5791d8e1cca025bd3 Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
This commit is contained in:
parent
4d415c11c4
commit
36a8f8fd47
5 changed files with 54 additions and 1 deletions
|
@ -65,6 +65,8 @@
|
|||
#define PSCI_STAT_RESIDENCY_AARCH64 U(0xc4000010)
|
||||
#define PSCI_STAT_COUNT_AARCH32 U(0x84000011)
|
||||
#define PSCI_STAT_COUNT_AARCH64 U(0xc4000011)
|
||||
#define PSCI_SYSTEM_RESET2_AARCH32 U(0x84000012)
|
||||
#define PSCI_SYSTEM_RESET2_AARCH64 U(0xc4000012)
|
||||
#define PSCI_MEM_PROTECT U(0x84000013)
|
||||
#define PSCI_MEM_CHK_RANGE_AARCH32 U(0x84000014)
|
||||
#define PSCI_MEM_CHK_RANGE_AARCH64 U(0xc4000014)
|
||||
|
@ -167,6 +169,14 @@
|
|||
|
||||
#define PSCI_INVALID_MPIDR ~((u_register_t)0)
|
||||
|
||||
/*
|
||||
* SYSTEM_RESET2 macros
|
||||
*/
|
||||
#define PSCI_RESET2_TYPE_VENDOR_SHIFT 31
|
||||
#define PSCI_RESET2_TYPE_VENDOR (1U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
|
||||
#define PSCI_RESET2_TYPE_ARCH (0U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
|
||||
#define PSCI_RESET2_SYSTEM_WARM_RESET (PSCI_RESET2_TYPE_ARCH | 0)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -294,6 +304,8 @@ typedef struct plat_psci_ops {
|
|||
int (*mem_protect_chk)(uintptr_t base, u_register_t length);
|
||||
int (*read_mem_protect)(int *val);
|
||||
int (*write_mem_protect)(int val);
|
||||
int (*system_reset2)(int is_vendor,
|
||||
int reset_type, u_register_t cookie);
|
||||
} plat_psci_ops_t;
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -414,6 +414,10 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
|
|||
case PSCI_MEM_CHK_RANGE_AARCH32:
|
||||
return psci_mem_chk_range(x1, x2);
|
||||
|
||||
case PSCI_SYSTEM_RESET2_AARCH32:
|
||||
/* We should never return from psci_system_reset2() */
|
||||
return psci_system_reset2(x1, x2);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -453,6 +457,9 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
|
|||
case PSCI_MEM_CHK_RANGE_AARCH64:
|
||||
return psci_mem_chk_range(x1, x2);
|
||||
|
||||
case PSCI_SYSTEM_RESET2_AARCH64:
|
||||
/* We should never return from psci_system_reset2() */
|
||||
return psci_system_reset2(x1, x2);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -89,7 +89,8 @@
|
|||
define_psci_cap(PSCI_NODE_HW_STATE_AARCH64) | \
|
||||
define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64) | \
|
||||
define_psci_cap(PSCI_STAT_RESIDENCY_AARCH64) | \
|
||||
define_psci_cap(PSCI_STAT_COUNT_AARCH64))
|
||||
define_psci_cap(PSCI_STAT_COUNT_AARCH64) | \
|
||||
define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64))
|
||||
|
||||
/*
|
||||
* Helper macros to get/set the fields of PSCI per-cpu data.
|
||||
|
@ -258,6 +259,7 @@ void psci_do_pwrup_cache_maintenance(void);
|
|||
/* Private exported functions from psci_system_off.c */
|
||||
void __dead2 psci_system_off(void);
|
||||
void __dead2 psci_system_reset(void);
|
||||
int psci_system_reset2(uint32_t reset_type, u_register_t cookie);
|
||||
|
||||
/* Private exported functions from psci_stat.c */
|
||||
void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
|
||||
|
|
|
@ -248,6 +248,8 @@ int psci_setup(const psci_lib_args_t *lib_args)
|
|||
psci_caps |= define_psci_cap(PSCI_MEM_PROTECT);
|
||||
if (psci_plat_pm_ops->mem_protect_chk)
|
||||
psci_caps |= define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64);
|
||||
if (psci_plat_pm_ops->system_reset2)
|
||||
psci_caps |= define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64);
|
||||
|
||||
#if ENABLE_PSCI_STAT
|
||||
psci_caps |= define_psci_cap(PSCI_STAT_RESIDENCY_AARCH64);
|
||||
|
|
|
@ -49,3 +49,33 @@ void __dead2 psci_system_reset(void)
|
|||
|
||||
/* This function does not return. We should never get here */
|
||||
}
|
||||
|
||||
int psci_system_reset2(uint32_t reset_type, u_register_t cookie)
|
||||
{
|
||||
int is_vendor;
|
||||
|
||||
psci_print_power_domain_map();
|
||||
|
||||
assert(psci_plat_pm_ops->system_reset2);
|
||||
|
||||
is_vendor = (reset_type >> PSCI_RESET2_TYPE_VENDOR_SHIFT) & 1;
|
||||
if (!is_vendor) {
|
||||
/*
|
||||
* Only WARM_RESET is allowed for architectural type resets.
|
||||
*/
|
||||
if (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
if (psci_plat_pm_ops->write_mem_protect &&
|
||||
psci_plat_pm_ops->write_mem_protect(0) < 0) {
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify the Secure Payload Dispatcher */
|
||||
if (psci_spd_pm && psci_spd_pm->svc_system_reset) {
|
||||
psci_spd_pm->svc_system_reset();
|
||||
}
|
||||
console_flush();
|
||||
|
||||
return psci_plat_pm_ops->system_reset2(is_vendor, reset_type, cookie);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue