1/* SPDX-License-Identifier: BSD-3-Clause */
2/*
3 * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
4 */
5
6#include <asm.S>
7
8#define	R_AARCH64_RELATIVE	1027
9
10/**
11 * The following code is responsible for setting the initial value of the stack
12 * pointer and doing relocation on SP boot.
13 */
14FUNC __sp_entry, :
15	/* Use __stack_end linker symbol to set the load relative stack address. */
16	adrp	x4, __stack_end
17	add	x4, x4, :lo12:__stack_end
18	mov	sp, x4
19
20	/*
21	 * X4 = load address
22	 * X5 = relocation table start
23	 * X6 = relocation table end
24	 */
25	adr	x4, __sp_entry
26	adrp	x5, __rela_start
27	add	x5, x5, :lo12:__rela_start
28	adrp	x6, __rela_end
29	add	x6, x6, :lo12:__rela_end
30
31	/* Iterating through relocation entries */
32	cmp	x5, x6
33	beq	2f
34
35	/*
36	 * Loading relocation entry
37	 * X7 = r_offset
38	 * X8 = r_info
39	 * X9 = r_addend
40	 */
411:	ldp	x7, x8, [x5], #16
42	ldr	x9, [x5], #8
43
44	/* Only R_AARCH64_RELATIVE type is supported */
45	cmp	w8, #R_AARCH64_RELATIVE
46	bne	relocation_error
47
48	/*
49	 * Apply relative adjustment on address
50	 * *(load_address + r_offset) = load_address + r_addend
51	 */
52	add	x9, x9, x4
53	str	x9, [x7, x4]
54
55	cmp	x5, x6
56	bne	1b
57
582:
59	/* Clear BSS */
60	adrp	x4, __bss_start
61	add	x4, x4, :lo12:__bss_start
62	adrp	x5, __bss_end
63	add	x5, x5, :lo12:__bss_end
64
65	cmp	x4,	x5
66	b.eq	clear_bss_end
67
68clear_bss:
69	str	xzr,	[x4],	#8
70	cmp	x4,	x5
71	b.lt	clear_bss
72
73clear_bss_end:
74	b	_sp_entry
75
76relocation_error:
77	adr	X0,	error_invalid_relocation
78	bl	trace_puts
79	b	.
80
81	.align 8
82error_invalid_relocation:
83	.asciz "Only R_AARCH64_RELATIVE type relocation is supported"
84	.align 8
85END_FUNC __sp_entry
86
87BTI(emit_aarch64_feature_1_and     GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
88