From b2219ca5209927769670aad523cf7885627c475d Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Thu, 7 Nov 2019 22:29:30 +0100 Subject: [PATCH] Housekeeping --- 05_safe_globals/README.md | 10 +- 05_safe_globals/src/arch/aarch64/sync.rs | 8 + 06_drivers_gpio_uart/kernel | Bin 83472 -> 83472 bytes 06_drivers_gpio_uart/kernel8.img | Bin 8064 -> 8064 bytes 06_drivers_gpio_uart/src/arch/aarch64/sync.rs | 8 + 07_uart_chainloader/kernel | Bin 85296 -> 85296 bytes 07_uart_chainloader/kernel8.img | Bin 8968 -> 8968 bytes 07_uart_chainloader/src/arch/aarch64/sync.rs | 8 + 08_timestamps/README.md | 10 +- 08_timestamps/kernel | Bin 90032 -> 90032 bytes 08_timestamps/kernel8.img | Bin 13080 -> 13080 bytes 08_timestamps/src/arch/aarch64/sync.rs | 8 + 08_timestamps/src/arch/aarch64/time.rs | 8 + 09_hw_debug_JTAG/kernel | Bin 90040 -> 90032 bytes 09_hw_debug_JTAG/kernel8.img | Bin 13080 -> 13080 bytes 09_hw_debug_JTAG/src/arch/aarch64/sync.rs | 8 + 09_hw_debug_JTAG/src/arch/aarch64/time.rs | 8 + 10_privilege_level/README.md | 8 +- 10_privilege_level/kernel | Bin 93784 -> 93784 bytes 10_privilege_level/kernel8.img | Bin 15672 -> 15672 bytes 10_privilege_level/src/arch/aarch64.rs | 2 +- .../src/arch/aarch64/exception.rs | 4 + 10_privilege_level/src/arch/aarch64/sync.rs | 8 + 10_privilege_level/src/arch/aarch64/time.rs | 8 + 11_virtual_memory/README.md | 139 +++++++++++++----- 11_virtual_memory/kernel | Bin 146792 -> 146944 bytes 11_virtual_memory/kernel8.img | Bin 65560 -> 65560 bytes 11_virtual_memory/src/arch/aarch64.rs | 10 +- .../src/arch/aarch64/exception.rs | 4 + 11_virtual_memory/src/arch/aarch64/mmu.rs | 73 ++++----- 11_virtual_memory/src/arch/aarch64/sync.rs | 8 + 11_virtual_memory/src/arch/aarch64/time.rs | 8 + .../src/bsp/rpi/virt_mem_layout.rs | 4 + 11_virtual_memory/src/interface.rs | 8 + 11_virtual_memory/src/main.rs | 4 +- 35 files changed, 283 insertions(+), 81 deletions(-) diff --git a/05_safe_globals/README.md b/05_safe_globals/README.md index 51fe8053..78984217 100644 --- a/05_safe_globals/README.md +++ b/05_safe_globals/README.md @@ -55,7 +55,7 @@ make qemu diff -uNr 04_zero_overhead_abstraction/src/arch/aarch64/sync.rs 05_safe_globals/src/arch/aarch64/sync.rs --- 04_zero_overhead_abstraction/src/arch/aarch64/sync.rs +++ 05_safe_globals/src/arch/aarch64/sync.rs -@@ -0,0 +1,44 @@ +@@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter @@ -65,6 +65,10 @@ diff -uNr 04_zero_overhead_abstraction/src/arch/aarch64/sync.rs 05_safe_globals/ +use crate::interface; +use core::cell::UnsafeCell; + ++//-------------------------------------------------------------------------------------------------- ++// Arch-public ++//-------------------------------------------------------------------------------------------------- ++ +/// A pseudo-lock for teaching purposes. +/// +/// Used to introduce [interior mutability]. @@ -91,6 +95,10 @@ diff -uNr 04_zero_overhead_abstraction/src/arch/aarch64/sync.rs 05_safe_globals/ + } +} + ++//-------------------------------------------------------------------------------------------------- ++// OS interface implementations ++//-------------------------------------------------------------------------------------------------- ++ +impl interface::sync::Mutex for &NullLock { + type Data = T; + diff --git a/05_safe_globals/src/arch/aarch64/sync.rs b/05_safe_globals/src/arch/aarch64/sync.rs index dfebc0e1..2f6900b0 100644 --- a/05_safe_globals/src/arch/aarch64/sync.rs +++ b/05_safe_globals/src/arch/aarch64/sync.rs @@ -7,6 +7,10 @@ use crate::interface; use core::cell::UnsafeCell; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + /// A pseudo-lock for teaching purposes. /// /// Used to introduce [interior mutability]. @@ -33,6 +37,10 @@ impl NullLock { } } +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::sync::Mutex for &NullLock { type Data = T; diff --git a/06_drivers_gpio_uart/kernel b/06_drivers_gpio_uart/kernel index 1dfc7228b62c9cfb0f18d1b7a79d1495e9bb9af0..bb9ebb9f67cadd7a35f6c2e1039297cf7e546653 100755 GIT binary patch delta 610 zcmZwDJuE{}7zW_)E#ekImDEAfH1$*eSDV&PB}fp9Xcs>V>DGb7K#YteqH6H1L8a}B}9xCk(io@usPQ`OT!(`P44r)=X~exZWrxt7j0Z1ArO^Gfgua;oDIN-4tW;9 zI)p4Gg3CpTI*Xjg{#}W_cqFJ|dpsA!0y_9Ih>Tb&(cvus( zHDe0G?{?w^wCvY=SDN@D=UU(s$A;5}b%-d(fso>enQXIOL&&sOIT^y5pb8?F3-n;+ zZ=T_o5KhE|I?Uk@!_}re&xfsw?^WBm_GyD|>y@ZjrrO{u5IIvHtj*s&&e=}&TMpz| zr@A4U_`3^FnCH80^);9K{jv#b0fmCB5XT3APp;#G%)vP&$;`3Z>9Nh?^Z7 z2s9_ix3&b-Oo9jx1qV0DCMd%E7c+(;Mc>hRe(WOEv85Vuo0o}~Sp**k6HdwhNuS@GKPj%5=f>T}*zT(y%OP8o1* z`#G<>Xo%!>qC^7p-5K8eC7-!?Bc7_mH1{oMY&+tU8O1+TTVMO_Ez>qD(Ws1Okxh!e zt=A`qcYna~y!tI2*_~H6gv)~>P7(391@(2;yc!Ho&7ZkOG(jLIHGIStmo#@QhgS`+ z*a81?q&Zdt=yuw+pTT&{vF6^m;jcGLyMD#+fWIh)FMoR2NM%aC7x>=2pi&B|mBsRs gU-rwqdLI{;%UTV^OGUP8`0U8=5sraheEt}@f0~+Ow*UYD diff --git a/06_drivers_gpio_uart/kernel8.img b/06_drivers_gpio_uart/kernel8.img index f5878447f3f0106266df41aead4165f619acec6e..8390c8320f092f5d7f626dbdad185d57190aa62b 100755 GIT binary patch delta 14 VcmZp$Z?NAGAjxRDIZ#rc4FDu11Rwwa delta 14 VcmZp$Z?NAGAjxRHIZ#rc4FDuD1R?+c diff --git a/06_drivers_gpio_uart/src/arch/aarch64/sync.rs b/06_drivers_gpio_uart/src/arch/aarch64/sync.rs index dfebc0e1..2f6900b0 100644 --- a/06_drivers_gpio_uart/src/arch/aarch64/sync.rs +++ b/06_drivers_gpio_uart/src/arch/aarch64/sync.rs @@ -7,6 +7,10 @@ use crate::interface; use core::cell::UnsafeCell; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + /// A pseudo-lock for teaching purposes. /// /// Used to introduce [interior mutability]. @@ -33,6 +37,10 @@ impl NullLock { } } +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::sync::Mutex for &NullLock { type Data = T; diff --git a/07_uart_chainloader/kernel b/07_uart_chainloader/kernel index 210c2c01f0afb0606d66eb5bbd677b6c17d11d8d..d9c547fabd7297d8a85a090e3a7e6d5c40f3a88e 100755 GIT binary patch delta 630 zcmZvYF-V(17>4gn3?!!7KZ#&}ipHNJNvw%UjEw=21aSzB6g!A@5y8OV;0aVs@MO{S5KoixHE(Ww zqH>x|7eQTitwWnOpj8vHo>qN8$Z%UPH8UIz>McdrJlRJN)w_9w_leG$65=~KBa9t> z)1ZL(V*bHv_!3PkTr>Djr%vY$_EA~k(|}Izne<(;A*w5!3TgZ;sM8s@jxW=t!k-Q9 zdaQBD$Xhb-3|4z6olOm=bGhMcawMBeW|NuJD3$Z*lEpkM+>2KVNZbpq3y8>{13(A4p81NsOc)rPvQEiCR+=za*bnO0tNhE#e@kTZ@YX!9c;)Op>LN z#TP=L2!)c#1Pix_A!BhUMT)eOLYFQDw{H3#cO3+8_>Py~J->Ut>oonHrhoSf9@v|~}>NMYL z8%H{%9jnH%PKOGghg5ryc>74>L4ydEy!+8_3;rLZX2S$!{HIVIdsjFbvmTp%`XCDI%`UZGqUrHpYWT; z1w_mIL%{F~Eh~I%@b5vLE*TuAn!?{=I{nF{{};u}p3p~z^tSyJ&mBLF0@1f2i? delta 14 VcmeBh>u}p3p~z^xSyJ&mBLF141fKu^ diff --git a/07_uart_chainloader/src/arch/aarch64/sync.rs b/07_uart_chainloader/src/arch/aarch64/sync.rs index dfebc0e1..2f6900b0 100644 --- a/07_uart_chainloader/src/arch/aarch64/sync.rs +++ b/07_uart_chainloader/src/arch/aarch64/sync.rs @@ -7,6 +7,10 @@ use crate::interface; use core::cell::UnsafeCell; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + /// A pseudo-lock for teaching purposes. /// /// Used to introduce [interior mutability]. @@ -33,6 +37,10 @@ impl NullLock { } } +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::sync::Mutex for &NullLock { type Data = T; diff --git a/08_timestamps/README.md b/08_timestamps/README.md index 315c19c6..5ee2f065 100644 --- a/08_timestamps/README.md +++ b/08_timestamps/README.md @@ -100,7 +100,7 @@ diff -uNr 07_uart_chainloader/Makefile 08_timestamps/Makefile diff -uNr 07_uart_chainloader/src/arch/aarch64/time.rs 08_timestamps/src/arch/aarch64/time.rs --- 07_uart_chainloader/src/arch/aarch64/time.rs +++ 08_timestamps/src/arch/aarch64/time.rs -@@ -0,0 +1,77 @@ +@@ -0,0 +1,85 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter @@ -113,8 +113,16 @@ diff -uNr 07_uart_chainloader/src/arch/aarch64/time.rs 08_timestamps/src/arch/aa + +const NS_PER_S: u64 = 1_000_000_000; + ++//-------------------------------------------------------------------------------------------------- ++// Arch-public ++//-------------------------------------------------------------------------------------------------- ++ +pub struct Timer; + ++//-------------------------------------------------------------------------------------------------- ++// OS interface implementations ++//-------------------------------------------------------------------------------------------------- ++ +impl interface::time::Timer for Timer { + fn resolution(&self) -> Duration { + Duration::from_nanos(NS_PER_S / (CNTFRQ_EL0.get() as u64)) diff --git a/08_timestamps/kernel b/08_timestamps/kernel index 080fe56a5c1b639dbe53b75b68087c25e5ae95d9..c83e3f47b362d76b0f08d878bcdbcca0bc323d87 100755 GIT binary patch delta 412 zcmdn6pLN52)`l&ND^wXxx35%XG-qX$oc>UY(VkIZyP`JZbS}w@+zbqiOiTN*##|#G6|?Msp%Vm(u_&lPnt7MXJibWo@fc= zPTyW>3F0bl7qn&!XJX{to@vV{&nW501u})1fx{TpvcBmH?SPgXhe|U*r6GzK7^0_N z1WC{3g}6aOA0nXvb;JGbK>xT4ix?W3nHrfJo0yvznHZQ@m>Zj#n@oQg#3;NyFNkq9 zBX)V65Jo-hGV4Pa)u&GhVeAnyHZe6eGB&p~GdD3XG&iv{Hk8t zz$62M;P#8AjO!U0Bc?Z+Gm1-I(7zbH?e6j6u^AErHxA z+bb NullLock { } } +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::sync::Mutex for &NullLock { type Data = T; diff --git a/08_timestamps/src/arch/aarch64/time.rs b/08_timestamps/src/arch/aarch64/time.rs index a6c9d50c..bbddd5e0 100644 --- a/08_timestamps/src/arch/aarch64/time.rs +++ b/08_timestamps/src/arch/aarch64/time.rs @@ -10,8 +10,16 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + pub struct Timer; +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::time::Timer for Timer { fn resolution(&self) -> Duration { Duration::from_nanos(NS_PER_S / (CNTFRQ_EL0.get() as u64)) diff --git a/09_hw_debug_JTAG/kernel b/09_hw_debug_JTAG/kernel index 952a835ef34a181a7aae3a31cf64340f3d8cec74..c83e3f47b362d76b0f08d878bcdbcca0bc323d87 100755 GIT binary patch delta 541 zcmZvXKP*F06vprOXppqwRjDTtDnk89lvjOiingJ;k%$rzX&59HA(0qNO~hJZI1)rm zT?i6#nWQm@v5BPy(yay?TL<^KZ|oWF$vMCCo%7v?C)>@F?ZAthbnksHcpo$>_921} z?&(Lyj#j!g;KnMw8rZ=*#e$+*r^O&rxa5yPEGY1h8ire&ZeUDNz&0JV%nVWfM~Px# zWbw?u!e|Fhc-;5=VU!%a^eM%0+~e4Jt&C z(XJci=}}d3m$jtK(@~_V@Jq!BaVsMFro&^G9NUJR8|UgIW`G2(#KpflDHj*J_jw_X z8X!%@DN%lqnh>e%)BC(jN1IOU+ zWb`MI%hWUxVk5B_3~!W@*ocMudf(^__vD=4`Of+7dBJsEaBcf=z2U#|g9o6J6+jHl zyuAmxTC~uGfhH`_gMl@?Qo(dO(%j>n!=@8*yYS@J-f;xHT;Lw!=NI99xB)OK^1*6TmplC&j!ha<{1^PB(M< NullLock { } } +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::sync::Mutex for &NullLock { type Data = T; diff --git a/09_hw_debug_JTAG/src/arch/aarch64/time.rs b/09_hw_debug_JTAG/src/arch/aarch64/time.rs index a6c9d50c..bbddd5e0 100644 --- a/09_hw_debug_JTAG/src/arch/aarch64/time.rs +++ b/09_hw_debug_JTAG/src/arch/aarch64/time.rs @@ -10,8 +10,16 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + pub struct Timer; +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::time::Timer for Timer { fn resolution(&self) -> Duration { Duration::from_nanos(NS_PER_S / (CNTFRQ_EL0.get() as u64)) diff --git a/10_privilege_level/README.md b/10_privilege_level/README.md index 2339514a..e254ab0b 100644 --- a/10_privilege_level/README.md +++ b/10_privilege_level/README.md @@ -213,7 +213,7 @@ make chainbot diff -uNr 09_hw_debug_JTAG/src/arch/aarch64/exception.rs 10_privilege_level/src/arch/aarch64/exception.rs --- 09_hw_debug_JTAG/src/arch/aarch64/exception.rs +++ 10_privilege_level/src/arch/aarch64/exception.rs -@@ -0,0 +1,44 @@ +@@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter @@ -222,6 +222,10 @@ diff -uNr 09_hw_debug_JTAG/src/arch/aarch64/exception.rs 10_privilege_level/src/ + +use cortex_a::regs::*; + ++//-------------------------------------------------------------------------------------------------- ++// Arch-public ++//-------------------------------------------------------------------------------------------------- ++ +pub trait DaifField { + fn daif_field() -> register::Field; +} @@ -339,7 +343,7 @@ diff -uNr 09_hw_debug_JTAG/src/arch/aarch64.rs 10_privilege_level/src/arch/aarch +pub mod state { + use cortex_a::regs::*; + -+ /// The current privilege level. ++ /// The processing element's current privilege level. + pub fn current_privilege_level() -> &'static str { + let el = CurrentEL.read_as_enum(CurrentEL::EL); + match el { diff --git a/10_privilege_level/kernel b/10_privilege_level/kernel index e369ead6ad9c5763cdcc19f6a98acc885e52b3cf..9d4d1590ee5e7fefc6d3becec25e05a213a7ae2b 100755 GIT binary patch delta 590 zcmZvXODIH97{||l9v-D(40GL@@>(z@x|%x=(a4M#W@5%HEHDY7Y%GwC$I{B9^d(YL zQWkdVqzGkcW1|T**;v~u%DHo{h4L-VIbXm3|NH(Y_iE3*+BYt6t3#zb9bwdQ_|aB| z7t(s5sGbVOV6m`pdkHhjS~wXS=aW5{h5F=>{M{$HXbYv#TLcP5=`(^AT+?DybgO(T zidw+U&w7!Ex^J34bZM?J&Br|3hjrk9>SH29+{u{50`}#SG7+gz@05(;2B+LPU`$=( z+Msb0CF8P(af)zjy`%LBEd{r_lN@ j(5KPFpQmt+|1dwC!FLfQx=_rI7I1{pWyK6b$rdO-mmp~l delta 588 zcmZvXPbkA-7{}l5{)p1D8QZT!LQ%qR+iylRF=@7CV=hu_Epc$*gi`G2B#B4tz)6lu zy*X{lQAs(hOyZ#2l#`;ozr8;PAlw{&bXVh% z)M2=k#u~<8GO?hilIdkGzl^1LdKmLiiZ;n#eUgi@Tnaspz=aw59Ki|-v>X!CI^PPR z2~haiD4w9~8|HUSn%#!^n4gSc1304Qu*fiBXUt>*`>K^P5vg2nln5h_Gj1Q(w`RE- z(fc7KqQd2(^b diff --git a/10_privilege_level/src/arch/aarch64.rs b/10_privilege_level/src/arch/aarch64.rs index d20dfe4d..7427441a 100644 --- a/10_privilege_level/src/arch/aarch64.rs +++ b/10_privilege_level/src/arch/aarch64.rs @@ -108,7 +108,7 @@ pub fn wait_forever() -> ! { pub mod state { use cortex_a::regs::*; - /// The current privilege level. + /// The processing element's current privilege level. pub fn current_privilege_level() -> &'static str { let el = CurrentEL.read_as_enum(CurrentEL::EL); match el { diff --git a/10_privilege_level/src/arch/aarch64/exception.rs b/10_privilege_level/src/arch/aarch64/exception.rs index 27939b84..f8d33f94 100644 --- a/10_privilege_level/src/arch/aarch64/exception.rs +++ b/10_privilege_level/src/arch/aarch64/exception.rs @@ -6,6 +6,10 @@ use cortex_a::regs::*; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + pub trait DaifField { fn daif_field() -> register::Field; } diff --git a/10_privilege_level/src/arch/aarch64/sync.rs b/10_privilege_level/src/arch/aarch64/sync.rs index dfebc0e1..2f6900b0 100644 --- a/10_privilege_level/src/arch/aarch64/sync.rs +++ b/10_privilege_level/src/arch/aarch64/sync.rs @@ -7,6 +7,10 @@ use crate::interface; use core::cell::UnsafeCell; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + /// A pseudo-lock for teaching purposes. /// /// Used to introduce [interior mutability]. @@ -33,6 +37,10 @@ impl NullLock { } } +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::sync::Mutex for &NullLock { type Data = T; diff --git a/10_privilege_level/src/arch/aarch64/time.rs b/10_privilege_level/src/arch/aarch64/time.rs index a6c9d50c..bbddd5e0 100644 --- a/10_privilege_level/src/arch/aarch64/time.rs +++ b/10_privilege_level/src/arch/aarch64/time.rs @@ -10,8 +10,16 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + pub struct Timer; +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::time::Timer for Timer { fn resolution(&self) -> Duration { Duration::from_nanos(NS_PER_S / (CNTFRQ_EL0.get() as u64)) diff --git a/11_virtual_memory/README.md b/11_virtual_memory/README.md index bcecf698..3d1d11bd 100644 --- a/11_virtual_memory/README.md +++ b/11_virtual_memory/README.md @@ -262,10 +262,23 @@ make chainbot ## Diff to previous ```diff +diff -uNr 10_privilege_level/Makefile 11_virtual_memory/Makefile +--- 10_privilege_level/Makefile ++++ 11_virtual_memory/Makefile +@@ -17,7 +17,7 @@ + OPENOCD_ARG = -f /openocd/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg -f /openocd/rpi3.cfg + JTAG_BOOT_IMAGE = jtag_boot_rpi3.img + LINKER_FILE = src/bsp/rpi/link.ld +- RUSTC_MISC_ARGS = -C target-cpu=cortex-a53 ++ RUSTC_MISC_ARGS = -C target-cpu=cortex-a53 -C llvm-args=-ffixed-x18 + else ifeq ($(BSP),rpi4) + TARGET = aarch64-unknown-none-softfloat + OUTPUT = kernel8.img + 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,309 @@ +@@ -0,0 +1,316 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter @@ -275,7 +288,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ +//! Static page tables, compiled on boot; Everything 64 KiB granule. + +use crate::{ -+ bsp, ++ bsp, interface, + memory::{AccessPermissions, AttributeFields, MemAttributes}, +}; +use core::convert; @@ -511,10 +524,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/ + let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); + + let (output_addr, attribute_fields) = -+ match bsp::virt_mem_layout().get_virt_addr_properties(virt_addr) { -+ Err(string) => return Err(string), -+ Ok((a, b)) => (a, b), -+ }; ++ bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; + + *l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); + } @@ -538,42 +548,52 @@ 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()`. -+/// -+/// # 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("64 KiB translation granule not supported"); -+ } ++//-------------------------------------------------------------------------------------------------- ++// Arch-public ++//-------------------------------------------------------------------------------------------------- + -+ // Prepare the memory attribute indirection register. -+ set_up_mair(); ++pub struct MMU; + -+ // Populate page tables. -+ if let Err(string) = populate_pt_entries() { -+ return Err(string); -+ } ++//-------------------------------------------------------------------------------------------------- ++// OS interface implementations ++//-------------------------------------------------------------------------------------------------- + -+ // Set the "Translation Table Base Register". -+ TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); ++impl interface::mm::MMU for MMU { ++ /// Compile the page tables from the `BSP`-supplied `virt_mem_layout()`. ++ /// ++ /// # Safety ++ /// ++ /// - User must ensure that the hardware supports the paremeters being set here. ++ unsafe fn init(&self) -> 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("64 KiB translation granule not supported"); ++ } + -+ configure_translation_control(); ++ // Prepare the memory attribute indirection register. ++ set_up_mair(); + -+ // Switch the MMU on. -+ // -+ // First, force all previous changes to be seen before the MMU is enabled. -+ barrier::isb(barrier::SY); ++ // Populate page tables. ++ populate_pt_entries()?; + -+ // Enable the MMU and turn on data and instruction caching. -+ SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable); ++ // Set the "Translation Table Base Register". ++ TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + -+ // Force MMU init to complete before next instruction -+ barrier::isb(barrier::SY); ++ configure_translation_control(); + -+ Ok(()) ++ // Switch the MMU on. ++ // ++ // First, force all previous changes to be seen before the MMU is enabled. ++ barrier::isb(barrier::SY); ++ ++ // Enable the MMU and turn on data and instruction caching. ++ SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable); ++ ++ // Force MMU init to complete before next instruction ++ barrier::isb(barrier::SY); ++ ++ Ok(()) ++ } +} diff -uNr 10_privilege_level/src/arch/aarch64.rs 11_virtual_memory/src/arch/aarch64.rs @@ -583,10 +603,27 @@ diff -uNr 10_privilege_level/src/arch/aarch64.rs 11_virtual_memory/src/arch/aarc //! AArch64. mod exception; -+pub mod mmu; ++mod mmu; pub mod sync; mod time; +@@ -77,6 +78,7 @@ + //-------------------------------------------------------------------------------------------------- + + static TIMER: time::Timer = time::Timer; ++static MMU: mmu::MMU = mmu::MMU; + + //-------------------------------------------------------------------------------------------------- + // Implementation of the kernel's architecture abstraction code +@@ -136,3 +138,8 @@ + println!(" FIQ: {}", to_mask_str(exception::is_masked::())); + } + } ++ ++/// Return a reference to an `interface::mm::MMU` implementation. ++pub fn mmu() -> &'static impl interface::mm::MMU { ++ &MMU ++} diff -uNr 10_privilege_level/src/bsp/rpi/link.ld 11_virtual_memory/src/bsp/rpi/link.ld --- 10_privilege_level/src/bsp/rpi/link.ld @@ -637,7 +674,7 @@ diff -uNr 10_privilege_level/src/bsp/rpi/memory_map.rs 11_virtual_memory/src/bsp diff -uNr 10_privilege_level/src/bsp/rpi/virt_mem_layout.rs 11_virtual_memory/src/bsp/rpi/virt_mem_layout.rs --- 10_privilege_level/src/bsp/rpi/virt_mem_layout.rs +++ 11_virtual_memory/src/bsp/rpi/virt_mem_layout.rs -@@ -0,0 +1,78 @@ +@@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +// +// Copyright (c) 2018-2019 Andre Richter @@ -651,6 +688,10 @@ diff -uNr 10_privilege_level/src/bsp/rpi/virt_mem_layout.rs 11_virtual_memory/sr +use crate::memory::*; +use core::ops::RangeInclusive; + ++//-------------------------------------------------------------------------------------------------- ++// BSP-public ++//-------------------------------------------------------------------------------------------------- ++ +pub const NUM_MEM_RANGES: usize = 3; + +pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( @@ -760,6 +801,22 @@ diff -uNr 10_privilege_level/src/bsp.rs 11_virtual_memory/src/bsp.rs #[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))] mod rpi; +diff -uNr 10_privilege_level/src/interface.rs 11_virtual_memory/src/interface.rs +--- 10_privilege_level/src/interface.rs ++++ 11_virtual_memory/src/interface.rs +@@ -127,3 +127,11 @@ + fn spin_for(&self, duration: Duration); + } + } ++ ++/// Memory Management interfaces. ++pub mod mm { ++ pub trait MMU { ++ /// Called by the kernel early during init. ++ unsafe fn init(&self) -> Result<(), &'static str>; ++ } ++} + diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs --- 10_privilege_level/src/main.rs +++ 11_virtual_memory/src/main.rs @@ -780,7 +837,7 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs mod panic_wait; mod print; -@@ -46,8 +49,16 @@ +@@ -46,8 +49,18 @@ /// # Safety /// /// - Only a single core must be active and running this function. @@ -791,14 +848,16 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs +/// drivers (which currently employ NullLocks instead of spinlocks), will fail to work on +/// the RPi SoCs. unsafe fn kernel_init() -> ! { -+ if let Err(string) = arch::mmu::init() { ++ use interface::mm::MMU; ++ ++ if let Err(string) = arch::mmu().init() { + panic!("MMU: {}", string); + } + for i in bsp::device_drivers().iter() { if let Err(()) = i.init() { panic!("Error loading driver: {}", i.compatible()) -@@ -67,6 +78,9 @@ +@@ -67,6 +80,9 @@ println!("Booting on: {}", bsp::board_name()); @@ -808,7 +867,7 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs println!( "Current privilege level: {}", arch::state::current_privilege_level() -@@ -87,6 +101,13 @@ +@@ -87,6 +103,13 @@ println!("Timer test, spinning for 1 second"); arch::timer().spin_for(Duration::from_secs(1)); diff --git a/11_virtual_memory/kernel b/11_virtual_memory/kernel index 5d8908842af458418eb45cb5e574e26a897e9dc4..46086de7c10e382da2a4d04056117a2b3ec005ea 100755 GIT binary patch delta 9416 zcmbVR4|r77m4D|>LS_;|GK7!}A(hAzSIzQr(YLBKHf zT&Od~jDxA>$J^b}qzT5}p+w__U4+k}PazoQ;T*ScL%HTieqz*3ZFd_^04Q;a1rO$#S~Ol@h}g{l8&q&I z9s{@rPT(1Ux}}Y2=Cj{PdBXi!$BB^*3DIA5c+3r--E|`VsPW>u7cz6~0sQ7Umom?m zDf9Oaf_cvj!`yy2V2-RcUfe~7#fv=A_yWTW9>fj>+Y$nB#(4=);>` z&=q_=!z6`M3d#9)>R9-4hMBxlqU`B}^a=Fa+7br8{m1M^tcrE@c5msmR z7k`PGmnv^*96LkKx5E5i#mU*}hA}YmJeUU-q?tJs?V+TkXj~gd!5Fz!MMsW-xjjFG z{v?=|dN^#x?@5Rrw+&vD1P{U{d?N{R$gcmSR%WE?O5@(|hQHJjZty2YYP3Vi9=H{T z@h%VewM!m2F{{CE23_4N8vFd_4avsdfDt&U6D*%TI>Fi!yH~7j#ru;X>vPdOvz|pM zIY(XeG5T_B(Qf=nGHl2kt~FC=2J|$0=;QuFtywsRwJA`Nm{@1-9>dKkP>|=PpPo8% zexk8;*E0<@kH91QmynM?^wpVf&8oxaQ=mB4oNvYpJUYw+XA0cWGx-UoJCbIS)+2?3 z_~#TT^S0HQpX4V+b>iy53fr)8B5cc~6wIVv8-B8Dh1>J`{*eV>zR-bhO@uONM3o9n z-VYM>;uzD(wmLsa2WWLFJW7!{lL}AK?e8YRw$Huxn|{xi2B{?# zR4^5PmIgHw^x`7be@=t>a0ut6L%t`FVn=HT*QdkX5XaN$&I8}SGe=-~+ zE54CI8L|VvodN&ME!Cfc+cUt2ty5s1V32ELb2B0QMQUojl>GkL2~iz{ctJ{`U0-IHBUC@)&r)tY>yCcnGWPa;da3*h{+!N& zf?3xE%rjKfl85TvEu_!lPcKzyQAHo)@+!e=vf=NQQG_pLLmrIb>1>Me2l&Tqcv~Gx z$FylMC--o==}BuCi@T;jL#chf;ZK)V{^ru9EZZiWG>tN4ZLD@0xIpJa4mA(s`W(nn zZC;$81DSY$zF;l>IEPkiYi!bV_!_{$*qU5OQqYR){qP%j2p0utb$>VZqX2vzU&#MhIiUuOzB;q`3vG(>fU%|0Y&2?O{vucmupHOVg(o1QZ`Z`; zUJKqtXp7A&rJ+=y9@mz^W}O_rbLkx}L9hHHROsI?qvaimO)ZBv6d2gs2vwL~1=$q0 z!YZnI4cJ1rNP88{23-^n>uRL$RQfDk`WLkUy6<5=k$&sTDSsVCwVFN_qY`Lc$GA=L zv94FS%}qnvv_`D!otUQ@N+5i-dS>Ig8aQ{=!#CI3UektS508)6LdjK+eiX-QVg6N* zo?T~;K7&VZ#QW-?;HpRO!9nV_{AxpXkw>>}AQS5CUzB*(^-ip%9=2WmR6LF6uY+Zf zj*)r)4`*8O@p(|v_2xX=m-Sr#H{9eTRxqEme`K#Aq|3GsRyA6{G~12 zUDSVNw}rU68S=tc-4ENYr)t@PTbrQ7`&g50bT%99!`>^w0X*LXO_9vz@gd3Pw%F|B zwuHpz2#GItUo%ue_-gg^;BX6kTG&0^9^U>o47qpb+P@xRz8Pt2d@q=PgAH3{pG>;Q zZL#hm!V>r!2;i%Bu?N3d-vybZ5m_(nkAsvB+T`)tx!NlzuS z>GvuezLBE47pZV$(U#;}2J?NPWwvmDg>T~a%)c%{pV9Bu8@lXO8EZdc>&A6OmgE**Z*^Pvj9Q!pw zBGIQD$|cEGVOZ0v9J`Dp*+y*Bv}{VET#{@Hnwsu#^p+&+#C}a5chCct8f6^C^F-rO zih$=dWAiXLfx5inF!w{I`*FFZf9{~qS~M5~xP$1fjT6Tw%>~--bm#>?#hd5U3>zOv zw&f3Swe-?XMhR|6RAggY$#^F_bdxo#VIbq|C}t(8i0^pgcq3$ST*R$OlwjGsJF*Jn zUF;vsF0;uL$*Ddrgu03zY z7Pp!o%%VVO$J!l(w+fD?TNNyq>g5#Ek7jzD9!Gb{wOU6#h_L)o43h0(IVV^seJy2L z4hn)x@{L+9`{>*tjCKFm`Uay1caT<}92rDr$eKhj;@GR{pE`Pflj)Nx^TfE}~Uc`7W;}XdL#ZFB&EeL zaWlbXM@Notf=@!2NZKB!C}<<+dhHoo#a_LGVWO88kuy3-JK1DPI_uiVxVSQ#@gFkY z$MS-2;2>SZ$0t&~J&414@PmuSr-_u$QS_z~-N45w)_u8r?!kzrM;)pAl$9om;=NVV z=NwTUu+%8yBRr&OIT4C-sb&{(P}6e$6#7H%-GVTQlI$iviwP}r^bm(p@MpP<2|k6x zAD(Q-HO@vRaff>t7vpL2tm_5FKeFW!C#gbuKY$}Sx*ax2bkiKTY}1+O zO;=fMJ(=T;c|OffUcoQ&CUKUtP^^;+v zl&rXaap3v|m)0z}90X3&4~>f+$)pk7k)izF;|?`|!x$_P3h zhH4nk$M6)D*+rX-L*RN#0E`bEdT(I7Ga&Zaf%z8AfVEk%9$^>LOKy#e0lWZ=M;N!B z(q?jS_3f8T$m85`=9XIyJ(j5gzT0MqcAM*9n+7nLsj?ys4ti3K9azC7;J4CWH`+Ak zgJP#O68x=wd(yte?Ax36?LGT;!M?dMIF)jJx>Y0Tl`=m{vf)NPa>$1n z-{Qcl8F$({&&DaTI7oK*0!zk+XEFDq2dpfWxj-3590E660(8)uHNN9r9M=O5{5Fha zDL?GQwk$er^zsO64`v=Cw z68jKq7~i91VO2iXPmh?^l|qgr80Rlh17Gr~)Sz7%l#%WTvF({MLI~4nPn6dmti}ji z0iovwM>h#{kHas?&f^YTCSVG-(J+O39khO)*5MGGHVo_9h`khG=(cWFsDSDC-Nd-)Zp^iDk>Aaw@RzpMv(~LEjdq90 zWVV!hDOMjdF11f)>t^~tP0J7D+v5oS;+Nog^yXB{OZ`4>ZS#h4zm0bpya0?IKH2>f zcaY++ii2^AahWdJP!lO%^Z--X{Q%2XGA@}dJN7Qd?G21FTjKTY3|o=xKzmuyZyA@B zRnPcLI>GCKS919mJ>O$oG~dSZ_tGqEx-#rQ$SjpJy0%`jW{ul8J?jRMaoM$eP z5>YFX^1XxyK2Hl@<5IHfd1(a5d5z0L6Z!vO+zxo`<~%iBC54TdoyFl&JQq-NVuu6j zBqVAegnRsIW^Dfqm7g4<|KP$^?V;*$RoNXCl~s4#5n8imP22Uw8#ms&sko{#Tp2De zuc|7qE-$UDC@l+z@!#jF>WnK9Gp|+Ozox4C_L)mo&fIWk$L2dX78kd5tZk=neXA@l zF5a~1TgAmRB6d|MfBvRTR%2$<%9-WsHn008*>Oi{ML1NprXmz7Z@aT{O=;|vYt?$l zC<|4G%4%xLLp7mLMNL__w6q56OH^^!6$qnk^WB?^%gW2jt3wr4m3Q7%T3%CKQBmHu zw)D=@%F?pRJE}^P_JG~ZOyY&L2oJr_-?%_q8E&CotmHg RT%KK(mgVB^dYWg$_#ZVDf;<2K delta 9286 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 diff --git a/11_virtual_memory/kernel8.img b/11_virtual_memory/kernel8.img index 450ae8c10de26f4fc2ae3f8a2fd5c9edfa9ec206..646cdc21cc6d33d99f0244722f4d8e32dabd5025 100755 GIT binary patch delta 3445 zcmb7HeN0=|6@Ta1#x`HJAqE=kt-tgLH0B6YY(Z4$O7kUz2v zwa}*8MjEZTJG7%D(xCj&zC`QDo}zxODjk!yrcweW>!$RNK_YE7YavmSCZ3eC^ZedR zx+qoTE8X|*@7#0G$M2qdpFKLHA05&kYlTJDR?z6?xMSBsT!I_VVqXoIL}MB^vS8rO z43m5vbw6;dEt2%Dmq1{HT}dB%&FtQqrhn%1Mx%X@Ng21;Qbmmt(0v9MFmW*j%&>YtDI>c!9c z&8+v%?n%2IKg1gHW&tOr*I5osL~<>rii+r<0TKa3=nDC2IZ|13rsuI0GdxCHD(qlLMM-UXvkjLBgU1MywF z7@q+);N6IVu^?-*lEn__#lI?%ZZjT+pWs=eiz51$@vuEyb1#?AnVy#CO@bj@D`$~z z-UW;Jlv$ATFwd7X2+X4!>WoYaYvzr&J694yDWklQ)w7t-EYmu>IF-P_hjLRmfAG=(2&h- zb>9E%C&y{muk?ZsLwRjBC}T(IbjK%w9r+;LMZvzB*TH+-`0u<@=)>%M!A2gIX>-yk z%P*^Vv270P@;ll+9wuKAp78)%Ape)hz!#^|L^vsWAbyZXrItE>4+G?-lwfF3DWpaXf&T>+THy)G9Y zwPC%>jwf7p=)pg@c0sq4z4rS6^>b+>Ze)U|R7mNJvi> zZ@TVC6TwSf zqRFREo+4BDK_bE+wvwj2I_9H$Mn~Gyc(%lQ$5GI?V)jv#7VX z{~+k5_c3+eKx4Vxt-l3DvNEk|(XEwiGb$!JlI_nbRw1Whs`_O6R5CwQ0hOtmDZ@Rr zD=9l~2`VYmcR_KEuLUbo_Wcefg7qo;c7zn)#j5WJ9t!zV_C1PoA>YHPvUOAStwcZp zY*t28Wy$ub)Vld#>YMN;Uft3GRt(pro=7*oR#!3jNu3f%ni|NQinVIGa2Ni&inZ#x z-~4^_rRI7MAO3Mz2|{zaPsN&({VG;ty|JKaO1 z4NZ33-{kOLQ~hY(wD&($c}#s@!P8Co=G}ra|5Kc6+84gwq#%u~n=00_O{iESt9GlR zZ&d}Y((_v_;JL3Egl1t=tGZY-e&1D1*ws>0nesA>ZWW*v`H! delta 3408 zcmb7He@q+K9lv+B!N)J#fHB6v`S6HiXyOtYi0zEu1p)yNw^P!jY9VOt8l*N!wIykm z;Ve=MG-~qpZMBR>D{cO0j;S5lHH}DBt!_7EU8jbOF48n|Q>mYQ?Cbp66d%kz1 zi84ig(!0CQ_xG>&3@4+;lTqV|EhI)eij4mVam#d%lSp*L#m92#o2}B>I$FU+BQxn~ zGU2#uHwO)}G*&_r9+PZFY?dI0`0tdGdP}J)8TWF!)MI3TpS8g!WDQZ^OA_iTv(TR& z&V1FpvTr&uV3e;!1Uj(t#B}^PH~G{#yGt`J(nSML7pi&s#Zf|^E#v5+em70@bCbgu zRJ>A<KziF;q{rV?g$978#S)Dhfhtj@U2E>$8&kh6r(Mpfzp285h(;~eRQmrNpw!P_PW zKYJfsH0`h-S$}uo2n?k?GJi5a+4Y7a}CQdlhI{=JxDXL zMd}O)xXo_`sc#aRGX17s1?jO#_->}R^fG>Z9HjLoZtw7TL*Pa7;^I_^Mj+ljyM-$D2o{PYhtZGsQ8QE>N(B==G-rSL zY9T}_3b%@Mdl8|=Qb{Q6vUpKz#1i6Xv*4m7kj7e=X00cE&}#JvGZ|Xx#$ccI8FB`$ zTARparQDWJ*8RXw&+(;nt!-#j&V6~*iKzuV7FvLB^+Xk6R}!a9a@<4c4h5db^=A`1 zRmb>HbAcN88@V5$^BegtzOe|x`A#^M_lia!N1!|ZXN(yuPBI^`SA8|Lk#sG!)gG_T z2aMPUi3Ax1Vo{Gk7tg232?Mt*tZbR~9scB1?CrII*cxaq=&;4S^cWud#A!lD-p_Dh zNIxkE^Rpr>7OWvXP~Z@4*s=v|K?dgXw`yMQI18fNC#I9%xKfJ$ z@+%@_78VJsy@2(F@bwQW=wEQO)NWtLeU9ho(9CO*@$c{Xq4|x%-`6ZPE@Kg|{l_4V z{}=ZP?haGK&pWxXNZ>TwD7=I{`P5lS`r+SB7cbf1lCy$%l%^sB;rpy`++~MHUG|cG zD-|pa%W*^gI8G=Uz4>r1n`pc;UvgCv4_t8VByOdk_#r}imE9%jJaNN5@sFehy4_Eb zZslF~HbTZAr)(!#Qg)Yhs^DFZ7r~!ANl;Pl^(|$qM`a=l=N0egsd>B(2V&XuSjMOg7Sal-Pojs&?FqH=qHfqwu?O&n-ty-bG<< zBR%x@jr7z}CAjt@zQP@%8~D}sPjS%@UH=u#qc!gS8rt;1CdFIXL5K}<)~$h)_kD*D zC1+i&iAYN81`pw9LNHMMwA$mp8aO;wM)e?0;H5lYU5%op5B!FQYc=g;I|OP)az8v$ zD>iPg#UqUi6Hl%Nd}ibB>iTBTjqfPqoA6s*cglxg60J-yDZHJMOJNubkzDUE%pj-Z z97gz1ac=UHs#MJs!ok2|%FZ_hwUk}DbC84nlzpE8Ayl8TZ*xfVjaPhfZGhpBH)Y>L zFdOprq*|>w^Q}dI2a{o(ujKkrd1Ukc)SGY;NL`q4&{LOsBHsYH&Oi8Gofc9W3na#{ zK25*817BoVpRRlH?;)>jtC#r3M;o;ubf=FqtUKvtn8nEHSg+nLWwNoJI5%7L@@j&* z`gX82JBS&4&7yN{vnHcYe+|O~VokNq-&+5lg|p3Vd1sicgT-;eYK9}>65B5rJ)hCv zfk2CxH_fQ}={|tcwiY`?TMB(&Fh9CC{XNC#GwdCQSc^mG6*c}Im~DAR`n*L$da>dR z>)9rtuT3NYg+6E@gZC6>%6erJ3|ko?@Sx^QH=d$BxYTOfkh%@n-CjxpaHP#|d%jHz zppXS*gVCyR~5tRPldY1 zU~ktYavmDHf8=cM)?^QAEbd|a7hx@ax5HAmNRELm>>!)K7p}Lt! ! { //-------------------------------------------------------------------------------------------------- static TIMER: time::Timer = time::Timer; +static MMU: mmu::MMU = mmu::MMU; //-------------------------------------------------------------------------------------------------- // Implementation of the kernel's architecture abstraction code @@ -109,7 +110,7 @@ pub fn wait_forever() -> ! { pub mod state { use cortex_a::regs::*; - /// The current privilege level. + /// The processing element's current privilege level. pub fn current_privilege_level() -> &'static str { let el = CurrentEL.read_as_enum(CurrentEL::EL); match el { @@ -137,3 +138,8 @@ pub mod state { println!(" FIQ: {}", to_mask_str(exception::is_masked::())); } } + +/// Return a reference to an `interface::mm::MMU` implementation. +pub fn mmu() -> &'static impl interface::mm::MMU { + &MMU +} diff --git a/11_virtual_memory/src/arch/aarch64/exception.rs b/11_virtual_memory/src/arch/aarch64/exception.rs index 27939b84..f8d33f94 100644 --- a/11_virtual_memory/src/arch/aarch64/exception.rs +++ b/11_virtual_memory/src/arch/aarch64/exception.rs @@ -6,6 +6,10 @@ use cortex_a::regs::*; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + pub trait DaifField { fn daif_field() -> register::Field; } diff --git a/11_virtual_memory/src/arch/aarch64/mmu.rs b/11_virtual_memory/src/arch/aarch64/mmu.rs index bdceefd3..a81e68de 100644 --- a/11_virtual_memory/src/arch/aarch64/mmu.rs +++ b/11_virtual_memory/src/arch/aarch64/mmu.rs @@ -7,7 +7,7 @@ //! Static page tables, compiled on boot; Everything 64 KiB granule. use crate::{ - bsp, + bsp, interface, memory::{AccessPermissions, AttributeFields, MemAttributes}, }; use core::convert; @@ -243,10 +243,7 @@ unsafe fn populate_pt_entries() -> Result<(), &'static str> { let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); let (output_addr, attribute_fields) = - match bsp::virt_mem_layout().get_virt_addr_properties(virt_addr) { - Err(string) => return Err(string), - Ok((a, b)) => (a, b), - }; + bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; *l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); } @@ -270,40 +267,50 @@ fn configure_translation_control() { ); } -/// 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("64 KiB translation granule not supported"); - } +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + +pub struct MMU; + +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + +impl interface::mm::MMU for MMU { + /// Compile the page tables from the `BSP`-supplied `virt_mem_layout()`. + /// + /// # Safety + /// + /// - User must ensure that the hardware supports the paremeters being set here. + unsafe fn init(&self) -> 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("64 KiB translation granule not supported"); + } - // Prepare the memory attribute indirection register. - set_up_mair(); + // Prepare the memory attribute indirection register. + set_up_mair(); - // Populate page tables. - if let Err(string) = populate_pt_entries() { - return Err(string); - } + // Populate page tables. + populate_pt_entries()?; - // Set the "Translation Table Base Register". - TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + // Set the "Translation Table Base Register". + TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); - configure_translation_control(); + configure_translation_control(); - // Switch the MMU on. - // - // First, force all previous changes to be seen before the MMU is enabled. - barrier::isb(barrier::SY); + // Switch the MMU on. + // + // First, force all previous changes to be seen before the MMU is enabled. + barrier::isb(barrier::SY); - // Enable the MMU and turn on data and instruction caching. - SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable); + // Enable the MMU and turn on data and instruction caching. + SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable); - // Force MMU init to complete before next instruction - barrier::isb(barrier::SY); + // Force MMU init to complete before next instruction + barrier::isb(barrier::SY); - Ok(()) + Ok(()) + } } diff --git a/11_virtual_memory/src/arch/aarch64/sync.rs b/11_virtual_memory/src/arch/aarch64/sync.rs index dfebc0e1..2f6900b0 100644 --- a/11_virtual_memory/src/arch/aarch64/sync.rs +++ b/11_virtual_memory/src/arch/aarch64/sync.rs @@ -7,6 +7,10 @@ use crate::interface; use core::cell::UnsafeCell; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + /// A pseudo-lock for teaching purposes. /// /// Used to introduce [interior mutability]. @@ -33,6 +37,10 @@ impl NullLock { } } +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::sync::Mutex for &NullLock { type Data = T; diff --git a/11_virtual_memory/src/arch/aarch64/time.rs b/11_virtual_memory/src/arch/aarch64/time.rs index a6c9d50c..bbddd5e0 100644 --- a/11_virtual_memory/src/arch/aarch64/time.rs +++ b/11_virtual_memory/src/arch/aarch64/time.rs @@ -10,8 +10,16 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; +//-------------------------------------------------------------------------------------------------- +// Arch-public +//-------------------------------------------------------------------------------------------------- + pub struct Timer; +//-------------------------------------------------------------------------------------------------- +// OS interface implementations +//-------------------------------------------------------------------------------------------------- + impl interface::time::Timer for Timer { fn resolution(&self) -> Duration { Duration::from_nanos(NS_PER_S / (CNTFRQ_EL0.get() as u64)) diff --git a/11_virtual_memory/src/bsp/rpi/virt_mem_layout.rs b/11_virtual_memory/src/bsp/rpi/virt_mem_layout.rs index 3b1b2014..0c05aa6d 100644 --- a/11_virtual_memory/src/bsp/rpi/virt_mem_layout.rs +++ b/11_virtual_memory/src/bsp/rpi/virt_mem_layout.rs @@ -11,6 +11,10 @@ use super::memory_map; use crate::memory::*; use core::ops::RangeInclusive; +//-------------------------------------------------------------------------------------------------- +// BSP-public +//-------------------------------------------------------------------------------------------------- + pub const NUM_MEM_RANGES: usize = 3; pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( diff --git a/11_virtual_memory/src/interface.rs b/11_virtual_memory/src/interface.rs index 55df89cb..24b3eb28 100644 --- a/11_virtual_memory/src/interface.rs +++ b/11_virtual_memory/src/interface.rs @@ -127,3 +127,11 @@ pub mod time { fn spin_for(&self, duration: Duration); } } + +/// Memory Management interfaces. +pub mod mm { + pub trait MMU { + /// Called by the kernel early during init. + unsafe fn init(&self) -> Result<(), &'static str>; + } +} diff --git a/11_virtual_memory/src/main.rs b/11_virtual_memory/src/main.rs index e0f6c3e4..c87cdeca 100644 --- a/11_virtual_memory/src/main.rs +++ b/11_virtual_memory/src/main.rs @@ -55,7 +55,9 @@ mod print; /// drivers (which currently employ NullLocks instead of spinlocks), will fail to work on /// the RPi SoCs. unsafe fn kernel_init() -> ! { - if let Err(string) = arch::mmu::init() { + use interface::mm::MMU; + + if let Err(string) = arch::mmu().init() { panic!("MMU: {}", string); }