Clean up mmu.rs

pull/37/head
Andre Richter 5 years ago
parent 1280d3804c
commit 2134146bb6
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -265,7 +265,7 @@ make chainbot
diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/aarch64/mmu.rs 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 --- 10_privilege_level/src/arch/aarch64/mmu.rs
+++ 11_virtual_memory/src/arch/aarch64/mmu.rs +++ 11_virtual_memory/src/arch/aarch64/mmu.rs
@@ -0,0 +1,316 @@ @@ -0,0 +1,300 @@
+// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: MIT
+// +//
+// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com> +// Copyright (c) 2018-2019 Andre Richter <andre.o.richter@gmail.com>
@ -347,18 +347,22 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ ] + ]
+} +}
+ +
+// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into +const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
+// a PageDescriptor slot in `struct PageTables`, and vice versa. +const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
+
+/// A table descriptor for 64 KiB aperture.
+///
+/// The output points to the next table.
+#[derive(Copy, Clone)] +#[derive(Copy, Clone)]
+#[repr(transparent)] +#[repr(transparent)]
+struct RawTableDescriptor(u64); +struct TableDescriptor(u64);
+ +
+/// A page descriptor with 64 KiB aperture.
+///
+/// The output points to physical memory.
+#[derive(Copy, Clone)] +#[derive(Copy, Clone)]
+#[repr(transparent)] +#[repr(transparent)]
+struct RawPageDescriptor(u64); +struct PageDescriptor(u64);
+
+const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
+const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
+ +
+/// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned, +/// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned,
+/// hence the "reverse" order of appearance. +/// hence the "reverse" order of appearance.
@ -366,9 +370,9 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+#[repr(align(65536))] +#[repr(align(65536))]
+struct PageTables<const N: usize> { +struct PageTables<const N: usize> {
+ // Page descriptors, covering 64 KiB windows per entry. + // Page descriptors, covering 64 KiB windows per entry.
+ lvl3: [[RawPageDescriptor; 8192]; N], + lvl3: [[PageDescriptor; 8192]; N],
+ // Table descriptors, covering 512 MiB windows. + // Table descriptors, covering 512 MiB windows.
+ lvl2: [RawTableDescriptor; N], + lvl2: [TableDescriptor; N],
+} +}
+ +
+/// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4. +/// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4.
@ -378,8 +382,8 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+/// +///
+/// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. +/// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries.
+static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables { +static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables {
+ lvl3: [[RawPageDescriptor(0); 8192]; ENTRIES_512_MIB], + lvl3: [[PageDescriptor(0); 8192]; ENTRIES_512_MIB],
+ lvl2: [RawTableDescriptor(0); ENTRIES_512_MIB], + lvl2: [TableDescriptor(0); ENTRIES_512_MIB],
+}; +};
+ +
+trait BaseAddr { +trait BaseAddr {
@ -397,24 +401,15 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ } + }
+} +}
+ +
+/// A descriptor pointing to the next page table. +impl convert::From<usize> for TableDescriptor {
+struct TableDescriptor(register::FieldValue<u64, STAGE1_TABLE_DESCRIPTOR::Register>); + fn from(next_lvl_table_addr: usize) -> Self {
+
+impl TableDescriptor {
+ fn new(next_lvl_table_addr: usize) -> TableDescriptor {
+ let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT; + let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT;
+ let val = (STAGE1_TABLE_DESCRIPTOR::VALID::True
+ + STAGE1_TABLE_DESCRIPTOR::TYPE::Table
+ + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64))
+ .value;
+ +
+ TableDescriptor( + TableDescriptor(val)
+ STAGE1_TABLE_DESCRIPTOR::VALID::True
+ + STAGE1_TABLE_DESCRIPTOR::TYPE::Table
+ + STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64),
+ )
+ }
+}
+
+impl convert::From<TableDescriptor> for RawTableDescriptor {
+ fn from(desc: TableDescriptor) -> Self {
+ RawTableDescriptor(desc.0.value)
+ } + }
+} +}
+ +
@ -452,28 +447,17 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ } + }
+} +}
+ +
+/// A page descriptor with 64 KiB aperture.
+///
+/// The output points to physical memory.
+struct PageDescriptor(register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>);
+
+impl PageDescriptor { +impl PageDescriptor {
+ fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor { + fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor {
+ let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT; + let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT;
+ + let val = (STAGE1_PAGE_DESCRIPTOR::VALID::True
+ PageDescriptor( + + STAGE1_PAGE_DESCRIPTOR::AF::True
+ STAGE1_PAGE_DESCRIPTOR::VALID::True + + attribute_fields.into()
+ + STAGE1_PAGE_DESCRIPTOR::AF::True + + STAGE1_PAGE_DESCRIPTOR::TYPE::Table
+ + attribute_fields.into() + + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64))
+ + STAGE1_PAGE_DESCRIPTOR::TYPE::Table + .value;
+ + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64), +
+ ) + PageDescriptor(val)
+ }
+}
+
+impl convert::From<PageDescriptor> for RawPageDescriptor {
+ fn from(desc: PageDescriptor) -> Self {
+ RawPageDescriptor(desc.0.value)
+ } + }
+} +}
+ +
@ -505,7 +489,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+/// - Modifies a `static mut`. Ensure it only happens from here. +/// - Modifies a `static mut`. Ensure it only happens from here.
+unsafe fn populate_pt_entries() -> Result<(), &'static str> { +unsafe fn populate_pt_entries() -> Result<(), &'static str> {
+ for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { + for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() {
+ *l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); + *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into();
+ +
+ for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { + for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() {
+ let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); + let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT);
@ -513,7 +497,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ let (output_addr, attribute_fields) = + let (output_addr, attribute_fields) =
+ bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; + bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?;
+ +
+ *l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); + *l3_entry = PageDescriptor::new(output_addr, attribute_fields);
+ } + }
+ } + }
+ +

Binary file not shown.

@ -79,18 +79,22 @@ register_bitfields! {u64,
] ]
} }
// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
// a PageDescriptor slot in `struct PageTables`, and vice versa. const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
/// A table descriptor for 64 KiB aperture.
///
/// The output points to the next table.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(transparent)] #[repr(transparent)]
struct RawTableDescriptor(u64); struct TableDescriptor(u64);
/// A page descriptor with 64 KiB aperture.
///
/// The output points to physical memory.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(transparent)] #[repr(transparent)]
struct RawPageDescriptor(u64); struct PageDescriptor(u64);
const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
/// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned, /// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned,
/// hence the "reverse" order of appearance. /// hence the "reverse" order of appearance.
@ -98,9 +102,9 @@ const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
#[repr(align(65536))] #[repr(align(65536))]
struct PageTables<const N: usize> { struct PageTables<const N: usize> {
// Page descriptors, covering 64 KiB windows per entry. // Page descriptors, covering 64 KiB windows per entry.
lvl3: [[RawPageDescriptor; 8192]; N], lvl3: [[PageDescriptor; 8192]; N],
// Table descriptors, covering 512 MiB windows. // Table descriptors, covering 512 MiB windows.
lvl2: [RawTableDescriptor; N], lvl2: [TableDescriptor; N],
} }
/// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4. /// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4.
@ -110,8 +114,8 @@ const ENTRIES_512_MIB: usize = bsp::addr_space_size() >> FIVETWELVE_MIB_SHIFT;
/// ///
/// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. /// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries.
static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables { static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables {
lvl3: [[RawPageDescriptor(0); 8192]; ENTRIES_512_MIB], lvl3: [[PageDescriptor(0); 8192]; ENTRIES_512_MIB],
lvl2: [RawTableDescriptor(0); ENTRIES_512_MIB], lvl2: [TableDescriptor(0); ENTRIES_512_MIB],
}; };
trait BaseAddr { trait BaseAddr {
@ -129,24 +133,15 @@ impl<T, const N: usize> BaseAddr for [T; N] {
} }
} }
/// A descriptor pointing to the next page table. impl convert::From<usize> for TableDescriptor {
struct TableDescriptor(register::FieldValue<u64, STAGE1_TABLE_DESCRIPTOR::Register>); fn from(next_lvl_table_addr: usize) -> Self {
impl TableDescriptor {
fn new(next_lvl_table_addr: usize) -> TableDescriptor {
let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT; let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT;
let val = (STAGE1_TABLE_DESCRIPTOR::VALID::True
+ STAGE1_TABLE_DESCRIPTOR::TYPE::Table
+ STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64))
.value;
TableDescriptor( TableDescriptor(val)
STAGE1_TABLE_DESCRIPTOR::VALID::True
+ STAGE1_TABLE_DESCRIPTOR::TYPE::Table
+ STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64),
)
}
}
impl convert::From<TableDescriptor> for RawTableDescriptor {
fn from(desc: TableDescriptor) -> Self {
RawTableDescriptor(desc.0.value)
} }
} }
@ -184,28 +179,17 @@ impl convert::From<AttributeFields>
} }
} }
/// A page descriptor with 64 KiB aperture.
///
/// The output points to physical memory.
struct PageDescriptor(register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>);
impl PageDescriptor { impl PageDescriptor {
fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor { fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor {
let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT; let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT;
let val = (STAGE1_PAGE_DESCRIPTOR::VALID::True
PageDescriptor( + STAGE1_PAGE_DESCRIPTOR::AF::True
STAGE1_PAGE_DESCRIPTOR::VALID::True + attribute_fields.into()
+ STAGE1_PAGE_DESCRIPTOR::AF::True + STAGE1_PAGE_DESCRIPTOR::TYPE::Table
+ attribute_fields.into() + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64))
+ STAGE1_PAGE_DESCRIPTOR::TYPE::Table .value;
+ STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64),
) PageDescriptor(val)
}
}
impl convert::From<PageDescriptor> for RawPageDescriptor {
fn from(desc: PageDescriptor) -> Self {
RawPageDescriptor(desc.0.value)
} }
} }
@ -237,7 +221,7 @@ fn set_up_mair() {
/// - Modifies a `static mut`. Ensure it only happens from here. /// - Modifies a `static mut`. Ensure it only happens from here.
unsafe fn populate_pt_entries() -> Result<(), &'static str> { unsafe fn populate_pt_entries() -> Result<(), &'static str> {
for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() {
*l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into();
for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() {
let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT);
@ -245,7 +229,7 @@ unsafe fn populate_pt_entries() -> Result<(), &'static str> {
let (output_addr, attribute_fields) = let (output_addr, attribute_fields) =
bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?;
*l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); *l3_entry = PageDescriptor::new(output_addr, attribute_fields);
} }
} }

@ -459,9 +459,9 @@ General purpose register:
## Diff to previous ## Diff to previous
```diff ```diff
diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_exceptions_part1/src/arch/aarch64/exception.rs diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_cpu_exceptions_part1/src/arch/aarch64/exception.rs
--- 11_virtual_memory/src/arch/aarch64/exception.rs --- 11_virtual_memory/src/arch/aarch64/exception.rs
+++ 12_exceptions_part1/src/arch/aarch64/exception.rs +++ 12_cpu_exceptions_part1/src/arch/aarch64/exception.rs
@@ -4,12 +4,248 @@ @@ -4,12 +4,248 @@
//! Exception handling. //! Exception handling.
@ -713,9 +713,9 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_exceptions_part1/sr
fn daif_field() -> register::Field<u32, DAIF::Register>; fn daif_field() -> register::Field<u32, DAIF::Register>;
} }
diff -uNr 11_virtual_memory/src/arch/aarch64/exception.S 12_exceptions_part1/src/arch/aarch64/exception.S diff -uNr 11_virtual_memory/src/arch/aarch64/exception.S 12_cpu_exceptions_part1/src/arch/aarch64/exception.S
--- 11_virtual_memory/src/arch/aarch64/exception.S --- 11_virtual_memory/src/arch/aarch64/exception.S
+++ 12_exceptions_part1/src/arch/aarch64/exception.S +++ 12_cpu_exceptions_part1/src/arch/aarch64/exception.S
@@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
+// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: MIT
+// +//
@ -853,9 +853,9 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.S 12_exceptions_part1/src
+ +
+ eret + eret
diff -uNr 11_virtual_memory/src/arch/aarch64.rs 12_exceptions_part1/src/arch/aarch64.rs diff -uNr 11_virtual_memory/src/arch/aarch64.rs 12_cpu_exceptions_part1/src/arch/aarch64.rs
--- 11_virtual_memory/src/arch/aarch64.rs --- 11_virtual_memory/src/arch/aarch64.rs
+++ 12_exceptions_part1/src/arch/aarch64.rs +++ 12_cpu_exceptions_part1/src/arch/aarch64.rs
@@ -106,6 +106,15 @@ @@ -106,6 +106,15 @@
} }
} }
@ -873,9 +873,9 @@ diff -uNr 11_virtual_memory/src/arch/aarch64.rs 12_exceptions_part1/src/arch/aar
pub fn mmu() -> &'static impl interface::mm::MMU { pub fn mmu() -> &'static impl interface::mm::MMU {
&MMU &MMU
diff -uNr 11_virtual_memory/src/bsp.rs 12_exceptions_part1/src/bsp.rs diff -uNr 11_virtual_memory/src/bsp.rs 12_cpu_exceptions_part1/src/bsp.rs
--- 11_virtual_memory/src/bsp.rs --- 11_virtual_memory/src/bsp.rs
+++ 12_exceptions_part1/src/bsp.rs +++ 12_cpu_exceptions_part1/src/bsp.rs
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
//! Conditional exporting of Board Support Packages. //! Conditional exporting of Board Support Packages.
@ -886,9 +886,9 @@ diff -uNr 11_virtual_memory/src/bsp.rs 12_exceptions_part1/src/bsp.rs
#[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))] #[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))]
mod rpi; mod rpi;
diff -uNr 11_virtual_memory/src/main.rs 12_exceptions_part1/src/main.rs diff -uNr 11_virtual_memory/src/main.rs 12_cpu_exceptions_part1/src/main.rs
--- 11_virtual_memory/src/main.rs --- 11_virtual_memory/src/main.rs
+++ 12_exceptions_part1/src/main.rs +++ 12_cpu_exceptions_part1/src/main.rs
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![feature(const_generics)] #![feature(const_generics)]

Binary file not shown.

@ -79,18 +79,22 @@ register_bitfields! {u64,
] ]
} }
// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
// a PageDescriptor slot in `struct PageTables`, and vice versa. const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
/// A table descriptor for 64 KiB aperture.
///
/// The output points to the next table.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(transparent)] #[repr(transparent)]
struct RawTableDescriptor(u64); struct TableDescriptor(u64);
/// A page descriptor with 64 KiB aperture.
///
/// The output points to physical memory.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(transparent)] #[repr(transparent)]
struct RawPageDescriptor(u64); struct PageDescriptor(u64);
const SIXTYFOUR_KIB_SHIFT: usize = 16; // log2(64 * 1024)
const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
/// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned, /// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned,
/// hence the "reverse" order of appearance. /// hence the "reverse" order of appearance.
@ -98,9 +102,9 @@ const FIVETWELVE_MIB_SHIFT: usize = 29; // log2(512 * 1024 * 1024)
#[repr(align(65536))] #[repr(align(65536))]
struct PageTables<const N: usize> { struct PageTables<const N: usize> {
// Page descriptors, covering 64 KiB windows per entry. // Page descriptors, covering 64 KiB windows per entry.
lvl3: [[RawPageDescriptor; 8192]; N], lvl3: [[PageDescriptor; 8192]; N],
// Table descriptors, covering 512 MiB windows. // Table descriptors, covering 512 MiB windows.
lvl2: [RawTableDescriptor; N], lvl2: [TableDescriptor; N],
} }
/// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4. /// Usually evaluates to 1 GiB for RPi3 and 4 GiB for RPi 4.
@ -110,8 +114,8 @@ const ENTRIES_512_MIB: usize = bsp::addr_space_size() >> FIVETWELVE_MIB_SHIFT;
/// ///
/// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. /// Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries.
static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables { static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables {
lvl3: [[RawPageDescriptor(0); 8192]; ENTRIES_512_MIB], lvl3: [[PageDescriptor(0); 8192]; ENTRIES_512_MIB],
lvl2: [RawTableDescriptor(0); ENTRIES_512_MIB], lvl2: [TableDescriptor(0); ENTRIES_512_MIB],
}; };
trait BaseAddr { trait BaseAddr {
@ -129,24 +133,15 @@ impl<T, const N: usize> BaseAddr for [T; N] {
} }
} }
/// A descriptor pointing to the next page table. impl convert::From<usize> for TableDescriptor {
struct TableDescriptor(register::FieldValue<u64, STAGE1_TABLE_DESCRIPTOR::Register>); fn from(next_lvl_table_addr: usize) -> Self {
impl TableDescriptor {
fn new(next_lvl_table_addr: usize) -> TableDescriptor {
let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT; let shifted = next_lvl_table_addr >> SIXTYFOUR_KIB_SHIFT;
let val = (STAGE1_TABLE_DESCRIPTOR::VALID::True
+ STAGE1_TABLE_DESCRIPTOR::TYPE::Table
+ STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64))
.value;
TableDescriptor( TableDescriptor(val)
STAGE1_TABLE_DESCRIPTOR::VALID::True
+ STAGE1_TABLE_DESCRIPTOR::TYPE::Table
+ STAGE1_TABLE_DESCRIPTOR::NEXT_LEVEL_TABLE_ADDR_64KiB.val(shifted as u64),
)
}
}
impl convert::From<TableDescriptor> for RawTableDescriptor {
fn from(desc: TableDescriptor) -> Self {
RawTableDescriptor(desc.0.value)
} }
} }
@ -184,28 +179,17 @@ impl convert::From<AttributeFields>
} }
} }
/// A page descriptor with 64 KiB aperture.
///
/// The output points to physical memory.
struct PageDescriptor(register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>);
impl PageDescriptor { impl PageDescriptor {
fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor { fn new(output_addr: usize, attribute_fields: AttributeFields) -> PageDescriptor {
let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT; let shifted = output_addr >> SIXTYFOUR_KIB_SHIFT;
let val = (STAGE1_PAGE_DESCRIPTOR::VALID::True
PageDescriptor( + STAGE1_PAGE_DESCRIPTOR::AF::True
STAGE1_PAGE_DESCRIPTOR::VALID::True + attribute_fields.into()
+ STAGE1_PAGE_DESCRIPTOR::AF::True + STAGE1_PAGE_DESCRIPTOR::TYPE::Table
+ attribute_fields.into() + STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64))
+ STAGE1_PAGE_DESCRIPTOR::TYPE::Table .value;
+ STAGE1_PAGE_DESCRIPTOR::OUTPUT_ADDR_64KiB.val(shifted as u64),
) PageDescriptor(val)
}
}
impl convert::From<PageDescriptor> for RawPageDescriptor {
fn from(desc: PageDescriptor) -> Self {
RawPageDescriptor(desc.0.value)
} }
} }
@ -237,7 +221,7 @@ fn set_up_mair() {
/// - Modifies a `static mut`. Ensure it only happens from here. /// - Modifies a `static mut`. Ensure it only happens from here.
unsafe fn populate_pt_entries() -> Result<(), &'static str> { unsafe fn populate_pt_entries() -> Result<(), &'static str> {
for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() {
*l2_entry = TableDescriptor::new(TABLES.lvl3[l2_nr].base_addr_usize()).into(); *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into();
for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() {
let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT);
@ -245,7 +229,7 @@ unsafe fn populate_pt_entries() -> Result<(), &'static str> {
let (output_addr, attribute_fields) = let (output_addr, attribute_fields) =
bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?; bsp::virt_mem_layout().get_virt_addr_properties(virt_addr)?;
*l3_entry = PageDescriptor::new(output_addr, attribute_fields).into(); *l3_entry = PageDescriptor::new(output_addr, attribute_fields);
} }
} }

Loading…
Cancel
Save