Merge branch 'pci_interrupts_rework' into 'master'
Couple of interrupt handling cleanups and some other changes See merge request redox-os/drivers!137
This commit is contained in:
+3
-3
@@ -76,9 +76,9 @@ 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));
|
||||
println!(" + ac97 {}", pci_config.func.display());
|
||||
|
||||
// Daemonize
|
||||
redox_daemon::Daemon::new(move |daemon| {
|
||||
@@ -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");
|
||||
|
||||
+7
-16
@@ -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;
|
||||
|
||||
@@ -81,22 +82,15 @@ 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 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);
|
||||
|
||||
info!(" + AHCI {} on: {} size: {} IRQ: {}", name, bar, bar_size, irq);
|
||||
info!(" + AHCI {}", pci_config.func.display());
|
||||
|
||||
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(
|
||||
@@ -105,11 +99,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");
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ fn main() {
|
||||
let irq_str = args.next().expect("alxd: no irq provided");
|
||||
let irq = irq_str.parse::<u8>().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| {
|
||||
|
||||
+1
-1
@@ -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() };
|
||||
|
||||
+5
-12
@@ -68,11 +68,11 @@ 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 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);
|
||||
eprintln!(" + E1000 {}", pci_config.func.display());
|
||||
|
||||
redox_daemon::Daemon::new(move |daemon| {
|
||||
let socket_fd = syscall::open(
|
||||
@@ -84,16 +84,9 @@ 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)
|
||||
.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")
|
||||
|
||||
+13
-21
@@ -74,11 +74,9 @@ fn setup_logging() -> Option<&'static RedoxLogger> {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<File> {
|
||||
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<File> {
|
||||
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<File> {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,17 +155,14 @@ 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];
|
||||
|
||||
log::info!(" + IHDA {} on: {:#X} size: {}", name, bar_ptr, bar_size);
|
||||
log::info!(" + IHDA {}", pci_config.func.display());
|
||||
|
||||
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).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)
|
||||
|
||||
+3
-4
@@ -78,9 +78,9 @@ 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);
|
||||
println!(" + IXGBE {}", pci_config.func.display());
|
||||
|
||||
redox_daemon::Daemon::new(move |daemon| {
|
||||
let socket_fd = syscall::open(
|
||||
@@ -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)
|
||||
|
||||
+17
-24
@@ -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),
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,14 +210,12 @@ 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))
|
||||
.expect("nvmed: failed to open INTx# interrupt line");
|
||||
let irq_handle = irq.irq_handle("nvmed");
|
||||
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 +226,12 @@ 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))
|
||||
.expect("nvmed: failed to open INTx# interrupt line");
|
||||
let irq_handle = irq.irq_handle("nvmed");
|
||||
Ok((InterruptMethod::Intx, InterruptSources::Intx(irq_handle)))
|
||||
} else {
|
||||
// No interrupts at all
|
||||
todo!("handling of no interrupts")
|
||||
panic!("nvmed: no interrupts supported at all")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,28 +289,20 @@ 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);
|
||||
|
||||
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"),
|
||||
});
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "pcid"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "pcid"
|
||||
|
||||
@@ -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)]
|
||||
@@ -57,10 +62,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<LegacyInterruptPin>,
|
||||
/// If INTx# interrupts aren't supported at all this is `None`.
|
||||
pub legacy_interrupt_line: Option<LegacyInterruptLine>,
|
||||
|
||||
/// All identifying information of the PCI function.
|
||||
pub full_device_id: FullDeviceId,
|
||||
@@ -70,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)]
|
||||
|
||||
+18
-22
@@ -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};
|
||||
@@ -244,11 +245,8 @@ fn handle_parsed_header(state: Arc<State>, 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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,6 +278,16 @@ fn handle_parsed_header(state: Arc<State>, 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 +299,14 @@ fn handle_parsed_header(state: Arc<State>, 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(LegacyInterruptLine(irq))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
full_device_id: header.full_device_id().clone(),
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,15 @@ pub enum PciBar {
|
||||
}
|
||||
|
||||
impl PciBar {
|
||||
pub fn display(&self) -> String {
|
||||
match self {
|
||||
PciBar::None => format!("<none>"),
|
||||
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,
|
||||
@@ -41,4 +50,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}"))
|
||||
}
|
||||
}
|
||||
|
||||
+9
-51
@@ -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<W: ConfigWriter>(&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<W: ConfigWriter>(&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<W: ConfigWriter>(&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<W: ConfigWriter>(&self, writer: &W, offset: u8) {
|
||||
self.write_a(writer, offset);
|
||||
self.write_b(writer, offset);
|
||||
self.write_c(writer, offset);
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
|
||||
+15
-22
@@ -108,11 +108,9 @@ impl MsixInfo {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<File> {
|
||||
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<File> {
|
||||
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!(),
|
||||
@@ -171,12 +169,10 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<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);
|
||||
@@ -220,34 +216,31 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<File> {
|
||||
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"))
|
||||
irq.irq_handle("rtl8139d")
|
||||
} 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<File> {
|
||||
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"))
|
||||
irq.irq_handle("rtl8139d")
|
||||
} else {
|
||||
// no interrupts at all
|
||||
None
|
||||
panic!("rtl8139d: no interrupts supported at all")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,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)
|
||||
@@ -340,7 +333,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 {
|
||||
|
||||
+15
-22
@@ -106,11 +106,9 @@ impl MsixInfo {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<File> {
|
||||
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<File> {
|
||||
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!(),
|
||||
@@ -169,12 +167,10 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<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);
|
||||
@@ -218,34 +214,31 @@ fn get_int_method(pcid_handle: &mut PcidServerHandle) -> Option<File> {
|
||||
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"))
|
||||
irq.irq_handle("rtl8168d")
|
||||
} 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<File> {
|
||||
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"))
|
||||
irq.irq_handle("rtl8168d")
|
||||
} else {
|
||||
// no interrupts at all
|
||||
None
|
||||
panic!("rtl8168d: no interrupts supported at all")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,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)
|
||||
@@ -338,7 +331,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 {
|
||||
|
||||
+1
-1
@@ -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| {
|
||||
|
||||
+5
-5
@@ -196,11 +196,11 @@ 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 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));
|
||||
println!(" + VirtualBox {}", pci_config.func.display());
|
||||
|
||||
// Daemonize
|
||||
redox_daemon::Daemon::new(move |daemon| {
|
||||
@@ -221,10 +221,10 @@ 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::<u32>::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) };
|
||||
|
||||
|
||||
@@ -27,16 +27,10 @@ pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result<File, Error> {
|
||||
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.
|
||||
{
|
||||
|
||||
+8
-17
@@ -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,11 +193,11 @@ 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.
|
||||
(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)
|
||||
@@ -209,11 +208,10 @@ 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<File>, 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)
|
||||
(Some(irq.irq_handle("xhcid")), InterruptMethod::Intx)
|
||||
} else {
|
||||
// no interrupts at all
|
||||
(None, InterruptMethod::Polling)
|
||||
@@ -234,20 +232,13 @@ 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 irq = pci_config.func.legacy_interrupt_line;
|
||||
let bar = &pci_config.func.bars[0];
|
||||
|
||||
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);
|
||||
let (irq_file, interrupt_method) = get_int_method(&mut pcid_handle, address);
|
||||
|
||||
print!(
|
||||
"{}",
|
||||
format!(" + XHCI {} on: {:016X} IRQ: {}\n", name, bar_ptr, irq)
|
||||
);
|
||||
println!(" + XHCI {}", pci_config.func.display());
|
||||
|
||||
let scheme_name = format!("usb.{}", name);
|
||||
let socket_fd = syscall::open(
|
||||
|
||||
Reference in New Issue
Block a user