Workarounds for x86 32-bit
This commit is contained in:
@@ -364,7 +364,7 @@ impl Intel8254x {
|
||||
self.receive_ring[i].buffer = self.receive_buffer[i].physical() as u64;
|
||||
}
|
||||
|
||||
self.write_reg(RDBAH, (self.receive_ring.physical() >> 32) as u32);
|
||||
self.write_reg(RDBAH, ((self.receive_ring.physical() as u64) >> 32) as u32);
|
||||
self.write_reg(RDBAL, self.receive_ring.physical() as u32);
|
||||
self.write_reg(
|
||||
RDLEN,
|
||||
@@ -378,7 +378,7 @@ impl Intel8254x {
|
||||
self.transmit_ring[i].buffer = self.transmit_buffer[i].physical() as u64;
|
||||
}
|
||||
|
||||
self.write_reg(TDBAH, (self.transmit_ring.physical() >> 32) as u32);
|
||||
self.write_reg(TDBAH, ((self.transmit_ring.physical() as u64) >> 32) as u32);
|
||||
self.write_reg(TDBAL, self.transmit_ring.physical() as u32);
|
||||
self.write_reg(
|
||||
TDLEN,
|
||||
|
||||
@@ -130,7 +130,7 @@ impl Corb {
|
||||
|
||||
pub fn set_address(&mut self, addr: usize) {
|
||||
self.regs.corblbase.write((addr & 0xFFFFFFFF) as u32);
|
||||
self.regs.corbubase.write((addr >> 32) as u32);
|
||||
self.regs.corbubase.write(((addr as u64) >> 32) as u32);
|
||||
}
|
||||
|
||||
pub fn reset_read_pointer(&mut self) {
|
||||
@@ -268,7 +268,7 @@ impl Rirb {
|
||||
|
||||
pub fn set_address(&mut self, addr: usize) {
|
||||
self.regs.rirblbase.write((addr & 0xFFFFFFFF) as u32);
|
||||
self.regs.rirbubase.write((addr >> 32) as u32);
|
||||
self.regs.rirbubase.write(((addr as u64) >> 32) as u32);
|
||||
}
|
||||
|
||||
pub fn reset_write_pointer(&mut self) {
|
||||
|
||||
@@ -156,7 +156,7 @@ impl StreamDescriptorRegs {
|
||||
|
||||
pub fn set_address(&mut self, addr: usize) {
|
||||
self.buff_desc_list_lo.write( (addr & 0xFFFFFFFF) as u32);
|
||||
self.buff_desc_list_hi.write( ( (addr >> 32) & 0xFFFFFFFF) as u32);
|
||||
self.buff_desc_list_hi.write( ( ((addr as u64) >> 32) & 0xFFFFFFFF) as u32);
|
||||
}
|
||||
|
||||
pub fn set_last_valid_index(&mut self, index:u16) {
|
||||
|
||||
@@ -420,7 +420,7 @@ impl Intel8259x {
|
||||
|
||||
self.write_reg(IXGBE_RDBAL(i), self.receive_ring.physical() as u32);
|
||||
|
||||
self.write_reg(IXGBE_RDBAH(i), (self.receive_ring.physical() >> 32) as u32);
|
||||
self.write_reg(IXGBE_RDBAH(i), ((self.receive_ring.physical() as u64) >> 32) as u32);
|
||||
self.write_reg(
|
||||
IXGBE_RDLEN(i),
|
||||
(self.receive_ring.len() * mem::size_of::<ixgbe_adv_rx_desc>()) as u32,
|
||||
@@ -462,7 +462,7 @@ impl Intel8259x {
|
||||
// section 7.1.9 - setup descriptor ring
|
||||
|
||||
self.write_reg(IXGBE_TDBAL(i), self.transmit_ring.physical() as u32);
|
||||
self.write_reg(IXGBE_TDBAH(i), (self.transmit_ring.physical() >> 32) as u32);
|
||||
self.write_reg(IXGBE_TDBAH(i), ((self.transmit_ring.physical() as u64) >> 32) as u32);
|
||||
self.write_reg(
|
||||
IXGBE_TDLEN(i),
|
||||
(self.transmit_ring.len() * mem::size_of::<ixgbe_adv_tx_desc>()) as u32,
|
||||
|
||||
+10
-1
@@ -217,13 +217,22 @@ fn get_int_method(
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: MSI on non-x86_64?
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
fn get_int_method(
|
||||
pcid_handle: &mut PcidServerHandle,
|
||||
function: &PciFunction,
|
||||
allocated_bars: &AllocatedBars,
|
||||
) -> Result<(InterruptMethod, InterruptSources)> {
|
||||
todo!("handling of interrupts on non-x86_64")
|
||||
if function.legacy_interrupt_pin.is_some() {
|
||||
// INTx# pin based interrupts.
|
||||
let irq_handle = File::open(format!("irq:{}", function.legacy_interrupt_line))
|
||||
.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")
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_logging() -> Option<&'static RedoxLogger> {
|
||||
|
||||
@@ -333,15 +333,15 @@ impl Rtl8168 {
|
||||
|
||||
// Set tx low priority buffer address
|
||||
self.regs.tnpds[0].write(self.transmit_ring.physical() as u32);
|
||||
self.regs.tnpds[1].write((self.transmit_ring.physical() >> 32) as u32);
|
||||
self.regs.tnpds[1].write(((self.transmit_ring.physical() as u64) >> 32) as u32);
|
||||
|
||||
// Set tx high priority buffer address
|
||||
self.regs.thpds[0].write(self.transmit_ring_h.physical() as u32);
|
||||
self.regs.thpds[1].write((self.transmit_ring_h.physical() >> 32) as u32);
|
||||
self.regs.thpds[1].write(((self.transmit_ring_h.physical() as u64) >> 32) as u32);
|
||||
|
||||
// Set rx buffer address
|
||||
self.regs.rdsar[0].write(self.receive_ring.physical() as u32);
|
||||
self.regs.rdsar[1].write((self.receive_ring.physical() >> 32) as u32);
|
||||
self.regs.rdsar[1].write(((self.receive_ring.physical() as u64) >> 32) as u32);
|
||||
|
||||
// Disable timer interrupt
|
||||
self.regs.timer_int.write(0);
|
||||
|
||||
+53
-30
@@ -82,38 +82,11 @@ fn setup_logging() -> Option<&'static RedoxLogger> {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Daemonize
|
||||
if unsafe { syscall::clone(CloneFlags::empty()).unwrap() } != 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let _logger_ref = setup_logging();
|
||||
|
||||
let mut pcid_handle = PcidServerHandle::connect_default().expect("xhcid: failed to setup channel to pcid");
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn get_int_method(pcid_handle: &mut PcidServerHandle) -> (Option<File>, InterruptMethod) {
|
||||
let pci_config = pcid_handle.fetch_config().expect("xhcid: failed to fetch config");
|
||||
info!("XHCI PCI CONFIG: {:?}", pci_config);
|
||||
|
||||
let bar = pci_config.func.bars[0];
|
||||
let bar_size = pci_config.func.bar_sizes[0];
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
let mut name = pci_config.func.name();
|
||||
name.push_str("_xhci");
|
||||
|
||||
let bar_ptr = match bar {
|
||||
pcid_interface::PciBar::Memory(ptr) => match ptr {
|
||||
0 => panic!("BAR 0 is mapped to address 0"),
|
||||
_ => ptr,
|
||||
},
|
||||
other => panic!("Expected memory bar, found {}", other),
|
||||
};
|
||||
|
||||
let address = unsafe {
|
||||
syscall::physmap(bar_ptr as usize, bar_size as usize, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
.expect("xhcid: failed to map address")
|
||||
};
|
||||
|
||||
let all_pci_features = pcid_handle.fetch_all_features().expect("xhcid: failed to fetch pci features");
|
||||
info!("XHCI PCI FEATURES: {:?}", all_pci_features);
|
||||
|
||||
@@ -127,7 +100,7 @@ fn main() {
|
||||
msix_enabled = true;
|
||||
}
|
||||
|
||||
let (mut irq_file, interrupt_method) = if msi_enabled && !msix_enabled {
|
||||
if msi_enabled && !msix_enabled {
|
||||
use pcid_interface::msi::x86_64::{DeliveryMode, self as x86_64_msix};
|
||||
|
||||
let mut capability = match pcid_handle.feature_info(PciFeature::MsiX).expect("xhcid: failed to retrieve the MSI capability structure from pcid") {
|
||||
@@ -226,8 +199,58 @@ fn main() {
|
||||
} else {
|
||||
// no interrupts at all
|
||||
(None, InterruptMethod::Polling)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: MSI on non-x86_64?
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
fn get_int_method(pcid_handle: &mut PcidServerHandle) -> (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() {
|
||||
// legacy INTx# interrupt pins.
|
||||
(Some(File::open(format!("irq:{}", irq)).expect("xhcid: failed to open legacy IRQ file")), InterruptMethod::Intx)
|
||||
} else {
|
||||
// no interrupts at all
|
||||
(None, InterruptMethod::Polling)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Daemonize
|
||||
if unsafe { syscall::clone(CloneFlags::empty()).unwrap() } != 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let _logger_ref = setup_logging();
|
||||
|
||||
let mut pcid_handle = PcidServerHandle::connect_default().expect("xhcid: failed to setup channel to pcid");
|
||||
let pci_config = pcid_handle.fetch_config().expect("xhcid: failed to fetch config");
|
||||
info!("XHCI PCI CONFIG: {:?}", pci_config);
|
||||
|
||||
let bar = pci_config.func.bars[0];
|
||||
let bar_size = pci_config.func.bar_sizes[0];
|
||||
let irq = pci_config.func.legacy_interrupt_line;
|
||||
|
||||
let mut name = pci_config.func.name();
|
||||
name.push_str("_xhci");
|
||||
|
||||
let bar_ptr = match bar {
|
||||
pcid_interface::PciBar::Memory(ptr) => match ptr {
|
||||
0 => panic!("BAR 0 is mapped to address 0"),
|
||||
_ => ptr,
|
||||
},
|
||||
other => panic!("Expected memory bar, found {}", other),
|
||||
};
|
||||
|
||||
let address = unsafe {
|
||||
syscall::physmap(bar_ptr as usize, bar_size as usize, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
.expect("xhcid: failed to map address")
|
||||
};
|
||||
|
||||
let (mut irq_file, interrupt_method) = get_int_method(&mut pcid_handle);
|
||||
|
||||
print!(
|
||||
"{}",
|
||||
format!(" + XHCI {} on: {} IRQ: {}\n", name, bar, irq)
|
||||
|
||||
@@ -182,7 +182,7 @@ impl ScratchpadBufferArray {
|
||||
|
||||
let pages = entries.iter_mut().map(|entry: &mut ScratchpadBufferEntry| -> Result<usize> {
|
||||
let pointer = unsafe { syscall::physalloc(page_size)? };
|
||||
assert_eq!(pointer & 0xFFFF_FFFF_FFFF_F000, pointer, "physically allocated pointer (physalloc) wasn't 4k page-aligned");
|
||||
assert_eq!((pointer as u64) & 0xFFFF_FFFF_FFFF_F000, pointer as u64, "physically allocated pointer (physalloc) wasn't 4k page-aligned");
|
||||
entry.set_addr(pointer as u64);
|
||||
Ok(pointer)
|
||||
}).collect::<Result<Vec<usize>, _>>()?;
|
||||
|
||||
@@ -66,8 +66,8 @@ impl Ring {
|
||||
/// # Panics
|
||||
/// Panics if paddr is not a multiple of 16 bytes, i.e. the size of a TRB.
|
||||
pub fn phys_addr_to_index(&self, ac64: bool, paddr: u64) -> Option<usize> {
|
||||
let base = self.trbs.physical() & if ac64 { 0xFFFF_FFFF_FFFF_FFFF } else { 0xFFFF_FFFF };
|
||||
let offset = paddr.checked_sub(base as u64)? as usize;
|
||||
let base = (self.trbs.physical() as u64) & if ac64 { 0xFFFF_FFFF_FFFF_FFFF } else { 0xFFFF_FFFF };
|
||||
let offset = paddr.checked_sub(base)? as usize;
|
||||
|
||||
assert_eq!(offset % mem::size_of::<Trb>(), 0, "unaligned TRB physical address");
|
||||
|
||||
|
||||
@@ -245,8 +245,8 @@ impl Trb {
|
||||
|
||||
pub fn address_device(&mut self, slot_id: u8, input_ctx_ptr: usize, bsr: bool, cycle: bool) {
|
||||
assert_eq!(
|
||||
input_ctx_ptr & 0xFFFF_FFFF_FFFF_FFF0,
|
||||
input_ctx_ptr,
|
||||
(input_ctx_ptr as u64) & 0xFFFF_FFFF_FFFF_FFF0,
|
||||
input_ctx_ptr as u64,
|
||||
"unaligned input context ptr"
|
||||
);
|
||||
self.set(
|
||||
@@ -261,8 +261,8 @@ impl Trb {
|
||||
// Synchronizes the input context endpoints with the device context endpoints, I think.
|
||||
pub fn configure_endpoint(&mut self, slot_id: u8, input_ctx_ptr: usize, cycle: bool) {
|
||||
assert_eq!(
|
||||
input_ctx_ptr & 0xFFFF_FFFF_FFFF_FFF0,
|
||||
input_ctx_ptr,
|
||||
(input_ctx_ptr as u64) & 0xFFFF_FFFF_FFFF_FFF0,
|
||||
input_ctx_ptr as u64,
|
||||
"unaligned input context ptr"
|
||||
);
|
||||
|
||||
@@ -276,8 +276,8 @@ impl Trb {
|
||||
}
|
||||
pub fn evaluate_context(&mut self, slot_id: u8, input_ctx_ptr: usize, bsr: bool, cycle: bool) {
|
||||
assert_eq!(
|
||||
input_ctx_ptr & 0xFFFF_FFFF_FFFF_FFF0,
|
||||
input_ctx_ptr,
|
||||
(input_ctx_ptr as u64) & 0xFFFF_FFFF_FFFF_FFF0,
|
||||
input_ctx_ptr as u64,
|
||||
"unaligned input context ptr"
|
||||
);
|
||||
self.set(
|
||||
|
||||
Reference in New Issue
Block a user