From d8060904eea998136f39866d0eaba233882a5f3f Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Tue, 25 Nov 2014 16:47:56 -0600 Subject: [PATCH] tegra132: prepare cpu startup in psci In order to start CPUs while in secmon/psci one needs to set up the proper SoC state. Therefore, refactor the current CPU startup API to allow for this by adding cpu_prepare_startup() and start_cpu_silent(). BUG=chrome-os-partner:32136 BRANCH=None TEST=Built and booted kernel. Change-Id: I1424500f6c9398f7d44350949c25bb3d4832cec7 Signed-off-by: Patrick Georgi Original-Commit-Id: 70f9cf67085b345b529b41dd6554e37d38a5b350 Original-Change-Id: I842a391d3e27ddbfcdef1a2d60e3c66e60f99c77 Original-Signed-off-by: Aaron Durbin Original-Reviewed-on: https://chromium-review.googlesource.com/231936 Original-Reviewed-by: Furquan Shaikh Reviewed-on: http://review.coreboot.org/9531 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/nvidia/tegra132/Makefile.inc | 2 ++ src/soc/nvidia/tegra132/cpu.c | 18 +++++++++++++----- src/soc/nvidia/tegra132/include/soc/cpu.h | 5 ++++- src/soc/nvidia/tegra132/psci.c | 12 ++++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/soc/nvidia/tegra132/Makefile.inc b/src/soc/nvidia/tegra132/Makefile.inc index 82ac11a7c0..a46a2e5e07 100644 --- a/src/soc/nvidia/tegra132/Makefile.inc +++ b/src/soc/nvidia/tegra132/Makefile.inc @@ -94,6 +94,8 @@ ramstage-$(CONFIG_DRIVERS_UART) += uart.c ramstage-y += ../tegra/usb.c ramstage-$(CONFIG_ARCH_USE_SECURE_MONITOR) += secmon.c +secmon-$(CONFIG_ARCH_USE_SECURE_MONITOR) += 32bit_reset.S +secmon-$(CONFIG_ARCH_USE_SECURE_MONITOR) += cpu.c secmon-$(CONFIG_ARCH_USE_SECURE_MONITOR) += cpu_lib.S secmon-$(CONFIG_ARCH_USE_SECURE_MONITOR) += psci.c secmon-$(CONFIG_ARCH_USE_SECURE_MONITOR) += uart.c diff --git a/src/soc/nvidia/tegra132/cpu.c b/src/soc/nvidia/tegra132/cpu.c index 5dd4c53493..c79bc9cf4e 100644 --- a/src/soc/nvidia/tegra132/cpu.c +++ b/src/soc/nvidia/tegra132/cpu.c @@ -60,12 +60,8 @@ static void set_armv8_64bit_reset_vector(uintptr_t entry) write32(0, &pmc->secure_scratch35); } - -void start_cpu(int cpu, void *entry_64) +void cpu_prepare_startup(void *entry_64) { - printk(BIOS_DEBUG, "Starting CPU%d @ %p trampolining to %p.\n", - cpu, reset_entry_32bit, entry_64); - /* Warm reset vector is pulled from the PMC scratch registers. */ set_armv8_64bit_reset_vector((uintptr_t)entry_64); @@ -75,6 +71,18 @@ void start_cpu(int cpu, void *entry_64) * to the traompoline location. */ set_armv8_32bit_reset_vector((uintptr_t)reset_entry_32bit); +} +void start_cpu_silent(int cpu, void *entry_64) +{ + cpu_prepare_startup(entry_64); enable_core_clocks(cpu); } + +void start_cpu(int cpu, void *entry_64) +{ + printk(BIOS_DEBUG, "Starting CPU%d @ %p trampolining to %p.\n", + cpu, reset_entry_32bit, entry_64); + + start_cpu_silent(cpu, entry_64); +} diff --git a/src/soc/nvidia/tegra132/include/soc/cpu.h b/src/soc/nvidia/tegra132/include/soc/cpu.h index c957d59608..b50c09bf89 100644 --- a/src/soc/nvidia/tegra132/include/soc/cpu.h +++ b/src/soc/nvidia/tegra132/include/soc/cpu.h @@ -25,8 +25,11 @@ * should be a 32-bit address. */ void start_cpu(int cpu, void *entry_64); +/* Start CPU wthout any log messages. */ +void start_cpu_silent(int cpu, void *entry_64); +/* Prepare SoC for starting a CPU. Initialize the global state of the SoC. */ +void cpu_prepare_startup(void *entry_64); void reset_entry_32bit(void); #endif /* __SOC_NVIDIA_TEGRA132_CPU_H__ */ - diff --git a/src/soc/nvidia/tegra132/psci.c b/src/soc/nvidia/tegra132/psci.c index 0b5d793aaf..b075ffc353 100644 --- a/src/soc/nvidia/tegra132/psci.c +++ b/src/soc/nvidia/tegra132/psci.c @@ -18,9 +18,21 @@ */ #include +#include + +static void *cpu_on_entry_point; void psci_soc_init(uintptr_t cpu_on_entry) { + /* + * Stash secmon entry point for CPUs starting up. The 32-bit reset + * vector register is accessible in < EL3 so one has to attempt to + * plug the potential race for that register being changed out from + * under us. Therefore, we set the appropriate registers here, but + * it is also done on each CPU_ON request. + */ + cpu_on_entry_point = (void *)cpu_on_entry; + cpu_prepare_startup(cpu_on_entry_point); } static size_t children_at_level(int parent_level, uint64_t mpidr)