/******************************************************************************* * STM32MP1 handler called when a power domain is about to be turned on. The * mpidr determines the CPU to be turned on. * call by core 0 to activate core 1 ******************************************************************************/ static int stm32_pwr_domain_on(u_register_t mpidr) { unsigned long current_cpu_mpidr = read_mpidr_el1(); uint32_t bkpr_core1_addr = tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); uint32_t bkpr_core1_magic = tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); if (mpidr == current_cpu_mpidr) { return PSCI_E_INVALID_PARAMS; } if ((stm32_sec_entrypoint < STM32MP_SYSRAM_BASE) || (stm32_sec_entrypoint > (STM32MP_SYSRAM_BASE + (STM32MP_SYSRAM_SIZE - 1)))) { return PSCI_E_INVALID_ADDRESS; } stm32mp_clk_enable(RTCAPB); cntfrq_core0 = read_cntfrq_el0(); /* Write entrypoint in backup RAM register */ mmio_write_32(bkpr_core1_addr, stm32_sec_entrypoint); /* Write magic number in backup register */ mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER); stm32mp_clk_disable(RTCAPB); /* Generate an IT to core 1 */ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP_SECONDARY_CPU); return PSCI_E_SUCCESS; }
/******************************************************************************* * STM32MP1 handler called when a power domain is about to be turned on. The * mpidr determines the CPU to be turned on. * call by core 0 to activate core 1 ******************************************************************************/ static int stm32_pwr_domain_on(u_register_t mpidr) { unsigned long current_cpu_mpidr = read_mpidr_el1(); uint32_t tamp_clk_off = 0; uint32_t bkpr_core1_addr = tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); uint32_t bkpr_core1_magic = tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); if (mpidr == current_cpu_mpidr) { return PSCI_E_INVALID_PARAMS; } if ((stm32_sec_entrypoint < STM32MP1_SRAM_BASE) || (stm32_sec_entrypoint > (STM32MP1_SRAM_BASE + (STM32MP1_SRAM_SIZE - 1)))) { return PSCI_E_INVALID_ADDRESS; } if (!stm32mp1_clk_is_enabled(RTCAPB)) { tamp_clk_off = 1; if (stm32mp1_clk_enable(RTCAPB) != 0) { panic(); } } cntfrq_core0 = read_cntfrq_el0(); /* Write entrypoint in backup RAM register */ mmio_write_32(bkpr_core1_addr, stm32_sec_entrypoint); /* Write magic number in backup register */ mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER); if (tamp_clk_off != 0U) { if (stm32mp1_clk_disable(RTCAPB) != 0) { panic(); } } /* Generate an IT to core 1 */ mmio_write_32(STM32MP1_GICD_BASE + GICD_SGIR, SEND_SECURE_IT_TO_CORE_1 | ARM_IRQ_SEC_SGI_0); return PSCI_E_SUCCESS; }
int stm32_save_boot_interface(uint32_t interface, uint32_t instance) { uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); stm32mp_clk_enable(RTCAPB); mmio_clrsetbits_32(bkpr_itf_idx, TAMP_BOOT_ITF_MASK, ((interface << 4) | (instance & 0xFU)) << TAMP_BOOT_ITF_SHIFT); stm32mp_clk_disable(RTCAPB); return 0; }