| // 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 |
| "# |
| ); |