diff --git a/Cargo.lock b/Cargo.lock index 57abb4719d..4c1f1c7833 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ac97d" @@ -620,15 +620,6 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "hermit-abi" version = "0.1.19" @@ -974,10 +965,10 @@ dependencies = [ "libredox", "log", "pci_types", + "pico-args", "plain", "redox-daemon", "serde", - "structopt", "thiserror", "toml 0.5.11", ] @@ -992,6 +983,12 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project-lite" version = "0.2.15" @@ -1010,30 +1007,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.89" @@ -1440,30 +1413,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "syn" version = "1.0.109" @@ -1582,12 +1531,6 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-width" version = "0.1.14" @@ -1680,12 +1623,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "vesad" version = "0.1.0" diff --git a/pcid/Cargo.toml b/pcid/Cargo.toml index 6acfa7774a..b78a994584 100644 --- a/pcid/Cargo.toml +++ b/pcid/Cargo.toml @@ -17,10 +17,10 @@ fdt = "0.1.5" libc = "0.2" log = "0.4" pci_types = "0.10" +pico-args = { version = "0.5", features = ["combined-flags"] } plain = "0.2" redox-daemon = "0.1" serde = { version = "1", features = ["derive"] } -structopt = { version = "0.3", default-features = false } thiserror = "1" toml = "0.5" diff --git a/pcid/src/config.rs b/pcid/src/driver_interface/config.rs similarity index 98% rename from pcid/src/config.rs rename to pcid/src/driver_interface/config.rs index c9610f667c..8278f33c3c 100644 --- a/pcid/src/config.rs +++ b/pcid/src/driver_interface/config.rs @@ -3,7 +3,7 @@ use std::ops::Range; use serde::Deserialize; -use pcid_interface::FullDeviceId; +use crate::driver_interface::FullDeviceId; #[derive(Clone, Debug, Default, Deserialize)] pub struct Config { diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 5d1054a23f..2cf16e8bba 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -16,6 +16,7 @@ pub use pci_types::PciAddress; mod bar; pub mod cap; +pub mod config; mod id; pub mod irq_helpers; pub mod msi; diff --git a/pcid/src/main.rs b/pcid/src/main.rs index c9e3d7f423..c432539fda 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -4,6 +4,7 @@ use std::fs::{metadata, read_dir, File}; use std::io::prelude::*; +use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::thread; @@ -12,33 +13,13 @@ use pci_types::{ Bar as TyBar, CommandRegister, EndpointHeader, HeaderType, PciAddress, PciHeader as TyPciHeader, PciPciBridgeHeader, }; -use structopt::StructOpt; use crate::cfg_access::Pcie; -use crate::config::Config; -use pcid_interface::{FullDeviceId, LegacyInterruptLine, PciBar}; +use pcid_interface::{config::Config, FullDeviceId, LegacyInterruptLine, PciBar}; mod cfg_access; -mod config; mod driver_handler; -#[derive(StructOpt)] -#[structopt(about)] -struct Args { - #[structopt( - short, - long, - help = "Increase logging level once for each arg.", - parse(from_occurrences) - )] - verbose: u8, - - #[structopt( - help = "A path to a pcid config file or a directory that contains pcid config files." - )] - config_path: Option, -} - pub struct State { threads: Mutex>>, pcie: Pcie, @@ -106,62 +87,7 @@ fn handle_parsed_header( info!(" BAR{}", string); } - // Enable bus mastering, memory space, and I/O space - endpoint_header.update_command(&state.pcie, |cmd| { - cmd | CommandRegister::BUS_MASTER_ENABLE - | CommandRegister::MEMORY_ENABLE - | CommandRegister::IO_ENABLE - }); - - // Set IRQ line to 9 if not set - let mut irq = 0xFF; - let mut interrupt_pin = 0xFF; - - endpoint_header.update_interrupt(&state.pcie, |(pin, mut line)| { - if line == 0xFF { - line = 9; - } - irq = line; - interrupt_pin = pin; - (pin, line) - }); - - let legacy_interrupt_enabled = match interrupt_pin { - 0 => false, - 1 | 2 | 3 | 4 => true, - - other => { - warn!("pcid: invalid interrupt pin: {}", other); - false - } - }; - - let mut phandled: Option<(u32, [u32; 3], usize)> = None; - if legacy_interrupt_enabled { - let pci_address = endpoint_header.header().address(); - let dt_address = ((pci_address.bus() as u32) << 16) - | ((pci_address.device() as u32) << 11) - | ((pci_address.function() as u32) << 8); - let addr = [ - dt_address & state.pcie.interrupt_map_mask[0], - 0u32, - 0u32, - interrupt_pin as u32 & state.pcie.interrupt_map_mask[3], - ]; - let mapping = state - .pcie - .interrupt_map - .iter() - .find(|x| x.addr == addr[0..3] && x.interrupt == addr[3]); - if let Some(mapping) = mapping { - phandled = Some(( - mapping.parent_phandle, - mapping.parent_interrupt, - mapping.parent_interrupt_cells, - )); - debug!("found mapping: addr={:?} => {:?}", addr, phandled); - } - } + let legacy_interrupt_line = enable_function(&state, &mut endpoint_header); let capabilities = if endpoint_header.status(&state.pcie).has_capability_list() { endpoint_header @@ -182,11 +108,7 @@ fn handle_parsed_header( let func = pcid_interface::PciFunction { bars, addr: endpoint_header.header().address(), - legacy_interrupt_line: if legacy_interrupt_enabled { - Some(LegacyInterruptLine { irq, phandled }) - } else { - None - }, + legacy_interrupt_line, full_device_id: full_device_id.clone(), }; @@ -194,12 +116,81 @@ fn handle_parsed_header( } } +fn enable_function( + state: &Arc, + endpoint_header: &mut EndpointHeader, +) -> Option { + // Enable bus mastering, memory space, and I/O space + endpoint_header.update_command(&state.pcie, |cmd| { + cmd | CommandRegister::BUS_MASTER_ENABLE + | CommandRegister::MEMORY_ENABLE + | CommandRegister::IO_ENABLE + }); + + // Set IRQ line to 9 if not set + let mut irq = 0xFF; + let mut interrupt_pin = 0xFF; + + endpoint_header.update_interrupt(&state.pcie, |(pin, mut line)| { + if line == 0xFF { + line = 9; + } + irq = line; + interrupt_pin = pin; + (pin, line) + }); + + let legacy_interrupt_enabled = match interrupt_pin { + 0 => false, + 1 | 2 | 3 | 4 => true, + + other => { + warn!("pcid: invalid interrupt pin: {}", other); + false + } + }; + + if legacy_interrupt_enabled { + let pci_address = endpoint_header.header().address(); + let dt_address = ((pci_address.bus() as u32) << 16) + | ((pci_address.device() as u32) << 11) + | ((pci_address.function() as u32) << 8); + let addr = [ + dt_address & state.pcie.interrupt_map_mask[0], + 0u32, + 0u32, + interrupt_pin as u32 & state.pcie.interrupt_map_mask[3], + ]; + let mapping = state + .pcie + .interrupt_map + .iter() + .find(|x| x.addr == addr[0..3] && x.interrupt == addr[3]); + let phandled = if let Some(mapping) = mapping { + Some(( + mapping.parent_phandle, + mapping.parent_interrupt, + mapping.parent_interrupt_cells, + )) + } else { + None + }; + if mapping.is_some() { + debug!("found mapping: addr={:?} => {:?}", addr, phandled); + } + + Some(LegacyInterruptLine { irq, phandled }) + } else { + None + } +} + fn main() { - let args = Args::from_args(); + let mut args = pico_args::Arguments::from_env(); let mut config = Config::default(); - if let Some(config_path) = args.config_path { + if let Ok(config_path) = args.free_from_str::() { if metadata(&config_path).unwrap().is_file() { if let Ok(mut config_file) = File::open(&config_path) { let mut config_data = String::new(); @@ -224,7 +215,8 @@ fn main() { } } - let log_level = match args.verbose { + let verbosity = (0..).find(|_| !args.contains("-v")).unwrap_or(0); + let log_level = match verbosity { 0 => log::LevelFilter::Info, 1 => log::LevelFilter::Debug, _ => log::LevelFilter::Trace,