1 /* 2 * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <lib/psci/psci.h> 8 #include <plat/arm/common/plat_arm.h> 9 #include <platform_def.h> 10 #include <plat/common/platform.h> 11 #ifdef CORSTONE1000_CORTEX_A320 12 #include <drivers/arm/gicv3.h> 13 #else 14 #include <drivers/arm/gicv2.h> 15 #endif 16 /******************************************************************************* 17 * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard 18 * platform layer will take care of registering the handlers with PSCI. 19 ******************************************************************************/ 20 corstone1000_system_reset(void)21static void corstone1000_system_reset(void) 22 { 23 24 uint32_t volatile * const watchdog_ctrl_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_CTRL_REG; 25 uint32_t volatile * const watchdog_val_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_VAL_REG; 26 27 /* 28 * Disable GIC CPU interface to prevent pending interrupt 29 * from waking up the AP from WFI. 30 */ 31 #ifdef CORSTONE1000_CORTEX_A320 32 gicv3_cpuif_disable(plat_my_core_pos()); 33 #else 34 gicv2_cpuif_disable(); 35 #endif 36 37 /* Flush and invalidate data cache */ 38 dcsw_op_all(DCCISW); 39 40 *(watchdog_val_reg) = SECURE_WATCHDOG_COUNTDOWN_VAL; 41 *watchdog_ctrl_reg = SECURE_WATCHDOG_MASK_ENABLE; 42 } 43 44 #if defined(CORSTONE1000_FVP_MULTICORE) corstone1000_validate_ns_entrypoint(uintptr_t entrypoint)45int corstone1000_validate_ns_entrypoint(uintptr_t entrypoint) 46 { 47 /* 48 * Check if the non secure entrypoint lies within the non 49 * secure DRAM. 50 */ 51 if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint < (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE))) { 52 return PSCI_E_SUCCESS; 53 } 54 return PSCI_E_INVALID_ADDRESS; 55 } 56 corstone1000_pwr_domain_on(u_register_t mpidr)57int corstone1000_pwr_domain_on(u_register_t mpidr) 58 { 59 int core_index = plat_core_pos_by_mpidr(mpidr); 60 uint64_t *secondary_core_hold_base = (uint64_t *)CORSTONE1000_SECONDARY_CORE_HOLD_BASE; 61 62 /* Validate the core index */ 63 if (core_index < 0 || core_index > PLATFORM_CORE_COUNT) { 64 return PSCI_E_INVALID_PARAMS; 65 } 66 secondary_core_hold_base[core_index] = CORSTONE1000_SECONDARY_CORE_STATE_GO; 67 dsbish(); 68 sev(); 69 70 return PSCI_E_SUCCESS; 71 } 72 corstone1000_pwr_domain_on_finish(const psci_power_state_t * target_state)73void corstone1000_pwr_domain_on_finish(const psci_power_state_t *target_state) 74 { 75 (void)target_state; 76 } 77 #endif 78 79 plat_psci_ops_t plat_arm_psci_pm_ops = { 80 #if defined(CORSTONE1000_FVP_MULTICORE) 81 .pwr_domain_on = corstone1000_pwr_domain_on, 82 .pwr_domain_on_finish = corstone1000_pwr_domain_on_finish, 83 .validate_ns_entrypoint = corstone1000_validate_ns_entrypoint, 84 .system_reset = corstone1000_system_reset, 85 #else 86 .validate_ns_entrypoint = NULL, 87 .system_reset = corstone1000_system_reset, 88 #endif 89 }; 90 plat_arm_psci_override_pm_ops(plat_psci_ops_t * ops)91const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) 92 { 93 ops = &plat_arm_psci_pm_ops; 94 return ops; 95 } 96