From 331db6ca3361b821c20226e1f3e13db8f8b5bd45 Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Tue, 5 Nov 2019 21:45:24 +0100 Subject: [PATCH] Little refactoring --- 11_virtual_memory/README.md | 49 +++++++++++++++------- 11_virtual_memory/kernel | Bin 146800 -> 146800 bytes 11_virtual_memory/kernel8.img | Bin 65560 -> 65560 bytes 11_virtual_memory/src/arch/aarch64/mmu.rs | 47 ++++++++++++++------- 4 files changed, 65 insertions(+), 31 deletions(-) diff --git a/11_virtual_memory/README.md b/11_virtual_memory/README.md index 47d93244..87352d67 100644 --- a/11_virtual_memory/README.md +++ b/11_virtual_memory/README.md @@ -266,7 +266,7 @@ make chainbot diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/aarch64/mmu.rs --- 10_privilege_level/src/arch/aarch64/mmu.rs +++ 11_virtual_memory/src/arch/aarch64/mmu.rs -@@ -0,0 +1,292 @@ +@@ -0,0 +1,309 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter @@ -499,21 +499,12 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + ); +} + -+/// Compile the page tables from the `BSP`-supplied `virt_mem_layout()`. ++/// Iterates over all static page table entries and fills them at once. +/// +/// # Safety +/// -+/// - User must ensure that the hardware supports the paremeters being set here. -+pub unsafe fn init() -> Result<(), &'static str> { -+ // Fail early if translation granule is not supported. Both RPis support it, though. -+ if !ID_AA64MMFR0_EL1.matches_all(ID_AA64MMFR0_EL1::TGran64::Supported) { -+ return Err("MMU does not support 64 KiB translation granule"); -+ } -+ -+ // Prepare the memory attribute indirection register. -+ set_up_mair(); -+ -+ // Iterate over all page table entries and fill them at once. ++/// - Modifies a `static mut`. Ensure it only happens from here. ++unsafe fn populate_pt_entries() -> Result<(), &'static str> { + for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { + *l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); + @@ -530,10 +521,11 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + } + } + -+ // Set the "Translation Table Base Register". -+ TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); ++ Ok(()) ++} + -+ // Configure various settings of stage 1 of the EL1 translation regime. ++/// Configure various settings of stage 1 of the EL1 translation regime. ++fn configure_translation_control() { + let ips = ID_AA64MMFR0_EL1.read(ID_AA64MMFR0_EL1::PARange); + TCR_EL1.write( + TCR_EL1::TBI0::Ignored @@ -545,6 +537,31 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + + TCR_EL1::EPD0::EnableTTBR0Walks + + TCR_EL1::T0SZ.val(32), // TTBR0 spans 4 GiB total. + ); ++} ++ ++/// Compile the page tables from the `BSP`-supplied `virt_mem_layout()`. ++/// ++/// # Safety ++/// ++/// - User must ensure that the hardware supports the paremeters being set here. ++pub unsafe fn init() -> Result<(), &'static str> { ++ // Fail early if translation granule is not supported. Both RPis support it, though. ++ if !ID_AA64MMFR0_EL1.matches_all(ID_AA64MMFR0_EL1::TGran64::Supported) { ++ return Err("MMU does not support 64 KiB translation granule"); ++ } ++ ++ // Prepare the memory attribute indirection register. ++ set_up_mair(); ++ ++ // Populate page tables. ++ if let Err(string) = populate_pt_entries() { ++ return Err(string); ++ } ++ ++ // Set the "Translation Table Base Register". ++ TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); ++ ++ configure_translation_control(); + + // Switch the MMU on. + // diff --git a/11_virtual_memory/kernel b/11_virtual_memory/kernel index f5c633136e325db7f054ebb1f6109198439765bc..4cdc7bfc138bd4bfd5ff7ec03b8468c68c80be47 100755 GIT binary patch delta 35 qcmezHi{ryDj)pCaH)J>-Fw3uc2*lHG$S}&Z|B+$b{zrzXL;(OV3J)9r delta 35 qcmezHi{ryDj)pCaH)N(ikYSYJc)%>b>LC!f|B+$b{zrzXL;(OT#SbI^ diff --git a/11_virtual_memory/kernel8.img b/11_virtual_memory/kernel8.img index 24e4e5f5ace801f0ef4a32f8e4a28ec2d3510246..823d6b9d5015bb0f873a2ef9b826770ba7ba3b52 100755 GIT binary patch delta 27 icmbQyz%rwOWy1{_jt9*0s~!UJ Result<(), &'static str> { - // Fail early if translation granule is not supported. Both RPis support it, though. - if !ID_AA64MMFR0_EL1.matches_all(ID_AA64MMFR0_EL1::TGran64::Supported) { - return Err("MMU does not support 64 KiB translation granule"); - } - - // Prepare the memory attribute indirection register. - set_up_mair(); - - // Iterate over all page table entries and fill them at once. +/// - Modifies a `static mut`. Ensure it only happens from here. +unsafe fn populate_pt_entries() -> Result<(), &'static str> { for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { *l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); @@ -261,10 +252,11 @@ pub unsafe fn init() -> Result<(), &'static str> { } } - // Set the "Translation Table Base Register". - TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + Ok(()) +} - // Configure various settings of stage 1 of the EL1 translation regime. +/// Configure various settings of stage 1 of the EL1 translation regime. +fn configure_translation_control() { let ips = ID_AA64MMFR0_EL1.read(ID_AA64MMFR0_EL1::PARange); TCR_EL1.write( TCR_EL1::TBI0::Ignored @@ -276,6 +268,31 @@ pub unsafe fn init() -> Result<(), &'static str> { + TCR_EL1::EPD0::EnableTTBR0Walks + TCR_EL1::T0SZ.val(32), // TTBR0 spans 4 GiB total. ); +} + +/// Compile the page tables from the `BSP`-supplied `virt_mem_layout()`. +/// +/// # Safety +/// +/// - User must ensure that the hardware supports the paremeters being set here. +pub unsafe fn init() -> Result<(), &'static str> { + // Fail early if translation granule is not supported. Both RPis support it, though. + if !ID_AA64MMFR0_EL1.matches_all(ID_AA64MMFR0_EL1::TGran64::Supported) { + return Err("MMU does not support 64 KiB translation granule"); + } + + // Prepare the memory attribute indirection register. + set_up_mair(); + + // Populate page tables. + if let Err(string) = populate_pt_entries() { + return Err(string); + } + + // Set the "Translation Table Base Register". + TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + + configure_translation_control(); // Switch the MMU on. //