Compare commits

..

No commits in common. "c6ea6e46cc0e52b1576aa9a4cde08504ded2ce7f" and "117b799bbe84f4c401a34362b5c992abccebbcc7" have entirely different histories.

4 changed files with 37 additions and 41 deletions

View File

@ -72,7 +72,7 @@ args = ["-rf", "build/initramfs", "build/initramfs.tar.lzma"]
[tasks.lib] [tasks.lib]
condition = { files_modified = { input = ["src/lib/**/*.rs"], output = ["${ARTIFACTDIR}/libgila.rlib"] }, fail_message = "(inputs unchanged)" } condition = { files_modified = { input = ["src/lib/**/*.rs"], output = ["${ARTIFACTDIR}/libgila.rlib"] }, fail_message = "(inputs unchanged)" }
dependencies = [] dependencies = ["prepare"]
command = "cargo" command = "cargo"
args = ["build", "--profile", "${PROFILE}", "--lib"] args = ["build", "--profile", "${PROFILE}", "--lib"]

View File

@ -4,39 +4,40 @@
use lazy_static::lazy_static; use lazy_static::lazy_static;
use x86_64::structures::idt::*; use x86_64::structures::idt::*;
use crate::format;
lazy_static! { lazy_static! {
pub static ref IDT: InterruptDescriptorTable = { pub static ref IDT: InterruptDescriptorTable = {
let idt = InterruptDescriptorTable::new(); let mut idt = InterruptDescriptorTable::new();
// TODO: Re-implement this once the x86-interrupt ABI is fixed. // TODO: Re-implement this once the x86-interrupt ABI is fixed.
// Alternatively: Write our own interrupt handler wrappers. //idt.double_fault.set_handler_fn(double_fault);
idt.page_fault.set_handler_fn(page_fault);
idt idt
}; };
} }
// For all these handlers, they will be called from a purely naked ASM //extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
// function. That function will first push all registers to the stack. // crate::interrupt::double_fault(&format!("{info:#?}"));
// It is the responsibility of these functions to recover this info. //}
// Recoverable exception: Occurs on division failure.
#[unsafe(no_mangle)]
pub extern "C" fn x86_divide_error() {
#[allow(dead_code)]
extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) {
if errcode.contains(PageFaultErrorCode::USER_MODE) {
// Fault occurred in usermode. Non fatal.
todo!()
} else {
// Fault occurred in kernel mode. This is possibly fatal.
// This is recoverable if we simply hit an unavailable page,
// but unrecoverable if we hit a nonexistent or invalid page.
if errcode.contains(PageFaultErrorCode::PROTECTION_VIOLATION)
| errcode.contains(PageFaultErrorCode::MALFORMED_TABLE)
{
let addr = unsafe {
let a: usize;
core::arch::asm! {"mov {}, cr2", out(reg) a};
a
};
crate::interrupt::page_fault(addr, &format!("{info:#?}"))
} }
// Recoverable exception: Occurs on failure in BOUND instruction.
#[unsafe(no_mangle)]
pub extern "C" fn x86_bound_range() {
} }
// Recoverable exception: Invalid opcode.
#[unsafe(no_mangle)]
pub extern "C" fn x86_invalid_opcode() {
}
// Recoverable exception: FPU not available or enabled.
#[unsafe(no_mangle)]
pub extern "C" fn x86_device_unavailable() {
} }

View File

@ -1,16 +1,11 @@
// Copyright (c) 2025 shibedrill // Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use core::str; #[allow(dead_code)]
pub fn double_fault(info: &str) -> ! {
#[unsafe(no_mangle)] panic!("Double fault: {}", info);
extern "C" fn double_fault(info: *const u8, info_len: usize) -> ! {
let info_slice = unsafe {&str::from_raw_parts(info, info_len)};
panic!("Double fault: {}", info_slice);
} }
#[unsafe(no_mangle)] pub fn page_fault(addr: usize, info: &str) -> ! {
pub extern "C" fn page_fault(addr: usize, info: *const u8, info_len: usize) -> ! { panic!("Page fault at 0x{:X}: {}", addr, info);
let info_slice = unsafe { &str::from_raw_parts(info, info_len) };
panic!("Page fault at 0x{:X}: {}", addr, info_slice);
} }

View File

@ -4,7 +4,7 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(allocator_api)] #![feature(allocator_api)]
#![feature(str_from_raw_parts)] #![feature(abi_x86_interrupt)]
mod arch; mod arch;
mod boot; mod boot;