summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv7/start.S29
-rw-r--r--arch/arm/cpu/armv8/start.S23
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/xferlist.c25
-rw-r--r--arch/arm/lib/xferlist.h19
5 files changed, 98 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 69e281b086a..7730a16e512 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -152,9 +152,38 @@ ENDPROC(c_runtime_cpu_setup)
*
*************************************************************************/
WEAK(save_boot_params)
+#if (IS_ENABLED(CONFIG_BLOBLIST))
+ /* Calculate the PC-relative address of saved_args */
+ adr r12, saved_args_offset
+ ldr r13, saved_args_offset
+ add r12, r12, r13
+
+ /*
+ * Intentionally swapping r0 with r2 in order to simplify the C
+ * function we use later.
+ */
+ str r2, [r12]
+ str r1, [r12, #4]
+ str r0, [r12, #8]
+ str r3, [r12, #12]
+#endif
b save_boot_params_ret @ back to my caller
ENDPROC(save_boot_params)
+#if (IS_ENABLED(CONFIG_BLOBLIST))
+saved_args_offset:
+ .long saved_args - . /* offset from current code to save_args */
+
+ .section .data
+ .align 2
+ .global saved_args
+saved_args:
+ .rept 4
+ .word 0
+ .endr
+END(saved_args)
+#endif
+
#ifdef CONFIG_ARMV7_LPAE
WEAK(switch_to_hypervisor)
b switch_to_hypervisor_ret
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index 6cc1d26e5e2..74612802617 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -370,5 +370,28 @@ ENTRY(c_runtime_cpu_setup)
ENDPROC(c_runtime_cpu_setup)
WEAK(save_boot_params)
+#if (IS_ENABLED(CONFIG_BLOBLIST))
+ /* Calculate the PC-relative address of saved_args */
+ adr x9, saved_args_offset
+ ldr w10, saved_args_offset
+ add x9, x9, w10, sxtw
+
+ stp x0, x1, [x9]
+ stp x2, x3, [x9, #16]
+#endif
b save_boot_params_ret /* back to my caller */
ENDPROC(save_boot_params)
+
+#if (IS_ENABLED(CONFIG_BLOBLIST))
+saved_args_offset:
+ .long saved_args - . /* offset from current code to save_args */
+
+ .section .data
+ .align 2
+ .global saved_args
+saved_args:
+ .rept 4
+ .dword 0
+ .endr
+END(saved_args)
+#endif
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index b1bcd374662..67275fba616 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -85,6 +85,8 @@ obj-y += psci-dt.o
obj-$(CONFIG_DEBUG_LL) += debug.o
+obj-$(CONFIG_BLOBLIST) += xferlist.o
+
# For EABI conformant tool chains, provide eabi_compat()
ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
extra-y += eabi_compat.o
diff --git a/arch/arm/lib/xferlist.c b/arch/arm/lib/xferlist.c
new file mode 100644
index 00000000000..f9c5d88bd47
--- /dev/null
+++ b/arch/arm/lib/xferlist.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Linaro Limited
+ * Author: Raymond Mao <[email protected]>
+ */
+#include <linux/types.h>
+#include <errno.h>
+#include <bloblist.h>
+#include "xferlist.h"
+
+int xferlist_from_boot_arg(ulong addr, ulong size)
+{
+ int ret;
+
+ ret = bloblist_check(saved_args[3], size);
+ if (ret)
+ return ret;
+
+ ret = bloblist_check_reg_conv(saved_args[0], saved_args[2],
+ saved_args[1]);
+ if (ret)
+ return ret;
+
+ return bloblist_reloc((void *)addr, size);
+}
diff --git a/arch/arm/lib/xferlist.h b/arch/arm/lib/xferlist.h
new file mode 100644
index 00000000000..60d79c1a8eb
--- /dev/null
+++ b/arch/arm/lib/xferlist.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause */
+/*
+ * Copyright (C) 2023 Linaro Limited
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#ifndef _XFERLIST_H_
+#define _XFERLIST_H_
+
+/*
+ * Boot parameters saved from start.S
+ * saved_args[0]: FDT base address
+ * saved_args[1]: Bloblist signature
+ * saved_args[2]: must be 0
+ * saved_args[3]: Bloblist base address
+ */
+extern unsigned long saved_args[];
+
+#endif /* _XFERLIST_H_ */