blob: e8d9a5e0b584a91ed947b78a6e27a81a3d2bd032 (
plain)
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
|
//! Destroy Kagami
const pmm = @import("../../pmm/pmm.zig");
const types = @import("../types/types.zig");
const state = @import("../state.zig");
const tables = @import("../tables/tables.zig");
const create_module = @import("../create/create.zig");
const Kagami = types.Kagami;
const Table = types.Table;
pub fn destroy(kagami: *Kagami) void {
if (kagami.is_kernel()) {
return;
}
const remaining = kagami.decrement_reference();
if (remaining > 0) {
return;
}
free_user_tables(kagami);
pmm.free_page(kagami.pml4_physical);
create_module.free_kagami_struct(kagami);
}
fn free_user_tables(kagami: *Kagami) void {
const pml4 = tables.get_pml4(kagami.pml4_physical);
var pml4_index: u9 = 0;
while (pml4_index < 256) : (pml4_index += 1) {
const pml4_entry = pml4.get_entry(pml4_index);
if (!pml4_entry.is_present()) continue;
const pdpt = tables.get_table_from_physical(pml4_entry.get_physical_address());
free_pdpt(pdpt);
pmm.free_page(pml4_entry.get_physical_address());
pml4_entry.clear();
}
}
fn free_pdpt(pdpt: *Table) void {
var pdpt_index: u9 = 0;
while (pdpt_index < 512) : (pdpt_index += 1) {
const pdpt_entry = pdpt.get_entry(pdpt_index);
if (!pdpt_entry.is_present()) continue;
if (pdpt_entry.is_huge()) continue;
const pd = tables.get_table_from_physical(pdpt_entry.get_physical_address());
free_pd(pd);
pmm.free_page(pdpt_entry.get_physical_address());
pdpt_entry.clear();
}
}
fn free_pd(pd: *Table) void {
var pd_index: u9 = 0;
while (pd_index < 512) : (pd_index += 1) {
const pd_entry = pd.get_entry(pd_index);
if (!pd_entry.is_present()) continue;
if (pd_entry.is_huge()) continue;
pmm.free_page(pd_entry.get_physical_address());
pd_entry.clear();
}
}
pub fn reference(kagami: *Kagami) void {
kagami.increment_reference();
}
pub fn release(kagami: *Kagami) void {
destroy(kagami);
}
|