working apic interrupts

This commit is contained in:
Zoe
2024-01-23 00:18:33 -06:00
parent 7b5f42f76a
commit 00037311c6
15 changed files with 378 additions and 69 deletions

View File

@@ -5,11 +5,13 @@ MODE ?= release
ARCH ?= x86_64 ARCH ?= x86_64
MEMORY ?= 512M MEMORY ?= 512M
# In MB # In MB
ISO_SIZE ?= 256 ISO_SIZE ?= 512
QEMU_OPTS ?= QEMU_OPTS ?=
MKSQUASHFS_OPTS ?= MKSQUASHFS_OPTS ?=
GDB ?= GDB ?=
ESP_BITS ?= 16 CPUS ?= 1
# FAT type
ESP_BITS ?= 32
ISO_PATH = ${ARTIFACTS_PATH}/iso_root ISO_PATH = ${ARTIFACTS_PATH}/iso_root
INITRAMFS_PATH = ${ARTIFACTS_PATH}/initramfs INITRAMFS_PATH = ${ARTIFACTS_PATH}/initramfs
@@ -22,6 +24,10 @@ ifeq (${MODE},release)
CARGO_OPTS += --release CARGO_OPTS += --release
endif endif
ifneq (${CPUS},1)
QEMU_OPTS += -smp ${CPUS}
endif
ifneq (${GDB},) ifneq (${GDB},)
QEMU_OPTS += -s -S QEMU_OPTS += -s -S
endif endif
@@ -118,16 +124,16 @@ partition-iso: copy-iso-files
dd if=/dev/zero of=${IMAGE_PATH} bs=1M count=0 seek=${ISO_SIZE} dd if=/dev/zero of=${IMAGE_PATH} bs=1M count=0 seek=${ISO_SIZE}
ifeq (${ISO_PARTITION_TYPE},GPT) ifeq (${ISO_PARTITION_TYPE},GPT)
parted -s ${IMAGE_PATH} mklabel gpt parted -s ${IMAGE_PATH} mklabel gpt
parted -s ${IMAGE_PATH} mkpart ESP fat${ESP_BITS} 2048s 34815s parted -s ${IMAGE_PATH} mkpart ESP fat${ESP_BITS} 2048s 262144s
else else
parted -s ${IMAGE_PATH} mklabel msdos parted -s ${IMAGE_PATH} mklabel msdos
parted -s ${IMAGE_PATH} mkpart primary fat${ESP_BITS} 2048s 34815s parted -s ${IMAGE_PATH} mkpart primary fat${ESP_BITS} 2048s 262144s
endif endif
# Make ISO with 1 partition starting at sector 2048 that is 32768 sectors, or 16MiB, in size # Make ISO with 1 partition starting at sector 2048 that is 32768 sectors, or 16MiB, in size
# Then a second partition spanning the rest of the disk # Then a second partition spanning the rest of the disk
parted -s ${IMAGE_PATH} mkpart primary 34816s 100% parted -s ${IMAGE_PATH} mkpart primary 262145s 100%
parted -s ${IMAGE_PATH} set 1 esp on parted -s ${IMAGE_PATH} set 1 esp on
build-iso: partition-iso copy-initramfs-files build-iso: partition-iso copy-initramfs-files

View File

@@ -34,8 +34,6 @@ struct Registers {
} }
extern "C" fn exception_handler(registers: u64) { extern "C" fn exception_handler(registers: u64) {
crate::println!("{:X?}", registers);
let registers = unsafe { *(registers as *const Registers) }; let registers = unsafe { *(registers as *const Registers) };
crate::println!("{:X?}", registers); crate::println!("{:X?}", registers);

View File

@@ -1,6 +1,9 @@
mod exceptions; mod exceptions;
use crate::{arch::x86_common::pic::ChainedPics, libs::mutex::Mutex}; use crate::{
arch::{apic, x86_common::pic::ChainedPics},
libs::mutex::Mutex,
};
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@@ -74,16 +77,24 @@ pub fn idt_set_gate(num: u8, function_ptr: usize) {
// If the interrupt with this number occurred with the "null" interrupt handler // If the interrupt with this number occurred with the "null" interrupt handler
// We will need to tell the PIC that interrupt is over, this stops new interrupts // We will need to tell the PIC that interrupt is over, this stops new interrupts
// From never firing because "it was never finished" // From never firing because "it was never finished"
PICS.lock().write().notify_end_of_interrupt(num); signal_end_of_interrupt(num);
} }
extern "x86-interrupt" fn null_interrupt_handler() {} extern "x86-interrupt" fn null_interrupt_handler() {
crate::log_info!("Unhandled interrupt!");
if apic::APIC.lock().read().is_some() {
apic::APIC
.lock()
.read()
.as_ref()
.unwrap()
.end_of_interrupt();
}
}
extern "x86-interrupt" fn timer_handler() { extern "x86-interrupt" fn timer_handler() {
// crate::usr::tty::puts("."); // crate::usr::tty::puts(".");
PICS.lock() signal_end_of_interrupt(InterruptIndex::Timer.as_u8());
.write()
.notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
} }
fn idt_init() { fn idt_init() {
@@ -114,6 +125,19 @@ fn idt_init() {
} }
} }
pub fn signal_end_of_interrupt(int: u8) {
if apic::APIC.lock().read().is_some() {
apic::APIC
.lock()
.read()
.as_ref()
.unwrap()
.end_of_interrupt();
} else {
PICS.lock().write().notify_end_of_interrupt(int);
}
}
#[naked] #[naked]
pub extern "C" fn syscall() { pub extern "C" fn syscall() {
unsafe { unsafe {

211
src/arch/x86_common/apic.rs Normal file
View File

@@ -0,0 +1,211 @@
use core::sync::atomic::AtomicBool;
use alloc::{boxed::Box, sync::Arc, vec::Vec};
use crate::{drivers::acpi::SDTHeader, libs::mutex::Mutex};
use super::{cpu_get_msr, cpu_set_msr, pic::ChainedPics};
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
struct MADT {
pub local_apic_address: u32,
pub flags: u32,
}
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
struct MADTEntry {}
impl MADT {
pub fn as_ptr(&self) -> *const u8 {
core::ptr::addr_of!(self).cast::<u8>()
}
}
const IA32_APIC_BASE_MSR: u32 = 0x1B;
const IA32_APIC_BASE_MSR_ENABLE: usize = 0x800;
pub fn has_apic() -> bool {
return unsafe { core::arch::x86_64::__cpuid_count(1, 0).edx } & 1 << 9 != 0;
}
fn set_apic_base(apic: usize) {
let edx: u32 = 0;
let eax = (apic & 0xfffff0000) | IA32_APIC_BASE_MSR_ENABLE;
unsafe { cpu_set_msr(IA32_APIC_BASE_MSR, &(eax as u32), &edx) };
}
fn get_apic_base() -> u32 {
let mut eax: u32 = 0;
let mut edx: u32 = 0;
unsafe { cpu_get_msr(IA32_APIC_BASE_MSR, &mut eax, &mut edx) };
return eax & 0xfffff000;
}
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct LAPIC {
pub acpi_processor_id: u8,
pub apic_id: u8,
pub flags: u32,
}
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct IOAPIC {
pub ioapic_id: u8,
_reserved: u8,
pub ptr: *mut u8,
pub global_interrupt_base: u32,
}
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct IOAPICSourceOverride {
bus_source: u8,
irq_source: u8,
global_system_interrupt: u32,
flags: u16,
}
#[derive(Debug)]
pub struct APIC {
pub io_apic: IOAPIC,
local_apic: *mut u8,
pub cpus: Arc<[LAPIC]>,
}
impl APIC {
pub fn new() -> Result<Self, ()> {
if !has_apic() {
return Err(());
}
let apic_base = get_apic_base() as usize;
set_apic_base(apic_base);
let madt = crate::drivers::acpi::find_table::<MADT>("APIC");
if madt.is_none() {
return Err(());
}
let mut cpus: Vec<LAPIC> = Vec::new();
let madt = madt.unwrap();
crate::log_info!("MADT located at: {:p}", core::ptr::addr_of!(madt));
let mut lapic_ptr = madt.inner.local_apic_address as *mut u8;
let mut io_apic = None;
let mut io_apic_source_override = None;
let mut ptr = madt.extra.unwrap().as_ptr();
let ptr_end = unsafe { ptr.add(madt.header.length as usize - 44) };
while (ptr as usize) < (ptr_end as usize) {
match unsafe { *ptr } {
0 => {
if unsafe { *(ptr.add(4)) } & 1 != 0 {
cpus.push(unsafe { *ptr.add(2).cast::<LAPIC>() });
}
}
1 => unsafe {
io_apic = Some(IOAPIC {
ioapic_id: *ptr.add(2),
_reserved: *ptr.add(3),
ptr: (*ptr.add(4).cast::<u32>()) as *mut u8,
global_interrupt_base: *ptr.add(8).cast::<u32>(),
})
},
2 => unsafe {
io_apic_source_override = Some(IOAPICSourceOverride {
bus_source: *ptr.add(2),
irq_source: *ptr.add(3),
global_system_interrupt: *ptr.add(4).cast::<u32>(),
flags: *ptr.add(8).cast::<u16>(),
})
},
5 => lapic_ptr = unsafe { *(ptr.add(4).cast::<u64>()) } as *mut u8,
_ => {}
}
ptr = unsafe { ptr.add((*ptr.add(1)) as usize) };
}
if io_apic.is_none() || io_apic_source_override.is_none() {
return Err(());
}
let io_apic_ptr = io_apic.unwrap().ptr;
crate::println!(
"Found {} cores, IOAPIC {:p}, LAPIC {lapic_ptr:p}, Processor IDs:",
cpus.len(),
io_apic_ptr,
);
for apic in &cpus {
crate::println!(" {}", apic.acpi_processor_id);
}
let apic = Self {
io_apic: io_apic.unwrap(),
local_apic: lapic_ptr,
cpus: cpus.into(),
};
apic.write_lapic(0xF0, apic.read_lapic(0xF0) | 0x100);
let io_apic_ver = apic.read_ioapic(0x01);
let number_of_inputs = ((io_apic_ver >> 16) & 0xFF) + 1;
crate::println!("{number_of_inputs}");
// Take the keyboard vector table, then mask out the top most bit (interrupt mask), then,
// mask out the bottom 8 bits, and put the kbd int in it setting the interrupt vector
let keyboard_vt = ((apic.read_ioapic(0x12) & 0x7FFF) & 0xFF00) | 0x21;
// enable keyboard interrupt
apic.write_ioapic(0x12, keyboard_vt);
return Ok(apic);
}
pub fn read_ioapic(&self, reg: u32) -> u32 {
unsafe {
core::ptr::write_volatile(self.io_apic.ptr.cast::<u32>(), reg & 0xff);
return core::ptr::read_volatile(self.io_apic.ptr.cast::<u32>().add(4));
}
}
pub fn write_ioapic(&self, reg: u32, value: u32) {
unsafe {
core::ptr::write_volatile(self.io_apic.ptr.cast::<u32>(), reg & 0xff);
core::ptr::write_volatile(self.io_apic.ptr.cast::<u32>().add(4), value);
}
}
pub fn read_lapic(&self, reg: u32) -> u32 {
unsafe {
return *self.local_apic.add(reg as usize).cast::<u32>();
}
}
pub fn write_lapic(&self, reg: u32, value: u32) {
unsafe {
*self.local_apic.add(reg as usize).cast::<u32>() = value;
}
}
pub fn end_of_interrupt(&self) {
self.write_lapic(0xB0, 0x00);
}
}
pub static APIC: Mutex<Option<APIC>> = Mutex::new(None);

View File

@@ -1,3 +1,4 @@
pub mod apic;
pub mod io; pub mod io;
pub mod pic; pub mod pic;
pub mod stack_trace; pub mod stack_trace;
@@ -9,3 +10,27 @@ pub fn pause() {
core::arch::asm!("pause"); core::arch::asm!("pause");
}; };
} }
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[inline(always)]
pub fn cpu_has_msr() -> bool {
return unsafe { core::arch::x86_64::__cpuid_count(1, 0).edx } & 1 << 5 != 0;
}
pub unsafe fn cpu_get_msr(msr: u32, lo: &mut u32, hi: &mut u32) {
core::arch::asm!(
"rdmsr",
in("ecx") msr,
inout("eax") *lo,
inout("edx") *hi,
);
}
pub unsafe fn cpu_set_msr(msr: u32, lo: &u32, hi: &u32) {
core::arch::asm!(
"wrmsr",
in("ecx") msr,
in("eax") *lo,
in("edx") *hi,
);
}

View File

@@ -1,6 +1,6 @@
use alloc::{borrow::ToOwned, format, string::String, vec::Vec}; use alloc::{borrow::ToOwned, string::String, vec::Vec};
use crate::drivers::{fs::vfs::VfsFileSystem, serial::write_serial}; use crate::drivers::fs::vfs::VfsFileSystem;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@@ -20,6 +20,13 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) {
let instruction_pointer = unsafe { (*stackframe).rip }; let instruction_pointer = unsafe { (*stackframe).rip };
if instruction_pointer == 0x0 {
unsafe {
stackframe = (*stackframe).back;
};
continue;
}
crate::print!(" {:#X} ", instruction_pointer); crate::print!(" {:#X} ", instruction_pointer);
let instrcution_info = get_function_name(instruction_pointer); let instrcution_info = get_function_name(instruction_pointer);

View File

@@ -1,16 +1,13 @@
// TODO: reduce the need to derive(Clone, Copy) everything use alloc::vec::Vec;
use alloc::{sync::Arc, vec::Vec};
use crate::{ use crate::{
arch::io::{inw, outb}, arch::io::{inw, outb},
libs::{lazy::Lazy, mutex::Mutex, oncecell::OnceCell}, libs::oncecell::OnceCell,
log_info,
}; };
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
struct SDTHeader { pub struct SDTHeader {
pub signature: [u8; 4], pub signature: [u8; 4],
pub length: u32, pub length: u32,
pub revision: u8, pub revision: u8,
@@ -23,23 +20,40 @@ struct SDTHeader {
} }
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy, Debug)] #[derive(Debug)]
pub struct SDT<T> { pub struct SDT<'a, T> {
pub header: SDTHeader, pub header: &'a SDTHeader,
pub inner: T, pub inner: &'a T,
pub extra: Option<&'a [u8]>,
} }
impl<T: Copy> SDT<T> { impl<'a, T> SDT<'a, T> {
unsafe fn new(pointer: *mut u8) -> Self { unsafe fn new(ptr: *const u8) -> Self {
let header = *(pointer.cast::<SDTHeader>()); let length = core::ptr::read_unaligned(ptr.add(4).cast::<u32>());
let inner = *(pointer.add(core::mem::size_of::<SDTHeader>()).cast::<T>()); let data = core::slice::from_raw_parts(ptr, length as usize);
return Self { header, inner }; crate::log_serial!("SDT at: {ptr:p}");
assert!(data.len() == length as usize);
let header: &SDTHeader = core::mem::transmute(data[0..].as_ptr());
let inner: &T = core::mem::transmute(data[core::mem::size_of::<SDTHeader>()..].as_ptr());
let mut extra = None;
if length as usize > core::mem::size_of::<SDTHeader>() + core::mem::size_of::<T>() {
extra = Some(&data[core::mem::size_of::<SDTHeader>() + core::mem::size_of::<T>()..]);
}
return Self {
header,
inner,
extra,
};
} }
} }
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Debug)] #[derive(Clone, Copy, Debug)]
struct RSDP { struct RSDP {
signature: [u8; 8], signature: [u8; 8],
checksum: u8, checksum: u8,
@@ -49,6 +63,7 @@ struct RSDP {
} }
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Debug)]
struct XSDP { struct XSDP {
rsdp: RSDP, rsdp: RSDP,
@@ -70,17 +85,17 @@ struct XSDT {
pointers: u64, pointers: u64,
} }
#[derive(Clone, Copy, Debug)] #[derive(Debug)]
enum RootSDT { enum RootSDT<'a> {
RSDT(SDT<RSDT>), RSDT(SDT<'a, RSDT>),
XSDT(SDT<XSDT>), XSDT(SDT<'a, XSDT>),
} }
impl RootSDT { impl<'a> RootSDT<'a> {
fn header(&self) -> SDTHeader { fn header(&self) -> SDTHeader {
return match self { return match self {
&RootSDT::RSDT(RSDT) => RSDT.header, RootSDT::RSDT(RSDT) => *RSDT.header,
&RootSDT::XSDT(XSDT) => XSDT.header, RootSDT::XSDT(XSDT) => *XSDT.header,
}; };
} }
@@ -97,12 +112,12 @@ impl RootSDT {
let mut offset = 0; let mut offset = 0;
let root_ptr = match self { let root_ptr = match self {
&RootSDT::RSDT(RSDT) => { RootSDT::RSDT(RSDT) => {
let ptrs = RSDT.inner.pointers as *const u8; let ptrs = RSDT.inner.pointers as *const u8;
assert!(!ptrs.is_null()); assert!(!ptrs.is_null());
ptrs.add(offset) ptrs.add(offset)
} }
&RootSDT::XSDT(XSDT) => { RootSDT::XSDT(XSDT) => {
let ptrs = XSDT.inner.pointers as *const u8; let ptrs = XSDT.inner.pointers as *const u8;
assert!(!ptrs.is_null()); assert!(!ptrs.is_null());
ptrs.add(offset) ptrs.add(offset)
@@ -110,19 +125,17 @@ impl RootSDT {
}; };
for _ in 0..idx { for _ in 0..idx {
let header = *root_ptr.add(offset).cast::<SDTHeader>(); let header: &SDTHeader = core::mem::transmute(root_ptr.add(offset).cast::<SDTHeader>());
offset += header.length as usize; offset += header.length as usize;
} }
crate::println!("{offset:X?} {idx}");
return root_ptr.add(offset); return root_ptr.add(offset);
} }
} }
#[derive(Clone, Debug)] #[derive(Debug)]
struct ACPI { struct ACPI<'a> {
root_sdt: RootSDT, root_sdt: RootSDT<'a>,
tables: Vec<[u8; 4]>, tables: Vec<[u8; 4]>,
} }
@@ -138,8 +151,6 @@ fn resolve_acpi() {
let rsdp = unsafe { &*rsdp_ptr.unwrap().address.as_ptr().unwrap().cast::<RSDP>() }; let rsdp = unsafe { &*rsdp_ptr.unwrap().address.as_ptr().unwrap().cast::<RSDP>() };
log_info!("RSDP: {rsdp:X?}");
// TODO: validate RSDT // TODO: validate RSDT
let root_sdt = { let root_sdt = {
if rsdp.revision == 0 { if rsdp.revision == 0 {
@@ -150,8 +161,6 @@ fn resolve_acpi() {
} }
}; };
log_info!("{root_sdt:X?}");
let tables: Vec<[u8; 4]> = (0..root_sdt.len()) let tables: Vec<[u8; 4]> = (0..root_sdt.len())
.map(|i| { .map(|i| {
let sdt_ptr = unsafe { root_sdt.get(i) }; let sdt_ptr = unsafe { root_sdt.get(i) };
@@ -243,19 +252,35 @@ struct FADT {
pub fn init_acpi() { pub fn init_acpi() {
resolve_acpi(); resolve_acpi();
crate::log_ok!("Found {} ACPI Tables!", ACPI.tables.len());
crate::log_serial!("Available serial tables:");
for i in 0..ACPI.tables.len() {
crate::log_serial!(" {}", core::str::from_utf8(&ACPI.tables[i]).unwrap())
}
let fadt = find_table::<FADT>("FACP").expect("Failed to find FADT"); let fadt = find_table::<FADT>("FACP").expect("Failed to find FADT");
crate::println!("{fadt:X?}"); outb(fadt.inner.smi_cmd_port as u16, fadt.inner.acpi_enable);
while inw(fadt.inner.pm1a_control_block as u16) & 1 == 0 {}
crate::arch::interrupts::PICS.lock().write().disable();
*crate::arch::apic::APIC.lock().write() =
Some(crate::arch::apic::APIC::new().expect("Failed to enable APIC!"));
crate::log_ok!("APIC enabled!");
} }
pub fn find_table<T: Copy>(table_name: &str) -> Option<SDT<T>> { pub fn find_table<T>(table_name: &str) -> Option<SDT<T>> {
assert_eq!(table_name.len(), 4); assert_eq!(table_name.len(), 4);
for (i, table) in ACPI.tables.iter().enumerate() { for (i, table) in ACPI.tables.iter().enumerate() {
if table == table_name.as_bytes() { if table == table_name.as_bytes() {
let ptr = unsafe { ACPI.root_sdt.get(i).cast::<SDT<T>>() }; let ptr = unsafe { ACPI.root_sdt.get(i) };
crate::println!("Found {table_name} at index {i} {ptr:p}");
let table = unsafe { *ptr }; let table = unsafe { SDT::new(ptr) };
return Some(table); return Some(table);
} }
} }

View File

@@ -21,10 +21,7 @@ static EXTENDED_KEY: AtomicBool = AtomicBool::new(false);
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub extern "x86-interrupt" fn keyboard_interrupt_handler() { pub extern "x86-interrupt" fn keyboard_interrupt_handler() {
interrupts::PICS interrupts::signal_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
.lock()
.write()
.notify_end_of_interrupt(interrupts::InterruptIndex::Keyboard.as_u8());
let scancode = inb(KBD_DATA_PORT); let scancode = inb(KBD_DATA_PORT);

View File

@@ -1,3 +1,4 @@
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod acpi; pub mod acpi;
pub mod fs; pub mod fs;
pub mod keyboard; pub mod keyboard;

View File

@@ -42,6 +42,14 @@ pub fn init_serial() -> u8 {
return 0; return 0;
} }
pub fn write_string(string: &str) {
for &ch in string.as_bytes() {
write_serial(ch as char);
}
write_serial('\n');
write_serial('\r');
}
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
pub fn init_serial() -> u8 { pub fn init_serial() -> u8 {
return 0; return 0;

View File

@@ -241,6 +241,9 @@ impl ATABus {
outb(self.io_bar + ATADriveDataRegister::LBA1 as u16, 0); outb(self.io_bar + ATADriveDataRegister::LBA1 as u16, 0);
outb(self.io_bar + ATADriveDataRegister::LBA2 as u16, 0); outb(self.io_bar + ATADriveDataRegister::LBA2 as u16, 0);
// disable interrupts by setting bit 2 in the control port
outb(self.control_bar + 0x0C - 0x0A, 2);
self.send_command(ATADriveCommand::Identify); self.send_command(ATADriveCommand::Identify);
if self.status() == 0x00 { if self.status() == 0x00 {

View File

@@ -3,6 +3,13 @@ macro_rules! log_info {
($($arg:tt)*) => ($crate::println!("\033[97m[ \033[90m? \033[97m]\033[0m {}", &alloc::format!($($arg)*))); ($($arg:tt)*) => ($crate::println!("\033[97m[ \033[90m? \033[97m]\033[0m {}", &alloc::format!($($arg)*)));
} }
#[macro_export]
macro_rules! log_serial {
($($arg:tt)*) => (
$crate::drivers::serial::write_string(&alloc::format!($($arg)*))
);
}
#[macro_export] #[macro_export]
macro_rules! log_error { macro_rules! log_error {
($($arg:tt)*) => ($crate::println!("\033[97m[ \033[91m! \033[97m]\033[0m {}", &alloc::format!($($arg)*))); ($($arg:tt)*) => ($crate::println!("\033[97m[ \033[91m! \033[97m]\033[0m {}", &alloc::format!($($arg)*)));

View File

@@ -28,10 +28,11 @@ pub extern "C" fn _start() -> ! {
serial::init_serial(); serial::init_serial();
mem::log_info(); #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
drivers::acpi::init_acpi(); drivers::acpi::init_acpi();
mem::log_info();
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
drivers::pci::enumerate_pci_bus(); drivers::pci::enumerate_pci_bus();

View File

@@ -137,17 +137,13 @@ pub fn log_memory_map() {
let memmap = memmap_request.unwrap().memmap(); let memmap = memmap_request.unwrap().memmap();
crate::println!("====== MEMORY MAP ======"); crate::log_serial!("====== MEMORY MAP ======");
for entry in memmap.iter() { for entry in memmap.iter() {
let label = (entry.len as usize).label_bytes(); let label = (entry.len as usize).label_bytes();
crate::println!( crate::log_serial!(
"[ {:#018X?} ] Type: \033[{};m{:?}\033[0;m Size: {}", "[ {:#018X?} ] Type: {:?} Size: {}",
entry.base..entry.base + entry.len, entry.base..entry.base + entry.len,
match entry.typ {
limine::MemoryMapEntryType::Usable => 32,
_ => 31,
},
entry.typ, entry.typ,
label label
) )