summaryrefslogtreecommitdiff
path: root/src/arch/arm64/armv8
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-09-19 15:47:27 -0500
committerPatrick Georgi <pgeorgi@google.com>2015-03-28 08:44:48 +0100
commit93eea8822d6c5932bb77d91fac35101ab2274490 (patch)
treeec620ef6efdd0a84bec6fe1fc3441dd626493834 /src/arch/arm64/armv8
parentbfbfcf719c6a64670cb11d7eb596e07c06685a49 (diff)
arm64: Provide secmon trampoline for restart
If an exception is taken that the secmon won't return to, there needs to be way to reset that cpu's state w.r.t. stack usage. Therefore, provide secmon_trampoline which will reinitialize the exception stack and SP_EL0 and start executing with SP_EL0 like the initial state of the secmon entry. BUG=chrome-os-partner:30785 BRANCH=None TEST=Built and booted to kernel. Also tested when PSCI is employed in the kernel. Change-Id: Ie9f5bbe715dcbcf8b67ea40f9a3a5088ac7aa2ad Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: f1f546ee3e9eca93baaa1ae0437351205bf548a5 Original-Change-Id: Ia3da75e1fa0251c8ea30eb0b0523c8a51c03b917 Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/218922 Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/9096 Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/arch/arm64/armv8')
-rw-r--r--src/arch/arm64/armv8/secmon/Makefile.inc1
-rw-r--r--src/arch/arm64/armv8/secmon/secmon.h34
-rw-r--r--src/arch/arm64/armv8/secmon/secmon_init.c5
-rw-r--r--src/arch/arm64/armv8/secmon/trampoline.S51
4 files changed, 91 insertions, 0 deletions
diff --git a/src/arch/arm64/armv8/secmon/Makefile.inc b/src/arch/arm64/armv8/secmon/Makefile.inc
index 040f56829a..03b93edaf2 100644
--- a/src/arch/arm64/armv8/secmon/Makefile.inc
+++ b/src/arch/arm64/armv8/secmon/Makefile.inc
@@ -33,6 +33,7 @@ secmon-S-ccopts += -I$(src)/arch/arm64/include/armv8/ -include $(src)/include/kc
secmon-y += secmon_init.c
secmon-y += smc.c
+secmon-y += trampoline.S
secmon-y += ../exception.c
secmon-y += ../../cpu.c
secmon-y += ../../transition_asm.S ../../transition.c
diff --git a/src/arch/arm64/armv8/secmon/secmon.h b/src/arch/arm64/armv8/secmon/secmon.h
new file mode 100644
index 0000000000..267ad23710
--- /dev/null
+++ b/src/arch/arm64/armv8/secmon/secmon.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 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
+ */
+
+#ifndef __SECMON_SECMON_H__
+#define __SECMON_SECMON_H__
+
+/*
+ * The secmon_trampoline() switches mode to EL3t, reinitializing both
+ * EL3t and EL3h stacks.
+ */
+void secmon_trampoline(void *entry, void *arg);
+
+/* Wait for action to take place. */
+void secmon_wait_for_action(void);
+
+#endif /* __SECMON_SECMON_H__ */
diff --git a/src/arch/arm64/armv8/secmon/secmon_init.c b/src/arch/arm64/armv8/secmon/secmon_init.c
index de433bb9ef..6172505523 100644
--- a/src/arch/arm64/armv8/secmon/secmon_init.c
+++ b/src/arch/arm64/armv8/secmon/secmon_init.c
@@ -29,6 +29,7 @@
#include <console/console.h>
#include <rmodule.h>
#include <stddef.h>
+#include "secmon.h"
static void cpu_init(int bsp)
{
@@ -62,7 +63,11 @@ static void secmon_init(struct secmon_params *params, int bsp)
transition_with_entry(params->entry, params->arg, &exc_state);
}
+ secmon_wait_for_action();
+}
+void secmon_wait_for_action(void)
+{
arch_cpu_wait_for_action();
}
diff --git a/src/arch/arm64/armv8/secmon/trampoline.S b/src/arch/arm64/armv8/secmon/trampoline.S
new file mode 100644
index 0000000000..cb6a4e4a93
--- /dev/null
+++ b/src/arch/arm64/armv8/secmon/trampoline.S
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 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/asm.h>
+
+/*
+ * Call entry(arg) after reinitializing stack state.
+ * void secmon_trampoline(void *entry, void *arg);
+ */
+ENTRY(secmon_trampoline)
+ mov x22, x0 /* x22 = function pointer */
+ mov x23, x1 /* x23 = argument */
+ bl smp_processor_id /* x0 = cpu */
+ mov x24, x0
+
+ /* Set the exception stack for this cpu. */
+ bl cpu_get_exception_stack
+ msr SPSel, #1
+ isb
+ mov sp, x0
+
+ /* Have stack pointer use SP_EL0. */
+ msr SPSel, #0
+ isb
+
+ /* Set stack for this cpu. */
+ mov x0, x24 /* x0 = cpu */
+ bl cpu_get_stack
+ mov sp, x0
+
+ /* Call the function with specified argument. */
+ mov x1, x22
+ mov x0, x23
+ br x1
+ENDPROC(secmon_trampoline)