blob: b5e83a0b8dc1904405953f718e45a80bbd40a3bf [file] [log] [blame]
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright The Zephyr Project Contributors
*/
#include <stddef.h>
#include <string.h>
#include <zephyr/sys/util_macro.h>
#include <zephyr/linker/section_tags.h>
#include <zephyr/linker/linker-defs.h>
/* LCOV_EXCL_START
*
* This code is called so early in the boot process that code coverage
* doesn't work properly. In addition, not all arches call this code,
* some like x86 do this with optimized assembly
*/
/**
* @brief equivalent of memset() for early boot usage
*
* Architectures that can't safely use the regular (optimized) memset very
* early during boot because e.g. hardware isn't yet sufficiently initialized
* may override this with their own safe implementation.
*/
__boot_func
void __weak arch_early_memset(void *dst, int c, size_t n)
{
(void) memset(dst, c, n);
}
/**
* @brief equivalent of memcpy() for early boot usage
*
* Architectures that can't safely use the regular (optimized) memcpy very
* early during boot because e.g. hardware isn't yet sufficiently initialized
* may override this with their own safe implementation.
*/
__boot_func
void __weak arch_early_memcpy(void *dst, const void *src, size_t n)
{
(void) memcpy(dst, src, n);
}
/**
* @brief Clear BSS
*
* This routine clears the BSS region, so all bytes are 0.
*/
__boot_func
void arch_bss_zero(void)
{
if (IS_ENABLED(CONFIG_SKIP_BSS_CLEAR)) {
return;
}
arch_early_memset(__bss_start, 0, __bss_end - __bss_start);
#if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_ccm))
arch_early_memset(&__ccm_bss_start, 0,
(uintptr_t) &__ccm_bss_end
- (uintptr_t) &__ccm_bss_start);
#endif
#if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_dtcm))
arch_early_memset(&__dtcm_bss_start, 0,
(uintptr_t) &__dtcm_bss_end
- (uintptr_t) &__dtcm_bss_start);
#endif
#if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_ocm))
arch_early_memset(&__ocm_bss_start, 0,
(uintptr_t) &__ocm_bss_end
- (uintptr_t) &__ocm_bss_start);
#endif
#ifdef CONFIG_CODE_DATA_RELOCATION
extern void bss_zeroing_relocation(void);
bss_zeroing_relocation();
#endif /* CONFIG_CODE_DATA_RELOCATION */
#ifdef CONFIG_COVERAGE_GCOV
arch_early_memset(&__gcov_bss_start, 0,
((uintptr_t) &__gcov_bss_end - (uintptr_t) &__gcov_bss_start));
#endif /* CONFIG_COVERAGE_GCOV */
#ifdef CONFIG_NOCACHE_MEMORY
arch_early_memset(&_nocache_ram_start, 0,
(uintptr_t) &_nocache_ram_end - (uintptr_t) &_nocache_ram_start);
#endif
}
#ifdef CONFIG_LINKER_USE_BOOT_SECTION
/**
* @brief Clear BSS within the boot region
*
* This routine clears the BSS within the boot region.
* This is separate from arch_bss_zero() as boot region may
* contain symbols required for the boot process before
* paging is initialized.
*/
__boot_func
void arch_bss_zero_boot(void)
{
arch_early_memset(&lnkr_boot_bss_start, 0,
(uintptr_t)&lnkr_boot_bss_end
- (uintptr_t)&lnkr_boot_bss_start);
}
#endif /* CONFIG_LINKER_USE_BOOT_SECTION */
#ifdef CONFIG_LINKER_USE_PINNED_SECTION
/**
* @brief Clear BSS within the pinned region
*
* This routine clears the BSS within the pinned region.
* This is separate from arch_bss_zero() as pinned region may
* contain symbols required for the boot process before
* paging is initialized.
*/
#ifdef CONFIG_LINKER_USE_BOOT_SECTION
__boot_func
#else
__pinned_func
#endif /* CONFIG_LINKER_USE_BOOT_SECTION */
void arch_bss_zero_pinned(void)
{
arch_early_memset(&lnkr_pinned_bss_start, 0,
(uintptr_t)&lnkr_pinned_bss_end
- (uintptr_t)&lnkr_pinned_bss_start);
}
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
/* LCOV_EXCL_STOP */