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);
}
}
|