Added gdt unit and runtime tests
Updated runtime tests Added doc comments for runtime tests PR review WIP Fixed testing Import GDT to run the unit tests Removed redundant arch tests Removed whitespace
This commit is contained in:
parent
9c35de8673
commit
07cc1ae89b
18 changed files with 1141 additions and 590 deletions
|
@ -1,7 +1,8 @@
|
|||
const std = @import("std");
|
||||
const MemProfile = @import("mem_mock.zig").MemProfile;
|
||||
const expect = std.testing.expect;
|
||||
const warn = std.debug.warn;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const mem = @import("mem_mock.zig");
|
||||
const MemProfile = mem.MemProfile;
|
||||
const gdt = @import("gdt_mock.zig");
|
||||
|
||||
const mock_framework = @import("mock_framework.zig");
|
||||
pub const initTest = mock_framework.initTest;
|
||||
|
@ -11,29 +12,20 @@ pub const addConsumeFunction = mock_framework.addConsumeFunction;
|
|||
pub const addRepeatFunction = mock_framework.addRepeatFunction;
|
||||
|
||||
pub const InterruptContext = struct {
|
||||
// Extra segments
|
||||
gs: u32,
|
||||
fs: u32,
|
||||
es: u32,
|
||||
ds: u32,
|
||||
|
||||
// Destination, source, base pointer
|
||||
edi: u32,
|
||||
esi: u32,
|
||||
ebp: u32,
|
||||
esp: u32,
|
||||
|
||||
// General registers
|
||||
ebx: u32,
|
||||
edx: u32,
|
||||
ecx: u32,
|
||||
eax: u32,
|
||||
|
||||
// Interrupt number and error code
|
||||
int_num: u32,
|
||||
error_code: u32,
|
||||
|
||||
// Instruction pointer, code segment and flags
|
||||
eip: u32,
|
||||
cs: u32,
|
||||
eflags: u32,
|
||||
|
@ -41,10 +33,6 @@ pub const InterruptContext = struct {
|
|||
ss: u32,
|
||||
};
|
||||
|
||||
pub fn init(mem_profile: *const MemProfile, allocator: *std.mem.Allocator, comptime options: type) void {
|
||||
//return mock_framework.performAction("init", void, mem_profile, allocator);
|
||||
}
|
||||
|
||||
pub fn outb(port: u16, data: u8) void {
|
||||
return mock_framework.performAction("outb", void, port, data);
|
||||
}
|
||||
|
@ -57,20 +45,20 @@ pub fn ioWait() void {
|
|||
return mock_framework.performAction("ioWait", void);
|
||||
}
|
||||
|
||||
pub fn registerInterruptHandler(int: u16, ctx: fn (ctx: *InterruptContext) void) void {
|
||||
return mock_framework.performAction("registerInterruptHandler", void, int, ctx);
|
||||
}
|
||||
|
||||
pub fn lgdt(gdt_ptr: *const gdt.GdtPtr) void {
|
||||
return mock_framework.performAction("lgdt", void, gdt_ptr.*);
|
||||
return mock_framework.performAction("lgdt", void, gdt_ptr);
|
||||
}
|
||||
|
||||
pub fn ltr() void {
|
||||
return mock_framework.performAction("ltr", void);
|
||||
pub fn sgdt() gdt.GdtPtr {
|
||||
return mock_framework.performAction("sgdt", gdt.GdtPtr);
|
||||
}
|
||||
|
||||
pub fn ltr(offset: u16) void {
|
||||
return mock_framework.performAction("ltr", void, offset);
|
||||
}
|
||||
|
||||
pub fn lidt(idt_ptr: *const idt.IdtPtr) void {
|
||||
return mock_framework.performAction("lidt", void, idt_ptr.*);
|
||||
return mock_framework.performAction("lidt", void, idt_ptr);
|
||||
}
|
||||
|
||||
pub fn enableInterrupts() void {
|
||||
|
@ -92,3 +80,9 @@ pub fn spinWait() noreturn {
|
|||
pub fn haltNoInterrupts() noreturn {
|
||||
while (true) {}
|
||||
}
|
||||
|
||||
pub fn init(mem_profile: *const MemProfile, allocator: *Allocator, comptime options: type) void {
|
||||
// I'll get back to this as this doesn't effect the GDT testing.
|
||||
// When I come on to the mem.zig testing, I'll fix :)
|
||||
//return mock_framework.performAction("init", void, mem_profile, allocator);
|
||||
}
|
||||
|
|
169
test/mock/kernel/gdt_mock.zig
Normal file
169
test/mock/kernel/gdt_mock.zig
Normal file
|
@ -0,0 +1,169 @@
|
|||
// Can't do: TODO: https://github.com/SamTebbs33/pluto/issues/77
|
||||
//const src_gdt = @import("arch").gdt;
|
||||
const src_gdt = @import("../../../src/kernel/arch/x86/gdt.zig");
|
||||
|
||||
const mock_framework = @import("mock_framework.zig");
|
||||
pub const initTest = mock_framework.initTest;
|
||||
pub const freeTest = mock_framework.freeTest;
|
||||
pub const addTestParams = mock_framework.addTestParams;
|
||||
pub const addConsumeFunction = mock_framework.addConsumeFunction;
|
||||
pub const addRepeatFunction = mock_framework.addRepeatFunction;
|
||||
|
||||
const AccessBits = packed struct {
|
||||
accessed: u1,
|
||||
read_write: u1,
|
||||
direction_conforming: u1,
|
||||
executable: u1,
|
||||
descriptor: u1,
|
||||
privilege: u2,
|
||||
present: u1,
|
||||
};
|
||||
|
||||
const FlagBits = packed struct {
|
||||
reserved_zero: u1,
|
||||
is_64_bit: u1,
|
||||
is_32_bit: u1,
|
||||
granularity: u1,
|
||||
};
|
||||
|
||||
const GdtEntry = packed struct {
|
||||
limit_low: u16,
|
||||
base_low: u24,
|
||||
access: AccessBits,
|
||||
limit_high: u4,
|
||||
flags: FlagBits,
|
||||
base_high: u8,
|
||||
};
|
||||
|
||||
const TtsEntry = packed struct {
|
||||
prev_tss: u32,
|
||||
esp0: u32,
|
||||
ss0: u32,
|
||||
esp1: u32,
|
||||
ss1: u32,
|
||||
esp2: u32,
|
||||
ss2: u32,
|
||||
cr3: u32,
|
||||
eip: u32,
|
||||
eflags: u32,
|
||||
eax: u32,
|
||||
ecx: u32,
|
||||
edx: u32,
|
||||
ebx: u32,
|
||||
esp: u32,
|
||||
ebp: u32,
|
||||
esi: u32,
|
||||
edi: u32,
|
||||
es: u32,
|
||||
cs: u32,
|
||||
ss: u32,
|
||||
ds: u32,
|
||||
fs: u32,
|
||||
gs: u32,
|
||||
ldtr: u32,
|
||||
trap: u16,
|
||||
io_permissions_base_offset: u16,
|
||||
};
|
||||
|
||||
// Need to use the type from the source file so that types match
|
||||
pub const GdtPtr = src_gdt.GdtPtr;
|
||||
|
||||
const NUMBER_OF_ENTRIES: u16 = 0x06;
|
||||
|
||||
const TABLE_SIZE: u16 = @sizeOf(GdtEntry) * NUMBER_OF_ENTRIES - 1;
|
||||
|
||||
const NULL_INDEX: u16 = 0x00;
|
||||
const KERNEL_CODE_INDEX: u16 = 0x01;
|
||||
const KERNEL_DATA_INDEX: u16 = 0x02;
|
||||
const USER_CODE_INDEX: u16 = 0x03;
|
||||
const USER_DATA_INDEX: u16 = 0x04;
|
||||
const TSS_INDEX: u16 = 0x05;
|
||||
|
||||
const NULL_SEGMENT: AccessBits = AccessBits{
|
||||
.accessed = 0,
|
||||
.read_write = 0,
|
||||
.direction_conforming = 0,
|
||||
.executable = 0,
|
||||
.descriptor = 0,
|
||||
.privilege = 0,
|
||||
.present = 0,
|
||||
};
|
||||
|
||||
const KERNEL_SEGMENT_CODE: AccessBits = AccessBits{
|
||||
.accessed = 0,
|
||||
.read_write = 1,
|
||||
.direction_conforming = 0,
|
||||
.executable = 1,
|
||||
.descriptor = 1,
|
||||
.privilege = 0,
|
||||
.present = 1,
|
||||
};
|
||||
|
||||
const KERNEL_SEGMENT_DATA: AccessBits = AccessBits{
|
||||
.accessed = 0,
|
||||
.read_write = 1,
|
||||
.direction_conforming = 0,
|
||||
.executable = 0,
|
||||
.descriptor = 1,
|
||||
.privilege = 0,
|
||||
.present = 1,
|
||||
};
|
||||
|
||||
const USER_SEGMENT_CODE: AccessBits = AccessBits{
|
||||
.accessed = 0,
|
||||
.read_write = 1,
|
||||
.direction_conforming = 0,
|
||||
.executable = 1,
|
||||
.descriptor = 1,
|
||||
.privilege = 3,
|
||||
.present = 1,
|
||||
};
|
||||
|
||||
const USER_SEGMENT_DATA: AccessBits = AccessBits{
|
||||
.accessed = 0,
|
||||
.read_write = 1,
|
||||
.direction_conforming = 0,
|
||||
.executable = 0,
|
||||
.descriptor = 1,
|
||||
.privilege = 3,
|
||||
.present = 1,
|
||||
};
|
||||
|
||||
const TSS_SEGMENT: AccessBits = AccessBits{
|
||||
.accessed = 1,
|
||||
.read_write = 0,
|
||||
.direction_conforming = 0,
|
||||
.executable = 1,
|
||||
.descriptor = 0,
|
||||
.privilege = 0,
|
||||
.present = 1,
|
||||
};
|
||||
|
||||
const NULL_FLAGS: FlagBits = FlagBits{
|
||||
.reserved_zero = 0,
|
||||
.is_64_bit = 0,
|
||||
.is_32_bit = 0,
|
||||
.granularity = 0,
|
||||
};
|
||||
|
||||
const PAGING_32_BIT: FlagBits = FlagBits{
|
||||
.reserved_zero = 0,
|
||||
.is_64_bit = 0,
|
||||
.is_32_bit = 1,
|
||||
.granularity = 1,
|
||||
};
|
||||
|
||||
pub const NULL_OFFSET: u16 = 0x00;
|
||||
pub const KERNEL_CODE_OFFSET: u16 = 0x08;
|
||||
pub const KERNEL_DATA_OFFSET: u16 = 0x10;
|
||||
pub const USER_CODE_OFFSET: u16 = 0x18;
|
||||
pub const USER_DATA_OFFSET: u16 = 0x20;
|
||||
pub const TSS_OFFSET: u16 = 0x28;
|
||||
|
||||
pub fn setTssStack(esp0: u32) void {
|
||||
return mock_framework.performAction("setTssStack", void, esp0);
|
||||
}
|
||||
|
||||
pub fn init() void {
|
||||
return mock_framework.performAction("init", void);
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const StringHashMap = std.StringHashMap;
|
||||
const expect = std.testing.expect;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
const GlobalAllocator = std.debug.global_allocator;
|
||||
const TailQueue = std.TailQueue;
|
||||
const warn = std.debug.warn;
|
||||
const gdt = @import("gdt_mock.zig");
|
||||
|
||||
///
|
||||
/// The enumeration of types that the mocking framework supports. These include basic types like u8
|
||||
|
@ -16,14 +16,17 @@ const DataElementType = enum {
|
|||
U8,
|
||||
U16,
|
||||
U32,
|
||||
PTR_CONST_GdtPtr,
|
||||
FN_OVOID,
|
||||
FN_OUSIZE,
|
||||
FN_OU16,
|
||||
FN_IU16_OVOID,
|
||||
FN_IU16_OU8,
|
||||
FN_IU4_IU4_OU8,
|
||||
FN_IU8_IU8_OU16,
|
||||
FN_IU16_IU8_OVOID,
|
||||
FN_IU16_IU16_OVOID,
|
||||
FN_IPTRCONSTGDTPTR_OVOID,
|
||||
};
|
||||
|
||||
///
|
||||
|
@ -36,14 +39,17 @@ const DataElement = union(DataElementType) {
|
|||
U8: u8,
|
||||
U16: u16,
|
||||
U32: u32,
|
||||
PTR_CONST_GdtPtr: *const gdt.GdtPtr,
|
||||
FN_OVOID: fn () void,
|
||||
FN_OUSIZE: fn () usize,
|
||||
FN_OU16: fn () u16,
|
||||
FN_IU16_OVOID: fn (u16) void,
|
||||
FN_IU16_OU8: fn (u16) u8,
|
||||
FN_IU4_IU4_OU8: fn (u4, u4) u8,
|
||||
FN_IU8_IU8_OU16: fn (u8, u8) u16,
|
||||
FN_IU16_IU8_OVOID: fn (u16, u8) void,
|
||||
FN_IU16_IU16_OVOID: fn (u16, u16) void,
|
||||
FN_IPTRCONSTGDTPTR_OVOID: fn (*const gdt.GdtPtr) void,
|
||||
};
|
||||
|
||||
///
|
||||
|
@ -123,14 +129,17 @@ fn Mock() type {
|
|||
u8 => DataElement{ .U8 = arg },
|
||||
u16 => DataElement{ .U16 = arg },
|
||||
u32 => DataElement{ .U32 = arg },
|
||||
*const gdt.GdtPtr => DataElement{ .PTR_CONST_GdtPtr = arg },
|
||||
fn () void => DataElement{ .FN_OVOID = arg },
|
||||
fn () usize => DataElement{ .FN_OUSIZE = arg },
|
||||
fn () u16 => DataElement{ .FN_OU16 = arg },
|
||||
fn (u16) void => DataElement{ .FN_IU16_OVOID = arg },
|
||||
fn (u16) u8 => DataElement{ .FN_IU16_OU8 = arg },
|
||||
fn (u4, u4) u8 => DataElement{ .FN_IU4_IU4_OU8 = arg },
|
||||
fn (u8, u8) u16 => DataElement{ .FN_IU8_IU8_OU16 = arg },
|
||||
fn (u16, u8) void => DataElement{ .FN_IU16_IU8_OVOID = arg },
|
||||
fn (u16, u16) void => DataElement{ .FN_IU16_IU16_OVOID = arg },
|
||||
fn (*const gdt.GdtPtr) void => DataElement{ .FN_IPTRCONSTGDTPTR_OVOID = arg },
|
||||
else => @compileError("Type not supported: " ++ @typeName(@typeOf(arg))),
|
||||
};
|
||||
}
|
||||
|
@ -150,13 +159,16 @@ fn Mock() type {
|
|||
u8 => DataElementType.U8,
|
||||
u16 => DataElementType.U16,
|
||||
u32 => DataElementType.U32,
|
||||
*const gdt.GdtPtr => DataElement.PTR_CONST_GdtPtr,
|
||||
fn () void => DataElementType.FN_OVOID,
|
||||
fn () u16 => DataElementType.FN_OU16,
|
||||
fn (u16) void => DataElementType.FN_IU16_OVOID,
|
||||
fn (u16) u8 => DataElementType.FN_IU16_OU8,
|
||||
fn (u4, u4) u8 => DataElementType.FN_IU4_IU4_OU8,
|
||||
fn (u8, u8) u16 => DataElementType.FN_IU8_IU8_OU16,
|
||||
fn (u16, u8) void => DataElementType.FN_IU16_IU8_OVOID,
|
||||
fn (u16, u16) void => DataElementType.FN_IU16_IU16_OVOID,
|
||||
fn (*const gdt.GdtPtr) void => DataElementType.FN_IPTRCONSTGDTPTR_OVOID,
|
||||
else => @compileError("Type not supported: " ++ @typeName(T)),
|
||||
};
|
||||
}
|
||||
|
@ -178,13 +190,16 @@ fn Mock() type {
|
|||
u8 => element.U8,
|
||||
u16 => element.U16,
|
||||
u32 => element.U32,
|
||||
*const gdt.GdtPtr => element.PTR_CONST_GdtPtr,
|
||||
fn () void => element.FN_OVOID,
|
||||
fn () u16 => element.FN_OU16,
|
||||
fn (u16) void => element.FN_IU16_OVOID,
|
||||
fn (u16) u8 => element.FN_IU16_OU8,
|
||||
fn (u4, u4) u8 => element.FN_IU4_IU4_OU8,
|
||||
fn (u8, u8) u16 => element.FN_IU8_IU8_OU16,
|
||||
fn (u16, u8) void => element.FN_IU16_IU8_OVOID,
|
||||
fn (u16, u16) void => element.FN_IU16_IU16_OVOID,
|
||||
fn (*const gdt.GdtPtr) void => element.FN_IPTRCONSTGDTPTR_OVOID,
|
||||
else => @compileError("Type not supported: " ++ @typeName(T)),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
pub const arch = @import("arch_mock.zig");
|
||||
pub const gdt = @import("gdt_mock.zig");
|
||||
pub const log = @import("log_mock.zig");
|
||||
pub const mem = @import("mem_mock.zig");
|
||||
pub const vga = @import("vga_mock.zig");
|
||||
pub const arch = @import("arch_mock.zig");
|
||||
pub const panic = @import("panic_mock.zig");
|
||||
pub const vga = @import("vga_mock.zig");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue