83 lines
3.1 KiB
Plaintext
83 lines
3.1 KiB
Plaintext
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
|
/*
|
|
* ft_tensix_firmware.ld — layout of a Tensix FIRMWARE image (one per processor).
|
|
*
|
|
* tools/emit_tensix_linker_script.py prepends this processor's constants (FT_FIRMWARE_BASE,
|
|
* FT_LOCAL_BASE, ...) from ft_tt_memmap.h; this file only arranges them.
|
|
*
|
|
* .text in L1 at the processor's firmware slot, `.start` (the reset entry) first.
|
|
* .data in the processor's local data memory (Baby RISC-V local RAM,
|
|
* .bss tt-isa-documentation BlackholeA0/TensixTile/BabyRISCV/README.md), read-only data
|
|
* included so constant tables are fetched from local RAM. The host stages this
|
|
* segment in L1 and the firmware copies it in (ft_tt_launch.c).
|
|
*
|
|
* Exported to the kernel link (which reads them through --just-symbols):
|
|
* __fw_export_text_end first 16-byte-aligned L1 address after the firmware text, where a
|
|
* kernel's text goes unless it is relocated;
|
|
* __fw_export_ldm_end first 16-byte-aligned local address after the firmware's data;
|
|
* __stack_top top of local memory; __global_pointer$ 0x7F0 above its base, so
|
|
* gp-relative addressing reaches the whole of a TRISC's 4 KiB.
|
|
*
|
|
* `.segments` (non-loaded) records, for the host loader's size check (ft_tt_elf.c): text
|
|
* address twice and its limit (the firmware slot), data address twice and its limit (local
|
|
* memory less the processor's minimum stack, less where the data starts).
|
|
*
|
|
* Status: clean-room replacement of the staged tree's linker script, plan Phase 3.
|
|
* Issues: None
|
|
* Todo: None
|
|
*/
|
|
OUTPUT_ARCH("riscv")
|
|
ENTRY(_start)
|
|
|
|
SECTIONS
|
|
{
|
|
.text FT_FIRMWARE_BASE :
|
|
{
|
|
KEEP(*(.start))
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
|
*(.text.exit .text.exit.*)
|
|
*(.text.startup .text.startup.*)
|
|
*(.text.hot .text.hot.*)
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)
|
|
. = ALIGN(4);
|
|
}
|
|
__fw_export_text_end = ALIGN(16);
|
|
|
|
.data FT_LOCAL_BASE :
|
|
{
|
|
__ldm_data_start = .;
|
|
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
|
*(.srodata .srodata.*)
|
|
*(.data .data.* .gnu.linkonce.d.*)
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
|
. = ALIGN(4);
|
|
__ldm_data_end = .;
|
|
}
|
|
.bss :
|
|
{
|
|
__ldm_bss_start = .;
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
|
*(COMMON)
|
|
. = ALIGN(4);
|
|
__ldm_bss_end = .;
|
|
}
|
|
__fw_export_ldm_end = ALIGN(16);
|
|
|
|
__stack_top = FT_LOCAL_BASE + FT_LOCAL_SIZE;
|
|
__global_pointer$ = FT_LOCAL_BASE + 0x7F0;
|
|
__instrn_buffer = 0xFFE40000; /* INSTRN_BUF_BASE, BabyRISCV/PushTensixInstruction.md */
|
|
|
|
.segments 0 (INFO) :
|
|
{
|
|
LONG(ADDR(.text)) LONG(ADDR(.text)) LONG(FT_FIRMWARE_SIZE)
|
|
LONG(ADDR(.data)) LONG(ADDR(.data))
|
|
LONG(FT_LOCAL_SIZE - FT_STACK_MIN_SIZE - (ADDR(.data) - FT_LOCAL_BASE))
|
|
}
|
|
|
|
ASSERT(__fw_export_text_end <= FT_FIRMWARE_BASE + FT_FIRMWARE_SIZE,
|
|
"firmware text overflows its L1 slot")
|
|
ASSERT(__fw_export_ldm_end <= __stack_top - FT_STACK_MIN_SIZE,
|
|
"firmware data leaves less than the minimum stack")
|
|
}
|