modify mmio() & set_mmio() in PageEntry

toolchain_update
equation314 6 years ago
parent 48cf25716f
commit b5cc79d1b2

@ -223,7 +223,7 @@ pub struct MemoryAttr {
readonly: bool, readonly: bool,
execute: bool, execute: bool,
hide: bool, hide: bool,
mmio: usize, mmio: u8,
} }
impl MemoryAttr { impl MemoryAttr {
@ -255,7 +255,7 @@ impl MemoryAttr {
** @brief set the MMIO type ** @brief set the MMIO type
** @retval MemoryAttr the memory attribute itself ** @retval MemoryAttr the memory attribute itself
*/ */
pub fn mmio(mut self, value: usize) -> Self { pub fn mmio(mut self, value: u8) -> Self {
self.mmio = value; self.mmio = value;
self self
} }

@ -198,13 +198,13 @@ pub trait Entry {
/* /*
** @brief get MMIO type ** @brief get MMIO type
** (e.g. aarch64 can have normal/device/normal_non_cacheable memory) ** (e.g. aarch64 can have normal/device/normal_non_cacheable memory)
** @retval usize ** @retval u8 the MMIO type
*/ */
fn mmio(&self) -> usize; fn mmio(&self) -> u8;
/* /*
** @brief set MMIO type ** @brief set MMIO type
** @param value: usize the value distinguished memory type ** @param value: u8 the MMIO type
** @retval none ** @retval none
*/ */
fn set_mmio(&mut self, value: usize); fn set_mmio(&mut self, value: u8);
} }

2
kernel/Cargo.lock generated

@ -1,7 +1,7 @@
[[package]] [[package]]
name = "aarch64" name = "aarch64"
version = "2.2.2" version = "2.2.2"
source = "git+https://github.com/equation314/aarch64#9770a21c00f5d74c32ed044ca200f0459caca828" source = "git+https://github.com/equation314/aarch64#b6a0f4a3be6f74927c88305a6af5ad2be079bccd"
dependencies = [ dependencies = [
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",

@ -48,7 +48,7 @@ use self::ColorFormat::*;
#[repr(C)] #[repr(C)]
union ColorBuffer { union ColorBuffer {
base_addr: u32, base_addr: usize,
buf16: &'static mut [u16], buf16: &'static mut [u16],
buf32: &'static mut [u32], buf32: &'static mut [u32],
} }
@ -154,10 +154,11 @@ impl Framebuffer {
} }
#[inline] #[inline]
pub fn base_addr(&self) -> u32 { pub fn base_addr(&self) -> usize {
unsafe { self.buf.base_addr } unsafe { self.buf.base_addr }
} }
/// Read pixel at `(x, y)`.
#[inline] #[inline]
pub fn read(&self, x: u32, y: u32) -> u32 { pub fn read(&self, x: u32, y: u32) -> u32 {
match self.color_format { match self.color_format {
@ -166,6 +167,7 @@ impl Framebuffer {
} }
} }
/// Write pixel at `(x, y)`.
#[inline] #[inline]
pub fn write(&mut self, x: u32, y: u32, pixel: u32) { pub fn write(&mut self, x: u32, y: u32, pixel: u32) {
match self.color_format { match self.color_format {

@ -8,7 +8,7 @@ use lazy_static::lazy_static;
use alloc::string::String; use alloc::string::String;
use core::mem; use core::mem;
use spin::Mutex; use spin::Mutex;
use aarch64::{asm, barrier}; use aarch64::asm;
lazy_static! { lazy_static! {
static ref MAILBOX: Mutex<Mailbox> = Mutex::new(Mailbox::new()); static ref MAILBOX: Mutex<Mailbox> = Mutex::new(Mailbox::new());

@ -1,6 +1,7 @@
//! Memory initialization for aarch64. //! Memory initialization for aarch64.
use crate::memory::{init_heap, MemoryArea, MemoryAttr, MemorySet, FRAME_ALLOCATOR}; use crate::memory::{init_heap, MemoryArea, MemoryAttr, MemorySet, FRAME_ALLOCATOR};
use super::paging::MMIOType;
use aarch64::paging::{memory_attribute::*, PhysFrame as Frame}; use aarch64::paging::{memory_attribute::*, PhysFrame as Frame};
use aarch64::{addr::*, barrier, regs::*}; use aarch64::{addr::*, barrier, regs::*};
use atags::atags::Atags; use atags::atags::Atags;
@ -32,8 +33,8 @@ pub fn init_mmu_early() {
// device. // device.
MAIR_EL1.write( MAIR_EL1.write(
MAIR_EL1::Attr0.val(MairDevice::config_value()) + MAIR_EL1::Attr0.val(MairNormal::config_value()) +
MAIR_EL1::Attr1.val(MairNormal::config_value()) + MAIR_EL1::Attr1.val(MairDevice::config_value()) +
MAIR_EL1::Attr2.val(MairNormalNonCacheable::config_value()), MAIR_EL1::Attr2.val(MairNormalNonCacheable::config_value()),
); );
@ -116,7 +117,7 @@ fn remap_the_kernel() {
ms.push(MemoryArea::new_identity( ms.push(MemoryArea::new_identity(
IO_REMAP_BASE, IO_REMAP_BASE,
IO_REMAP_END, IO_REMAP_END,
MemoryAttr::default().mmio(MairDevice::attr_value().value as usize), MemoryAttr::default().mmio(MMIOType::Device as u8),
"io_remap", "io_remap",
)); ));
@ -129,7 +130,7 @@ pub fn ioremap(start: usize, len: usize, name: &'static str) -> usize {
let area = MemoryArea::new_identity( let area = MemoryArea::new_identity(
start, start,
start + len, start + len,
MemoryAttr::default().mmio(MairNormalNonCacheable::attr_value().value as usize), MemoryAttr::default().mmio(MMIOType::NormalNonCacheable as u8),
name, name,
); );
ms.push(area); ms.push(area);

@ -22,7 +22,7 @@ pub fn setup_temp_page_table(frame_lvl4: Frame, frame_lvl3: Frame, frame_lvl2: F
p2.zero(); p2.zero();
let (start_addr, end_addr) = (0, 0x40000000); let (start_addr, end_addr) = (0, 0x40000000);
let block_flags = EF::VALID | EF::AF | EF::WRITE | EF::XN; let block_flags = EF::VALID | EF::AF | EF::WRITE | EF::UXN;
for page in Page::<Size2MiB>::range_of(start_addr, end_addr) { for page in Page::<Size2MiB>::range_of(start_addr, end_addr) {
let paddr = PhysAddr::new(page.start_address().as_u64()); let paddr = PhysAddr::new(page.start_address().as_u64());
@ -106,6 +106,14 @@ impl ActivePageTable {
} }
} }
#[repr(u8)]
pub enum MMIOType {
Normal = 0,
Device = 1,
NormalNonCacheable = 2,
Unsupported = 3,
}
impl Entry for PageEntry { impl Entry for PageEntry {
fn update(&mut self) { fn update(&mut self) {
let addr = VirtAddr::new_unchecked((self as *const _ as u64) << 9); let addr = VirtAddr::new_unchecked((self as *const _ as u64) << 9);
@ -150,22 +158,38 @@ impl Entry for PageEntry {
} }
fn execute(&self) -> bool { fn execute(&self) -> bool {
if self.user() { if self.user() {
!self.0.flags().contains(EF::XN) !self.0.flags().contains(EF::UXN)
} else { } else {
!self.0.flags().contains(EF::PXN) !self.0.flags().contains(EF::PXN)
} }
} }
fn set_execute(&mut self, value: bool) { fn set_execute(&mut self, value: bool) {
if self.user() { if self.user() {
self.as_flags().set(EF::XN, !value) self.as_flags().set(EF::UXN, !value)
} else { } else {
self.as_flags().set(EF::PXN, !value) self.as_flags().set(EF::PXN, !value)
} }
} }
fn mmio(&self) -> usize { self.0.attr().value as usize } fn mmio(&self) -> u8 {
fn set_mmio(&mut self, value: usize) { let value = self.0.attr().value;
use aarch64::paging::{PageTableAttribute, MEMORY_ATTR_MASK}; if value == MairNormal::attr_value().value {
self.0.modify_attr(PageTableAttribute::new(MEMORY_ATTR_MASK, 0, value as u64)) 0
} else if value == MairDevice::attr_value().value {
1
} else if value == MairNormalNonCacheable::attr_value().value {
2
} else {
3
}
}
fn set_mmio(&mut self, value: u8) {
let attr = match value {
0 => MairNormal::attr_value(),
1 => MairDevice::attr_value(),
2 => MairNormalNonCacheable::attr_value(),
_ => return,
};
self.0.modify_attr(attr);
} }
} }

@ -26,7 +26,7 @@ pub fn setup_page_table(frame: Frame) {
// Set kernel identity map // Set kernel identity map
// 0x10000000 ~ 1K area // 0x10000000 ~ 1K area
p2.map_identity(0x40, EF::VALID | EF::READABLE | EF::WRITABLE); p2.map_identity(0x40, EF::VALID | EF::READABLE | EF::WRITABLE);
// 0x80000000 ~ 12M area // 0x80000000 ~ 12M area
p2.map_identity(KERNEL_P2_INDEX, EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE); p2.map_identity(KERNEL_P2_INDEX, EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE);
p2.map_identity(KERNEL_P2_INDEX + 1, EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE); p2.map_identity(KERNEL_P2_INDEX + 1, EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE);
p2.map_identity(KERNEL_P2_INDEX + 2, EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE); p2.map_identity(KERNEL_P2_INDEX + 2, EF::VALID | EF::READABLE | EF::WRITABLE | EF::EXECUTABLE);
@ -196,8 +196,8 @@ impl Entry for PageEntry {
fn set_user(&mut self, value: bool) { self.as_flags().set(EF::USER, value); } fn set_user(&mut self, value: bool) { self.as_flags().set(EF::USER, value); }
fn execute(&self) -> bool { self.0.flags().contains(EF::EXECUTABLE) } fn execute(&self) -> bool { self.0.flags().contains(EF::EXECUTABLE) }
fn set_execute(&mut self, value: bool) { self.as_flags().set(EF::EXECUTABLE, value); } fn set_execute(&mut self, value: bool) { self.as_flags().set(EF::EXECUTABLE, value); }
fn mmio(&self) -> bool { unimplemented!() } fn mmio(&self) -> u8 { 0 }
fn set_mmio(&mut self, value: bool) { unimplemented!() } fn set_mmio(&mut self, _value: u8) { }
} }
impl PageEntry { impl PageEntry {

@ -142,8 +142,8 @@ impl Entry for PageEntry {
} }
fn execute(&self) -> bool { !self.0.flags().contains(EF::NO_EXECUTE) } fn execute(&self) -> bool { !self.0.flags().contains(EF::NO_EXECUTE) }
fn set_execute(&mut self, value: bool) { self.as_flags().set(EF::NO_EXECUTE, !value); } fn set_execute(&mut self, value: bool) { self.as_flags().set(EF::NO_EXECUTE, !value); }
fn mmio(&self) -> bool { unimplemented!() } fn mmio(&self) -> u8 { 0 }
fn set_mmio(&mut self, value: bool) { unimplemented!() } fn set_mmio(&mut self, _value: u8) { }
} }
fn get_entry_ptr(addr: usize, level: u8) -> *mut PageEntry { fn get_entry_ptr(addr: usize, level: u8) -> *mut PageEntry {

Loading…
Cancel
Save