Skip to content
This repository has been archived by the owner on Dec 11, 2024. It is now read-only.

Commit

Permalink
Add logger for both serial and console
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanPlant committed Feb 22, 2024
1 parent e3d07af commit 9922b05
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 49 deletions.
42 changes: 39 additions & 3 deletions charlotte_core/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@ pub mod riscv64;
#[cfg(target_arch = "x86_64")]
pub mod x86_64;

use core::fmt::Write;
use core::fmt::{Write, Result};

use spin::{lazy::Lazy, mutex::TicketMutex};

use crate::framebuffer::console::CONSOLE;

pub static LOGGER: Lazy<TicketMutex<Logger>> = Lazy::new(|| TicketMutex::new(Logger {
logger: <ArchApi as Api>::get_logger(),
}));

pub trait Api {
type Logger: Write;
type DebugLogger: Write;

fn get_logger() -> Self::Logger;
fn get_logger() -> Self::DebugLogger;
fn get_paddr_width() -> u8;
fn get_vaddr_width() -> u8;
fn halt() -> !;
Expand All @@ -27,6 +35,34 @@ pub trait Api {
fn init_ap();
}

/// A logger that writes to both the framebuffer console and the serial port.
pub struct Logger {
logger: <ArchApi as Api>::DebugLogger,
}

impl Write for Logger {
fn write_str(&mut self, s: &str) -> Result {
write!(self.logger, "{}", s).unwrap();
write!(CONSOLE.lock(), "{}", s).unwrap();
Ok(())
}
}

#[macro_export]
macro_rules! log {
($($arg:tt)*) => {
$crate::arch::LOGGER.lock().write_fmt(format_args!($($arg)*)).unwrap();
};
}

#[macro_export]
macro_rules! logln {
($($arg:tt)*) => {
$crate::arch::LOGGER.lock().write_fmt(format_args!($($arg)*)).unwrap();
$crate::arch::LOGGER.lock().write_str("\n").unwrap();
};
}

#[cfg(target_arch = "x86_64")]
pub type ArchApi = x86_64::Api;
#[cfg(target_arch = "aarch64")]
Expand Down
30 changes: 14 additions & 16 deletions charlotte_core/src/arch/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ use cpu::*;
use spin::lazy::Lazy;
use spin::mutex::spin::SpinMutex;

use ignore_result::Ignore;

use gdt::{tss::Tss, Gdt};

use serial::{ComPort, SerialPort};

use idt::*;

use crate::logln;

/// The Api struct is used to provide an implementation of the ArchApi trait for the x86_64 architecture.
pub struct Api;

Expand All @@ -40,10 +40,10 @@ static BSP_IDT: SpinMutex<Idt> = SpinMutex::new(Idt::new());
/// Provide the implementation of the Api trait for the Api struct
impl crate::arch::Api for Api {
/// Define the logger type
type Logger = SerialPort;
type DebugLogger = SerialPort;

/// Get a new logger instance
fn get_logger() -> Self::Logger {
fn get_logger() -> Self::DebugLogger {
SerialPort::try_new(ComPort::COM1).unwrap()
}
/// Get the number of significant physical address bits supported by the current CPU
Expand Down Expand Up @@ -76,31 +76,29 @@ impl crate::arch::Api for Api {
let mut logger = SerialPort::try_new(ComPort::COM1).unwrap();

writeln!(&mut logger, "Initializing the bootstrap processor...").ignore();
logln!("Initializing the bootstrap processor...");

BSP_GDT.load();
writeln!(&mut logger, "Loaded GDT").ignore();
logln!("Loaded GDT");
Gdt::reload_segment_regs();
writeln!(&mut logger, "Reloaded segment registers").ignore();
logln!("Reloaded segment registers");
Gdt::load_tss();
writeln!(&mut logger, "Loaded TSS").ignore();
logln!("Loaded TSS");

writeln!(&mut logger, "Registering exception ISRs in the IDT").ignore();
logln!("Registering exception ISRs in the IDT");
exceptions::load_exceptions(BSP_IDT.lock().borrow_mut());
writeln!(&mut logger, "Exception ISRs registered").ignore();
logln!("Exception ISRs registered");

writeln!(&mut logger, "Attempting to load IDT").ignore();
logln!("Attempting to load IDT");
BSP_IDT.lock().borrow().load();
writeln!(&mut logger, "Loaded IDT").ignore();
logln!("Loaded IDT");

let mut vendor_string = [0u8; 12];
unsafe { cpu::cpuid::asm_get_vendor_string(&mut vendor_string) }
writeln!(
&mut logger,
logln!(
"CPU Vendor ID: {}",
str::from_utf8(&vendor_string).unwrap()
)
.unwrap();
);
}
///
/// Initialize the application processors (APs)
Expand Down
41 changes: 11 additions & 30 deletions charlotte_core/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,52 +21,33 @@ unsafe extern "C" fn main() -> ! {
FRAMEBUFFER.lock().clear_screen(0x00000000);
println!("Hello, world!");

write!(&mut logger, "Initializing BSP\n").unwrap();
logln!("Initializing BSP");
ArchApi::init_bsp();
write!(&mut logger, "BSP Initialized\n").unwrap();
logln!("BSP Initialized");

write!(&mut logger, "All tests in main passed.\n").unwrap();
logln!("All tests in main passed.");

writeln!(
&mut logger,
"Number of Significant Physical Address Bits Supported: {}",
ArchApi::get_paddr_width()
)
.unwrap();
logln!("Number of Significant Physical Address Bits Supported: {}", ArchApi::get_paddr_width());
logln!("Number of Significant Virtual Address Bits Supported: {}", ArchApi::get_vaddr_width());

writeln!(
&mut logger,
"Number of Significant Virtual Address Bits Supported: {}",
ArchApi::get_vaddr_width()
)
.unwrap();

writeln!(&mut logger, "Testing physical frame allocator").unwrap();
logln!("Testing physical frame allocator");
let mut pfa = PFA.lock();
match pfa.allocate_frames(50, None) {
Ok(region_descriptor) => {
writeln!(&mut logger, "Allocated region: {:?}", region_descriptor).unwrap();
logln!("Allocated region: {:?}", region_descriptor);
let _ = pfa.deallocate_frames(region_descriptor);
writeln!(&mut logger, "Deallocated previously allocated region.").unwrap();
logln!("Deallocated previously allocated region.");
}
Err(e) => {
writeln!(&mut logger, "Failed to allocate region with error {:?}", e).unwrap();
logln!("Failed to allocate region with error {:?}", e);
}
}
ArchApi::halt()
}

#[panic_handler]
fn rust_panic(_info: &core::panic::PanicInfo) -> ! {
ArchApi::get_logger()
.write_fmt(format_args!(
"A kernel panic has occurred due to a Rust runtime panic.\n PanicInfo: {:?}\n",
_info
))
.unwrap();
println!(
"A kernel panic has occurred due to a Rust runtime panic.\n PanicInfo: {:?}\n",
_info
);
logln!("A kernel panic has occurred due to a Rust runtime panic.");
logln!("PanicInfo: {:?}", _info);
ArchApi::panic()
}

0 comments on commit 9922b05

Please sign in to comment.