Skip to content

Commit

Permalink
[imm_rom_ext] Refine linker script and startup asm
Browse files Browse the repository at this point in the history
* Refine ld and .S file for IMM_ROM_EXT.
* Update the hello-world IMM_ROM_EXT to access some data in .data and
  .bss sections to make sure the startup initialization is implemented
  correctly.

Signed-off-by: Chia-Wei Liu <[email protected]>
  • Loading branch information
lchiawei committed Jan 20, 2025
1 parent 673c41f commit 2aeb83d
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 15 deletions.
3 changes: 3 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ ld_library(
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey_memory",
"//sw/device:info_sections",
"//sw/device/silicon_creator/lib/base:static_critical_sections",
],
)

Expand All @@ -69,6 +70,7 @@ cc_library(
hdrs = ["hello_world.h"],
target_compatible_with = [OPENTITAN_CPU],
deps = [
"//sw/device/silicon_creator/lib/base:static_critical",
"//sw/device/silicon_creator/lib/drivers:uart",
],
)
Expand All @@ -85,6 +87,7 @@ opentitan_binary(
linker_script = ":ld_hello_world",
deps = [
":hello_world",
"//sw/device/lib/crt",
],
)

Expand Down
16 changes: 14 additions & 2 deletions sw/device/silicon_creator/imm_rom_ext/hello_world.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,27 @@

#include "sw/device/silicon_creator/lib/drivers/uart.h"

// These arrays are used to "HelloWorld!" to the UART console.
// o l l e H
uint64_t kArray1[8] = {0x6f6c6c6548};
// The value will be updated in the main function.
uint64_t kArray2[8];

void imm_rom_ext_main(void) {
// Print "Immutable" to the UART console.
// l b a t u m m I
const uint64_t kStr1 = 0x6c626174756d6d49;
// e
const uint32_t kStr2 = 0x65;
// : e
const uint32_t kStr2 = 0x3a65;
const uint32_t kSpace = 0x20;
const uint32_t kNewline = 0x0a0d;
uart_write_imm(kStr1);
uart_write_imm(kStr2);
uart_write_imm(kSpace);
// ! d l r o W
kArray2[0] += 0x21646c726f57;
uart_write_imm(kArray1[0]); // To test the .data section.
uart_write_imm(kArray2[0]); // To test the .bss section.
uart_write_imm(kNewline);

// Wait until the UART is done transmitting.
Expand Down
138 changes: 127 additions & 11 deletions sw/device/silicon_creator/imm_rom_ext/hello_world.ld
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
* TODO(#24368): Adapt the linker script for real IMM_ROM_EXT. This linker
* script only works for hello-world IMM_ROM_EXT.
*/

INCLUDE hw/top_earlgrey/sw/autogen/top_earlgrey_memory.ld

/**
* Symbols to be used in the setup of the address translation for IMM_ROM_EXT.
*/

MEMORY {
imm_rom_ext_virtual(rx) : ORIGIN = ORIGIN(rom_ext_virtual) + 0x400, LENGTH = 0x80000 - 0x400
}

REGION_ALIAS("rom_ext_flash", imm_rom_ext_virtual);

OUTPUT_ARCH(riscv)

/**
Expand All @@ -19,28 +32,131 @@ _dv_log_offset = 0x10000;
ENTRY(_imm_rom_ext_start_boot)

SECTIONS {
.rom_ext_immutable : ALIGN(4) {
/* Ibex */
*(.vectors)
. = ALIGN(256);
/* CRT */
*(.crt)
. = ALIGN(4);
/* Text */
/**
* Ibex interrupt vector.
*
* This has to be set up at a 256-byte offset, so that we can use it with
* Ibex.
*/
.vectors : ALIGN(256) {
_text_start = .;
_rom_ext_immutable_start = .;
KEEP(*(.vectors))
} > rom_ext_flash

/**
* C runtime (CRT) section, containing program initialization code.
*/
.crt : ALIGN(4) {
KEEP(*(.crt))
} > rom_ext_flash

/**
* Standard text section, containing program code.
*/
.text : ALIGN(4) {
*(.text)
*(.text.*)

/* Ensure section end is word-aligned. */
. = ALIGN(4);
/* Read-only Data */
} > rom_ext_flash

/**
* Shutdown text section, containing shutdown function(s).
*
* This must be the last executable section in the ROM_EXT flash image.
*/
.shutdown : ALIGN(4) {
*(.shutdown)
*(.shutdown.*)

/* Ensure section end is word-aligned. */
. = ALIGN(4);
_text_end = .;
} > rom_ext_flash

/**
* 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.*)
. = ALIGN(4);
} > rom_ext_flash

/**
* Critical static data that is accessible by both the ROM and the ROM
* extension.
*/
INCLUDE sw/device/silicon_creator/lib/base/static_critical.ld

/**
* Mutable data section, at the bottom of ram_main. This will be initialized
* from flash at runtime by the CRT.
*
* Load this by copying the bytes from [_data_init_start, _data_init_end] into
* the range [_data_start, _data_end].
*/
.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);
_rom_ext_immutable_end = LOADADDR(.data) + SIZEOF(.data);

/* This puts it in ram_main at runtime (for the VMA), but puts the section
* into flash for load time (for the LMA). This is why `_data_init_*` uses
* `LOADADDR`.
*
* Using `AT>` means we don't have to keep track of the next free part of
* flash, as we do in our other linker scripts. */
} > ram_main AT> rom_ext_flash

/**
* 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.*)

/* Ensure section end is word-aligned. */
. = ALIGN(4);
}
_bss_end = .;
} > ram_main

INCLUDE sw/device/info_sections.ld
}
81 changes: 79 additions & 2 deletions sw/device/silicon_creator/imm_rom_ext/hello_world_start.S
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,90 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// TODO(#24368): Adapt the startup assembly for real IMM_ROM_EXT. This startup
// assembly only works for hello-world IMM_ROM_EXT.
#include "hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h"
#include "sw/device/lib/base/hardened_asm.h"

/**
* NOTE: The "ax" flag below is necessary to ensure that this section
* is allocated executable space in ROM by the linker.
*/
.section .crt, "ax"

/**
* Entry point.
*
* This symbol is jumped to from `rom_boot` using the `entry_point` field
* of the manifest.
*/
.balign 4
.global _imm_rom_ext_start_boot
.type _imm_rom_ext_start_boot, @function
_imm_rom_ext_start_boot:

.option push
.option norelax

/**
* Set up the global pointer `gp`.
*/
la gp, __global_pointer$

.option pop

/**
* Save registers.
*/
addi sp, sp, -8
sw ra, 4(sp)

/**
* Disable Interrupts.
*
* We cannot disable exceptions, or Ibex's non-maskable interrupts (interrupt
* 31), so we still need to be careful.
*/

// Clear `MIE` field of `mstatus` (disable interrupts globally).
csrci mstatus, 0x8

/**
* Clear all the machine-defined interrupts, `MEIE`, `MTIE`, and `MSIE` fields
* of `mie`.
*/
li t0, 0xFFFF0888
csrc mie, t0

/**
* Setup C Runtime
*/
/**
* Initialize the `.data` section in RAM from ROM.
*/
la a0, _data_start
la a1, _data_end
la a2, _data_init_start
jal ra, crt_section_copy

/**
* Initialize the `.bss` section.
*
* We do this despite zeroing all of SRAM above, so that we still zero `.bss`
* once we've enabled SRAM scrambling.
*/
la a0, _bss_start
la a1, _bss_end
jal ra, crt_section_clear


/**
* Restore registers.
*/
lw ra, 4(sp)
addi sp, sp, 8

/**
* Jump to IMM_ROM_EXT.
*/
tail imm_rom_ext_main

.size _imm_rom_ext_start_boot, .-_imm_rom_ext_start_boot

0 comments on commit 2aeb83d

Please sign in to comment.