Minor fixes

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

@ -87,15 +87,19 @@ is hardcoded here (`64 KiB` page descriptors).
The actual page tables are stored in a global instance of the `PageTables` struct: The actual page tables are stored in a global instance of the `PageTables` struct:
```rust ```rust
// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into /// A table descriptor for 64 KiB aperture.
// a PageDescriptor slot in `struct PageTables`, and vice versa. ///
/// 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);
/// 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.
@ -103,9 +107,9 @@ struct RawPageDescriptor(u64);
#[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.
@ -115,8 +119,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],
}; };
``` ```
@ -135,11 +139,11 @@ memory and device memory (which is not cached).
fn set_up_mair() { fn set_up_mair() {
// Define the memory types being mapped. // Define the memory types being mapped.
MAIR_EL1.write( MAIR_EL1.write(
// Attribute 1 - Cacheable normal DRAM // Attribute 1 - Cacheable normal DRAM.
MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc
+ MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc + MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
// Attribute 0 - Device // Attribute 0 - Device.
+ MAIR_EL1::Attr0_HIGH::Device + MAIR_EL1::Attr0_HIGH::Device
+ MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE, + MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE,
); );
@ -303,7 +307,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+// A level 3 page descriptor, as per AArch64 Reference Manual Figure D4-17. +// A level 3 page descriptor, as per AArch64 Reference Manual Figure D4-17.
+register_bitfields! {u64, +register_bitfields! {u64,
+ STAGE1_PAGE_DESCRIPTOR [ + STAGE1_PAGE_DESCRIPTOR [
+ /// Privileged execute-never + /// Privileged execute-never.
+ PXN OFFSET(53) NUMBITS(1) [ + PXN OFFSET(53) NUMBITS(1) [
+ False = 0, + False = 0,
+ True = 1 + True = 1
@ -312,19 +316,19 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ /// Physical address of the next page table (lvl2) or the page descriptor (lvl3). + /// Physical address of the next page table (lvl2) or the page descriptor (lvl3).
+ OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16] + OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16]
+ +
+ /// Access flag + /// Access flag.
+ AF OFFSET(10) NUMBITS(1) [ + AF OFFSET(10) NUMBITS(1) [
+ False = 0, + False = 0,
+ True = 1 + True = 1
+ ], + ],
+ +
+ /// Shareability field + /// Shareability field.
+ SH OFFSET(8) NUMBITS(2) [ + SH OFFSET(8) NUMBITS(2) [
+ OuterShareable = 0b10, + OuterShareable = 0b10,
+ InnerShareable = 0b11 + InnerShareable = 0b11
+ ], + ],
+ +
+ /// Access Permissions + /// Access Permissions.
+ AP OFFSET(6) NUMBITS(2) [ + AP OFFSET(6) NUMBITS(2) [
+ RW_EL1 = 0b00, + RW_EL1 = 0b00,
+ RW_EL1_EL0 = 0b01, + RW_EL1_EL0 = 0b01,
@ -332,7 +336,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ RO_EL1_EL0 = 0b11 + RO_EL1_EL0 = 0b11
+ ], + ],
+ +
+ /// Memory attributes index into the MAIR_EL1 register + /// Memory attributes index into the MAIR_EL1 register.
+ AttrIndx OFFSET(2) NUMBITS(3) [], + AttrIndx OFFSET(2) NUMBITS(3) [],
+ +
+ TYPE OFFSET(1) NUMBITS(1) [ + TYPE OFFSET(1) NUMBITS(1) [
@ -418,7 +422,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register> + for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>
+{ +{
+ fn from(attribute_fields: AttributeFields) -> Self { + fn from(attribute_fields: AttributeFields) -> Self {
+ // Memory attributes + // Memory attributes.
+ let mut desc = match attribute_fields.mem_attributes { + let mut desc = match attribute_fields.mem_attributes {
+ MemAttributes::CacheableDRAM => { + MemAttributes::CacheableDRAM => {
+ STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable + STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable
@ -430,13 +434,13 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ } + }
+ }; + };
+ +
+ // Access Permissions + // Access Permissions.
+ desc += match attribute_fields.acc_perms { + desc += match attribute_fields.acc_perms {
+ AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1, + AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1,
+ AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1, + AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1,
+ }; + };
+ +
+ // Execute Never + // Execute Never.
+ desc += if attribute_fields.execute_never { + desc += if attribute_fields.execute_never {
+ STAGE1_PAGE_DESCRIPTOR::PXN::True + STAGE1_PAGE_DESCRIPTOR::PXN::True
+ } else { + } else {
@ -472,11 +476,11 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+fn set_up_mair() { +fn set_up_mair() {
+ // Define the memory types being mapped. + // Define the memory types being mapped.
+ MAIR_EL1.write( + MAIR_EL1.write(
+ // Attribute 1 - Cacheable normal DRAM + // Attribute 1 - Cacheable normal DRAM.
+ MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc + MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc
+ + MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc + + MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
+ +
+ // Attribute 0 - Device + // Attribute 0 - Device.
+ + MAIR_EL1::Attr0_HIGH::Device + + MAIR_EL1::Attr0_HIGH::Device
+ + MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE, + + MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE,
+ ); + );
@ -560,7 +564,7 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+ // Enable the MMU and turn on data and instruction caching. + // 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); + SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable);
+ +
+ // Force MMU init to complete before next instruction + // Force MMU init to complete before next instruction.
+ barrier::isb(barrier::SY); + barrier::isb(barrier::SY);
+ +
+ Ok(()) + Ok(())

@ -35,7 +35,7 @@ register_bitfields! {u64,
// A level 3 page descriptor, as per AArch64 Reference Manual Figure D4-17. // A level 3 page descriptor, as per AArch64 Reference Manual Figure D4-17.
register_bitfields! {u64, register_bitfields! {u64,
STAGE1_PAGE_DESCRIPTOR [ STAGE1_PAGE_DESCRIPTOR [
/// Privileged execute-never /// Privileged execute-never.
PXN OFFSET(53) NUMBITS(1) [ PXN OFFSET(53) NUMBITS(1) [
False = 0, False = 0,
True = 1 True = 1
@ -44,19 +44,19 @@ register_bitfields! {u64,
/// Physical address of the next page table (lvl2) or the page descriptor (lvl3). /// Physical address of the next page table (lvl2) or the page descriptor (lvl3).
OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16] OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16]
/// Access flag /// Access flag.
AF OFFSET(10) NUMBITS(1) [ AF OFFSET(10) NUMBITS(1) [
False = 0, False = 0,
True = 1 True = 1
], ],
/// Shareability field /// Shareability field.
SH OFFSET(8) NUMBITS(2) [ SH OFFSET(8) NUMBITS(2) [
OuterShareable = 0b10, OuterShareable = 0b10,
InnerShareable = 0b11 InnerShareable = 0b11
], ],
/// Access Permissions /// Access Permissions.
AP OFFSET(6) NUMBITS(2) [ AP OFFSET(6) NUMBITS(2) [
RW_EL1 = 0b00, RW_EL1 = 0b00,
RW_EL1_EL0 = 0b01, RW_EL1_EL0 = 0b01,
@ -64,7 +64,7 @@ register_bitfields! {u64,
RO_EL1_EL0 = 0b11 RO_EL1_EL0 = 0b11
], ],
/// Memory attributes index into the MAIR_EL1 register /// Memory attributes index into the MAIR_EL1 register.
AttrIndx OFFSET(2) NUMBITS(3) [], AttrIndx OFFSET(2) NUMBITS(3) [],
TYPE OFFSET(1) NUMBITS(1) [ TYPE OFFSET(1) NUMBITS(1) [
@ -150,7 +150,7 @@ impl convert::From<AttributeFields>
for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register> for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>
{ {
fn from(attribute_fields: AttributeFields) -> Self { fn from(attribute_fields: AttributeFields) -> Self {
// Memory attributes // Memory attributes.
let mut desc = match attribute_fields.mem_attributes { let mut desc = match attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => { MemAttributes::CacheableDRAM => {
STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable
@ -162,13 +162,13 @@ impl convert::From<AttributeFields>
} }
}; };
// Access Permissions // Access Permissions.
desc += match attribute_fields.acc_perms { desc += match attribute_fields.acc_perms {
AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1, AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1,
AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1, AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1,
}; };
// Execute Never // Execute Never.
desc += if attribute_fields.execute_never { desc += if attribute_fields.execute_never {
STAGE1_PAGE_DESCRIPTOR::PXN::True STAGE1_PAGE_DESCRIPTOR::PXN::True
} else { } else {
@ -204,11 +204,11 @@ mod mair {
fn set_up_mair() { fn set_up_mair() {
// Define the memory types being mapped. // Define the memory types being mapped.
MAIR_EL1.write( MAIR_EL1.write(
// Attribute 1 - Cacheable normal DRAM // Attribute 1 - Cacheable normal DRAM.
MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc
+ MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc + MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
// Attribute 0 - Device // Attribute 0 - Device.
+ MAIR_EL1::Attr0_HIGH::Device + MAIR_EL1::Attr0_HIGH::Device
+ MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE, + MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE,
); );
@ -292,7 +292,7 @@ impl interface::mm::MMU for MMU {
// Enable the MMU and turn on data and instruction caching. // 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); SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable);
// Force MMU init to complete before next instruction // Force MMU init to complete before next instruction.
barrier::isb(barrier::SY); barrier::isb(barrier::SY);
Ok(()) Ok(())

@ -474,7 +474,7 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_cpu_exceptions_part
+// Assembly counterpart to this file. +// Assembly counterpart to this file.
+global_asm!(include_str!("exception.S")); +global_asm!(include_str!("exception.S"));
+ +
+/// Wrapper struct for memory copy of SPSR_EL1 +/// Wrapper struct for memory copy of SPSR_EL1.
+#[repr(transparent)] +#[repr(transparent)]
+struct SpsrEL1(InMemoryRegister<u32, SPSR_EL1::Register>); +struct SpsrEL1(InMemoryRegister<u32, SPSR_EL1::Register>);
+ +
@ -491,7 +491,7 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_cpu_exceptions_part
+ spsr_el1: SpsrEL1, + spsr_el1: SpsrEL1,
+} +}
+ +
+/// Wrapper struct for pretty printing ESR_EL1 +/// Wrapper struct for pretty printing ESR_EL1.
+struct EsrEL1; +struct EsrEL1;
+ +
+//-------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------
@ -537,7 +537,7 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_cpu_exceptions_part
+/// Asynchronous exception taken from the current EL, using SP of the current EL. +/// Asynchronous exception taken from the current EL, using SP of the current EL.
+#[no_mangle] +#[no_mangle]
+unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) { +unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
+ let far_el1 = FAR_EL1.extract().get(); + let far_el1 = FAR_EL1.get();
+ +
+ // This catches the demo case for this tutorial. If the fault address happens to be 8 GiB, + // This catches the demo case for this tutorial. If the fault address happens to be 8 GiB,
+ // advance the exception link register for one instruction, so that execution can continue. + // advance the exception link register for one instruction, so that execution can continue.
@ -697,7 +697,7 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_cpu_exceptions_part
+/// - The vector table and the symbol `__exception_vector_table_start` from the linker script must +/// - The vector table and the symbol `__exception_vector_table_start` from the linker script must
+/// adhere to the alignment and size constraints demanded by the AArch64 spec. +/// adhere to the alignment and size constraints demanded by the AArch64 spec.
+pub unsafe fn set_vbar_el1() { +pub unsafe fn set_vbar_el1() {
+ // Provided by exception_vec_table.S. + // Provided by exception.S.
+ extern "C" { + extern "C" {
+ static mut __exception_vector_start: u64; + static mut __exception_vector_start: u64;
+ } + }

@ -11,7 +11,7 @@ use register::InMemoryRegister;
// Assembly counterpart to this file. // Assembly counterpart to this file.
global_asm!(include_str!("exception.S")); global_asm!(include_str!("exception.S"));
/// Wrapper struct for memory copy of SPSR_EL1 /// Wrapper struct for memory copy of SPSR_EL1.
#[repr(transparent)] #[repr(transparent)]
struct SpsrEL1(InMemoryRegister<u32, SPSR_EL1::Register>); struct SpsrEL1(InMemoryRegister<u32, SPSR_EL1::Register>);
@ -28,7 +28,7 @@ struct ExceptionContext {
spsr_el1: SpsrEL1, spsr_el1: SpsrEL1,
} }
/// Wrapper struct for pretty printing ESR_EL1 /// Wrapper struct for pretty printing ESR_EL1.
struct EsrEL1; struct EsrEL1;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -74,7 +74,7 @@ unsafe extern "C" fn current_el0_serror(e: &mut ExceptionContext) {
/// Asynchronous exception taken from the current EL, using SP of the current EL. /// Asynchronous exception taken from the current EL, using SP of the current EL.
#[no_mangle] #[no_mangle]
unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) { unsafe extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
let far_el1 = FAR_EL1.extract().get(); let far_el1 = FAR_EL1.get();
// This catches the demo case for this tutorial. If the fault address happens to be 8 GiB, // This catches the demo case for this tutorial. If the fault address happens to be 8 GiB,
// advance the exception link register for one instruction, so that execution can continue. // advance the exception link register for one instruction, so that execution can continue.
@ -234,7 +234,7 @@ impl fmt::Display for ExceptionContext {
/// - The vector table and the symbol `__exception_vector_table_start` from the linker script must /// - The vector table and the symbol `__exception_vector_table_start` from the linker script must
/// adhere to the alignment and size constraints demanded by the AArch64 spec. /// adhere to the alignment and size constraints demanded by the AArch64 spec.
pub unsafe fn set_vbar_el1() { pub unsafe fn set_vbar_el1() {
// Provided by exception_vec_table.S. // Provided by exception.S.
extern "C" { extern "C" {
static mut __exception_vector_start: u64; static mut __exception_vector_start: u64;
} }

@ -35,7 +35,7 @@ register_bitfields! {u64,
// A level 3 page descriptor, as per AArch64 Reference Manual Figure D4-17. // A level 3 page descriptor, as per AArch64 Reference Manual Figure D4-17.
register_bitfields! {u64, register_bitfields! {u64,
STAGE1_PAGE_DESCRIPTOR [ STAGE1_PAGE_DESCRIPTOR [
/// Privileged execute-never /// Privileged execute-never.
PXN OFFSET(53) NUMBITS(1) [ PXN OFFSET(53) NUMBITS(1) [
False = 0, False = 0,
True = 1 True = 1
@ -44,19 +44,19 @@ register_bitfields! {u64,
/// Physical address of the next page table (lvl2) or the page descriptor (lvl3). /// Physical address of the next page table (lvl2) or the page descriptor (lvl3).
OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16] OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16]
/// Access flag /// Access flag.
AF OFFSET(10) NUMBITS(1) [ AF OFFSET(10) NUMBITS(1) [
False = 0, False = 0,
True = 1 True = 1
], ],
/// Shareability field /// Shareability field.
SH OFFSET(8) NUMBITS(2) [ SH OFFSET(8) NUMBITS(2) [
OuterShareable = 0b10, OuterShareable = 0b10,
InnerShareable = 0b11 InnerShareable = 0b11
], ],
/// Access Permissions /// Access Permissions.
AP OFFSET(6) NUMBITS(2) [ AP OFFSET(6) NUMBITS(2) [
RW_EL1 = 0b00, RW_EL1 = 0b00,
RW_EL1_EL0 = 0b01, RW_EL1_EL0 = 0b01,
@ -64,7 +64,7 @@ register_bitfields! {u64,
RO_EL1_EL0 = 0b11 RO_EL1_EL0 = 0b11
], ],
/// Memory attributes index into the MAIR_EL1 register /// Memory attributes index into the MAIR_EL1 register.
AttrIndx OFFSET(2) NUMBITS(3) [], AttrIndx OFFSET(2) NUMBITS(3) [],
TYPE OFFSET(1) NUMBITS(1) [ TYPE OFFSET(1) NUMBITS(1) [
@ -150,7 +150,7 @@ impl convert::From<AttributeFields>
for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register> for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>
{ {
fn from(attribute_fields: AttributeFields) -> Self { fn from(attribute_fields: AttributeFields) -> Self {
// Memory attributes // Memory attributes.
let mut desc = match attribute_fields.mem_attributes { let mut desc = match attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => { MemAttributes::CacheableDRAM => {
STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable
@ -162,13 +162,13 @@ impl convert::From<AttributeFields>
} }
}; };
// Access Permissions // Access Permissions.
desc += match attribute_fields.acc_perms { desc += match attribute_fields.acc_perms {
AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1, AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1,
AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1, AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1,
}; };
// Execute Never // Execute Never.
desc += if attribute_fields.execute_never { desc += if attribute_fields.execute_never {
STAGE1_PAGE_DESCRIPTOR::PXN::True STAGE1_PAGE_DESCRIPTOR::PXN::True
} else { } else {
@ -204,11 +204,11 @@ mod mair {
fn set_up_mair() { fn set_up_mair() {
// Define the memory types being mapped. // Define the memory types being mapped.
MAIR_EL1.write( MAIR_EL1.write(
// Attribute 1 - Cacheable normal DRAM // Attribute 1 - Cacheable normal DRAM.
MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc MAIR_EL1::Attr1_HIGH::Memory_OuterWriteBack_NonTransient_ReadAlloc_WriteAlloc
+ MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc + MAIR_EL1::Attr1_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
// Attribute 0 - Device // Attribute 0 - Device.
+ MAIR_EL1::Attr0_HIGH::Device + MAIR_EL1::Attr0_HIGH::Device
+ MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE, + MAIR_EL1::Attr0_LOW_DEVICE::Device_nGnRE,
); );
@ -292,7 +292,7 @@ impl interface::mm::MMU for MMU {
// Enable the MMU and turn on data and instruction caching. // 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); SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable);
// Force MMU init to complete before next instruction // Force MMU init to complete before next instruction.
barrier::isb(barrier::SY); barrier::isb(barrier::SY);
Ok(()) Ok(())

Loading…
Cancel
Save