diff options
-rw-r--r-- | fw/fe310/bsp/default.lds | 196 |
1 files changed, 125 insertions, 71 deletions
diff --git a/fw/fe310/bsp/default.lds b/fw/fe310/bsp/default.lds index 6be3f46..7beb458 100644 --- a/fw/fe310/bsp/default.lds +++ b/fw/fe310/bsp/default.lds @@ -1,85 +1,65 @@ -OUTPUT_ARCH("riscv") - ENTRY(_enter) MEMORY { - flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 0x6a120 - itim (wx!rai) : ORIGIN = 0x8000000, LENGTH = 0x2000 - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x4000 + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20000000, LENGTH = 0x10000000 } PHDRS { - flash PT_LOAD; + rom PT_LOAD; + text PT_LOAD; ram PT_LOAD; ram_init PT_LOAD; - itim PT_LOAD; itim_init PT_LOAD; + lim_init PT_LOAD; } SECTIONS { + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x1000; - __stack_size = 0x1000; - PROVIDE(__metal_boot_hart = 0); - PROVIDE(__metal_chicken_bit = 0); + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ KEEP (*(.text.metal.init.enter)) KEEP (*(.text.metal.init.*)) KEEP (*(SORT_NONE(.init))) KEEP (*(.text.libgloss.start)) - } >flash AT>flash :flash + } >rom :rom .fini : { KEEP (*(SORT_NONE(.fini))) - } >flash AT>flash :flash + } >rom :rom - .text : { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) - *(.text .text.*) - *(.gnu.linkonce.t.*) - } >flash AT>flash :flash - - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - .rodata : { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - } >flash AT>flash :flash - - . = ALIGN(8); - - .preinit_array : { + .preinit_array : ALIGN(8) { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); - } >flash AT>flash :flash + } >rom :rom - .init_array : { + .init_array : ALIGN(8) { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); - } >flash AT>flash :flash + } >rom :rom - .fini_array : { + .fini_array : ALIGN(8) { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); - } >flash AT>flash :flash + } >rom :rom .ctors : { KEEP (*crtbegin.o(.ctors)) @@ -87,7 +67,7 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) - } >flash AT>flash :flash + } >rom :rom .dtors : { KEEP (*crtbegin.o(.dtors)) @@ -95,60 +75,134 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) - } >flash AT>flash :flash + } >rom : rom + + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >rom :rom + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ .itim : ALIGN(8) { *(.itim .itim.*) - } >itim AT>flash :itim_init + *(.itim2 .itim2.*) + } >itim AT>rom :itim_init PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); - .data : ALIGN(8) { + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>rom :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : { *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.* .sdata2.*) *(.gnu.linkonce.s.*) - } >itim AT>flash :itim_init -/* } >ram AT>flash :ram_init */ + } >ram AT>rom :ram_init PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); PROVIDE( metal_segment_data_target_start = ADDR(.data) ); PROVIDE( metal_segment_data_target_end = ADDR(.data) + SIZEOF(.data) ); - .bss : ALIGN(8) { - *(.ibss .ibss.*) + .bss (NOLOAD) : { *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss .bss.*) *(.gnu.linkonce.b.*) *(COMMON) - } >itim AT>ram :itim -/* } >ram AT>ram :ram */ - - PROVIDE( metal_segment_bss_target_start = ADDR(.bss) ); - PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); - - __heap_size = 0x4000 - __stack_size; -/* __heap_size = 0x1000; */ - .heap : { - PROVIDE( metal_segment_heap_target_start = . ); - . += __heap_size; - PROVIDE( metal_segment_heap_target_end = . ); - PROVIDE( _heap_end = . ); - } >ram AT>ram :ram + } >ram :ram - PROVIDE(__stack_size = __stack_size); + PROVIDE( metal_segment_bss_start = ADDR(.bss) ); + PROVIDE( metal_segment_bss_end = ADDR(.bss) + SIZEOF(.bss) ); - .stack : { - PROVIDE(metal_segment_stack_begin = .); + .stack (NOLOAD) : ALIGN(16) { . += __stack_size; - PROVIDE(metal_segment_stack_end = .); PROVIDE( _sp = . ); - } >ram AT>ram :ram + } >ram :ram -} + PROVIDE( metal_segment_stack_start = ADDR(.stack) ); + PROVIDE( metal_segment_stack_end = ADDR(.stack) + SIZEOF(.stack) ); + PROVIDE(__stack_size = __stack_size); + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + . = LENGTH(ram) - ( . - ORIGIN(ram)); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + PROVIDE( metal_segment_heap_start = ADDR(.heap) ); + PROVIDE( metal_segment_heap_end = ADDR(.heap) + SIZEOF(.heap) ); + + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +}
\ No newline at end of file |