mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 19:33:23 +00:00
Implement VmIoOnce
for IoMem
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
aa62f0a4e6
commit
c8ba695c85
@ -79,7 +79,7 @@ impl VirtioMmioTransport {
|
||||
};
|
||||
if device.common_device.version() == VirtioMmioVersion::Legacy {
|
||||
field_ptr!(&device.layout, VirtioMmioLayout, legacy_guest_page_size)
|
||||
.write(&(PAGE_SIZE as u32))
|
||||
.write_once(&(PAGE_SIZE as u32))
|
||||
.unwrap();
|
||||
}
|
||||
device
|
||||
@ -100,11 +100,11 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
device_ptr: &SafePtr<UsedRing, DmaCoherent>,
|
||||
) -> Result<(), VirtioTransportError> {
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_sel)
|
||||
.write(&(idx as u32))
|
||||
.write_once(&(idx as u32))
|
||||
.unwrap();
|
||||
|
||||
let queue_num_max: u32 = field_ptr!(&self.layout, VirtioMmioLayout, queue_num_max)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap();
|
||||
|
||||
if queue_size as u32 > queue_num_max {
|
||||
@ -117,7 +117,7 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
let device_paddr = device_ptr.paddr();
|
||||
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_num)
|
||||
.write(&(queue_size as u32))
|
||||
.write_once(&(queue_size as u32))
|
||||
.unwrap();
|
||||
|
||||
match self.common_device.version() {
|
||||
@ -131,39 +131,39 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
assert_eq!(descriptor_paddr % PAGE_SIZE, 0);
|
||||
let pfn = (descriptor_paddr / PAGE_SIZE) as u32;
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, legacy_queue_align)
|
||||
.write(&(PAGE_SIZE as u32))
|
||||
.write_once(&(PAGE_SIZE as u32))
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, legacy_queue_pfn)
|
||||
.write(&pfn)
|
||||
.write_once(&pfn)
|
||||
.unwrap();
|
||||
}
|
||||
VirtioMmioVersion::Modern => {
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_desc_low)
|
||||
.write(&(descriptor_paddr as u32))
|
||||
.write_once(&(descriptor_paddr as u32))
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_desc_high)
|
||||
.write(&((descriptor_paddr >> 32) as u32))
|
||||
.write_once(&((descriptor_paddr >> 32) as u32))
|
||||
.unwrap();
|
||||
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_driver_low)
|
||||
.write(&(driver_paddr as u32))
|
||||
.write_once(&(driver_paddr as u32))
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_driver_high)
|
||||
.write(&((driver_paddr >> 32) as u32))
|
||||
.write_once(&((driver_paddr >> 32) as u32))
|
||||
.unwrap();
|
||||
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_device_low)
|
||||
.write(&(device_paddr as u32))
|
||||
.write_once(&(device_paddr as u32))
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_device_high)
|
||||
.write(&((device_paddr >> 32) as u32))
|
||||
.write_once(&((device_paddr >> 32) as u32))
|
||||
.unwrap();
|
||||
// enable queue
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_sel)
|
||||
.write(&(idx as u32))
|
||||
.write_once(&(idx as u32))
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_ready)
|
||||
.write(&1u32)
|
||||
.write_once(&1u32)
|
||||
.unwrap();
|
||||
}
|
||||
};
|
||||
@ -182,10 +182,10 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
const MAX_QUEUES: u32 = 512;
|
||||
while num_queues < MAX_QUEUES {
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_sel)
|
||||
.write(&num_queues)
|
||||
.write_once(&num_queues)
|
||||
.unwrap();
|
||||
if field_ptr!(&self.layout, VirtioMmioLayout, queue_num_max)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap()
|
||||
== 0u32
|
||||
{
|
||||
@ -207,17 +207,17 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
fn device_features(&self) -> u64 {
|
||||
// select low
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, device_features_select)
|
||||
.write(&0u32)
|
||||
.write_once(&0u32)
|
||||
.unwrap();
|
||||
let device_feature_low = field_ptr!(&self.layout, VirtioMmioLayout, device_features)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap();
|
||||
// select high
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, device_features_select)
|
||||
.write(&1u32)
|
||||
.write_once(&1u32)
|
||||
.unwrap();
|
||||
let device_feature_high = field_ptr!(&self.layout, VirtioMmioLayout, device_features)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap() as u64;
|
||||
device_feature_high << 32 | device_feature_low as u64
|
||||
}
|
||||
@ -226,16 +226,16 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
let low = features as u32;
|
||||
let high = (features >> 32) as u32;
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, driver_features_select)
|
||||
.write(&0u32)
|
||||
.write_once(&0u32)
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, driver_features)
|
||||
.write(&low)
|
||||
.write_once(&low)
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, driver_features_select)
|
||||
.write(&1u32)
|
||||
.write_once(&1u32)
|
||||
.unwrap();
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, driver_features)
|
||||
.write(&high)
|
||||
.write_once(&high)
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
@ -243,7 +243,7 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
fn device_status(&self) -> DeviceStatus {
|
||||
DeviceStatus::from_bits(
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, status)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap() as u8,
|
||||
)
|
||||
.unwrap()
|
||||
@ -251,7 +251,7 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
|
||||
fn set_device_status(&mut self, status: DeviceStatus) -> Result<(), VirtioTransportError> {
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, status)
|
||||
.write(&(status.bits() as u32))
|
||||
.write_once(&(status.bits() as u32))
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
@ -262,10 +262,10 @@ impl VirtioTransport for VirtioMmioTransport {
|
||||
|
||||
fn max_queue_size(&self, idx: u16) -> Result<u16, VirtioTransportError> {
|
||||
field_ptr!(&self.layout, VirtioMmioLayout, queue_sel)
|
||||
.write(&(idx as u32))
|
||||
.write_once(&(idx as u32))
|
||||
.unwrap();
|
||||
Ok(field_ptr!(&self.layout, VirtioMmioLayout, queue_num_max)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap() as u16)
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ impl MultiplexIrq {
|
||||
return;
|
||||
};
|
||||
let irq = multiplex_irq.read();
|
||||
let interrupt_status = irq.interrupt_status.read().unwrap();
|
||||
let interrupt_status = irq.interrupt_status.read_once().unwrap();
|
||||
let callbacks = if interrupt_status & 0x01 == 1 {
|
||||
// Used buffer notification
|
||||
&irq.queue_callbacks
|
||||
@ -55,7 +55,7 @@ impl MultiplexIrq {
|
||||
for callback in callbacks.iter() {
|
||||
callback.call((trap_frame,));
|
||||
}
|
||||
irq.interrupt_ack.write(&interrupt_status).unwrap();
|
||||
irq.interrupt_ack.write_once(&interrupt_status).unwrap();
|
||||
};
|
||||
lock.irq.on_active(callback);
|
||||
drop(lock);
|
||||
|
@ -80,30 +80,30 @@ impl VirtioTransport for VirtioPciTransport {
|
||||
return Err(VirtioTransportError::InvalidArgs);
|
||||
}
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select)
|
||||
.write(&idx)
|
||||
.write_once(&idx)
|
||||
.unwrap();
|
||||
debug_assert_eq!(
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap(),
|
||||
idx
|
||||
);
|
||||
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_size)
|
||||
.write(&queue_size)
|
||||
.write_once(&queue_size)
|
||||
.unwrap();
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_desc)
|
||||
.write(&(descriptor_ptr.paddr() as u64))
|
||||
.write_once(&(descriptor_ptr.paddr() as u64))
|
||||
.unwrap();
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_driver)
|
||||
.write(&(avail_ring_ptr.paddr() as u64))
|
||||
.write_once(&(avail_ring_ptr.paddr() as u64))
|
||||
.unwrap();
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_device)
|
||||
.write(&(used_ring_ptr.paddr() as u64))
|
||||
.write_once(&(used_ring_ptr.paddr() as u64))
|
||||
.unwrap();
|
||||
// Enable queue
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_enable)
|
||||
.write(&1u16)
|
||||
.write_once(&1u16)
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
@ -120,7 +120,7 @@ impl VirtioTransport for VirtioPciTransport {
|
||||
|
||||
fn num_queues(&self) -> u16 {
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, num_queues)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
@ -142,17 +142,17 @@ impl VirtioTransport for VirtioPciTransport {
|
||||
fn device_features(&self) -> u64 {
|
||||
// select low
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, device_feature_select)
|
||||
.write(&0u32)
|
||||
.write_once(&0u32)
|
||||
.unwrap();
|
||||
let device_feature_low = field_ptr!(&self.common_cfg, VirtioPciCommonCfg, device_features)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap();
|
||||
// select high
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, device_feature_select)
|
||||
.write(&1u32)
|
||||
.write_once(&1u32)
|
||||
.unwrap();
|
||||
let device_feature_high = field_ptr!(&self.common_cfg, VirtioPciCommonCfg, device_features)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap() as u64;
|
||||
device_feature_high << 32 | device_feature_low as u64
|
||||
}
|
||||
@ -161,47 +161,47 @@ impl VirtioTransport for VirtioPciTransport {
|
||||
let low = features as u32;
|
||||
let high = (features >> 32) as u32;
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, driver_feature_select)
|
||||
.write(&0u32)
|
||||
.write_once(&0u32)
|
||||
.unwrap();
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, driver_features)
|
||||
.write(&low)
|
||||
.write_once(&low)
|
||||
.unwrap();
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, driver_feature_select)
|
||||
.write(&1u32)
|
||||
.write_once(&1u32)
|
||||
.unwrap();
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, driver_features)
|
||||
.write(&high)
|
||||
.write_once(&high)
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn device_status(&self) -> DeviceStatus {
|
||||
let status = field_ptr!(&self.common_cfg, VirtioPciCommonCfg, device_status)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap();
|
||||
DeviceStatus::from_bits(status).unwrap()
|
||||
}
|
||||
|
||||
fn set_device_status(&mut self, status: DeviceStatus) -> Result<(), VirtioTransportError> {
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, device_status)
|
||||
.write(&(status.bits()))
|
||||
.write_once(&(status.bits()))
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn max_queue_size(&self, idx: u16) -> Result<u16, crate::transport::VirtioTransportError> {
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select)
|
||||
.write(&idx)
|
||||
.write_once(&idx)
|
||||
.unwrap();
|
||||
debug_assert_eq!(
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap(),
|
||||
idx
|
||||
);
|
||||
|
||||
Ok(field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_size)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
@ -223,16 +223,16 @@ impl VirtioTransport for VirtioPciTransport {
|
||||
};
|
||||
irq.on_active(func);
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select)
|
||||
.write(&index)
|
||||
.write_once(&index)
|
||||
.unwrap();
|
||||
debug_assert_eq!(
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_select)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap(),
|
||||
index
|
||||
);
|
||||
field_ptr!(&self.common_cfg, VirtioPciCommonCfg, queue_msix_vector)
|
||||
.write(&vector)
|
||||
.write_once(&vector)
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user