Align cache tutorial as well

pull/15/head
Andre Richter 5 years ago
parent c6e12f7bcf
commit 0f1f09730d
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

Binary file not shown.

Binary file not shown.

@ -24,6 +24,7 @@
#![no_std]
#![no_main]
#![feature(range_contains)]
const MMIO_BASE: u32 = 0x3F00_0000;

@ -99,8 +99,7 @@ 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 three memory types that we will map. Cacheable and
// non-cacheable normal DRAM, and device.
@ -125,14 +124,27 @@ pub unsafe fn init() {
pub const NORMAL_NON_CACHEABLE: u64 = 2;
}
// 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
+ STAGE1_DESCRIPTOR::NEXT_LVL_TABLE_ADDR_4KiB.val(lvl3_base))
.value;
// The second 2 MiB block.
// The second 2 MiB as block entry.
//
// Mapped as non-cacheable.
//
// 0x0000_0000_0020_0000 |
// |> 2 MiB
// 0x0000_0000_003F_FFFF |
LVL2_TABLE.entries[1] = (STAGE1_DESCRIPTOR::VALID::True
+ STAGE1_DESCRIPTOR::TYPE::Block
+ STAGE1_DESCRIPTOR::AttrIndx.val(mair::NORMAL_NON_CACHEABLE)
@ -148,9 +160,22 @@ 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
@ -162,7 +187,7 @@ pub unsafe fn init() {
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)
@ -202,10 +227,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;

Loading…
Cancel
Save