int psci_cpu_on(uint32_t core_idx, uint32_t entry, uint32_t context_id) { uint32_t val = 0; size_t pos = get_core_pos_mpidr(core_idx); vaddr_t bootsram = core_mmu_get_va(BOOTSRAM_BASE, MEM_AREA_IO_SEC); vaddr_t crg = core_mmu_get_va(CPU_CRG_BASE, MEM_AREA_IO_SEC); if (!bootsram || !crg) { EMSG("No bootsram or crg mapping"); return PSCI_RET_INVALID_PARAMETERS; } if ((pos == 0) || (pos >= CFG_TEE_CORE_NB_CORE)) return PSCI_RET_INVALID_PARAMETERS; /* set secondary core's NS entry addresses */ generic_boot_set_core_ns_entry(pos, entry, context_id); val = virt_to_phys((void *)TEE_TEXT_VA_START); io_write32(bootsram + REG_CPU_START_ADDR, val); io_write32(bootsram + REG_CPU_START_COMMAND, 0xe51ff004); /* release secondary core */ io_clrbits32(crg + REG_CPU_SUSSYS_RESET, RELEASE_CORE_MASK); return PSCI_RET_SUCCESS; }
/* Override default psci_cpu_on() with platform specific sequence */ int psci_cpu_on(uint32_t core_id, uint32_t entry, uint32_t context_id) { size_t pos = get_core_pos_mpidr(core_id); uint32_t exceptions = 0; int rc = 0; if (!pos || pos >= CFG_TEE_CORE_NB_CORE) return PSCI_RET_INVALID_PARAMETERS; DMSG("core %zu, ns_entry 0x%" PRIx32 ", state %u", pos, entry, core_state[pos]); exceptions = lock_state_access(); switch (core_state[pos]) { case CORE_ON: rc = PSCI_RET_ALREADY_ON; break; case CORE_AWAKE: rc = PSCI_RET_ON_PENDING; break; case CORE_RET: rc = PSCI_RET_DENIED; break; case CORE_OFF: core_state[pos] = CORE_AWAKE; rc = PSCI_RET_SUCCESS; break; default: panic(); } unlock_state_access(exceptions); if (rc == PSCI_RET_SUCCESS) { generic_boot_set_core_ns_entry(pos, entry, context_id); release_secondary_early_hpen(pos); } return rc; }
int psci_cpu_on(uint32_t core_id, uint32_t entry, uint32_t context_id) { size_t pos = get_core_pos_mpidr(core_id); static bool core_is_released[CFG_TEE_CORE_NB_CORE]; if (!pos || pos >= CFG_TEE_CORE_NB_CORE) return PSCI_RET_INVALID_PARAMETERS; DMSG("core pos: %zu: ns_entry %#" PRIx32, pos, entry); if (core_is_released[pos]) { DMSG("core %zu already released", pos); return PSCI_RET_DENIED; } core_is_released[pos] = true; generic_boot_set_core_ns_entry(pos, entry, context_id); release_secondary_early_hpen(pos); return PSCI_RET_SUCCESS; }
int psci_affinity_info(uint32_t affinity, uint32_t lowest_affinity_level) { unsigned int pos = get_core_pos_mpidr(affinity); DMSG("core %zu, state %u", pos, core_state[pos]); if ((pos >= CFG_TEE_CORE_NB_CORE) || (lowest_affinity_level > PSCI_AFFINITY_LEVEL_ON)) { return PSCI_RET_INVALID_PARAMETERS; } switch (core_state[pos]) { case CORE_OFF: case CORE_RET: return PSCI_AFFINITY_LEVEL_OFF; case CORE_AWAKE: return PSCI_AFFINITY_LEVEL_ON_PENDING; case CORE_ON: return PSCI_AFFINITY_LEVEL_ON; default: panic(); } }