mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-09 21:25:15 -05:00
Update BSP and SDK for HiFive board (#645)
* Update BSP and SDK for HiFive board This commit also adds demo start and success/failure output messages.
This commit is contained in:
parent
b550e6090d
commit
2fedeff332
263 changed files with 36551 additions and 6623 deletions
|
|
@ -0,0 +1,306 @@
|
|||
/* Copyright (c) 2020 SiFive Inc. */
|
||||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
OUTPUT_ARCH("riscv")
|
||||
|
||||
/* RAM Read-Only Data Linker Script
|
||||
*
|
||||
* This linker script places application code and read-only data into writable
|
||||
* memories in an attempt to improve performance, since writable memories
|
||||
* are generally lower-latency. This linker script may cause your application
|
||||
* to overflow RAM, since it dramatically increases the quantity of data vying
|
||||
* for space there.
|
||||
*/
|
||||
|
||||
ENTRY(_enter)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000
|
||||
ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000
|
||||
rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
rom PT_LOAD;
|
||||
ram_init PT_LOAD;
|
||||
tls PT_TLS;
|
||||
ram PT_LOAD;
|
||||
itim_init PT_LOAD;
|
||||
text PT_LOAD;
|
||||
lim_init PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Each hart is allocated its own stack of size __stack_size. This value
|
||||
* can be overriden at build-time by adding the following to CFLAGS:
|
||||
*
|
||||
* -Xlinker --defsym=__stack_size=0xf00
|
||||
*
|
||||
* where 0xf00 can be replaced with a multiple of 16 of your choice.
|
||||
*
|
||||
* __stack_size is PROVIDE-ed as a symbol so that initialization code
|
||||
* initializes the stack pointers for each hart at the right offset from
|
||||
* the _sp symbol.
|
||||
*/
|
||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
|
||||
PROVIDE(__stack_size = __stack_size);
|
||||
|
||||
/* The size of the heap can be overriden at build-time by adding the
|
||||
* following to CFLAGS:
|
||||
*
|
||||
* -Xlinker --defsym=__heap_size=0xf00
|
||||
*
|
||||
* where 0xf00 can be replaced with the value of your choice.
|
||||
*
|
||||
* Altertatively, the heap can be grown to fill the entire remaining region
|
||||
* of RAM by adding the following to CFLAGS:
|
||||
*
|
||||
* -Xlinker --defsym=__heap_max=1
|
||||
*
|
||||
* Note that depending on the memory layout, the bitness (32/64bit) of the
|
||||
* target, and the code model in use, this might cause a relocation error.
|
||||
*/
|
||||
__heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
|
||||
|
||||
/* The boot hart sets which hart runs the pre-main initialization routines,
|
||||
* including copying .data into RAM, zeroing the BSS region, running
|
||||
* constructors, etc. After initialization, the boot hart is also the only
|
||||
* hart which runs application code unless the application overrides the
|
||||
* secondary_main() function to start execution on secondary harts.
|
||||
*/
|
||||
PROVIDE(__metal_boot_hart = 0);
|
||||
|
||||
/* The chicken bit is used by pre-main initialization to enable/disable
|
||||
* certain core features */
|
||||
PROVIDE(__metal_chicken_bit = 1);
|
||||
|
||||
/* The memory_ecc_scrub bit is used by _entry code to enable/disable
|
||||
* memories scrubbing to zero */
|
||||
PROVIDE(__metal_eccscrub_bit = 0);
|
||||
|
||||
/* The RAM memories map for ECC scrubbing */
|
||||
PROVIDE( metal_dtim_0_memory_start = 0x80000000 );
|
||||
PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 );
|
||||
PROVIDE( metal_itim_0_memory_start = 0x8000000 );
|
||||
PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 );
|
||||
|
||||
/* 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))
|
||||
} >rom :rom
|
||||
|
||||
.fini : {
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} >rom :rom
|
||||
|
||||
.preinit_array : ALIGN(8) {
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >rom :rom
|
||||
|
||||
.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 = .);
|
||||
PROVIDE_HIDDEN ( metal_constructors_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
|
||||
KEEP (*(.metal.init_array));
|
||||
PROVIDE_HIDDEN ( metal_constructors_end = .);
|
||||
} >rom :rom
|
||||
|
||||
.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 = .);
|
||||
PROVIDE_HIDDEN ( metal_destructors_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
|
||||
KEEP (*(.metal.fini_array));
|
||||
PROVIDE_HIDDEN ( metal_destructors_end = .);
|
||||
} >rom :rom
|
||||
|
||||
|
||||
|
||||
.ctors : {
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*(.metal.ctors .metal.ctors.*))
|
||||
} >rom :rom
|
||||
|
||||
.dtors : {
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
KEEP (*(.metal.dtors .metal.dtors.*))
|
||||
} >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>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) );
|
||||
|
||||
/* 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 : ALIGN(8) {
|
||||
*(.data .data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
. = ALIGN(8);
|
||||
PROVIDE( __global_pointer$ = . + 0x800 );
|
||||
*(.sdata .sdata.* .sdata2.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
/* Read-only data is placed in RAM to improve performance, since
|
||||
* read-only memory generally has higher latency than RAM */
|
||||
. = ALIGN(8);
|
||||
*(.srodata.cst16)
|
||||
*(.srodata.cst8)
|
||||
*(.srodata.cst4)
|
||||
*(.srodata.cst2)
|
||||
*(.srodata .srodata.*)
|
||||
. = ALIGN(8);
|
||||
*(.rdata)
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
} >ram AT>rom :ram_init
|
||||
|
||||
.tdata : ALIGN(8) {
|
||||
PROVIDE( __tls_base = . );
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
} >ram AT>rom :tls :ram_init
|
||||
|
||||
PROVIDE( __tdata_source = LOADADDR(.tdata) );
|
||||
PROVIDE( __tdata_size = SIZEOF(.tdata) );
|
||||
|
||||
PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
|
||||
PROVIDE( metal_segment_data_target_start = ADDR(.data) );
|
||||
PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
|
||||
|
||||
.tbss : ALIGN(8) {
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon .tcommon.*)
|
||||
PROVIDE( __tls_end = . );
|
||||
} >ram AT>ram :tls :ram
|
||||
PROVIDE( __tbss_size = SIZEOF(.tbss) );
|
||||
PROVIDE( __tls_size = __tls_end - __tls_base );
|
||||
|
||||
.tbss_space : ALIGN(8) {
|
||||
. = . + __tbss_size;
|
||||
} >ram :ram
|
||||
|
||||
.bss (NOLOAD): ALIGN(8) {
|
||||
*(.sbss*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.bss .bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
} >ram :ram
|
||||
|
||||
PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
|
||||
PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
|
||||
PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
|
||||
|
||||
|
||||
|
||||
.stack (NOLOAD) : ALIGN(16) {
|
||||
PROVIDE(metal_segment_stack_begin = .);
|
||||
. += __stack_size; /* Hart 0 */
|
||||
PROVIDE( _sp = . );
|
||||
PROVIDE(metal_segment_stack_end = .);
|
||||
} >ram :ram
|
||||
|
||||
.heap (NOLOAD) : ALIGN(8) {
|
||||
PROVIDE( __end = . );
|
||||
PROVIDE( __heap_start = . );
|
||||
PROVIDE( metal_segment_heap_target_start = . );
|
||||
/* If __heap_max is defined, grow the heap to use the rest of RAM,
|
||||
* otherwise set the heap size to __heap_size */
|
||||
. = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
|
||||
PROVIDE( metal_segment_heap_target_end = . );
|
||||
PROVIDE( _heap_end = . );
|
||||
PROVIDE( __heap_end = . );
|
||||
} >ram :ram
|
||||
|
||||
/* 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.*)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue