Support more operations on PageFlags
This commit is contained in:
+55
-1
@@ -1,4 +1,7 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::{
|
||||
fmt,
|
||||
marker::PhantomData
|
||||
};
|
||||
|
||||
use crate::Arch;
|
||||
|
||||
@@ -21,6 +24,18 @@ impl<A: Arch> PageFlags<A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn new_table() -> Self {
|
||||
unsafe {
|
||||
Self::from_data(
|
||||
// Flags set to present, kernel space, read-only, no-execute by default
|
||||
A::ENTRY_FLAG_DEFAULT_TABLE |
|
||||
A::ENTRY_FLAG_READONLY |
|
||||
A::ENTRY_FLAG_NO_EXEC
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn from_data(data: usize) -> Self {
|
||||
Self { data, phantom: PhantomData }
|
||||
@@ -31,6 +46,7 @@ impl<A: Arch> PageFlags<A> {
|
||||
self.data
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn custom_flag(mut self, flag: usize, value: bool) -> Self {
|
||||
if value {
|
||||
@@ -41,11 +57,28 @@ impl<A: Arch> PageFlags<A> {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn has_flag(&self, flag: usize) -> bool {
|
||||
self.data & flag == flag
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn has_present(&self) -> bool {
|
||||
self.has_flag(A::ENTRY_FLAG_PRESENT)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn user(self, value: bool) -> Self {
|
||||
self.custom_flag(A::ENTRY_FLAG_USER, value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn has_user(&self) -> bool {
|
||||
self.has_flag(A::ENTRY_FLAG_USER)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn write(self, value: bool) -> Self {
|
||||
// Architecture may use readonly or readwrite, support either
|
||||
@@ -53,6 +86,13 @@ impl<A: Arch> PageFlags<A> {
|
||||
.custom_flag(A::ENTRY_FLAG_READWRITE, value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn has_write(&self) -> bool {
|
||||
// Architecture may use readonly or readwrite, support either
|
||||
self.data & (A::ENTRY_FLAG_READONLY | A::ENTRY_FLAG_READWRITE) == A::ENTRY_FLAG_READWRITE
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn execute(self, value: bool) -> Self {
|
||||
//TODO: write xor execute?
|
||||
@@ -60,4 +100,18 @@ impl<A: Arch> PageFlags<A> {
|
||||
self.custom_flag(A::ENTRY_FLAG_NO_EXEC, !value)
|
||||
.custom_flag(A::ENTRY_FLAG_EXEC, value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn has_execute(&self) -> bool {
|
||||
// Architecture may use no exec or exec, support either
|
||||
self.data & (A::ENTRY_FLAG_NO_EXEC | A::ENTRY_FLAG_EXEC) == A::ENTRY_FLAG_EXEC
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Arch> fmt::Debug for PageFlags<A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("PageFlags")
|
||||
.field("data", &self.data)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user