mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-27 21:58:20 +00:00
ke: rework kernel initialization
This commit is contained in:
+4
-9
@@ -11,8 +11,7 @@ const rtl = @import("rtl");
|
||||
// XXX
|
||||
const fbconsole = @import("../dev/fbconsole.zig");
|
||||
|
||||
export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
|
||||
ke.init(boot_info);
|
||||
pub fn init() void {
|
||||
mm.init();
|
||||
ps.init();
|
||||
|
||||
@@ -23,11 +22,11 @@ export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
|
||||
exp.console.init();
|
||||
exp.string.init();
|
||||
|
||||
if (boot_info.cmdline) |cline| {
|
||||
if (r.boot_info.cmdline) |cline| {
|
||||
if (rtl.cmdline.get_string(cline, "test")) |tst| {
|
||||
// Run a test if specified.
|
||||
if (r.tests.tests.get(tst)) |func| {
|
||||
const t = ps.thread.create_kernel(ke.Thread.Priority.default, func, boot_info) catch @panic("oom");
|
||||
const t = ps.thread.create_kernel(ke.Thread.Priority.default, func, r.boot_info) catch @panic("oom");
|
||||
ke.sched.enqueue(&t.kern);
|
||||
} else {
|
||||
std.log.info("invalid test: \"{s}\"", .{tst});
|
||||
@@ -35,11 +34,7 @@ export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
|
||||
}
|
||||
}
|
||||
|
||||
if (boot_info.framebuffer != null) {
|
||||
if (r.boot_info.framebuffer != null) {
|
||||
// fbconsole.init(boot_info);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
std.atomic.spinLoopHint();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ pub const DelayedWorkItem = p.work.DelayedWorkItem;
|
||||
pub const Console = p.console.Console;
|
||||
pub const InternedString = p.string.InternedString;
|
||||
|
||||
pub const init = p.init;
|
||||
|
||||
pub const work = struct {
|
||||
pub const enqueue = p.work.enqueue;
|
||||
pub const enqueue_in = p.work.enqueue_in;
|
||||
|
||||
@@ -26,6 +26,7 @@ const ThreadFrame = extern struct {
|
||||
extern fn asm_thread_entry() void;
|
||||
|
||||
extern fn do_context_switch(old: *ThreadContext, new: *ThreadContext, lock: *u8, switching: *bool) callconv(.c) void;
|
||||
extern fn do_context_load(td: *ThreadContext) callconv(.c) void;
|
||||
|
||||
pub const ThreadContext = extern struct {
|
||||
rsp: u64 align(1),
|
||||
@@ -35,7 +36,6 @@ pub const ThreadContext = extern struct {
|
||||
const entry_fn: *const fn (?*anyopaque) void = @ptrFromInt(entry);
|
||||
ke.ipl.lower(.Passive);
|
||||
entry_fn(@ptrFromInt(arg));
|
||||
// TODO: This shouldn't be reached!!!
|
||||
}
|
||||
|
||||
pub fn init(stack: r.VAddr, stack_size: usize, entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) @This() {
|
||||
@@ -62,6 +62,10 @@ pub const ThreadContext = extern struct {
|
||||
const thread: *ke.Thread = @alignCast(@fieldParentPtr("context", self));
|
||||
do_context_switch(self, new, &thread.lock.inner.locked.raw, &thread.switching.raw);
|
||||
}
|
||||
|
||||
pub fn load(self: *ThreadContext) callconv(.c) void {
|
||||
do_context_load(self);
|
||||
}
|
||||
};
|
||||
|
||||
inline fn percpu_ptr_for(variable: anytype, cpu: u32) @TypeOf(variable) {
|
||||
|
||||
@@ -91,16 +91,17 @@ pub fn ap_entry(cpu_id: u32, booted: *std.atomic.Value(usize)) noreturn {
|
||||
ki.cpu.init_cpu(cpu_id);
|
||||
pl.impl.init_ap();
|
||||
|
||||
ki.sched.percpu.local().current_thread = pl.impl.smp.start_thread.local().*;
|
||||
const sched = ki.sched.percpu.local();
|
||||
|
||||
sched.current_thread = pl.impl.smp.start_thread.local().*;
|
||||
sched.idle_thread = sched.current_thread;
|
||||
|
||||
amd64.sti();
|
||||
|
||||
_ = booted.fetchAdd(1, .monotonic);
|
||||
ke.ipl.lower(.Passive);
|
||||
|
||||
while (true) {
|
||||
std.atomic.spinLoopHint();
|
||||
}
|
||||
ki.sched.idle(null);
|
||||
}
|
||||
|
||||
var initial_offsets: [1]usize = .{0};
|
||||
|
||||
@@ -166,6 +166,19 @@ do_context_switch:
|
||||
pop %r15
|
||||
ret
|
||||
|
||||
.global do_context_load
|
||||
do_context_load:
|
||||
/* Load new stack pointer. */
|
||||
mov (%rdi), %rsp
|
||||
|
||||
/* Restore callee-saved registers. */
|
||||
pop %rbp
|
||||
pop %rbx
|
||||
pop %r12
|
||||
pop %r13
|
||||
pop %r14
|
||||
pop %r15
|
||||
ret
|
||||
|
||||
.extern thread_entry
|
||||
.global asm_thread_entry
|
||||
|
||||
+21
-14
@@ -7,10 +7,24 @@ const ki = ke.private;
|
||||
const ex = r.ex;
|
||||
|
||||
var thread0: ke.Thread = undefined;
|
||||
var stack: [r.kib(16)]u8 align(16) = undefined;
|
||||
|
||||
pub fn init(boot_info: *r.BootInfo) linksection(r.init) void {
|
||||
export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
|
||||
r.boot_info = boot_info;
|
||||
|
||||
thread0.init(
|
||||
boot_info.kernel_stack,
|
||||
boot_info.kernel_stack_size,
|
||||
ke.Thread.Priority.idle_low,
|
||||
init,
|
||||
null,
|
||||
);
|
||||
thread0.pinned = true;
|
||||
|
||||
// Jump into the thread.
|
||||
thread0.context.load();
|
||||
}
|
||||
|
||||
pub fn init(_: ?*anyopaque) linksection(r.init) void {
|
||||
ke.ncpus = 1;
|
||||
ki.impl.early_init();
|
||||
ki.tunable.init();
|
||||
@@ -20,18 +34,11 @@ pub fn init(boot_info: *r.BootInfo) linksection(r.init) void {
|
||||
ki.cpu.init_cpu(0);
|
||||
ki.turnstile.init_turnstiles();
|
||||
|
||||
thread0.init(
|
||||
@intFromPtr(&stack),
|
||||
r.kib(16),
|
||||
ke.Thread.Priority.idle_low,
|
||||
ki.sched.idle,
|
||||
null,
|
||||
);
|
||||
thread0.priority = 0;
|
||||
thread0.base_priority = 0;
|
||||
thread0.pinned = true;
|
||||
|
||||
ki.sched.percpu.local().current_thread = &thread0;
|
||||
ki.sched.percpu.local().idle_thread = &thread0;
|
||||
|
||||
std.log.info("Zag for {s} ({s}), cmdline is \"{?s}\"", .{ pl.name, arch.name, boot_info.cmdline });
|
||||
std.log.info("Zag for {s} ({s}), cmdline is \"{?s}\"", .{ pl.name, arch.name, r.boot_info.cmdline });
|
||||
|
||||
ex.init();
|
||||
ki.sched.idle(null);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,9 @@ pub const Framebuffer = struct {
|
||||
// Kept in sync with the kernel
|
||||
pub const page_struct_size = 16;
|
||||
|
||||
kernel_stack: usize,
|
||||
kernel_stack_size: usize,
|
||||
|
||||
/// RSDP on ACPI machines
|
||||
rsdp: ?usize,
|
||||
|
||||
|
||||
@@ -93,6 +93,9 @@ pub fn loader_main(kernel: *anyopaque) void {
|
||||
|
||||
const memmap = &r.loader_info.memory_map;
|
||||
|
||||
r.loader_info.kernel_stack = stack;
|
||||
r.loader_info.kernel_stack_size = stack_size;
|
||||
|
||||
// Finally, sort the memory map once we're done allocating everything.
|
||||
std.mem.sort(Entry, memmap.entries[0..memmap.entry_count], {}, cmp_entries);
|
||||
|
||||
|
||||
+1
-1
@@ -172,7 +172,7 @@ pub const PMap = struct {
|
||||
|
||||
/// Choose the largest page size that satisfies the alignment and
|
||||
/// size constraints of the current VA, PA, and remaining byte count.
|
||||
/// Tries large pages first; falls back to 4K.
|
||||
/// Tries large pages first, falls back to 4K.
|
||||
fn choose_target_level(self: *Cursor, pa: usize, remain: usize) usize {
|
||||
var level: usize = num_levels;
|
||||
while (level > 0) {
|
||||
|
||||
@@ -110,7 +110,6 @@ pub fn init() linksection(r.init) void {
|
||||
const stack_top = @intFromPtr(mm.heap.alloc(r.kib(32), .DontWaitForMemory) catch @panic("Failed to allocate AP stack")) + r.kib(32);
|
||||
|
||||
start_stack.remote(@intCast(cpu_id)).* = stack_top & ~@as(usize, 15);
|
||||
|
||||
start_thread.remote(@intCast(cpu_id)).* = make_thread(@ptrCast(&ap_entry), stack_top - r.kib(32));
|
||||
|
||||
rtl.barrier.fence(.release);
|
||||
|
||||
+1
-1
@@ -67,5 +67,5 @@ pub const panic = std.debug.FullPanic(ke.panic);
|
||||
|
||||
comptime {
|
||||
// Ensure the entry point is linked in.
|
||||
_ = @import("ex/init.zig");
|
||||
_ = @import("kern/init.zig");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user