Compare commits
No commits in common. "da5335410db3af69addd9a593ea04450f5cb2ec2" and "fce8a58cf603192ddd23b09afcc2a0c8002b9237" have entirely different histories.
da5335410d
...
fce8a58cf6
@ -73,80 +73,11 @@ export fn asmInterruptEntry() callconv(.Naked) void {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Exceptions = enum(u64) {
|
|
||||||
GeneralProtectionFault = 0xd,
|
|
||||||
PageFault = 0xe,
|
|
||||||
};
|
|
||||||
|
|
||||||
const PageFaultCodes = enum(u64) {
|
|
||||||
Present = 1 << 0,
|
|
||||||
Write = 1 << 1,
|
|
||||||
User = 1 << 2,
|
|
||||||
Reserved = 1 << 3,
|
|
||||||
NoExecuteViolation = 1 << 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
const SYSCALL_INTERRUPT = 66;
|
const SYSCALL_INTERRUPT = 66;
|
||||||
|
|
||||||
fn generalProtectionFault(frame: *InterruptStackFrame) void {
|
|
||||||
debug.print("General protection fault!\n", .{});
|
|
||||||
debug.print("Faulting instruction: {x}\n", .{frame.rip});
|
|
||||||
|
|
||||||
const code = frame.error_or_irq;
|
|
||||||
|
|
||||||
debug.print("Error code: {d}\n", .{code});
|
|
||||||
|
|
||||||
while (true) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pageFault(frame: *InterruptStackFrame) void {
|
|
||||||
var fault_address: u64 = undefined;
|
|
||||||
asm volatile ("mov %%cr2, %[cr2]"
|
|
||||||
: [cr2] "=r" (fault_address),
|
|
||||||
);
|
|
||||||
|
|
||||||
debug.print("Page fault while accessing {x}!\n", .{fault_address});
|
|
||||||
debug.print("Faulting instruction: {x}\n", .{frame.rip});
|
|
||||||
|
|
||||||
const code = frame.error_or_irq;
|
|
||||||
|
|
||||||
debug.print("Fault details: {s} | ", .{switch ((code & @intFromEnum(PageFaultCodes.Present)) > 0) {
|
|
||||||
true => "Present",
|
|
||||||
false => "Not present",
|
|
||||||
}});
|
|
||||||
|
|
||||||
debug.print("{s} | ", .{switch ((code & @intFromEnum(PageFaultCodes.Write)) > 0) {
|
|
||||||
true => "Write access",
|
|
||||||
false => "Read access",
|
|
||||||
}});
|
|
||||||
|
|
||||||
debug.print("{s}", .{switch ((code & @intFromEnum(PageFaultCodes.User)) > 0) {
|
|
||||||
true => "User mode",
|
|
||||||
false => "Kernel mode",
|
|
||||||
}});
|
|
||||||
|
|
||||||
debug.print("{s}", .{switch ((code & @intFromEnum(PageFaultCodes.Reserved)) > 0) {
|
|
||||||
true => " | Reserved bits set",
|
|
||||||
false => "",
|
|
||||||
}});
|
|
||||||
|
|
||||||
debug.print("{s}\n", .{switch ((code & @intFromEnum(PageFaultCodes.NoExecuteViolation)) > 0) {
|
|
||||||
true => " | NX Violation",
|
|
||||||
false => "",
|
|
||||||
}});
|
|
||||||
|
|
||||||
while (true) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export fn interruptEntry(frame: *InterruptStackFrame) callconv(.C) void {
|
export fn interruptEntry(frame: *InterruptStackFrame) callconv(.C) void {
|
||||||
debug.print("Caught interrupt {d}\n", .{frame.isr});
|
debug.print("Caught interrupt {d}\n", .{frame.isr});
|
||||||
switch (frame.isr) {
|
switch (frame.isr) {
|
||||||
@intFromEnum(Exceptions.PageFault) => {
|
|
||||||
pageFault(frame);
|
|
||||||
},
|
|
||||||
@intFromEnum(Exceptions.GeneralProtectionFault) => {
|
|
||||||
generalProtectionFault(frame);
|
|
||||||
},
|
|
||||||
SYSCALL_INTERRUPT => {
|
SYSCALL_INTERRUPT => {
|
||||||
var args = sys.Arguments{ .arg0 = frame.rdi, .arg1 = frame.rsi, .arg2 = frame.rdx, .arg3 = frame.r10, .arg4 = frame.r8, .arg5 = frame.r9 };
|
var args = sys.Arguments{ .arg0 = frame.rdi, .arg1 = frame.rsi, .arg2 = frame.rdx, .arg3 = frame.r10, .arg4 = frame.r8, .arg5 = frame.r9 };
|
||||||
sys.invokeSyscall(frame.rax, frame, &args, @ptrFromInt(@as(usize, @intFromPtr(&frame.rax))));
|
sys.invokeSyscall(frame.rax, frame, &args, @ptrFromInt(@as(usize, @intFromPtr(&frame.rax))));
|
||||||
|
@ -15,5 +15,4 @@ pub fn platformInit() void {
|
|||||||
pub fn platformEndInit() void {
|
pub fn platformEndInit() void {
|
||||||
pic.remapPIC();
|
pic.remapPIC();
|
||||||
interrupts.syncInterrupts();
|
interrupts.syncInterrupts();
|
||||||
interrupts.enableInterrupts();
|
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,6 @@ const pmm = @import("pmm.zig");
|
|||||||
const MultibootInfo = [*c]u8;
|
const MultibootInfo = [*c]u8;
|
||||||
|
|
||||||
export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn {
|
export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn {
|
||||||
interrupts.disableInterrupts();
|
|
||||||
|
|
||||||
if (magic != easyboot.MULTIBOOT2_BOOTLOADER_MAGIC) {
|
if (magic != easyboot.MULTIBOOT2_BOOTLOADER_MAGIC) {
|
||||||
debug.print("Invalid magic number: {x}\n", .{magic});
|
debug.print("Invalid magic number: {x}\n", .{magic});
|
||||||
while (true) {}
|
while (true) {}
|
||||||
@ -21,10 +19,14 @@ export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn {
|
|||||||
|
|
||||||
multiboot.parseMultibootTags(@ptrCast(info));
|
multiboot.parseMultibootTags(@ptrCast(info));
|
||||||
|
|
||||||
|
interrupts.disableInterrupts();
|
||||||
platform.platformInit();
|
platform.platformInit();
|
||||||
|
|
||||||
debug.print("GDT initialized\n", .{});
|
debug.print("GDT initialized\n", .{});
|
||||||
|
|
||||||
|
platform.platformEndInit();
|
||||||
|
interrupts.enableInterrupts();
|
||||||
|
|
||||||
if (multiboot.findMultibootTag(easyboot.multiboot_tag_mmap_t, @ptrCast(info))) |tag| {
|
if (multiboot.findMultibootTag(easyboot.multiboot_tag_mmap_t, @ptrCast(info))) |tag| {
|
||||||
var allocator = pmm.initializeFrameAllocator(tag) catch |err| {
|
var allocator = pmm.initializeFrameAllocator(tag) catch |err| {
|
||||||
debug.print("Error while initializing frame allocator: {}\n", .{err});
|
debug.print("Error while initializing frame allocator: {}\n", .{err});
|
||||||
@ -42,8 +44,6 @@ export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn {
|
|||||||
debug.print("No memory map multiboot tag found!\n", .{});
|
debug.print("No memory map multiboot tag found!\n", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
platform.platformEndInit();
|
|
||||||
|
|
||||||
asm volatile ("int3");
|
asm volatile ("int3");
|
||||||
|
|
||||||
while (true) {}
|
while (true) {}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
const easyboot = @cImport(@cInclude("easyboot.h"));
|
const easyboot = @cImport(@cInclude("easyboot.h"));
|
||||||
const target = @import("builtin").target;
|
|
||||||
|
|
||||||
const MemoryMapIterator = struct {
|
const MemoryMapIterator = struct {
|
||||||
tag: *easyboot.multiboot_tag_mmap_t,
|
tag: *easyboot.multiboot_tag_mmap_t,
|
||||||
@ -16,16 +15,6 @@ const MemoryMapIterator = struct {
|
|||||||
|
|
||||||
if (@intFromPtr(self.entry) >= self.end) self.entry = null;
|
if (@intFromPtr(self.entry) >= self.end) self.entry = null;
|
||||||
|
|
||||||
if (target.cpu.arch == .x86_64) {
|
|
||||||
// Workaround for https://gitlab.com/qemu-project/qemu/-/commit/8504f129450b909c88e199ca44facd35d38ba4de
|
|
||||||
// This invalid 12GiB reserved entry is made up by QEMU (doesn't appear on any real hardware), so we can simply
|
|
||||||
// ignore it and move on to the next entry.
|
|
||||||
if (current_entry) |entry| {
|
|
||||||
if (entry.base_addr == 0x000000fd00000000 and entry.length == (0x000000ffffffffff - 0x000000fd00000000) + 1)
|
|
||||||
return self.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return current_entry;
|
return current_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ pub fn findMultibootTag(comptime Type: type, info: MultibootInfo) ?*Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Find every multiboot tag of the given type.
|
/// Find every multiboot tag of the given type.
|
||||||
pub fn findMultibootTags(comptime Type: type, info: MultibootInfo, callback: *const fn (tag: *Type, ctx: *const anyopaque) void, ctx: *const anyopaque) void {
|
pub fn findMultibootTags(comptime Type: type, info: MultibootInfo, callback: *const fn (tag: *Type) void) void {
|
||||||
const mb_tag: *easyboot.multiboot_info_t = @alignCast(@ptrCast(info));
|
const mb_tag: *easyboot.multiboot_info_t = @alignCast(@ptrCast(info));
|
||||||
const mb_size = mb_tag.total_size;
|
const mb_size = mb_tag.total_size;
|
||||||
|
|
||||||
@ -77,43 +77,43 @@ pub fn findMultibootTags(comptime Type: type, info: MultibootInfo, callback: *co
|
|||||||
while ((@intFromPtr(tag) < last) and (tag.type != easyboot.MULTIBOOT_TAG_TYPE_END)) {
|
while ((@intFromPtr(tag) < last) and (tag.type != easyboot.MULTIBOOT_TAG_TYPE_END)) {
|
||||||
switch (tag.type) {
|
switch (tag.type) {
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_CMDLINE => {
|
easyboot.MULTIBOOT_TAG_TYPE_CMDLINE => {
|
||||||
if (Type == easyboot.multiboot_tag_cmdline_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_cmdline_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME => {
|
easyboot.MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME => {
|
||||||
if (Type == easyboot.multiboot_tag_loader_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_loader_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_MODULE => {
|
easyboot.MULTIBOOT_TAG_TYPE_MODULE => {
|
||||||
if (Type == easyboot.multiboot_tag_module_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_module_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_MMAP => {
|
easyboot.MULTIBOOT_TAG_TYPE_MMAP => {
|
||||||
if (Type == easyboot.multiboot_tag_mmap_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_mmap_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_FRAMEBUFFER => {
|
easyboot.MULTIBOOT_TAG_TYPE_FRAMEBUFFER => {
|
||||||
if (Type == easyboot.multiboot_tag_framebuffer_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_framebuffer_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_EFI64 => {
|
easyboot.MULTIBOOT_TAG_TYPE_EFI64 => {
|
||||||
if (Type == easyboot.multiboot_tag_efi64_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_efi64_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_EFI64_IH => {
|
easyboot.MULTIBOOT_TAG_TYPE_EFI64_IH => {
|
||||||
if (Type == easyboot.multiboot_tag_efi64_ih_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_efi64_ih_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_SMBIOS => {
|
easyboot.MULTIBOOT_TAG_TYPE_SMBIOS => {
|
||||||
if (Type == easyboot.multiboot_tag_smbios_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_smbios_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_ACPI_OLD => {
|
easyboot.MULTIBOOT_TAG_TYPE_ACPI_OLD => {
|
||||||
if (Type == easyboot.multiboot_tag_old_acpi_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_old_acpi_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_ACPI_NEW => {
|
easyboot.MULTIBOOT_TAG_TYPE_ACPI_NEW => {
|
||||||
if (Type == easyboot.multiboot_tag_new_acpi_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_new_acpi_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_SMP => {
|
easyboot.MULTIBOOT_TAG_TYPE_SMP => {
|
||||||
if (Type == easyboot.multiboot_tag_smp_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_smp_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_PARTUUID => {
|
easyboot.MULTIBOOT_TAG_TYPE_PARTUUID => {
|
||||||
if (Type == easyboot.multiboot_tag_partuuid_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_partuuid_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
easyboot.MULTIBOOT_TAG_TYPE_EDID => {
|
easyboot.MULTIBOOT_TAG_TYPE_EDID => {
|
||||||
if (Type == easyboot.multiboot_tag_edid_t) callback(@alignCast(@ptrCast(tag)), ctx);
|
if (Type == easyboot.multiboot_tag_edid_t) callback(@alignCast(@ptrCast(tag)));
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,5 @@ pub fn initializeFrameAllocator(tag: *easyboot.multiboot_tag_mmap_t) !FrameAlloc
|
|||||||
const frames_to_lock = try std.math.divCeil(usize, bitmap_size, platform.PAGE_SIZE);
|
const frames_to_lock = try std.math.divCeil(usize, bitmap_size, platform.PAGE_SIZE);
|
||||||
try lockFrames(&allocator, @intFromPtr(bitmap_base_address), frames_to_lock);
|
try lockFrames(&allocator, @intFromPtr(bitmap_base_address), frames_to_lock);
|
||||||
|
|
||||||
// Avoid causing trouble.
|
|
||||||
try lockFrame(&allocator, 0);
|
|
||||||
|
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user