/*
 * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "sdkconfig.h"

#define ALIGN_UP(SIZE, AL)   (((SIZE) + (AL - 1)) & ~(AL - 1))

/* CPU instruction prefetch padding size for flash mmap scenario */
#define _esp_flash_mmap_prefetch_pad_size 16

/*
 * PMP region granularity size
 * Software may determine the PMP granularity by writing zero to pmp0cfg, then writing all ones
 * to pmpaddr0, then reading back pmpaddr0. If G is the index of the least-significant bit set,
 * the PMP granularity is 2^G+2 bytes.
 */
#ifdef CONFIG_SOC_CPU_PMP_REGION_GRANULARITY
#define _esp_pmp_align_size CONFIG_SOC_CPU_PMP_REGION_GRANULARITY
#else
#define _esp_pmp_align_size 0
#endif

/* CPU instruction prefetch padding size for memory protection scenario */
#ifdef CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE
#define _esp_memprot_prefetch_pad_size CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE
#else
#define _esp_memprot_prefetch_pad_size 0
#endif

/* Memory alignment size for PMS */
#ifdef CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE
#define _esp_memprot_align_size CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE
#else
#define _esp_memprot_align_size 0
#endif

#if CONFIG_APP_BUILD_TYPE_RAM
#define _esp_mmu_page_size 0
#else
#define _esp_mmu_page_size CONFIG_MMU_PAGE_SIZE
#endif

#define ALIGN_UP(SIZE, AL)   (((SIZE) + (AL - 1)) & ~(AL - 1))

#if CONFIG_SOC_RTC_MEM_SUPPORTED
    #if CONFIG_BOOTLOADER_RESERVE_RTC_MEM
        /**
         * The ESP_BOOTLOADER_RESERVE_RTC size must have the same alignment of RTC_TIMER_RESERVE_RTC, else
         * the segment will overflow at link time because not enough bytes are allocated for the RTC segment.
         */
        #ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
            #define ESP_BOOTLOADER_RESERVE_RTC ALIGN_UP(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE, 8)
        #else
            #define ESP_BOOTLOADER_RESERVE_RTC ALIGN_UP(CONFIG_BOOTLOADER_RESERVE_RTC_SIZE, 8)
        #endif // not CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC
    #else
        #define ESP_BOOTLOADER_RESERVE_RTC 0
    #endif // not CONFIG_BOOTLOADER_RESERVE_RTC_MEM

    /* rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). For rtc_timer_data_in_rtc_mem section. */
    #define RTC_TIMER_RESERVE_RTC (24)

    #if CONFIG_IDF_TARGET_ESP32
        #define RESERVE_RTC_MEM (RTC_TIMER_RESERVE_RTC)
    #elif CONFIG_ESP_ROM_HAS_LP_ROM && CONFIG_ULP_COPROC_ENABLED
	/* RTC Reserved is placed before ULP memory, expand it to make sure the ULP start address
	   has the required alignment */
	    #define ULP_ALIGNMENT_REQ_BYTES 256
        #define RESERVE_RTC_MEM ALIGN_UP(ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC, ULP_ALIGNMENT_REQ_BYTES)
    #else
        #define RESERVE_RTC_MEM (ESP_BOOTLOADER_RESERVE_RTC + RTC_TIMER_RESERVE_RTC)
    #endif

    #if CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND
        #define MSPI_WORKAROUND_SIZE   CONFIG_P4_REV3_MSPI_WORKAROUND_SIZE
    #else
        #define MSPI_WORKAROUND_SIZE   0x0
    #endif

#endif // SOC_RTC_MEM_SUPPORTED

#define QUOTED_STRING(STRING) #STRING
#define ASSERT_SECTIONS_GAP(PREV_SECTION, NEXT_SECTION)                   \
ASSERT((ADDR(NEXT_SECTION) == ADDR(PREV_SECTION) + SIZEOF(PREV_SECTION)), \
        QUOTED_STRING(The gap between PREV_SECTION and NEXT_SECTION must not exist to produce the final bin image.))

#define ALIGNED_SYMBOL(X, SYMBOL)   \
\n    . = ALIGN(X);                 \
\n    SYMBOL = ABSOLUTE(.);

#if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME
#define EH_FRAME_LINKING_ENABLED 1
#endif

#if EH_FRAME_LINKING_ENABLED
#define SECTION_AFTER_FLASH_RODATA .eh_frame_hdr
#else
#define SECTION_AFTER_FLASH_RODATA .flash.tdata
#endif
