blob: c324363d8a21962e2e8e950f8b6128070569ed33 [file] [log] [blame]
/* Copyright lowRISC contributors. */
/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */
/* SPDX-License-Identifier: Apache-2.0 */
/**
* Linker script for an OpenTitan ROM.
*
* Portions of this file are Ibex-specific.
*/
OUTPUT_ARCH(riscv)
/**
* Indicate that there are no dynamic libraries, whatsoever.
*/
__DYNAMIC = 0;
INCLUDE hw/top_earlgrey/sw/autogen/top_earlgrey_memory.ld
/**
* The boot address, which indicates the location of the initial interrupt
* vector.
*/
_rom_boot_address = ORIGIN(rom);
/**
* Symbols to be used in the setup of the address translation for ROM_EXT.
*/
_rom_ext_virtual_start_address = ORIGIN(rom_ext_virtual);
_rom_ext_virtual_size = LENGTH(rom_ext_virtual);
ASSERT((_rom_ext_virtual_size <= (LENGTH(eflash) / 2)),
"Error: rom ext flash is bigger than slot.");
/* DV Log offset (has to be different to other boot stages). */
_dv_log_offset = 0x0;
/**
* This symbol is used as a jump target when an error is detected by the
* hardened shadow call stack implementation. We set it to 0 which will
* trigger an instruction access exception.
*
* If a compiler without hardened shadow call stack support is used this
* symbol will be ignored.
*/
__abi_shutdown$ = 0x0;
/**
* Physical Memory Protection (PMP) encoded address register values.
*
* Some addresses required for PMP entries are known only at link time.
* These addresses are encoded here so that no calculations need to be
* performed at runtime.
*
* See The RISC-V Instruction Set Manual Volume II: Privileged Architecture
* for more information about PMP address register encodings.
*/
_epmp_text_tor_lo = _text_start / 4;
_epmp_text_tor_hi = _text_end / 4;
_epmp_stack_guard_na4 = _stack_start / 4;
ENTRY(_rom_start_boot);
/**
* NOTE: We have to align each section to word boundaries as our current
* s19->slm conversion scripts are not able to handle non-word aligned sections.
*/
SECTIONS {
/**
* Ibex interrupt vector. See rom_init.S for more information.
*
* This has to be set up at the boot address, so that execution jumps to the
* reset handler correctly.
*/
.vectors _rom_boot_address : ALIGN(256) {
_text_start = .;
KEEP(*(.vectors))
} > rom
/**
* C runtime (CRT) section, containing program initialization code.
*
* This is a separate section to `.text` so that the jumps inside `.vectors`
* will fit into the instruction encoding.
*/
.crt : ALIGN(4) {
/* Pad with zeros. */
FILL(0x0000)
KEEP(*(.crt))
/* .crt must fit in the ePMP RX region at reset. */
ASSERT(
SIZEOF(.vectors) + SIZEOF(.crt) <= _epmp_reset_rx_size,
"Error: .crt overflows reset ePMP region");
. = MAX(., _epmp_reset_rx_size - SIZEOF(.vectors));
} > rom
/**
* Standard text section, containing program code.
*/
.text : ALIGN(4) {
*(.text)
*(.text.*)
/* Ensure section end is word-aligned. */
. = ALIGN(4);
} > rom
/**
* Shutdown text section, containing shutdown function(s).
*
* This must be the last executable section in the ROM.
*/
.shutdown : ALIGN(4) {
*(.shutdown)
*(.shutdown.*)
/* Ensure section end is word-aligned. */
. = ALIGN(4);
_text_end = .;
} > rom
/**
* Read-only data section, containing all large compile-time constants, like
* strings.
*/
.rodata : ALIGN(4) {
/* Small read-only data comes before regular read-only data for the same
* reasons as in the data section */
*(.srodata)
*(.srodata.*)
*(.rodata)
*(.rodata.*)
} > rom
/**
* Critical static data that is accessible by both the ROM and the ROM
* extension.
*/
INCLUDE sw/device/silicon_creator/lib/base/static_critical.ld
/**
* OpenTitan ROM does not have a mutable `.data` section.
*/
.data (NOLOAD) : {
*(.sdata)
*(.sdata.*)
*(.data)
*(.data.*)
/* Tests are an exception to the rule that .data must be empty */
ASSERT(
(DEFINED(rom_test) ? 0 : SIZEOF(.data)) == 0,
"Error: .data section must be empty");
} > ram_main
/**
* Standard BSS section. This will be zeroed at runtime by the CRT.
*/
.bss : ALIGN(4) {
_bss_start = .;
/* This will get loaded into `gp`, and the linker will use that register for
* accessing data within [-2048,2047] of `__global_pointer$`.
*
* This is much cheaper (for small data) than materializing the
* address and loading from that (which will take one extra instruction).
*/
__global_pointer$ = . + 2048;
/* Small BSS should come before regular BSS. This helps to ensure small
* globals are within 2048 bytes of the value of `gp`, making their accesses
* hopefully only take one instruction. */
*(.sbss)
*(.sbss.*)
*(.bss)
*(.bss.*)
/* Ensure section end is word-aligned. */
. = ALIGN(4);
_bss_end = .;
} > ram_main
/**
* Immutable chip_info data, containing build-time-recorded information.
*
* This is the last thing in rom.
*/
.chip_info _chip_info_start : ALIGN(4) {
KEEP(*(.chip_info))
} > rom
INCLUDE sw/device/info_sections.ld
}