forked from koniifer/ableos
PCI: a lot of refactoration
This commit is contained in:
parent
ca3826bfe5
commit
57d6a5f2bb
|
@ -3,7 +3,6 @@ mod dev_vterm;
|
||||||
|
|
||||||
pub mod id;
|
pub mod id;
|
||||||
pub mod pci;
|
pub mod pci;
|
||||||
pub mod pci_inner;
|
|
||||||
|
|
||||||
pub use self::Device::*;
|
pub use self::Device::*;
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, able <abl3theabove@gmail.com>
|
* Copyright (c) 2022, able <abl3theabove@gmail.com>
|
||||||
|
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use core::fmt::Display;
|
use core::fmt::Display;
|
||||||
|
|
||||||
/// The major class specification for a PCI device.
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
#[allow(dead_code)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
/// Class specification for a PCI device
|
||||||
pub enum PciClass {
|
pub enum PciClass {
|
||||||
Unclassified = 0x00,
|
Unclassified = 0x00,
|
||||||
MassStorage = 0x01,
|
MassStorage = 0x01,
|
||||||
|
@ -19,37 +19,28 @@ pub enum PciClass {
|
||||||
Multimedia = 0x04,
|
Multimedia = 0x04,
|
||||||
Memory = 0x05,
|
Memory = 0x05,
|
||||||
Bridge = 0x06,
|
Bridge = 0x06,
|
||||||
Other = 0xFF,
|
Unknown = 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u8> for PciClass {
|
impl From<u8> for PciClass {
|
||||||
/// Convert a u8 into the corresponding PciClass
|
/// Convert a u8 into the corresponding PciClass
|
||||||
fn from(n: u8) -> Self {
|
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)]
|
#[allow(non_camel_case_types, dead_code)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
/// Full class specification (type and subtype) for a PCI device.
|
/// Full class specification (type and subtype) for a PCI device.
|
||||||
///
|
///
|
||||||
|
@ -110,6 +101,7 @@ pub enum PciFullClass {
|
||||||
|
|
||||||
Unknown = 0xFFFF,
|
Unknown = 0xFFFF,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PciFullClass {
|
impl PciFullClass {
|
||||||
// listen, i know this sucks, but i didn't want to include
|
// listen, i know this sucks, but i didn't want to include
|
||||||
// `num`, `num-traits` and `num-derive` as dependencies for
|
// `num`, `num-traits` and `num-derive` as dependencies for
|
||||||
|
@ -173,11 +165,13 @@ impl PciFullClass {
|
||||||
_ => PciFullClass::Unknown,
|
_ => PciFullClass::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a PciFullClass to its u16 representation
|
/// Convert a PciFullClass to its u16 representation
|
||||||
pub fn as_u16(&self) -> u16 {
|
pub fn as_u16(&self) -> u16 {
|
||||||
*self as u16
|
*self as u16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for PciFullClass {
|
impl From<u16> for PciFullClass {
|
||||||
/// Convert a u16 into the corresponding PciFullClass
|
/// Convert a u16 into the corresponding PciFullClass
|
||||||
fn from(n: u16) -> Self {
|
fn from(n: u16) -> Self {
|
181
ableos/src/devices/pci/device.rs
Normal file
181
ableos/src/devices/pci/device.rs
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, able <abl3theabove@gmail.com>
|
||||||
|
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
|
||||||
|
*
|
||||||
|
* 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<PciDeviceInfo> {
|
||||||
|
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::<u32>::new(0xCF8).write(address);
|
||||||
|
|
||||||
|
// read data
|
||||||
|
Port::<u32>::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)
|
||||||
|
}
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022, able <abl3theabove@gmail.com>
|
|
||||||
*
|
|
||||||
* 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);
|
|
|
@ -1,240 +1,28 @@
|
||||||
// The MIT License (MIT)
|
/*
|
||||||
// Copyright (c) 2021 trashbyte
|
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
|
||||||
// See LICENSE.txt for full license
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
extern crate alloc;
|
pub mod class;
|
||||||
use alloc::{format, string::String, vec::Vec};
|
pub mod device;
|
||||||
use core::fmt::{Display, Error, Formatter};
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
pub mod devices;
|
|
||||||
mod enums;
|
|
||||||
pub mod support;
|
|
||||||
pub mod vendors;
|
pub mod vendors;
|
||||||
pub use enums::*;
|
|
||||||
|
|
||||||
pub mod port;
|
|
||||||
use port::*;
|
|
||||||
|
|
||||||
// MassStorage_IDE (0x0101)
|
// MassStorage_IDE (0x0101)
|
||||||
pub mod piix;
|
pub mod piix;
|
||||||
|
|
||||||
use self::devices::DeviceID;
|
pub use class::*;
|
||||||
|
pub use device::*;
|
||||||
|
|
||||||
// PciDeviceInfo ///////////////////////////////////////////////////////////////
|
/// Enumerate PCI devices and run initialisation routines on ones we support
|
||||||
|
pub fn init() {
|
||||||
#[allow(dead_code)]
|
for bus in 0..=255 {
|
||||||
#[derive(Clone, Debug)]
|
for device in 0..32 {
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
if let Some(device_info) = device::check_device(bus, device) {
|
||||||
/// A struct containing info about a PCI device.
|
if !device::check_pci_support(device_info.device_id) {
|
||||||
pub struct PciDeviceInfo {
|
trace!("PCI device {} on bus {} unsupported", device_info.device, device_info.bus)
|
||||||
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<PciDeviceInfo> {
|
|
||||||
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<PciDeviceInfo> {
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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::<u32>::new(0xCF8).write(address);
|
|
||||||
|
|
||||||
// read data
|
|
||||||
Port::<u32>::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::<u32>::new(0xCF8).write(address);
|
|
||||||
|
|
||||||
// write data
|
|
||||||
Port::<u32>::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)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
use core::num::TryFromIntError;
|
use core::num::TryFromIntError;
|
||||||
|
|
||||||
use x86_64::instructions::interrupts;
|
use x86_64::instructions::interrupts;
|
||||||
|
use x86_64::instructions::port::Port;
|
||||||
use x86_64::structures::paging::{FrameAllocator, FrameDeallocator};
|
use x86_64::structures::paging::{FrameAllocator, FrameDeallocator};
|
||||||
// FIXME: platform agnostic paging stuff
|
// FIXME: platform agnostic paging stuff
|
||||||
use x86_64::structures::paging::{mapper::MapToError, Mapper, Page, PhysFrame, Size4KiB};
|
use x86_64::structures::paging::{mapper::MapToError, Mapper, Page, PhysFrame, Size4KiB};
|
||||||
use x86_64::VirtAddr;
|
use x86_64::VirtAddr;
|
||||||
|
|
||||||
use crate::arch::memory::BootInfoFrameAllocator;
|
use crate::arch::memory::BootInfoFrameAllocator;
|
||||||
|
use crate::devices::pci::check_device;
|
||||||
use super::{check_device, port::Port};
|
|
||||||
|
|
||||||
const PRDT_START: u64 = 0x_ffff_ffff_0000_0000;
|
const PRDT_START: u64 = 0x_ffff_ffff_0000_0000;
|
||||||
const BUFFER_START: u64 = 0x_ffff_ffff_0000_1000;
|
const BUFFER_START: u64 = 0x_ffff_ffff_0000_1000;
|
||||||
|
@ -68,7 +68,7 @@ impl Piix {
|
||||||
pub fn new(bus: u8, device: u8) -> Option<Self> {
|
pub fn new(bus: u8, device: u8) -> Option<Self> {
|
||||||
let device_info = check_device(bus, device)?;
|
let device_info = check_device(bus, device)?;
|
||||||
trace!("device_info: {device_info}");
|
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}");
|
trace!("idetim: {idetim:b}");
|
||||||
// FIXME: enable the right bits in idetim (and sidetim) to use fast timings
|
// 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 {
|
Some(Self {
|
||||||
ide_devices,
|
ide_devices,
|
||||||
|
@ -280,7 +280,7 @@ impl Piix {
|
||||||
0
|
0
|
||||||
} + self.bmiba
|
} + self.bmiba
|
||||||
+ BMIC_OFFSET;
|
+ BMIC_OFFSET;
|
||||||
let port: Port<u8> = Port::new(addr);
|
let mut port: Port<u8> = Port::new(addr);
|
||||||
let mut bmic = port.read();
|
let mut bmic = port.read();
|
||||||
// stop ongoing transfer
|
// stop ongoing transfer
|
||||||
bmic &= !1;
|
bmic &= !1;
|
||||||
|
@ -295,7 +295,7 @@ impl Piix {
|
||||||
0
|
0
|
||||||
} + self.bmiba
|
} + self.bmiba
|
||||||
+ BMIC_OFFSET;
|
+ BMIC_OFFSET;
|
||||||
let port: Port<u8> = Port::new(addr);
|
let mut port: Port<u8> = Port::new(addr);
|
||||||
let mut bmic = port.read();
|
let mut bmic = port.read();
|
||||||
// mark bit 3 as 0 (read)
|
// mark bit 3 as 0 (read)
|
||||||
bmic &= !(1 << 3);
|
bmic &= !(1 << 3);
|
||||||
|
@ -310,7 +310,7 @@ impl Piix {
|
||||||
0
|
0
|
||||||
} + self.bmiba
|
} + self.bmiba
|
||||||
+ BMIC_OFFSET;
|
+ BMIC_OFFSET;
|
||||||
let port: Port<u8> = Port::new(addr);
|
let mut port: Port<u8> = Port::new(addr);
|
||||||
let mut bmic = port.read();
|
let mut bmic = port.read();
|
||||||
// mark bit 3 as 1 (write)
|
// mark bit 3 as 1 (write)
|
||||||
bmic |= 1 << 3;
|
bmic |= 1 << 3;
|
||||||
|
@ -325,7 +325,7 @@ impl Piix {
|
||||||
0
|
0
|
||||||
} + self.bmiba
|
} + self.bmiba
|
||||||
+ BMIS_OFFSET;
|
+ BMIS_OFFSET;
|
||||||
let port: Port<u8> = Port::new(addr);
|
let mut port: Port<u8> = Port::new(addr);
|
||||||
let mut bmis = port.read();
|
let mut bmis = port.read();
|
||||||
// write 1 to bits 1 (DMA error) and 2 (int status) which clears them
|
// write 1 to bits 1 (DMA error) and 2 (int status) which clears them
|
||||||
bmis |= 1 << 1 | 1 << 2;
|
bmis |= 1 << 1 | 1 << 2;
|
||||||
|
@ -340,7 +340,7 @@ unsafe fn select_drive(drive: Drive, channel: Channel) {
|
||||||
} else {
|
} else {
|
||||||
PRIMARY_COMMAND
|
PRIMARY_COMMAND
|
||||||
} + DRIVE_HEAD_OFFSET;
|
} + DRIVE_HEAD_OFFSET;
|
||||||
let port: Port<u8> = Port::new(addr);
|
let mut port: Port<u8> = Port::new(addr);
|
||||||
let mut drive_command = port.read();
|
let mut drive_command = port.read();
|
||||||
if drive.slave() {
|
if drive.slave() {
|
||||||
// mark bit 4
|
// mark bit 4
|
||||||
|
@ -361,7 +361,7 @@ unsafe fn ata_send_command(command: u8, channel: Channel) -> u8 {
|
||||||
} else {
|
} else {
|
||||||
PRIMARY_COMMAND
|
PRIMARY_COMMAND
|
||||||
} + COMMAND_STATUS_OFFSET;
|
} + COMMAND_STATUS_OFFSET;
|
||||||
let port: Port<u8> = Port::new(addr);
|
let mut port: Port<u8> = Port::new(addr);
|
||||||
port.write(command);
|
port.write(command);
|
||||||
ata_delay(channel);
|
ata_delay(channel);
|
||||||
port.read()
|
port.read()
|
||||||
|
@ -374,7 +374,7 @@ unsafe fn ata_delay(channel: Channel) {
|
||||||
} else {
|
} else {
|
||||||
PRIMARY_CONTROL
|
PRIMARY_CONTROL
|
||||||
} + ALT_STATUS_OFFSET;
|
} + ALT_STATUS_OFFSET;
|
||||||
let port: Port<u8> = Port::new(addr);
|
let mut port: Port<u8> = Port::new(addr);
|
||||||
for _ in 0..14 {
|
for _ in 0..14 {
|
||||||
port.read();
|
port.read();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<T: PortRW> {
|
|
||||||
addr: u16,
|
|
||||||
_phantom: PhantomData<T>,
|
|
||||||
}
|
|
||||||
impl<T: PortRW> Port<T> {
|
|
||||||
/// 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022, able <abl3theabove@gmail.com>
|
|
||||||
*
|
|
||||||
* 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,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,12 +9,49 @@ use core::fmt::Display;
|
||||||
#[derive(PartialEq, Debug, Clone, Eq)]
|
#[derive(PartialEq, Debug, Clone, Eq)]
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
pub enum Vendor {
|
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,
|
Qemu = 0x1234,
|
||||||
VMware = 0x15AD,
|
QuantumDesignsHKLtd = 0x1098,
|
||||||
VirtIO = 0x1AF4,
|
Real3D = 0x003d,
|
||||||
Ati = 1002,
|
Rendition = 0x1163,
|
||||||
Intel = 0x8086,
|
|
||||||
S3Inc = 0x5333,
|
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),
|
Unknown(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,9 +59,49 @@ impl From<u16> for Vendor {
|
||||||
fn from(vendor_id: u16) -> Self {
|
fn from(vendor_id: u16) -> Self {
|
||||||
use Vendor::*;
|
use Vendor::*;
|
||||||
match vendor_id {
|
match vendor_id {
|
||||||
0x15AD => VMware,
|
0x121a => ThreeDfxInteractiveInc,
|
||||||
0x8086 => Intel,
|
0x3d3d => ThreeDLabs,
|
||||||
1002 => Ati,
|
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),
|
id => Unknown(id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,12 +111,49 @@ impl Into<u16> for Vendor {
|
||||||
fn into(self) -> u16 {
|
fn into(self) -> u16 {
|
||||||
use Vendor::*;
|
use Vendor::*;
|
||||||
match self {
|
match self {
|
||||||
VMware => 0x15AD,
|
ThreeDfxInteractiveInc => 0x121a,
|
||||||
Ati => 1002,
|
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,
|
Qemu => 0x1234,
|
||||||
VirtIO => 0x1AF4,
|
QuantumDesignsHKLtd => 0x1098,
|
||||||
Intel => 0x8086,
|
Real3D => 0x003d,
|
||||||
|
Rendition => 0x1163,
|
||||||
S3Inc => 0x5333,
|
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,
|
Unknown(id) => id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,20 +163,18 @@ 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::*;
|
||||||
|
|
||||||
let mut ret: String = match self {
|
match self {
|
||||||
Qemu => "\0PINK\0QEMU (0x1234)".into(),
|
Qemu => write!(f, "{}", "\0PINK\0QEMU (0x1234)"),
|
||||||
VirtIO => "\0PINK\0VirtIO (0x1AF4)".into(),
|
VirtIO => write!(f, "{}", "\0PINK\0VirtIO (0x1AF4)"),
|
||||||
VMware => "\0PINK\0VMWARE (0x15AD)".into(),
|
VMWareInc => write!(f, "{}", "\0PINK\0VMWARE (0x15AD)"),
|
||||||
S3Inc => "\0YELLOW\0S3 Incorporated (0x5333)".into(),
|
S3Inc => write!(f, "{}", "\0YELLOW\0S3 Incorporated (0x5333)"),
|
||||||
Intel => "\0BLUE\0Intel Corp. (0x8086)".into(),
|
IntelCorp => write!(f, "{}", "\0BLUE\0Intel Corp. (0x8086)"),
|
||||||
Ati => "\0RED\0ATI (0x1002)".into(),
|
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),
|
write!(f, "\0RESET\0")?;
|
||||||
};
|
|
||||||
|
|
||||||
ret.push_str("\0RESET\0");
|
|
||||||
|
|
||||||
write!(f, "{}", ret)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
//! map the DeviceClass via <https://pci-ids.ucw.cz/read/PD>
|
|
||||||
//!
|
|
||||||
//!
|
|
||||||
|
|
||||||
#[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() {}
|
|
|
@ -10,7 +10,7 @@ use core::sync::atomic::AtomicU64;
|
||||||
|
|
||||||
use crate::arch::memory::BootInfoFrameAllocator;
|
use crate::arch::memory::BootInfoFrameAllocator;
|
||||||
use crate::arch::{drivers::sysinfo::master, init, sloop};
|
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::relib::network::socket::{SimpleSock, Socket};
|
||||||
use crate::{boot_conf::KernelConfig, scratchpad, systeminfo::RELEASE_TYPE, TERM};
|
use crate::{boot_conf::KernelConfig, scratchpad, systeminfo::RELEASE_TYPE, TERM};
|
||||||
use crate::{filesystem, hardware};
|
use crate::{filesystem, hardware};
|
||||||
|
@ -44,18 +44,14 @@ pub fn kernel_main(
|
||||||
// term.draw_term();
|
// term.draw_term();
|
||||||
// drop(term);
|
// drop(term);
|
||||||
|
|
||||||
|
pci::init();
|
||||||
|
|
||||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||||
hardware::init_mouse();
|
hardware::init_mouse();
|
||||||
});
|
});
|
||||||
|
|
||||||
filesystem::init().unwrap();
|
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");
|
// println!("abc");
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
use crate::arch::drivers::sysinfo::master;
|
use crate::arch::drivers::sysinfo::master;
|
||||||
use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2};
|
use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2};
|
||||||
use crate::devices::pci::brute_force_scan;
|
|
||||||
use crate::filesystem;
|
use crate::filesystem;
|
||||||
use crate::filesystem::vfs::VFS;
|
use crate::filesystem::vfs::VFS;
|
||||||
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
|
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
|
||||||
|
@ -73,9 +72,6 @@ pub fn scratchpad() {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// bruh();
|
// bruh();
|
||||||
for x in brute_force_scan() {
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
disable();
|
disable();
|
||||||
let tick_time = fetch_time();
|
let tick_time = fetch_time();
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub fn device_handler(device: PciDeviceInfo) {
|
||||||
// Network => todo!(),
|
// Network => todo!(),
|
||||||
Display => {
|
Display => {
|
||||||
trace!("Display found");
|
trace!("Display found");
|
||||||
println!("{}", device.interrupt_pin);
|
println!("{}", device.interrupt_pin());
|
||||||
}
|
}
|
||||||
// Multimedia => todo!(),
|
// Multimedia => todo!(),
|
||||||
// Memory => todo!(),
|
// Memory => todo!(),
|
||||||
|
|
Loading…
Reference in a new issue