1use aarch64_cpu::{asm::barrier, registers::*};
4use ax_memory_addr::PhysAddr;
5
6pub unsafe fn switch_to_el1() {
16 SPSel.write(SPSel::SP::ELx);
17 SP_EL0.set(0);
18 let current_el = CurrentEL.read(CurrentEL::EL);
19 if current_el >= 2 {
20 if current_el == 3 {
21 SCR_EL3.write(
23 SCR_EL3::NS::NonSecure + SCR_EL3::HCE::HvcEnabled + SCR_EL3::RW::NextELIsAarch64,
24 );
25 SPSR_EL3.write(
27 SPSR_EL3::M::EL1h
28 + SPSR_EL3::D::Masked
29 + SPSR_EL3::A::Masked
30 + SPSR_EL3::I::Masked
31 + SPSR_EL3::F::Masked,
32 );
33 ELR_EL3.set(LR.get());
34 }
35 CNTHCTL_EL2.modify(CNTHCTL_EL2::EL1PCEN::SET + CNTHCTL_EL2::EL1PCTEN::SET);
37 CNTVOFF_EL2.set(0);
38 HCR_EL2.write(HCR_EL2::RW::EL1IsAarch64);
40 SPSR_EL2.write(
42 SPSR_EL2::M::EL1h
43 + SPSR_EL2::D::Masked
44 + SPSR_EL2::A::Masked
45 + SPSR_EL2::I::Masked
46 + SPSR_EL2::F::Masked,
47 );
48 SP_EL1.set(SP.get());
49 ELR_EL2.set(LR.get());
50 aarch64_cpu::asm::eret();
51 }
52}
53
54pub unsafe fn init_mmu(root_paddr: PhysAddr) {
64 use ax_page_table_entry::aarch64::MemAttr;
65
66 MAIR_EL1.set(MemAttr::MAIR_VALUE);
67
68 let tcr_flags0 = TCR_EL1::EPD0::EnableTTBR0Walks
70 + TCR_EL1::TG0::KiB_4
71 + TCR_EL1::SH0::Inner
72 + TCR_EL1::ORGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable
73 + TCR_EL1::IRGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable
74 + TCR_EL1::T0SZ.val(16);
75 let tcr_flags1 = TCR_EL1::EPD1::EnableTTBR1Walks
76 + TCR_EL1::TG1::KiB_4
77 + TCR_EL1::SH1::Inner
78 + TCR_EL1::ORGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable
79 + TCR_EL1::IRGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable
80 + TCR_EL1::T1SZ.val(16);
81 TCR_EL1.write(TCR_EL1::IPS::Bits_48 + tcr_flags0 + tcr_flags1);
82 barrier::isb(barrier::SY);
83
84 let root_paddr = root_paddr.as_usize() as u64;
86 TTBR0_EL1.set(root_paddr);
87 TTBR1_EL1.set(root_paddr);
88
89 crate::asm::flush_tlb(None);
91
92 SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable);
94 SCTLR_EL1.set(SCTLR_EL1.get() | (1 << 23));
96 barrier::isb(barrier::SY);
97}
98
99pub fn init_trap() {
104 #[cfg(feature = "uspace")]
105 crate::uspace_common::init_exception_table();
106 unsafe extern "C" {
107 fn exception_vector_base();
108 }
109 unsafe {
110 crate::asm::write_exception_vector_base(exception_vector_base as *const () as usize);
111 crate::asm::write_user_page_table(0.into());
112 }
113}