blob: 99ec235a0e5ab1ba0216a13d9501e310d9810891 [file] [edit]
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0
#![no_std]
#![no_main]
use core::arch::global_asm;
use arch_riscv::Arch;
use kernel::{self as _};
mod epmp;
#[unsafe(no_mangle)]
#[allow(non_snake_case)]
pub unsafe extern "C" fn pw_assert_HandleFailure() -> ! {
use kernel::Arch as _;
Arch::panic()
}
#[riscv_rt::entry]
fn main() -> ! {
kernel::static_init_state!(static mut INIT_STATE: InitKernelState<Arch>);
epmp::init();
// SAFETY: `main` is only executed once, so we never generate more than one
// `&mut` reference to `INIT_STATE`.
#[allow(static_mut_refs)]
kernel::main(Arch, unsafe { &mut INIT_STATE });
}
global_asm!(
"
.option push
.option norvc
.option norelax
.balign 256
.global _mtvec_table
_mtvec_table:
j _start_trap /* 0: exception and user software interrupt */
j _start_trap /* 1: supervisor software interrupt */
j _start_trap /* 2: reserved */
j _start_trap /* 3: machine software interrupt */
j _start_trap /* 4: user timer interrupt */
j _start_trap /* 5: supervisor timer interrupt */
j _start_trap /* 6: reserved */
j _start_trap /* 7: machine timer interrupt */
j _start_trap /* 8: user external interrupt */
j _start_trap /* 9: supervisor external interrupt */
j _start_trap /* 10: reserved */
j _start_trap /* 11: machine external interrupt */
j _start_trap /* 12: reserved */
j _start_trap /* 13: reserved */
j _start_trap /* 14: reserved */
j _start_trap /* 15: reserved */
j _start_trap /* 16-30: On Ibex, reserved for 'fast' interrupts */
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap
j _start_trap /* 31: reset vector */
.size _mtvec_table, .-_mtvec_table
.option pop
"
);
#[cfg(feature = "verilator")]
global_asm!(
r#"
/*
* We don't want to have separate build targets or linker script templating
* to run under verilator (e.g. to set the origin to 0x2000_0000 instead of
* the normal value of 0x2001_0000).
*
* Instead, when building for verilator, we add a ".fake_rom_ext" section that
* the linker script locates at 0x2000_0000. In this section, we construct
* the most trivial of ROM_EXT manifests and set the entrypoint to the start
* offset of the kernel.
*
* The verilator test ROM doesn't do any validation of the manifest header.
* We don't _need_ to set any version numbers or magic identifier words.
*
* We set the following:
* address_translation: HardenedFalse (we want the test_rom to boot us at 0x20000000).
* identifier: So we show up nicely in `opentitantool image manifest show ...`.
* length: So we show up nicely...
* entry_point: Offset the test_rom will jump to.
*/
.section .fake_rom_ext, "ax"
.option push
.option norvc
.option norelax
.global _rom_ext_manifest
.global _rom_ext_trampoline
_rom_ext_manifest:
.space 816
.word 0x1d4 /* address_translation (HardenedFalse) */
.word 0x4552544f /* identifier (OTRE) */
.word 0 /* manifest_version (minor, major) */
.word 0 /* signed_region_end */
.word 0x10000 /* length */
.space 64
.word _rom_ext_trampoline-_rom_ext_manifest /* entry_point */
.space 120
_rom_ext_trampoline:
la a0, 0x411f0000 /* base of rv_core_ibex */
la a1, 0xa007FFFF /* target address & size for remap (512K) */
la a2, _rom_ext_manifest /* reads from this source address */
/* store target to IBUS_ and DBUS_ADDR_MATCHING_1 */
sw a1, 0x20(a0)
sw a1, 0x40(a0)
/* store source to IBUS_ and DBUS_REMAP_ADDR_1 */
sw a2, 0x28(a0)
sw a2, 0x48(a0)
/* enable via IBUS_ and DBUS_ADDR_EN_1 */
li a2, 1
sw a2, 0x18(a0)
sw a2, 0x38(a0)
/* next manifest address */
la a1, 0xa0010000
/* next manifest entry point */
lw a2, 900(a1)
add ra, a1, a2
jalr zero, ra, 0
.option pop
"#
);