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:
commit
81e2603c4d
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
target/
|
target/
|
||||||
|
/.idea
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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") }
|
||||||
}
|
}
|
||||||
|
|
67
kernel/src/arch/x86_64/device_info_collector.rs
Normal file
67
kernel/src/arch/x86_64/device_info_collector.rs
Normal 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);
|
||||||
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(|| {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue