From bd6716efe490164f88e944fccfa7adf2da216e67 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 22 Jan 2024 19:07:57 +0100 Subject: [PATCH 1/6] Make legacy_interrupt_line an Option Drivers don't need to know the exact legacy_interrupt_pin in use. Just if legacy interrupts are enabled and if so which legacy_interrupt_line is used. --- ac97d/src/main.rs | 2 +- ahcid/src/main.rs | 2 +- e1000d/src/main.rs | 2 +- ihdad/src/main.rs | 25 ++++++++++--------------- ixgbed/src/main.rs | 2 +- nvmed/src/main.rs | 14 ++++++-------- pcid/src/driver_interface/mod.rs | 6 ++---- pcid/src/main.rs | 28 +++++++++++----------------- rtl8139d/src/main.rs | 27 +++++++++++---------------- rtl8168d/src/main.rs | 27 +++++++++++---------------- vboxd/src/main.rs | 2 +- xhcid/src/main.rs | 9 +++------ 12 files changed, 59 insertions(+), 87 deletions(-) diff --git a/ac97d/src/main.rs b/ac97d/src/main.rs index 04a5f3f7be..f061fcda7d 100644 --- a/ac97d/src/main.rs +++ b/ac97d/src/main.rs @@ -76,7 +76,7 @@ fn main() { let bar0 = pci_config.func.bars[0].expect_port(); let bar1 = pci_config.func.bars[1].expect_port(); - let irq = pci_config.func.legacy_interrupt_line; + let irq = pci_config.func.legacy_interrupt_line.expect("ac97d: no legacy interrupts supported"); print!("{}", format!(" + ac97 {} on: {:X}, {:X}, IRQ {}\n", name, bar0, bar1, irq)); diff --git a/ahcid/src/main.rs b/ahcid/src/main.rs index 3d661c321f..03ebaefd69 100644 --- a/ahcid/src/main.rs +++ b/ahcid/src/main.rs @@ -83,7 +83,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let (bar, bar_size) = pci_config.func.bars[5].expect_mem(); - let irq = pci_config.func.legacy_interrupt_line; + let irq = pci_config.func.legacy_interrupt_line.expect("ahcid: no legacy interrupts supported"); let _logger_ref = setup_logging(&name); diff --git a/e1000d/src/main.rs b/e1000d/src/main.rs index dffeb43f4d..3520e5be71 100644 --- a/e1000d/src/main.rs +++ b/e1000d/src/main.rs @@ -70,7 +70,7 @@ fn main() { let (bar, bar_size) = pci_config.func.bars[0].expect_mem(); - let irq = pci_config.func.legacy_interrupt_line; + let irq = pci_config.func.legacy_interrupt_line.expect("e1000d: no legacy interrupts supported"); eprintln!(" + E1000 {} on: {:X} size: {} IRQ: {}", name, bar, bar_size, irq); diff --git a/ihdad/src/main.rs b/ihdad/src/main.rs index 860446ad5c..f447df8566 100755 --- a/ihdad/src/main.rs +++ b/ihdad/src/main.rs @@ -74,11 +74,9 @@ fn setup_logging() -> Option<&'static RedoxLogger> { } #[cfg(target_arch = "x86_64")] -fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { +fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pci_config = pcid_handle.fetch_config().expect("ihdad: failed to fetch config"); - let irq = pci_config.func.legacy_interrupt_line; - let all_pci_features = pcid_handle.fetch_all_features().expect("ihdad: failed to fetch pci features"); log::debug!("PCI FEATURES: {:?}", all_pci_features); @@ -123,30 +121,27 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { pcid_handle.enable_feature(PciFeature::Msi).expect("ihdad: failed to enable MSI"); log::debug!("Enabled MSI"); - Some(interrupt_handle) - } else if pci_config.func.legacy_interrupt_pin.is_some() { + interrupt_handle + } else if let Some(irq) = pci_config.func.legacy_interrupt_line { log::debug!("Legacy IRQ {}", irq); // legacy INTx# interrupt pins. - Some(File::open(format!("irq:{}", irq)).expect("ihdad: failed to open legacy IRQ file")) + File::open(format!("irq:{}", irq)).expect("ihdad: failed to open legacy IRQ file") } else { - // no interrupts at all - None + panic!("ihdad: no interrupts supported at all") } } //TODO: MSI on non-x86_64? #[cfg(not(target_arch = "x86_64"))] -fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { +fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pci_config = pcid_handle.fetch_config().expect("ihdad: failed to fetch config"); - let irq = pci_config.func.legacy_interrupt_line; - if pci_config.func.legacy_interrupt_pin.is_some() { + if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - Some(File::open(format!("irq:{}", irq)).expect("ihdad: failed to open legacy IRQ file")) + File::open(format!("irq:{}", irq)).expect("ihdad: failed to open legacy IRQ file") } else { - // no interrupts at all - None + panic!("ihdad: no interrupts supported at all") } } @@ -170,7 +165,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { }; //TODO: MSI-X - let mut irq_file = get_int_method(&mut pcid_handle).expect("ihdad: no interrupt file"); + let mut irq_file = get_int_method(&mut pcid_handle); { let vend_prod: u32 = ((pci_config.func.full_device_id.vendor_id as u32) << 16) diff --git a/ixgbed/src/main.rs b/ixgbed/src/main.rs index 4666b98142..f53c0259b8 100644 --- a/ixgbed/src/main.rs +++ b/ixgbed/src/main.rs @@ -78,7 +78,7 @@ fn main() { let (bar, _) = pci_config.func.bars[0].expect_mem(); - let irq = pci_config.func.legacy_interrupt_line; + let irq = pci_config.func.legacy_interrupt_line.expect("ixgbed: no legacy interrupts supported"); println!(" + IXGBE {} on: {:X} IRQ: {}", name, bar, irq); diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index 09ced15aff..eda7d701c9 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -205,14 +205,13 @@ fn get_int_method( pcid_handle.enable_feature(PciFeature::Msi).unwrap(); Ok((interrupt_method, interrupt_sources)) - } else if function.legacy_interrupt_pin.is_some() { + } else if let Some(irq) = function.legacy_interrupt_line { // INTx# pin based interrupts. - let irq_handle = File::open(format!("irq:{}", function.legacy_interrupt_line)) + let irq_handle = File::open(format!("irq:{}", irq)) .expect("nvmed: failed to open INTx# interrupt line"); Ok((InterruptMethod::Intx, InterruptSources::Intx(irq_handle))) } else { - // No interrupts at all - todo!("handling of no interrupts") + panic!("nvmed: no interrupts supported at all") } } @@ -223,14 +222,13 @@ fn get_int_method( function: &PciFunction, allocated_bars: &AllocatedBars, ) -> Result<(InterruptMethod, InterruptSources)> { - if function.legacy_interrupt_pin.is_some() { + if let Some(irq) = function.legacy_interrupt_line { // INTx# pin based interrupts. - let irq_handle = File::open(format!("irq:{}", function.legacy_interrupt_line)) + let irq_handle = File::open(format!("irq:{}", irq)) .expect("nvmed: failed to open INTx# interrupt line"); Ok((InterruptMethod::Intx, InterruptSources::Intx(irq_handle))) } else { - // No interrupts at all - todo!("handling of no interrupts") + panic!("nvmed: no interrupts supported at all") } } diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 36c002a15f..faae3229f8 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -57,10 +57,8 @@ pub struct PciFunction { /// Legacy IRQ line: It's the responsibility of pcid to make sure that it be mapped in either /// the I/O APIC or the 8259 PIC, so that the subdriver can map the interrupt vector directly. /// The vector to map is always this field, plus 32. - pub legacy_interrupt_line: u8, - - /// Legacy interrupt pin (INTx#), none if INTx# interrupts aren't supported at all. - pub legacy_interrupt_pin: Option, + /// If INTx# interrupts aren't supported at all this is `None`. + pub legacy_interrupt_line: Option, /// All identifying information of the PCI function. pub full_device_id: FullDeviceId, diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 2858433a43..09ef81d23b 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -280,6 +280,16 @@ fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, he state.pcie.write(addr, 0x3C, data); }; + let legacy_interrupt_enabled = match interrupt_pin { + 0 => false, + 1 | 2 | 3 | 4 => true, + + other => { + warn!("pcid: invalid interrupt pin: {}", other); + false + } + }; + let capabilities = if endpoint_header.status(&state.pcie).has_capability_list() { let func = PciFunc { pci: &state.pcie, @@ -291,26 +301,10 @@ fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, he }; debug!("PCI DEVICE CAPABILITIES for {}: {:?}", args.iter().map(|string| string.as_ref()).nth(0).unwrap_or("[unknown]"), capabilities); - use driver_interface::LegacyInterruptPin; - - let legacy_interrupt_pin = match interrupt_pin { - 0 => None, - 1 => Some(LegacyInterruptPin::IntA), - 2 => Some(LegacyInterruptPin::IntB), - 3 => Some(LegacyInterruptPin::IntC), - 4 => Some(LegacyInterruptPin::IntD), - - other => { - warn!("pcid: invalid interrupt pin: {}", other); - None - } - }; - let func = driver_interface::PciFunction { bars, addr, - legacy_interrupt_line: irq, - legacy_interrupt_pin, + legacy_interrupt_line: if legacy_interrupt_enabled { Some(irq) } else { None }, full_device_id: header.full_device_id().clone(), }; diff --git a/rtl8139d/src/main.rs b/rtl8139d/src/main.rs index dc3616a08a..95051c4eb4 100644 --- a/rtl8139d/src/main.rs +++ b/rtl8139d/src/main.rs @@ -108,11 +108,9 @@ impl MsixInfo { } #[cfg(target_arch = "x86_64")] -fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { +fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pci_config = pcid_handle.fetch_config().expect("rtl8139d: failed to fetch config"); - let irq = pci_config.func.legacy_interrupt_line; - let all_pci_features = pcid_handle.fetch_all_features().expect("rtl8139d: failed to fetch pci features"); log::info!("PCI FEATURES: {:?}", all_pci_features); @@ -157,7 +155,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { pcid_handle.enable_feature(PciFeature::Msi).expect("rtl8139d: failed to enable MSI"); log::info!("Enabled MSI"); - Some(interrupt_handle) + interrupt_handle } else if msix_enabled { let capability = match pcid_handle.feature_info(PciFeature::MsiX).expect("rtl8139d: failed to retrieve the MSI-X capability structure from pcid") { PciFeatureInfo::Msi(_) => panic!(), @@ -220,34 +218,31 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { table_entry_pointer.msg_data.write(msg_data); table_entry_pointer.vec_ctl.writef(MsixTableEntry::VEC_CTL_MASK_BIT, false); - Some(interrupt_handle) + interrupt_handle }; pcid_handle.enable_feature(PciFeature::MsiX).expect("rtl8139d: failed to enable MSI-X"); log::info!("Enabled MSI-X"); method - } else if pci_config.func.legacy_interrupt_pin.is_some() { + } else if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - Some(File::open(format!("irq:{}", irq)).expect("rtl8139d: failed to open legacy IRQ file")) + File::open(format!("irq:{}", irq)).expect("rtl8139d: failed to open legacy IRQ file") } else { - // no interrupts at all - None + panic!("rtl8139d: no interrupts supported at all") } } //TODO: MSI on non-x86_64? #[cfg(not(target_arch = "x86_64"))] -fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { +fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pci_config = pcid_handle.fetch_config().expect("rtl8139d: failed to fetch config"); - let irq = pci_config.func.legacy_interrupt_line; - if pci_config.func.legacy_interrupt_pin.is_some() { + if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - Some(File::open(format!("irq:{}", irq)).expect("rtl8139d: failed to open legacy IRQ file")) + File::open(format!("irq:{}", irq)).expect("rtl8139d: failed to open legacy IRQ file") } else { - // no interrupts at all - None + panic!("rtl8139d: no interrupts supported at all") } } @@ -340,7 +335,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { })); //TODO: MSI-X - let mut irq_file = get_int_method(&mut pcid_handle).expect("rtl8139d: no interrupt file"); + let mut irq_file = get_int_method(&mut pcid_handle); { let device = Arc::new(RefCell::new(unsafe { diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index 2592100b2c..c657a716dc 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -106,11 +106,9 @@ impl MsixInfo { } #[cfg(target_arch = "x86_64")] -fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { +fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pci_config = pcid_handle.fetch_config().expect("rtl8168d: failed to fetch config"); - let irq = pci_config.func.legacy_interrupt_line; - let all_pci_features = pcid_handle.fetch_all_features().expect("rtl8168d: failed to fetch pci features"); log::info!("PCI FEATURES: {:?}", all_pci_features); @@ -155,7 +153,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { pcid_handle.enable_feature(PciFeature::Msi).expect("rtl8168d: failed to enable MSI"); log::info!("Enabled MSI"); - Some(interrupt_handle) + interrupt_handle } else if msix_enabled { let capability = match pcid_handle.feature_info(PciFeature::MsiX).expect("rtl8168d: failed to retrieve the MSI-X capability structure from pcid") { PciFeatureInfo::Msi(_) => panic!(), @@ -218,34 +216,31 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { table_entry_pointer.msg_data.write(msg_data); table_entry_pointer.vec_ctl.writef(MsixTableEntry::VEC_CTL_MASK_BIT, false); - Some(interrupt_handle) + interrupt_handle }; pcid_handle.enable_feature(PciFeature::MsiX).expect("rtl8168d: failed to enable MSI-X"); log::info!("Enabled MSI-X"); method - } else if pci_config.func.legacy_interrupt_pin.is_some() { + } else if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - Some(File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open legacy IRQ file")) + File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open legacy IRQ file") } else { - // no interrupts at all - None + panic!("rtl8168d: no interrupts supported at all") } } //TODO: MSI on non-x86_64? #[cfg(not(target_arch = "x86_64"))] -fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option { +fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pci_config = pcid_handle.fetch_config().expect("rtl8168d: failed to fetch config"); - let irq = pci_config.func.legacy_interrupt_line; - if pci_config.func.legacy_interrupt_pin.is_some() { + if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - Some(File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open legacy IRQ file")) + File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open legacy IRQ file") } else { - // no interrupts at all - None + panic!("rtl8168d: no interrupts supported at all") } } @@ -338,7 +333,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { })); //TODO: MSI-X - let mut irq_file = get_int_method(&mut pcid_handle).expect("rtl8168d: no interrupt file"); + let mut irq_file = get_int_method(&mut pcid_handle); { let device = Arc::new(RefCell::new(unsafe { diff --git a/vboxd/src/main.rs b/vboxd/src/main.rs index 77f43eb10d..be17b4f934 100644 --- a/vboxd/src/main.rs +++ b/vboxd/src/main.rs @@ -198,7 +198,7 @@ fn main() { let (bar1, _) = pci_config.func.bars[1].expect_mem(); - let irq = pci_config.func.legacy_interrupt_line; + let irq = pci_config.func.legacy_interrupt_line.expect("vboxd: no legacy interrupts supported"); print!("{}", format!(" + VirtualBox {} on: {:X}, {:X}, IRQ {}\n", name, bar0, bar1, irq)); diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index 9c8dbf542e..7fad420600 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -86,7 +86,6 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option let pci_config = pcid_handle.fetch_config().expect("xhcid: failed to fetch config"); let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem(); - let irq = pci_config.func.legacy_interrupt_line; let all_pci_features = pcid_handle.fetch_all_features().expect("xhcid: failed to fetch pci features"); log::debug!("XHCI PCI FEATURES: {:?}", all_pci_features); @@ -194,7 +193,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option log::debug!("Enabled MSI-X"); method - } else if pci_config.func.legacy_interrupt_pin.is_some() { + } else if let Some(irq) = pci_config.func.legacy_interrupt_line { log::debug!("Legacy IRQ {}", irq); // legacy INTx# interrupt pins. @@ -209,9 +208,8 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option #[cfg(not(target_arch = "x86_64"))] fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option, InterruptMethod) { let pci_config = pcid_handle.fetch_config().expect("xhcid: failed to fetch config"); - let irq = pci_config.func.legacy_interrupt_line; - if pci_config.func.legacy_interrupt_pin.is_some() { + if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. (Some(File::open(format!("irq:{}", irq)).expect("xhcid: failed to open legacy IRQ file")), InterruptMethod::Intx) } else { @@ -235,7 +233,6 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::debug!("XHCI PCI CONFIG: {:?}", pci_config); let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem(); - let irq = pci_config.func.legacy_interrupt_line; let address = unsafe { common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) @@ -246,7 +243,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { print!( "{}", - format!(" + XHCI {} on: {:016X} IRQ: {}\n", name, bar_ptr, irq) + format!(" + XHCI {} on: {:016X}\n", name, bar_ptr) ); let scheme_name = format!("usb.{}", name); From ad23ad5d93f1c8980e867d884397ac0a9910300b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 22 Jan 2024 19:34:26 +0100 Subject: [PATCH 2/6] Introduce irq_handle helper for legacy interrupts --- ac97d/src/main.rs | 2 +- ahcid/src/main.rs | 8 +++----- e1000d/src/main.rs | 6 +----- ixgbed/src/main.rs | 3 +-- nvmed/src/main.rs | 6 ++---- pcid/Cargo.toml | 2 +- pcid/src/driver_interface/mod.rs | 27 ++++++++++++++++----------- pcid/src/main.rs | 7 ++++++- rtl8139d/src/main.rs | 4 ++-- rtl8168d/src/main.rs | 4 ++-- vboxd/src/main.rs | 2 +- xhcid/src/main.rs | 4 ++-- 12 files changed, 38 insertions(+), 37 deletions(-) diff --git a/ac97d/src/main.rs b/ac97d/src/main.rs index f061fcda7d..93f6b3297f 100644 --- a/ac97d/src/main.rs +++ b/ac97d/src/main.rs @@ -86,7 +86,7 @@ fn main() { unsafe { syscall::iopl(3) }.expect("ac97d: failed to set I/O privilege level to Ring 3"); - let mut irq_file = File::open(format!("irq:{}", irq)).expect("ac97d: failed to open IRQ file"); + let mut irq_file = irq.irq_handle("ac97d"); let device = Arc::new(RefCell::new(unsafe { device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") })); let socket_fd = syscall::open(":audiohw", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("ac97d: failed to create hda scheme"); diff --git a/ahcid/src/main.rs b/ahcid/src/main.rs index 03ebaefd69..fcd3c0920d 100644 --- a/ahcid/src/main.rs +++ b/ahcid/src/main.rs @@ -6,6 +6,7 @@ extern crate byteorder; use std::fs::File; use std::io::{ErrorKind, Read, Write}; +use std::os::fd::AsRawFd; use std::os::unix::io::{FromRawFd, RawFd}; use std::usize; @@ -105,11 +106,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { ).expect("ahcid: failed to create disk scheme"); let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; - let irq_fd = syscall::open( - &format!("irq:{}", irq), - syscall::O_RDWR | syscall::O_NONBLOCK - ).expect("ahcid: failed to open irq file"); - let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) }; + let mut irq_file = irq.irq_handle("ahcid"); + let irq_fd = irq_file.as_raw_fd() as usize; let mut event_file = File::open("event:").expect("ahcid: failed to open event file"); diff --git a/e1000d/src/main.rs b/e1000d/src/main.rs index 3520e5be71..094ec47b03 100644 --- a/e1000d/src/main.rs +++ b/e1000d/src/main.rs @@ -84,11 +84,7 @@ fn main() { File::from_raw_fd(socket_fd as RawFd) })); - let irq_fd = syscall::open( - format!("irq:{}", irq), - syscall::O_RDWR | syscall::O_NONBLOCK - ).expect("e1000d: failed to open IRQ file"); - let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) }; + let mut irq_file = irq.irq_handle("e1000d"); let address = unsafe { common::physmap(bar, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) diff --git a/ixgbed/src/main.rs b/ixgbed/src/main.rs index f53c0259b8..a9a65cd248 100644 --- a/ixgbed/src/main.rs +++ b/ixgbed/src/main.rs @@ -94,8 +94,7 @@ fn main() { daemon.ready().expect("ixgbed: failed to signal readiness"); - let mut irq_file = - File::open(format!("irq:{}", irq)).expect("ixgbed: failed to open IRQ file"); + let mut irq_file = irq.irq_handle("ixgbed"); let address = unsafe { common::physmap(bar, IXGBE_MMIO_SIZE, common::Prot::RW, common::MemoryType::Uncacheable) diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index eda7d701c9..e52b922ebd 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -207,8 +207,7 @@ fn get_int_method( Ok((interrupt_method, interrupt_sources)) } else if let Some(irq) = function.legacy_interrupt_line { // INTx# pin based interrupts. - let irq_handle = File::open(format!("irq:{}", irq)) - .expect("nvmed: failed to open INTx# interrupt line"); + let irq_handle = irq.irq_handle("nvmed"); Ok((InterruptMethod::Intx, InterruptSources::Intx(irq_handle))) } else { panic!("nvmed: no interrupts supported at all") @@ -224,8 +223,7 @@ fn get_int_method( ) -> Result<(InterruptMethod, InterruptSources)> { if let Some(irq) = function.legacy_interrupt_line { // INTx# pin based interrupts. - let irq_handle = File::open(format!("irq:{}", irq)) - .expect("nvmed: failed to open INTx# interrupt line"); + let irq_handle = irq.irq_handle("nvmed"); Ok((InterruptMethod::Intx, InterruptSources::Intx(irq_handle))) } else { panic!("nvmed: no interrupts supported at all") diff --git a/pcid/Cargo.toml b/pcid/Cargo.toml index 794002fb18..b883b4e8ce 100644 --- a/pcid/Cargo.toml +++ b/pcid/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pcid" version = "0.1.0" -edition = "2018" +edition = "2021" [[bin]] name = "pcid" diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index faae3229f8..1678ef7594 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -1,3 +1,4 @@ +use std::fmt; use std::fs::File; use std::io::prelude::*; use std::{env, io}; @@ -14,16 +15,20 @@ pub use crate::pci::{FullDeviceId, PciAddress, PciBar}; pub mod irq_helpers; #[derive(Clone, Copy, Debug, Serialize, Deserialize)] -#[repr(u8)] -pub enum LegacyInterruptPin { - /// INTa# - IntA = 1, - /// INTb# - IntB = 2, - /// INTc# - IntC = 3, - /// INTd# - IntD = 4, +pub struct LegacyInterruptLine(pub(crate) u8); + +impl LegacyInterruptLine { + /// Get an IRQ handle for this interrupt line. + pub fn irq_handle(self, driver: &str) -> File { + File::open(format!("irq:{}", self.0)) + .unwrap_or_else(|err| panic!("{driver}: failed to open IRQ file: {err}")) + } +} + +impl fmt::Display for LegacyInterruptLine { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } } #[derive(Serialize, Deserialize)] @@ -58,7 +63,7 @@ pub struct PciFunction { /// the I/O APIC or the 8259 PIC, so that the subdriver can map the interrupt vector directly. /// The vector to map is always this field, plus 32. /// If INTx# interrupts aren't supported at all this is `None`. - pub legacy_interrupt_line: Option, + pub legacy_interrupt_line: Option, /// All identifying information of the PCI function. pub full_device_id: FullDeviceId, diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 09ef81d23b..6591e385e6 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -13,6 +13,7 @@ use redox_log::{OutputBuilder, RedoxLogger}; use crate::cfg_access::Pcie; use crate::config::Config; +use crate::driver_interface::LegacyInterruptLine; use crate::pci::{PciBar, PciFunc}; use crate::pci::cap::Capability as PciCapability; use crate::pci::func::{ConfigReader, ConfigWriter}; @@ -304,7 +305,11 @@ fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, he let func = driver_interface::PciFunction { bars, addr, - legacy_interrupt_line: if legacy_interrupt_enabled { Some(irq) } else { None }, + legacy_interrupt_line: if legacy_interrupt_enabled { + Some(LegacyInterruptLine(irq)) + } else { + None + }, full_device_id: header.full_device_id().clone(), }; diff --git a/rtl8139d/src/main.rs b/rtl8139d/src/main.rs index 95051c4eb4..703fc55f1b 100644 --- a/rtl8139d/src/main.rs +++ b/rtl8139d/src/main.rs @@ -227,7 +227,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { method } else if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - File::open(format!("irq:{}", irq)).expect("rtl8139d: failed to open legacy IRQ file") + irq.irq_handle("rtl8139d") } else { panic!("rtl8139d: no interrupts supported at all") } @@ -240,7 +240,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - File::open(format!("irq:{}", irq)).expect("rtl8139d: failed to open legacy IRQ file") + irq.irq_handle("rtl8139d") } else { panic!("rtl8139d: no interrupts supported at all") } diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index c657a716dc..19140b6f9a 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -225,7 +225,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { method } else if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open legacy IRQ file") + irq.irq_handle("rtl8168d") } else { panic!("rtl8168d: no interrupts supported at all") } @@ -238,7 +238,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - File::open(format!("irq:{}", irq)).expect("rtl8168d: failed to open legacy IRQ file") + irq.irq_handle("rtl8168d") } else { panic!("rtl8168d: no interrupts supported at all") } diff --git a/vboxd/src/main.rs b/vboxd/src/main.rs index be17b4f934..7905f00e7f 100644 --- a/vboxd/src/main.rs +++ b/vboxd/src/main.rs @@ -221,7 +221,7 @@ fn main() { } } - let mut irq_file = File::open(format!("irq:{}", irq)).expect("vboxd: failed to open IRQ file"); + let mut irq_file = irq.irq_handle("vboxd"); let mut port = Pio::::new(bar0 as u16); let address = unsafe { common::physmap(bar1, 4096, common::Prot::RW, common::MemoryType::Uncacheable).expect("vboxd: failed to map address") }; diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index 7fad420600..21ea4f9d4e 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -197,7 +197,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option log::debug!("Legacy IRQ {}", irq); // legacy INTx# interrupt pins. - (Some(File::open(format!("irq:{}", irq)).expect("xhcid: failed to open legacy IRQ file")), InterruptMethod::Intx) + (Some(irq.irq_handle("xhcid")), InterruptMethod::Intx) } else { // no interrupts at all (None, InterruptMethod::Polling) @@ -211,7 +211,7 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle, address: usize) -> (Option if let Some(irq) = pci_config.func.legacy_interrupt_line { // legacy INTx# interrupt pins. - (Some(File::open(format!("irq:{}", irq)).expect("xhcid: failed to open legacy IRQ file")), InterruptMethod::Intx) + (Some(irq.irq_handle("xhcid")), InterruptMethod::Intx) } else { // no interrupts at all (None, InterruptMethod::Polling) From c13161c4a52e94acf78fdf0c78399e578bc60dcd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 22 Jan 2024 19:57:24 +0100 Subject: [PATCH 3/6] Fix nvmed --- nvmed/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index e52b922ebd..6aeceeb7f8 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -284,7 +284,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .fetch_config() .expect("nvmed: failed to fetch config"); - let scheme_name = format!("disk.pci-{}-nvme", pci_config.func.addr); + let scheme_name = format!("disk.{}-nvme", pci_config.func.name()); let _logger_ref = setup_logging(&scheme_name); From 4302a35a7e7c01f8af87eeafaaefaf7fce5a093d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:44:17 +0100 Subject: [PATCH 4/6] Remove a couple of unused functions from MsixCapability The set and write methods were useless as no rpc call is exposed by pcid to actually write the new values. As for the rest, there were no uses and they can be emulated using the other methods. --- pcid/src/pci/msi.rs | 60 +++++++-------------------------------------- 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/pcid/src/pci/msi.rs b/pcid/src/pci/msi.rs index ba37e30127..fe09768a91 100644 --- a/pcid/src/pci/msi.rs +++ b/pcid/src/pci/msi.rs @@ -203,11 +203,11 @@ impl MsiCapability { } impl MsixCapability { - pub const MC_MSIX_ENABLED_BIT: u16 = 1 << 15; - pub const MC_MSIX_ENABLED_SHIFT: u8 = 15; - pub const MC_FUNCTION_MASK_BIT: u16 = 1 << 14; - pub const MC_FUNCTION_MASK_SHIFT: u8 = 14; - pub const MC_TABLE_SIZE_MASK: u16 = 0x03FF; + const MC_MSIX_ENABLED_BIT: u16 = 1 << 15; + const MC_MSIX_ENABLED_SHIFT: u8 = 15; + const MC_FUNCTION_MASK_BIT: u16 = 1 << 14; + const MC_FUNCTION_MASK_SHIFT: u8 = 14; + const MC_TABLE_SIZE_MASK: u16 = 0x03FF; /// The Message Control field, containing the enabled and function mask bits, as well as the /// table size. @@ -246,8 +246,8 @@ impl MsixCapability { new_message_control |= u16::from(function_mask) << Self::MC_FUNCTION_MASK_SHIFT; self.set_message_control(new_message_control); } - pub const TABLE_OFFSET_MASK: u32 = 0xFFFF_FFF8; - pub const TABLE_BIR_MASK: u32 = 0x0000_0007; + const TABLE_OFFSET_MASK: u32 = 0xFFFF_FFF8; + const TABLE_BIR_MASK: u32 = 0x0000_0007; /// The table offset is guaranteed to be QWORD aligned (8 bytes). pub const fn table_offset(&self) -> u32 { @@ -258,13 +258,8 @@ impl MsixCapability { (self.b & Self::TABLE_BIR_MASK) as u8 } - pub fn set_table_offset(&mut self, offset: u32) { - assert_eq!(offset & Self::TABLE_OFFSET_MASK, offset, "MSI-X table offset has to be QWORD aligned"); - self.b &= !Self::TABLE_OFFSET_MASK; - self.b |= offset; - } - pub const PBA_OFFSET_MASK: u32 = 0xFFFF_FFF8; - pub const PBA_BIR_MASK: u32 = 0x0000_0007; + const PBA_OFFSET_MASK: u32 = 0xFFFF_FFF8; + const PBA_BIR_MASK: u32 = 0x0000_0007; /// The Pending Bit Array offset is guaranteed to be QWORD aligned (8 bytes). pub const fn pba_offset(&self) -> u32 { @@ -275,11 +270,6 @@ impl MsixCapability { (self.c & Self::PBA_BIR_MASK) as u8 } - pub fn set_pba_offset(&mut self, offset: u32) { - assert_eq!(offset & Self::PBA_OFFSET_MASK, offset, "MSI-X Pending Bit Array offset has to be QWORD aligned"); - self.c &= !Self::PBA_OFFSET_MASK; - self.c |= offset; - } pub fn table_base_pointer(&self, bars: [PciBar; 6]) -> usize { if self.table_bir() > 5 { @@ -287,9 +277,6 @@ impl MsixCapability { } bars[usize::from(self.table_bir())].expect_mem().0 + self.table_offset() as usize } - pub fn table_pointer(&self, bars: [PciBar; 6], k: u16) -> usize { - self.table_base_pointer(bars) + k as usize * 16 - } pub fn pba_base_pointer(&self, bars: [PciBar; 6]) -> usize { if self.pba_bir() > 5 { @@ -297,41 +284,12 @@ impl MsixCapability { } bars[usize::from(self.pba_bir())].expect_mem().0 + self.pba_offset() as usize } - pub fn pba_pointer_dword(&self, bars: [PciBar; 6], k: u16) -> usize { - self.pba_base_pointer(bars) + (k as usize / 32) * 4 - } - pub const fn pba_bit_dword(&self, k: u16) -> u8 { - (k % 32) as u8 - } - - pub fn pba_pointer_qword(&self, bars: [PciBar; 6], k: u16) -> usize { - self.pba_base_pointer(bars) + (k as usize / 64) * 8 - } - pub const fn pba_bit_qword(&self, k: u16) -> u8 { - (k % 64) as u8 - } /// Write the first DWORD into configuration space (containing the partially modifiable Message /// Control field). pub unsafe fn write_a(&self, writer: &W, offset: u8) { writer.write_u32(u16::from(offset), self.a) } - /// Write the second DWORD into configuration space (containing the modifiable table - /// offset and the readonly table BIR). - pub unsafe fn write_b(&self, writer: &W, offset: u8) { - writer.write_u32(u16::from(offset + 4), self.a) - } - /// Write the third DWORD into configuration space (containing the modifiable pending bit array - /// offset, and the readonly PBA BIR). - pub unsafe fn write_c(&self, writer: &W, offset: u8) { - writer.write_u32(u16::from(offset + 8), self.a) - } - /// Write this capability structure back to configuration space. - pub unsafe fn write_all(&self, writer: &W, offset: u8) { - self.write_a(writer, offset); - self.write_b(writer, offset); - self.write_c(writer, offset); - } } #[repr(packed)] From 77b97bb2edfd81733e56cec343a43e0a8c7f3206 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:02:40 +0100 Subject: [PATCH 5/6] Introduce PciBar::physmap_mem helper --- ahcid/src/main.rs | 14 ++++---------- e1000d/src/main.rs | 10 ++++------ ihdad/src/main.rs | 8 +++----- nvmed/src/main.rs | 23 ++++++++++------------- pcid/src/pci/bar.rs | 14 ++++++++++++++ rtl8139d/src/main.rs | 8 +++----- rtl8168d/src/main.rs | 8 +++----- vboxd/src/main.rs | 7 ++++--- virtio-core/src/arch/x86_64.rs | 12 +++--------- xhcid/src/main.rs | 8 +++----- 10 files changed, 51 insertions(+), 61 deletions(-) diff --git a/ahcid/src/main.rs b/ahcid/src/main.rs index fcd3c0920d..166214934c 100644 --- a/ahcid/src/main.rs +++ b/ahcid/src/main.rs @@ -82,22 +82,16 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut name = pci_config.func.name(); name.push_str("_ahci"); - let (bar, bar_size) = pci_config.func.bars[5].expect_mem(); + let bar = &pci_config.func.bars[5]; + let (bar_ptr, bar_size) = bar.expect_mem(); let irq = pci_config.func.legacy_interrupt_line.expect("ahcid: no legacy interrupts supported"); let _logger_ref = setup_logging(&name); - info!(" + AHCI {} on: {} size: {} IRQ: {}", name, bar, bar_size, irq); + info!(" + AHCI {} on: {} size: {} IRQ: {}", name, bar_ptr, bar_size, irq); - let address = unsafe { - common::physmap( - bar, - bar_size, - common::Prot { read: true, write: true }, - common::MemoryType::Uncacheable, - ).expect("ahcid: failed to map address") - }; + let address = unsafe { bar.physmap_mem("ahcid") }; { let scheme_name = format!("disk.{}", name); let socket_fd = syscall::open( diff --git a/e1000d/src/main.rs b/e1000d/src/main.rs index 094ec47b03..d77c3f82f0 100644 --- a/e1000d/src/main.rs +++ b/e1000d/src/main.rs @@ -68,11 +68,12 @@ fn main() { let mut name = pci_config.func.name(); name.push_str("_e1000"); - let (bar, bar_size) = pci_config.func.bars[0].expect_mem(); + let bar = &pci_config.func.bars[0]; + let (bar_ptr, bar_size) = bar.expect_mem(); let irq = pci_config.func.legacy_interrupt_line.expect("e1000d: no legacy interrupts supported"); - eprintln!(" + E1000 {} on: {:X} size: {} IRQ: {}", name, bar, bar_size, irq); + eprintln!(" + E1000 {} on: {:X} size: {} IRQ: {}", name, bar_ptr, bar_size, irq); redox_daemon::Daemon::new(move |daemon| { let socket_fd = syscall::open( @@ -86,10 +87,7 @@ fn main() { let mut irq_file = irq.irq_handle("e1000d"); - let address = unsafe { - common::physmap(bar, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) - .expect("e1000d: failed to map address") - } as usize; + let address = unsafe { bar.physmap_mem("e1000d") } as usize; { let device = Arc::new(RefCell::new(unsafe { device::Intel8254x::new(address).expect("e1000d: failed to allocate device") diff --git a/ihdad/src/main.rs b/ihdad/src/main.rs index f447df8566..f603197608 100755 --- a/ihdad/src/main.rs +++ b/ihdad/src/main.rs @@ -155,14 +155,12 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut name = pci_config.func.name(); name.push_str("_ihda"); - let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem(); + let bar = &pci_config.func.bars[0]; + let (bar_ptr, bar_size) = bar.expect_mem(); log::info!(" + IHDA {} on: {:#X} size: {}", name, bar_ptr, bar_size); - let address = unsafe { - common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) - .expect("ihdad: failed to map address") as usize - }; + let address = unsafe { bar.physmap_mem("ihdad") } as usize; //TODO: MSI-X let mut irq_file = get_int_method(&mut pcid_handle); diff --git a/nvmed/src/main.rs b/nvmed/src/main.rs index 6aeceeb7f8..8e57eb4db0 100644 --- a/nvmed/src/main.rs +++ b/nvmed/src/main.rs @@ -48,7 +48,12 @@ impl Bar { impl Drop for Bar { fn drop(&mut self) { - let _ = unsafe { syscall::funmap(self.physical, self.bar_size.next_multiple_of(PAGE_SIZE)) }; + let _ = unsafe { + syscall::funmap( + self.ptr.as_ptr() as usize, + self.bar_size.next_multiple_of(PAGE_SIZE), + ) + }; } } @@ -288,24 +293,16 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let _logger_ref = setup_logging(&scheme_name); - let (bar, bar_size) = pci_config.func.bars[0].expect_mem(); - let irq = pci_config.func.legacy_interrupt_line; + let bar = &pci_config.func.bars[0]; + let (bar_ptr, bar_size) = bar.expect_mem(); log::debug!("NVME PCI CONFIG: {:?}", pci_config); let allocated_bars = AllocatedBars::default(); - let address = unsafe { - common::physmap( - bar, - bar_size, - common::Prot { read: true, write: true }, - common::MemoryType::Uncacheable, - ) - .expect("nvmed: failed to map address") - } as usize; + let address = unsafe { bar.physmap_mem("nvmed") } as usize; *allocated_bars.0[0].lock().unwrap() = Some(Bar { - physical: bar, + physical: bar_ptr, bar_size, ptr: NonNull::new(address as *mut u8).expect("Physmapping BAR gave nullptr"), }); diff --git a/pcid/src/pci/bar.rs b/pcid/src/pci/bar.rs index 4ee887d91f..fa497d755b 100644 --- a/pcid/src/pci/bar.rs +++ b/pcid/src/pci/bar.rs @@ -41,4 +41,18 @@ impl PciBar { PciBar::None => panic!("expected BAR to exist"), } } + + pub unsafe fn physmap_mem(&self, driver: &str) -> *mut () { + let (bar, bar_size) = self.expect_mem(); + unsafe { + common::physmap( + bar, + bar_size, + common::Prot::RW, + // FIXME once the kernel supports this use write-through for prefetchable BAR + common::MemoryType::Uncacheable, + ) + } + .unwrap_or_else(|err| panic!("{driver}: failed to map BAR at {bar:016X}: {err}")) + } } diff --git a/rtl8139d/src/main.rs b/rtl8139d/src/main.rs index 703fc55f1b..771683010a 100644 --- a/rtl8139d/src/main.rs +++ b/rtl8139d/src/main.rs @@ -169,12 +169,10 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pba_base = capability.pba_base_pointer(pci_config.func.bars); let bir = capability.table_bir() as usize; - let (bar_ptr, bar_size) = pci_config.func.bars[bir].expect_mem(); + let bar = &pci_config.func.bars[bir]; + let (bar_ptr, bar_size) = bar.expect_mem(); - let address = unsafe { - common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) - .expect("rtl8139d: failed to map address") as usize - }; + let address = unsafe { bar.physmap_mem("rtl8139d") } as usize; if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) { panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size); diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index 19140b6f9a..c38b506d21 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -167,12 +167,10 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> File { let pba_base = capability.pba_base_pointer(pci_config.func.bars); let bir = capability.table_bir() as usize; - let (bar_ptr, bar_size) = pci_config.func.bars[bir].expect_mem(); + let bar = &pci_config.func.bars[bir]; + let (bar_ptr, bar_size) = bar.expect_mem(); - let address = unsafe { - common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) - .expect("rtl8168d: failed to map address") as usize - }; + let address = unsafe { bar.physmap_mem("rtl8168d") } as usize; if !(bar_ptr as u64..bar_ptr as u64 + bar_size as u64).contains(&(table_base as u64 + table_min_length as u64)) { panic!("Table {:#x}{:#x} outside of BAR {:#x}:{:#x}", table_base, table_base + table_min_length as usize, bar_ptr, bar_ptr + bar_size); diff --git a/vboxd/src/main.rs b/vboxd/src/main.rs index 7905f00e7f..17a8c23a2d 100644 --- a/vboxd/src/main.rs +++ b/vboxd/src/main.rs @@ -196,11 +196,12 @@ fn main() { let bar0 = pci_config.func.bars[0].expect_port(); - let (bar1, _) = pci_config.func.bars[1].expect_mem(); + let bar1 = &pci_config.func.bars[1]; + let (bar1_ptr, _) = bar1.expect_mem(); let irq = pci_config.func.legacy_interrupt_line.expect("vboxd: no legacy interrupts supported"); - print!("{}", format!(" + VirtualBox {} on: {:X}, {:X}, IRQ {}\n", name, bar0, bar1, irq)); + print!("{}", format!(" + VirtualBox {} on: {:X}, {:X}, IRQ {}\n", name, bar0, bar1_ptr, irq)); // Daemonize redox_daemon::Daemon::new(move |daemon| { @@ -224,7 +225,7 @@ fn main() { let mut irq_file = irq.irq_handle("vboxd"); let mut port = Pio::::new(bar0 as u16); - let address = unsafe { common::physmap(bar1, 4096, common::Prot::RW, common::MemoryType::Uncacheable).expect("vboxd: failed to map address") }; + let address = unsafe { bar1.physmap_mem("vboxd") }; { let vmmdev = unsafe { &mut *(address as *mut VboxVmmDev) }; diff --git a/virtio-core/src/arch/x86_64.rs b/virtio-core/src/arch/x86_64.rs index 5bccd00c2a..a160f508cd 100644 --- a/virtio-core/src/arch/x86_64.rs +++ b/virtio-core/src/arch/x86_64.rs @@ -27,16 +27,10 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result { let pba_base = capability.pba_base_pointer(pci_config.func.bars); let bir = capability.table_bir() as usize; - let (bar_ptr, bar_size) = pci_config.func.bars[bir].expect_mem(); + let bar = &pci_config.func.bars[bir]; + let (bar_ptr, bar_size) = bar.expect_mem(); - let address = unsafe { - common::physmap( - bar_ptr, - bar_size, - common::Prot::RW, - common::MemoryType::Uncacheable, - )? as usize - }; + let address = unsafe { bar.physmap_mem("virtio-core") } as usize; // Ensure that the table and PBA are be within the BAR. { diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index 21ea4f9d4e..9f95131be7 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -232,12 +232,10 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let _logger_ref = setup_logging(&name); log::debug!("XHCI PCI CONFIG: {:?}", pci_config); - let (bar_ptr, bar_size) = pci_config.func.bars[0].expect_mem(); + let bar = &pci_config.func.bars[0]; + let (bar_ptr, _) = bar.expect_mem(); - let address = unsafe { - common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) - .expect("xhcid: failed to map address") as usize - }; + let address = unsafe { bar.physmap_mem("xhcid") } as usize; let (mut irq_file, interrupt_method) = get_int_method(&mut pcid_handle, address); From 354c351b1938a7b4a30e843b083ff28149b155b9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Jan 2024 13:01:40 +0100 Subject: [PATCH 6/6] Unify device info printing between drivers --- ac97d/src/main.rs | 2 +- ahcid/src/main.rs | 3 +-- alxd/src/device/mod.rs | 2 +- alxd/src/main.rs | 2 +- bgad/src/main.rs | 2 +- e1000d/src/main.rs | 3 +-- ihdad/src/main.rs | 3 +-- ixgbed/src/main.rs | 2 +- pcid/src/driver_interface/mod.rs | 18 ++++++++++++++++++ pcid/src/main.rs | 7 ++----- pcid/src/pci/bar.rs | 9 +++++++++ rtl8139d/src/main.rs | 2 +- rtl8168d/src/main.rs | 2 +- sb16d/src/main.rs | 2 +- vboxd/src/main.rs | 3 +-- xhcid/src/main.rs | 8 ++------ 16 files changed, 43 insertions(+), 27 deletions(-) diff --git a/ac97d/src/main.rs b/ac97d/src/main.rs index 93f6b3297f..2a26dc193b 100644 --- a/ac97d/src/main.rs +++ b/ac97d/src/main.rs @@ -78,7 +78,7 @@ fn main() { let irq = pci_config.func.legacy_interrupt_line.expect("ac97d: no legacy interrupts supported"); - print!("{}", format!(" + ac97 {} on: {:X}, {:X}, IRQ {}\n", name, bar0, bar1, irq)); + println!(" + ac97 {}", pci_config.func.display()); // Daemonize redox_daemon::Daemon::new(move |daemon| { diff --git a/ahcid/src/main.rs b/ahcid/src/main.rs index 166214934c..60dd30ab12 100644 --- a/ahcid/src/main.rs +++ b/ahcid/src/main.rs @@ -83,13 +83,12 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { name.push_str("_ahci"); let bar = &pci_config.func.bars[5]; - let (bar_ptr, bar_size) = bar.expect_mem(); let irq = pci_config.func.legacy_interrupt_line.expect("ahcid: no legacy interrupts supported"); let _logger_ref = setup_logging(&name); - info!(" + AHCI {} on: {} size: {} IRQ: {}", name, bar_ptr, bar_size, irq); + info!(" + AHCI {}", pci_config.func.display()); let address = unsafe { bar.physmap_mem("ahcid") }; { diff --git a/alxd/src/device/mod.rs b/alxd/src/device/mod.rs index 04da35d59e..e3d8ff4996 100644 --- a/alxd/src/device/mod.rs +++ b/alxd/src/device/mod.rs @@ -1705,7 +1705,7 @@ impl Alx { } let mac = self.get_perm_macaddr(); - print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); + println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); let _ = setcfg("mac", &format!("{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}-{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); if ! self.get_phy_info() { diff --git a/alxd/src/main.rs b/alxd/src/main.rs index d52371f94a..9bd0d6edb3 100644 --- a/alxd/src/main.rs +++ b/alxd/src/main.rs @@ -32,7 +32,7 @@ fn main() { let irq_str = args.next().expect("alxd: no irq provided"); let irq = irq_str.parse::().expect("alxd: failed to parse irq"); - print!("{}", format!(" + ALX {} on: {:X}, IRQ: {}\n", name, bar, irq)); + println!(" + ALX {} on: {:X}, IRQ: {}\n", name, bar, irq); // Daemonize redox_daemon::Daemon::new(move |daemon| { diff --git a/bgad/src/main.rs b/bgad/src/main.rs index e9b7bb7600..18ac70df34 100644 --- a/bgad/src/main.rs +++ b/bgad/src/main.rs @@ -25,7 +25,7 @@ fn main() { let mut name = pci_config.func.name(); name.push_str("_bga"); - println!(" + BGA {}", name); + println!(" + BGA {}", pci_config.func.display()); redox_daemon::Daemon::new(move |daemon| { unsafe { iopl(3).unwrap() }; diff --git a/e1000d/src/main.rs b/e1000d/src/main.rs index d77c3f82f0..1746883701 100644 --- a/e1000d/src/main.rs +++ b/e1000d/src/main.rs @@ -69,11 +69,10 @@ fn main() { name.push_str("_e1000"); let bar = &pci_config.func.bars[0]; - let (bar_ptr, bar_size) = bar.expect_mem(); let irq = pci_config.func.legacy_interrupt_line.expect("e1000d: no legacy interrupts supported"); - eprintln!(" + E1000 {} on: {:X} size: {} IRQ: {}", name, bar_ptr, bar_size, irq); + eprintln!(" + E1000 {}", pci_config.func.display()); redox_daemon::Daemon::new(move |daemon| { let socket_fd = syscall::open( diff --git a/ihdad/src/main.rs b/ihdad/src/main.rs index f603197608..7f87807b40 100755 --- a/ihdad/src/main.rs +++ b/ihdad/src/main.rs @@ -156,9 +156,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { name.push_str("_ihda"); let bar = &pci_config.func.bars[0]; - let (bar_ptr, bar_size) = bar.expect_mem(); - log::info!(" + IHDA {} on: {:#X} size: {}", name, bar_ptr, bar_size); + log::info!(" + IHDA {}", pci_config.func.display()); let address = unsafe { bar.physmap_mem("ihdad") } as usize; diff --git a/ixgbed/src/main.rs b/ixgbed/src/main.rs index a9a65cd248..a5ec7bfa7f 100644 --- a/ixgbed/src/main.rs +++ b/ixgbed/src/main.rs @@ -80,7 +80,7 @@ fn main() { let irq = pci_config.func.legacy_interrupt_line.expect("ixgbed: no legacy interrupts supported"); - println!(" + IXGBE {} on: {:X} IRQ: {}", name, bar, irq); + println!(" + IXGBE {}", pci_config.func.display()); redox_daemon::Daemon::new(move |daemon| { let socket_fd = syscall::open( diff --git a/pcid/src/driver_interface/mod.rs b/pcid/src/driver_interface/mod.rs index 1678ef7594..88b7068915 100644 --- a/pcid/src/driver_interface/mod.rs +++ b/pcid/src/driver_interface/mod.rs @@ -73,6 +73,24 @@ impl PciFunction { // FIXME stop replacing : with - once it is a valid character in scheme names format!("pci-{}", self.addr).replace(':', "-") } + + pub fn display(&self) -> String { + let mut string = self.name(); + let mut first = true; + for (i, bar) in self.bars.iter().enumerate() { + if !bar.is_none() { + if first { + first = false; + string.push_str(" on:"); + } + string.push_str(&format!(" {i}={}", bar.display())); + } + } + if let Some(irq) = self.legacy_interrupt_line { + string.push_str(&format!(" IRQ: {irq}")); + } + string + } } #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/pcid/src/main.rs b/pcid/src/main.rs index 6591e385e6..bbc46d0794 100644 --- a/pcid/src/main.rs +++ b/pcid/src/main.rs @@ -245,11 +245,8 @@ fn handle_parsed_header(state: Arc, config: &Config, addr: PciAddress, he let mut string = String::new(); let bars = header.bars(&state.pcie); for (i, bar) in bars.iter().enumerate() { - match bar { - PciBar::None => {}, - PciBar::Memory32 { addr, .. } => string.push_str(&format!(" {i}={addr:08X}")), - PciBar::Memory64 { addr, .. } => string.push_str(&format!(" {i}={addr:016X}")), - PciBar::Port(port) => string.push_str(&format!(" {i}=P{port:04X}")), + if !bar.is_none() { + string.push_str(&format!(" {i}={}", bar.display())); } } diff --git a/pcid/src/pci/bar.rs b/pcid/src/pci/bar.rs index fa497d755b..b9e8008f51 100644 --- a/pcid/src/pci/bar.rs +++ b/pcid/src/pci/bar.rs @@ -11,6 +11,15 @@ pub enum PciBar { } impl PciBar { + pub fn display(&self) -> String { + match self { + PciBar::None => format!(""), + PciBar::Memory32 { addr, .. } => format!("{addr:08X}"), + PciBar::Memory64 { addr, .. } => format!("{addr:016X}"), + PciBar::Port(port) => format!("P{port:04X}"), + } + } + pub fn is_none(&self) -> bool { match self { &PciBar::None => true, diff --git a/rtl8139d/src/main.rs b/rtl8139d/src/main.rs index 771683010a..e0bfbf2648 100644 --- a/rtl8139d/src/main.rs +++ b/rtl8139d/src/main.rs @@ -316,7 +316,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { name.push_str("_rtl8139"); let (bar_ptr, bar_size) = find_bar(&pci_config).expect("rtl8139d: failed to find BAR"); - log::info!(" + RTL8139 {} on: {:#X} size: {}", name, bar_ptr, bar_size); + log::info!(" + RTL8139 {}", pci_config.func.display()); let address = unsafe { common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index c38b506d21..d157ab8706 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -314,7 +314,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { name.push_str("_rtl8168"); let (bar_ptr, bar_size) = find_bar(&pci_config).expect("rtl8168d: failed to find BAR"); - log::info!(" + RTL8168 {} on: {:#X} size: {}", name, bar_ptr, bar_size); + log::info!(" + RTL8168 {}", pci_config.func.display()); let address = unsafe { common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) diff --git a/sb16d/src/main.rs b/sb16d/src/main.rs index 5415e2fcb6..6671ac9b39 100644 --- a/sb16d/src/main.rs +++ b/sb16d/src/main.rs @@ -68,7 +68,7 @@ fn main() { let addr_str = args.next().unwrap_or("220".to_string()); let addr = u16::from_str_radix(&addr_str, 16).expect("sb16: failed to parse address"); - print!("{}", format!(" + sb16 at 0x{:X}\n", addr)); + println!(" + sb16 at 0x{:X}\n", addr); // Daemonize redox_daemon::Daemon::new(move |daemon| { diff --git a/vboxd/src/main.rs b/vboxd/src/main.rs index 17a8c23a2d..7555482450 100644 --- a/vboxd/src/main.rs +++ b/vboxd/src/main.rs @@ -197,11 +197,10 @@ fn main() { let bar0 = pci_config.func.bars[0].expect_port(); let bar1 = &pci_config.func.bars[1]; - let (bar1_ptr, _) = bar1.expect_mem(); let irq = pci_config.func.legacy_interrupt_line.expect("vboxd: no legacy interrupts supported"); - print!("{}", format!(" + VirtualBox {} on: {:X}, {:X}, IRQ {}\n", name, bar0, bar1_ptr, irq)); + println!(" + VirtualBox {}", pci_config.func.display()); // Daemonize redox_daemon::Daemon::new(move |daemon| { diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index 9f95131be7..c6dd1565a5 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -233,16 +233,12 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::debug!("XHCI PCI CONFIG: {:?}", pci_config); let bar = &pci_config.func.bars[0]; - let (bar_ptr, _) = bar.expect_mem(); let address = unsafe { bar.physmap_mem("xhcid") } as usize; - let (mut irq_file, interrupt_method) = get_int_method(&mut pcid_handle, address); + let (irq_file, interrupt_method) = get_int_method(&mut pcid_handle, address); - print!( - "{}", - format!(" + XHCI {} on: {:016X}\n", name, bar_ptr) - ); + println!(" + XHCI {}", pci_config.func.display()); let scheme_name = format!("usb.{}", name); let socket_fd = syscall::open(