|  | /* Copyright 2023 Google LLC. */ | 
|  | /* 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 (test) boot ROM. | 
|  | * | 
|  | * Portions of this file are Ibex-specific. | 
|  | */ | 
|  |  | 
|  | OUTPUT_ARCH(riscv) | 
|  |  | 
|  | /** | 
|  | * Indicate that there are no dynamic libraries, whatsoever. | 
|  | */ | 
|  | __DYNAMIC = 0; | 
|  |  | 
|  | INCLUDE hw/top_matcha/sw/autogen/top_matcha_memory.ld | 
|  |  | 
|  | /** | 
|  | * The boot address, which indicates the location of the initial interrupt | 
|  | * vector. | 
|  | */ | 
|  | _boot_address = ORIGIN(rom); | 
|  |  | 
|  | /** | 
|  | * Symbols to be used in the setup of the address translation for ROM_EXT. | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * This symbol points at the manifest of the OTTF + test binary, which contains | 
|  | * loading and signing information. | 
|  | * | 
|  | * See `sw/device/lib/testing/test_framework/ottf.ld`, under the | 
|  | * .manifest section, which populates it. | 
|  | */ | 
|  | _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."); | 
|  |  | 
|  | _rom_digest_size = 32; | 
|  | _chip_info_start = ORIGIN(rom) + LENGTH(rom) - _rom_digest_size - _chip_info_size; | 
|  |  | 
|  | /* DV Log offset (has to be different to other boot stages). */ | 
|  | _dv_log_offset = 0x0; | 
|  |  | 
|  | /** | 
|  | * We define an entry point only for documentation purposes (and to stop LLD | 
|  | * erroring). In reality, we don't use this information within the ROM image, as | 
|  | * we start at a fixed offset. | 
|  | */ | 
|  | ENTRY(_reset_start); | 
|  |  | 
|  | /** | 
|  | * 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 test_rom_start.S for more information. | 
|  | * | 
|  | * This has to be set up at the boot address, so that execution jumps to the | 
|  | * reset handler correctly. | 
|  | */ | 
|  | .vectors _boot_address : ALIGN(4) { | 
|  | KEEP(*(.vectors)) | 
|  | } > rom | 
|  |  | 
|  | /** | 
|  | * C runtime (CRT) section, containing program initialization code. | 
|  | */ | 
|  | .crt : ALIGN(4) { | 
|  | KEEP(*(.crt)) | 
|  | } > rom | 
|  |  | 
|  | /** | 
|  | * Standard text section, containing program code. | 
|  | */ | 
|  | .text : ALIGN(4) { | 
|  | *(.text) | 
|  | *(.text.*) | 
|  | } > 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 external/lowrisc_opentitan/sw/device/silicon_creator/lib/base/static_critical.ld | 
|  |  | 
|  | /** | 
|  | * Standard mutable data section, at the bottom of RAM. This will be | 
|  | * initialized from the .idata section at runtime by the CRT. | 
|  | */ | 
|  | .data : ALIGN(4) { | 
|  | _data_start = .; | 
|  | _data_init_start = LOADADDR(.data); | 
|  |  | 
|  | /* 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 data should come before larger data. This helps to ensure small | 
|  | * globals are within 2048 bytes of the value of `gp`, making their accesses | 
|  | * hopefully only take one instruction. */ | 
|  | *(.sdata) | 
|  | *(.sdata.*) | 
|  |  | 
|  | /* Other data will likely need multiple instructions to load, so we're less | 
|  | * concerned about address materialisation taking more than one instruction. | 
|  | */ | 
|  | *(.data) | 
|  | *(.data.*) | 
|  |  | 
|  | /* Ensure section end is word-aligned. */ | 
|  | . = ALIGN(4); | 
|  | _data_end = .; | 
|  | _data_init_end = LOADADDR(.data) + SIZEOF(.data); | 
|  |  | 
|  | /* This puts it in ram_main at runtime (for the VMA), but puts the section | 
|  | * into rom for load time (for the LMA). This is why `_data_init_*` uses | 
|  | * `LOADADDR`. */ | 
|  | } > ram_main AT> rom | 
|  |  | 
|  | /** | 
|  | * Immutable chip_info data, containing build-time-recorded information. | 
|  | */ | 
|  | .chip_info _chip_info_start : ALIGN(4) { | 
|  | KEEP(*(.chip_info)) | 
|  | } > rom | 
|  |  | 
|  | /** | 
|  | * Standard BSS section. This will be zeroed at runtime by the CRT. | 
|  | */ | 
|  | .bss : ALIGN(4) { | 
|  | _bss_start = .; | 
|  | /* Small BSS comes before regular BSS for the same reasons as in the data | 
|  | * section */ | 
|  | *(.sbss) | 
|  | *(.sbss.*) | 
|  | *(.bss) | 
|  | *(.bss.*) | 
|  | . = ALIGN(4); | 
|  | _bss_end = .; | 
|  | } > ram_main | 
|  |  | 
|  | INCLUDE external/lowrisc_opentitan/sw/device/info_sections.ld | 
|  | } |