From 57d6a5f2bb3b1192795a54785c26a9c15b162311 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Fri, 12 Aug 2022 16:40:23 +0300 Subject: [PATCH] PCI: a lot of refactoration --- ableos/src/arch/x86_64/interrupts.rs | 8 +- ableos/src/arch/x86_64/mod.rs | 8 +- ableos/src/devices/mod.rs | 1 - ableos/src/devices/pci/{enums.rs => class.rs} | 54 ++-- ableos/src/devices/pci/device.rs | 181 +++++++++++++ ableos/src/devices/pci/devices.rs | 29 --- ableos/src/devices/pci/mod.rs | 244 ++---------------- ableos/src/devices/pci/piix.rs | 22 +- ableos/src/devices/pci/port.rs | 72 ------ ableos/src/devices/pci/support.rs | 22 -- ableos/src/devices/pci/vendors.rs | 168 ++++++++++-- ableos/src/devices/pci_inner.rs | 56 ---- ableos/src/kmain.rs | 10 +- ableos/src/panic.rs | 8 +- ableos/src/scratchpad.rs | 4 - ableos/src/tests/mod.rs | 8 +- ableos/src/tests/old_tests.rs | 8 +- ableos/src/virtio/mod.rs | 2 +- repbuild/src/main.rs | 10 +- 19 files changed, 401 insertions(+), 514 deletions(-) rename ableos/src/devices/pci/{enums.rs => class.rs} (90%) create mode 100644 ableos/src/devices/pci/device.rs delete mode 100644 ableos/src/devices/pci/devices.rs delete mode 100644 ableos/src/devices/pci/port.rs delete mode 100644 ableos/src/devices/pci/support.rs delete mode 100644 ableos/src/devices/pci_inner.rs diff --git a/ableos/src/arch/x86_64/interrupts.rs b/ableos/src/arch/x86_64/interrupts.rs index 7ae3d3e..a59384a 100644 --- a/ableos/src/arch/x86_64/interrupts.rs +++ b/ableos/src/arch/x86_64/interrupts.rs @@ -1,8 +1,8 @@ /* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, able + * + * SPDX-License-Identifier: MPL-2.0 + */ use core::panic::PanicInfo; diff --git a/ableos/src/arch/x86_64/mod.rs b/ableos/src/arch/x86_64/mod.rs index d2680fa..cabb6bb 100644 --- a/ableos/src/arch/x86_64/mod.rs +++ b/ableos/src/arch/x86_64/mod.rs @@ -1,8 +1,8 @@ /* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, able + * + * SPDX-License-Identifier: MPL-2.0 + */ pub mod drivers; pub mod gdt; diff --git a/ableos/src/devices/mod.rs b/ableos/src/devices/mod.rs index 52758fb..ea102d6 100644 --- a/ableos/src/devices/mod.rs +++ b/ableos/src/devices/mod.rs @@ -3,7 +3,6 @@ mod dev_vterm; pub mod id; pub mod pci; -pub mod pci_inner; pub use self::Device::*; diff --git a/ableos/src/devices/pci/enums.rs b/ableos/src/devices/pci/class.rs similarity index 90% rename from ableos/src/devices/pci/enums.rs rename to ableos/src/devices/pci/class.rs index 1c1fe67..5cbddbf 100644 --- a/ableos/src/devices/pci/enums.rs +++ b/ableos/src/devices/pci/class.rs @@ -1,16 +1,16 @@ /* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, able + * Copyright (c) 2022, Umut İnan Erdoğan + * + * SPDX-License-Identifier: MPL-2.0 + */ use core::fmt::Display; -/// The major class specification for a PCI device. -#[allow(dead_code)] -#[derive(Debug, Clone, Copy, PartialEq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(non_camel_case_types, dead_code)] +#[derive(Debug, Clone, Copy, PartialEq)] #[repr(C)] +/// Class specification for a PCI device pub enum PciClass { Unclassified = 0x00, MassStorage = 0x01, @@ -19,37 +19,28 @@ pub enum PciClass { Multimedia = 0x04, Memory = 0x05, Bridge = 0x06, - Other = 0xFF, -} -impl PciClass { - /// Convert a u8 into the corresponding PciClass - pub fn from_u8(n: u8) -> PciClass { - match n { - 0x00 => PciClass::Unclassified, - 0x01 => PciClass::MassStorage, - 0x02 => PciClass::Network, - 0x03 => PciClass::Display, - 0x04 => PciClass::Multimedia, - 0x05 => PciClass::Memory, - 0x06 => PciClass::Bridge, - _ => PciClass::Other, - } - } - /// Convert a PciClass to its u8 representation - pub fn as_u8(&self) -> u8 { - *self as u8 - } + Unknown = 0xFF, } + impl From for PciClass { /// Convert a u8 into the corresponding PciClass fn from(n: u8) -> Self { - Self::from_u8(n) + use PciClass::*; + match n { + 0x00 => Unclassified, + 0x01 => MassStorage, + 0x02 => Network, + 0x03 => Display, + 0x04 => Multimedia, + 0x05 => Memory, + 0x06 => Bridge, + _ => Unknown, + } } } #[allow(non_camel_case_types, dead_code)] #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[repr(C)] /// Full class specification (type and subtype) for a PCI device. /// @@ -110,6 +101,7 @@ pub enum PciFullClass { Unknown = 0xFFFF, } + impl PciFullClass { // listen, i know this sucks, but i didn't want to include // `num`, `num-traits` and `num-derive` as dependencies for @@ -173,11 +165,13 @@ impl PciFullClass { _ => PciFullClass::Unknown, } } + /// Convert a PciFullClass to its u16 representation pub fn as_u16(&self) -> u16 { *self as u16 } } + impl From for PciFullClass { /// Convert a u16 into the corresponding PciFullClass fn from(n: u16) -> Self { diff --git a/ableos/src/devices/pci/device.rs b/ableos/src/devices/pci/device.rs new file mode 100644 index 0000000..1b4371c --- /dev/null +++ b/ableos/src/devices/pci/device.rs @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2022, able + * Copyright (c) 2022, Umut İnan Erdoğan + * + * SPDX-License-Identifier: MPL-2.0 + */ + +use core::fmt; + +use x86_64::instructions::port::Port; + +use super::{vendors::Vendor::{self, *}, PciFullClass, PciClass}; + +// FIXME: Unknown class +pub const S3INC_TRIO64V2: DeviceID = DeviceID::new(S3Inc, 0x8900); + +// MassStorage_IDE (0x0101) +pub const INTEL_PIIX3_IDE: DeviceID = DeviceID::new(IntelCorp, 0x7010); +pub const INTEL_PIIX4_IDE: DeviceID = DeviceID::new(IntelCorp, 0x7111); + +// Display_VGA (0x0300) +pub const VMWARE_SVGA2: DeviceID = DeviceID::new(VMWareInc, 0x0405); + +#[derive(Clone, Debug)] +/// A struct containing info about a PCI device. +pub struct PciDeviceInfo { + pub header_type: u8, + pub device: u8, + pub bus: u8, + pub device_id: DeviceID, + pub full_class: PciFullClass, + pub rev_id: u8, +} + +impl PciDeviceInfo { + /// Get the class of the PCI device as a PciClass + pub fn class(&self) -> PciClass { + (((self.full_class.as_u16() >> 8) & 0xFF) as u8).into() + } + + /// Get the bar, 0-indexed + pub fn bar(&self, bar: u8) -> u32 { + assert!(bar < 6); + unsafe { + self.io_read(0, 0x10 + bar * 4) + } + } + + /// Get the interrupt pin + pub fn interrupt_pin(&self) -> u8 { + let last_row = unsafe { self.io_read(0, 0x3C) }; + ((last_row >> 8) & 0xFF) as u8 + } + + /// Read from IO space + pub unsafe fn io_read(&self, func: u8, offset: u8) -> u32 { + pci_io_read(self.bus, self.device, func, offset) + } +} + +impl fmt::Display for PciDeviceInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + let vendor_name = &self.device_id.vendor; + let device_id = &self.device_id.id; + writeln!( + f, + "Device: {} | Bus: 0x{:X} | Vendor: {} | Device ID: 0x{:X}", + self.device, self.bus, vendor_name, device_id, + )?; + writeln!(f, "{}", self.full_class)?; + writeln!(f, " Header type: 0x{:X}", self.header_type)?; + writeln!(f, " Revision ID: {}", self.rev_id)?; + // write!(f, " Supported functions: 0")?; + // for (i, b) in self.supported_fns.iter().enumerate().skip(1) { + // if *b { + // write!(f, ", {}", i)?; + // } + // } + // writeln!(f)?; + // write!(f, " BARs: [ ")?; + // for i in self.bars.iter() { + // if *i == 0 { + // write!(f, "0x0 ")?; + // } else { + // write!(f, "{:#010X} ", i)?; + // } + // } + // writeln!(f, "]")?; + // writeln!( + // f, + // " Interrupt line / pin: {} / {}", + // self.interrupt_line, self.interrupt_pin + // )?; + Ok(()) + } +} + +#[derive(PartialEq, Clone, Eq, Debug)] +pub struct DeviceID { + pub vendor: Vendor, + pub id: u16, +} + +impl DeviceID { + pub const fn new(vendor: Vendor, id: u16) -> Self { + Self { vendor, id } + } +} + +pub fn check_pci_support(device_id: DeviceID) -> bool { + match device_id { + // FIXME: Unknown class + S3INC_TRIO64V2 => true, + + // MassStorage_IDE (0x0101) + INTEL_PIIX3_IDE => true, + INTEL_PIIX4_IDE => true, + + // Display_VGA (0x0300) + VMWARE_SVGA2 => true, + _ => false, + } +} + +pub fn check_device(bus: u8, device: u8) -> Option { + assert!(device < 32); + let (device_id, vendor_id) = get_ids(bus, device, 0); + if vendor_id == 0xFFFF { + // Device doesn't exist + return None; + } + + let reg2 = unsafe { pci_io_read(bus, device, 0, 0x8) }; + let class = ((reg2 >> 16) & 0x0000FFFF) as u16; + let pci_class = PciFullClass::from_u16(class); + let header_type = get_header_type(bus, device, 0); + + Some(PciDeviceInfo { + header_type, + device, + bus, + device_id: DeviceID { + vendor: vendor_id.into(), + id: device_id, + }, + full_class: pci_class, + rev_id: (reg2 & 0x000000FF) as u8, + }) +} + +unsafe fn pci_io_read(bus: u8, device: u8, func: u8, offset: u8) -> u32 { + let bus = bus as u32; + let device = device as u32; + let func = func as u32; + let offset = offset as u32; + // construct address param + let address = + ((bus << 16) | (device << 11) | (func << 8) | (offset & 0xfc) | 0x80000000) as u32; + + // write address + Port::::new(0xCF8).write(address); + + // read data + Port::::new(0xCFC).read() +} + +fn get_header_type(bus: u8, device: u8, function: u8) -> u8 { + assert!(device < 32); + assert!(function < 8); + let res = unsafe { pci_io_read(bus, device, function, 0x0C) }; + ((res >> 16) & 0xFF) as u8 +} + +fn get_ids(bus: u8, device: u8, function: u8) -> (u16, u16) { + assert!(device < 32); + assert!(function < 8); + let res = unsafe { pci_io_read(bus, device, function, 0) }; + let dev_id = ((res >> 16) & 0xFFFF) as u16; + let vnd_id = (res & 0xFFFF) as u16; + (dev_id, vnd_id) +} diff --git a/ableos/src/devices/pci/devices.rs b/ableos/src/devices/pci/devices.rs deleted file mode 100644 index 9af2c94..0000000 --- a/ableos/src/devices/pci/devices.rs +++ /dev/null @@ -1,29 +0,0 @@ -/* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ - -use super::vendors::Vendor::{self, *}; - -#[derive(PartialEq, Clone, Eq, Debug)] -pub struct DeviceID { - pub vendor: Vendor, - pub id: u16, -} - -impl DeviceID { - pub const fn new(vendor: Vendor, id: u16) -> Self { - Self { vendor, id } - } -} - -// FIXME: Unknown class -pub const S3INC_TRIO64V2: DeviceID = DeviceID::new(S3Inc, 0x8900); - -// MassStorage_IDE (0x0101) -pub const INTEL_PIIX3_IDE: DeviceID = DeviceID::new(Intel, 0x7010); -pub const INTEL_PIIX4_IDE: DeviceID = DeviceID::new(Intel, 0x7111); - -// Display_VGA (0x0300) -pub const VMWARE_SVGA2: DeviceID = DeviceID::new(VMware, 0x0405); diff --git a/ableos/src/devices/pci/mod.rs b/ableos/src/devices/pci/mod.rs index 08b6e2f..3338c2a 100644 --- a/ableos/src/devices/pci/mod.rs +++ b/ableos/src/devices/pci/mod.rs @@ -1,240 +1,28 @@ -// The MIT License (MIT) -// Copyright (c) 2021 trashbyte -// See LICENSE.txt for full license +/* + * Copyright (c) 2022, Umut İnan Erdoğan + * + * SPDX-License-Identifier: MPL-2.0 + */ -extern crate alloc; -use alloc::{format, string::String, vec::Vec}; -use core::fmt::{Display, Error, Formatter}; - -#[cfg(feature = "serde")] -#[macro_use] -extern crate serde; - -pub mod devices; -mod enums; -pub mod support; +pub mod class; +pub mod device; pub mod vendors; -pub use enums::*; - -pub mod port; -use port::*; // MassStorage_IDE (0x0101) pub mod piix; -use self::devices::DeviceID; +pub use class::*; +pub use device::*; -// PciDeviceInfo /////////////////////////////////////////////////////////////// - -#[allow(dead_code)] -#[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -/// A struct containing info about a PCI device. -pub struct PciDeviceInfo { - pub device: u8, - pub bus: u8, - pub device_id: DeviceID, - pub full_class: PciFullClass, - pub command: u16, - pub status: u16, - pub prog_if: u8, - pub rev_id: u8, - pub header_type: u8, - pub bars: [u32; 6], - pub supported_fns: [bool; 8], - pub interrupt_line: u8, - pub interrupt_pin: u8, -} -impl PciDeviceInfo { - /// Get the class of the PCI device as a PciClass - pub fn class(&self) -> PciClass { - PciClass::from_u8(((self.full_class.as_u16() >> 8) & 0xFF) as u8) - } - /// Get the full class of the PCI device as a PciFullClass - pub fn subclass(&self) -> PciClass { - PciClass::from_u8((self.full_class.as_u16() & 0xFF) as u8) - } - - pub unsafe fn config_read(&self, func: u8, offset: u8) -> u32 { - pci_config_read(self.bus, self.device, func, offset) - } -} -impl Display for PciDeviceInfo { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { - let vendor_name = &self.device_id.vendor; - let device_id = &self.device_id.id; - writeln!( - f, - "Device: {} | Bus: 0x{:X} | Vendor: {} | Device ID: 0x{:X}", - self.device, self.bus, vendor_name, device_id, - )?; - writeln!(f, "{}", self.full_class)?; - writeln!( - f, - " Command: {:b} | Status: {:b}", - self.command, self.status - )?; - writeln!(f, " Revision ID: {}", self.rev_id)?; - writeln!(f, " Prog IF: 0b{:b}", self.prog_if)?; - writeln!(f, " Header type: 0x{:X}", self.header_type)?; - write!(f, " Supported functions: 0")?; - for (i, b) in self.supported_fns.iter().enumerate().skip(1) { - if *b { - write!(f, ", {}", i)?; - } - } - writeln!(f)?; - write!(f, " BARs: [ ")?; - for i in self.bars.iter() { - if *i == 0 { - write!(f, "0x0 ")?; - } else { - write!(f, "{:#010X} ", i)?; - } - } - writeln!(f, "]")?; - writeln!( - f, - " Interrupt line / pin: {} / {}", - self.interrupt_line, self.interrupt_pin - )?; - Ok(()) - } -} - -// Public functions //////////////////////////////////////////////////////////// - -/// Brute force scans for devices 0-31 on buses 0-255. -pub fn brute_force_scan() -> Vec { - let mut infos = Vec::new(); - for bus in 0u8..=255 { - for device in 0u8..32 { - if let Some(info) = check_device(bus, device) { - infos.push(info); - } - } - } - infos -} - -// Internal functions ////////////////////////////////////////////////////////// - -fn check_device(bus: u8, device: u8) -> Option { - assert!(device < 32); - let function = 0u8; - - let (device_id, vendor_id) = get_ids(bus, device, function); - if vendor_id == 0xFFFF { - // Device doesn't exist - return None; - } - - let reg1 = unsafe { pci_config_read(bus, device, 0, 0x4) }; - let reg2 = unsafe { pci_config_read(bus, device, 0, 0x8) }; - let command = (reg1 & 0x0000FFFF) as u16; - let status = ((reg1 >> 16) & 0x0000FFFF) as u16; - let rev_id = (reg2 & 0x000000FF) as u8; - let prog_if = ((reg2 >> 8) & 0x000000FF) as u8; - let class = ((reg2 >> 16) & 0x0000FFFF) as u16; - let pci_class = PciFullClass::from_u16(class); - let header_type = get_header_type(bus, device, function); - - let mut supported_fns = [true, false, false, false, false, false, false, false]; - if (header_type & 0x80) != 0 { - // It is a multi-function device, so check remaining functions - for function in 0u8..8 { - if get_ids(bus, device, function).1 != 0xFFFF { - if check_function(bus, device, function) { - supported_fns[function as usize] = true; +/// Enumerate PCI devices and run initialisation routines on ones we support +pub fn init() { + for bus in 0..=255 { + for device in 0..32 { + if let Some(device_info) = device::check_device(bus, device) { + if !device::check_pci_support(device_info.device_id) { + trace!("PCI device {} on bus {} unsupported", device_info.device, device_info.bus) } } } } - - let mut bars = [0, 0, 0, 0, 0, 0]; - unsafe { - bars[0] = pci_config_read(bus, device, 0, 0x10); - bars[1] = pci_config_read(bus, device, 0, 0x14); - bars[2] = pci_config_read(bus, device, 0, 0x18); - bars[3] = pci_config_read(bus, device, 0, 0x1C); - bars[4] = pci_config_read(bus, device, 0, 0x20); - bars[5] = pci_config_read(bus, device, 0, 0x24); - } - - let last_row = unsafe { pci_config_read(bus, device, 0, 0x3C) }; - - Some(PciDeviceInfo { - device, - bus, - device_id: DeviceID { - vendor: vendor_id.into(), - id: device_id, - }, - // vendor_id, - full_class: pci_class, - command, - status, - prog_if, - rev_id, - header_type, - bars, - supported_fns, - interrupt_line: (last_row & 0xFF) as u8, - interrupt_pin: ((last_row >> 8) & 0xFF) as u8, - }) -} - -unsafe fn pci_config_read(bus: u8, device: u8, func: u8, offset: u8) -> u32 { - let bus = bus as u32; - let device = device as u32; - let func = func as u32; - let offset = offset as u32; - // construct address param - let address = - ((bus << 16) | (device << 11) | (func << 8) | (offset & 0xfc) | 0x80000000) as u32; - - // write address - Port::::new(0xCF8).write(address); - - // read data - Port::::new(0xCFC).read() -} - -#[allow(dead_code)] -unsafe fn pci_config_write(bus: u8, device: u8, func: u8, offset: u8, value: u32) { - let bus = bus as u32; - let device = device as u32; - let func = func as u32; - let offset = offset as u32; - // construct address param - let address = - ((bus << 16) | (device << 11) | (func << 8) | (offset & 0xfc) | 0x80000000) as u32; - - // write address - Port::::new(0xCF8).write(address); - - // write data - Port::::new(0xCFC).write(value); -} - -fn get_header_type(bus: u8, device: u8, function: u8) -> u8 { - assert!(device < 32); - assert!(function < 8); - let res = unsafe { pci_config_read(bus, device, function, 0x0C) }; - ((res >> 16) & 0xFF) as u8 -} - -fn check_function(bus: u8, device: u8, function: u8) -> bool { - assert!(device < 32); - assert!(function < 8); - get_ids(bus, device, function).1 != 0xFFFF -} - -fn get_ids(bus: u8, device: u8, function: u8) -> (u16, u16) { - assert!(device < 32); - assert!(function < 8); - let res = unsafe { pci_config_read(bus, device, function, 0) }; - let dev_id = ((res >> 16) & 0xFFFF) as u16; - let vnd_id = (res & 0xFFFF) as u16; - (dev_id, vnd_id) } diff --git a/ableos/src/devices/pci/piix.rs b/ableos/src/devices/pci/piix.rs index 693fbcc..d1bda61 100644 --- a/ableos/src/devices/pci/piix.rs +++ b/ableos/src/devices/pci/piix.rs @@ -7,14 +7,14 @@ use core::num::TryFromIntError; use x86_64::instructions::interrupts; +use x86_64::instructions::port::Port; use x86_64::structures::paging::{FrameAllocator, FrameDeallocator}; // FIXME: platform agnostic paging stuff use x86_64::structures::paging::{mapper::MapToError, Mapper, Page, PhysFrame, Size4KiB}; use x86_64::VirtAddr; use crate::arch::memory::BootInfoFrameAllocator; - -use super::{check_device, port::Port}; +use crate::devices::pci::check_device; const PRDT_START: u64 = 0x_ffff_ffff_0000_0000; const BUFFER_START: u64 = 0x_ffff_ffff_0000_1000; @@ -68,7 +68,7 @@ impl Piix { pub fn new(bus: u8, device: u8) -> Option { let device_info = check_device(bus, device)?; trace!("device_info: {device_info}"); - let idetim = unsafe { device_info.config_read(0, 0x40) }; + let idetim = unsafe { device_info.io_read(0, 0x40) }; trace!("idetim: {idetim:b}"); // FIXME: enable the right bits in idetim (and sidetim) to use fast timings @@ -157,7 +157,7 @@ impl Piix { } } - let bmiba = device_info.bars[4] & 0xFFFFFFFC; + let bmiba = device_info.bar(4) & 0xFFFFFFFC; Some(Self { ide_devices, @@ -280,7 +280,7 @@ impl Piix { 0 } + self.bmiba + BMIC_OFFSET; - let port: Port = Port::new(addr); + let mut port: Port = Port::new(addr); let mut bmic = port.read(); // stop ongoing transfer bmic &= !1; @@ -295,7 +295,7 @@ impl Piix { 0 } + self.bmiba + BMIC_OFFSET; - let port: Port = Port::new(addr); + let mut port: Port = Port::new(addr); let mut bmic = port.read(); // mark bit 3 as 0 (read) bmic &= !(1 << 3); @@ -310,7 +310,7 @@ impl Piix { 0 } + self.bmiba + BMIC_OFFSET; - let port: Port = Port::new(addr); + let mut port: Port = Port::new(addr); let mut bmic = port.read(); // mark bit 3 as 1 (write) bmic |= 1 << 3; @@ -325,7 +325,7 @@ impl Piix { 0 } + self.bmiba + BMIS_OFFSET; - let port: Port = Port::new(addr); + let mut port: Port = Port::new(addr); let mut bmis = port.read(); // write 1 to bits 1 (DMA error) and 2 (int status) which clears them bmis |= 1 << 1 | 1 << 2; @@ -340,7 +340,7 @@ unsafe fn select_drive(drive: Drive, channel: Channel) { } else { PRIMARY_COMMAND } + DRIVE_HEAD_OFFSET; - let port: Port = Port::new(addr); + let mut port: Port = Port::new(addr); let mut drive_command = port.read(); if drive.slave() { // mark bit 4 @@ -361,7 +361,7 @@ unsafe fn ata_send_command(command: u8, channel: Channel) -> u8 { } else { PRIMARY_COMMAND } + COMMAND_STATUS_OFFSET; - let port: Port = Port::new(addr); + let mut port: Port = Port::new(addr); port.write(command); ata_delay(channel); port.read() @@ -374,7 +374,7 @@ unsafe fn ata_delay(channel: Channel) { } else { PRIMARY_CONTROL } + ALT_STATUS_OFFSET; - let port: Port = Port::new(addr); + let mut port: Port = Port::new(addr); for _ in 0..14 { port.read(); } diff --git a/ableos/src/devices/pci/port.rs b/ableos/src/devices/pci/port.rs deleted file mode 100644 index e22b107..0000000 --- a/ableos/src/devices/pci/port.rs +++ /dev/null @@ -1,72 +0,0 @@ -use core::marker::PhantomData; - -/// Trait for limiting [Port] to only being able to read/write u8/16/32. -pub(crate) trait PortRW { - /// Read a value (self) from the port - unsafe fn read_port(port: u16) -> Self; - /// Write a value (self) to the port - unsafe fn write_port(port: u16, value: Self); -} - -// PortRW Implementations ////////////////////////////////////////////////////////////////////////// - -impl PortRW for u8 { - unsafe fn read_port(port: u16) -> Self { - let value: u8; - asm!("in al, dx", out("al") value, in("dx") port, options(nomem, nostack, preserves_flags)); - value - } - - unsafe fn write_port(port: u16, value: Self) { - asm!("out dx, al", in("dx") port, in("al") value, options(nomem, nostack, preserves_flags)); - } -} - -impl PortRW for u16 { - unsafe fn read_port(port: u16) -> Self { - let value: u16; - asm!("in ax, dx", out("ax") value, in("dx") port, options(nomem, nostack, preserves_flags)); - value - } - - unsafe fn write_port(port: u16, value: Self) { - asm!("out dx, ax", in("dx") port, in("ax") value, options(nomem, nostack, preserves_flags)); - } -} - -impl PortRW for u32 { - unsafe fn read_port(port: u16) -> Self { - let value: u32; - asm!("in eax, dx", out("eax") value, in("dx") port, options(nomem, nostack, preserves_flags)); - value - } - - unsafe fn write_port(port: u16, value: Self) { - asm!("out dx, eax", in("dx") port, in("eax") value, options(nomem, nostack, preserves_flags)); - } -} - -/// A simple wrapper around the asm instructions needed to read/write I/O ports. -pub(crate) struct Port { - addr: u16, - _phantom: PhantomData, -} -impl Port { - /// Create a new `Port` with the given address and data size - pub(crate) fn new(addr: u16) -> Self { - Self { - addr, - _phantom: PhantomData, - } - } - - /// Read a value from the port - pub(crate) unsafe fn read(&self) -> T { - T::read_port(self.addr) - } - - /// Write a value to the port - pub(crate) unsafe fn write(&self, value: T) { - T::write_port(self.addr, value); - } -} diff --git a/ableos/src/devices/pci/support.rs b/ableos/src/devices/pci/support.rs deleted file mode 100644 index 7cbb651..0000000 --- a/ableos/src/devices/pci/support.rs +++ /dev/null @@ -1,22 +0,0 @@ -/* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ - -use super::devices::*; - -pub fn check_pci_support(device_id: DeviceID) -> bool { - match device_id { - // FIXME: Unknown class - S3INC_TRIO64V2 => true, - - // MassStorage_IDE (0x0101) - INTEL_PIIX3_IDE => true, - INTEL_PIIX4_IDE => true, - - // Display_VGA (0x0300) - VMWARE_SVGA2 => true, - _ => false, - } -} diff --git a/ableos/src/devices/pci/vendors.rs b/ableos/src/devices/pci/vendors.rs index 04454c5..0a4c973 100644 --- a/ableos/src/devices/pci/vendors.rs +++ b/ableos/src/devices/pci/vendors.rs @@ -1,20 +1,57 @@ /* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, able + * + * SPDX-License-Identifier: MPL-2.0 + */ use core::fmt::Display; #[derive(PartialEq, Debug, Clone, Eq)] #[repr(u16)] pub enum Vendor { + ThreeDfxInteractiveInc = 0x121a, + ThreeDLabs = 0x3d3d, + AllianceSemiconductorCorp = 0x1142, + ARKLogicInc = 0xedd8, + ATITechnologiesInc = 0x1002, + AvanceLogicIncALI = 0x1005, + ChipsandTechnologies = 0x102c, + CirrusLogic = 0x1013, + Compaq = 0x0e11, + CyrixCorp = 0x1078, + DiamondMultimediaSystems = 0x1092, + DigitalEquipmentCorp = 0x1011, + Iit = 0x1061, + IntegratedMicroSolutionsInc = 0x10e0, + IntelCorp = 0x8086, + IntergraphicsSystems = 0x10ea, + MacronixInc = 0x10d9, + MatroxGraphicsInc = 0x102b, + MiroComputersProductsAG = 0x1031, + NationalSemiconductorCorp = 0x100b, + NeoMagicCorp = 0x10c8, + Number9ComputerCompany = 0x105d, + NVidiaCorporation = 0x10de, + NVidiaSgsthomson = 0x12d2, + OakTechnologyInc = 0x104e, Qemu = 0x1234, - VMware = 0x15AD, - VirtIO = 0x1AF4, - Ati = 1002, - Intel = 0x8086, + QuantumDesignsHKLtd = 0x1098, + Real3D = 0x003d, + Rendition = 0x1163, S3Inc = 0x5333, + SierraSemiconductor = 0x10a8, + SiliconIntegratedSystemsSiS = 0x1039, + SiliconMotionInc = 0x126f, + STBSystemsInc = 0x10b4, + TexasInstruments = 0x104c, + ToshibaAmericaInfoSystems = 0x1179, + TridentMicrosystems = 0x1023, + TsengLabsInc = 0x100c, + TundraSemiconductorCorp = 0x10e3, + VIATechnologiesInc = 0x1106, + VirtIO = 0x1AF4, + VMWareInc = 0x15ad, + Weitek = 0x100e, Unknown(u16), } @@ -22,9 +59,49 @@ impl From for Vendor { fn from(vendor_id: u16) -> Self { use Vendor::*; match vendor_id { - 0x15AD => VMware, - 0x8086 => Intel, - 1002 => Ati, + 0x121a => ThreeDfxInteractiveInc, + 0x3d3d => ThreeDLabs, + 0x1142 => AllianceSemiconductorCorp, + 0xedd8 => ARKLogicInc, + 0x1002 => ATITechnologiesInc, + 0x1005 => AvanceLogicIncALI, + 0x102c => ChipsandTechnologies, + 0x1013 => CirrusLogic, + 0x0e11 => Compaq, + 0x1078 => CyrixCorp, + 0x1092 => DiamondMultimediaSystems, + 0x1011 => DigitalEquipmentCorp, + 0x1061 => Iit, + 0x10e0 => IntegratedMicroSolutionsInc, + 0x8086 => IntelCorp, + 0x10ea => IntergraphicsSystems, + 0x10d9 => MacronixInc, + 0x102b => MatroxGraphicsInc, + 0x1031 => MiroComputersProductsAG, + 0x100b => NationalSemiconductorCorp, + 0x10c8 => NeoMagicCorp, + 0x105d => Number9ComputerCompany, + 0x10de => NVidiaCorporation, + 0x12d2 => NVidiaSgsthomson, + 0x104e => OakTechnologyInc, + 0x1234 => Qemu, + 0x1098 => QuantumDesignsHKLtd, + 0x003d => Real3D, + 0x1163 => Rendition, + 0x5333 => S3Inc, + 0x10a8 => SierraSemiconductor, + 0x1039 => SiliconIntegratedSystemsSiS, + 0x126f => SiliconMotionInc, + 0x10b4 => STBSystemsInc, + 0x104c => TexasInstruments, + 0x1179 => ToshibaAmericaInfoSystems, + 0x1023 => TridentMicrosystems, + 0x100c => TsengLabsInc, + 0x10e3 => TundraSemiconductorCorp, + 0x1106 => VIATechnologiesInc, + 0x1AF4 => VirtIO, + 0x15ad => VMWareInc, + 0x100e => Weitek, id => Unknown(id), } } @@ -34,12 +111,49 @@ impl Into for Vendor { fn into(self) -> u16 { use Vendor::*; match self { - VMware => 0x15AD, - Ati => 1002, + ThreeDfxInteractiveInc => 0x121a, + ThreeDLabs => 0x3d3d, + AllianceSemiconductorCorp => 0x1142, + ARKLogicInc => 0xedd8, + ATITechnologiesInc => 0x1002, + AvanceLogicIncALI => 0x1005, + ChipsandTechnologies => 0x102c, + CirrusLogic => 0x1013, + Compaq => 0x0e11, + CyrixCorp => 0x1078, + DiamondMultimediaSystems => 0x1092, + DigitalEquipmentCorp => 0x1011, + Iit => 0x1061, + IntegratedMicroSolutionsInc => 0x10e0, + IntelCorp => 0x8086, + IntergraphicsSystems => 0x10ea, + MacronixInc => 0x10d9, + MatroxGraphicsInc => 0x102b, + MiroComputersProductsAG => 0x1031, + NationalSemiconductorCorp => 0x100b, + NeoMagicCorp => 0x10c8, + Number9ComputerCompany => 0x105d, + NVidiaCorporation => 0x10de, + NVidiaSgsthomson => 0x12d2, + OakTechnologyInc => 0x104e, Qemu => 0x1234, - VirtIO => 0x1AF4, - Intel => 0x8086, + QuantumDesignsHKLtd => 0x1098, + Real3D => 0x003d, + Rendition => 0x1163, S3Inc => 0x5333, + SierraSemiconductor => 0x10a8, + SiliconIntegratedSystemsSiS => 0x1039, + SiliconMotionInc => 0x126f, + STBSystemsInc => 0x10b4, + TexasInstruments => 0x104c, + ToshibaAmericaInfoSystems => 0x1179, + TridentMicrosystems => 0x1023, + TsengLabsInc => 0x100c, + TundraSemiconductorCorp => 0x10e3, + VIATechnologiesInc => 0x1106, + VirtIO => 0x1AF4, + VMWareInc => 0x15ad, + Weitek => 0x100e, Unknown(id) => id, } } @@ -49,20 +163,18 @@ impl Display for Vendor { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { use Vendor::*; - let mut ret: String = match self { - Qemu => "\0PINK\0QEMU (0x1234)".into(), - VirtIO => "\0PINK\0VirtIO (0x1AF4)".into(), - VMware => "\0PINK\0VMWARE (0x15AD)".into(), - S3Inc => "\0YELLOW\0S3 Incorporated (0x5333)".into(), - Intel => "\0BLUE\0Intel Corp. (0x8086)".into(), - Ati => "\0RED\0ATI (0x1002)".into(), + match self { + Qemu => write!(f, "{}", "\0PINK\0QEMU (0x1234)"), + VirtIO => write!(f, "{}", "\0PINK\0VirtIO (0x1AF4)"), + VMWareInc => write!(f, "{}", "\0PINK\0VMWARE (0x15AD)"), + S3Inc => write!(f, "{}", "\0YELLOW\0S3 Incorporated (0x5333)"), + IntelCorp => write!(f, "{}", "\0BLUE\0Intel Corp. (0x8086)"), + ATITechnologiesInc => write!(f, "{}", "\0RED\0ATI (0x1002)"), + Unknown(id) => write!(f, "\0RED\0Unknown ({:#6})", id), + other => write!(f, "{other:?}"), + }?; - Unknown(id) => format!("\0RED\0Unknown ({:#6})", id), - }; - - ret.push_str("\0RESET\0"); - - write!(f, "{}", ret)?; + write!(f, "\0RESET\0")?; Ok(()) } } diff --git a/ableos/src/devices/pci_inner.rs b/ableos/src/devices/pci_inner.rs deleted file mode 100644 index 83cff97..0000000 --- a/ableos/src/devices/pci_inner.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! map the DeviceClass via -//! -//! - -#[repr(C)] -pub enum Vendors { - ThreeDfxInteractiveInc = 0x121a, - ThreeDLabs = 0x3d3d, - AllianceSemiconductorCorp = 0x1142, - ARKLogicInc = 0xedd8, - ATITechnologiesInc = 0x1002, - AvanceLogicIncALI = 0x1005, - ChipsandTechnologies = 0x102c, - CirrusLogic = 0x1013, - Compaq = 0x0e11, - CyrixCorp = 0x1078, - DiamondMultimediaSystems = 0x1092, - DigitalEquipmentCorp = 0x1011, - Iit = 0x1061, - IntegratedMicroSolutionsInc = 0x10e0, - IntelCorp = 0x8086, - IntergraphicsSystems = 0x10ea, - MacronixInc = 0x10d9, - MatroxGraphicsInc = 0x102b, - MiroComputersProductsAG = 0x1031, - NationalSemiconductorCorp = 0x100b, - NeoMagicCorp = 0x10c8, - Number9ComputerCompany = 0x105d, - NVidiaCorporation = 0x10de, - NVidiaSgsthomson = 0x12d2, - OakTechnologyInc = 0x104e, - QuantumDesignsHKLtd = 0x1098, - Real3D = 0x003d, - Rendition = 0x1163, - S3Inc = 0x5333, - SierraSemiconductor = 0x10a8, - SiliconIntegratedSystemsSiS = 0x1039, - SiliconMotionInc = 0x126f, - STBSystemsInc = 0x10b4, - TexasInstruments = 0x104c, - ToshibaAmericaInfoSystems = 0x1179, - TridentMicrosystems = 0x1023, - TsengLabsInc = 0x100c, - TundraSemiconductorCorp = 0x10e3, - VIATechnologiesInc = 0x1106, - VMWareInc = 0x15ad, - Weitek = 0x100e, - Unknown = 0xffff, -} - -pub struct PciDevice { - pub vendor: Vendors, -} - -#[allow(dead_code)] -fn scan_pci_bus() {} diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs index 0a2ac2e..9a37c3f 100644 --- a/ableos/src/kmain.rs +++ b/ableos/src/kmain.rs @@ -10,7 +10,7 @@ use core::sync::atomic::AtomicU64; use crate::arch::memory::BootInfoFrameAllocator; use crate::arch::{drivers::sysinfo::master, init, sloop}; -use crate::devices::pci::piix::Piix; +use crate::devices::pci; use crate::relib::network::socket::{SimpleSock, Socket}; use crate::{boot_conf::KernelConfig, scratchpad, systeminfo::RELEASE_TYPE, TERM}; use crate::{filesystem, hardware}; @@ -44,18 +44,14 @@ pub fn kernel_main( // term.draw_term(); // drop(term); + pci::init(); + x86_64::instructions::interrupts::without_interrupts(|| { hardware::init_mouse(); }); filesystem::init().unwrap(); - // FIXME: unhardcode this and do device discovery - let mut piix = Piix::new(0, 3).unwrap(); - piix.allocate_dma_frame(&mut mapper, &mut frame_allocator) - .unwrap(); - piix.read().unwrap(); - /* // println!("abc"); diff --git a/ableos/src/panic.rs b/ableos/src/panic.rs index 41b0837..609b2a6 100644 --- a/ableos/src/panic.rs +++ b/ableos/src/panic.rs @@ -1,8 +1,8 @@ /* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, able + * + * SPDX-License-Identifier: MPL-2.0 + */ use core::panic::PanicInfo; use log::error; diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index 045289f..bfb7751 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -6,7 +6,6 @@ use crate::arch::drivers::sysinfo::master; use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2}; -use crate::devices::pci::brute_force_scan; use crate::filesystem; use crate::filesystem::vfs::VFS; use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE}; @@ -73,9 +72,6 @@ pub fn scratchpad() { // } // bruh(); - for x in brute_force_scan() { - println!("{}", x); - } disable(); let tick_time = fetch_time(); diff --git a/ableos/src/tests/mod.rs b/ableos/src/tests/mod.rs index d01f45f..4429d36 100644 --- a/ableos/src/tests/mod.rs +++ b/ableos/src/tests/mod.rs @@ -1,8 +1,8 @@ /* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, able + * + * SPDX-License-Identifier: MPL-2.0 + */ use core::panic::PanicInfo; diff --git a/ableos/src/tests/old_tests.rs b/ableos/src/tests/old_tests.rs index 0813157..c041774 100644 --- a/ableos/src/tests/old_tests.rs +++ b/ableos/src/tests/old_tests.rs @@ -1,8 +1,8 @@ /* -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, able + * + * SPDX-License-Identifier: MPL-2.0 + */ use crate::{ kmain::KERNEL_CONF, diff --git a/ableos/src/virtio/mod.rs b/ableos/src/virtio/mod.rs index cb22fa1..802a722 100644 --- a/ableos/src/virtio/mod.rs +++ b/ableos/src/virtio/mod.rs @@ -19,7 +19,7 @@ pub fn device_handler(device: PciDeviceInfo) { // Network => todo!(), Display => { trace!("Display found"); - println!("{}", device.interrupt_pin); + println!("{}", device.interrupt_pin()); } // Multimedia => todo!(), // Memory => todo!(), diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs index e3662bc..bc4d571 100644 --- a/repbuild/src/main.rs +++ b/repbuild/src/main.rs @@ -1,9 +1,9 @@ /* -* Copyright (c) 2022, Umut İnan Erdoğan -* Copyright (c) 2022, able -* -* SPDX-License-Identifier: MPL-2.0 -*/ + * Copyright (c) 2022, Umut İnan Erdoğan + * Copyright (c) 2022, able + * + * SPDX-License-Identifier: MPL-2.0 + */ use std::{fs, process::Command};