1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  * Copyright The Zephyr Project Contributors
4  */
5 
6 #include <stddef.h>
7 #include <string.h>
8 #include <zephyr/sys/util_macro.h>
9 #include <zephyr/linker/section_tags.h>
10 #include <zephyr/linker/linker-defs.h>
11 
12 /* LCOV_EXCL_START
13  *
14  * This code is called so early in the boot process that code coverage
15  * doesn't work properly. In addition, not all arches call this code,
16  * some like x86 do this with optimized assembly
17  */
18 
19 /**
20  * @brief equivalent of memset() for early boot usage
21  *
22  * Architectures that can't safely use the regular (optimized) memset very
23  * early during boot because e.g. hardware isn't yet sufficiently initialized
24  * may override this with their own safe implementation.
25  */
26 __boot_func
arch_early_memset(void * dst,int c,size_t n)27 void __weak arch_early_memset(void *dst, int c, size_t n)
28 {
29 	(void) memset(dst, c, n);
30 }
31 
32 /**
33  * @brief equivalent of memcpy() for early boot usage
34  *
35  * Architectures that can't safely use the regular (optimized) memcpy very
36  * early during boot because e.g. hardware isn't yet sufficiently initialized
37  * may override this with their own safe implementation.
38  */
39 __boot_func
arch_early_memcpy(void * dst,const void * src,size_t n)40 void __weak arch_early_memcpy(void *dst, const void *src, size_t n)
41 {
42 	(void) memcpy(dst, src, n);
43 }
44 
45 /**
46  * @brief Clear BSS
47  *
48  * This routine clears the BSS region, so all bytes are 0.
49  */
50 __boot_func
arch_bss_zero(void)51 void arch_bss_zero(void)
52 {
53 	if (IS_ENABLED(CONFIG_SKIP_BSS_CLEAR)) {
54 		return;
55 	}
56 
57 	arch_early_memset(__bss_start, 0, __bss_end - __bss_start);
58 #if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_dtcm))
59 	arch_early_memset(&__dtcm_bss_start, 0,
60 		       (uintptr_t) &__dtcm_bss_end
61 		       - (uintptr_t) &__dtcm_bss_start);
62 #endif
63 #if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_ocm))
64 	arch_early_memset(&__ocm_bss_start, 0,
65 		       (uintptr_t) &__ocm_bss_end
66 		       - (uintptr_t) &__ocm_bss_start);
67 #endif
68 #ifdef CONFIG_CODE_DATA_RELOCATION
69 	extern void bss_zeroing_relocation(void);
70 
71 	bss_zeroing_relocation();
72 #endif	/* CONFIG_CODE_DATA_RELOCATION */
73 #ifdef CONFIG_COVERAGE_GCOV
74 	arch_early_memset(&__gcov_bss_start, 0,
75 		       ((uintptr_t) &__gcov_bss_end - (uintptr_t) &__gcov_bss_start));
76 #endif /* CONFIG_COVERAGE_GCOV */
77 #ifdef CONFIG_NOCACHE_MEMORY
78 	arch_early_memset(&_nocache_ram_start, 0,
79 			(uintptr_t) &_nocache_ram_end - (uintptr_t) &_nocache_ram_start);
80 #endif
81 }
82 
83 #ifdef CONFIG_LINKER_USE_BOOT_SECTION
84 /**
85  * @brief Clear BSS within the boot region
86  *
87  * This routine clears the BSS within the boot region.
88  * This is separate from arch_bss_zero() as boot region may
89  * contain symbols required for the boot process before
90  * paging is initialized.
91  */
92 __boot_func
arch_bss_zero_boot(void)93 void arch_bss_zero_boot(void)
94 {
95 	arch_early_memset(&lnkr_boot_bss_start, 0,
96 		       (uintptr_t)&lnkr_boot_bss_end
97 		       - (uintptr_t)&lnkr_boot_bss_start);
98 }
99 #endif /* CONFIG_LINKER_USE_BOOT_SECTION */
100 
101 #ifdef CONFIG_LINKER_USE_PINNED_SECTION
102 /**
103  * @brief Clear BSS within the pinned region
104  *
105  * This routine clears the BSS within the pinned region.
106  * This is separate from arch_bss_zero() as pinned region may
107  * contain symbols required for the boot process before
108  * paging is initialized.
109  */
110 #ifdef CONFIG_LINKER_USE_BOOT_SECTION
111 __boot_func
112 #else
113 __pinned_func
114 #endif /* CONFIG_LINKER_USE_BOOT_SECTION */
arch_bss_zero_pinned(void)115 void arch_bss_zero_pinned(void)
116 {
117 	arch_early_memset(&lnkr_pinned_bss_start, 0,
118 		       (uintptr_t)&lnkr_pinned_bss_end
119 		       - (uintptr_t)&lnkr_pinned_bss_start);
120 }
121 #endif /* CONFIG_LINKER_USE_PINNED_SECTION */
122 
123 /* LCOV_EXCL_STOP */
124