1/*
2 * Copyright 2020 ETH Zurich
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 * Author: Robert Balas (balasr@iis.ee.ethz.ch)
18 */
19
20OUTPUT_ARCH(riscv)
21ENTRY(_start)
22MEMORY
23{
24  L2           : ORIGIN = 0x1c000004, LENGTH = 0x0007fffc
25  L2_aliased   : ORIGIN = 0x00000004, LENGTH = 0x00003ffc
26}
27
28/*
29 * This linker script try to put FC data in L2 private bank0 and FC code
30 * in L2 private bank1 to avoid contention between FC code and data
31 * as FC has no instruction cache and is so often accessing L2 to
32 * get instructions. Everything can be shifted in case one bank is full.
33 *
34 * Cluster code and initialized data are put in shared banks to not polute
35 * private banks which are quite small, and also avoid contentions between
36 * cluster cache refill and FC.
37 */
38
39
40SECTIONS
41{
42
43  PROVIDE(__boot_address = 0x1c008080);
44  /* stack and heap related settings */
45  __stack_size = DEFINED(__stack_size) ? __stack_size : 0x800;
46  PROVIDE(__stack_size = __stack_size);
47  /* __heap_size = DEFINED(__heap_size) ? __heap_size : 0x400; */
48  __heap_size = 0x06000;
49  PROVIDE(__heap_size = __heap_size);
50
51  /*
52   * L2 PRIVATE BANK0
53   *
54   * Contains FC tiny data and code
55   */
56
57  /* This section is for tiny FC data which benefits
58   * from the alias at 0
59   */
60   /* TODO: what do we really want to put here when we have the gp */
61  .data_tiny_fc : ALIGN(4)
62  {
63    *(.data_tiny_fc)
64    *(.data_tiny_fc.*)
65  } > L2_aliased AT> L2
66
67
68  /* text */
69  .init : ALIGN(4)
70  {
71    KEEP( *(.init) )
72  } > L2
73
74  .vectors MAX(0x1c000800, ALIGN(256)) : /* lets leak the first 2k free for now "half zero page" */
75  {
76    __irq_vector_base = .;
77    __vector_start = .;
78    KEEP(*(.vectors))
79  } > L2
80
81  .text __boot_address :
82  {
83    _stext = .;
84    *(.text.start)
85    *(.text)
86    *(.text.*)
87    _etext = .; /* man 3 end: first addr after text */
88    *(.lit)
89    *(.shdata)
90    _endtext = .;
91    . = ALIGN(4);
92
93		 /* section information for finsh shell */
94    . = ALIGN(4);
95    __fsymtab_start = .;
96    KEEP(*(FSymTab))
97    __fsymtab_end = .;
98    . = ALIGN(4);
99    __vsymtab_start = .;
100    KEEP(*(VSymTab))
101    __vsymtab_end = .;
102    . = ALIGN(4);
103
104    /* section information for initial. */
105    . = ALIGN(4);
106    __rt_init_start = .;
107    KEEP(*(SORT(.rti_fn*)))
108    __rt_init_end = .;
109    . = ALIGN(4);
110
111    /* section information for utest */
112    . = ALIGN(4);
113    __rt_utest_tc_tab_start = .;
114    KEEP(*(UtestTcTab))
115    __rt_utest_tc_tab_end = .;
116  } > L2
117
118  .fini : ALIGN(4)
119  {
120    KEEP( *(.fini) )
121  } > L2
122
123
124  __l2_priv0_end = ALIGN(4);
125
126
127  /*
128   * L2 PRIVATE BANK1
129   *
130   * Contains FC data
131   */
132
133
134  /* make sure we start filling fc data into the correct bank */
135  /* read-only sections */
136  .rodata MAX(0x1c008000, ALIGN(4)) :
137  {
138    *(.rodata .rodata.* .gnu.linkonce.r.*)
139  } > L2
140  .rodata1        :
141  {
142    *(.rodata1)
143  } > L2
144
145
146  .boot : ALIGN(4)
147  {
148    *(.boot)
149    *(.boot.data)
150  } > L2
151
152  /* .got : ALIGN(4) */
153  /* { */
154  /*   *(.got.plt) * (.igot.plt) *(.got) *(.igot) */
155  /* } > L2 */
156
157  .talias :
158  {
159  } > L2
160
161
162  /* gcc language agnostic exception related sections (try-catch-finally) */
163  .eh_frame_hdr :
164  {
165    *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*)
166  } > L2
167  .eh_frame       : ONLY_IF_RO
168  {
169    KEEP (*(.eh_frame)) *(.eh_frame.*)
170  } > L2
171  .gcc_except_table   : ONLY_IF_RO
172  {
173    *(.gcc_except_table .gcc_except_table.*)
174  } > L2
175  .gnu_extab   : ONLY_IF_RO
176  {
177    *(.gnu_extab*)
178  } > L2
179
180
181  /* Exception handling  */
182  .eh_frame       : ONLY_IF_RW
183  {
184    KEEP (*(.eh_frame)) *(.eh_frame.*)
185  } > L2
186  .gnu_extab      : ONLY_IF_RW
187  {
188    *(.gnu_extab)
189  } > L2
190  .gcc_except_table   : ONLY_IF_RW
191  {
192    *(.gcc_except_table .gcc_except_table.*)
193  } > L2
194  .exception_ranges   : ONLY_IF_RW
195  {
196    *(.exception_ranges .exception_ranges*)
197  } > L2
198
199
200  /* Thread Local Storage sections  */
201  .tdata	  :
202  {
203    PROVIDE_HIDDEN (__tdata_start = .);
204    *(.tdata .tdata.* .gnu.linkonce.td.*)
205  } > L2
206  .tbss		  :
207  {
208    *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
209  } > L2
210
211
212  /* constructors / destructors */
213  .preinit_array : ALIGN(4)
214  {
215    PROVIDE_HIDDEN (__preinit_array_start = .);
216    KEEP (*(.preinit_array))
217    PROVIDE_HIDDEN (__preinit_array_end = .);
218  } > L2
219
220  .init_array : ALIGN(4)
221  {
222    PROVIDE_HIDDEN (__init_array_start = .);
223    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
224    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
225    PROVIDE_HIDDEN (__init_array_end = .);
226  } > L2
227
228  .fini_array : ALIGN(4)
229  {
230    PROVIDE_HIDDEN (__fini_array_start = .);
231    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
232    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
233    PROVIDE_HIDDEN (__fini_array_end = .);
234  } > L2
235
236  .ctors          :
237  {
238    /* gcc uses crtbegin.o to find the start of
239       the constructors, so we make sure it is
240       first.  Because this is a wildcard, it
241       doesn't matter if the user does not
242       actually link against crtbegin.o; the
243       linker won't look for a file to match a
244       wildcard.  The wildcard also means that it
245       doesn't matter which directory crtbegin.o
246       is in.  */
247    KEEP (*crtbegin.o(.ctors))
248    KEEP (*crtbegin?.o(.ctors))
249    /* We don't want to include the .ctor section from
250       the crtend.o file until after the sorted ctors.
251       The .ctor section from the crtend file contains the
252       end of ctors marker and it must be last */
253    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
254    KEEP (*(SORT(.ctors.*)))
255    KEEP (*(.ctors))
256  } > L2
257
258  .dtors          :
259  {
260    KEEP (*crtbegin.o(.dtors))
261    KEEP (*crtbegin?.o(.dtors))
262    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
263    KEEP (*(SORT(.dtors.*)))
264    KEEP (*(.dtors))
265  } > L2
266
267
268  /* Open MP */
269  .gnu.offload_funcs : ALIGN(4)
270  {
271    KEEP(*(.gnu.offload_funcs))
272  } > L2
273
274
275  .gnu.offload_vars : ALIGN(4)
276  {
277    KEEP(*(.gnu.offload_vars))
278  } > L2
279
280
281  .data : ALIGN(4)
282  {
283    sdata  =  .;
284    _sdata  =  .;
285    __data_begin = .;
286    *(.data_fc)
287    *(.data_fc.*)
288    *(.data);
289    *(.data.*)
290    __sdata_begin = .;
291    *(.sdata);
292    *(.sdata.*)
293    *(.sdata2.*) /* FreeRTOS xISRStackTop, __global_impure_ptr */
294    *(.heapl2ram)
295    *(.fcTcdm)
296    *(.fcTcdm.*)
297    *(.fcTcdm_g)
298    *(.fcTcdm_g.*)
299    . = ALIGN(4);
300    edata  =  .;
301    _edata  =  .; /* man 3 end: first addr after data */
302  } > L2
303
304
305  .bss : ALIGN(8)
306  {
307    _bss_start = .;
308    __bss_start = .;
309    *(.shbss) /* don't even know where this is from */
310    *(.bss)
311    *(.bss.*)
312    *(.sbss)
313    *(.sbss.*)
314    *(COMMON)
315    . = ALIGN(4);
316    __bss_end = .;
317    _bss_end = .;
318    _end = .; /* man 3 end: first addr after bss */
319  } > L2
320
321
322  /* The compiler uses this to access data in the .sdata, .data, .sbss and .bss
323     sections with fewer instructions (relaxation). This reduces code size. */
324    PROVIDE(__global_pointer$ = MIN(__sdata_begin + 0x800,
325			    MAX(__data_begin + 0x800, __bss_end - 0x800)));
326
327  .heap : ALIGN(16)
328  {
329    __heap_start = .;
330    . += __heap_size;
331    /* __heap_end = .; */ /* Will be automatically filled by the ucHeap array */
332    /* . = ALIGN(16); */
333    KEEP(*(.heap))
334    __heap_end = .;
335    ASSERT((__heap_start + __heap_size < __heap_end), "Error (Linkerscript): Heap is too large");
336  } > L2
337
338
339  .stack : ALIGN(16)
340  {
341    stack_start = .;
342    __stack_bottom = .;
343    . += __stack_size;
344    __stack_top = .;
345    PROVIDE( __rt_rvstack = . );
346    __freertos_irq_stack_top = .; /* sytem stack */
347    stack = .;
348  } > L2
349
350
351  __l2_priv1_end = ALIGN(4);
352
353
354  /*
355   * L2 SHARED BANKS
356   *
357   * Contains other data such as peripheral data and cluster code and data
358   */
359
360  .l2_data MAX(0x1c010000, ALIGN(4)) :
361  {
362    __cluster_text_start = .;
363    *(.cluster.text)
364    *(.cluster.text.*)
365    . = ALIGN(4);
366    __cluster_text_end = .;
367    *(.l2_data)
368    *(.l2_data.*)
369    *(.data_fc_shared)
370    *(.data_fc_shared.*)
371    . = ALIGN(4);
372  } > L2
373
374  __l2_shared_end = LOADADDR(.l2_data) + SIZEOF(.l2_data);
375
376}
377