1/*******************************************************************************
2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of Maxim Integrated
23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
24 * Products, Inc. Branding Policy.
25 *
26 * The mere transfer of this software does not imply any licenses
27 * of trade secrets, proprietary technology, copyrights, patents,
28 * trademarks, maskwork rights, or any other form of intellectual
29 * property whatsoever. Maxim Integrated Products, Inc. retains all
30 * ownership rights.
31 *
32 * $Date: 2018-12-18 15:37:22 -0600 (Tue, 18 Dec 2018) $
33 * $Revision: 40072 $
34 *
35 ******************************************************************************/
36
37MEMORY {
38    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 /* 256kB "FLASH" */
39	SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00018000
40}
41
42OUTPUT_FORMAT ("elf32-littlearm")
43ENTRY(Reset_Handler)
44EXTERN(__start_c main __stack __section_end_heap)
45
46SECTIONS {
47
48    /* SRAM start/stop addresses used during startup (PreInit(), preinit.S) to initialize ECCEN register
49     * and initial Error correcting state. (SEC-DED) */
50    __sram_ecc_initialize_start = ORIGIN(SRAM);
51    __sram_ecc_initialize_stop = (ORIGIN(SRAM) + LENGTH(SRAM));
52
53    .text : ALIGN(0x100)
54    {
55        _text = .;
56		__section_load_nvic = .;
57		KEEP(*(.isr_vector))
58		__section_load_nvic_end = .;
59
60        KEEP(*startup*(.text))
61        *(.text*) /* program code */
62        *(.flashprog*) /* Flash program */
63        KEEP(*(.init))
64        KEEP(*(.fini))
65        *(.rodata*)  /* read-only data: "const" */
66		KEEP(*(.iota_rom_params))
67
68        /* C++ Exception handling */
69        KEEP(*(.eh_frame*))
70        _etext = .;
71    } > FLASH
72
73  __section_nvic_size = __section_load_nvic_end - __section_load_nvic;
74  __section_nvic_start = ORIGIN(SRAM);
75  __section_nvic_end = __section_nvic_start + __section_nvic_size;
76
77    /* it's used for C++ exception handling      */
78    /* we need to keep this to avoid overlapping */
79    .ARM.exidx :
80    {
81        __exidx_start = .;
82        *(.ARM.exidx*)
83        __exidx_end = .;
84    } > FLASH
85
86    .data __section_nvic_end : ALIGN(0x10)
87    {
88        _data = ALIGN(., 4);
89        *(.data*)           /*read-write initialized data: initialized global variable*/
90        *(.spix_config*) /* SPIX configuration functions need to be run from SRAM */
91
92        /* These array sections are used by __libc_init_array to call static C++ constructors */
93        . = ALIGN(4);
94        /* preinit data */
95        PROVIDE_HIDDEN (__preinit_array_start = .);
96        KEEP(*(.preinit_array))
97        PROVIDE_HIDDEN (__preinit_array_end = .);
98
99        . = ALIGN(4);
100        /* init data */
101        PROVIDE_HIDDEN (__init_array_start = .);
102        KEEP(*(SORT(.init_array.*)))
103        KEEP(*(.init_array))
104        PROVIDE_HIDDEN (__init_array_end = .);
105
106        . = ALIGN(4);
107        /* finit data */
108        PROVIDE_HIDDEN (__fini_array_start = .);
109        KEEP(*(SORT(.fini_array.*)))
110        KEEP(*(.fini_array))
111        PROVIDE_HIDDEN (__fini_array_end = .);
112
113        _edata = ALIGN(., 4);
114        __section_end_data = .;
115
116    } > SRAM AT>FLASH
117    __load_data = LOADADDR(.data);
118
119	/** Info block/OTP reserved area */
120  	__virtual_otp_size = 0x400;
121  	__virtual_end_otp = ORIGIN(FLASH) + LENGTH(FLASH);
122  	__virtual_start_otp = __virtual_end_otp - __virtual_otp_size;
123
124
125	/** Free area to program application */
126  	__virtual_start_iota = ALIGN(__load_data,0x10);
127  	__virtual_end_iota = __virtual_start_otp;
128  	__virtual_iota_size = __virtual_end_iota - __virtual_start_iota;
129
130  /** Work buffer */
131  .iota_work __virtual_start_iota :
132  {
133  	. += __virtual_iota_size;
134  }
135
136  /** OTP area */
137  .iota_otp __virtual_start_otp :
138  {
139  	. += __virtual_otp_size;
140  }
141
142
143    .bss :
144    {
145        . = ALIGN(4);
146        _bss = .;
147        *(.bss*)     /*read-write zero initialized data: uninitialzed global variable*/
148        *(COMMON)
149        _ebss = ALIGN(., 4);
150    } > SRAM
151
152    /* Set stack top to end of RAM, and stack limit move down by
153     * size of stack_dummy section */
154
155    /* .stack_dummy section doesn't contains any symbols. It is only
156     * used for linker to calculate size of stack sections, and assign
157     * values to stack symbols later */
158
159	/* Stack and Heap */
160  	.heap (NOLOAD) : ALIGN(0x80)
161  	{
162	    __section_start_heap = .;
163		*(.heap*)
164    	__section_end_heap = .;
165
166  	} > SRAM
167
168  	__section_start_heap_va = __section_start_heap;
169  	__section_end_heap_va = __section_start_heap_va + SIZEOF(.heap);
170
171  	.stack __section_end_heap : ALIGN(0x80)
172  	{
173	  	__section_start_stack = .;
174	    *(.stack*)
175	    _stack = .;
176	    __section_end_stack = .;
177
178  	} > SRAM
179  	__stack_va = __stack;
180
181    PROVIDE(__stack = _stack);
182
183 /* ======================================================================== */
184  /** RAM for STP and SCP **/
185  __section_protocol_ram_end = (ORIGIN(SRAM) + LENGTH(SRAM));
186  __region_end_ram = (ORIGIN(SRAM) + LENGTH(SRAM));
187
188  /** Cryptography work buffer */
189  .iota_work.sh __section_end_stack : ALIGN(0x10)
190  {
191  	KEEP(*(.iota_work.sh))
192  } >SRAM=0
193
194  __iota_work_sh_start = LOADADDR(.iota_work.sh);
195  __iota_work_sh_end = LOADADDR(.iota_work.sh) + SIZEOF(.iota_work.sh);
196  __iota_work_sh_size = SIZEOF(.iota_work.sh);
197
198  /** Configuration Management work buffer */
199  .iota_work.cm __iota_work_sh_end : ALIGN(0x10)
200  {
201  	KEEP(*(.iota_work.cm))
202  } >SRAM=0
203
204  __iota_work_cm_start = LOADADDR(.iota_work.cm);
205  __iota_work_cm_end = LOADADDR(.iota_work.cm) + SIZEOF(.iota_work.cm);
206  __iota_work_cm_size = SIZEOF(.iota_work.cm);
207
208  /** RCE Signature check work buffer */
209  .iota_work.rce __iota_work_cm_end : ALIGN(0x10)
210  {
211	KEEP(*(.iota_work.rce))
212
213  } >SRAM=0
214
215	__iota_work_rce_start = LOADADDR(.iota_work.rce);
216	__iota_work_rce_end = LOADADDR(.iota_work.rce) + SIZEOF(.iota_work.rce);
217	__iota_work_rce_size = SIZEOF(.iota_work.rce);
218
219  /* ======================================================================== */
220
221  /** STP Application, SCP Applet memory areas */
222  .protocol_ram.stack __iota_work_rce_end : ALIGN(0x10)
223  {
224    __section_protocol_start = .;
225  	/** Stack dedicated to STP/SCP application matter if needed */
226   	__section_start_stp_stack = .;
227   	KEEP(*(.protocol_ram.stack))
228	/* . += __stack_size_stp;*/
229	__stack_stp = .;
230
231  } >SRAM
232	__section_end_stp_stack = .;
233
234  .protocol_ram.bss __section_end_stp_stack : ALIGN(0x10)
235  {
236    *stp_*(.bss .bss.* .gnu.linkonce.b.*)
237
238  } >SRAM
239
240  __section_start_bss_stp = LOADADDR(.protocol_ram.bss);
241  __section_end_bss_stp = LOADADDR(.protocol_ram.bss) + SIZEOF(.protocol_ram.bss);
242  __section_bss_stp_size = SIZEOF(.protocol_ram.bss);
243
244  .protocol_ram __section_end_bss_stp : ALIGN(0x10)
245  {
246	/** Code part */
247    KEEP(*stp_*(.data .data.* .gnu.linkonce.d.*))
248    KEEP(*(.protocol_ram))
249
250  } >SRAM
251  __section_protocol_end = ALIGN(0x10);
252  __scp_applet_area_size = __section_protocol_ram_end - __section_protocol_end;
253
254  /** Lasting free internal SRAM space */
255  .iota_scp_applet __section_protocol_end : ALIGN(0x10)
256  {
257    __scp_applet_start = .;
258    . += __scp_applet_area_size;
259    __scp_applet_end = .;
260
261  } >SRAM
262
263  __section_scp_start = LOADADDR(.protocol_ram);
264  __section_scp_stop = LOADADDR(.iota_scp_applet) + SIZEOF(.iota_scp_applet);
265
266  __section_bss_size_stp = __section_end_bss_stp - __section_start_bss_stp;
267  __section_stp_size = SIZEOF(.protocol_ram.stack) + SIZEOF(.protocol_ram.bss) + SIZEOF(.protocol_ram);
268
269    /* Check if data + heap + stack exceeds RAM limit */
270    ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
271}
272