|
|
@@ -4,9 +4,9 @@ use super::{
|
|
|
};
|
|
|
use crate::{
|
|
|
address::{AddrOps as _, VRange},
|
|
|
- paging::{Page, PageAccess, PageAlloc, PAGE_SIZE},
|
|
|
+ paging::{Page, PageAccess, PageAlloc, LEVEL0_PAGE_SIZE, LEVEL1_PAGE_SIZE, LEVEL2_PAGE_SIZE},
|
|
|
};
|
|
|
-use core::marker::PhantomData;
|
|
|
+use core::{marker::PhantomData, panic};
|
|
|
|
|
|
pub struct KernelIterator;
|
|
|
pub struct UserIterator;
|
|
|
@@ -60,6 +60,8 @@ where
|
|
|
X: PageAccess,
|
|
|
K: IteratorType<M>,
|
|
|
{
|
|
|
+ // from root to down: 0 1 2 3
|
|
|
+ level_in_array: usize,
|
|
|
remaining: usize,
|
|
|
|
|
|
indicies: [u16; 8],
|
|
|
@@ -78,13 +80,12 @@ where
|
|
|
K: IteratorType<M>,
|
|
|
{
|
|
|
fn parse_tables_starting_from(&mut self, idx_level: usize) {
|
|
|
- let levels_len = M::LEVELS.len();
|
|
|
|
|
|
for (idx, &pt_idx) in self
|
|
|
.indicies
|
|
|
.iter()
|
|
|
.enumerate()
|
|
|
- .take(levels_len - 1)
|
|
|
+ .take(self.level_in_array)
|
|
|
.skip(idx_level)
|
|
|
{
|
|
|
let [parent_table, child_table] = unsafe {
|
|
|
@@ -99,12 +100,20 @@ where
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- pub fn new(page_table: M::RawTable<'a>, range: VRange, alloc: A) -> Self {
|
|
|
+ pub fn new(page_table: M::RawTable<'a>, range: VRange, alloc: A, level_in_array: usize) -> Self {
|
|
|
let start = range.start().floor();
|
|
|
let end = range.end().ceil();
|
|
|
|
|
|
+ // not allow to modify root page table
|
|
|
+ let page_size = match level_in_array {
|
|
|
+ 1 => LEVEL2_PAGE_SIZE,
|
|
|
+ 2 => LEVEL1_PAGE_SIZE,
|
|
|
+ 3 => LEVEL0_PAGE_SIZE,
|
|
|
+ _ => panic!("Out of index"),
|
|
|
+ };
|
|
|
let mut me = Self {
|
|
|
- remaining: (end - start) / PAGE_SIZE,
|
|
|
+ level_in_array,
|
|
|
+ remaining: (end - start) / page_size,
|
|
|
indicies: [0; 8],
|
|
|
tables: [const { None }; 8],
|
|
|
alloc,
|
|
|
@@ -139,25 +148,25 @@ where
|
|
|
self.remaining -= 1;
|
|
|
}
|
|
|
|
|
|
- let len_levels = M::LEVELS.len();
|
|
|
-
|
|
|
- let retval = self.tables[len_levels - 1]
|
|
|
+ let retval = self.tables[self.level_in_array]
|
|
|
.as_mut()
|
|
|
.unwrap()
|
|
|
- .index_mut(self.indicies[len_levels - 1]);
|
|
|
+ .index_mut(self.indicies[self.level_in_array]);
|
|
|
|
|
|
let idx_level_start_updating = M::LEVELS
|
|
|
.iter()
|
|
|
.zip(self.indicies.iter_mut())
|
|
|
.enumerate()
|
|
|
.rev()
|
|
|
- .skip_while(|(_, (level, idx))| **idx == level.max_index())
|
|
|
+ .skip_while(|(i, (level, idx))| {
|
|
|
+ *i >= self.level_in_array && **idx == level.max_index()
|
|
|
+ })
|
|
|
.map(|(i, _)| i)
|
|
|
.next()
|
|
|
.expect("Index out of bounds");
|
|
|
|
|
|
self.indicies[idx_level_start_updating] += 1;
|
|
|
- self.indicies[idx_level_start_updating + 1..len_levels].fill(0);
|
|
|
+ self.indicies[idx_level_start_updating + 1..self.level_in_array].fill(0);
|
|
|
self.parse_tables_starting_from(idx_level_start_updating);
|
|
|
|
|
|
Some(retval)
|