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
mod stream;
mod vmar;
mod vmo;
pub use self::{stream::*, vmar::*, vmo::*};
use super::{ZxError, ZxResult};
use alloc::sync::Arc;
pub use kernel_hal::{CachePolicy, MMUFlags};
use lazy_static::*;
pub type PhysAddr = usize;
pub type VirtAddr = usize;
pub type DevVAddr = usize;
pub const PAGE_SIZE: usize = 0x1000;
pub const PAGE_SIZE_LOG2: usize = 12;
pub fn page_aligned(x: usize) -> bool {
check_aligned(x, PAGE_SIZE)
}
pub fn check_aligned(x: usize, align: usize) -> bool {
x % align == 0
}
pub fn pages(size: usize) -> usize {
ceil(size, PAGE_SIZE)
}
pub fn ceil(x: usize, align: usize) -> usize {
x.wrapping_add(align - 1) / align
}
pub fn roundup_pages(size: usize) -> usize {
pages(size) * PAGE_SIZE
}
pub fn round_down_pages(size: usize) -> usize {
size / PAGE_SIZE * PAGE_SIZE
}
lazy_static! {
pub static ref KERNEL_ASPACE: Arc<VmAddressRegion> = VmAddressRegion::new_kernel();
}
pub fn kernel_allocate_physical(
size: usize,
paddr: PhysAddr,
mmu_flags: MMUFlags,
cache_policy: CachePolicy,
) -> ZxResult<VirtAddr> {
if !page_aligned(paddr) {
return Err(ZxError::INVALID_ARGS);
}
let size = roundup_pages(size);
let vmo = VmObject::new_physical(paddr, pages(size));
vmo.set_cache_policy(cache_policy)?;
let flags = mmu_flags - MMUFlags::CACHE_1 - MMUFlags::CACHE_2;
KERNEL_ASPACE.map(None, vmo, 0, size, flags)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_round_pages() {
assert_eq!(roundup_pages(0), 0);
assert_eq!(roundup_pages(core::usize::MAX), 0);
assert_eq!(
roundup_pages(core::usize::MAX - PAGE_SIZE + 1),
core::usize::MAX - PAGE_SIZE + 1
);
assert_eq!(roundup_pages(PAGE_SIZE * 3 - 1), PAGE_SIZE * 3);
}
}