core: Add a struct named "platform.Registers" to cover different architectures
This replaces the architecture-independent usage of InterruptStackFrame, which is an x86_64 implementation thing.
This commit is contained in:
parent
52cb29dbca
commit
d858700da4
@ -1,4 +1,5 @@
|
|||||||
const io = @import("ioports.zig");
|
const io = @import("ioports.zig");
|
||||||
|
const platform = @import("platform.zig");
|
||||||
const interrupts = @import("interrupts.zig");
|
const interrupts = @import("interrupts.zig");
|
||||||
const pic = @import("pic.zig");
|
const pic = @import("pic.zig");
|
||||||
const thread = @import("../../thread.zig");
|
const thread = @import("../../thread.zig");
|
||||||
@ -23,6 +24,6 @@ pub fn initializePIT() void {
|
|||||||
_ = interrupts.registerIRQ(0, &pitTimerHandler);
|
_ = interrupts.registerIRQ(0, &pitTimerHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pitTimerHandler(_: u32, regs: *interrupts.InterruptStackFrame) void {
|
pub fn pitTimerHandler(_: u32, regs: *platform.Registers) void {
|
||||||
thread.preempt(regs);
|
thread.preempt(regs);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ const interrupts = @import("interrupts.zig");
|
|||||||
|
|
||||||
pub const PAGE_SIZE = 4096;
|
pub const PAGE_SIZE = 4096;
|
||||||
|
|
||||||
|
pub const Registers = interrupts.InterruptStackFrame;
|
||||||
|
|
||||||
// FIXME: Check if it's supported first.
|
// FIXME: Check if it's supported first.
|
||||||
fn enableNX() void {
|
fn enableNX() void {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const interrupts = @import("interrupts.zig");
|
const platform = @import("platform.zig");
|
||||||
|
|
||||||
pub inline fn enterThread(regs: *interrupts.InterruptStackFrame, base: u64, directory: u64) noreturn {
|
pub inline fn enterThread(regs: *platform.Registers, base: u64, directory: u64) noreturn {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
\\ addq %[base], %rsp
|
\\ addq %[base], %rsp
|
||||||
\\ push %[ss]
|
\\ push %[ss]
|
||||||
@ -54,28 +54,28 @@ pub inline fn readStackPointer() usize {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setAddress(regs: *interrupts.InterruptStackFrame, address: u64) void {
|
pub fn setAddress(regs: *platform.Registers, address: u64) void {
|
||||||
regs.rip = address;
|
regs.rip = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setArguments(regs: *interrupts.InterruptStackFrame, arg0: u64, arg1: u64) void {
|
pub fn setArguments(regs: *platform.Registers, arg0: u64, arg1: u64) void {
|
||||||
regs.rdi = arg0;
|
regs.rdi = arg0;
|
||||||
regs.rsi = arg1;
|
regs.rsi = arg1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setStack(regs: *interrupts.InterruptStackFrame, stack: u64) void {
|
pub fn setStack(regs: *platform.Registers, stack: u64) void {
|
||||||
regs.rsp = stack;
|
regs.rsp = stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initKernelRegisters(regs: *interrupts.InterruptStackFrame) void {
|
pub fn initKernelRegisters(regs: *platform.Registers) void {
|
||||||
regs.* = std.mem.zeroes(interrupts.InterruptStackFrame);
|
regs.* = std.mem.zeroes(platform.Registers);
|
||||||
regs.cs = 0x08;
|
regs.cs = 0x08;
|
||||||
regs.ss = 0x10;
|
regs.ss = 0x10;
|
||||||
regs.rflags = 1 << 9; // IF (Interrupt enable flag)
|
regs.rflags = 1 << 9; // IF (Interrupt enable flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initUserRegisters(regs: *interrupts.InterruptStackFrame) void {
|
pub fn initUserRegisters(regs: *platform.Registers) void {
|
||||||
regs.* = std.mem.zeroes(interrupts.InterruptStackFrame);
|
regs.* = std.mem.zeroes(platform.Registers);
|
||||||
regs.cs = 0x18 | 3;
|
regs.cs = 0x18 | 3;
|
||||||
regs.ss = 0x20 | 3;
|
regs.ss = 0x20 | 3;
|
||||||
regs.rflags = 1 << 9; // IF (Interrupt enable flag)
|
regs.rflags = 1 << 9; // IF (Interrupt enable flag)
|
||||||
|
@ -15,7 +15,7 @@ const MultibootInfo = [*c]u8;
|
|||||||
const Context = struct {
|
const Context = struct {
|
||||||
allocator: *pmm.FrameAllocator,
|
allocator: *pmm.FrameAllocator,
|
||||||
space: vmm.AddressSpace,
|
space: vmm.AddressSpace,
|
||||||
regs: *interrupts.InterruptStackFrame,
|
regs: *platform.Registers,
|
||||||
};
|
};
|
||||||
|
|
||||||
export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn {
|
export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
const interrupts = @import("../arch/interrupts.zig").arch;
|
const platform = @import("../arch/platform.zig").arch;
|
||||||
const sys = @import("syscall.zig");
|
const sys = @import("syscall.zig");
|
||||||
const pmm = @import("../pmm.zig");
|
const pmm = @import("../pmm.zig");
|
||||||
|
|
||||||
pub fn allocFrame(_: *interrupts.InterruptStackFrame, _: *sys.Arguments, retval: *isize) anyerror!void {
|
pub fn allocFrame(_: *platform.Registers, _: *sys.Arguments, retval: *isize) anyerror!void {
|
||||||
const allocator = pmm.lockGlobalAllocator();
|
const allocator = pmm.lockGlobalAllocator();
|
||||||
defer pmm.unlockGlobalAllocator();
|
defer pmm.unlockGlobalAllocator();
|
||||||
|
|
||||||
@ -11,14 +11,14 @@ pub fn allocFrame(_: *interrupts.InterruptStackFrame, _: *sys.Arguments, retval:
|
|||||||
retval.* = @bitCast(frame.address);
|
retval.* = @bitCast(frame.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeFrame(_: *interrupts.InterruptStackFrame, args: *sys.Arguments, _: *isize) anyerror!void {
|
pub fn freeFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||||
const allocator = pmm.lockGlobalAllocator();
|
const allocator = pmm.lockGlobalAllocator();
|
||||||
defer pmm.unlockGlobalAllocator();
|
defer pmm.unlockGlobalAllocator();
|
||||||
|
|
||||||
try pmm.freeFrame(allocator, args.arg0);
|
try pmm.freeFrame(allocator, args.arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lockFrame(_: *interrupts.InterruptStackFrame, args: *sys.Arguments, _: *isize) anyerror!void {
|
pub fn lockFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||||
const allocator = pmm.lockGlobalAllocator();
|
const allocator = pmm.lockGlobalAllocator();
|
||||||
defer pmm.unlockGlobalAllocator();
|
defer pmm.unlockGlobalAllocator();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const interrupts = @import("../arch/interrupts.zig").arch;
|
const platform = @import("../arch/platform.zig").arch;
|
||||||
const sys = @import("syscall.zig");
|
const sys = @import("syscall.zig");
|
||||||
const debug = @import("../arch/debug.zig");
|
const debug = @import("../arch/debug.zig");
|
||||||
|
|
||||||
pub fn print(_: *interrupts.InterruptStackFrame, args: *sys.Arguments, _: *isize) anyerror!void {
|
pub fn print(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||||
debug.print("The userspace program gave us the number {x}\n", .{args.arg0});
|
debug.print("The userspace program gave us the number {x}\n", .{args.arg0});
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
const interrupts = @import("../arch/interrupts.zig").arch;
|
const platform = @import("../arch/platform.zig").arch;
|
||||||
const sys = @import("syscall.zig");
|
const sys = @import("syscall.zig");
|
||||||
const thread = @import("../thread.zig");
|
const thread = @import("../thread.zig");
|
||||||
const cpu = @import("../arch/cpu.zig");
|
const cpu = @import("../arch/cpu.zig");
|
||||||
|
|
||||||
pub fn yield(regs: *interrupts.InterruptStackFrame, _: *sys.Arguments, _: *isize) anyerror!void {
|
pub fn yield(regs: *platform.Registers, _: *sys.Arguments, _: *isize) anyerror!void {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
const new_thread = thread.fetchNewThread(core, false) orelse return;
|
const new_thread = thread.fetchNewThread(core, false) orelse return;
|
||||||
const current_thread = thread.scheduleNewThread(core, regs, new_thread);
|
const current_thread = thread.scheduleNewThread(core, regs, new_thread);
|
||||||
thread.addThreadToPriorityQueue(core, current_thread);
|
thread.addThreadToPriorityQueue(core, current_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setPriority(_: *interrupts.InterruptStackFrame, args: *sys.Arguments, _: *isize) anyerror!void {
|
pub fn setPriority(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
core.current_thread.user_priority = @truncate(args.arg0);
|
core.current_thread.user_priority = @truncate(args.arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPriority(_: *interrupts.InterruptStackFrame, _: *sys.Arguments, retval: *isize) anyerror!void {
|
pub fn getPriority(_: *platform.Registers, _: *sys.Arguments, retval: *isize) anyerror!void {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
retval.* = core.current_thread.user_priority;
|
retval.* = core.current_thread.user_priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(regs: *interrupts.InterruptStackFrame, args: *sys.Arguments, _: *isize) anyerror!void {
|
pub fn sleep(regs: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||||
_ = thread.startSleep(regs, args.arg0);
|
_ = thread.startSleep(regs, args.arg0);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const interrupts = @import("../arch/interrupts.zig").arch;
|
const platform = @import("../arch/platform.zig").arch;
|
||||||
const print = @import("print.zig").print;
|
const print = @import("print.zig").print;
|
||||||
const mem = @import("mem.zig");
|
const mem = @import("mem.zig");
|
||||||
const sched = @import("sched.zig");
|
const sched = @import("sched.zig");
|
||||||
@ -13,11 +13,11 @@ pub const Arguments = struct {
|
|||||||
arg5: usize,
|
arg5: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SystemCall = *const fn (frame: *interrupts.InterruptStackFrame, args: *Arguments, retval: *isize) anyerror!void;
|
const SystemCall = *const fn (frame: *platform.Registers, args: *Arguments, retval: *isize) anyerror!void;
|
||||||
|
|
||||||
const syscalls = [_]SystemCall{ print, mem.allocFrame, mem.lockFrame, mem.freeFrame, sched.yield, sched.setPriority, sched.getPriority, sched.sleep };
|
const syscalls = [_]SystemCall{ print, mem.allocFrame, mem.lockFrame, mem.freeFrame, sched.yield, sched.setPriority, sched.getPriority, sched.sleep };
|
||||||
|
|
||||||
pub fn invokeSyscall(number: usize, frame: *interrupts.InterruptStackFrame, args: *Arguments, retval: *isize) void {
|
pub fn invokeSyscall(number: usize, frame: *platform.Registers, args: *Arguments, retval: *isize) void {
|
||||||
if (number >= syscalls.len) {
|
if (number >= syscalls.len) {
|
||||||
retval.* = -1;
|
retval.* = -1;
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const vmm = @import("arch/vmm.zig").arch;
|
const vmm = @import("arch/vmm.zig").arch;
|
||||||
const interrupts = @import("arch/interrupts.zig").arch;
|
const platform = @import("arch/platform.zig").arch;
|
||||||
pub const arch = @import("arch/thread.zig").arch;
|
pub const arch = @import("arch/thread.zig").arch;
|
||||||
const pmm = @import("pmm.zig");
|
const pmm = @import("pmm.zig");
|
||||||
const cpu = @import("arch/cpu.zig");
|
const cpu = @import("arch/cpu.zig");
|
||||||
@ -16,7 +16,7 @@ pub const ThreadState = enum {
|
|||||||
pub const ThreadControlBlock = struct {
|
pub const ThreadControlBlock = struct {
|
||||||
id: u64,
|
id: u64,
|
||||||
address_space: ?vmm.AddressSpace,
|
address_space: ?vmm.AddressSpace,
|
||||||
regs: interrupts.InterruptStackFrame,
|
regs: platform.Registers,
|
||||||
state: ThreadState,
|
state: ThreadState,
|
||||||
user_priority: u8,
|
user_priority: u8,
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ pub fn enterThread(thread: *ThreadControlBlock) noreturn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the processor state to run a new thread.
|
/// Updates the processor state to run a new thread.
|
||||||
fn switchThread(regs: *interrupts.InterruptStackFrame, new_thread: *ThreadControlBlock) void {
|
fn switchThread(regs: *platform.Registers, new_thread: *ThreadControlBlock) void {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
|
|
||||||
core.current_thread.regs = regs.*;
|
core.current_thread.regs = regs.*;
|
||||||
@ -74,7 +74,7 @@ fn switchThread(regs: *interrupts.InterruptStackFrame, new_thread: *ThreadContro
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the running thread to a new one and returns the previous one.
|
/// Changes the running thread to a new one and returns the previous one.
|
||||||
pub fn scheduleNewThread(core: *cpu.arch.Core, regs: *interrupts.InterruptStackFrame, new_thread: *ThreadControlBlock) *ThreadControlBlock {
|
pub fn scheduleNewThread(core: *cpu.arch.Core, regs: *platform.Registers, new_thread: *ThreadControlBlock) *ThreadControlBlock {
|
||||||
if (core.active_thread_list.first) |first| {
|
if (core.active_thread_list.first) |first| {
|
||||||
first.data.current_priority +|= 4;
|
first.data.current_priority +|= 4;
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ pub fn scheduleNewThread(core: *cpu.arch.Core, regs: *interrupts.InterruptStackF
|
|||||||
///
|
///
|
||||||
/// Updates the core's sleep queue, checks if the running thread's time
|
/// Updates the core's sleep queue, checks if the running thread's time
|
||||||
/// is up, and if it is, schedules a new one.
|
/// is up, and if it is, schedules a new one.
|
||||||
pub fn preempt(regs: *interrupts.InterruptStackFrame) void {
|
pub fn preempt(regs: *platform.Registers) void {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
|
|
||||||
updateSleepQueue(core);
|
updateSleepQueue(core);
|
||||||
@ -107,7 +107,7 @@ pub fn preempt(regs: *interrupts.InterruptStackFrame) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current thread's state to "Blocked" and schedules a new one to replace it.
|
/// Sets the current thread's state to "Blocked" and schedules a new one to replace it.
|
||||||
pub fn block(regs: *interrupts.InterruptStackFrame) *ThreadControlBlock {
|
pub fn block(regs: *platform.Registers) *ThreadControlBlock {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
|
|
||||||
// fetchNewThread() always returns a thread if should_idle_if_not_found is set to true.
|
// fetchNewThread() always returns a thread if should_idle_if_not_found is set to true.
|
||||||
@ -119,7 +119,7 @@ pub fn block(regs: *interrupts.InterruptStackFrame) *ThreadControlBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Puts the current thread to sleep, adding it to the sleep queue, and schedules a new one to replace it.
|
/// Puts the current thread to sleep, adding it to the sleep queue, and schedules a new one to replace it.
|
||||||
pub fn startSleep(regs: *interrupts.InterruptStackFrame, ticks: u64) *ThreadControlBlock {
|
pub fn startSleep(regs: *platform.Registers, ticks: u64) *ThreadControlBlock {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
|
|
||||||
// fetchNewThread() always returns a thread if should_idle_if_not_found is set to true.
|
// fetchNewThread() always returns a thread if should_idle_if_not_found is set to true.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user