1
0
Fork 0
forked from AbleOS/ableos

Merge pull request 'x86_64: Refactor device info fetching' (#7) from JohnyTheCarrot/ableos:chore/refactor-device-info into master

Reviewed-on: https://git.ablecorp.us/AbleOS/ableos/pulls/7

LG2M
This commit is contained in:
able 2023-07-15 13:05:33 +00:00
commit 81e2603c4d
10 changed files with 85 additions and 86 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
target/ target/
/.idea

View file

@ -341,5 +341,5 @@ unsafe impl Send for Heap {}
fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! { fn alloc_error_handler(layout: alloc::alloc::Layout) -> ! {
log::error!("allocation error: {:?}", layout); log::error!("allocation error: {:?}", layout);
// Todo: Maybe panic here instead // Todo: Maybe panic here instead
crate::arch::sloop() crate::arch::spin_loop()
} }

View file

@ -11,7 +11,7 @@ pub fn log(_args: core::fmt::Arguments<'_>) -> core::fmt::Result {
panic!() panic!()
} }
pub fn sloop() -> ! { pub fn spin_loop() -> ! {
loop {} loop {}
} }
pub fn hardware_random_u64() -> u64 { pub fn hardware_random_u64() -> u64 {

View file

@ -79,7 +79,7 @@ unsafe extern fn _kernel_start() -> ! {
} }
/// Spin loop /// Spin loop
pub fn sloop() -> ! { pub fn spin_loop() -> ! {
loop { loop {
unsafe { asm!("wfi") } unsafe { asm!("wfi") }
} }

View file

@ -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);
}

View file

@ -1,8 +1,6 @@
use {limine::SmpRequest, xml::XMLElement};
use embedded_graphics::pixelcolor::Rgb888; 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; pub mod memory;
@ -13,6 +11,7 @@ pub(crate) mod interrupts;
pub mod logging; pub mod logging;
pub mod pci; pub mod pci;
pub mod virtio; pub mod virtio;
mod device_info_collector;
pub use {logging::log, memory::PAGE_SIZE}; 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 KFILE_REQ: KernelFileRequest = KernelFileRequest::new(0);
static MOD_REQ: ModuleRequest = ModuleRequest::new(0); static MOD_REQ: ModuleRequest = ModuleRequest::new(0);
static SMP: SmpRequest = SmpRequest::new(0); device_info_collector::collect_device_info();
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);
// Graphics test // Graphics test
{ {
@ -244,7 +176,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
} }
/// Spin loop /// Spin loop
pub fn sloop() -> ! { pub fn spin_loop() -> ! {
loop { loop {
x86_64::instructions::hlt(); x86_64::instructions::hlt();
} }

View file

@ -9,10 +9,10 @@ pub struct PciDeviceInfo {
pub rev_id: u8, pub rev_id: u8,
} }
use crate::alloc::string::ToString; use crate::alloc::string::ToString;
/// Enumerate PCI devices and run initialisation routines on ones we support /// Enumerate PCI devices and run initialisation routines on ones we support
pub fn init() { pub fn init(device_tree: &mut DeviceTree) {
let mut dt = DEVICE_TREE.lock(); device_tree.devices
dt.devices
.insert("Unidentified PCI".to_string(), alloc::vec![]); .insert("Unidentified PCI".to_string(), alloc::vec![]);
let mut devices = alloc::vec![]; let mut devices = alloc::vec![];
@ -52,7 +52,7 @@ pub fn init() {
} }
} }
for (dev_type, dev) in devices { 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); abc.push(dev);
} }
} }
@ -248,7 +248,7 @@ impl Into<u16> for Vendor {
} }
} }
impl core::fmt::Display for Vendor { impl Display for Vendor {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use Vendor::*; use Vendor::*;
@ -269,9 +269,8 @@ impl core::fmt::Display for Vendor {
use core::fmt::Display; use core::fmt::Display;
use crate::kmain::DEVICE_TREE;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
use crate::device_tree::DeviceTree;
#[allow(non_camel_case_types, dead_code)] #[allow(non_camel_case_types, dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]

View file

@ -11,7 +11,7 @@ use {
pub type Device = xml::XMLElement; pub type Device = xml::XMLElement;
/// A tree of devices /// A tree of devices
// TODO: alphabatize this list // TODO: alphabetize this list
#[derive(Debug)] #[derive(Debug)]
pub struct DeviceTree { pub struct DeviceTree {
/// The device tree /// The device tree

View file

@ -45,7 +45,7 @@ pub fn kmain(cmdline: &str, boot_modules: BootModules) -> ! {
sched.new_process(boot_modules[1].bytes.clone()); sched.new_process(boot_modules[1].bytes.clone());
sched.run(); sched.run();
// sloop(); // spin_loop();
} }
pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| { pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {

View file

@ -43,8 +43,8 @@ impl Scheduler<'_> {
loop { loop {
// If there are no programs to run then sleep. // If there are no programs to run then sleep.
if self.data.is_empty() { if self.data.is_empty() {
use crate::arch::sloop; use crate::arch::spin_loop;
sloop(); spin_loop();
} }
let mut prog = self.data.pop_front().unwrap(); let mut prog = self.data.pop_front().unwrap();