mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-28 22:18:22 +00:00
feat: fireworks!
This commit is contained in:
@@ -142,10 +142,11 @@ pub fn send_sipi(apic_id: u32, startup_page: u8) void {
|
||||
}
|
||||
|
||||
pub fn send_ipi(apic_id: u32, vector: u8, delivery_mode: u8) void {
|
||||
const icr_value = (@as(u64, apic_id) << 32) | (@as(u64, delivery_mode) << 8) | vector;
|
||||
if (in_x2apic_mode.local().*) {
|
||||
const icr_value = (@as(u64, apic_id) << 32) | (@as(u64, delivery_mode) << 8) | vector;
|
||||
x2apic_write(.Icr, icr_value);
|
||||
} else {
|
||||
const icr_value = (@as(u32, delivery_mode) << 8) | vector;
|
||||
// Write to ICR1 first, because writing to the low word causes
|
||||
// the IPI to be sent.
|
||||
xapic_write(.Icr1, @as(u32, apic_id) << 24);
|
||||
|
||||
@@ -5,7 +5,7 @@ const std = @import("std");
|
||||
const tsc = @import("tsc.zig");
|
||||
const pvclock = @import("pvclock.zig");
|
||||
pub const apic = @import("apic.zig");
|
||||
const smp = @import("smp.zig");
|
||||
pub const smp = @import("smp.zig");
|
||||
|
||||
const ki = r.ke.private;
|
||||
|
||||
@@ -105,3 +105,7 @@ pub fn debug_write(c: u8) void {
|
||||
pub fn arm_timer(deadline: r.Nanoseconds) void {
|
||||
apic.arm_timer(deadline);
|
||||
}
|
||||
|
||||
pub fn send_resched_ipi(target_cpu: u32) void {
|
||||
apic.send_ipi(smp.cpu_id_to_apic_id[target_cpu], 240, 0);
|
||||
}
|
||||
|
||||
+18
-2
@@ -17,10 +17,12 @@ extern var AP_TRAMPOLINE_DATA: u8;
|
||||
extern var __percpu_start: u8;
|
||||
extern var __percpu_end: u8;
|
||||
|
||||
export var cpu_id_to_apic_id: [config.CONFIG_NCPUS]u32 = undefined;
|
||||
pub export var cpu_id_to_apic_id: [config.CONFIG_NCPUS]u32 = undefined;
|
||||
|
||||
const start_stack = ke.ExportedCpuLocal(usize, 0, "ap_start_stack");
|
||||
|
||||
pub const start_thread = ke.CpuLocal(*ke.Thread, undefined);
|
||||
|
||||
var aps_booted: std.atomic.Value(usize) = .init(0);
|
||||
|
||||
const ApData = extern struct {
|
||||
@@ -35,6 +37,16 @@ fn ap_entry(cpu_id: u32) callconv(.c) noreturn {
|
||||
ki.impl.init.ap_entry(cpu_id, &aps_booted);
|
||||
}
|
||||
|
||||
fn make_thread(entrypoint: *const fn (?*anyopaque) void, stack: usize) *ke.Thread {
|
||||
const td = mm.zone.gpa.create(ke.Thread) catch @panic("Failed to allocate thread for AP");
|
||||
|
||||
td.init(stack, r.kib(32), entrypoint, null);
|
||||
|
||||
td.priority = 0;
|
||||
td.priority_class = .Idle;
|
||||
return td;
|
||||
}
|
||||
|
||||
pub fn init() linksection(r.init) void {
|
||||
const trampoline_start = @intFromPtr(&AP_TRAMPOLINE_START);
|
||||
const trampoline_size = @intFromPtr(&AP_TRAMPOLINE_END) - trampoline_start;
|
||||
@@ -94,10 +106,12 @@ pub fn init() linksection(r.init) void {
|
||||
// copy the offset into the AP's self_offset variable
|
||||
@as(*usize, @ptrCast(@alignCast(&cpu_data[self_offset_offset]))).* = ki.impl.cpu_offsets[cpu_id];
|
||||
|
||||
const stack_top = @intFromPtr(mm.heap.alloc(r.kib(16)) catch @panic("Failed to allocate AP stack")) + r.kib(16);
|
||||
const stack_top = @intFromPtr(mm.heap.alloc(r.kib(32)) 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.wmb();
|
||||
|
||||
// Send the INIT-SIPI-SIPI sequence to start the AP.
|
||||
@@ -109,6 +123,8 @@ pub fn init() linksection(r.init) void {
|
||||
apic.send_sipi(apic_id, 0x08);
|
||||
}
|
||||
|
||||
log.info("Waiting for APs...", .{});
|
||||
|
||||
while (aps_booted.load(.acquire) < apic.apics.items.len) {
|
||||
std.atomic.spinLoopHint();
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ pub const GlobalState = struct {
|
||||
|
||||
pub const CpuState = struct {
|
||||
pthread: c.pthread_t,
|
||||
td: *ke.Thread,
|
||||
};
|
||||
|
||||
pub var global_state: GlobalState = undefined;
|
||||
@@ -122,6 +123,8 @@ fn other_cpu_entry(_: ?*anyopaque) callconv(.c) ?*anyopaque {
|
||||
|
||||
ki.cpu.init_cpu(@intCast(my_cpu_id));
|
||||
|
||||
ki.sched.percpu.local().current_thread = percpu.local().td;
|
||||
|
||||
timer.init_cpu();
|
||||
|
||||
while (true) {}
|
||||
@@ -174,6 +177,10 @@ pub fn late_init(_: *pl.BootInfo) linksection(r.init) void {
|
||||
|
||||
@memcpy(block, @as([*]u8, @ptrCast(&__percpu_start))[0..size]);
|
||||
|
||||
const td = allocator.create(ke.Thread) catch @panic("oom");
|
||||
make_thread(idle, td);
|
||||
percpu.remote(@intCast(i)).td = td;
|
||||
|
||||
var attr: c.pthread_attr_t = undefined;
|
||||
|
||||
_ = c.pthread_attr_init(&attr);
|
||||
|
||||
Reference in New Issue
Block a user