1/******************************************************************************* 2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * MPFS HAL Embedded Software 7 * 8 */ 9/******************************************************************************* 10 * 11 * file name : mpfs-lim-lma-scratchpad-vma.ld 12 * Used when debugging code. The debugger loads the code to LIM. 13 * Code starts from LIM and relocates itself to an L2 cache scratchpad mapped in 14 * the Zero Device address range. 15 * 16 * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md 17 * which can be found under the link below: 18 * https://github.com/polarfire-soc/polarfire-soc-documentation 19 * 20 */ 21 22OUTPUT_ARCH( "riscv" ) 23ENTRY(_start) 24 25/*----------------------------------------------------------------------------- 26 27-- MSS hart Reset vector 28 29The MSS reset vector for each hart is stored securely in the MPFS. 30The most common usage will be where the reset vector for each hart will be set 31to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous 32non-volatile storage. Normally this is where the initial boot-loader will 33reside. (Note: The first 256B page of envm is used for metadata associated with 34secure boot. When not using secure boot (mode 0,1), this area is still reserved 35by convention. It allows easier transition from non-secure to secure boot flow 36during the development process. 37 38------------------------------------------------------------------------------*/ 39 40MEMORY 41{ 42 envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100 43 dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k 44 e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k 45 u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k 46 u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k 47 u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k 48 u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k 49 l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k 50 scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k 51 /* This 1k of DTIM is used to run code when switching the envm clock */ 52 switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k 53 /* DDR sections example */ 54 ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M 55 ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M 56 ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M 57 ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M 58 ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k 59 ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k 60} 61 62HEAP_SIZE = 8k; /* needs to be calculated for your application if using */ 63 64/* 65 * There is common area for shared variables, accessed from a pointer in a harts HLS 66 */ 67SIZE_OF_COMMON_HART_MEM = 4k; 68 69/* 70 * The stack size needs to be calculated for your 71 * application. It must be Must be aligned 72 * Also Thread local storage (AKA hart local storage) is allocated for each hart 73 * as part of the stack 74 * So the memory map will look like once apportion in startup code: 75 * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) 76 * TLS hart 0 77 * stack hart1 78 * TLS hart 1 79 * etc 80 * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h 81 */ 82 83/* 84 * STACK_SIZE_xxx_STARTUP 85 * Stack size for each hart's startup code. 86 * Before copying itself to the scratchpad memory area and executing the code from there, the 87 * startup code is executing from LIM. The scratchpad area is not configured yet. This per-hart 88 * startup stack area is located in LIM and used during this phase of the startup code. 89 * STACK_SIZE_xxx_APPLICATION 90 * After the startup code executing from LIM configures the scratchpad memory, it configures 91 * the each hart's SP with this stack area for the respective hart's application function, 92 * (namely e51(), u54_1(), u54_2(), u54_3(), u54_4() ) to use it. 93 * This per-hart application stack area is located in scratchpad and used by application when 94 * it is executing from scratchpad. 95 * 96 */ 97STACK_SIZE_E51_STARTUP = 4k; 98STACK_SIZE_U54_1_STARTUP = 4k; 99STACK_SIZE_U54_2_STARTUP = 4k; 100STACK_SIZE_U54_3_STARTUP = 4k; 101STACK_SIZE_U54_4_STARTUP = 4k; 102 103STACK_SIZE_E51_APPLICATION = 8k; 104STACK_SIZE_U54_1_APPLICATION = 8k; 105STACK_SIZE_U54_2_APPLICATION = 8k; 106STACK_SIZE_U54_3_APPLICATION = 8k; 107STACK_SIZE_U54_4_APPLICATION = 8k; 108 109SECTIONS 110{ 111 PROVIDE(__envm_start = ORIGIN(envm)); 112 PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm)); 113 PROVIDE(__l2lim_start = ORIGIN(l2lim)); 114 PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim)); 115 PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit)); 116 PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit)); 117 PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit)); 118 PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit)); 119 PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit)); 120 PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit)); 121 PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit)); 122 PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit)); 123 PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit)); 124 PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit)); 125 PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit)); 126 PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit)); 127 PROVIDE(__dtim_start = ORIGIN(dtim)); 128 PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim)); 129 PROVIDE(__e51itim_start = ORIGIN(e51_itim)); 130 PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim)); 131 PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim)); 132 PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim)); 133 PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim)); 134 PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim)); 135 PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim)); 136 PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim)); 137 PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim)); 138 PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim)); 139 140 . = __l2lim_start; 141 .text_init : ALIGN(0x10) 142 { 143 *(.text.init) 144 *system_startup.o (.text .text* .rodata .rodata* .srodata*) 145 *mtrap.o (.text .text* .rodata .rodata* .srodata*) 146 *mss_h2f.o (.text .text* .rodata .rodata* .srodata*) 147 *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*) 148 . = ALIGN(0x10); 149 } >l2lim 150 151 .text : ALIGN(0x10) 152 { 153 __text_load = LOADADDR(.text); 154 . = ALIGN(0x10); 155 __text_start = .; 156 /* placed at the start of used scratchpad, used as check to verify enough available in code */ 157 __l2_scratchpad_vma_start = .; 158 *(.text .text.* .gnu.linkonce.t.*) 159 *(.plt) 160 . = ALIGN(0x10); 161 162 KEEP (*crtbegin.o(.ctors)) 163 KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 164 KEEP (*(SORT(.ctors.*))) 165 KEEP (*crtend.o(.ctors)) 166 KEEP (*crtbegin.o(.dtors)) 167 KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 168 KEEP (*(SORT(.dtors.*))) 169 KEEP (*crtend.o(.dtors)) 170 171 *(.rodata .rodata.* .gnu.linkonce.r.*) 172 *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) 173 *(.gcc_except_table) 174 *(.eh_frame_hdr) 175 *(.eh_frame) 176 177 KEEP (*(.init)) 178 KEEP (*(.fini)) 179 180 PROVIDE_HIDDEN (__preinit_array_start = .); 181 KEEP (*(.preinit_array)) 182 PROVIDE_HIDDEN (__preinit_array_end = .); 183 PROVIDE_HIDDEN (__init_array_start = .); 184 KEEP (*(SORT(.init_array.*))) 185 KEEP (*(.init_array)) 186 PROVIDE_HIDDEN (__init_array_end = .); 187 PROVIDE_HIDDEN (__fini_array_start = .); 188 KEEP (*(.fini_array)) 189 KEEP (*(SORT(.fini_array.*))) 190 PROVIDE_HIDDEN (__fini_array_end = .); 191 192 *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) 193 *(.srodata*) 194 195 . = ALIGN(0x10); 196 __text_end = .; 197 } >scratchpad AT> l2lim 198 199 /* short/global data section */ 200 .sdata : ALIGN(0x10) 201 { 202 __sdata_load = LOADADDR(.sdata); 203 __sdata_start = .; 204 /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */ 205 /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */ 206 __global_pointer$ = . + 0x800; 207 *(.sdata .sdata.* .gnu.linkonce.s.*) 208 . = ALIGN(0x10); 209 __sdata_end = .; 210 } >scratchpad AT> l2lim 211 212 /* data section */ 213 .data : ALIGN(0x10) 214 { 215 __data_load = LOADADDR(.data); 216 __data_start = .; 217 *(.got.plt) *(.got) 218 *(.shdata) 219 *(.data .data.* .gnu.linkonce.d.*) 220 . = ALIGN(0x10); 221 __data_end = .; 222 } > scratchpad AT> l2lim 223 224 /* sbss section */ 225 .sbss : ALIGN(0x10) 226 { 227 __sbss_start = .; 228 *(.sbss .sbss.* .gnu.linkonce.sb.*) 229 *(.scommon) 230 . = ALIGN(0x10); 231 __sbss_end = .; 232 } > scratchpad 233 234 /* sbss section */ 235 .bss : ALIGN(0x10) 236 { 237 __bss_start = .; 238 *(.shbss) 239 *(.bss .bss.* .gnu.linkonce.b.*) 240 *(COMMON) 241 . = ALIGN(0x10); 242 __bss_end = .; 243 } > scratchpad 244 245 /* End of uninitialized data segment */ 246 _end = .; 247 248 .heap : ALIGN(0x10) 249 { 250 __heap_start = .; 251 . += HEAP_SIZE; 252 __heap_end = .; 253 . = ALIGN(0x10); 254 _heap_end = __heap_end; 255 } > scratchpad 256 257 /* must be on 4k boundary- corresponds to page size */ 258 .stack_e51 : /* ALIGN(0x1000) */ 259 { 260 PROVIDE(__stack_bottom_h0$ = .); 261 . += STACK_SIZE_E51_STARTUP; 262 PROVIDE(__stack_top_h0$ = .); 263 } > l2lim 264 265 /* must be on 4k boundary- corresponds to page size */ 266 .stack_u54_1 : /* ALIGN(0x1000) */ 267 { 268 PROVIDE(__stack_bottom_h1$ = .); 269 . += STACK_SIZE_U54_1_STARTUP; 270 PROVIDE(__stack_top_h1$ = .); 271 } > l2lim 272 273 /* must be on 4k boundary- corresponds to page size */ 274 .stack_u54_2 : /* ALIGN(0x1000) */ 275 { 276 PROVIDE(__stack_bottom_h2$ = .); 277 . += STACK_SIZE_U54_2_STARTUP; 278 PROVIDE(__stack_top_h2$ = .); 279 } > l2lim 280 281 /* */ 282 .stack_u54_3 : /* ALIGN(0x1000) */ 283 { 284 PROVIDE(__stack_bottom_h3$ = .); 285 . += STACK_SIZE_U54_3_STARTUP; 286 PROVIDE(__stack_top_h3$ = .); 287 } > l2lim 288 289 /* */ 290 .stack_u54_4 : /* ALIGN(0x1000) */ 291 { 292 PROVIDE(__stack_bottom_h4$ = .); 293 . += STACK_SIZE_U54_4_STARTUP; 294 PROVIDE(__stack_top_h4$ = .); 295 } > l2lim 296 /* application stacks defined below here */ 297 298 /* must be on 4k boundary- corresponds to page size */ 299 .app_stack_e51 : /* ALIGN(0x1000) */ 300 { 301 PROVIDE(__app_stack_bottom_h0 = .); 302 . += STACK_SIZE_E51_APPLICATION; 303 PROVIDE(__app_stack_top_h0 = .); 304 } > scratchpad 305 306 /* must be on 4k boundary- corresponds to page size */ 307 .app_stack_u54_1 : /* ALIGN(0x1000) */ 308 { 309 PROVIDE(__app_stack_bottom_h1$ = .); 310 . += STACK_SIZE_U54_1_APPLICATION; 311 PROVIDE(__app_stack_top_h1 = .); 312 } > scratchpad 313 314 /* */ 315 .app_stack_u54_2 : /* ALIGN(0x1000) */ 316 { 317 PROVIDE(__app_stack_bottom_h2 = .); 318 . += STACK_SIZE_U54_2_APPLICATION; 319 PROVIDE(__app_stack_top_h2 = .); 320 } > scratchpad 321 322 /* */ 323 .app_stack_u54_3 : /* ALIGN(0x1000) */ 324 { 325 PROVIDE(__app_stack_bottom_h3 = .); 326 . += STACK_SIZE_U54_3_APPLICATION; 327 PROVIDE(__app_stack_top_h3 = .); 328 } > scratchpad 329 330 /* */ 331 .app_stack_u54_4 : /* ALIGN(0x1000) */ 332 { 333 PROVIDE(__app_stack_bottom_h4 = .); 334 . += STACK_SIZE_U54_4_APPLICATION; 335 PROVIDE(__app_stack_top_h4 = .); 336 } > scratchpad 337 338 339 /* 340 * memory shared accross harts. 341 * The boot Hart Local Storage holds a pointer to this area for each hart if 342 * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the 343 * mss_sw_config.h 344 */ 345 .app_hart_common : /* ALIGN(0x1000) */ 346 { 347 PROVIDE(__app_hart_common_start = .); 348 . += SIZE_OF_COMMON_HART_MEM; 349 PROVIDE(__app_hart_common_end = .); 350 /* place at the end of used scratchpad, used as check to verify enough available in code */ 351 __l2_scratchpad_vma_end = .; 352 } > scratchpad 353 354 /* 355 * The .ram_code section will contain the code That is run from RAM. 356 * We are using this code to switch the clocks including envm clock. 357 * This can not be done when running from envm 358 * This will need to be copied to ram, before any of this code is run. 359 */ 360 .ram_code : 361 { 362 . = ALIGN (4); 363 __sc_load = LOADADDR (.ram_code); 364 __sc_start = .; 365 *(.ram_codetext) /* .ram_codetext sections (code) */ 366 *(.ram_codetext*) /* .ram_codetext* sections (code) */ 367 *(.ram_coderodata) /* read-only data (constants) */ 368 *(.ram_coderodata*) 369 . = ALIGN (4); 370 __sc_end = .; 371 /* place __start_of_free_lim$ after last allocation of l2lim */ 372 PROVIDE(__start_of_free_lim$ = .); 373 } >switch_code AT> l2lim /* On the MPFS for startup code use, >switch_code AT>envm */ 374 375} 376