Add internal locking to the Xhci struct.

This commit is contained in:
4lDO2
2020-03-26 18:18:00 +01:00
parent cfc4d65d48
commit 443b160b6d
16 changed files with 1221 additions and 455 deletions
+22 -1
View File
@@ -10,21 +10,42 @@ use thiserror::Error;
pub use crate::pci::PciBar;
pub use crate::pci::msi;
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
#[repr(u8)]
pub enum LegacyInterruptPin {
/// INTa#
IntA = 1,
/// INTb#
IntB = 2,
/// INTc#
IntC = 3,
/// INTd#
IntD = 4,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct PciFunction {
/// Number of PCI bus
pub bus_num: u8,
/// Number of PCI device
pub dev_num: u8,
/// Number of PCI function
pub func_num: u8,
/// PCI Base Address Registers
pub bars: [PciBar; 6],
/// BAR sizes
pub bar_sizes: [u32; 6],
/// Legacy IRQ line
// TODO: Stop using legacy IRQ lines, and physical pins, but MSI/MSI-X instead.
pub legacy_interrupt_line: u8,
/// Legacy interrupt pin (INTx#), none if INTx# interrupts aren't supported at all.
pub legacy_interrupt_pin: Option<LegacyInterruptPin>,
/// Vendor ID
pub venid: u16,
/// Device ID
+22 -1
View File
@@ -75,7 +75,10 @@ impl DriverHandler {
None => return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)),
};
unsafe {
with_pci_func_raw(&self.state.pci, self.bus_num, self.dev_num, self.func_num, |func| capability.set_enabled(func, offset, true));
with_pci_func_raw(&self.state.pci, self.bus_num, self.dev_num, self.func_num, |func| {
capability.set_enabled(true);
capability.write_message_control(func, offset);
});
}
PcidClientResponse::FeatureEnabled(feature)
}
@@ -255,6 +258,8 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, bus_num: u8,
pci.write(bus_num, dev_num, func_num, 0x3C, data);
}
let interrupt_pin = unsafe { pci.read(bus_num, dev_num, func_num, 0x3B) };
// Find BAR sizes
let mut bars = [PciBar::None; 6];
let mut bar_sizes = [0; 6];
@@ -308,6 +313,21 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, bus_num: u8,
};
println!("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 => {
println!("pcid: invalid interrupt pin: {}", other);
None
}
};
let func = driver_interface::PciFunction {
bars,
bar_sizes,
@@ -316,6 +336,7 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, bus_num: u8,
func_num,
devid: header.device_id(),
legacy_interrupt_line: irq,
legacy_interrupt_pin,
venid: header.vendor_id(),
};
+11 -4
View File
@@ -68,11 +68,10 @@ impl MsiCapability {
pub fn message_control(&self) -> u16 {
(self.message_control_raw() >> 16) as u16
}
pub unsafe fn set_message_control<W: ConfigWriter>(&mut self, writer: &W, offset: u8, value: u16) {
pub fn set_message_control(&mut self, value: u16) {
let mut new_message_control = self.message_control_raw();
new_message_control &= 0x0000_FFFF;
new_message_control |= u32::from(value) << 16;
writer.write_u32(offset, new_message_control);
match self {
Self::_32BitAddress { ref mut message_control, .. }
@@ -81,6 +80,9 @@ impl MsiCapability {
| Self::_64BitAddressWithPvm { ref mut message_control, .. } => *message_control = new_message_control,
}
}
pub unsafe fn write_message_control<W: ConfigWriter>(&mut self, writer: &W, offset: u8) {
writer.write_u32(offset, self.message_control_raw());
}
pub fn is_pvt_capable(&self) -> bool {
self.message_control() & Self::MC_PVT_CAPABLE_BIT != 0
}
@@ -90,10 +92,10 @@ impl MsiCapability {
pub fn enabled(&self) -> bool {
self.message_control() & Self::MC_MSI_ENABLED_BIT != 0
}
pub unsafe fn set_enabled<W: ConfigWriter>(&mut self, writer: &W, offset: u8, enabled: bool) {
pub fn set_enabled(&mut self, enabled: bool) {
let mut new_message_control = self.message_control() & (!Self::MC_MSI_ENABLED_BIT);
new_message_control |= u16::from(enabled);
self.set_message_control(writer, offset, new_message_control)
self.set_message_control(new_message_control);
}
pub fn multi_message_capable(&self) -> u8 {
((self.message_control() & Self::MC_MULTI_MESSAGE_MASK) >> Self::MC_MULTI_MESSAGE_SHIFT) as u8
@@ -101,6 +103,11 @@ impl MsiCapability {
pub fn multi_message_enabled(&self) -> u8 {
((self.message_control() & Self::MC_MULTI_MESSAGE_ENABLE_MASK) >> Self::MC_MULTI_MESSAGE_ENABLE_SHIFT) as u8
}
pub fn set_multi_message_enabled(&mut self, log_mme: u8) {
let mut new_message_control = self.message_control() & (!Self::MC_MULTI_MESSAGE_ENABLE_MASK);
new_message_control |= (u16::from(log_mme) << Self::MC_MULTI_MESSAGE_ENABLE_SHIFT);
self.set_message_control(new_message_control);
}
}
impl MsixCapability {