From 53fca0478670fb4e8175b293b01948c51c89b11b Mon Sep 17 00:00:00 2001 From: JohnyTheCarrot Date: Sat, 15 Jul 2023 14:47:46 +0200 Subject: [PATCH] x86_64: Refactor device info fetching --- .gitignore | 1 + kernel/src/allocator.rs | 2 +- .../src/arch/x86_64/device_info_collector.rs | 67 ++++++++++++++++ kernel/src/arch/x86_64/mod.rs | 76 +------------------ kernel/src/arch/x86_64/pci/mod.rs | 13 ++-- kernel/src/device_tree.rs | 2 +- kernel/src/scheduler.rs | 4 +- 7 files changed, 82 insertions(+), 83 deletions(-) create mode 100644 kernel/src/arch/x86_64/device_info_collector.rs diff --git a/.gitignore b/.gitignore index 2f7896d1..fa56bbb5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ target/ +/.idea \ No newline at end of file diff --git a/kernel/src/allocator.rs b/kernel/src/allocator.rs index 6e162f69..5329844e 100644 --- a/kernel/src/allocator.rs +++ b/kernel/src/allocator.rs @@ -341,5 +341,5 @@ unsafe impl Send for Heap {} fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! { log::error!("allocation error: {:?}", layout); // Todo: Maybe panic here instead - crate::arch::sloop() + crate::arch::spin_loop() } diff --git a/kernel/src/arch/x86_64/device_info_collector.rs b/kernel/src/arch/x86_64/device_info_collector.rs new file mode 100644 index 00000000..4430f3aa --- /dev/null +++ b/kernel/src/arch/x86_64/device_info_collector.rs @@ -0,0 +1,67 @@ +use { + crate::{ + arch::{pci, x86_64::cpuid}, + device_tree::DeviceTree, + kmain::DEVICE_TREE, + }, + limine::SmpRequest, + xml::XMLElement, +}; + +fn collect_cpu_info(device_tree: &mut DeviceTree) { + use crate::alloc::string::ToString; + + static SMP: SmpRequest = SmpRequest::new(0); + let smp_response = SMP.get_response().get().unwrap(); + + let mut cpu = XMLElement::new("cpu"); + + // Get the amount of cores on the CPU + let core_count = smp_response.cpu_count.to_string(); + cpu.set_attribute("core count", core_count); + for x in 0..smp_response.cpu_count { + let core_name = alloc::format!("core_{}", x); + let core = XMLElement::new(core_name); + cpu.set_child(core); + } + + let cpu_info = cpuid::master().unwrap(); + + let brand_string = cpu_info.brand_string().unwrap_or("Unknown").to_string(); + cpu.set_attribute("brand string", brand_string); + + cpu.set_attribute("speed", "unknown"); + + // Get CPU features and add them to the device tree entry. + let mut cpu_features = XMLElement::new("CPU Features"); + for (feature_key, feature_enabled) in cpu_info.features() { + cpu_features.set_attribute(feature_key, feature_enabled.to_string()); + } + cpu.set_child(cpu_features); + + // CPU temperature + if cpu_info.digital_temperature_sensor() { + let mut temperature_child = XMLElement::new("Temperature"); + + temperature_child.set_attribute("degrees", "Unknown"); + cpu.set_child(temperature_child); + } + + // Add CPU to device tree + let cpus = device_tree.devices.get_mut("CPUs").unwrap(); + cpus.push(cpu); +} + +pub fn collect_device_info() { + // Lock device tree + unsafe { + DEVICE_TREE.force_unlock(); + } + let device_tree = &mut DEVICE_TREE.lock(); + + // Generate device tree from PCI enumeration. + pci::init(device_tree); + + // Collect CPU info and add it to the device tree + collect_cpu_info(device_tree); +} diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index a7d141f2..9bce2071 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -1,8 +1,6 @@ -use {limine::SmpRequest, xml::XMLElement}; - use embedded_graphics::pixelcolor::Rgb888; -use crate::{arch::x86_64::graphics::DISPLAY, bootmodules::BootModule, kmain::DEVICE_TREE}; +use crate::{arch::x86_64::graphics::DISPLAY, bootmodules::BootModule}; pub mod memory; @@ -13,6 +11,7 @@ pub(crate) mod interrupts; pub mod logging; pub mod pci; pub mod virtio; +mod device_info_collector; pub use {logging::log, memory::PAGE_SIZE}; @@ -62,74 +61,7 @@ unsafe extern "C" fn _kernel_start() -> ! { static KFILE_REQ: KernelFileRequest = KernelFileRequest::new(0); static MOD_REQ: ModuleRequest = ModuleRequest::new(0); - static SMP: SmpRequest = SmpRequest::new(0); - let smp = SMP.get_response().get().unwrap(); - use crate::alloc::string::ToString; - - let cpuinfo = cpuid::master().unwrap(); - let brand_string = cpuinfo.brand_string().unwrap_or("Unknown").to_string(); - DEVICE_TREE.force_unlock(); - - pci::init(); - - let mut dt = DEVICE_TREE.lock(); - - let cpus = dt.devices.get_mut("CPUs").unwrap(); - let mut cpu = XMLElement::new("cpu"); - let core_count = smp.cpu_count.to_string(); - cpu.set_attribute("core count", core_count); - for x in 0..smp.cpu_count { - let core_name = alloc::format!("core_{}", x); - let core = XMLElement::new(core_name); - cpu.set_child(core); - } - - cpu.set_attribute("brand string", brand_string); - - let _cpu_speed = 0; - - cpu.set_attribute("speed", "unknown"); - - if false { - // disable() // disable interrupts (if still not done) - let _i = 0; - let start = cpuinfo.time_stamp_counter(); - - log::info!("{:?}", start.unwrap().invariant_tsc()); - for _x in 0..1000 {} - let _end = cpuinfo.time_stamp_counter(); - } - - let mut cpu_features = xml::XMLElement::new("CPU Features"); - { - cpuinfo.version_information().unwrap(); - let apic = cpuinfo.apic(); - let avx = cpuinfo.avx(); - let avx2 = cpuinfo.avx2(); - let x2 = cpuinfo.x2apic(); - - let gb_pages = cpuinfo.gigabyte_pages(); - let rdseed = cpuinfo.rdseed(); - let rdrand = cpuinfo.rdrand(); - - cpu_features.set_attribute("apic", apic.to_string()); - cpu_features.set_attribute("avx", avx.to_string()); - cpu_features.set_attribute("avx2", avx2.to_string()); - cpu_features.set_attribute("gigabyte pages", gb_pages.to_string()); - cpu_features.set_attribute("rdrand", rdrand.to_string()); - cpu_features.set_attribute("rdseed", rdseed.to_string()); - cpu_features.set_attribute("x2apic", x2.to_string()); - } - if cpuinfo.digital_temperature_sensor() { - let mut temperature_child = XMLElement::new("Temperature"); - - temperature_child.set_attribute("degrees", "Unknown"); - cpu.set_child(temperature_child); - } - - cpu.set_child(cpu_features); - cpus.push(cpu); - drop(dt); + device_info_collector::collect_device_info(); // Graphics test { @@ -244,7 +176,7 @@ unsafe extern "C" fn _kernel_start() -> ! { } /// Spin loop -pub fn sloop() -> ! { +pub fn spin_loop() -> ! { loop { x86_64::instructions::hlt(); } diff --git a/kernel/src/arch/x86_64/pci/mod.rs b/kernel/src/arch/x86_64/pci/mod.rs index aba08a66..5e2bbe7b 100644 --- a/kernel/src/arch/x86_64/pci/mod.rs +++ b/kernel/src/arch/x86_64/pci/mod.rs @@ -9,10 +9,10 @@ pub struct PciDeviceInfo { pub rev_id: u8, } use crate::alloc::string::ToString; + /// Enumerate PCI devices and run initialisation routines on ones we support -pub fn init() { - let mut dt = DEVICE_TREE.lock(); - dt.devices +pub fn init(device_tree: &mut DeviceTree) { + device_tree.devices .insert("Unidentified PCI".to_string(), alloc::vec![]); let mut devices = alloc::vec![]; @@ -52,7 +52,7 @@ pub fn init() { } } for (dev_type, dev) in devices { - if let Some(abc) = dt.devices.get_mut(dev_type) { + if let Some(abc) = device_tree.devices.get_mut(dev_type) { abc.push(dev); } } @@ -248,7 +248,7 @@ impl Into for Vendor { } } -impl core::fmt::Display for Vendor { +impl Display for Vendor { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { use Vendor::*; @@ -269,9 +269,8 @@ impl core::fmt::Display for Vendor { use core::fmt::Display; -use crate::kmain::DEVICE_TREE; - use x86_64::instructions::port::Port; +use crate::device_tree::DeviceTree; #[allow(non_camel_case_types, dead_code)] #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/kernel/src/device_tree.rs b/kernel/src/device_tree.rs index e02bd191..0ec81d11 100644 --- a/kernel/src/device_tree.rs +++ b/kernel/src/device_tree.rs @@ -11,7 +11,7 @@ use { pub type Device = xml::XMLElement; /// A tree of devices -// TODO: alphabatize this list +// TODO: alphabetize this list #[derive(Debug)] pub struct DeviceTree { /// The device tree diff --git a/kernel/src/scheduler.rs b/kernel/src/scheduler.rs index df075b96..0ef47827 100644 --- a/kernel/src/scheduler.rs +++ b/kernel/src/scheduler.rs @@ -43,8 +43,8 @@ impl Scheduler<'_> { loop { // If there are no programs to run then sleep. if self.data.is_empty() { - use crate::arch::sloop; - sloop(); + use crate::arch::spin_loop; + spin_loop(); } let mut prog = self.data.pop_front().unwrap();