Skip to content

Commit

Permalink
Small improvement for idt + remove errno
Browse files Browse the repository at this point in the history
  • Loading branch information
Ratakor committed Nov 30, 2023
1 parent e57ce38 commit 5bdac6a
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 113 deletions.
2 changes: 1 addition & 1 deletion kernel/TTY.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ capslock_active: bool,

callback: *const CallbackFn,

pub const Reader = std.io.Reader(*TTY, error{}, read);
pub const Reader = std.io.GenericReader(*TTY, error{}, read); // TODO: change to AnyReader?
pub const Writer = std.io.Writer(*TTY, error{}, write);
pub const CallbackFn = fn (*TTY, Callback, u64, u64, u64) void;

Expand Down
14 changes: 3 additions & 11 deletions kernel/arch/x86_64/gdt.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const std = @import("std");
const log = std.log.scoped(.gdt);
const SpinLock = @import("root").SpinLock;

/// Global Descriptor Table
Expand All @@ -21,15 +19,10 @@ const GDT = extern struct {
base_high: u8 = 0,
};

const Descriptor = extern struct {
limit: u16 align(1) = @sizeOf(GDT) - 1,
base: u64 align(1) = undefined,
const Descriptor = packed struct(u80) {
limit: u16 = @sizeOf(GDT) - 1,
base: u64 = undefined,
};

comptime {
std.debug.assert(@sizeOf(GDT) == 7 * @sizeOf(u64));
std.debug.assert(@bitSizeOf(Descriptor) == 80);
}
};

/// Task State Segment
Expand Down Expand Up @@ -96,7 +89,6 @@ var tss_lock: SpinLock = .{};
pub fn init() void {
gdtr.base = @intFromPtr(&gdt);
reload();
log.info("init: successfully reloaded GDT", .{});
}

pub fn reload() void {
Expand Down
89 changes: 49 additions & 40 deletions kernel/arch/x86_64/idt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ const gdt = @import("gdt.zig");
const vmm = @import("root").vmm;
const log = std.log.scoped(.idt);

const interrupt_gate = 0b1000_1110;
const trap_gate = 0b1000_1111;

pub const InterruptHandler = *const fn (ctx: *Context) callconv(.SysV) void;

pub const Context = extern struct {
Expand Down Expand Up @@ -36,32 +33,45 @@ pub const Context = extern struct {
ss: u64,
};

/// Interrupt Descriptor Table Entry
const IDTEntry = extern struct {
offset_low: u16 align(1),
selector: u16 align(1),
ist: u8 align(1),
type_attributes: u8 align(1),
offset_mid: u16 align(1),
offset_high: u32 align(1),
reserved: u32 align(1),
/// Interrupt Descriptor Table
const IDT = struct {
entries: [256]Entry = undefined,
descriptor: Descriptor = .{},

fn init(handler: u64, ist: u8, gate: u8) IDTEntry {
return .{
.offset_low = @truncate(handler),
.selector = gdt.kernel_code,
.ist = ist,
.type_attributes = gate,
.offset_mid = @truncate(handler >> 16),
.offset_high = @truncate(handler >> 32),
.reserved = 0,
};
}
};
const Entry = packed struct(u128) {
offset_low: u16,
selector: u16,
ist: u3,
reserved0: u5 = 0,
gate_type: u4,
zero: u1 = 0,
dpl: u2, // Descriptor Privilege Level
p: u1, // present flag
offset_mid: u16,
offset_high: u32,
reserved1: u32 = 0,

const interrupt_gate = 0b1110;
const trap_gate = 0b1111;

fn init(handler: u64, ist: u3) Entry {
return .{
.offset_low = @truncate(handler),
.selector = gdt.kernel_code,
.ist = ist,
.gate_type = interrupt_gate,
.dpl = 0b00,
.p = 1,
.offset_mid = @truncate(handler >> 16),
.offset_high = @truncate(handler >> 32),
};
}
};

const IDTDescriptor = extern struct {
limit: u16 align(1) = @sizeOf(@TypeOf(idt)) - 1,
base: u64 align(1) = undefined,
const Descriptor = packed struct(u80) {
limit: u16 = @sizeOf([256]Entry) - 1,
base: u64 = undefined,
};
};

const exceptions = [_][]const u8{
Expand Down Expand Up @@ -99,36 +109,35 @@ const exceptions = [_][]const u8{
"Reserved",
};

pub var panic_ipi_vector: u8 = undefined;

// TODO: replace isr with a interrupt dispatcher func?
// -> move all handlers to interrupt.zig?
var isr = [_]InterruptHandler{defaultHandler} ** 256;
var next_vector: u8 = exceptions.len;
pub var panic_ipi_vector: u8 = undefined;
var idt: IDT = .{};

var idtr: IDTDescriptor = .{};
var idt: [256]IDTEntry = undefined;
var next_vector: u8 = exceptions.len;

pub fn init() void {
idtr.base = @intFromPtr(&idt);
idt.descriptor.base = @intFromPtr(&idt.entries);

inline for (0..256) |i| {
const handler = makeHandler(i);
idt[i] = IDTEntry.init(@intFromPtr(handler), 0, interrupt_gate);
inline for (0..256) |vector| {
const handler = makeHandler(vector);
idt.entries[vector] = IDT.Entry.init(@intFromPtr(handler), 0);
}

setIST(0x0e, 2); // page fault uses IST 2
panic_ipi_vector = allocVector();
idt[panic_ipi_vector] = IDTEntry.init(@intFromPtr(&panicHandler), 0, interrupt_gate);
idt.entries[panic_ipi_vector] = IDT.Entry.init(@intFromPtr(&panicHandler), 0);

reload();
log.info("init: successfully reloaded IDT", .{});
}

pub fn reload() void {
asm volatile (
\\lidt (%[idtr])
:
: [idtr] "r" (&idtr),
: [idtr] "r" (&idt.descriptor),
: "memory"
);
}
Expand All @@ -142,8 +151,8 @@ pub fn allocVector() u8 {
return vector;
}

pub inline fn setIST(vector: u8, ist: u8) void {
idt[vector].ist = ist;
pub inline fn setIST(vector: u8, ist: u3) void {
idt.entries[vector].ist = ist;
}

pub inline fn registerHandler(vector: u8, handler: InterruptHandler) void {
Expand Down
10 changes: 5 additions & 5 deletions kernel/lib/lock.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ const atomic = @import("std").atomic;
pub const SpinLock = struct {
state: State = State.init(.unlocked),

const State = atomic.Atomic(enum(u32) { unlocked, locked });
const State = atomic.Value(enum(u32) { unlocked, locked });

/// return true on success
pub inline fn tryLock(self: *SpinLock) bool {
return if (self.isUnlocked()) self.lockImpl("compareAndSwap") else false;
return if (self.isUnlocked()) self.cmpxchg("Strong") else false;
}

pub fn lock(self: *SpinLock) void {
while (!self.lockImpl("tryCompareAndSwap")) {
while (!self.cmpxchg("Weak")) {
while (!self.isUnlocked()) {
atomic.spinLoopHint();
}
Expand All @@ -27,8 +27,8 @@ pub const SpinLock = struct {
return self.state.load(.Monotonic) == .unlocked;
}

inline fn lockImpl(self: *SpinLock, comptime cas_fn_name: []const u8) bool {
const casFn = @field(@TypeOf(self.state), cas_fn_name);
inline fn cmpxchg(self: *SpinLock, comptime strength: []const u8) bool {
const casFn = @field(@TypeOf(self.state), "cmpxchg" ++ strength);
return casFn(&self.state, .unlocked, .locked, .Acquire, .Monotonic) == null;
}
};
8 changes: 1 addition & 7 deletions kernel/sched.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub const Process = struct {
fds_lock: SpinLock,
fds: std.ArrayListUnmanaged(*vfs.FileDescriptor),

var next_pid = std.atomic.Atomic(std.os.pid_t).init(0);
var next_pid = std.atomic.Value(std.os.pid_t).init(0);

// TODO: more errdefer
pub fn init(parent: ?*Process, addr_space: ?*vmm.AddressSpace) !*Process {
Expand Down Expand Up @@ -88,7 +88,6 @@ pub const Process = struct {
};

pub const Thread = struct {
errno: usize,
tid: usize,
lock: SpinLock = .{},
process: *Process,
Expand Down Expand Up @@ -121,7 +120,6 @@ pub const Thread = struct {
errdefer root.allocator.destroy(thread);

thread.* = .{
.errno = 0,
.tid = undefined,
.process = kernel_process,
.ctx = undefined, // defined after
Expand Down Expand Up @@ -323,10 +321,6 @@ pub inline fn currentProcess() *Process {
return currentThread().process;
}

pub inline fn setErrno(errno: std.os.E) void {
currentThread().errno = @intFromEnum(errno);
}

fn nextThread() ?*Thread {
const ticket = pcg.random().uintLessThan(usize, total_tickets + 1);
var sum: usize = 0;
Expand Down
99 changes: 50 additions & 49 deletions kernel/vfs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -154,54 +154,55 @@ pub const Node = struct {
}
};

pub const Stream = struct {
node: *Node,
offset: u64 = 0,

pub const SeekError = error{};
pub const GetSeekPosError = error{};

pub const SeekableStream = std.io.SeekableStream(
*Stream,
SeekError,
GetSeekPosError,
Stream.seekTo,
Stream.seekBy,
Stream.getPosFn,
Stream.getEndPosFn,
);

pub const Reader = std.io.Reader(*Stream, ReadError, Stream.read);

fn seekTo(self: *Stream, offset: u64) SeekError!void {
self.offset = offset;
}

fn seekBy(self: *Stream, offset: i64) SeekError!void {
self.offset +%= @bitCast(offset);
}

fn getPosFn(self: *Stream) GetSeekPosError!u64 {
return self.offset;
}

fn getEndPosFn(self: *Stream) GetSeekPosError!u64 {
_ = self;
return 0; // TODO
}

fn read(self: *Stream, buf: []u8) ReadError!usize {
return self.node.read(buf, self.offset);
}

pub fn seekableStream(self: *Stream) SeekableStream {
return .{ .context = self };
}

pub fn reader(self: *Stream) Reader {
return .{ .context = self };
}
};
// TODO: useless?
// pub const Stream = struct {
// node: *Node,
// offset: u64 = 0,

// pub const SeekError = error{};
// pub const GetSeekPosError = error{};

// pub const SeekableStream = std.io.SeekableStream(
// *Stream,
// SeekError,
// GetSeekPosError,
// Stream.seekTo,
// Stream.seekBy,
// Stream.getPosFn,
// Stream.getEndPosFn,
// );

// pub const Reader = std.io.Reader(*Stream, ReadError, Stream.read);

// fn seekTo(self: *Stream, offset: u64) SeekError!void {
// self.offset = offset;
// }

// fn seekBy(self: *Stream, offset: i64) SeekError!void {
// self.offset +%= @bitCast(offset);
// }

// fn getPosFn(self: *Stream) GetSeekPosError!u64 {
// return self.offset;
// }

// fn getEndPosFn(self: *Stream) GetSeekPosError!u64 {
// _ = self;
// return 0; // TODO
// }

// fn read(self: *Stream, buf: []u8) ReadError!usize {
// return self.node.read(buf, self.offset);
// }

// pub fn seekableStream(self: *Stream) SeekableStream {
// return .{ .context = self };
// }

// pub fn reader(self: *Stream) Reader {
// return .{ .context = self };
// }
// };

pub fn init(
vtable: *const VTable,
Expand Down Expand Up @@ -365,7 +366,7 @@ pub const FileDescriptor = struct {

// pub const MountFn = *const fn (parent: *Node, name: []const u8, source: *Node) CreateError!*Node;

var filesystems: std.StringHashMapUnmanaged(MountFn) = .{};
var filesystems: std.StringHashMapUnmanaged(MountFn) = .{}; // TODO: use ComptimeStringMap
pub var root_node: *Node = undefined;
var vfs_lock: SpinLock = .{};
var dev_id_counter: os.dev_t = 0;
Expand Down

0 comments on commit 5bdac6a

Please sign in to comment.