mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-29 16:13:27 +00:00
Implement VmIoOnce
for IoMem
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
aa62f0a4e6
commit
c8ba695c85
@ -81,10 +81,9 @@ impl aster_block::BlockDevice for BlockDevice {
|
||||
}
|
||||
|
||||
fn metadata(&self) -> BlockDeviceMeta {
|
||||
let device_config = self.device.config.read().unwrap();
|
||||
BlockDeviceMeta {
|
||||
max_nr_segments_per_bio: self.queue.max_nr_segments_per_bio(),
|
||||
nr_sectors: device_config.capacity_sectors(),
|
||||
nr_sectors: VirtioBlockConfig::read_capacity_sectors(&self.device.config).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,7 +106,7 @@ impl DeviceInner {
|
||||
pub fn init(mut transport: Box<dyn VirtioTransport>) -> Result<Arc<Self>, VirtioDeviceError> {
|
||||
let config = VirtioBlockConfig::new(transport.as_mut());
|
||||
assert_eq!(
|
||||
config.read().unwrap().block_size(),
|
||||
VirtioBlockConfig::read_block_size(&config).unwrap(),
|
||||
VirtioBlockConfig::sector_size(),
|
||||
"currently not support customized device logical block size"
|
||||
);
|
||||
|
@ -3,7 +3,7 @@
|
||||
pub mod device;
|
||||
|
||||
use aster_block::SECTOR_SIZE;
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use aster_util::{field_ptr, safe_ptr::SafePtr};
|
||||
use bitflags::bitflags;
|
||||
use int_to_c_enum::TryFromInt;
|
||||
use ostd::{io_mem::IoMem, Pod};
|
||||
@ -119,15 +119,17 @@ impl VirtioBlockConfig {
|
||||
SECTOR_SIZE
|
||||
}
|
||||
|
||||
pub(self) fn block_size(&self) -> usize {
|
||||
self.blk_size as usize
|
||||
pub(self) fn read_block_size(this: &SafePtr<Self, IoMem>) -> ostd::prelude::Result<usize> {
|
||||
field_ptr!(this, Self, blk_size)
|
||||
.read_once()
|
||||
.map(|val| val as usize)
|
||||
}
|
||||
|
||||
pub(self) fn capacity_sectors(&self) -> usize {
|
||||
self.capacity as usize
|
||||
}
|
||||
|
||||
pub(self) fn capacity_bytes(&self) -> usize {
|
||||
self.capacity_sectors() * Self::sector_size()
|
||||
pub(self) fn read_capacity_sectors(
|
||||
this: &SafePtr<Self, IoMem>,
|
||||
) -> ostd::prelude::Result<usize> {
|
||||
field_ptr!(this, Self, capacity)
|
||||
.read_once()
|
||||
.map(|val| val as usize)
|
||||
}
|
||||
}
|
||||
|
@ -171,15 +171,17 @@ impl InputDevice {
|
||||
/// result to `out`, return the result size.
|
||||
pub fn query_config_select(&self, select: InputConfigSelect, subsel: u8, out: &mut [u8]) -> u8 {
|
||||
field_ptr!(&self.config, VirtioInputConfig, select)
|
||||
.write(&(select as u8))
|
||||
.write_once(&(select as u8))
|
||||
.unwrap();
|
||||
field_ptr!(&self.config, VirtioInputConfig, subsel)
|
||||
.write(&subsel)
|
||||
.write_once(&subsel)
|
||||
.unwrap();
|
||||
let size = field_ptr!(&self.config, VirtioInputConfig, size)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap();
|
||||
let data: [u8; 128] = field_ptr!(&self.config, VirtioInputConfig, data)
|
||||
// FIXME: It is impossible to call `read_once` on `[u8; 128]`. What's the proper way to
|
||||
// read this field out?
|
||||
.read()
|
||||
.unwrap();
|
||||
out[..size as usize].copy_from_slice(&data[..size as usize]);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use aster_network::EthernetAddr;
|
||||
use aster_util::safe_ptr::SafePtr;
|
||||
use aster_util::{field_ptr, safe_ptr::SafePtr};
|
||||
use bitflags::bitflags;
|
||||
use ostd::{io_mem::IoMem, Pod};
|
||||
|
||||
@ -76,4 +76,25 @@ impl VirtioNetConfig {
|
||||
let memory = transport.device_config_memory();
|
||||
SafePtr::new(memory, 0)
|
||||
}
|
||||
|
||||
pub(super) fn read(this: &SafePtr<Self, IoMem>) -> ostd::prelude::Result<Self> {
|
||||
Ok(Self {
|
||||
// FIXME: It is impossible to call `read_once` on `EthernetAddr`. What's the proper way
|
||||
// to read this field out?
|
||||
mac: field_ptr!(this, Self, mac).read()?,
|
||||
status: field_ptr!(this, Self, status).read_once()?,
|
||||
max_virtqueue_pairs: field_ptr!(this, Self, max_virtqueue_pairs).read_once()?,
|
||||
mtu: field_ptr!(this, Self, mtu).read_once()?,
|
||||
speed: field_ptr!(this, Self, speed).read_once()?,
|
||||
duplex: field_ptr!(this, Self, duplex).read_once()?,
|
||||
rss_max_key_size: field_ptr!(this, Self, rss_max_key_size).read_once()?,
|
||||
rss_max_indirection_table_length: field_ptr!(
|
||||
this,
|
||||
Self,
|
||||
rss_max_indirection_table_length
|
||||
)
|
||||
.read_once()?,
|
||||
supported_hash_types: field_ptr!(this, Self, supported_hash_types).read_once()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ use aster_network::{
|
||||
AnyNetworkDevice, EthernetAddr, RxBuffer, TxBuffer, VirtioNetError, RX_BUFFER_POOL,
|
||||
TX_BUFFER_POOL,
|
||||
};
|
||||
use aster_util::{field_ptr, slot_vec::SlotVec};
|
||||
use aster_util::slot_vec::SlotVec;
|
||||
use log::debug;
|
||||
use ostd::{offset_of, sync::SpinLock, trap::TrapFrame};
|
||||
use ostd::{sync::SpinLock, trap::TrapFrame};
|
||||
use smoltcp::phy::{DeviceCapabilities, Medium};
|
||||
|
||||
use super::{config::VirtioNetConfig, header::VirtioNetHdr};
|
||||
@ -44,13 +44,11 @@ impl NetworkDevice {
|
||||
));
|
||||
debug!("virtio_net_config = {:?}", virtio_net_config);
|
||||
debug!("features = {:?}", features);
|
||||
let mac_addr = field_ptr!(&virtio_net_config, VirtioNetConfig, mac)
|
||||
.read()
|
||||
.unwrap();
|
||||
let status = field_ptr!(&virtio_net_config, VirtioNetConfig, status)
|
||||
.read()
|
||||
.unwrap();
|
||||
debug!("mac addr = {:x?}, status = {:?}", mac_addr, status);
|
||||
|
||||
let config = VirtioNetConfig::read(&virtio_net_config).unwrap();
|
||||
let mac_addr = config.mac;
|
||||
debug!("mac addr = {:x?}, status = {:?}", mac_addr, config.status);
|
||||
|
||||
let mut recv_queue = VirtQueue::new(QUEUE_RECV, QUEUE_SIZE, transport.as_mut())
|
||||
.expect("creating recv queue fails");
|
||||
let send_queue = VirtQueue::new(QUEUE_SEND, QUEUE_SIZE, transport.as_mut())
|
||||
@ -71,7 +69,7 @@ impl NetworkDevice {
|
||||
recv_queue.notify();
|
||||
}
|
||||
let mut device = Self {
|
||||
config: virtio_net_config.read().unwrap(),
|
||||
config,
|
||||
mac_addr,
|
||||
send_queue,
|
||||
recv_queue,
|
||||
|
@ -53,10 +53,10 @@ impl SocketDevice {
|
||||
let virtio_vsock_config = VirtioVsockConfig::new(transport.as_mut());
|
||||
debug!("virtio_vsock_config = {:?}", virtio_vsock_config);
|
||||
let guest_cid = field_ptr!(&virtio_vsock_config, VirtioVsockConfig, guest_cid_low)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap() as u64
|
||||
| (field_ptr!(&virtio_vsock_config, VirtioVsockConfig, guest_cid_high)
|
||||
.read()
|
||||
.read_once()
|
||||
.unwrap() as u64)
|
||||
<< 32;
|
||||
|
||||
@ -83,7 +83,7 @@ impl SocketDevice {
|
||||
}
|
||||
|
||||
let mut device = Self {
|
||||
config: virtio_vsock_config.read().unwrap(),
|
||||
config: virtio_vsock_config.read_once().unwrap(),
|
||||
guest_cid,
|
||||
send_queue,
|
||||
recv_queue,
|
||||
|
Reference in New Issue
Block a user