aboutsummaryrefslogtreecommitdiff
path: root/src/process.zig
blob: d26faac51b69b4ee93c68c55e7ff26f3b7039be4 (plain) (blame)
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
// SPDX-FileCopyrightText: 2024 Himbeer <himbeer@disroot.org>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

const std=@import("std");

const interrupts = @import("interrupts.zig");
const paging = @import("paging.zig");

const num_stack_pages = 2;

var next_pid = 0;

pub const State = enum {
    waiting,
    active,
    sleeping,
    terminated,
};

pub const Info = extern struct {
    id: u32,
    trap_frame: interrupts.TrapFrame,
    stack: [*]u8,
    pc: usize,
    page_table: *paging.Table,
    state: State,

    pub fn destroy(self: *Info) !void {
        try paging.free(self.stack);
        try self.page_table.unmap();
        try paging.free(self.page_table);
    }
};

pub fn new(entry: *fn() void) !Info {
    const stack = try paging.alloc(num_stack_pages);
    errdefer paging.free(stack);

    const procmem = try paging.zeroedAlloc(1);
    errdefer paging.free(procmem);

    const proc = .{
        id= next_pid++,
        trap_frame= std.mem.zeroInit(interrupts.TrapFrame),
        stack= stack,
        pc= @ptrCast(entry),
        page_table= procmem,
        state= .waiting,
    };

    const stack_top = proc.stack + num_stack_pages * paging.page_size;
    proc.trap_frame.general_purpose_registers[2] = stack_top;

    try procmem.map(@intFromPtr(entry), @intFromPtr(entry), ., paging.EntryFlags.userReadExec);
    // Not using identityMapRange because this is going to be expanded for non-relocatable binaries.
    for (0..num_stack_pages) |page| {
        const vaddr = page * paging.page_size;
        const paddr = page * paging.page_size;

        try procmem.map(vaddr, paddr, paging.EntryFlags.userReadWrite, 0);
    }
}