| /* 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 |
| } |