summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fw/fe310/bsp/default.lds196
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