/*
 * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
 * Copyright (c) 2020-2021 IAR Systems AB
 * Copyright (c) 2022-2024 Cypress Semiconductor Corporation (an Infineon company)
 * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/***********  WARNING: This is an auto-generated file. Do not edit!  ***********/

/*
 * Customized region name prefix abbreviation:
 *  LR : A Load region.
 *  ER : A typical execution region.
 *  PT : An empty execution region used as position-tag/address-alignment.
 *
 * No applying customized prefixes on linker/system reserved/intentional
 * names, such as 'ARM_LIB_STACK'.
 */

#include "region_defs.h"

/* Include file with definitions for section alignments.
 * Note: it should be included after region_defs.h to let platform define
 * default values if needed. */
#include "tfm_s_linker_alignments.h"

#if ((defined(__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \
     (defined(__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__)) || \
     (defined(__ARM8EM_MAINLINE__) && (__CORE__ == __ARM8EM_MAINLINE__)))
#define STACKSEAL_SIZE  0x8
#else
#define STACKSEAL_SIZE  0x0
#endif

/* Position tag block: code + RO-data */
define block PT_RO_START with alignment = TFM_LINKER_PT_RO_ALIGNMENT, size = 0 { };
define block PT_RO_END with alignment = TFM_LINKER_PT_RO_ALIGNMENT, size = 0 { };

define block ER_VECTORS with size = S_CODE_VECTOR_TABLE_SIZE {
    ro section .intvec
};

/* Position tag: Start of unprivileged code (shared, not PXN) */
define block PT_UNPRIV_CODE_START with alignment = TFM_LINKER_PT_UNPRIV_CODE_ALIGNMENT, size = 0 { };

#ifdef CONFIG_TFM_USE_TRUSTZONE
/*
 * Place the CMSE Veneers (containing the SG instruction) in a separate
 * at least 32 bytes aligned region so that the SAU can be programmed to
 * just set this region as Non-Secure Callable.
 */
define block ER_VENEER with alignment = TFM_LINKER_VENEERS_ALIGNMENT {
    section Veneer$$CMSE
};

define block VENEER_ALIGN with alignment = TFM_LINKER_VENEERS_ALIGNMENT, size = 0 { };
#endif

/* Shared library code */
define block ER_UNPRIV_CODE {
    ro code object *(:sys), /* IAR runtime libraries */
    ro code object *libtfm_sprt*,
    ro code object *libqcbor*,
    ro code object *libtfm_t_cose_s*,
};

/* Position tag: End of unprivileged code (shared, not PXN) */
define block PT_UNPRIV_CODE_END with alignment = TFM_LINKER_PT_UNPRIV_CODE_ALIGNMENT, size = 0 { };

/* Position tag: Start of Application RoT code (unprivileged, PXN) */
define block PT_APP_ROT_CODE_START with alignment = TFM_LINKER_PT_APP_ROT_CODE_ALIGNMENT, size = 0 { };

define block ER_APP_ROT_CODE {
    ro code object *tfm_app_rot_partition*,
    section TFM_*_APP-ROT_ATTR_FN,
       ro code object *tfm_*partition_ps.*,
       section TFM_SP_PS_APP-ROT_ATTR_FN,
};

/* Position tag: End of Application RoT code (unprivileged, PXN) */
define block PT_APP_ROT_CODE_END with alignment = TFM_LINKER_PT_APP_ROT_CODE_ALIGNMENT, size = 0 { };

/* Position tag: Start of PSA RoT code (privileged) */
define block PT_PSA_ROT_CODE_START with alignment = TFM_LINKER_PT_PSA_ROT_CODE_ALIGNMENT, size = 0 { };

define block ER_PSA_ROT_CODE {
    ro code object *tfm_psa_rot_partition*,
    section TFM_*_PSA-ROT_ATTR_FN,
       ro code object *tfm_*partition_its.*,
       section TFM_SP_ITS_PSA-ROT_ATTR_FN,
       ro code object *tfm_*partition_crypto.*,
       ro code object *tfpsacrypto.*,
       ro code object *tfpsacrypto*acceleration.*,
       section TFM_SP_CRYPTO_PSA-ROT_ATTR_FN,
       ro code object *tfm_*partition_platform.*,
       section TFM_SP_PLATFORM_PSA-ROT_ATTR_FN,
};

/* Capture all remaining code (except RAM code) in the privileged TF-M
 * code region.
 */
define block ER_TFM_CODE {
    ro code,
};

/* Position tag: End of PSA RoT code (privileged) */
define block PT_PSA_ROT_CODE_END with alignment = TFM_LINKER_PT_PSA_ROT_CODE_ALIGNMENT, size = 0 { };

/* Position tag: Start of RO-Data (unprivileged, execute-never) */
define block PT_RO_DATA_START with alignment = TFM_LINKER_PT_RO_DATA_ALIGNMENT, size = 0 { };

/* Collect all RO-data into a single unprivileged region */
define block ER_RO_DATA {
    ro data,
};

/**** Section for holding partition RO load data */
/*
 * Sort the partition info by priority to guarantee the initing order.
 * The first loaded partition will be inited at last in SFN model.
 */
define block TFM_SP_LOAD_LIST with alignment = TFM_LINKER_PT_RO_DATA_ALIGNMENT {
    ro section .part_load
};

/* Position tag: End of RO-Data (unprivileged, execute-never) */
define block PT_RO_DATA_END with alignment = TFM_LINKER_PT_RO_DATA_ALIGNMENT, size = 0 { };

#ifdef S_RAM_CODE_START
/* Flash drivers code that gets copied from Flash */
initialize by copy {
    ro object *libflash_drivers*,
};

define block ER_CODE_SRAM with fixed order, alignment = 32, maximum size = S_RAM_CODE_SIZE {
    rw section .text,
    rw section .rodata,
    rw section .textrw, /* __ramfunc */
};

place at address S_RAM_CODE_START { block ER_CODE_SRAM };
#endif

/**** Base address of secure data area */
define block TFM_SECURE_DATA_START with size = 0 { };

/* Shared area between BL2 and runtime to exchange data */
define block TFM_SHARED_DATA with alignment = TFM_LINKER_BL2_SHARED_DATA_ALIGNMENT, size = BOOT_TFM_SHARED_DATA_SIZE { };

keep {block TFM_SHARED_DATA};

/* Position tag: Start of Application RoT data (unprivileged) */
define block PT_APP_ROT_DATA_START with alignment = TFM_LINKER_PT_APP_ROT_DATA_ALIGNMENT, size = 0 { };

#ifdef CONFIG_TFM_PARTITION_META
define block TFM_SP_META_PTR with alignment = TFM_LINKER_SP_META_PTR_ALIGNMENT {
    zi section .bss.SP_META_PTR_SPRTL_INST
};

/*
 * This empty, zero long execution region is here to mark the end address
 * of TFM partition metadata pointer region.
 */
define block TFM_SP_META_PTR_END with alignment = TFM_LINKER_SP_META_PTR_ALIGNMENT, size = 0 { };
#endif

/* Position tag: Start of Application RoT partition's private data */
define block PT_TFM_SP_PS_PRIVATE_DATA_START with alignment = TFM_LINKER_PT_AROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };

define block ER_TFM_SP_PS_RWZI {
    rw data object *tfm_*partition_ps.*,
    section TFM_SP_PS_APP-ROT_ATTR_RW,
    section TFM_SP_PS_APP-ROT_ATTR_ZI,
};

/* Position tag: End of Application RoT partition's private data */
define block PT_TFM_SP_PS_PRIVATE_DATA_END with alignment = TFM_LINKER_PT_AROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };

/* Position tag: End of Application RoT data (unprivileged) */
define block PT_APP_ROT_DATA_END with alignment = TFM_LINKER_PT_APP_ROT_DATA_ALIGNMENT, size = 0 { };

#if ((defined(__ARM6M__) && (__CORE__ == __ARM6M__)) || \
     (defined(__ARM7M__) && (__CORE__ == __ARM7M__)) || \
     (defined(__ARM7EM__) && (__CORE__ == __ARM7EM__))) && \
    defined(S_DATA_PRIV_START)
/**** Privileged data area base address specified by Armv6-M/v7-M platform */
define block TFM_SECURE_PRIV_DATA_BOUNDARY with size = 0 { };
#endif

/* Position tag: Start of PSA RoT data (privileged) */
define block PT_PSA_ROT_DATA_START with alignment = TFM_LINKER_PT_PSA_ROT_DATA_ALIGNMENT, size = 0 { };

define block ARM_LIB_STACK with alignment = TFM_LINKER_MSP_STACK_ALIGNMENT, size = S_MSP_STACK_SIZE - STACKSEAL_SIZE { };
keep {block ARM_LIB_STACK};

#if ((defined(__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \
     (defined(__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__)) || \
     (defined(__ARM8EM_MAINLINE__) && (__CORE__ == __ARM8EM_MAINLINE__)))
define block STACKSEAL with size = STACKSEAL_SIZE { };
#endif

#ifdef ENABLE_HEAP
    define block HEAP with alignment = TFM_LINKER_TFM_HEAP_ALIGNMENT, size = S_HEAP_SIZE { };
    define block ARM_LIB_HEAP {block HEAP};
    keep {block HEAP, block ARM_LIB_HEAP};
#endif

/* Position tag: Start of PSA RoT partition's private data */
define block PT_TFM_SP_ITS_PRIVATE_DATA_START with alignment = TFM_LINKER_PT_PROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };

define block ER_TFM_SP_ITS_RWZI {
    rw data object *tfm_*partition_its.*,
    section TFM_SP_ITS_PSA-ROT_ATTR_RW,
    section TFM_SP_ITS_PSA-ROT_ATTR_ZI,
};

/* Position tag: End of PSA RoT partition's private data */
define block PT_TFM_SP_ITS_PRIVATE_DATA_END with alignment = TFM_LINKER_PT_PROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };
/* Position tag: Start of PSA RoT partition's private data */
define block PT_TFM_SP_CRYPTO_PRIVATE_DATA_START with alignment = TFM_LINKER_PT_PROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };

define block ER_TFM_SP_CRYPTO_RWZI {
    rw data object *tfm_*partition_crypto.*,
    rw data object *tfpsacrypto.*,
    rw data object *tfpsacrypto*acceleration.*,
    section TFM_SP_CRYPTO_PSA-ROT_ATTR_RW,
    section TFM_SP_CRYPTO_PSA-ROT_ATTR_ZI,
};

/* Position tag: End of PSA RoT partition's private data */
define block PT_TFM_SP_CRYPTO_PRIVATE_DATA_END with alignment = TFM_LINKER_PT_PROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };
/* Position tag: Start of PSA RoT partition's private data */
define block PT_TFM_SP_PLATFORM_PRIVATE_DATA_START with alignment = TFM_LINKER_PT_PROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };

define block ER_TFM_SP_PLATFORM_RWZI {
    rw data object *tfm_*partition_platform.*,
    section TFM_SP_PLATFORM_PSA-ROT_ATTR_RW,
    section TFM_SP_PLATFORM_PSA-ROT_ATTR_ZI,
};

/* Position tag: End of PSA RoT partition's private data */
define block PT_TFM_SP_PLATFORM_PRIVATE_DATA_END with alignment = TFM_LINKER_PT_PROT_PART_PRIVATE_DATA_ALIGNMENT, size = 0 { };

define block ER_TFM_DATA {
    rw data,
};

/* The runtime partition placed order is same as load partition */
define block ER_PART_RT_POOL with alignment = TFM_LINKER_TFM_BSS_ALIGNMENT {
    zi section .bss.part_runtime
};

/* The runtime service placed order is same as load partition */
define block ER_SERV_RT_POOL with alignment = TFM_LINKER_TFM_BSS_ALIGNMENT {
    zi section .bss.serv_runtime
};

keep {block ER_PART_RT_POOL, block ER_SERV_RT_POOL};

/* Position tag: End of PSA RoT data (privileged) */
define block PT_PSA_ROT_DATA_END with alignment = TFM_LINKER_PT_PSA_ROT_DATA_ALIGNMENT, size = 0 { };

#ifdef RAM_VECTORS_SUPPORT
define block ER_RAM_VECTORS with alignment = TFM_LINKER_RAM_VECTORS_ALIGNMENT {
    section .ramvec
};
#endif

/* This empty, zero long execution region is here to mark the limit address
 * of the last execution region that is allocated in SRAM.
 */
define block SRAM_WATERMARK with size = 0 { };

define block LR_CODE with fixed order, maximum size = S_CODE_SIZE {
    block PT_RO_START,
    block ER_VECTORS,

    block PT_UNPRIV_CODE_START,
#ifdef CONFIG_TFM_USE_TRUSTZONE
    block ER_VENEER,
    block VENEER_ALIGN,
#endif
    block ER_UNPRIV_CODE,
    block PT_UNPRIV_CODE_END,

    block PT_APP_ROT_CODE_START,
    block ER_APP_ROT_CODE,
    block PT_APP_ROT_CODE_END,

    block PT_PSA_ROT_CODE_START,
    block ER_PSA_ROT_CODE,
    block ER_TFM_CODE,
    block PT_PSA_ROT_CODE_END,

    block PT_RO_DATA_START,
    block ER_RO_DATA,
    block TFM_SP_LOAD_LIST,
    block PT_RO_DATA_END,
    block PT_RO_END,
};

do not initialize {
   section .noinit,
   rw section .ramvec
};
initialize by copy with packing = none { readwrite }
#ifndef S_RAM_CODE_START
    except { section .textrw }
#endif
    ;
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
    /* Required in a multi-threaded application */
    initialize by copy { section __DLIB_PERTHREAD };
}

place at address S_CODE_START { block LR_CODE };

define block DATA with fixed order {
    block TFM_SECURE_DATA_START,

    /*
     * MPU on Armv6-M/v7-M core in multi-core topology may require more strict
     * alignment that MPU region base address must align with the MPU region
     * size.
     * As a result, on Armv6-M/v7-M cores, to save memory resource and MPU
     * regions, unprivileged data sections and privileged data sections can be
     * separated and gathered in unprivileged/privileged data area respectively
     * by defining S_DATA_PRIV_START. If so, the BL2 shared data area is moved
     * to the beginning of the privileged data area, otherwise it is kept at the
     * beginning of the secure data area.
     */
#ifndef S_DATA_PRIV_START
    block TFM_SHARED_DATA,
#endif /* !S_DATA_PRIV_START */

    block PT_APP_ROT_DATA_START,
#ifdef CONFIG_TFM_PARTITION_META
    block TFM_SP_META_PTR,
    block TFM_SP_META_PTR_END,
#endif
    block PT_TFM_SP_PS_PRIVATE_DATA_START,
    block ER_TFM_SP_PS_RWZI,
    block PT_TFM_SP_PS_PRIVATE_DATA_END,
    block PT_APP_ROT_DATA_END,

#ifdef S_DATA_PRIV_START
};
define block PRIV_DATA with fixed order {
    block TFM_SECURE_PRIV_DATA_BOUNDARY,
    /*
     * Move BL2 shared area to the beginning of privileged data area on
     * Armv6-M/v7-M platforms.
     */
    block TFM_SHARED_DATA,
#endif /* S_DATA_PRIV_START */

    block PT_PSA_ROT_DATA_START,
    block ARM_LIB_STACK,
#if ((defined(__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \
     (defined(__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__)) || \
     (defined(__ARM8EM_MAINLINE__) && (__CORE__ == __ARM8EM_MAINLINE__)))
    block STACKSEAL,
#endif
#ifdef ENABLE_HEAP
    block ARM_LIB_HEAP,
#endif
    block PT_TFM_SP_ITS_PRIVATE_DATA_START,
    block ER_TFM_SP_ITS_RWZI,
    block PT_TFM_SP_ITS_PRIVATE_DATA_END,
    block PT_TFM_SP_CRYPTO_PRIVATE_DATA_START,
    block ER_TFM_SP_CRYPTO_RWZI,
    block PT_TFM_SP_CRYPTO_PRIVATE_DATA_END,
    block PT_TFM_SP_PLATFORM_PRIVATE_DATA_START,
    block ER_TFM_SP_PLATFORM_RWZI,
    block PT_TFM_SP_PLATFORM_PRIVATE_DATA_END,
    block ER_TFM_DATA,
    block ER_PART_RT_POOL,
    block ER_SERV_RT_POOL,
    block PT_PSA_ROT_DATA_END,

#ifdef RAM_VECTORS_SUPPORT
    block ER_RAM_VECTORS,
#endif

    block SRAM_WATERMARK,

    /* Make sure that the sections allocated in the SRAM does not exceed the
     * size of the SRAM available.
     */
};

place at address S_DATA_START { block DATA };
#if ((defined(__ARM6M__) && (__CORE__ == __ARM6M__)) || \
     (defined(__ARM7M__) && (__CORE__ == __ARM7M__)) || \
     (defined(__ARM7EM__) && (__CORE__ == __ARM7EM__))) && \
    defined(S_DATA_PRIV_START)
place at address S_DATA_PRIV_START { block PRIV_DATA };
#endif

/* Reserved place for NS application.
 * No code will be placed here, just address of this region is used in the
 * secure code to configure certain HW components. This generates an empty
 * execution region description warning during linking.
 */
define block LR_NS_PARTITION with size = NS_PARTITION_SIZE { };
place at address NS_PARTITION_START { block LR_NS_PARTITION };

#ifdef BL2
/* Reserved place for new image in case of firmware upgrade.
 * No code will be placed here, just address of this region is used in the
 * secure code to configure certain HW components. This generates an empty
 * execution region description warning during linking.
 */
define block LR_SECONDARY_PARTITION with size = SECONDARY_PARTITION_SIZE { };
place at address SECONDARY_PARTITION_START { block LR_SECONDARY_PARTITION };
#endif /* BL2 */
