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
use super::{PageTableShuttle, Pos, Visitor};
use crate::{Pte, VmMeta, PPN, VPN};
use core::{fmt, marker::PhantomData};
#[rustfmt::skip]
impl<Meta: VmMeta, F: Fn(PPN<Meta>) -> VPN<Meta>> fmt::Debug
for PageTableShuttle<Meta, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.walk(FmtVisitor {
f,
max_level: 0,
new_line: true,
_phantom: PhantomData,
});
Ok(())
}
}
struct FmtVisitor<'f1, 'f2, Meta: VmMeta> {
f: &'f1 mut fmt::Formatter<'f2>,
max_level: usize,
new_line: bool,
_phantom: PhantomData<Meta>,
}
impl<'f1, 'f2, Meta: VmMeta> Visitor<Meta> for FmtVisitor<'f1, 'f2, Meta> {
#[inline]
fn start(&mut self, pos: Pos<Meta>) -> Pos<Meta> {
self.max_level = pos.level;
pos
}
fn arrive(&mut self, pte: Pte<Meta>, target_hint: Pos<Meta>) -> Pos<Meta> {
let level = target_hint.level;
if pte.is_valid() {
if self.new_line {
for _ in level..self.max_level {
for _ in 0..18 {
write!(self.f, " ").unwrap();
}
write!(self.f, " - ").unwrap();
}
} else if level < self.max_level {
write!(self.f, " - ").unwrap();
}
write!(self.f, "{:#018x}", pte.ppn().val()).unwrap();
if pte.is_leaf() {
for _ in 0..level {
write!(self.f, " - ").unwrap();
for _ in 0..18 {
write!(self.f, "-").unwrap();
}
}
let range = target_hint.vpn.vaddr_range(target_hint.level);
write!(
self.f,
" {:#018x}..{:#018x} (",
range.start.val(),
range.end.val()
)
.unwrap();
Meta::fmt_flags(self.f, pte.flags().0).unwrap();
write!(self.f, ")").unwrap();
} else {
self.new_line = false;
return target_hint.down();
}
}
let vpn = target_hint.next().vpn;
let next_level = vpn.align_level().min(self.max_level);
if pte.is_valid() || (!self.new_line && next_level > level) {
self.new_line = true;
writeln!(self.f).unwrap();
}
Pos::new(vpn, next_level)
}
#[inline]
fn meet(&mut self, _level: usize, _pte: Pte<Meta>, _target_hint: Pos<Meta>) -> Pos<Meta> {
unreachable!()
}
}