diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm/cpu/armv7/start.S | 29 | ||||
| -rw-r--r-- | arch/arm/cpu/armv8/start.S | 23 | ||||
| -rw-r--r-- | arch/arm/lib/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/lib/xferlist.c | 25 | ||||
| -rw-r--r-- | arch/arm/lib/xferlist.h | 19 |
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_ */ |
