Skip to content

Commit

Permalink
threads and trees
Browse files Browse the repository at this point in the history
Signed-off-by: TalonFloof <[email protected]>
  • Loading branch information
TalonFloof committed Nov 17, 2024
1 parent 8594d76 commit c0fef4a
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 9 deletions.
2 changes: 2 additions & 0 deletions kobold/hal/hal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub const debug = @import("debug/debug.zig");
pub const Writer = std.io.Writer(@TypeOf(.{}), error{}, arch.write);
pub const writer = Writer{ .context = .{} };
const team = @import("root").team;
const thread = @import("root").thread;

pub var hiList: ?[]*HartInfo = null;

Expand All @@ -37,6 +38,7 @@ pub export fn HALInitialize(stackTop: usize, dtb: *allowzero anyopaque) callconv
if (arch.memModel.layout == .Flat)
@panic("MMUless setups are not supported!");
team.Init();
thread.Init();
root.KoboldInit();
@panic("No Command");
}
Expand Down
2 changes: 1 addition & 1 deletion kobold/hal/x86_64/hart.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn startSMP() void {
cycles += 1;
if (cycles >= 50000000) {
std.log.err("Hart #{} took too long (potential triple fault on hart!)", .{hartCount});
hal.HALOops("X86_64 HAL Initialization Failure");
hal.HALOops("X86-64 HAL Initialization Failure");
}
std.atomic.spinLoopHint();
}
Expand Down
72 changes: 66 additions & 6 deletions kobold/hal/x86_64/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,15 @@ pub export fn HartStart(stackTop: usize) callconv(.C) noreturn {
}

fn ArchWriteString(_: @TypeOf(.{}), string: []const u8) error{}!usize {
var i: isize = 0;
while (i < string.len) : (i += 1) {
while ((io.inb(0x3F8 + 5) & 0x20) == 0)
std.atomic.spinLoopHint();
io.outb(0x3f8, string[@bitCast(i)]);
}
if (termCtx) |ctx| {
flanterm.flanterm_write(ctx, string.ptr, string.len);
} else {
var i: isize = 0;
while (i < string.len) : (i += 1) {
while ((io.inb(0x3F8 + 5) & 0x20) == 0)
std.atomic.spinLoopHint();
io.outb(0x3f8, string[@bitCast(i)]);
}
}
return string.len;
}
Expand Down Expand Up @@ -234,6 +235,65 @@ const Context = packed struct {
rsp: u64 = 0,
ss: u64 = 0,

pub fn SetMode(self: *Context, kern: bool) void {
if (kern) {
self.cs = 0x28;
self.ss = 0x30;
} else {
self.cs = 0x43;
self.ss = 0x3b;
}
self.rflags = 0x202;
}

pub fn SetReg(self: *Context, reg: u8, val: usize) void {
switch (reg) {
0 => {
self.rax = val;
},
1 => {
self.rdi = val;
},
2 => {
self.rsi = val;
},
3 => {
self.rdx = val;
},
4 => {
self.r10 = val;
},
5 => {
self.r8 = val;
},
6 => {
self.r9 = val;
},
128 => {
self.rip = val;
},
129 => {
self.rsp = val;
},
else => {},
}
}

pub fn GetReg(self: *Context, reg: u8) usize {
return switch (reg) {
0 => self.rax,
1 => self.rdi,
2 => self.rsi,
3 => self.rdx,
4 => self.r10,
5 => self.r8,
6 => self.r9,
128 => self.rip,
129 => self.rsp,
else => 0,
};
}

pub fn Dump(self: *Context) void {
std.log.debug(" rax 0x{x: <16} rbx 0x{x: <16} rcx 0x{x: <16}\n", .{ self.rax, self.rbx, self.rcx });
std.log.debug(" rdx 0x{x: <16} rsi 0x{x: <16} rdi 0x{x: <16}\n", .{ self.rdx, self.rsi, self.rdi });
Expand Down
2 changes: 1 addition & 1 deletion kobold/hal/x86_64/timer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ pub fn setDeadline(microsecs: u64) void {
}

pub fn getRemainingUs() u64 {
const count = 0xffffffff - apic.read(0x390);
const count = apic.read(0x390);
return @intFromFloat(@as(f64, @floatFromInt(count)) * (@as(f64, @floatFromInt(ticksPerSecond)) / 1000000.0));
}
1 change: 1 addition & 0 deletions kobold/kernel/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub const Spinlock = @import("perlib").Spinlock;
pub const elf = @import("elf.zig");
pub const pfn = @import("pfn.zig");
pub const team = @import("team.zig");
pub const thread = @import("thread.zig");

pub const kmain_log = std.log.scoped(.KernelMain);

Expand Down
37 changes: 37 additions & 0 deletions kobold/kernel/team.zig
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,44 @@ pub fn NewTeam(parent: ?*Team, name: []const u8) *Team {
return team;
}

pub fn GetTeamByID(id: i64) ?*Team {
const old = hal.arch.intControl(false);
teamLock.acquire();
if (teams.root != null) {
var x = teams.root;
while (x) |node| {
if (id < node.key.teamID) {
x = node.children[0];
} else if (id > node.key.teamID) {
x = node.children[1];
} else {
return node.key;
}
}
}
teamLock.release();
_ = hal.arch.intControl(old);
return null;
}

fn mttreeCommand(cmd: []const u8, iter: *std.mem.SplitIterator(u8, .sequence)) void {
_ = iter;
_ = cmd;
var ind = teams.inorderIterator();
while (ind.next()) |node| {
const team = node.key;
std.log.debug("Team {}: {s}\n", .{ team.teamID, team.name });
var tInd = team.threads.first;
while (tInd) |tNode| {
const thr: *thread.Thread = tNode.data;
std.log.debug(" |-- Thread {}: {s}\n", .{ thr.threadID, thr.name });
tInd = tNode.next;
}
}
}

pub fn Init() void {
std.log.info("Creating Kernel Team", .{});
kteam = NewTeam(null, "Kernel Team");
hal.debug.NewDebugCommand("mtTree", "Prints a tree of all of the threads and teams available", &mttreeCommand);
}
60 changes: 59 additions & 1 deletion kobold/kernel/thread.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ const hal = @import("root").hal;
const Spinlock = @import("root").Spinlock;
const team = @import("team.zig");
const RedBlackTree = @import("perlib").RedBlackTree;
const physmem = @import("physmem.zig");

pub const ThreadState = enum {
Embryo,
Runnable,
Running,
Waiting,
Expand Down Expand Up @@ -34,3 +34,61 @@ const ThreadTreeType = RedBlackTree(*Thread, struct {
return std.math.order(a.threadID, b.threadID);
}
}.compare);

pub var threads: ThreadTreeType = ThreadTreeType{};
var threadLock: Spinlock = .unaquired;
pub var nextThreadID: i64 = 1;

pub fn NewThread(
t: *team.Team,
name: []u8,
ip: usize,
sp: ?usize,
prior: usize,
) *Thread { // If SP is null then this is a kernel thread
const old = hal.arch.intControl(false);
threadLock.acquire();
var thread = @as(*Thread, @ptrCast(@alignCast(physmem.Allocate(@sizeOf(Thread), @alignOf(Thread)).?)));
@memset(@as([*]u8, @ptrFromInt(@intFromPtr(&thread.name)))[0..32], 0);
@memcpy(@as([*]u8, @ptrFromInt(@intFromPtr(&thread.name))), name);
thread.queueNode.data = thread;
thread.semaphoreNode.data = thread;
thread.teamListNode.data = thread;
thread.team = t;
thread.threadID = nextThreadID;
nextThreadID += 1;
thread.state = .Runnable;
thread.priority = prior;
const stack = @as([*]u8, @ptrFromInt(@intFromPtr(physmem.Allocate(8192, 4096).?)))[0..8192];
thread.kstack = stack;
if (sp == null) {
thread.gpContext.SetMode(true);
thread.gpContext.SetReg(129, @intFromPtr(stack.ptr) + stack.len);
} else {
thread.gpContext.SetMode(false);
thread.gpContext.SetReg(129, sp.?);
}
thread.gpContext.SetReg(128, ip);
t.threads.append(&thread.teamListNode);
threadLock.release();
_ = hal.arch.intControl(old);
return thread;
}

pub fn Init() void {
const kteam = team.GetTeamByID(1).?;
var i: i32 = 0;
var buf: [32]u8 = [_]u8{0} ** 32;
while (i < hal.hiList.?.len) : (i += 1) {
const name = std.fmt.bufPrint(buf[0..32], "Idle Thread #{}", .{i + 1}) catch {
@panic("Unable to parse string!");
};
_ = NewThread(kteam, name, @intFromPtr(&IdleThread), null, 0);
}
}

fn IdleThread() callconv(.C) void {
while (true) {
hal.arch.waitForInt();
}
}

0 comments on commit c0fef4a

Please sign in to comment.