Skip to content

Commit e4a168d

Browse files
committed
[kernel] Init the boot percpu data
1 parent 6f19092 commit e4a168d

File tree

4 files changed

+85
-7
lines changed

4 files changed

+85
-7
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//! Copyright 2025 The Drift Authors. All rights reserved.
2+
//! Use of this source code is governed by a BSD-style license that can be
3+
//! found in the LICENSE file.
4+
5+
const std = @import("std");
6+
const assert = @import("assert.zig");
7+
const lazy_init = @import("lazy_init");
8+
const Scheduler = @import("Scheduler.zig");
9+
const defines = @import("../arch/x86/defines.zig");
10+
const arch = @import("arch/mp.zig").Impl;
11+
const cpu = @import("cpu.zig");
12+
const PerCpu = @This();
13+
14+
const CpuNum = cpu.CpuNum;
15+
16+
scheduler: Scheduler,
17+
18+
// The percpu for the boot processor.
19+
var boot_processor: lazy_init.LazyInitChecked(PerCpu) align(defines.max_cache_line) linksection(".data.cpu_align_exclusive") = undefined;
20+
21+
// Pointer to heap memory allocated for additional percpu instances.
22+
var secondary_processors: *PerCpu = null;
23+
24+
// Translates from CPU number to percpu instance. Some or all instances
25+
// of percpu may be discontiguous.
26+
var processor_index: []*PerCpu = undefined;
27+
28+
// Number of percpu entries.
29+
var processor_count: usize = 1;
30+
31+
pub fn init(cpu_num: CpuNum) PerCpu {
32+
return PerCpu{ .scheduler = Scheduler{ .this_cpu = cpu_num } };
33+
}
34+
35+
/// Initialize the boot processor's per-CPU data
36+
pub fn initBoot() void {
37+
_ = boot_processor.initialize(init(0));
38+
// Install a pointer to the boot CPU's high-level percpu struct in its low-level percpu struct.
39+
arch.setupPercpu(0, boot_processor.get());
40+
}
41+
42+
// Returns a reference to the percpu instance for given CPU number.
43+
pub fn get(cpu_num: CpuNum) *PerCpu {
44+
assert.debug_assert(@src(), cpu_num < processor_count);
45+
return processor_index[cpu_num];
46+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//! Copyright 2025 The Drift Authors. All rights reserved.
2+
//! Use of this source code is governed by a BSD-style license that can be
3+
//! found in the LICENSE file.
4+
5+
const cpu = @import("cpu.zig");
6+
const Scheduler = @This();
7+
8+
const CpuNum = cpu.CpuNum;
9+
10+
// The CPU this scheduler instance is associated with.
11+
// NOTE: This member is not initialized to prevent clobbering the value set
12+
// by sched_early_init(), which is called before the global ctors that
13+
// initialize the rest of the members of this class.
14+
// TODO(eieio): Figure out a better long-term solution to determine which
15+
// CPU is associated with each instance of this class. This is needed by
16+
// non-static methods that are called from arbitrary CPUs, namely Insert().
17+
this_cpu: CpuNum,

slipstream/kernel/kernel/Thread.zig

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,37 @@
33
//! found in the LICENSE file.
44

55
const std = @import("std");
6+
const dbl = @import("dbl");
7+
const lazy_init = @import("lazy_init");
8+
const assert = @import("assert.zig");
9+
const arch = @import("arch/mp.zig").Impl;
10+
const spin_lock = @import("spin_lock.zig");
11+
const PerCpu = @import("PerCpu.zig");
12+
const Thread = @This();
613

7-
const arch = @import("../arch/x86/mp.zig");
14+
const SpinLock = spin_lock.SpinLock;
15+
const List = dbl.DoublyLinkedList(*Thread);
816

9-
const debug_assert = @import("assert.zig").debug_assert;
17+
list_lock: SpinLock,
18+
19+
var thread_list: lazy_init.LazyInitDefault(List) = undefined;
20+
21+
pub fn getListLock() *SpinLock {
22+
return &Thread.list_lock;
23+
}
1024

1125
/// Initialize threading system
1226
///
1327
/// This function is called once, from kmain()
1428
pub fn threadInitEarly() void {
15-
debug_assert(@src(), arch.currCpuNum() == 0);
29+
assert.debug_assert(@src(), arch.currCpuNum() == 0);
1630

1731
// Initialize the thread list. This needs to be done manually now, since initial thread code
1832
// manipulates the list before global constructors are run.
19-
//threadList.init();
33+
_ = thread_list.initialize(List{});
2034

2135
// Init the boot percpu data.
22-
//percpu.initBoot();
36+
PerCpu.initBoot();
2337

2438
// Create a thread to cover the current running state
2539
//const t = &percpu.get(0).idle_power_thread.thread;

slipstream/kernel/top/main.zig

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
//! found in the LICENSE file.
44

55
const Init = @import("../lib/init/init.zig");
6-
const Thread = @import("../kernel/Thread.zig");
6+
7+
const threadInitEarly = @import("../kernel/Thread.zig").threadInitEarly;
78

89
// saved boot arguments from whoever loaded the system
910
var lk_boot_args: [4]u64 = undefined;
@@ -17,7 +18,7 @@ export fn lk_main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) align(16) callconv
1718
lk_boot_args[3] = arg3;
1819

1920
//Init.initLevelAll(.{ .primary_cpu = true });
20-
Thread.threadInitEarly();
21+
threadInitEarly();
2122

2223
//Init.initLevelAll(.{ .secondary_cpus = true });
2324
}

0 commit comments

Comments
 (0)