1#![no_std]
2#![allow(incomplete_features)]
3#![feature(alloc_error_handler)]
4#![feature(specialization)]
5#![warn(rust_2018_idioms)]
6
7#[cfg(not(any(test, fuzzing)))]
8pub mod allocator;
9pub mod asm;
10pub mod config;
11pub(crate) mod cose;
12pub mod cpu;
13pub(crate) mod event;
14pub mod exception;
15pub mod gic;
16#[macro_use]
17pub mod granule;
18#[macro_use]
19pub(crate) mod host;
20pub mod logger;
21pub mod mm;
22#[cfg(not(any(test, kani, miri, fuzzing)))]
23pub mod panic;
24pub mod pmu;
25pub mod realm;
26pub mod rec;
27pub mod rmi;
28pub mod rsi;
29pub mod simd;
30#[cfg(feature = "stat")]
31pub mod stat;
32#[cfg(any(test, miri))]
33pub(crate) mod test_utils;
34#[cfg(fuzzing)]
35pub mod test_utils;
36#[macro_use]
37pub mod r#macro;
38mod measurement;
39#[cfg(kani)]
40pub mod monitor;
43#[cfg(not(kani))]
44mod monitor;
45mod rmm_el3;
46
47extern crate alloc;
48
49#[macro_use]
50extern crate lazy_static;
51
52#[macro_use]
53extern crate log;
54
55use crate::config::PlatformMemoryLayout;
56use crate::exception::vectors;
57#[cfg(feature = "gst_page_table")]
58use crate::granule::create_granule_status_table as setup_gst;
59use crate::mm::translation::{get_page_table, init_page_table};
60use crate::monitor::Monitor;
61use crate::rmm_el3::setup_el3_ifc;
62
63use aarch64_cpu::registers::*;
64use armv9a::{MDCR_EL2, PMCR_EL0};
65use core::ptr::addr_of;
66
67#[cfg(not(kani))]
68pub unsafe fn start(cpu_id: usize, layout: PlatformMemoryLayout) {
80 let el3_shared_buf = layout.el3_shared_buf;
81 setup_mmu_cfg(layout);
82 info!(
83 "booted on core {:2} with EL{}!",
84 cpu_id,
85 CurrentEL.read(CurrentEL::EL) as u8
86 );
87 setup_el2();
88 #[cfg(feature = "gst_page_table")]
89 setup_gst();
90 if cpu_id == 0 {
92 setup_el3_ifc(el3_shared_buf);
93 }
94
95 Monitor::new().run();
96}
97
98unsafe fn setup_el2() {
112 HCR_EL2.write(
113 HCR_EL2::FWB::SET
114 + HCR_EL2::TEA::SET
115 + HCR_EL2::TERR::SET
116 + HCR_EL2::TLOR::SET
117 + HCR_EL2::RW::SET
118 + HCR_EL2::TSW::SET
119 + HCR_EL2::TACR::SET
120 + HCR_EL2::TIDCP::SET
121 + HCR_EL2::TSC::SET
122 + HCR_EL2::TID3::SET
123 + HCR_EL2::BSU::InnerShareable
124 + HCR_EL2::FB::SET
125 + HCR_EL2::AMO::SET
126 + HCR_EL2::IMO::SET
127 + HCR_EL2::FMO::SET
128 + HCR_EL2::VM::SET
129 + HCR_EL2::API::SET
130 + HCR_EL2::APK::SET,
131 );
133 VBAR_EL2.set(addr_of!(vectors) as u64);
134 SCTLR_EL2
135 .write(SCTLR_EL2::C::SET + SCTLR_EL2::I::SET + SCTLR_EL2::M::SET + SCTLR_EL2::EOS::SET);
136 CPTR_EL2.write(CPTR_EL2::TAM::SET);
137 ICC_SRE_EL2.write(
138 ICC_SRE_EL2::ENABLE::SET
139 + ICC_SRE_EL2::DIB::SET
140 + ICC_SRE_EL2::DFB::SET
141 + ICC_SRE_EL2::SRE::SET,
142 );
143 MDCR_EL2.write(
144 MDCR_EL2::MTPME::SET
145 + MDCR_EL2::HCCD::SET
146 + MDCR_EL2::HPMD::SET
147 + MDCR_EL2::TDA::SET
148 + MDCR_EL2::TPM::SET
149 + MDCR_EL2::TPMCR::SET
150 + MDCR_EL2::HPMN.val(PMCR_EL0.read(PMCR_EL0::N)),
151 );
152}
153
154unsafe fn setup_mmu_cfg(layout: PlatformMemoryLayout) {
167 core::arch::asm!("tlbi alle2is", "dsb ish", "isb",);
168
169 let mair_el2 = MAIR_EL2::Attr0_Normal_Outer::WriteBack_NonTransient_ReadWriteAlloc
171 + MAIR_EL2::Attr0_Normal_Inner::WriteBack_NonTransient_ReadWriteAlloc
172 + MAIR_EL2::Attr1_Device::nonGathering_nonReordering_noEarlyWriteAck
173 + MAIR_EL2::Attr2_Device::nonGathering_nonReordering_EarlyWriteAck;
174
175 let tcr_el2 = TCR_EL2::T0SZ.val(0x19)
183 + TCR_EL2::PS::Bits_40
184 + TCR_EL2::TG0::KiB_4
185 + TCR_EL2::SH0::Inner
186 + TCR_EL2::ORGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable
187 + TCR_EL2::IRGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable;
188
189 init_page_table(layout);
192 let ttbl_base = get_page_table();
193
194 MAIR_EL2.write(mair_el2);
197 TCR_EL2.write(tcr_el2);
198 TTBR0_EL2.set(ttbl_base);
199 core::arch::asm!("dsb ish", "isb",);
200}
201
202#[cfg(not(kani))]
220pub unsafe fn rmm_exit(args: [usize; 4]) -> [usize; 4] {
221 let mut ret: [usize; 4] = [0usize; 4];
222
223 core::arch::asm!(
224 "bl rmm_exit",
225 inlateout("x0") args[0] => ret[0],
226 inlateout("x1") args[1] => ret[1],
227 inlateout("x2") args[2] => ret[2],
228 inlateout("x3") args[3] => ret[3],
229 );
230
231 ret
232}
233
234#[cfg(kani)]
235pub unsafe fn rmm_exit(_args: [usize; 4]) -> [usize; 4] {
236 let ret: [usize; 4] = [0usize; 4];
237 ret
238}