summaryrefslogtreecommitdiff
path: root/src/arch/arm64/startup.c
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@google.com>2014-11-21 15:42:40 -0800
committerPatrick Georgi <pgeorgi@google.com>2015-04-10 20:47:44 +0200
commit9482498003d500db6aced4c94bf4ab3485cab18e (patch)
treee2c2ec3cc22f6893d772da62782b3795245c101a /src/arch/arm64/startup.c
parentb17f580d2955822d0095e1fb914d98eeabf2a708 (diff)
arm64: Add support for save/restore registers for CPU startup.
startup.c provides function to enable CPU in any stage to save register data that can be used by secondary CPU (for normal boot) or any CPU (for resume boot). stage_entry.S defines space for saving arm64_startup_data. This can be filled by: 1) Primary CPU before bringing up secondary CPUs so that the secondary can use register values to initialize MMU-related and other required registers to appropriate values. 2) CPU suspend path to ensure that on resume the values which were saved are restored appropriately. stage_entry.S provides a common path for both normal and resume boot to initialize saved registers. For resume path, it is important to set the secondary entry point for startup since x26 needs to be 1 for enabling MMU and cache. This also ensures that we do not fall into false memory cache errors which caused CPU to fail during normal / resume boot. Thus, we can get rid of the stack cache invalidate for secondary CPUs. BUG=chrome-os-partner:33962 BRANCH=None TEST=Compiles and boots both CPU0 and CPU1 on ryu without mmu_enable and stack cache invalidate for CPU1. Change-Id: Ia4ca0e7d35c0738dbbaa926cce4268143c6f9de3 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 9f5e78469313ddd144ad7cf5abc3e07cb712183a Original-Signed-off-by: Furquan Shaikh <furquan@google.com> Original-Change-Id: I527a95779cf3fed37392b6605b096f54f8286d64 Original-Reviewed-on: https://chromium-review.googlesource.com/231561 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Original-Tested-by: Furquan Shaikh <furquan@chromium.org> Original-Commit-Queue: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/9540 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/arch/arm64/startup.c')
-rw-r--r--src/arch/arm64/startup.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/arch/arm64/startup.c b/src/arch/arm64/startup.c
new file mode 100644
index 0000000000..d2b76913d2
--- /dev/null
+++ b/src/arch/arm64/startup.c
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <arch/cache.h>
+#include <arch/lib_helpers.h>
+#include <arch/startup.h>
+#include <console/console.h>
+
+/* This space is defined in stage_entry.S. */
+extern u8 _arm64_startup_data[];
+
+static inline void save_element(size_t index, uint64_t val)
+{
+ uint64_t *ptr = (uint64_t *)_arm64_startup_data;
+
+ ptr[index] = val;
+}
+
+/*
+ * startup_save_cpu_data is used to save register values that need to be setup
+ * when a CPU starts booting. This is used by secondary CPUs as well as resume
+ * path to directly setup MMU and other related registers.
+ */
+void startup_save_cpu_data(void)
+{
+ save_element(MAIR_INDEX, raw_read_mair_current());
+ save_element(TCR_INDEX, raw_read_tcr_current());
+ save_element(TTBR0_INDEX, raw_read_ttbr0_current());
+ save_element(VBAR_INDEX, raw_read_vbar_current());
+
+ if (get_current_el() == EL3)
+ save_element(SCR_INDEX, raw_read_scr_el3());
+
+ dcache_clean_by_mva(_arm64_startup_data,
+ NUM_ELEMENTS * PER_ELEMENT_SIZE_BYTES);
+}