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