Minor fixes

pull/37/head
Andre Richter 4 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:
```rust
// Two newtypes for added type safety, so that you cannot accidentally place a TableDescriptor into
// a PageDescriptor slot in `struct PageTables`, and vice versa.
/// A table descriptor for 64 KiB aperture.
///
/// The output points to the next table.
#[derive(Copy, Clone)]
#[repr(transparent)]
struct RawTableDescriptor(u64);
struct TableDescriptor(u64);
/// A page descriptor with 64 KiB aperture.
///
/// The output points to physical memory.
#[derive(Copy, Clone)]
#[repr(transparent)]
struct RawPageDescriptor(u64);
struct PageDescriptor(u64);
/// Big monolithic struct for storing the page tables. Individual levels must be 64 KiB aligned,
/// hence the "reverse" order of appearance.
@ -103,9 +107,9 @@ struct RawPageDescriptor(u64);
#[repr(align(65536))]
struct PageTables<const N: usize> {
// Page descriptors, covering 64 KiB windows per entry.
lvl3: [[RawPageDescriptor; 8192]; N],
lvl3: [[PageDescriptor; 8192]; N],
// 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.
@ -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.
static mut TABLES: PageTables<{ ENTRIES_512_MIB }> = PageTables {
lvl3: [[RawPageDescriptor(0); 8192]; ENTRIES_512_MIB],
lvl2: [RawTableDescriptor(0); ENTRIES_512_MIB],
lvl3: [[PageDescriptor(0); 8192]; 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() {
// Define the memory types being mapped.
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_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
// Attribute 0 - Device
// Attribute 0 - Device.
+ MAIR_EL1::Attr0_HIGH::Device
+ 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.
+register_bitfields! {u64,
+ STAGE1_PAGE_DESCRIPTOR [
+ /// Privileged execute-never
+ /// Privileged execute-never.
+ PXN OFFSET(53) NUMBITS(1) [
+ False = 0,
+ 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).
+ OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16]
+
+ /// Access flag
+ /// Access flag.
+ AF OFFSET(10) NUMBITS(1) [
+ False = 0,
+ True = 1
+ ],
+
+ /// Shareability field
+ /// Shareability field.
+ SH OFFSET(8) NUMBITS(2) [
+ OuterShareable = 0b10,
+ InnerShareable = 0b11
+ ],
+
+ /// Access Permissions
+ /// Access Permissions.
+ AP OFFSET(6) NUMBITS(2) [
+ RW_EL1 = 0b00,
+ 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
+ ],
+
+ /// Memory attributes index into the MAIR_EL1 register
+ /// Memory attributes index into the MAIR_EL1 register.
+ AttrIndx OFFSET(2) NUMBITS(3) [],
+
+ 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>
+{
+ fn from(attribute_fields: AttributeFields) -> Self {
+ // Memory attributes
+ // Memory attributes.
+ let mut desc = match attribute_fields.mem_attributes {
+ MemAttributes::CacheableDRAM => {
+ 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 {
+ AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1,
+ AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1,
+ };
+
+ // Execute Never
+ // Execute Never.
+ desc += if attribute_fields.execute_never {
+ STAGE1_PAGE_DESCRIPTOR::PXN::True
+ } else {
@ -472,11 +476,11 @@ diff -uNr 10_privilege_level/src/arch/aarch64/mmu.rs 11_virtual_memory/src/arch/
+fn set_up_mair() {
+ // Define the memory types being mapped.
+ 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_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
+
+ // Attribute 0 - Device
+ // Attribute 0 - Device.
+ + MAIR_EL1::Attr0_HIGH::Device
+ + 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.
+ 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);
+
+ Ok(())

@ -35,7 +35,7 @@ register_bitfields! {u64,
// A level 3 page descriptor, as per AArch64 Reference Manual Figure D4-17.
register_bitfields! {u64,
STAGE1_PAGE_DESCRIPTOR [
/// Privileged execute-never
/// Privileged execute-never.
PXN OFFSET(53) NUMBITS(1) [
False = 0,
True = 1
@ -44,19 +44,19 @@ register_bitfields! {u64,
/// Physical address of the next page table (lvl2) or the page descriptor (lvl3).
OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16]
/// Access flag
/// Access flag.
AF OFFSET(10) NUMBITS(1) [
False = 0,
True = 1
],
/// Shareability field
/// Shareability field.
SH OFFSET(8) NUMBITS(2) [
OuterShareable = 0b10,
InnerShareable = 0b11
],
/// Access Permissions
/// Access Permissions.
AP OFFSET(6) NUMBITS(2) [
RW_EL1 = 0b00,
RW_EL1_EL0 = 0b01,
@ -64,7 +64,7 @@ register_bitfields! {u64,
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) [],
TYPE OFFSET(1) NUMBITS(1) [
@ -150,7 +150,7 @@ impl convert::From<AttributeFields>
for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>
{
fn from(attribute_fields: AttributeFields) -> Self {
// Memory attributes
// Memory attributes.
let mut desc = match attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => {
STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable
@ -162,13 +162,13 @@ impl convert::From<AttributeFields>
}
};
// Access Permissions
// Access Permissions.
desc += match attribute_fields.acc_perms {
AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1,
AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1,
};
// Execute Never
// Execute Never.
desc += if attribute_fields.execute_never {
STAGE1_PAGE_DESCRIPTOR::PXN::True
} else {
@ -204,11 +204,11 @@ mod mair {
fn set_up_mair() {
// Define the memory types being mapped.
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_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
// Attribute 0 - Device
// Attribute 0 - Device.
+ MAIR_EL1::Attr0_HIGH::Device
+ 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.
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);
Ok(())

@ -474,7 +474,7 @@ diff -uNr 11_virtual_memory/src/arch/aarch64/exception.rs 12_cpu_exceptions_part
+// Assembly counterpart to this file.
+global_asm!(include_str!("exception.S"));
+
+/// Wrapper struct for memory copy of SPSR_EL1
+/// Wrapper struct for memory copy of SPSR_EL1.
+#[repr(transparent)]
+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,
+}
+
+/// Wrapper struct for pretty printing ESR_EL1
+/// Wrapper struct for pretty printing ESR_EL1.
+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.
+#[no_mangle]
+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,
+ // 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
+/// adhere to the alignment and size constraints demanded by the AArch64 spec.
+pub unsafe fn set_vbar_el1() {
+ // Provided by exception_vec_table.S.
+ // Provided by exception.S.
+ extern "C" {
+ static mut __exception_vector_start: u64;
+ }

@ -11,7 +11,7 @@ use register::InMemoryRegister;
// Assembly counterpart to this file.
global_asm!(include_str!("exception.S"));
/// Wrapper struct for memory copy of SPSR_EL1
/// Wrapper struct for memory copy of SPSR_EL1.
#[repr(transparent)]
struct SpsrEL1(InMemoryRegister<u32, SPSR_EL1::Register>);
@ -28,7 +28,7 @@ struct ExceptionContext {
spsr_el1: SpsrEL1,
}
/// Wrapper struct for pretty printing ESR_EL1
/// Wrapper struct for pretty printing ESR_EL1.
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.
#[no_mangle]
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,
// 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
/// adhere to the alignment and size constraints demanded by the AArch64 spec.
pub unsafe fn set_vbar_el1() {
// Provided by exception_vec_table.S.
// Provided by exception.S.
extern "C" {
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.
register_bitfields! {u64,
STAGE1_PAGE_DESCRIPTOR [
/// Privileged execute-never
/// Privileged execute-never.
PXN OFFSET(53) NUMBITS(1) [
False = 0,
True = 1
@ -44,19 +44,19 @@ register_bitfields! {u64,
/// Physical address of the next page table (lvl2) or the page descriptor (lvl3).
OUTPUT_ADDR_64KiB OFFSET(16) NUMBITS(32) [], // [47:16]
/// Access flag
/// Access flag.
AF OFFSET(10) NUMBITS(1) [
False = 0,
True = 1
],
/// Shareability field
/// Shareability field.
SH OFFSET(8) NUMBITS(2) [
OuterShareable = 0b10,
InnerShareable = 0b11
],
/// Access Permissions
/// Access Permissions.
AP OFFSET(6) NUMBITS(2) [
RW_EL1 = 0b00,
RW_EL1_EL0 = 0b01,
@ -64,7 +64,7 @@ register_bitfields! {u64,
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) [],
TYPE OFFSET(1) NUMBITS(1) [
@ -150,7 +150,7 @@ impl convert::From<AttributeFields>
for register::FieldValue<u64, STAGE1_PAGE_DESCRIPTOR::Register>
{
fn from(attribute_fields: AttributeFields) -> Self {
// Memory attributes
// Memory attributes.
let mut desc = match attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => {
STAGE1_PAGE_DESCRIPTOR::SH::InnerShareable
@ -162,13 +162,13 @@ impl convert::From<AttributeFields>
}
};
// Access Permissions
// Access Permissions.
desc += match attribute_fields.acc_perms {
AccessPermissions::ReadOnly => STAGE1_PAGE_DESCRIPTOR::AP::RO_EL1,
AccessPermissions::ReadWrite => STAGE1_PAGE_DESCRIPTOR::AP::RW_EL1,
};
// Execute Never
// Execute Never.
desc += if attribute_fields.execute_never {
STAGE1_PAGE_DESCRIPTOR::PXN::True
} else {
@ -204,11 +204,11 @@ mod mair {
fn set_up_mair() {
// Define the memory types being mapped.
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_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc
// Attribute 0 - Device
// Attribute 0 - Device.
+ MAIR_EL1::Attr0_HIGH::Device
+ 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.
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);
Ok(())

Loading…
Cancel
Save