From 4a78984a753790330f838917d189dc39c0fba2d9 Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Sun, 4 Sep 2022 18:07:55 +0200
Subject: new linker script

---
 fw/fe310/bsp/default.lds | 196 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 125 insertions(+), 71 deletions(-)

(limited to 'fw/fe310')

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
-- 
cgit v1.2.3