mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 17:55:20 +08:00
Compare commits
No commits in common. "2ace3f14e11bcdf48e44091d7c25d83a223854ea" and "9c95cb4f5e342cb801adbcdcb4a0c8636a90af46" have entirely different histories.
2ace3f14e1
...
9c95cb4f5e
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RsVcsConfiguration">
|
|
||||||
<option name="rustFmt" value="true" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -14,12 +14,6 @@ version = "1.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "2.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -41,7 +35,7 @@ version = "10.7.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
|
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -84,7 +78,6 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|||||||
name = "tiny_os"
|
name = "tiny_os"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.1",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"sbi-rt",
|
"sbi-rt",
|
||||||
@ -98,7 +91,7 @@ version = "0.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
|
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"x86",
|
"x86",
|
||||||
]
|
]
|
||||||
@ -110,6 +103,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
|
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"bitflags 1.3.2",
|
"bitflags",
|
||||||
"raw-cpuid",
|
"raw-cpuid",
|
||||||
]
|
]
|
||||||
|
@ -23,7 +23,6 @@ panic = "abort"
|
|||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "2.4.1"
|
|
||||||
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
|
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
sbi-rt = { version = "0.0.2", features = ["legacy"] }
|
sbi-rt = { version = "0.0.2", features = ["legacy"] }
|
||||||
|
@ -5,6 +5,6 @@ pub mod io;
|
|||||||
pub mod lowlevel;
|
pub mod lowlevel;
|
||||||
|
|
||||||
// Arch Level
|
// Arch Level
|
||||||
#[cfg(any(feature = "arch_riscv64", feature = "arch_riscv32"))]
|
#[cfg(feature = "arch_riscv64")]
|
||||||
#[path = "riscv/mod.rs"]
|
#[path = "riscv/mod.rs"]
|
||||||
mod riscv;
|
mod riscv;
|
||||||
|
@ -6,7 +6,7 @@ unsafe extern "C" fn _start(hart_id: usize, device_tree_addr: usize) -> ! {
|
|||||||
// no stack here
|
// no stack here
|
||||||
|
|
||||||
const STACK_SIZE: usize = 4096 * 16;
|
const STACK_SIZE: usize = 4096 * 16;
|
||||||
#[link_section = ".bss.boot_stack"]
|
#[link_section = ".boot_stack"]
|
||||||
static mut STACK: [u8; STACK_SIZE] = [0u8; STACK_SIZE];
|
static mut STACK: [u8; STACK_SIZE] = [0u8; STACK_SIZE];
|
||||||
|
|
||||||
core::arch::asm!(
|
core::arch::asm!(
|
||||||
@ -20,8 +20,6 @@ unsafe extern "C" fn _start(hart_id: usize, device_tree_addr: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn pre_main(hart_id: usize, device_tree_addr: usize) -> ! {
|
extern "C" fn pre_main(hart_id: usize, device_tree_addr: usize) -> ! {
|
||||||
// TODO: multiboot
|
|
||||||
|
|
||||||
unsafe { zero_bss() }
|
unsafe { zero_bss() }
|
||||||
|
|
||||||
// TODO: initialize page table
|
// TODO: initialize page table
|
||||||
@ -30,14 +28,16 @@ extern "C" fn pre_main(hart_id: usize, device_tree_addr: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static mut __boot_stack_end: u8;
|
static mut __bss_start: u8;
|
||||||
static mut __bss_end: u8;
|
static mut __bss_end: u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
unsafe fn zero_bss() {
|
unsafe fn zero_bss() {
|
||||||
let cur = &mut __boot_stack_end as *mut u8;
|
let mut cur = &mut __bss_start as *mut u8;
|
||||||
let end = &mut __bss_end as *mut u8;
|
let end = &mut __bss_end as *mut u8;
|
||||||
|
|
||||||
core::slice::from_raw_parts_mut(cur, end.offset_from(cur) as usize).fill(0);
|
while cur < end {
|
||||||
|
cur.write_volatile(0);
|
||||||
|
cur = cur.add(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,12 +42,14 @@ SECTIONS {
|
|||||||
__data_end = .;
|
__data_end = .;
|
||||||
} > DRAM
|
} > DRAM
|
||||||
|
|
||||||
|
.stack : {
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.boot_stack)
|
||||||
|
} > DRAM
|
||||||
|
|
||||||
.bss : {
|
.bss : {
|
||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
||||||
__bss_start = .;
|
__bss_start = .;
|
||||||
*(.bss.boot_stack)
|
|
||||||
__boot_stack_end = .;
|
|
||||||
|
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
*(.sbss .sbss.*)
|
*(.sbss .sbss.*)
|
||||||
__bss_end = .;
|
__bss_end = .;
|
||||||
|
@ -1 +0,0 @@
|
|||||||
pub mod page;
|
|
@ -1,135 +0,0 @@
|
|||||||
use crate::mm::addr::{AddressOps, PhysAddr, VirtAddr};
|
|
||||||
use crate::mm::page;
|
|
||||||
|
|
||||||
use bitflags::bitflags;
|
|
||||||
use static_assertions::assert_eq_size;
|
|
||||||
|
|
||||||
const PAGE_SIZE: usize = 4096;
|
|
||||||
const PAGE_TABLE_ENTRIES: usize = 512;
|
|
||||||
|
|
||||||
const PG_OFFSET: u64 = 12;
|
|
||||||
const PPN_OFFSET: u64 = 10;
|
|
||||||
const PPN_BITS: u64 = 44;
|
|
||||||
const PTE_PPN_MASK: u64 = ((1 << PPN_BITS) - 1) << PPN_OFFSET;
|
|
||||||
const PA_PPN_MASK: u64 = ((1 << PPN_BITS) - 1) << PG_OFFSET;
|
|
||||||
|
|
||||||
bitflags! {
|
|
||||||
pub struct PTEFlags : u64 {
|
|
||||||
const VALID = 1 << 0;
|
|
||||||
const READABLE = 1 << 1;
|
|
||||||
const WRITABLE = 1 << 2;
|
|
||||||
const EXECUTABLE = 1 << 3;
|
|
||||||
const USER_ACCESSIBLE = 1 << 4;
|
|
||||||
const GLOBAL = 1 << 5;
|
|
||||||
const ACCESSED = 1 << 6;
|
|
||||||
const DIRTY = 1 << 7;
|
|
||||||
const RSW = 1 << 8 | 1 << 9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PTEFlags> for page::MapAttr {
|
|
||||||
fn from(flags: PTEFlags) -> Self {
|
|
||||||
let mut attr = Self::empty();
|
|
||||||
|
|
||||||
if flags.contains(PTEFlags::READABLE) {
|
|
||||||
attr.insert(Self::READABLE);
|
|
||||||
}
|
|
||||||
if flags.contains(PTEFlags::WRITABLE) {
|
|
||||||
attr.insert(Self::WRITABLE);
|
|
||||||
}
|
|
||||||
if flags.contains(PTEFlags::EXECUTABLE) {
|
|
||||||
attr.insert(Self::EXECUTABLE);
|
|
||||||
}
|
|
||||||
if flags.contains(PTEFlags::USER_ACCESSIBLE) {
|
|
||||||
attr.insert(Self::USER_ACCESSIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
attr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<page::MapAttr> for PTEFlags {
|
|
||||||
fn from(attr: page::MapAttr) -> Self {
|
|
||||||
if attr.is_empty() {
|
|
||||||
return Self::empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut flags = Self::VALID;
|
|
||||||
|
|
||||||
if attr.contains(page::MapAttr::READABLE) {
|
|
||||||
flags.insert(Self::READABLE);
|
|
||||||
}
|
|
||||||
if attr.contains(page::MapAttr::WRITABLE) {
|
|
||||||
flags.insert(Self::WRITABLE);
|
|
||||||
}
|
|
||||||
if attr.contains(page::MapAttr::EXECUTABLE) {
|
|
||||||
flags.insert(Self::EXECUTABLE);
|
|
||||||
}
|
|
||||||
if attr.contains(page::MapAttr::USER_ACCESSIBLE) {
|
|
||||||
flags.insert(Self::USER_ACCESSIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
flags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
struct PTE(u64);
|
|
||||||
|
|
||||||
impl page::PageTableEntry for PTE {
|
|
||||||
fn new_page(paddr: PhysAddr, attr: page::MapAttr) -> Self {
|
|
||||||
let flags = PTEFlags::from(attr);
|
|
||||||
let ppn = ((paddr.as_u64() & PA_PPN_MASK) >> PG_OFFSET) << PPN_OFFSET;
|
|
||||||
|
|
||||||
Self(ppn | flags.bits())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_table(paddr: PhysAddr) -> Self {
|
|
||||||
let flags = PTEFlags::VALID;
|
|
||||||
let ppn = ((paddr.as_u64() & PA_PPN_MASK) >> PG_OFFSET) << PPN_OFFSET;
|
|
||||||
|
|
||||||
Self(ppn | flags.bits())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn addr(&self) -> PhysAddr {
|
|
||||||
let ppn = (self.0 & PTE_PPN_MASK) >> PPN_OFFSET;
|
|
||||||
let paddr = ppn << PG_OFFSET;
|
|
||||||
PhysAddr::from(paddr as usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn attr(&self) -> page::MapAttr {
|
|
||||||
let flags = PTEFlags::from_bits_truncate(self.0);
|
|
||||||
flags.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_addr(&mut self, addr: PhysAddr) {
|
|
||||||
let ppn = ((addr.as_u64() & PA_PPN_MASK) >> PG_OFFSET) << PPN_OFFSET;
|
|
||||||
self.0 = (self.0 & !PTE_PPN_MASK) | ppn;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_attr(&mut self, attr: page::MapAttr) {
|
|
||||||
let flags = PTEFlags::from(attr);
|
|
||||||
self.0 = (self.0 & !PTEFlags::all().bits()) | flags.bits();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_valid(&self) -> bool {
|
|
||||||
self.0 & PTEFlags::VALID.bits() != 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we'll implement sv39 paging scheme
|
|
||||||
|
|
||||||
pub struct Size4KiB;
|
|
||||||
impl page::PageSize for Size4KiB {
|
|
||||||
const SIZE: usize = 1 << 12; // 4KiB
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Size2MiB;
|
|
||||||
impl page::PageSize for Size2MiB {
|
|
||||||
const SIZE: usize = 1 << 21; // 2MiB
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Size1GiB;
|
|
||||||
impl page::PageSize for Size1GiB {
|
|
||||||
const SIZE: usize = 1 << 30; // 1GiB
|
|
||||||
}
|
|
@ -7,5 +7,4 @@ mod layout;
|
|||||||
pub mod entry;
|
pub mod entry;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod lowlevel;
|
pub mod lowlevel;
|
||||||
pub mod mm;
|
|
||||||
pub mod trap;
|
pub mod trap;
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
pub struct Trap;
|
|
||||||
|
|
||||||
pub trait Trampoline {
|
|
||||||
fn init();
|
|
||||||
}
|
|
@ -2,6 +2,7 @@
|
|||||||
#![feature(asm_const)]
|
#![feature(asm_const)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
|
#![feature(fmt_internals)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
||||||
extern crate static_assertions;
|
extern crate static_assertions;
|
||||||
@ -15,8 +16,5 @@ pub mod lang;
|
|||||||
// entrypoint
|
// entrypoint
|
||||||
pub mod entry;
|
pub mod entry;
|
||||||
|
|
||||||
// page table
|
|
||||||
pub mod mm;
|
|
||||||
|
|
||||||
// logging
|
// logging
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
|
223
src/mm/addr.rs
223
src/mm/addr.rs
@ -1,223 +0,0 @@
|
|||||||
use core::fmt::{Debug, Formatter, LowerHex, Result, UpperHex};
|
|
||||||
use core::hash::Hash;
|
|
||||||
use core::ops::{Add, AddAssign, Sub, SubAssign};
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn align_up(addr: usize, align: usize) -> usize {
|
|
||||||
(addr + align - 1) & !(align - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn align_down(addr: usize, align: usize) -> usize {
|
|
||||||
addr & !(align - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PhysAddr(pub usize);
|
|
||||||
|
|
||||||
pub struct VirtAddr(pub usize);
|
|
||||||
|
|
||||||
pub trait AddressOps {
|
|
||||||
fn as_u32(&self) -> u32;
|
|
||||||
fn as_u64(&self) -> u64;
|
|
||||||
fn as_usize(&self) -> usize;
|
|
||||||
fn align_up<T>(&self, align: T) -> Self
|
|
||||||
where
|
|
||||||
T: Into<usize>;
|
|
||||||
fn align_down<T>(&self, align: T) -> Self
|
|
||||||
where
|
|
||||||
T: Into<usize>;
|
|
||||||
fn is_aligned<T>(&self, align: T) -> bool
|
|
||||||
where
|
|
||||||
T: Into<usize> + Copy,
|
|
||||||
{
|
|
||||||
if align.into().is_power_of_two() {
|
|
||||||
self.as_usize() & (align.into() - 1) == 0
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AddressOps for PhysAddr {
|
|
||||||
fn as_u32(&self) -> u32 {
|
|
||||||
self.0 as u32
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_u64(&self) -> u64 {
|
|
||||||
self.0 as u64
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_usize(&self) -> usize {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn align_up<T>(&self, align: T) -> Self
|
|
||||||
where
|
|
||||||
T: Into<usize>,
|
|
||||||
{
|
|
||||||
PhysAddr(align_up(self.0, align.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn align_down<T>(&self, align: T) -> Self
|
|
||||||
where
|
|
||||||
T: Into<usize>,
|
|
||||||
{
|
|
||||||
PhysAddr(align_down(self.0, align.into()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AddressOps for VirtAddr {
|
|
||||||
fn as_u32(&self) -> u32 {
|
|
||||||
self.0 as u32
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_u64(&self) -> u64 {
|
|
||||||
self.0 as u64
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_usize(&self) -> usize {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn align_up<T>(&self, align: T) -> Self
|
|
||||||
where
|
|
||||||
T: Into<usize>,
|
|
||||||
{
|
|
||||||
VirtAddr(align_up(self.0, align.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn align_down<T>(&self, align: T) -> Self
|
|
||||||
where
|
|
||||||
T: Into<usize>,
|
|
||||||
{
|
|
||||||
VirtAddr(align_down(self.0, align.into()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Add<usize> for PhysAddr {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
|
||||||
Self(self.0 + rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AddAssign<usize> for PhysAddr {
|
|
||||||
fn add_assign(&mut self, rhs: usize) {
|
|
||||||
*self = PhysAddr::from(self.0 + rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub<usize> for PhysAddr {
|
|
||||||
type Output = PhysAddr;
|
|
||||||
|
|
||||||
fn sub(self, rhs: usize) -> Self::Output {
|
|
||||||
PhysAddr(self.0 - rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SubAssign<usize> for PhysAddr {
|
|
||||||
fn sub_assign(&mut self, rhs: usize) {
|
|
||||||
*self = PhysAddr::from(self.0 - rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Add<usize> for VirtAddr {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
|
||||||
Self(self.0 + rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AddAssign<usize> for VirtAddr {
|
|
||||||
fn add_assign(&mut self, rhs: usize) {
|
|
||||||
*self = VirtAddr::from(self.0 + rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub<usize> for VirtAddr {
|
|
||||||
type Output = VirtAddr;
|
|
||||||
|
|
||||||
fn sub(self, rhs: usize) -> Self::Output {
|
|
||||||
VirtAddr(self.0 - rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SubAssign<usize> for VirtAddr {
|
|
||||||
fn sub_assign(&mut self, rhs: usize) {
|
|
||||||
*self = VirtAddr::from(self.0 - rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<usize> for PhysAddr {
|
|
||||||
fn from(addr: usize) -> Self {
|
|
||||||
PhysAddr(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PhysAddr> for usize {
|
|
||||||
fn from(addr: PhysAddr) -> Self {
|
|
||||||
addr.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<usize> for VirtAddr {
|
|
||||||
fn from(addr: usize) -> Self {
|
|
||||||
VirtAddr(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<VirtAddr> for usize {
|
|
||||||
fn from(addr: VirtAddr) -> Self {
|
|
||||||
addr.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for PhysAddr {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
|
||||||
write!(f, "PhysAddr({:#x})", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LowerHex for PhysAddr {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
|
||||||
write!(f, "{:#x}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpperHex for PhysAddr {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
|
||||||
write!(f, "{:#X}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for VirtAddr {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
|
||||||
write!(f, "VirtAddr({:#x})", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LowerHex for VirtAddr {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
|
||||||
write!(f, "{:#x}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpperHex for VirtAddr {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
|
||||||
write!(f, "{:#X}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for PhysAddr {
|
|
||||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.0.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for VirtAddr {
|
|
||||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.0.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
pub mod addr;
|
|
||||||
pub mod page;
|
|
@ -1,53 +0,0 @@
|
|||||||
use crate::mm::addr::{AddressOps, PhysAddr, VirtAddr};
|
|
||||||
use bitflags::bitflags;
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum PagingError {
|
|
||||||
AddressNotAligned,
|
|
||||||
}
|
|
||||||
|
|
||||||
bitflags! {
|
|
||||||
pub struct MapAttr: usize {
|
|
||||||
const READABLE = 1 << 1;
|
|
||||||
const WRITABLE = 1 << 2;
|
|
||||||
const EXECUTABLE = 1 << 3;
|
|
||||||
const USER_ACCESSIBLE = 1 << 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PageTableEntry {
|
|
||||||
fn new_page(paddr: PhysAddr, attr: MapAttr) -> Self;
|
|
||||||
fn new_table(paddr: PhysAddr) -> Self;
|
|
||||||
|
|
||||||
fn addr(&self) -> PhysAddr;
|
|
||||||
fn attr(&self) -> MapAttr;
|
|
||||||
|
|
||||||
fn set_addr(&mut self, addr: PhysAddr);
|
|
||||||
fn set_attr(&mut self, attr: MapAttr);
|
|
||||||
|
|
||||||
fn is_valid(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PageSize {
|
|
||||||
// Arch should implement this
|
|
||||||
// For example, 4KiB / 2MiB / 1GiB in sv39
|
|
||||||
|
|
||||||
const SIZE: usize;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Page<S: PageSize> {
|
|
||||||
start_address: VirtAddr,
|
|
||||||
size: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: PageSize> Page<S> {
|
|
||||||
pub const SIZE: usize = S::SIZE;
|
|
||||||
|
|
||||||
pub fn new(addr: VirtAddr) -> Self {
|
|
||||||
Self {
|
|
||||||
start_address: addr.align_down(Self::SIZE),
|
|
||||||
size: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user