summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld')
-rw-r--r--FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld387
1 files changed, 387 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld b/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld
new file mode 100644
index 000000000..b98f73424
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole/polarfire_hal/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * MPFS HAL Embedded Software
+ *
+ */
+/*******************************************************************************
+ *
+ * file name : mpfs-envm-lma-scratchpad-vma.ld
+ * Code starts from eNVM and relocates itself to an L2 cache scratchpad mapped in
+ * the Zero Device address range.
+ *
+ * You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md
+ * which can be found under the link below:
+ * https://github.com/polarfire-soc/polarfire-soc-documentation
+ *
+ */
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+/*-----------------------------------------------------------------------------
+
+-- MSS hart Reset vector
+
+The MSS reset vector for each hart is stored securely in the MPFS.
+The most common usage will be where the reset vector for each hart will be set
+to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous
+non-volatile storage. Normally this is where the initial boot-loader will
+reside. (Note: The first 256B page of envm is used for metadata associated with
+secure boot. When not using secure boot (mode 0,1), this area is still reserved
+by convention. It allows easier transition from non-secure to secure boot flow
+during the development process.
+When debugging a bare metal program that is run out of reset from envm, a linker
+script will be used whereby the program will run from LIM instead of envm.
+In this case, the reset vector in the linker script is normally set to the
+start of LIM, 0x0800_0000.
+This means you are not continually programming the envm each time you load a
+program and there is no limitation with break points when debugging.
+See the mpfs-lim.ld example linker script when runing from LIM.
+
+------------------------------------------------------------------------------*/
+
+MEMORY
+{
+ /* In this example, our reset vector is set to point to the */
+ /* start at page 1 of the envm */
+ envm (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100
+ dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 7k
+ e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k
+ u54_1_itim (rwx) : ORIGIN = 0x01808000, LENGTH = 28k
+ u54_2_itim (rwx) : ORIGIN = 0x01810000, LENGTH = 28k
+ u54_3_itim (rwx) : ORIGIN = 0x01818000, LENGTH = 28k
+ u54_4_itim (rwx) : ORIGIN = 0x01820000, LENGTH = 28k
+ l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 256k
+ scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k
+ /* This 1k of DTIM is used to run code when switching the envm clock */
+ switch_code (rx) : ORIGIN = 0x01001c00, LENGTH = 1k
+ /* DDR sections example */
+ ddr_cached_32bit (rwx) : ORIGIN = 0x80000000, LENGTH = 768M
+ ddr_non_cached_32bit (rwx) : ORIGIN = 0xC0000000, LENGTH = 256M
+ ddr_wcb_32bit (rwx) : ORIGIN = 0xD0000000, LENGTH = 256M
+ ddr_cached_38bit (rwx) : ORIGIN = 0x1000000000, LENGTH = 1024M
+ ddr_non_cached_38bit (rwx) : ORIGIN = 0x1400000000, LENGTH = 0k
+ ddr_wcb_38bit (rwx) : ORIGIN = 0x1800000000, LENGTH = 0k
+}
+
+HEAP_SIZE = 8k; /* needs to be calculated for your application if using */
+
+/*
+ * There is common area for shared variables, accessed from a pointer in a harts HLS
+ */
+SIZE_OF_COMMON_HART_MEM = 4k;
+
+/*
+ * The stack size needs to be calculated for your
+ * application. It must be Must be aligned
+ * Also Thread local storage (AKA hart local storage) is allocated for each hart
+ * as part of the stack
+ * So the memory map will look like once apportion in startup code:
+ * stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE)
+ * TLS hart 0
+ * stack hart1
+ * TLS hart 1
+ * etc
+ * note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h
+ */
+
+/*
+ * STACK_SIZE_xxx_STARTUP
+ * Stack size for each hart's startup code.
+ * Before copying itself to the scratchpad memory area and executing the code from there, the
+ * startup code is executing from LIM. The scratchpad area is not configured yet. This per-hart
+ * startup stack area is located in LIM and used during this phase of the startup code.
+ * STACK_SIZE_xxx_APPLICATION
+ * After the startup code executing from LIM configures the scratchpad memory, it configures
+ * the each hart's SP with this stack area for the respective hart's application function,
+ * (namely e51(), u54_1(), u54_2(), u54_3(), u54_4() ) to use it.
+ * This per-hart application stack area is located in scratchpad and used by application when
+ * it is executing from scratchpad.
+ *
+ */
+STACK_SIZE_E51_STARTUP = 4k;
+STACK_SIZE_U54_1_STARTUP = 4k;
+STACK_SIZE_U54_2_STARTUP = 4k;
+STACK_SIZE_U54_3_STARTUP = 4k;
+STACK_SIZE_U54_4_STARTUP = 4k;
+
+STACK_SIZE_E51_APPLICATION = 8k;
+STACK_SIZE_U54_1_APPLICATION = 8k;
+STACK_SIZE_U54_2_APPLICATION = 8k;
+STACK_SIZE_U54_3_APPLICATION = 8k;
+STACK_SIZE_U54_4_APPLICATION = 8k;
+
+
+SECTIONS
+{
+ PROVIDE(__envm_start = ORIGIN(envm));
+ PROVIDE(__envm_end = ORIGIN(envm) + LENGTH(envm));
+ PROVIDE(__l2lim_start = ORIGIN(l2lim));
+ PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim));
+ PROVIDE(__ddr_cached_32bit_start = ORIGIN(ddr_cached_32bit));
+ PROVIDE(__ddr_cached_32bit_end = ORIGIN(ddr_cached_32bit) + LENGTH(ddr_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_start = ORIGIN(ddr_non_cached_32bit));
+ PROVIDE(__ddr_non_cached_32bit_end = ORIGIN(ddr_non_cached_32bit) + LENGTH(ddr_non_cached_32bit));
+ PROVIDE(__ddr_wcb_32bit_start = ORIGIN(ddr_wcb_32bit));
+ PROVIDE(__ddr_wcb_32bit_end = ORIGIN(ddr_wcb_32bit) + LENGTH(ddr_wcb_32bit));
+ PROVIDE(__ddr_cached_38bit_start = ORIGIN(ddr_cached_38bit));
+ PROVIDE(__ddr_cached_38bit_end = ORIGIN(ddr_cached_38bit) + LENGTH(ddr_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_start = ORIGIN(ddr_non_cached_38bit));
+ PROVIDE(__ddr_non_cached_38bit_end = ORIGIN(ddr_non_cached_38bit) + LENGTH(ddr_non_cached_38bit));
+ PROVIDE(__ddr_wcb_38bit_start = ORIGIN(ddr_wcb_38bit));
+ PROVIDE(__ddr_wcb_38bit_end = ORIGIN(ddr_wcb_38bit) + LENGTH(ddr_wcb_38bit));
+ PROVIDE(__dtim_start = ORIGIN(dtim));
+ PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim));
+ PROVIDE(__e51itim_start = ORIGIN(e51_itim));
+ PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim));
+ PROVIDE(__u54_1_itim_start = ORIGIN(u54_1_itim));
+ PROVIDE(__u54_1_itim_end = ORIGIN(u54_1_itim) + LENGTH(u54_1_itim));
+ PROVIDE(__u54_2_itim_start = ORIGIN(u54_2_itim));
+ PROVIDE(__u54_2_itim_end = ORIGIN(u54_2_itim) + LENGTH(u54_2_itim));
+ PROVIDE(__u54_3_itim_start = ORIGIN(u54_3_itim));
+ PROVIDE(__u54_3_itim_end = ORIGIN(u54_3_itim) + LENGTH(u54_3_itim));
+ PROVIDE(__u54_4_itim_start = ORIGIN(u54_4_itim));
+ PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim));
+
+ . = __envm_start;
+ .text_init : ALIGN(0x10)
+ {
+ *(.text.init)
+ *system_startup.o (.text .text* .rodata .rodata* .srodata*)
+ *mtrap.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_h2f.o (.text .text* .rodata .rodata* .srodata*)
+ *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*)
+ . = ALIGN(0x10);
+ } >envm
+
+ .text : ALIGN(0x10)
+ {
+ __text_load = LOADADDR(.text);
+ . = ALIGN(0x10);
+ __text_start = .;
+ /* placed at the start of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_start = .;
+
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ . = ALIGN(0x10);
+
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2)
+ *(.srodata*)
+
+ . = ALIGN(0x10);
+ __text_end = .;
+ } >scratchpad AT> envm
+
+ /* short/global data section */
+ .sdata : ALIGN(0x10)
+ {
+ __sdata_load = LOADADDR(.sdata);
+ __sdata_start = .;
+ /* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */
+ /* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */
+ __global_pointer$ = . + 0x800;
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(0x10);
+ __sdata_end = .;
+ } >scratchpad AT> envm
+
+ /* data section */
+ .data : ALIGN(0x10)
+ {
+ __data_load = LOADADDR(.data);
+ __data_start = .;
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(0x10);
+ __data_end = .;
+ } > scratchpad AT> envm
+
+ /* sbss section */
+ .sbss : ALIGN(0x10)
+ {
+ __sbss_start = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(0x10);
+ __sbss_end = .;
+ } > scratchpad
+
+ /* sbss section */
+ .bss : ALIGN(0x10)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(0x10);
+ __bss_end = .;
+ } > scratchpad
+
+ /* End of uninitialized data segment */
+ _end = .;
+
+ .heap : ALIGN(0x10)
+ {
+ __heap_start = .;
+ . += HEAP_SIZE;
+ __heap_end = .;
+ . = ALIGN(0x10);
+ _heap_end = __heap_end;
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h0$ = .);
+ . += STACK_SIZE_E51_STARTUP;
+ PROVIDE(__stack_top_h0$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_STARTUP;
+ PROVIDE(__stack_top_h1$ = .);
+ } > l2lim
+
+ /* must be on 4k boundary- corresponds to page size */
+ .stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h2$ = .);
+ . += STACK_SIZE_U54_2_STARTUP;
+ PROVIDE(__stack_top_h2$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h3$ = .);
+ . += STACK_SIZE_U54_3_STARTUP;
+ PROVIDE(__stack_top_h3$ = .);
+ } > l2lim
+
+ /* */
+ .stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__stack_bottom_h4$ = .);
+ . += STACK_SIZE_U54_4_STARTUP;
+ PROVIDE(__stack_top_h4$ = .);
+ } > l2lim
+ /* application stacks defined below here */
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_e51 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h0 = .);
+ . += STACK_SIZE_E51_APPLICATION;
+ PROVIDE(__app_stack_top_h0 = .);
+ } > scratchpad
+
+ /* must be on 4k boundary- corresponds to page size */
+ .app_stack_u54_1 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h1$ = .);
+ . += STACK_SIZE_U54_1_APPLICATION;
+ PROVIDE(__app_stack_top_h1 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_2 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h2 = .);
+ . += STACK_SIZE_U54_2_APPLICATION;
+ PROVIDE(__app_stack_top_h2 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_3 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h3 = .);
+ . += STACK_SIZE_U54_3_APPLICATION;
+ PROVIDE(__app_stack_top_h3 = .);
+ } > scratchpad
+
+ /* */
+ .app_stack_u54_4 : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_stack_bottom_h4 = .);
+ . += STACK_SIZE_U54_4_APPLICATION;
+ PROVIDE(__app_stack_top_h4 = .);
+ } > scratchpad
+
+ /*
+ * memory shared accross harts.
+ * The boot Hart Local Storage holds a pointer to this area for each hart if
+ * when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the
+ * mss_sw_config.h
+ */
+ .app_hart_common : /* ALIGN(0x1000) */
+ {
+ PROVIDE(__app_hart_common_start = .);
+ . += SIZE_OF_COMMON_HART_MEM;
+ PROVIDE(__app_hart_common_end = .);
+ /* place at the end of used scratchpad, used as check to verify enough available in code */
+ __l2_scratchpad_vma_end = .;
+ } > scratchpad
+
+ /*
+ * The .ram_code section will contain the code That is run from RAM.
+ * We are using this code to switch the clocks including envm clock.
+ * This can not be done when running from envm
+ * This will need to be copied to ram, before any of this code is run.
+ */
+ .ram_code :
+ {
+ . = ALIGN (4);
+ __sc_load = LOADADDR (.ram_code);
+ __sc_start = .;
+ *(.ram_codetext) /* .ram_codetext sections (code) */
+ *(.ram_codetext*) /* .ram_codetext* sections (code) */
+ *(.ram_coderodata) /* read-only data (constants) */
+ *(.ram_coderodata*)
+ . = ALIGN (4);
+ __sc_end = .;
+ /* place __start_of_free_lim$ after last allocation of l2lim */
+ PROVIDE(__start_of_free_lim$ = .);
+ } >switch_code AT> envm /* On the MPFS for startup code use, >switch_code AT>envm */
+}
+
+