mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-31 23:38:21 +00:00
ke: rework kernel initialization
This commit is contained in:
+4
-9
@@ -11,8 +11,7 @@ const rtl = @import("rtl");
|
|||||||
// XXX
|
// XXX
|
||||||
const fbconsole = @import("../dev/fbconsole.zig");
|
const fbconsole = @import("../dev/fbconsole.zig");
|
||||||
|
|
||||||
export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
|
pub fn init() void {
|
||||||
ke.init(boot_info);
|
|
||||||
mm.init();
|
mm.init();
|
||||||
ps.init();
|
ps.init();
|
||||||
|
|
||||||
@@ -23,11 +22,11 @@ export fn kmain(boot_info: *r.BootInfo) callconv(.c) void {
|
|||||||
exp.console.init();
|
exp.console.init();
|
||||||
exp.string.init();
|
exp.string.init();
|
||||||
|
|
||||||
if (boot_info.cmdline) |cline| {
|
if (r.boot_info.cmdline) |cline| {
|
||||||
if (rtl.cmdline.get_string(cline, "test")) |tst| {
|
if (rtl.cmdline.get_string(cline, "test")) |tst| {
|
||||||
// Run a test if specified.
|
// Run a test if specified.
|
||||||
if (r.tests.tests.get(tst)) |func| {
|
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);
|
ke.sched.enqueue(&t.kern);
|
||||||
} else {
|
} else {
|
||||||
std.log.info("invalid test: \"{s}\"", .{tst});
|
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);
|
// 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 Console = p.console.Console;
|
||||||
pub const InternedString = p.string.InternedString;
|
pub const InternedString = p.string.InternedString;
|
||||||
|
|
||||||
|
pub const init = p.init;
|
||||||
|
|
||||||
pub const work = struct {
|
pub const work = struct {
|
||||||
pub const enqueue = p.work.enqueue;
|
pub const enqueue = p.work.enqueue;
|
||||||
pub const enqueue_in = p.work.enqueue_in;
|
pub const enqueue_in = p.work.enqueue_in;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const ThreadFrame = extern struct {
|
|||||||
extern fn asm_thread_entry() void;
|
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_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 {
|
pub const ThreadContext = extern struct {
|
||||||
rsp: u64 align(1),
|
rsp: u64 align(1),
|
||||||
@@ -35,7 +36,6 @@ pub const ThreadContext = extern struct {
|
|||||||
const entry_fn: *const fn (?*anyopaque) void = @ptrFromInt(entry);
|
const entry_fn: *const fn (?*anyopaque) void = @ptrFromInt(entry);
|
||||||
ke.ipl.lower(.Passive);
|
ke.ipl.lower(.Passive);
|
||||||
entry_fn(@ptrFromInt(arg));
|
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() {
|
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));
|
const thread: *ke.Thread = @alignCast(@fieldParentPtr("context", self));
|
||||||
do_context_switch(self, new, &thread.lock.inner.locked.raw, &thread.switching.raw);
|
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) {
|
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);
|
ki.cpu.init_cpu(cpu_id);
|
||||||
pl.impl.init_ap();
|
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();
|
amd64.sti();
|
||||||
|
|
||||||
_ = booted.fetchAdd(1, .monotonic);
|
_ = booted.fetchAdd(1, .monotonic);
|
||||||
ke.ipl.lower(.Passive);
|
ke.ipl.lower(.Passive);
|
||||||
|
|
||||||
while (true) {
|
ki.sched.idle(null);
|
||||||
std.atomic.spinLoopHint();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var initial_offsets: [1]usize = .{0};
|
var initial_offsets: [1]usize = .{0};
|
||||||
|
|||||||
@@ -166,6 +166,19 @@ do_context_switch:
|
|||||||
pop %r15
|
pop %r15
|
||||||
ret
|
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
|
.extern thread_entry
|
||||||
.global asm_thread_entry
|
.global asm_thread_entry
|
||||||
|
|||||||
+21
-14
@@ -7,10 +7,24 @@ const ki = ke.private;
|
|||||||
const ex = r.ex;
|
const ex = r.ex;
|
||||||
|
|
||||||
var thread0: ke.Thread = undefined;
|
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;
|
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;
|
ke.ncpus = 1;
|
||||||
ki.impl.early_init();
|
ki.impl.early_init();
|
||||||
ki.tunable.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.cpu.init_cpu(0);
|
||||||
ki.turnstile.init_turnstiles();
|
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().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
|
// Kept in sync with the kernel
|
||||||
pub const page_struct_size = 16;
|
pub const page_struct_size = 16;
|
||||||
|
|
||||||
|
kernel_stack: usize,
|
||||||
|
kernel_stack_size: usize,
|
||||||
|
|
||||||
/// RSDP on ACPI machines
|
/// RSDP on ACPI machines
|
||||||
rsdp: ?usize,
|
rsdp: ?usize,
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ pub fn loader_main(kernel: *anyopaque) void {
|
|||||||
|
|
||||||
const memmap = &r.loader_info.memory_map;
|
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.
|
// Finally, sort the memory map once we're done allocating everything.
|
||||||
std.mem.sort(Entry, memmap.entries[0..memmap.entry_count], {}, cmp_entries);
|
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
|
/// Choose the largest page size that satisfies the alignment and
|
||||||
/// size constraints of the current VA, PA, and remaining byte count.
|
/// 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 {
|
fn choose_target_level(self: *Cursor, pa: usize, remain: usize) usize {
|
||||||
var level: usize = num_levels;
|
var level: usize = num_levels;
|
||||||
while (level > 0) {
|
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);
|
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_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));
|
start_thread.remote(@intCast(cpu_id)).* = make_thread(@ptrCast(&ap_entry), stack_top - r.kib(32));
|
||||||
|
|
||||||
rtl.barrier.fence(.release);
|
rtl.barrier.fence(.release);
|
||||||
|
|||||||
+1
-1
@@ -67,5 +67,5 @@ pub const panic = std.debug.FullPanic(ke.panic);
|
|||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
// Ensure the entry point is linked in.
|
// Ensure the entry point is linked in.
|
||||||
_ = @import("ex/init.zig");
|
_ = @import("kern/init.zig");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user