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  | 
