From 14022d69c3eefa597b22233b31ab0f2d33d2a617 Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Sun, 3 Feb 2019 21:39:26 +0100 Subject: [PATCH] Align code with updates that went into follow-up tutorials --- 0C_virtual_memory/kernel8 | Bin 71032 -> 71032 bytes 0C_virtual_memory/kernel8.img | Bin 2176 -> 2176 bytes 0C_virtual_memory/src/main.rs | 1 + 0C_virtual_memory/src/mmu.rs | 50 +++++++++++++++++++++++++--------- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/0C_virtual_memory/kernel8 b/0C_virtual_memory/kernel8 index e428cd10026e5c3f3a67e5a8bfe3d5de01870692..8d326c650932f6de33f1347eca7375f0af26c91e 100755 GIT binary patch delta 178 zcmeydisi>DmWC~iIxOOs6gy_wGx5GwnB@O!BCEs2KqkReK(X!4ER3dXj4svFbFX)GMr)KU;qIK$-vM(eIhTTxa4%8v;YG$1A_rf0<4N*;r4^Pj3ulhhKA;V4^{~ry3Nz+z{~^qnz{s?gb$XNtqZ|NmDmWC~iIxONshJCZ_nRs6-O!EIVk=5a1Ad}!KpxAb27DiJxM(6F7T#Wyj zBwJV+7=#!Y8P2eAFn|DrWMJr=K9QGETyiQfx!SK0anE@fBQjR#u8RxQxi)A pQ!p|%G&MFiG%z-u?kUWuhgG6mm@#+zH(|ykMyA!Q)1yQf!I%SsgA0G6}8%ifwjgv1I`O)b9&= diff --git a/0C_virtual_memory/src/main.rs b/0C_virtual_memory/src/main.rs index 815e5136..bd646dce 100644 --- a/0C_virtual_memory/src/main.rs +++ b/0C_virtual_memory/src/main.rs @@ -24,6 +24,7 @@ #![no_std] #![no_main] +#![feature(range_contains)] const MMIO_BASE: u32 = 0x3F00_0000; diff --git a/0C_virtual_memory/src/mmu.rs b/0C_virtual_memory/src/mmu.rs index a07429c3..ef352461 100644 --- a/0C_virtual_memory/src/mmu.rs +++ b/0C_virtual_memory/src/mmu.rs @@ -118,10 +118,9 @@ static mut SINGLE_LVL3_TABLE: PageTable = PageTable { entries: [0; NUM_ENTRIES_4KIB], }; -/// Set up identity mapped page tables for the first 1 gigabyte of address -/// space. +/// Set up identity mapped page tables for the first 1 GiB of address space. pub unsafe fn init() { - // First, define the two memory types that we will map. Normal DRAM and + // First, define the two memory types that we will map. Cacheable normal DRAM and // device. MAIR_EL1.write( // Attribute 1 @@ -132,13 +131,20 @@ pub unsafe fn init() { + MAIR_EL1::Attr0_LOW_MEMORY::InnerWriteBack_NonTransient_ReadAlloc_WriteAlloc, ); - // Two descriptive consts for indexing into the correct MAIR_EL1 attributes. + // Descriptive consts for indexing into the correct MAIR_EL1 attributes. mod mair { pub const NORMAL: u64 = 0; pub const DEVICE: u64 = 1; } - // Set up the first LVL2 entry, pointing to a 4KiB table base address. + // The first 2 MiB. + // + // Set up the first LVL2 entry, pointing to the base address of a follow-up + // table containing 4 KiB pages. + // + // 0x0000_0000_0000_0000 | + // |> 2 MiB + // 0x0000_0000_001F_FFFF | let lvl3_base: u64 = SINGLE_LVL3_TABLE.entries.base_addr() >> 12; LVL2_TABLE.entries[0] = (STAGE1_DESCRIPTOR::VALID::True + STAGE1_DESCRIPTOR::TYPE::Table @@ -147,6 +153,10 @@ pub unsafe fn init() { // For educational purposes and fun, let the start of the second 2 MiB block // point to the 2 MiB aperture which contains the UART's base address. + // + // 0x0000_0000_0020_0000 | + // |> 2 MiB + // 0x0000_0000_003F_FFFF | let uart_phys_base: u64 = (uart::UART_PHYS_BASE >> 21).into(); LVL2_TABLE.entries[1] = (STAGE1_DESCRIPTOR::VALID::True + STAGE1_DESCRIPTOR::TYPE::Block @@ -158,20 +168,34 @@ pub unsafe fn init() { + STAGE1_DESCRIPTOR::XN::True) .value; - // Fill the rest of the LVL2 (2MiB) entries as block - // descriptors. Differentiate between normal and device mem. - let mmio_base: u64 = (super::MMIO_BASE >> 21).into(); + // Fill the rest of the LVL2 (2 MiB) entries as block descriptors. + // + // Differentiate between + // - cacheable DRAM + // - device memory + // + // Ranges are stored in memory.rs. + // + // 0x0000_0000_0040_0000 | + // |> 1004 MiB cacheable DRAM + // 0x0000_0000_3EFF_FFFF | + // 0x0000_0000_3F00_0000 | + // |> 16 MiB device (MMIO) + // 0x0000_0000_4000_0000 | + let mmio_first_block_index: u64 = (super::MMIO_BASE >> 21).into(); + let common = STAGE1_DESCRIPTOR::VALID::True + STAGE1_DESCRIPTOR::TYPE::Block + STAGE1_DESCRIPTOR::AP::RW_EL1 + STAGE1_DESCRIPTOR::AF::True + STAGE1_DESCRIPTOR::XN::True; - // Notice the skip(2) + // Notice the skip(2) which makes the iteration start at the third 2 MiB + // block (0x40_0000). for (i, entry) in LVL2_TABLE.entries.iter_mut().enumerate().skip(2) { let j: u64 = i as u64; - let mem_attr = if j >= mmio_base { + let mem_attr = if j >= mmio_first_block_index { STAGE1_DESCRIPTOR::SH::OuterShareable + STAGE1_DESCRIPTOR::AttrIndx.val(mair::DEVICE) } else { STAGE1_DESCRIPTOR::SH::InnerShareable + STAGE1_DESCRIPTOR::AttrIndx.val(mair::NORMAL) @@ -211,10 +235,10 @@ pub unsafe fn init() { for (i, entry) in SINGLE_LVL3_TABLE.entries.iter_mut().enumerate() { let j: u64 = i as u64; - let mem_attr = if j < ro_first_page_index || j > ro_last_page_index { - STAGE1_DESCRIPTOR::AP::RW_EL1 + STAGE1_DESCRIPTOR::XN::True - } else { + let mem_attr = if (ro_first_page_index..=ro_last_page_index).contains(&j) { STAGE1_DESCRIPTOR::AP::RO_EL1 + STAGE1_DESCRIPTOR::XN::False + } else { + STAGE1_DESCRIPTOR::AP::RW_EL1 + STAGE1_DESCRIPTOR::XN::True }; *entry = (common + mem_attr + STAGE1_DESCRIPTOR::NEXT_LVL_TABLE_ADDR_4KiB.val(j)).value;