aboutsummaryrefslogtreecommitdiff
path: root/mirai/kagami/create/create.zig
blob: 8e7bad346f64dc18ad1ea24c2b8acf48a54b546c (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
//! Create Kagami

const common = @import("../../../common/common.zig");
const pmm = @import("../../pmm/pmm.zig");
const types = @import("../types/types.zig");
const state = @import("../state.zig");
const tables = @import("../tables/tables.zig");

const AllocationError = common.errors.memory.AllocationError;
const Kagami = types.Kagami;
const Table = types.Table;

var kagami_pool: [256]Kagami = undefined;
var kagami_pool_bitmap: [32]u8 = [_]u8{0} ** 32;

pub fn create() AllocationError!*Kagami {
    const pml4_physical = try pmm.allocate_page_zeroed();

    const kagami = allocate_kagami_struct() orelse {
        pmm.free_page(pml4_physical);
        return AllocationError.OutOfMemory;
    };

    kagami.* = Kagami{
        .pml4_physical = pml4_physical,
        .reference_count = 1,
        .resident_pages = 0,
        .wired_pages = 0,
        .table_pages = 1,
        .lock = false,
    };

    const kernel_kagami = state.get_kernel_kagami();
    const new_pml4 = tables.get_pml4(pml4_physical);
    const kernel_pml4 = tables.get_pml4(kernel_kagami.pml4_physical);

    new_pml4.copy_kernel_entries(kernel_pml4);

    return kagami;
}

fn allocate_kagami_struct() ?*Kagami {
    var index: usize = 0;
    while (index < 256) : (index += 1) {
        const byte_index = index / 8;
        const bit_index: u3 = @truncate(index % 8);

        if ((kagami_pool_bitmap[byte_index] & (@as(u8, 1) << bit_index)) == 0) {
            kagami_pool_bitmap[byte_index] |= (@as(u8, 1) << bit_index);
            return &kagami_pool[index];
        }
    }
    return null;
}

pub fn free_kagami_struct(kagami: *Kagami) void {
    const base_ptr: usize = @intFromPtr(&kagami_pool[0]);
    const kagami_ptr: usize = @intFromPtr(kagami);

    if (kagami_ptr < base_ptr) return;

    const offset = kagami_ptr - base_ptr;
    const index = offset / @sizeOf(Kagami);

    if (index >= 256) return;

    const byte_index = index / 8;
    const bit_index: u3 = @truncate(index % 8);

    kagami_pool_bitmap[byte_index] &= ~(@as(u8, 1) << bit_index);
}