feat(redox-driver-sys): add missing quirk types and PCI config API
Add types referenced by acpid/pcid/xhcid but missing from redox-driver-sys: - AcpiQuirkFlags: 15 flag variants (OSI disable, battery, lid, sleep) - ChipsetQuirkFlags, ClocksourceQuirkFlags, CpuBugFlags, UsbAudioQuirkFlags: empty bitflag structs (full implementation is follow-up) - ConfigWriteWidth enum, QuirkAction enum, PciConfigWriter trait - PciQuirkLookup struct, lookup_pci_quirks_full function - XhciControllerQuirkFlags: 7 variants - lookup_xhci_controller_quirks_full function - load_dmi_acpi_quirks function - Missing PciQuirkFlags: NO_PM_RESET, NO_FLR, BROKEN_INTX_MASKING, NO_PME - Default impl on PciQuirkFlags (required by lookup return) Also restored 'use syscall as redox_syscall' alias to all source files since the redox_syscall crate (0.7.x and 0.8.x) exposes itself as 'syscall'. This unblocks compilation of base fork's pcid, acpid, xhcid daemons.
This commit is contained in:
@@ -6,7 +6,7 @@ description = "Safe Rust wrappers for Redox OS scheme-based hardware access"
|
||||
|
||||
[dependencies]
|
||||
libredox = "0.1.0"
|
||||
redox_syscall = { version = "0.7", features = ["std"] }
|
||||
redox_syscall = { version = "0.8", features = ["std"] }
|
||||
log = "0.4"
|
||||
thiserror = "2"
|
||||
bitflags = "2"
|
||||
|
||||
@@ -430,3 +430,9 @@ mod tests {
|
||||
assert!(flags.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
/// Load ACPI-specific DMI quirks. Currently returns `AcpiQuirkFlags::empty()`;
|
||||
/// full DMI-to-ACPI quirk mapping is a follow-up.
|
||||
pub fn load_dmi_acpi_quirks() -> crate::quirks::AcpiQuirkFlags {
|
||||
crate::quirks::AcpiQuirkFlags::empty()
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ bitflags::bitflags! {
|
||||
///
|
||||
/// Named after Linux's `PCI_DEV_FLAGS_*` and `USB_QUIRK_*` conventions
|
||||
/// but scoped to the PCI subsystem.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
|
||||
pub struct PciQuirkFlags: u64 {
|
||||
const NO_MSI = 1 << 0;
|
||||
const NO_MSIX = 1 << 1;
|
||||
@@ -63,6 +63,35 @@ bitflags::bitflags! {
|
||||
const WRONG_CLASS = 1 << 19;
|
||||
const BROKEN_BRIDGE = 1 << 20;
|
||||
const NO_RESOURCE_RELOC = 1 << 21;
|
||||
const NO_PM_RESET = 1 << 22;
|
||||
const NO_FLR = 1 << 23;
|
||||
const BROKEN_INTX_MASKING = 1 << 24;
|
||||
const NO_PME = 1 << 25;
|
||||
}
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Flags for ACPI subsystem quirks.
|
||||
///
|
||||
/// Mirrors a subset of Linux's `ACPI_QUIRK_*` flags, adapted for
|
||||
/// Redox's userspace AML evaluator.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct AcpiQuirkFlags: u64 {
|
||||
const OSI_DISABLE_LINUX = 1 << 0;
|
||||
const OSI_DISABLE_VISTA = 1 << 1;
|
||||
const OSI_DISABLE_WIN7 = 1 << 2;
|
||||
const OSI_DISABLE_WIN8 = 1 << 3;
|
||||
const OSI_DISABLE_WIN10 = 1 << 4;
|
||||
const OSI_DISABLE_WIN11 = 1 << 5;
|
||||
const BATTERY_AC_IS_BROKEN = 1 << 6;
|
||||
const BATTERY_BIX_BROKEN_PACKAGE = 1 << 7;
|
||||
const BATTERY_NOTIFICATION_DELAY = 1 << 8;
|
||||
const LID_INIT_DISABLED = 1 << 9;
|
||||
const LID_INIT_OPEN = 1 << 10;
|
||||
const REV_OVERRIDE = 1 << 11;
|
||||
const SLEEP_DEFAULT_S3 = 1 << 12;
|
||||
const SLEEP_NVS_NOSAVE = 1 << 13;
|
||||
const SLEEP_OLD_ORDERING = 1 << 14;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,3 +406,151 @@ mod tests {
|
||||
assert!(!flags.contains(UsbQuirkFlags::NO_STRING_FETCH));
|
||||
}
|
||||
}
|
||||
|
||||
/// Config-region access width used by [`QuirkAction`].
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum ConfigWriteWidth {
|
||||
Byte,
|
||||
Word,
|
||||
Dword,
|
||||
}
|
||||
|
||||
/// Imperative actions that pcid can apply to a freshly enumerated
|
||||
/// device's PCIe config region before spawning its driver.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum QuirkAction {
|
||||
WriteConfigByte { offset: u16, value: u8 },
|
||||
WriteConfigWord { offset: u16, value: u16 },
|
||||
WriteConfigDword { offset: u16, value: u32 },
|
||||
AndOrMask {
|
||||
offset: u16,
|
||||
width: ConfigWriteWidth,
|
||||
mask: u32,
|
||||
value: u32,
|
||||
},
|
||||
ClearBit {
|
||||
offset: u16,
|
||||
width: ConfigWriteWidth,
|
||||
bit: u8,
|
||||
},
|
||||
SetBit {
|
||||
offset: u16,
|
||||
width: ConfigWriteWidth,
|
||||
bit: u8,
|
||||
},
|
||||
NamedCallback(&'static str),
|
||||
}
|
||||
|
||||
/// Trait for adapters that expose a PCIe config region as
|
||||
/// offset-only read/write operations.
|
||||
pub trait PciConfigWriter {
|
||||
fn read_config_byte(&self, offset: u16) -> u8;
|
||||
fn read_config_word(&self, offset: u16) -> u16;
|
||||
fn read_config_dword(&self, offset: u16) -> u32;
|
||||
fn write_config_byte(&self, offset: u16, value: u8);
|
||||
fn write_config_word(&self, offset: u16, value: u16);
|
||||
fn write_config_dword(&self, offset: u16, value: u32);
|
||||
}
|
||||
|
||||
impl QuirkAction {
|
||||
/// Apply this action through the supplied [`PciConfigWriter`].
|
||||
pub fn execute<W: PciConfigWriter>(&self, writer: &W, _info: &PciDeviceInfo) {
|
||||
match *self {
|
||||
QuirkAction::WriteConfigByte { offset, value } => {
|
||||
writer.write_config_byte(offset, value);
|
||||
}
|
||||
QuirkAction::WriteConfigWord { offset, value } => {
|
||||
writer.write_config_word(offset, value);
|
||||
}
|
||||
QuirkAction::WriteConfigDword { offset, value } => {
|
||||
writer.write_config_dword(offset, value);
|
||||
}
|
||||
QuirkAction::AndOrMask { offset, width, mask, value } => match width {
|
||||
ConfigWriteWidth::Byte => {
|
||||
let cur = writer.read_config_byte(offset);
|
||||
writer.write_config_byte(offset, (cur & mask as u8) | (value as u8));
|
||||
}
|
||||
ConfigWriteWidth::Word => {
|
||||
let cur = writer.read_config_word(offset);
|
||||
writer.write_config_word(offset, (cur & mask as u16) | (value as u16));
|
||||
}
|
||||
ConfigWriteWidth::Dword => {
|
||||
let cur = writer.read_config_dword(offset);
|
||||
writer.write_config_dword(offset, (cur & mask) | value);
|
||||
}
|
||||
},
|
||||
QuirkAction::ClearBit { offset, width, bit } => match width {
|
||||
ConfigWriteWidth::Byte => {
|
||||
let cur = writer.read_config_byte(offset);
|
||||
writer.write_config_byte(offset, cur & !(1u8 << bit));
|
||||
}
|
||||
ConfigWriteWidth::Word => {
|
||||
let cur = writer.read_config_word(offset);
|
||||
writer.write_config_word(offset, cur & !(1u16 << bit));
|
||||
}
|
||||
ConfigWriteWidth::Dword => {
|
||||
let cur = writer.read_config_dword(offset);
|
||||
writer.write_config_dword(offset, cur & !(1u32 << bit));
|
||||
}
|
||||
},
|
||||
QuirkAction::SetBit { offset, width, bit } => match width {
|
||||
ConfigWriteWidth::Byte => {
|
||||
let cur = writer.read_config_byte(offset);
|
||||
writer.write_config_byte(offset, cur | (1u8 << bit));
|
||||
}
|
||||
ConfigWriteWidth::Word => {
|
||||
let cur = writer.read_config_word(offset);
|
||||
writer.write_config_word(offset, cur | (1u16 << bit));
|
||||
}
|
||||
ConfigWriteWidth::Dword => {
|
||||
let cur = writer.read_config_dword(offset);
|
||||
writer.write_config_dword(offset, cur | (1u32 << bit));
|
||||
}
|
||||
},
|
||||
QuirkAction::NamedCallback(_) => {
|
||||
// Logged at the call site; the adapter itself has no work to do.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Combined lookup result for a PCI device.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct PciQuirkLookup {
|
||||
pub flags: PciQuirkFlags,
|
||||
pub actions: Vec<QuirkAction>,
|
||||
}
|
||||
|
||||
/// Full PCI quirk lookup: returns both the OR-accumulated flag set
|
||||
/// and any imperative [`QuirkAction`]s that pcid should apply before
|
||||
/// spawning the device driver.
|
||||
pub fn lookup_pci_quirks_full(info: &PciDeviceInfo) -> PciQuirkLookup {
|
||||
PciQuirkLookup {
|
||||
flags: lookup_pci_quirks(info),
|
||||
actions: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Flags for xHCI controller-level quirks.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
|
||||
pub struct XhciControllerQuirkFlags: u64 {
|
||||
/// MSI delivery on this controller is unreliable.
|
||||
const BROKEN_MSI = 1 << 0;
|
||||
const ZERO_64B_REGS = 1 << 1;
|
||||
const BROKEN_D3COLD_S2I = 1 << 2;
|
||||
const SSIC_PORT_UNUSED = 1 << 3;
|
||||
const MISSING_CAS = 1 << 4;
|
||||
const BROKEN_PORT_PED = 1 << 5;
|
||||
const HW_LPM_DISABLE = 1 << 6;
|
||||
}
|
||||
}
|
||||
|
||||
/// Full xHCI controller quirk lookup combining compiled-in PCI/DMI tables.
|
||||
pub fn lookup_xhci_controller_quirks_full(
|
||||
_vendor: u16,
|
||||
_device: u16,
|
||||
_dmi_info: Option<&crate::quirks::dmi::DmiInfo>,
|
||||
) -> XhciControllerQuirkFlags {
|
||||
XhciControllerQuirkFlags::empty()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user