Browse Source

Merge changes from topic "RDN2_WARM_REBOOT_WITH_SGI" into integration

* changes:
  feat(sgi): enable css implementation of warm reset
  feat(scmi): send powerdown request to online secondary cpus
  feat(plat/arm/css): add interrupt handler for reboot request
  refactor(psci): move psci_do_pwrdown_sequence() out of private header
  feat(plat/arm/css): add per-cpu power down support for warm reset
  feat(scmi): set warm reboot entry point
  fix(gicv3): update the affinity mask to 8 bit
pull/1988/head
Manish V Badarkhe 2 years ago
committed by TrustedFirmware Code Review
parent
commit
75eb87f073
  1. 5
      docs/plat/arm/arm-build-options.rst
  2. 33
      drivers/arm/css/scp/css_pm_scmi.c
  3. 2
      include/drivers/arm/gicv3.h
  4. 1
      include/lib/psci/psci_lib.h
  5. 8
      include/plat/arm/css/common/css_pm.h
  6. 2
      lib/psci/psci_common.c
  7. 2
      lib/psci/psci_off.c
  8. 1
      lib/psci/psci_private.h
  9. 2
      lib/psci/psci_suspend.c
  10. 4
      plat/arm/board/rdn2/include/platform_def.h
  11. 5
      plat/arm/board/rdn2/platform.mk
  12. 9
      plat/arm/css/common/css_common.mk
  13. 55
      plat/arm/css/common/css_pm.c
  14. 1
      plat/arm/css/common/sp_min/css_sp_min.mk
  15. 14
      plat/arm/css/sgi/sgi_bl31_setup.c

5
docs/plat/arm/arm-build-options.rst

@ -152,6 +152,11 @@ Arm CSS Platform-Specific Build Options
to select the appropriate platform variant for the build. The range of
valid values is platform specific.
- ``CSS_SYSTEM_GRACEFUL_RESET``: Build option to enable graceful powerdown of
CPU core on reset. This build option can be used on CSS platforms that
require all the CPUs to execute the CPU specific power down sequence to
complete a warm reboot sequence in which only the CPUs are power cycled.
--------------
.. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png

33
drivers/arm/css/scp/css_pm_scmi.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,6 +11,7 @@
#include <common/debug.h>
#include <drivers/arm/css/css_scp.h>
#include <drivers/arm/css/scmi.h>
#include <lib/mmio.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/arm/css/common/css_pm.h>
#include <plat/common/platform.h>
@ -286,15 +287,42 @@ int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level)
return HW_OFF;
}
/*
* Callback function to raise a SGI designated to trigger the CPU power down
* sequence on all the online secondary cores.
*/
static void css_raise_pwr_down_interrupt(u_register_t mpidr)
{
#if CSS_SYSTEM_GRACEFUL_RESET
plat_ic_raise_el3_sgi(CSS_CPU_PWR_DOWN_REQ_INTR, mpidr);
#endif
}
void __dead2 css_scp_system_off(int state)
{
int ret;
/*
* Before issuing the system power down command, set the trusted mailbox
* to 0. This will ensure that in the case of a warm/cold reset, the
* primary CPU executes from the cold boot sequence.
*/
mmio_write_64(PLAT_ARM_TRUSTED_MAILBOX_BASE, 0U);
/*
* Send powerdown request to online secondary core(s)
*/
ret = psci_stop_other_cores(0, css_raise_pwr_down_interrupt);
if (ret != PSCI_E_SUCCESS) {
ERROR("Failed to powerdown secondary core(s)\n");
}
/*
* Disable GIC CPU interface to prevent pending interrupt from waking
* up the AP from WFI.
*/
plat_arm_gic_cpuif_disable();
plat_arm_gic_redistif_off();
/*
* Issue SCMI command. First issue a graceful
@ -309,6 +337,9 @@ void __dead2 css_scp_system_off(int state)
state, ret);
panic();
}
/* Powerdown of primary core */
psci_pwrdown_cpu(PLAT_MAX_PWR_LVL);
wfi();
ERROR("CSS set power state: operation not handled.\n");
panic();

2
include/drivers/arm/gicv3.h

@ -315,7 +315,7 @@
#define SGIR_IRM_SHIFT 40
#define SGIR_IRM_MASK ULL(0x1)
#define SGIR_AFF3_SHIFT 48
#define SGIR_AFF_MASK ULL(0xf)
#define SGIR_AFF_MASK ULL(0xff)
#define SGIR_IRM_TO_AFF U(0)

1
include/lib/psci/psci_lib.h

@ -92,6 +92,7 @@ void psci_prepare_next_non_secure_ctx(
int psci_stop_other_cores(unsigned int wait_ms,
void (*stop_func)(u_register_t mpidr));
bool psci_is_last_on_cpu_safe(void);
void psci_pwrdown_cpu(unsigned int power_level);
#endif /* __ASSEMBLER__ */

8
include/plat/arm/css/common/css_pm.h

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -12,6 +12,9 @@
#include <lib/psci/psci.h>
/* SGI used to trigger per-core power down request */
#define CSS_CPU_PWR_DOWN_REQ_INTR ARM_IRQ_SEC_SGI_7
/* Macros to read the CSS power domain state */
#define CSS_CORE_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL0]
#define CSS_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL1]
@ -37,6 +40,9 @@ void __dead2 css_system_reset(void);
void css_cpu_standby(plat_local_state_t cpu_state);
void css_get_sys_suspend_power_state(psci_power_state_t *req_state);
int css_node_hw_state(u_register_t mpidr, unsigned int power_level);
void css_setup_cpu_pwr_down_intr(void);
int css_reboot_interrupt_handler(uint32_t intr_raw, uint32_t flags,
void *handle, void *cookie);
/*
* This mapping array has to be exported by the platform. Each element at

2
lib/psci/psci_common.c

@ -954,7 +954,7 @@ int psci_secondaries_brought_up(void)
* Initiate power down sequence, by calling power down operations registered for
* this CPU.
******************************************************************************/
void psci_do_pwrdown_sequence(unsigned int power_level)
void psci_pwrdown_cpu(unsigned int power_level)
{
#if HW_ASSISTED_COHERENCY
/*

2
lib/psci/psci_off.c

@ -109,7 +109,7 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
/*
* Arch. management. Initiate power down sequence.
*/
psci_do_pwrdown_sequence(psci_find_max_off_lvl(&state_info));
psci_pwrdown_cpu(psci_find_max_off_lvl(&state_info));
#if ENABLE_RUNTIME_INSTRUMENTATION
PMF_CAPTURE_TIMESTAMP(rt_instr_svc,

1
lib/psci/psci_private.h

@ -296,7 +296,6 @@ void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl);
void psci_print_power_domain_map(void);
unsigned int psci_is_last_on_cpu(void);
int psci_spd_migrate_info(u_register_t *mpidr);
void psci_do_pwrdown_sequence(unsigned int power_level);
/*
* CPU power down is directly called only when HW_ASSISTED_COHERENCY is

2
lib/psci/psci_suspend.c

@ -124,7 +124,7 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
* TODO : Introduce a mechanism to query the cache level to flush
* and the cpu-ops power down to perform from the platform.
*/
psci_do_pwrdown_sequence(max_off_lvl);
psci_pwrdown_cpu(max_off_lvl);
#if ENABLE_RUNTIME_INSTRUMENTATION
PMF_CAPTURE_TIMESTAMP(rt_instr_svc,

4
plat/arm/board/rdn2/include/platform_def.h

@ -96,4 +96,8 @@
#define PLAT_ARM_GICR_BASE UL(0x301C0000)
#endif
/* Interrupt priority level for shutdown/reboot */
#define PLAT_REBOOT_PRI GIC_HIGHEST_SEC_PRIORITY
#define PLAT_EHF_DESC EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
#endif /* PLATFORM_DEF_H */

5
plat/arm/board/rdn2/platform.mk

@ -1,4 +1,4 @@
# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -24,6 +24,9 @@ ifeq (${CSS_SGI_PLATFORM_VARIANT}, 2)
GICV3_IMPL_GIC600_MULTICHIP := 1
endif
override CSS_SYSTEM_GRACEFUL_RESET := 1
override EL3_EXCEPTION_HANDLING := 1
include plat/arm/css/sgi/sgi-common.mk
RDN2_BASE = plat/arm/board/rdn2

9
plat/arm/css/common/css_common.mk

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -35,6 +35,7 @@ BL31_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \
drivers/arm/css/scmi/scmi_common.c \
drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \
drivers/arm/css/scmi/scmi_sys_pwr_proto.c \
drivers/delay_timer/delay_timer.c \
drivers/arm/css/scp/css_pm_scmi.c
endif
@ -88,3 +89,9 @@ CSS_NON_SECURE_UART := 0
$(eval $(call assert_boolean,CSS_NON_SECURE_UART))
$(eval $(call add_define,CSS_NON_SECURE_UART))
# Process CSS_SYSTEM_GRACEFUL_RESET flag
# This build option can be used on CSS platforms that require all the CPUs
# to execute the CPU specific power down sequence to complete a warm reboot
# sequence in which only the CPUs are power cycled.
CSS_SYSTEM_GRACEFUL_RESET := 0
$(eval $(call add_define,CSS_SYSTEM_GRACEFUL_RESET))

55
plat/arm/css/common/css_pm.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -9,10 +9,14 @@
#include <platform_def.h>
#include <arch_helpers.h>
#include <bl31/interrupt_mgmt.h>
#include <common/debug.h>
#include <drivers/arm/css/css_scp.h>
#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <plat/arm/css/common/css_pm.h>
/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
@ -110,6 +114,9 @@ void css_pwr_domain_on_finish_late(const psci_power_state_t *target_state)
/* Enable the gic cpu interface */
plat_arm_gic_cpuif_enable();
/* Setup the CPU power down request interrupt for secondary core(s) */
css_setup_cpu_pwr_down_intr();
}
/*******************************************************************************
@ -331,6 +338,52 @@ static int css_translate_power_state_by_mpidr(u_register_t mpidr,
return arm_validate_power_state(power_state, output_state);
}
/*
* Setup the SGI interrupt that will be used trigger the execution of power
* down sequence for all the secondary cores. This interrupt is setup to be
* handled in EL3 context at a priority defined by the platform.
*/
void css_setup_cpu_pwr_down_intr(void)
{
#if CSS_SYSTEM_GRACEFUL_RESET
plat_ic_set_interrupt_type(CSS_CPU_PWR_DOWN_REQ_INTR, INTR_TYPE_EL3);
plat_ic_set_interrupt_priority(CSS_CPU_PWR_DOWN_REQ_INTR,
PLAT_REBOOT_PRI);
plat_ic_enable_interrupt(CSS_CPU_PWR_DOWN_REQ_INTR);
#endif
}
/*
* For a graceful shutdown/reboot, each CPU in the system should do their power
* down sequence. On a PSCI shutdown/reboot request, only one CPU gets an
* opportunity to do the powerdown sequence. To achieve graceful reset, of all
* cores in the system, the CPU gets the opportunity raise warm reboot SGI to
* rest of the CPUs which are online. Add handler for the reboot SGI where the
* rest of the CPU execute the powerdown sequence.
*/
int css_reboot_interrupt_handler(uint32_t intr_raw, uint32_t flags,
void *handle, void *cookie)
{
assert(intr_raw == CSS_CPU_PWR_DOWN_REQ_INTR);
/* Deactivate warm reboot SGI */
plat_ic_end_of_interrupt(CSS_CPU_PWR_DOWN_REQ_INTR);
/*
* Disable GIC CPU interface to prevent pending interrupt from waking
* up the AP from WFI.
*/
plat_arm_gic_cpuif_disable();
plat_arm_gic_redistif_off();
psci_pwrdown_cpu(PLAT_MAX_PWR_LVL);
dmbsy();
wfi();
return 0;
}
/*******************************************************************************
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
* platform will take care of registering the handlers with PSCI.

1
plat/arm/css/common/sp_min/css_sp_min.mk

@ -15,6 +15,7 @@ BL32_SOURCES += drivers/arm/css/mhu/css_mhu.c \
else
BL32_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \
drivers/arm/css/scp/css_pm_scmi.c \
drivers/delay_timer/delay_timer.c \
drivers/arm/css/scmi/scmi_common.c \
drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \
drivers/arm/css/scmi/scmi_sys_pwr_proto.c

14
plat/arm/css/sgi/sgi_bl31_setup.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -13,8 +13,11 @@
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <plat/arm/css/common/css_pm.h>
#include <sgi_ras.h>
#include <sgi_variant.h>
@ -105,6 +108,15 @@ void sgi_bl31_common_platform_setup(void)
#if RAS_EXTENSION
sgi_ras_intr_handler_setup();
#endif
/* Configure the warm reboot SGI for primary core */
css_setup_cpu_pwr_down_intr();
#if CSS_SYSTEM_GRACEFUL_RESET
/* Register priority level handlers for reboot */
ehf_register_priority_handler(PLAT_REBOOT_PRI,
css_reboot_interrupt_handler);
#endif
}
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)

Loading…
Cancel
Save