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(
99 SCTLR_EL1::M::Enable
100 + SCTLR_EL1::C::Cacheable
101 + SCTLR_EL1::I::Cacheable
102 + SCTLR_EL1::UCT::DontTrap
103 + SCTLR_EL1::DZE::DontTrap
104 + SCTLR_EL1::UCI::DontTrap,
105 );
106 SCTLR_EL1.set(SCTLR_EL1.get() | (1 << 23));
108 barrier::isb(barrier::SY);
109}
110
111pub fn init_trap() {
116 #[cfg(feature = "uspace")]
117 {
118 crate::uspace_common::init_exception_table();
119 CNTKCTL_EL1.modify(CNTKCTL_EL1::EL0VCTEN::TrappedNone + CNTKCTL_EL1::EL0PCTEN::TrappedNone);
120 barrier::isb(barrier::SY);
121 }
122 unsafe extern "C" {
123 fn exception_vector_base();
124 }
125 unsafe {
126 crate::asm::write_exception_vector_base(exception_vector_base as *const () as usize);
127 crate::asm::write_user_page_table(0.into());
128 }
129}