x86_64: Refactor device info fetching

This commit is contained in:
JohnyTheCarrot 2023-07-15 14:47:46 +02:00
parent a8005728bf
commit 53fca04786
7 changed files with 82 additions and 83 deletions

1
.gitignore vendored
View file

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

View file

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

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

View file

@ -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<u16> 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)]

View file

@ -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

View file

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