-
-
Notifications
You must be signed in to change notification settings - Fork 188
Expand file tree
/
Copy pathmemory.rs
More file actions
120 lines (93 loc) · 3.28 KB
/
memory.rs
File metadata and controls
120 lines (93 loc) · 3.28 KB
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
// SPDX-License-Identifier: MIT OR Apache-2.0
use alloc::vec::Vec;
use uefi::boot::{self, AllocateType};
use uefi::mem::memory_map::{MemoryMap, MemoryMapMut, MemoryType};
use uefi_raw::table::boot::PAGE_SIZE;
pub fn test() {
info!("Testing memory functions");
test_allocate_pages();
test_allocate_pool();
vec_alloc();
alloc_alignment();
test_memory_map();
}
fn test_allocate_pages() {
let num_pages = 3;
let mut ptr =
boot::allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, num_pages).unwrap();
let buffer = unsafe { ptr.as_mut() };
assert_eq!(
buffer.as_ptr().align_offset(PAGE_SIZE),
0,
"Page pointer is not page-aligned"
);
// Verify the page can be written to.
{
buffer[0] = 0xff;
buffer[4095] = 0xff;
buffer[5095] = 0xff;
assert_eq!(buffer[0], 0xff);
assert_eq!(buffer[4095], 0xff);
assert_eq!(buffer[5095], 0xff);
}
unsafe { boot::free_pages(ptr.cast(), num_pages) }.unwrap();
}
fn test_allocate_pool() {
let mut ptr = boot::allocate_pool(MemoryType::LOADER_DATA, 10).unwrap();
let buffer = unsafe { ptr.as_mut() };
// Verify the allocation can be written to.
{
buffer[0] = 0xff;
buffer[9] = 0xff;
assert_eq!(buffer[0], 0xff);
assert_eq!(buffer[9], 0xff);
}
unsafe { boot::free_pool(ptr.cast()) }.unwrap();
}
// Simple test to ensure our custom allocator works with the `alloc` crate.
fn vec_alloc() {
info!("Allocating a vector through the `alloc` crate");
#[allow(clippy::useless_vec)]
let mut values = vec![-5, 16, 23, 4, 0];
values.sort_unstable();
assert_eq!(values[..], [-5, 0, 4, 16, 23], "Failed to sort vector");
}
// Simple test to ensure our custom allocator works with correct alignment.
fn alloc_alignment() {
info!("Allocating a structure with alignment to 0x100");
#[repr(align(0x100))]
struct Block(
// Ignore warning due to field not being read.
#[allow(dead_code)] [u8; 0x100],
);
let value = vec![Block([1; 0x100])];
assert_eq!(value.as_ptr() as usize % 0x100, 0, "Wrong alignment");
}
fn test_memory_map() {
info!("Testing memory map functions");
let mut memory_map =
boot::memory_map(MemoryType::LOADER_DATA).expect("Failed to retrieve UEFI memory map");
memory_map.sort();
// Collect the descriptors into a vector
let descriptors = memory_map.entries().copied().collect::<Vec<_>>();
// Ensured we have at least one entry.
// Real memory maps usually have dozens of entries.
assert!(!descriptors.is_empty(), "Memory map is empty");
let mut curr_value = descriptors[0];
for value in descriptors.iter().skip(1) {
if value.phys_start <= curr_value.phys_start {
panic!("memory map sorting failed");
}
curr_value = *value;
}
// This is pretty much a basic sanity test to ensure returned memory
// isn't filled with random values.
let first_desc = descriptors[0];
#[cfg(target_arch = "x86_64")]
{
let phys_start = first_desc.phys_start;
assert_eq!(phys_start, 0, "Memory does not start at address 0");
}
let page_count = first_desc.page_count;
assert!(page_count != 0, "Memory map entry has size zero");
}