diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h index b82ff47..93f8616 100644 --- a/include/plat/arm/css/common/css_pm.h +++ b/include/plat/arm/css/common/css_pm.h @@ -27,6 +27,7 @@ int css_pwr_domain_on(u_register_t mpidr); void css_pwr_domain_on_finish(const psci_power_state_t *target_state); +void css_pwr_domain_on_finish_late(const psci_power_state_t *target_state); void css_pwr_domain_off(const psci_power_state_t *target_state); void css_pwr_domain_suspend(const psci_power_state_t *target_state); void css_pwr_domain_suspend_finish( diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 42dec8d..0a62543 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -247,10 +247,19 @@ { fvp_power_domain_on_finish_common(target_state); - /* Enable the gic cpu interface */ +} + +/******************************************************************************* + * FVP handler called when a power domain has just been powered on and the cpu + * and its cluster are fully participating in coherent transaction on the + * interconnect. Data cache must be enabled for CPU at this point. + ******************************************************************************/ +static void fvp_pwr_domain_on_finish_late(const psci_power_state_t *target_state) +{ + /* Program GIC per-cpu distributor or re-distributor interface */ plat_arm_gic_pcpu_init(); - /* Program the gic per-cpu distributor or re-distributor interface */ + /* Enable GIC CPU interface */ plat_arm_gic_cpuif_enable(); } @@ -272,7 +281,7 @@ fvp_power_domain_on_finish_common(target_state); - /* Enable the gic cpu interface */ + /* Enable GIC CPU interface */ plat_arm_gic_cpuif_enable(); } @@ -397,6 +406,7 @@ .pwr_domain_off = fvp_pwr_domain_off, .pwr_domain_suspend = fvp_pwr_domain_suspend, .pwr_domain_on_finish = fvp_pwr_domain_on_finish, + .pwr_domain_on_finish_late = fvp_pwr_domain_on_finish_late, .pwr_domain_suspend_finish = fvp_pwr_domain_suspend_finish, .system_off = fvp_system_off, .system_reset = fvp_system_reset, diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index 7f4957f..fef5376 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -67,7 +68,7 @@ static const gicv3_driver_data_t arm_gic_data __unused = { .gicd_base = PLAT_ARM_GICD_BASE, - .gicr_base = PLAT_ARM_GICR_BASE, + .gicr_base = 0U, .interrupt_props = arm_interrupt_props, .interrupt_props_num = ARRAY_SIZE(arm_interrupt_props), .rdistif_num = PLATFORM_CORE_COUNT, @@ -86,6 +87,11 @@ #if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ (defined(__aarch64__) && defined(IMAGE_BL31)) gicv3_driver_init(&arm_gic_data); + + if (gicv3_rdistif_probe(PLAT_ARM_GICR_BASE) == -1) { + ERROR("No GICR base frame found for Primary CPU\n"); + panic(); + } #endif } @@ -116,10 +122,20 @@ } /****************************************************************************** - * ARM common helper to initialize the per-cpu redistributor interface in GICv3 + * ARM common helper function to iterate over all GICR frames and discover the + * corresponding per-cpu redistributor frame as well as initialize the + * corresponding interface in GICv3. At the moment, Arm platforms do not have + * non-contiguous GICR frames. *****************************************************************************/ void plat_arm_gic_pcpu_init(void) { + int result; + + result = gicv3_rdistif_probe(PLAT_ARM_GICR_BASE); + if (result == -1) { + ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr()); + panic(); + } gicv3_rdistif_init(plat_my_core_pos()); } diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index f6fc6aa..01c674f 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -76,9 +76,6 @@ { assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF); - /* Enable the gic cpu interface */ - plat_arm_gic_cpuif_enable(); - /* * Perform the common cluster specific operations i.e enable coherency * if this cluster was off. @@ -100,10 +97,21 @@ /* Assert that the system power domain need not be initialized */ assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN); + css_pwr_domain_on_finisher_common(target_state); +} + +/******************************************************************************* + * Handler called when a power domain has just been powered on and the cpu + * and its cluster are fully participating in coherent transaction on the + * interconnect. Data cache must be enabled for CPU at this point. + ******************************************************************************/ +void css_pwr_domain_on_finish_late(const psci_power_state_t *target_state) +{ /* Program the gic per-cpu distributor or re-distributor interface */ plat_arm_gic_pcpu_init(); - css_pwr_domain_on_finisher_common(target_state); + /* Enable the gic cpu interface */ + plat_arm_gic_cpuif_enable(); } /******************************************************************************* @@ -185,6 +193,9 @@ arm_system_pwr_domain_resume(); css_pwr_domain_on_finisher_common(target_state); + + /* Enable the gic cpu interface */ + plat_arm_gic_cpuif_enable(); } /******************************************************************************* @@ -306,6 +317,7 @@ plat_psci_ops_t plat_arm_psci_pm_ops = { .pwr_domain_on = css_pwr_domain_on, .pwr_domain_on_finish = css_pwr_domain_on_finish, + .pwr_domain_on_finish_late = css_pwr_domain_on_finish_late, .pwr_domain_off = css_pwr_domain_off, .cpu_standby = css_cpu_standby, .pwr_domain_suspend = css_pwr_domain_suspend,