Add x86 syscalls
This commit is contained in:
parent
190f21f907
commit
60ba451aec
6 changed files with 339 additions and 7 deletions
|
@ -7,6 +7,7 @@ const irq = @import("irq.zig");
|
||||||
const isr = @import("isr.zig");
|
const isr = @import("isr.zig");
|
||||||
const log = @import("../../log.zig");
|
const log = @import("../../log.zig");
|
||||||
const pit = @import("pit.zig");
|
const pit = @import("pit.zig");
|
||||||
|
const syscalls = @import("syscalls.zig");
|
||||||
|
|
||||||
pub const InterruptContext = struct {
|
pub const InterruptContext = struct {
|
||||||
// Extra segments
|
// Extra segments
|
||||||
|
@ -58,6 +59,8 @@ pub fn init(mem_profile: *const MemProfile, allocator: *std.mem.Allocator, compt
|
||||||
|
|
||||||
paging.init(mem_profile, allocator);
|
paging.init(mem_profile, allocator);
|
||||||
|
|
||||||
|
syscalls.init(options);
|
||||||
|
|
||||||
// Enable interrupts
|
// Enable interrupts
|
||||||
enableInterrupts();
|
enableInterrupts();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
const panic = @import("../../panic.zig");
|
const panic = @import("../../panic.zig");
|
||||||
const idt = @import("idt.zig");
|
const idt = @import("idt.zig");
|
||||||
const arch = @import("arch.zig");
|
const arch = @import("arch.zig");
|
||||||
|
const syscalls = @import("syscalls.zig");
|
||||||
|
|
||||||
const NUMBER_OF_ENTRIES: u16 = 32;
|
const NUMBER_OF_ENTRIES: u16 = 32;
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ extern fn isr28() void;
|
||||||
extern fn isr29() void;
|
extern fn isr29() void;
|
||||||
extern fn isr30() void;
|
extern fn isr30() void;
|
||||||
extern fn isr31() void;
|
extern fn isr31() void;
|
||||||
|
extern fn isr128() void;
|
||||||
|
|
||||||
/// The exception messaged that is printed when a exception happens
|
/// The exception messaged that is printed when a exception happens
|
||||||
const exception_msg: [NUMBER_OF_ENTRIES][]const u8 = [NUMBER_OF_ENTRIES][]const u8 {
|
const exception_msg: [NUMBER_OF_ENTRIES][]const u8 = [NUMBER_OF_ENTRIES][]const u8 {
|
||||||
|
@ -76,8 +78,18 @@ const exception_msg: [NUMBER_OF_ENTRIES][]const u8 = [NUMBER_OF_ENTRIES][]const
|
||||||
"Reserved"
|
"Reserved"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Errors that an isr function can return
|
||||||
|
pub const IsrError = error {
|
||||||
|
UnrecognisedIsr
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An isr handler. Takes an interrupt context and returns void.
|
||||||
|
/// Should finish quickly to avoid delaying further interrupts and the previously running code
|
||||||
|
pub const IsrHandler = fn(*arch.InterruptContext)void;
|
||||||
|
|
||||||
// The of exception handlers initialised to unhandled.
|
// The of exception handlers initialised to unhandled.
|
||||||
var isr_handlers: [NUMBER_OF_ENTRIES]fn(*arch.InterruptContext)void = []fn(*arch.InterruptContext)void{unhandled} ** NUMBER_OF_ENTRIES;
|
var isr_handlers: [NUMBER_OF_ENTRIES]IsrHandler = []IsrHandler{unhandled} ** NUMBER_OF_ENTRIES;
|
||||||
|
var syscall_handler: IsrHandler = unhandled;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// A dummy handler that will make a call to panic as it is a unhandled exception.
|
/// A dummy handler that will make a call to panic as it is a unhandled exception.
|
||||||
|
@ -91,6 +103,17 @@ fn unhandled(context: *arch.InterruptContext) void {
|
||||||
panic.panicFmt(null, "Unhandled exception: {}, number {}", exception_msg[interrupt_num], interrupt_num);
|
panic.panicFmt(null, "Unhandled exception: {}, number {}", exception_msg[interrupt_num], interrupt_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Checks if the isr is valid and returns true if it is, else false.
|
||||||
|
/// To be valid it must be greater than or equal to 0 and less than NUMBER_OF_ENTRIES.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN isr_num: u16 - The isr number to check
|
||||||
|
///
|
||||||
|
pub fn isValidIsr(isr_num: u32) bool {
|
||||||
|
return isr_num >= 0 and isr_num < NUMBER_OF_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The exception handler that each of the exceptions will call when a exception happens.
|
/// The exception handler that each of the exceptions will call when a exception happens.
|
||||||
///
|
///
|
||||||
|
@ -100,7 +123,13 @@ fn unhandled(context: *arch.InterruptContext) void {
|
||||||
///
|
///
|
||||||
export fn isrHandler(context: *arch.InterruptContext) void {
|
export fn isrHandler(context: *arch.InterruptContext) void {
|
||||||
const isr_num = context.int_num;
|
const isr_num = context.int_num;
|
||||||
|
if (isr_num == syscalls.INTERRUPT) {
|
||||||
|
syscall_handler(context);
|
||||||
|
} else if (isValidIsr(isr_num)) {
|
||||||
isr_handlers[isr_num](context);
|
isr_handlers[isr_num](context);
|
||||||
|
} else {
|
||||||
|
panic.panicFmt(null, "Unrecognised isr: {}\n", isr_num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -109,8 +138,17 @@ export fn isrHandler(context: *arch.InterruptContext) void {
|
||||||
/// Arguments:
|
/// Arguments:
|
||||||
/// IN irq_num: u16 - The exception number to register.
|
/// IN irq_num: u16 - The exception number to register.
|
||||||
///
|
///
|
||||||
pub fn registerIsr(isr_num: u16, handler: fn(*arch.InterruptContext)void) void {
|
/// Errors:
|
||||||
|
/// IsrError.UnrecognisedIsr - If `isr_num` is invalid (see isValidIsr)
|
||||||
|
///
|
||||||
|
pub fn registerIsr(isr_num: u16, handler: fn(*arch.InterruptContext)void) !void {
|
||||||
|
if (isr_num == syscalls.INTERRUPT) {
|
||||||
|
syscall_handler = handler;
|
||||||
|
} else if (isValidIsr(isr_num)) {
|
||||||
isr_handlers[isr_num] = handler;
|
isr_handlers[isr_num] = handler;
|
||||||
|
} else {
|
||||||
|
return IsrError.UnrecognisedIsr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -160,4 +198,5 @@ pub fn init() void {
|
||||||
idt.openInterruptGate(29, isr29);
|
idt.openInterruptGate(29, isr29);
|
||||||
idt.openInterruptGate(30, isr30);
|
idt.openInterruptGate(30, isr30);
|
||||||
idt.openInterruptGate(31, isr31);
|
idt.openInterruptGate(31, isr31);
|
||||||
|
idt.openInterruptGate(syscalls.INTERRUPT, isr128);
|
||||||
}
|
}
|
|
@ -87,3 +87,4 @@ isrGenerator 28
|
||||||
isrGenerator 29
|
isrGenerator 29
|
||||||
isrGenerator 30
|
isrGenerator 30
|
||||||
isrGenerator 31
|
isrGenerator 31
|
||||||
|
isrGenerator 128
|
||||||
|
|
|
@ -142,7 +142,7 @@ pub fn init(mem_profile: *const MemProfile, allocator: *std.mem.Allocator) void
|
||||||
mapDir(kernel_directory, p_start, p_end, v_start, v_end, allocator) catch unreachable;
|
mapDir(kernel_directory, p_start, p_end, v_start, v_end, allocator) catch unreachable;
|
||||||
const dir_physaddr = @ptrToInt(kernel_directory) - constants.KERNEL_ADDR_OFFSET;
|
const dir_physaddr = @ptrToInt(kernel_directory) - constants.KERNEL_ADDR_OFFSET;
|
||||||
asm volatile ("mov %[addr], %%cr3" :: [addr] "{eax}" (dir_physaddr));
|
asm volatile ("mov %[addr], %%cr3" :: [addr] "{eax}" (dir_physaddr));
|
||||||
isr.registerIsr(14, pageFault);
|
isr.registerIsr(14, pageFault) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
test "isAligned" {
|
test "isAligned" {
|
||||||
|
|
287
src/kernel/arch/x86/syscalls.zig
Normal file
287
src/kernel/arch/x86/syscalls.zig
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
const arch = @import("arch.zig");
|
||||||
|
const testing = @import("std").testing;
|
||||||
|
const assert = @import("std").debug.assert;
|
||||||
|
const isr = @import("isr.zig");
|
||||||
|
const log = @import("../../log.zig");
|
||||||
|
|
||||||
|
/// The isr number associated with syscalls
|
||||||
|
pub const INTERRUPT: u16 = 0x80;
|
||||||
|
|
||||||
|
/// The maximum number of syscall handlers that can be registered
|
||||||
|
pub const NUM_HANDLERS: u16 = 256;
|
||||||
|
|
||||||
|
/// A syscall handler
|
||||||
|
pub const SyscallHandler = fn (ctx: *arch.InterruptContext) u32;
|
||||||
|
|
||||||
|
/// Errors that syscall utility functions can throw
|
||||||
|
pub const SyscallError = error {
|
||||||
|
SyscallExists,
|
||||||
|
InvalidSyscall
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The array of registered syscalls
|
||||||
|
var handlers: [NUM_HANDLERS]?SyscallHandler = []?SyscallHandler{null} ** NUM_HANDLERS;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns true if the syscall is valid, else false.
|
||||||
|
/// A syscall is valid if it's less than NUM_HANDLERS.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u32 - The syscall to check
|
||||||
|
///
|
||||||
|
pub fn isValidSyscall(syscall: u32) bool {
|
||||||
|
return syscall < NUM_HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Handle a syscall. Gets the syscall number from eax within the context and calls the registered handler.
|
||||||
|
/// If there isn't a registered handler or the syscall is invalid (>= NUM_HANDLERS) then a warning is logged.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN ctx: *arch.InterruptContext - The cpu context when the syscall was triggered. The syscall number is
|
||||||
|
/// stored in eax.
|
||||||
|
///
|
||||||
|
fn handle(ctx: *arch.InterruptContext) void {
|
||||||
|
// The syscall number is put in eax
|
||||||
|
const syscall = ctx.eax;
|
||||||
|
if (isValidSyscall(syscall)) {
|
||||||
|
if (handlers[syscall]) |handler| {
|
||||||
|
ctx.eax = handler(ctx);
|
||||||
|
} else {
|
||||||
|
log.logWarning("Syscall {} triggered but not registered\n", syscall);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.logWarning("Syscall {} is invalid\n", syscall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Register a syscall so it can be called by triggering interrupt 128.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u8 - The syscall number to register the handler with.
|
||||||
|
/// IN handler: SyscallHandler - The handler to register the syscall with.
|
||||||
|
///
|
||||||
|
/// Errors:
|
||||||
|
/// SyscallError.InvalidSyscall - If the syscall is invalid (see isValidSyscall).
|
||||||
|
/// SyscallError.SyscallExists - If the syscall has already been registered.
|
||||||
|
///
|
||||||
|
pub fn registerSyscall(syscall: u8, handler: SyscallHandler) SyscallError!void {
|
||||||
|
if (!isValidSyscall(syscall))
|
||||||
|
return SyscallError.InvalidSyscall;
|
||||||
|
if (handlers[syscall]) |_|
|
||||||
|
return SyscallError.SyscallExists;
|
||||||
|
handlers[syscall] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Trigger a syscall with no arguments. Returns the value put in eax by the syscall.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u32 - The syscall to trigger, put in eax.
|
||||||
|
///
|
||||||
|
inline fn syscall0(syscall: u32) u32 {
|
||||||
|
return asm volatile (
|
||||||
|
\\int $0x80
|
||||||
|
: [ret] "={eax}" (-> u32)
|
||||||
|
: [syscall] "{eax}" (syscall),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Trigger a syscall with one argument. Returns the value put in eax by the syscall.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u32 - The syscall to trigger, put in eax.
|
||||||
|
/// IN arg: u32 - The argument to pass. Put in ebx.
|
||||||
|
///
|
||||||
|
inline fn syscall1(syscall: u32, arg: u32) u32 {
|
||||||
|
return asm volatile (
|
||||||
|
\\int $0x80
|
||||||
|
: [ret] "={eax}" (-> u32)
|
||||||
|
: [syscall] "{eax}" (syscall),
|
||||||
|
[arg1] "{ebx}" (arg),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Trigger a syscall with two arguments. Returns the value put in eax by the syscall.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u32 - The syscall to trigger, put in eax.
|
||||||
|
/// IN arg1: u32 - The first argument to pass. Put in ebx.
|
||||||
|
/// IN arg2: u32 - The second argument to pass. Put in ecx.
|
||||||
|
///
|
||||||
|
inline fn syscall2(syscall: u32, arg1: u32, arg2: u32) u32 {
|
||||||
|
return asm volatile (
|
||||||
|
\\int $0x80
|
||||||
|
: [ret] "={eax}" (-> u32)
|
||||||
|
: [syscall] "{eax}" (syscall),
|
||||||
|
[arg1] "{ebx}" (arg1),
|
||||||
|
[arg2] "{ecx}" (arg2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Trigger a syscall with three arguments. Returns the value put in eax by the syscall.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u32 - The syscall to trigger, put in eax.
|
||||||
|
/// IN arg1: u32 - The first argument to pass. Put in ebx.
|
||||||
|
/// IN arg2: u32 - The second argument to pass. Put in ecx.
|
||||||
|
/// IN arg3: u32 - The third argument to pass. Put in edx.
|
||||||
|
///
|
||||||
|
inline fn syscall3(syscall: u32, arg1: u32, arg2: u32, arg3: u32) u32 {
|
||||||
|
return asm volatile (
|
||||||
|
\\int $0x80
|
||||||
|
: [ret] "={eax}" (-> u32)
|
||||||
|
: [syscall] "{eax}" (syscall),
|
||||||
|
[arg1] "{ebx}" (arg1),
|
||||||
|
[arg2] "{ecx}" (arg2),
|
||||||
|
[arg3] "{edx}" (arg3),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Trigger a syscall with four arguments. Returns the value put in eax by the syscall.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u32 - The syscall to trigger, put in eax.
|
||||||
|
/// IN arg1: u32 - The first argument to pass. Put in ebx.
|
||||||
|
/// IN arg2: u32 - The second argument to pass. Put in ecx.
|
||||||
|
/// IN arg3: u32 - The third argument to pass. Put in edx.
|
||||||
|
/// IN arg4: u32 - The fourth argument to pass. Put in esi.
|
||||||
|
///
|
||||||
|
inline fn syscall4(syscall: u32, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
|
||||||
|
return asm volatile (
|
||||||
|
\\int $0x80
|
||||||
|
: [ret] "={eax}" (-> u32)
|
||||||
|
: [syscall] "{eax}" (syscall),
|
||||||
|
[arg1] "{ebx}" (arg1),
|
||||||
|
[arg2] "{ecx}" (arg2),
|
||||||
|
[arg3] "{edx}" (arg3),
|
||||||
|
[arg4] "{esi}" (arg4),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Trigger a syscall with five arguments. Returns the value put in eax by the syscall.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN syscall: u32 - The syscall to trigger, put in eax.
|
||||||
|
/// IN arg1: u32 - The first argument to pass. Put in ebx.
|
||||||
|
/// IN arg2: u32 - The second argument to pass. Put in ecx.
|
||||||
|
/// IN arg3: u32 - The third argument to pass. Put in edx.
|
||||||
|
/// IN arg4: u32 - The fourth argument to pass. Put in esi.
|
||||||
|
/// IN arg5: u32 - The fifth argument to pass. Put in edi.
|
||||||
|
///
|
||||||
|
inline fn syscall5(syscall: u32, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
|
||||||
|
return asm volatile (
|
||||||
|
\\int $0x80
|
||||||
|
: [ret] "={eax}" (-> u32)
|
||||||
|
: [syscall] "{eax}" (syscall),
|
||||||
|
[arg1] "{ebx}" (arg1),
|
||||||
|
[arg2] "{ecx}" (arg2),
|
||||||
|
[arg3] "{edx}" (arg3),
|
||||||
|
[arg4] "{esi}" (arg4),
|
||||||
|
[arg5] "{edi}" (arg5),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets the syscall argument according to the given index. 0 => ebx, 1 => ecx, 2 => edx, 3 => esi and 4 => edi.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// IN ctx: *arch.InterruptContext - The interrupt context from which to get the argument
|
||||||
|
/// IN arg_idx: comptime u32 - The argument index to get. Between 0 and 4.
|
||||||
|
///
|
||||||
|
inline fn syscallArg(ctx: *arch.InterruptContext, comptime arg_idx: u32) u32 {
|
||||||
|
return switch (arg_idx) {
|
||||||
|
0 => ctx.ebx,
|
||||||
|
1 => ctx.ecx,
|
||||||
|
2 => ctx.edx,
|
||||||
|
3 => ctx.esi,
|
||||||
|
4 => ctx.edi,
|
||||||
|
else => @compileError("Arg index must be between 0 and 4")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Initialise syscalls. Registers the isr associated with INTERRUPT.
|
||||||
|
///
|
||||||
|
pub fn init(comptime options: type) void {
|
||||||
|
log.logInfo("Init syscalls\n");
|
||||||
|
isr.registerIsr(INTERRUPT, handle) catch unreachable;
|
||||||
|
log.logInfo("Done\n");
|
||||||
|
if (options.rt_test) runtimeTests();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tests
|
||||||
|
|
||||||
|
var testInt: u32 = 0;
|
||||||
|
|
||||||
|
fn testHandler0(ctx: *arch.InterruptContext) u32 {
|
||||||
|
testInt += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testHandler1(ctx: *arch.InterruptContext) u32 {
|
||||||
|
testInt += syscallArg(ctx, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testHandler2(ctx: *arch.InterruptContext) u32 {
|
||||||
|
testInt += syscallArg(ctx, 1);
|
||||||
|
return testHandler1(ctx) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testHandler3(ctx: *arch.InterruptContext) u32 {
|
||||||
|
testInt += syscallArg(ctx, 2);
|
||||||
|
return testHandler2(ctx) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testHandler4(ctx: *arch.InterruptContext) u32 {
|
||||||
|
testInt += syscallArg(ctx, 3);
|
||||||
|
return testHandler3(ctx) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testHandler5(ctx: *arch.InterruptContext) u32 {
|
||||||
|
testInt += syscallArg(ctx, 4);
|
||||||
|
return testHandler4(ctx) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "registerSyscall returns SyscallExists" {
|
||||||
|
registerSyscall(123, testHandler) catch unreachable;
|
||||||
|
registerSyscall(123, testHandler) catch |err| {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runtimeTests() void {
|
||||||
|
registerSyscall(123, testHandler0) catch unreachable;
|
||||||
|
registerSyscall(124, testHandler1) catch unreachable;
|
||||||
|
registerSyscall(125, testHandler2) catch unreachable;
|
||||||
|
registerSyscall(126, testHandler3) catch unreachable;
|
||||||
|
registerSyscall(127, testHandler4) catch unreachable;
|
||||||
|
registerSyscall(128, testHandler5) catch unreachable;
|
||||||
|
assert(testInt == 0);
|
||||||
|
|
||||||
|
if (syscall0(123) == 0 and testInt == 1)
|
||||||
|
log.logInfo("Syscalls: Tested no args\n");
|
||||||
|
|
||||||
|
if (syscall1(124, 2) == 1 and testInt == 3)
|
||||||
|
log.logInfo("Syscalls: Tested 1 arg\n");
|
||||||
|
|
||||||
|
if (syscall2(125, 2, 3) == 2 and testInt == 8)
|
||||||
|
log.logInfo("Syscalls: Tested 2 args\n");
|
||||||
|
|
||||||
|
if (syscall3(126, 2, 3, 4) == 3 and testInt == 17)
|
||||||
|
log.logInfo("Syscalls: Tested 3 args\n");
|
||||||
|
|
||||||
|
if (syscall4(127, 2, 3, 4, 5) == 4 and testInt == 31)
|
||||||
|
log.logInfo("Syscalls: Tested 4 args\n");
|
||||||
|
|
||||||
|
if (syscall5(128, 2, 3, 4, 5, 6) == 5 and testInt == 51)
|
||||||
|
log.logInfo("Syscalls: Tested 5 args\n");
|
||||||
|
}
|
|
@ -2,5 +2,7 @@ def getTestCases(TestCase):
|
||||||
return [
|
return [
|
||||||
TestCase("GDT init", [r"Init gdt", r"Done"]),
|
TestCase("GDT init", [r"Init gdt", r"Done"]),
|
||||||
TestCase("IDT init", [r"Init idt", r"Done"]),
|
TestCase("IDT init", [r"Init idt", r"Done"]),
|
||||||
TestCase("PIT init", [r"Init pit", r".+", "Done"])
|
TestCase("PIT init", [r"Init pit", r".+", "Done"]),
|
||||||
|
TestCase("Syscalls init", [r"Init syscalls", "Done"]),
|
||||||
|
TestCase("Syscall tests", [r"Syscalls: Tested no args", r"Syscalls: Tested 1 arg", r"Syscalls: Tested 2 args", r"Syscalls: Tested 3 args", r"Syscalls: Tested 4 args", r"Syscalls: Tested 5 args"])
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue