From e39bd7bf6e411bae5d60542f8cfd7e2df0d39511 Mon Sep 17 00:00:00 2001 From: Arthur Beck Date: Sat, 25 Jan 2025 19:32:03 -0600 Subject: [PATCH] arch-independent stuff working, x86 renamed to x86_asmp because missile --- kernel/Cargo.toml | 2 +- kernel/grub/boot/aphrodite.kernel | Bin 47808 -> 33188 bytes kernel/grub/boot/grub/grub.cfg | 4 +- kernel/kernel.flat | Bin 47808 -> 33188 bytes kernel/src/include/arch/mod.rs | 4 +- .../arch/{x86 => x86_asmp}/constants.rs | 0 .../include/arch/{x86 => x86_asmp}/egatext.rs | 0 .../arch/{x86 => x86_asmp}/interrupts.rs | 0 .../src/include/arch/{x86 => x86_asmp}/mod.rs | 0 .../include/arch/{x86 => x86_asmp}/output.rs | 0 .../include/arch/{x86 => x86_asmp}/paging.rs | 0 .../include/arch/{x86 => x86_asmp}/ports.rs | 0 kernel/src/include/boot.rs | 17 +- kernel/src/include/multiboot2.rs | 91 +++++---- kernel/src/include/traits.rs | 4 +- .../internal/arch/{x86 => x86_asmp}/entry.rs | 190 ++++++++---------- 16 files changed, 158 insertions(+), 154 deletions(-) rename kernel/src/include/arch/{x86 => x86_asmp}/constants.rs (100%) rename kernel/src/include/arch/{x86 => x86_asmp}/egatext.rs (100%) rename kernel/src/include/arch/{x86 => x86_asmp}/interrupts.rs (100%) rename kernel/src/include/arch/{x86 => x86_asmp}/mod.rs (100%) rename kernel/src/include/arch/{x86 => x86_asmp}/output.rs (100%) rename kernel/src/include/arch/{x86 => x86_asmp}/paging.rs (100%) rename kernel/src/include/arch/{x86 => x86_asmp}/ports.rs (100%) rename kernel/src/internal/arch/{x86 => x86_asmp}/entry.rs (65%) diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index c7c29c4..d1e3fa9 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -15,7 +15,7 @@ panic = "abort" [[bin]] name = "entrypoint" -path = "src/internal/arch/x86/entry.rs" +path = "src/internal/arch/x86_asmp/entry.rs" [[bin]] name = "main" diff --git a/kernel/grub/boot/aphrodite.kernel b/kernel/grub/boot/aphrodite.kernel index 88044a2e540cbc611c51b0b2157cd9053ed801c9..66281f39849d70e30e0406aca09c3c92493dd653 100755 GIT binary patch literal 33188 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 literal 47808 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

t2(bNlDS!{tp2VKRZ->Gyj) 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 HL&yIGmE2tJ diff --git a/kernel/grub/boot/grub/grub.cfg b/kernel/grub/boot/grub/grub.cfg index b4d0af5..8be03ea 100644 --- a/kernel/grub/boot/grub/grub.cfg +++ b/kernel/grub/boot/grub/grub.cfg @@ -1,8 +1,8 @@ set timeout=15 set default=0 -menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-devel-6a2a677-out-of-tree' { - echo 'Loading Aphrodite aphrodite-devel-6a2a677-out-of-tree ...' +menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-devel-86a85b8-out-of-tree' { + echo 'Loading Aphrodite aphrodite-devel-86a85b8-out-of-tree ...' multiboot2 /boot/aphrodite.kernel boot } \ No newline at end of file diff --git a/kernel/kernel.flat b/kernel/kernel.flat index 88044a2e540cbc611c51b0b2157cd9053ed801c9..66281f39849d70e30e0406aca09c3c92493dd653 100755 GIT binary patch literal 33188 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 literal 47808 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

t2(bNlDS!{tp2VKRZ->Gyj) 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 HL&yIGmE2tJ diff --git a/kernel/src/include/arch/mod.rs b/kernel/src/include/arch/mod.rs index 7bfed5f..840a29c 100644 --- a/kernel/src/include/arch/mod.rs +++ b/kernel/src/include/arch/mod.rs @@ -1,5 +1,5 @@ //! Arch-specific code. -mod x86; +mod x86_asmp; -pub use x86::*; \ No newline at end of file +pub use x86_asmp::*; \ No newline at end of file diff --git a/kernel/src/include/arch/x86/constants.rs b/kernel/src/include/arch/x86_asmp/constants.rs similarity index 100% rename from kernel/src/include/arch/x86/constants.rs rename to kernel/src/include/arch/x86_asmp/constants.rs diff --git a/kernel/src/include/arch/x86/egatext.rs b/kernel/src/include/arch/x86_asmp/egatext.rs similarity index 100% rename from kernel/src/include/arch/x86/egatext.rs rename to kernel/src/include/arch/x86_asmp/egatext.rs diff --git a/kernel/src/include/arch/x86/interrupts.rs b/kernel/src/include/arch/x86_asmp/interrupts.rs similarity index 100% rename from kernel/src/include/arch/x86/interrupts.rs rename to kernel/src/include/arch/x86_asmp/interrupts.rs diff --git a/kernel/src/include/arch/x86/mod.rs b/kernel/src/include/arch/x86_asmp/mod.rs similarity index 100% rename from kernel/src/include/arch/x86/mod.rs rename to kernel/src/include/arch/x86_asmp/mod.rs diff --git a/kernel/src/include/arch/x86/output.rs b/kernel/src/include/arch/x86_asmp/output.rs similarity index 100% rename from kernel/src/include/arch/x86/output.rs rename to kernel/src/include/arch/x86_asmp/output.rs diff --git a/kernel/src/include/arch/x86/paging.rs b/kernel/src/include/arch/x86_asmp/paging.rs similarity index 100% rename from kernel/src/include/arch/x86/paging.rs rename to kernel/src/include/arch/x86_asmp/paging.rs diff --git a/kernel/src/include/arch/x86/ports.rs b/kernel/src/include/arch/x86_asmp/ports.rs similarity index 100% rename from kernel/src/include/arch/x86/ports.rs rename to kernel/src/include/arch/x86_asmp/ports.rs diff --git a/kernel/src/include/boot.rs b/kernel/src/include/boot.rs index b2b32fc..78ada3c 100644 --- a/kernel/src/include/boot.rs +++ b/kernel/src/include/boot.rs @@ -9,6 +9,8 @@ pub enum MemoryType { /// Free RAM with no use. Free, + /// RAM used by the kernel + Kernel, /// Reserved by something. Reserved, /// Reserved by something on the hardware. @@ -19,7 +21,9 @@ pub enum MemoryType { Unknown, /// Hardware-specific use. The boolean argument states /// whether memory can be allocated in this region. - HardwareSpecific(u32, bool) + HardwareSpecific(u32, bool), + /// Flash/semi-permanent memory. Generally used in embedded systems. + Permanent } /// A single memory mapping for [MemoryMap]. @@ -27,17 +31,20 @@ pub trait MemoryMapping { /// Returns the type of the memory. fn get_type(&self) -> MemoryType; /// Returns the beginning of the memory. - fn get_start(&self) -> usize; + fn get_start(&self) -> u64; /// Returns the length of the memory. - fn get_length(&self) -> usize; + fn get_length(&self) -> u64; } /// Memory mapping. -pub trait MemoryMap<'a>: core::iter::Iterator + core::ops::Index { +pub trait _MemoryMap: core::iter::Iterator + core::ops::Index { /// Returns the number of [MemoryMapping]s in the MemoryMap. This is total, not remainder. fn len(&self) -> usize; } +/// Memory mapping. Used so that we can downcast. +pub trait MemoryMap: _MemoryMap + core::any::Any {} + /// Bootloader-independent information. #[derive(Clone)] pub struct BootInfo<'a> { @@ -46,7 +53,7 @@ pub struct BootInfo<'a> { pub cmdline: Option<&'static str>, /// The memory map provided by the bootloader. If None, the kernel will attempt to generate it. - pub memory_map: Option<&'a dyn MemoryMap<'a>>, + pub memory_map: Option<&'a dyn MemoryMap>, /// The name of the bootloader(for example, "GRUB 2.12"). pub bootloader_name: Option<&'static str>, diff --git a/kernel/src/include/multiboot2.rs b/kernel/src/include/multiboot2.rs index 550aa9c..3589ee9 100644 --- a/kernel/src/include/multiboot2.rs +++ b/kernel/src/include/multiboot2.rs @@ -1,38 +1,5 @@ //! Definitions of structs for multiboot2 information. Mostly used during pre-userspace. -/// Used when a CString is passed. Move into separate file? -#[derive(Clone, Copy)] -pub struct CString { - /// The raw pointer to the string. - pub ptr: *const u8, - /// The length of the string, excluding the null byte(\0) at the end. - pub len: usize, -} - -impl core::ops::Index for CString { - type Output = u8; - fn index(&self, index: usize) -> &Self::Output { - unsafe { - if index>self.len { - panic!("index into CString too large"); - } - let mut ptr = self.ptr as usize; - ptr += index * size_of::(); - let ptr = ptr as *const u8; - &*ptr - } - } -} - -impl Into<&'static str> for CString { - fn into(self) -> &'static str { - unsafe { - let val: *const str = core::ptr::from_raw_parts(self.ptr, self.len); - return &*val; - } - } -} - /// Used for Multiboot2 tags. This shouldn't be used after a [BootInfo] struct has been initalized, but it still can be used. #[repr(C)] #[derive(Clone)] @@ -63,7 +30,7 @@ pub struct Module { pub mod_end: *const u8, /// A string that should be in the format `module_name (command line arguments)`. /// See https://github.com/AverseABFun/aphrodite/wiki/Plan/#Bootloader-modules (remember to update link later!). - pub mod_str: CString + pub mod_str: &'static core::ffi::CStr } /// One memory section provided by a Multiboot2 bootloader. @@ -81,6 +48,24 @@ pub struct MemorySection { reserved: u32, } +impl crate::boot::MemoryMapping for MemorySection { + fn get_type(&self) -> crate::boot::MemoryType { + match self.mem_type { + 1 => crate::boot::MemoryType::Free, + 2 => crate::boot::MemoryType::HardwareReserved, + 3 => crate::boot::MemoryType::HardwareSpecific(3, false), + 5 => crate::boot::MemoryType::Faulty, + _ => crate::boot::MemoryType::Reserved + } + } + fn get_start(&self) -> u64 { + self.base_addr + } + fn get_length(&self) -> u64 { + self.length + } +} + /// The raw memory map provided by a Multiboot2 bootloader. This is interpreted /// into a [MemoryMap]. #[repr(C)] @@ -106,6 +91,36 @@ pub struct MemoryMap { pub entry_size: u32, /// All sections. pub sections: &'static [MemorySection], + + /// Iterator's index. + pub idx: usize, +} + +impl crate::boot::MemoryMap for MemoryMap {} + +impl crate::boot::_MemoryMap for MemoryMap { + fn len(&self) -> usize { + self.sections.len() + } +} + +impl core::ops::Index for MemoryMap { + type Output = dyn crate::boot::MemoryMapping; + + fn index(&self, index: usize) -> &Self::Output { + &self.sections[index] as &'static dyn crate::boot::MemoryMapping + } +} + +impl core::iter::Iterator for MemoryMap { + type Item = &'static dyn crate::boot::MemoryMapping; + fn next(&mut self) -> Option { + self.idx += 1; + if self.sections.len()<=self.idx-1 { + return None; + } + Some(&self.sections[self.idx-1]) + } } /// A color descriptor for [ColorInfo::Palette]. @@ -177,7 +192,7 @@ pub struct FramebufferInfo { /// Boot info collected from provided [Tag]s. #[derive(Clone)] -pub struct BootInfo { +pub struct Multiboot2BootInfo { /// See https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Basic-memory-information. /// Tl;dr: mem_lower indicates the amount of "lower memory" /// and mem_upper the amount of "upper memory". @@ -192,7 +207,7 @@ pub struct BootInfo { /// We're provided with a C-style UTF-8(null-terminated UTF-8) string. This should contain the original pointer provided by /// the bootloader. /// See https://github.com/AverseABFun/aphrodite/wiki/Plan#bootloader (remember to update link later!) for the format. - pub cmdline: Option, + pub cmdline: Option<&'static core::ffi::CStr>, // Due to the way modules work, it's not easily possible to make a struct that contains all the modules. // Therefore, they are loaded on the fly. @@ -205,7 +220,7 @@ pub struct BootInfo { /// The name of the bootloader(for example, "GRUB 2.12"). C-style UTF-8(null-terminated UTF-8) string. /// This should contain the original pointer provided by the bootloader. - pub bootloader_name: Option, + pub bootloader_name: Option<&'static core::ffi::CStr>, // APM table is ignored as APM has been superseded by ACPI. If your system doesn't support ACPI, good luck. @@ -222,4 +237,4 @@ pub struct BootInfo { // EFI memory map and image handle pointers are not included for portability. // "Image load base physical address" is not included as at the moment the kernel is not relocatable. -} \ No newline at end of file +} diff --git a/kernel/src/include/traits.rs b/kernel/src/include/traits.rs index 17a589d..e9ce602 100644 --- a/kernel/src/include/traits.rs +++ b/kernel/src/include/traits.rs @@ -6,8 +6,8 @@ pub type Color = u8; /// Black-on-black. pub const COLOR_BLACK: Color = 0; -/// Should be whatever colors commonly used for status messages. -/// Generally should be white-on-black. +/// Should be whatever color commonly used for status messages. +/// Generally should be white-on-black. Value is one. pub const COLOR_DEFAULT: Color = 1; /// Some form of display that can be written too with text. diff --git a/kernel/src/internal/arch/x86/entry.rs b/kernel/src/internal/arch/x86_asmp/entry.rs similarity index 65% rename from kernel/src/internal/arch/x86/entry.rs rename to kernel/src/internal/arch/x86_asmp/entry.rs index 94a8002..ef2e815 100644 --- a/kernel/src/internal/arch/x86/entry.rs +++ b/kernel/src/internal/arch/x86_asmp/entry.rs @@ -8,10 +8,12 @@ #![feature(cfg_match)] use core::{arch::asm, ffi::CStr, panic::PanicInfo}; -use aphrodite::multiboot2::{BootInfo, CString, ColorInfo, FramebufferInfo, MemoryMap, MemorySection, PaletteColorDescriptor, RawMemoryMap, RootTag, Tag}; -use aphrodite::arch::x86::output::*; -use aphrodite::arch::x86::egatext as egatext; +use aphrodite::boot::BootInfo; +use aphrodite::multiboot2::{FramebufferInfo, MemoryMap, MemorySection, RawMemoryMap, RootTag, Tag}; +use aphrodite::arch::output::*; +use aphrodite::arch::egatext as egatext; use egatext::*; +use aphrodite::output::*; #[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))] #[unsafe(link_section = ".multiboot2")] @@ -25,26 +27,39 @@ static MULTIBOOT2_HEADER: [u8; 29] = [ // The root tag, provided directly from the multiboot2 bootloader. static mut RT: *const RootTag = core::ptr::null(); -// The boot info struct, created from all of the tags. -static mut BI: BootInfo = BootInfo { - mem_lower: None, - mem_upper: None, - cmdline: None, - memory_map: None, - bootloader_name: None, - framebuffer_info: None, - color_info: None, -}; // The raw pointer to bootloader-specific data. static mut O: *const u8 = core::ptr::null(); +static mut MM: MemoryMap = MemoryMap { + entry_size: 0, + version: 0, + sections: &[], + idx: 0, +}; + +static mut FBI: aphrodite::arch::egatext::FramebufferInfo = aphrodite::arch::egatext::FramebufferInfo { + address: 0, + pitch: 0, + width: 0, + height: 0, + bpp: 0, + change_cursor: false, +}; + // The magic number in eax. 0x36D76289 for multiboot2. static mut MAGIC: u32 = 0xFFFFFFFF; #[unsafe(link_section = ".start")] #[unsafe(no_mangle)] extern "C" fn _start() -> ! { + #[allow(non_snake_case)] + let mut BI: BootInfo<'static> = BootInfo { + cmdline: None, + memory_map: None, + bootloader_name: None, + output: None, + }; unsafe { // Copy values provided by the bootloader out // Aphrodite bootloaders pass values in eax and ebx, however rust doesn't know that it can't overwrite those. @@ -103,10 +118,6 @@ extern "C" fn _start() -> ! { if current_tag.tag_len != 16 { // Unexpected size, something is probably up panic!("size of basic memory information tag != 16"); } - - BI.mem_lower = Some(*((ptr + 8) as *const u32)); - BI.mem_upper = Some(*((ptr + 12) as *const u32)); - // The end result of the above is adding an offset to a pointer and retrieving the value at that pointer }, 5 => { // BIOS boot device, ignore if current_tag.tag_len != 20 { // Unexpected size, something is probably up @@ -120,13 +131,7 @@ extern "C" fn _start() -> ! { let cstring = CStr::from_ptr((ptr + 8) as *const i8); // creates a &core::ffi::CStr from the start of the command line... - let cstring = CString { - ptr: cstring.as_ptr() as *const u8, - len: cstring.to_bytes().len() - }; - // ...which can then be converted to a aphrodite::multiboot2::CString... - - BI.cmdline = Some(cstring); + BI.cmdline = Some(cstring.to_str().unwrap()); // ...before the BootInfo's commandline is set. }, 6 => { // Memory map tag @@ -139,11 +144,13 @@ extern "C" fn _start() -> ! { // The end result of the above is creating a *const RawMemoryMap that has the same address as current_tag // and has all of the [aphrodite::multiboot2::MemorySection]s for the memory map - BI.memory_map = Some(MemoryMap { + MM = MemoryMap { version: (*rawmemorymap).entry_version, entry_size: (*rawmemorymap).entry_size, sections: &*core::ptr::from_raw_parts((&(*rawmemorymap).sections[0]) as &MemorySection, (*rawmemorymap).sections.len()), - }); + idx: 0 + }; + BI.memory_map = Some(&MM); }, 2 => { // Bootloader name if current_tag.tag_len < 8 { // Unexpected size, something is probably up @@ -152,13 +159,7 @@ extern "C" fn _start() -> ! { let cstring = CStr::from_ptr((ptr + 8) as *const i8); // creates a &core::ffi::CStr from the start of the bootloader name... - let cstring = CString { - ptr: cstring.as_ptr() as *const u8, - len: cstring.to_bytes().len() - }; - // ...which can then be converted to a aphrodite::multiboot2::CString... - - BI.bootloader_name = Some(cstring); + BI.bootloader_name = Some(cstring.to_str().unwrap()); // ...before the BootInfo's bootloader_name is set. }, 8 => { // Framebuffer info @@ -166,33 +167,30 @@ extern "C" fn _start() -> ! { panic!("size of framebuffer info tag < 32"); } let framebufferinfo: *const FramebufferInfo = (ptr as usize + size_of::()) as *const FramebufferInfo; - let colorinfo: ColorInfo; match (*framebufferinfo).fb_type { 0 => { // Indexed - colorinfo = ColorInfo::Palette { - num_colors: *((ptr + 32) as *const u32), - palette: (ptr + 36) as *const PaletteColorDescriptor - }; + panic!("Indexed color is unimplemented"); }, 1 => { // RGB - colorinfo = ColorInfo::RGBColor { - red_field_position: *((ptr + 32) as *const u8), - red_mask_size: *((ptr + 33) as *const u8), - green_field_position: *((ptr + 34) as *const u8), - green_mask_size: *((ptr + 35) as *const u8), - blue_field_position: *((ptr + 36) as *const u8), - blue_mask_size: *((ptr + 37) as *const u8) - } + panic!("RGB color is unimplemented"); }, - 2 => { // EGA Text - colorinfo = ColorInfo::EGAText; + 2 => { // EGA Text }, _ => { panic!("unknown color info type") } } - BI.framebuffer_info = Some((*framebufferinfo).clone()); - BI.color_info = Some(colorinfo); + let framebuffer_info = (*framebufferinfo).clone(); + + FBI = egatext::FramebufferInfo { + address: framebuffer_info.address, + pitch: framebuffer_info.pitch, + width: framebuffer_info.width, + height: framebuffer_info.height, + bpp: framebuffer_info.bpp, + change_cursor: false, + }; + BI.output = Some(&FBI) }, _ => { // Unknown/unimplemented tag type, ignore swarnings("Unknown tag type "); @@ -232,9 +230,8 @@ extern "C" fn _start() -> ! { sdebugsln("Bootloader information has been successfully loaded"); soutputu(b'\n'); unsafe { - if BI.framebuffer_info.clone().is_some() { - let framebuffer_info = BI.framebuffer_info.clone().unwrap(); - let color_info = BI.color_info.clone().unwrap(); + if BI.output.clone().is_some() { + let framebuffer_info = FBI; sdebugs("Framebuffer width: "); sdebugbnpln(&aphrodite::u32_as_u8_slice(framebuffer_info.width)); @@ -246,68 +243,43 @@ extern "C" fn _start() -> ! { sdebugbnpln(&aphrodite::usize_as_u8_slice(framebuffer_info.address as usize)); sdebugs("Framebuffer bpp: "); sdebugbnpln(&aphrodite::u8_as_u8_slice(framebuffer_info.bpp)); - sdebugs("Framebuffer type: "); - sdebugbnp(&aphrodite::u8_as_u8_slice(framebuffer_info.fb_type)); + + sdebugsln("Beginning output to screen..."); - match framebuffer_info.fb_type { - 0 => { // Indexed - sdebugsnpln("(Indexed)"); - let ColorInfo::Palette{num_colors, palette: _} = color_info else { unreachable!() }; - sdebugs("Number of palette colors: "); - sdebugbnpln(&aphrodite::u32_as_u8_slice(num_colors)); - - sfatalsln("Halting CPU; Indexed color unimplemented"); - asm!("hlt", options(noreturn)); - }, - 1 => { // RGB - sdebugsnpln("(RGB)"); + let ega: &dyn aphrodite::TextDisplay = &framebuffer_info; + framebuffer_info.disable_cursor(); + ega.clear_screen(WHITE_ON_BLACK); + tdebugsln("Testing EGA Text framebuffer...", ega).unwrap(); + tdebugsln("Testing EGA Text framebuffer...", ega).unwrap(); + tdebugsln("Testing EGA Text framebuffer...", ega).unwrap(); - sfatalsln("Halting CPU; RGB color unimplemented"); - asm!("hlt", options(noreturn)); - }, - 2 => { // EGA Text - sdebugsnpln("(EGA Text)"); - sdebugsln("Beginning output to screen..."); - - let ega = egatext::FramebufferInfo { - address: framebuffer_info.address, - pitch: framebuffer_info.pitch, - width: framebuffer_info.width, - height: framebuffer_info.height, - bpp: framebuffer_info.bpp, - change_cursor: true, - }; - ega.clear_screen(WHITE_ON_BLACK); - ega.enable_cursor(14, 15); - ega.set_cursor_location((0, 0)); - tdebugsln("Testing EGA Text framebuffer...", ega).unwrap(); - tdebugsln("Testing EGA Text framebuffer...", ega).unwrap(); - tdebugsln("Testing EGA Text framebuffer...", ega).unwrap(); - - aphrodite::_entry::_entry(Some(ega), &BI); - }, - _ => { - unreachable!(); - } - } + aphrodite::_entry::_entry(Some(ega), &BI); } } - unsafe { - aphrodite::_entry::_entry(None, &BI); - } + aphrodite::_entry::_entry(None, &BI); } #[unsafe(link_section = ".panic")] #[panic_handler] #[cfg(not(CONFIG_HALT_ON_PANIC = "false"))] fn halt_on_panic(info: &PanicInfo) -> ! { + if info.location().is_some() { + sfatals("Panic at "); + sfatalsnp(info.location().unwrap().file()); + sfatalsnp(":"); + sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line())); + sfatalsnp(":"); + sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column())); + sfatalsnp(": "); + } else { + sfatals("Panic: "); + } let message = info.message().as_str().unwrap_or(""); if message != "" { - sfatals(message); - aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n'); + sfatalsnpln(message); } - aphrodite::arch::x86::interrupts::disable_interrupts(); + aphrodite::arch::interrupts::disable_interrupts(); unsafe { asm!("hlt", options(noreturn)); } @@ -317,11 +289,21 @@ fn halt_on_panic(info: &PanicInfo) -> ! { #[panic_handler] #[cfg(all(CONFIG_SPIN_ON_PANIC = "true", CONFIG_PREUSER_HALT_ON_PANIC = "false"))] fn spin_on_panic(info: &PanicInfo) -> ! { + if info.location().is_some() { + sfatals("Panic at "); + sfatalsnp(info.location().unwrap().file()); + sfatalsnp(":"); + sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line())); + sfatalsnp(":"); + sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column())); + sfatalsnp(": "); + } else { + sfatals("Panic: "); + } let message = info.message().as_str().unwrap_or(""); if message != "" { - sfatals(message); - aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n'); + sfatalsnpln(message); } - aphrodite::arch::x86::interrupts::disable_interrupts(); + aphrodite::arch::interrupts::disable_interrupts(); loop {} } \ No newline at end of file