rusty_mos/memory/marcos.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
//! Definitions of the conversion macros for the pages and memory.
/// Get the page number through the page object.
#[macro_export]
macro_rules! page2ppn {
($pp:expr, $pages:expr; $t:ty) => {{
(($pp as usize - $pages as usize) / core::mem::size_of::<$t>()) as usize
}};
}
/// Get the physical address of the page object.
///
/// See also: [pa2page](crate::pa2page)
#[macro_export]
macro_rules! page2pa {
($pp:expr, $pages:expr; $t:ty) => {{
$crate::page2ppn!($pp, $pages; $t) << $crate::memory::regions::PGSHIFT
}};
}
/// Get the kernel virtual address of the page object.
#[macro_export]
macro_rules! page2kva {
($pp:expr, $pages:expr; $t:ty) => {{
$crate::KADDR!($crate::page2pa!($pp, $pages; $t))
}};
}
/// Get the page object of the phisical address.
///
/// See also: [page2pa]
#[macro_export]
macro_rules! pa2page {
($pa:expr, $pages:expr; $t:ty) => {{
let ppn = $crate::PPN!($pa) as usize;
// assert!(ppn >= npage);
$pages as usize + ppn * core::mem::size_of::<$t>()
}};
}
/// Get the physical address of the given virtual address. This macro will
/// look up the page table to do the transmition.
///
/// `-1` or `0xffffffff` will be spawned if the address is not found or
/// the page table entry is invalid.
///
/// **ATTENTION**! The address spawned will ignore the in-page offset.
#[macro_export]
macro_rules! va2pa {
($pgdir:expr, $va:expr) => {{
let pgdir = $crate::ARRAY_PTR!($pgdir; $crate::PDX!($va), $crate::kern::pmap::Pde);
if 0 == (*pgdir & $crate::memory::regions::PTE_V) {
!0
} else {
let p = $crate::KADDR!($crate::PTE_ADDR!(*pgdir)) as *mut $crate::kern::pmap::Pte;
if 0 == (*$crate::ARRAY_PTR!(p; $crate::PTX!($va), $crate::kern::pmap::Pte) & $crate::memory::regions::PTE_V) {
!0
} else {
$crate::PTE_ADDR!(*$crate::ARRAY_PTR!(p; $crate::PTX!($va), $crate::kern::pmap::Pte) as u32) as usize
}
}
}};
}
/// Get the physical address of the virtual address in **kernel segment**
///
/// Someway the opposite of [KADDR](crate::KADDR)
///
/// # Panic
/// Assertion will fail if the virtual address is not in the **kernel
/// segment**.
#[macro_export]
macro_rules! PADDR {
($x: expr) => {{
assert!($x >= 0x80000000);
$x - 0x80000000
}};
}
/// Get the virtual address (in **kernel segment**) from the physical address
///
/// Someway the opposite of [PADDR]
///
/// # Panic
/// **NOT IMPLEMENTED**
/// Assertion will fail if the virtual address is not in the **kernel
/// segment**.
#[macro_export]
macro_rules! KADDR {
($x: expr) => {{
// assert!(($x >> 12) < npage);
$x + 0x80000000
}};
}
/// Get the address(or the frame number etc.) from the page table entry (PTE)
#[macro_export]
macro_rules! PTE_ADDR {
($pte: expr) => {{
$pte & !0xFFF
}};
}
/// Get the **Page Directory Offset** from the virtual address
///
/// See also: [PTX](crate::PTX)
#[macro_export]
macro_rules! PDX {
($va: expr) => {{
($va >> $crate::memory::regions::PDSHIFT) & 0x03FF
}};
}
/// Get the **Page Table Offset** from the virtual address
///
/// See also: [PDX]
#[macro_export]
macro_rules! PTX {
($va: expr) => {{
($va >> $crate::memory::regions::PGSHIFT) & 0x03FF
}};
}
/// Get the Page Number from the physical address
#[macro_export]
macro_rules! PPN {
($pa: expr) => {
$pa >> $crate::memory::regions::PGSHIFT
};
}