Workarounds for x86 32-bit

This commit is contained in:
Jeremy Soller
2022-07-26 17:20:34 -06:00
parent da8ecef8a7
commit 00de428d6b
10 changed files with 82 additions and 50 deletions
+2 -2
View File
@@ -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,
+2 -2
View File
@@ -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) {
+1 -1
View File
@@ -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) {
+2 -2
View File
@@ -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
View File
@@ -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> {
+3 -3
View File
@@ -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
View File
@@ -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)
+1 -1
View File
@@ -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>, _>>()?;
+2 -2
View File
@@ -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");
+6 -6
View File
@@ -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(