Selaa lähdekoodia

VirtIO网卡能够正常发送、接收数据 (#204)

* virtio-net小修改

* 移动volatile.rs到libs文件夹

* 使用virtio-drivers 0.3.0

* bugfix: 初始化BAR之后,未正确设置command register的问题


---------

Co-authored-by: longjin <[email protected]>
YJwu2023 2 vuotta sitten
vanhempi
commit
73c607aadd

+ 1 - 1
kernel/Cargo.toml

@@ -12,7 +12,7 @@ crate-type = ["staticlib"]
 [dependencies]
 x86_64 = "0.14.10"
 bitflags = "1.3.2"
-virtio-drivers = "0.2.0"
+virtio-drivers = "0.3.0"
 # 一个无锁MPSC队列
 thingbuf = { version = "0.1.3", default-features = false, features = ["alloc"] }
 # smoltcp 0.9.1

+ 31 - 4
kernel/src/driver/pci/pci.rs

@@ -46,7 +46,7 @@ bitflags! {
 
 bitflags! {
     /// The command register in PCI configuration space.
-    pub struct Command: u16 {
+    pub struct CommandRegister: u16 {
         /// The device can respond to I/O Space accesses.
         const IO_SPACE = 1 << 0;
         /// The device can respond to Memory Space accesses.
@@ -131,9 +131,10 @@ impl Display for PciError {
 impl DeviceFunction {
     /// Returns whether the device and function numbers are valid, i.e. the device is between 0 and
     /// 31, and the function is between 0 and 7.
-    ///@brief 检测DeviceFunction实例是否有效
-    ///@param self
-    ///@return bool 是否有效
+    /// @brief 检测DeviceFunction实例是否有效
+    /// @param self
+    /// @return bool 是否有效
+    #[allow(dead_code)]
     pub fn valid(&self) -> bool {
         self.device < 32 && self.function < 8
     }
@@ -449,6 +450,7 @@ pub struct CapabilityInfo {
     /// The third and fourth bytes of the capability, to save reading them again.
     pub private_header: u16,
 }
+
 /// Iterator over capabilities for a device.
 /// 创建迭代器以遍历PCI设备的capability
 #[derive(Debug)]
@@ -492,3 +494,28 @@ impl Iterator for CapabilityIterator {
         })
     }
 }
+
+/// @brief 设置PCI Config Space里面的Command Register
+///
+/// @param device_function 设备
+/// @param value command register要被设置成的值
+pub fn set_command_register(device_function: &DeviceFunction, value: CommandRegister) {
+    unsafe {
+        pci_write_config(
+            device_function.bus,
+            device_function.device,
+            device_function.function,
+            STATUS_COMMAND_OFFSET,
+            value.bits().into(),
+        );
+    }
+}
+/// @brief 使能对PCI Memory/IO空间的写入,使能PCI设备作为主设备(主动进行Memory的写入等,msix中断使用到)
+///
+/// @param device_function 设备
+pub fn pci_enable_master(device_function: DeviceFunction) {
+    set_command_register(
+        &device_function,
+        CommandRegister::IO_SPACE | CommandRegister::MEMORY_SPACE | CommandRegister::BUS_MASTER,
+    );
+}

+ 0 - 1
kernel/src/driver/virtio/mod.rs

@@ -1,4 +1,3 @@
 pub mod transport_pci;
 pub mod virtio;
 pub mod virtio_impl;
-pub mod volatile;

+ 39 - 17
kernel/src/driver/virtio/transport_pci.rs

@@ -1,12 +1,13 @@
 //! PCI transport for VirtIO.
-use super::volatile::{
-    volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
-};
 use crate::driver::pci::pci::{
-    capabilities_offset, pci_bar_init, CapabilityIterator, DeviceFunction, PciDeviceBar, PciError,
-    PCI_CAP_ID_VNDR,
+    capabilities_offset, pci_bar_init, pci_enable_master, CapabilityIterator, DeviceFunction,
+    PciDeviceBar, PciError, PCI_CAP_ID_VNDR,
 };
 use crate::include::bindings::bindings::pci_read_config;
+
+use crate::libs::volatile::{
+    volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
+};
 use core::{
     fmt::{self, Display, Formatter},
     mem::{align_of, size_of},
@@ -14,9 +15,10 @@ use core::{
 };
 use virtio_drivers::{
     transport::{DeviceStatus, DeviceType, Transport},
-    Error, Hal, PhysAddr, VirtAddr,
+    Error, Hal, PhysAddr,
 };
 
+type VirtAddr = usize;
 /// The PCI vendor ID for VirtIO devices.
 /// PCI Virtio设备的vendor ID
 const VIRTIO_VENDOR_ID: u16 = 0x1af4;
@@ -119,8 +121,9 @@ impl PciTransport {
             device_function: device_function,
             next_capability_offset: capabilities_offset(device_function),
         };
-        let device_bar = pci_bar_init(device_function)?;
 
+        let device_bar = pci_bar_init(device_function)?;
+        pci_enable_master(device_function);
         for capability in device_capability {
             if capability.id != PCI_CAP_ID_VNDR {
                 continue;
@@ -197,6 +200,7 @@ impl PciTransport {
                 notify_off_multiplier,
             ));
         }
+        //kdebug!("notify.offset={},notify.length={}",notify_cfg.offset,notify_cfg.length);
         let notify_region = get_bar_region_slice::<_>(&device_bar, &notify_cfg)?;
         let isr_status = get_bar_region::<_>(
             &device_bar,
@@ -282,7 +286,9 @@ impl Transport for PciTransport {
     fn set_guest_page_size(&mut self, _guest_page_size: u32) {
         // No-op, the PCI transport doesn't care.
     }
-
+    fn requires_legacy_layout(&self) -> bool {
+        false
+    }
     fn queue_set(
         &mut self,
         queue: u16,
@@ -293,6 +299,10 @@ impl Transport for PciTransport {
     ) {
         // Safe because the common config pointer is valid and we checked in get_bar_region that it
         // was aligned.
+        // kdebug!("queue_select={}",queue);
+        // kdebug!("queue_size={}",size as u16);
+        // kdebug!("queue_desc={:#x}",descriptors as u64);
+        // kdebug!("driver_area={:#x}",driver_area);
         unsafe {
             volwrite!(self.common_cfg, queue_select, queue);
             volwrite!(self.common_cfg, queue_size, size as u16);
@@ -307,7 +317,6 @@ impl Transport for PciTransport {
         // Safe because the common config pointer is valid and we checked in get_bar_region that it
         // was aligned.
         unsafe {
-            volwrite!(self.common_cfg, queue_enable, 0);
             volwrite!(self.common_cfg, queue_select, queue);
             volwrite!(self.common_cfg, queue_size, 0);
             volwrite!(self.common_cfg, queue_desc, 0);
@@ -355,8 +364,13 @@ impl Transport for PciTransport {
     }
 }
 
-/// `virtio_pci_common_cfg`, see 4.1.4.3 "Common configuration structure layout".
-///
+impl Drop for PciTransport {
+    fn drop(&mut self) {
+        // Reset the device when the transport is dropped.
+        self.set_status(DeviceStatus::empty())
+    }
+}
+
 #[repr(C)]
 struct CommonCfg {
     device_feature_select: Volatile<u32>,
@@ -488,6 +502,7 @@ fn get_bar_region<T>(
     {
         return Err(VirtioPciError::BarOffsetOutOfRange);
     }
+    //kdebug!("Chossed bar ={},used={}",struct_info.bar,struct_info.offset + struct_info.length);
     let vaddr = (bar_info
         .virtual_address()
         .ok_or(VirtioPciError::BarGetVaddrFailed)?) as usize
@@ -498,18 +513,25 @@ fn get_bar_region<T>(
             alignment: align_of::<T>(),
         });
     }
-    Ok(NonNull::new((vaddr) as _).unwrap())
+    let vaddr = NonNull::new(vaddr as *mut u8).unwrap();
+    Ok(vaddr.cast())
 }
 
-///@brief 获取虚拟地址并将其转化为对应类型的指针
-///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息
+///@brief 获取虚拟地址并将其转化为对应类型的
+///@param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针
 ///@return Result<NonNull<[T]>, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error
 fn get_bar_region_slice<T>(
     device_bar: &PciDeviceBar,
     struct_info: &VirtioCapabilityInfo,
 ) -> Result<NonNull<[T]>, VirtioPciError> {
     let ptr = get_bar_region::<T>(device_bar, struct_info)?;
-    let raw_slice =
-        ptr::slice_from_raw_parts_mut(ptr.as_ptr(), struct_info.length as usize / size_of::<T>());
-    Ok(NonNull::new(raw_slice).unwrap())
+    // let raw_slice =
+    //     ptr::slice_from_raw_parts_mut(ptr.as_ptr(), struct_info.length as usize / size_of::<T>());
+    Ok(nonnull_slice_from_raw_parts(
+        ptr,
+        struct_info.length as usize / size_of::<T>(),
+    ))
+}
+fn nonnull_slice_from_raw_parts<T>(data: NonNull<T>, len: usize) -> NonNull<[T]> {
+    NonNull::new(ptr::slice_from_raw_parts_mut(data.as_ptr(), len)).unwrap()
 }

+ 1 - 1
kernel/src/driver/virtio/virtio.h

@@ -9,4 +9,4 @@
 // 获取virtio-net 设备
 uint8_t get_virtio_net_device(uint8_t * bus, uint8_t *device,uint8_t * function);
 //寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备后续也可添加)
-extern void  c_virtio_probe();
+void  c_virtio_probe();

+ 29 - 6
kernel/src/driver/virtio/virtio.rs

@@ -90,18 +90,41 @@ fn virtio_net<T: Transport>(transport: T) {
             return;
         }
     };
-    // let mut buf = [0u8; 0x100];
+    let mut buf = [0u8; 0x100];
     // let len = match driver_net.recv(&mut buf)
     // {
     //     Ok(len) =>{len},
     //     Err(_) =>{kerror!("virtio_net recv failed");return;}
     // };
-    // kdebug!("recv: {:?}", &buf[..len]);
-    // match driver_net.send(&buf[..len])
-    // {
-    //     Ok(_) =>{kdebug!("virtio_net send success");},
-    //     Err(_) =>{kerror!("virtio_net send failed");return;},
+    match driver_net.can_send() {
+        true => {
+            kdebug!("Virtio-net can send");
+        }
+        false => {
+            kdebug!("Virtio-net can not send");
+        }
+    }
+    // match driver_net.can_recv() {
+    //     true => {
+    //         kdebug!("can recv")
+    //     }
+    //     false => {
+    //         kdebug!("can not recv");
+    //     }
     // }
+
+    let len = 100;
+    //kdebug!("recv: {:?}", &buf[..len]);
+    match driver_net.send(&buf[..len]) {
+        Ok(_) => {
+            kdebug!("virtio_net send success");
+        }
+        Err(_) => {
+            kerror!("virtio_net send failed");
+            return;
+        }
+    }
+
     let mac = driver_net.mac();
     kdebug!("virtio_net MAC={:?}", mac);
     kdebug!("virtio-net test finished");

+ 20 - 33
kernel/src/driver/virtio/virtio_impl.rs

@@ -1,63 +1,57 @@
+/// 为virtio-drivers库提供的操作系统接口
 use crate::include::bindings::bindings::{
     alloc_pages, free_pages, memory_management_struct, Page, PAGE_2M_SHIFT, PAGE_2M_SIZE,
     PAGE_OFFSET, PAGE_SHARED, ZONE_NORMAL,
 };
 
+use crate::mm::virt_2_phys;
 use core::mem::size_of;
 use core::ptr::NonNull;
-use virtio_drivers::{BufferDirection, Hal, PhysAddr, VirtAddr, PAGE_SIZE};
-
+use virtio_drivers::{BufferDirection, Hal, PhysAddr, PAGE_SIZE};
 pub struct HalImpl;
 impl Hal for HalImpl {
     /// @brief 申请用于DMA的内存页
     /// @param pages 页数(4k一页)
     /// @return PhysAddr 获得的内存页的初始物理地址
-    fn dma_alloc(pages: usize) -> PhysAddr {
-        let reminder = pages * PAGE_SIZE % (PAGE_2M_SIZE as usize);
-        let page_num = if reminder > 0 {
-            (pages * PAGE_SIZE / (PAGE_2M_SIZE as usize) + 1) as i32
-        } else {
-            (pages * PAGE_SIZE / (PAGE_2M_SIZE as usize)) as i32
-        };
-
+    fn dma_alloc(pages: usize, _direction: BufferDirection) -> (PhysAddr, NonNull<u8>) {
+        let page_num = (pages * PAGE_SIZE - 1 + PAGE_2M_SIZE as usize) / PAGE_2M_SIZE as usize;
         unsafe {
-            let pa = alloc_pages(ZONE_NORMAL, page_num, PAGE_SHARED as u64);
+            let pa = alloc_pages(ZONE_NORMAL, page_num as i32, PAGE_SHARED as u64);
             let page = *pa;
-            //kdebug!("alloc pages num:{},Phyaddr={}",page_num,page.addr_phys);
-            return page.addr_phys as PhysAddr;
+            //kdebug!("alloc pages num:{},Phyaddr={:#x}",pages,page.addr_phys);
+            (
+                page.addr_phys as PhysAddr,
+                NonNull::new((page.addr_phys as PhysAddr + PAGE_OFFSET as usize) as _).unwrap(),
+            )
         }
     }
     /// @brief 释放用于DMA的内存页
     /// @param paddr 起始物理地址 pages 页数(4k一页)
     /// @return i32 0表示成功
-    fn dma_dealloc(paddr: PhysAddr, pages: usize) -> i32 {
-        let reminder = pages * PAGE_SIZE % (PAGE_2M_SIZE as usize);
-        let page_num = if reminder > 0 {
-            (pages * PAGE_SIZE / (PAGE_2M_SIZE as usize) + 1) as i32
-        } else {
-            (pages * PAGE_SIZE / (PAGE_2M_SIZE as usize)) as i32
-        };
+    fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull<u8>, pages: usize) -> i32 {
+        let page_num = (pages * PAGE_SIZE - 1 + PAGE_2M_SIZE as usize) / PAGE_2M_SIZE as usize;
         unsafe {
             let pa = (memory_management_struct.pages_struct as usize
                 + (paddr >> PAGE_2M_SHIFT) * size_of::<Page>()) as *mut Page;
             //kdebug!("free pages num:{},Phyaddr={}",page_num,paddr);
-            free_pages(pa, page_num);
+            free_pages(pa, page_num as i32);
         }
         return 0;
     }
-    /// @brief 物理地址转换为虚拟地址
+    /// @brief mmio物理地址转换为虚拟地址,不需要使用
     /// @param paddr 起始物理地址
-    /// @return VirtAddr 虚拟地址
-    fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
-        paddr + PAGE_OFFSET as usize
+    /// @return NonNull<u8> 虚拟地址的指针
+    fn mmio_phys_to_virt(_paddr: PhysAddr, _size: usize) -> NonNull<u8> {
+        NonNull::new((0) as _).unwrap()
     }
     /// @brief 与真实物理设备共享
     /// @param buffer 要共享的buffer _direction:设备到driver或driver到设备
     /// @return buffer在内存中的物理地址
     fn share(buffer: NonNull<[u8]>, _direction: BufferDirection) -> PhysAddr {
         let vaddr = buffer.as_ptr() as *mut u8 as usize;
+        //kdebug!("virt:{:x}", vaddr);
         // Nothing to do, as the host already has access to all memory.
-        virt_to_phys(vaddr)
+        virt_2_phys(vaddr)
     }
     /// @brief 停止共享(让主机可以访问全部内存的话什么都不用做)
     fn unshare(_paddr: PhysAddr, _buffer: NonNull<[u8]>, _direction: BufferDirection) {
@@ -65,10 +59,3 @@ impl Hal for HalImpl {
         // anywhere else.
     }
 }
-
-/// @brief 虚拟地址转换为物理地址
-/// @param vaddr 虚拟地址
-/// @return PhysAddr 物理地址
-fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
-    vaddr - PAGE_OFFSET as usize
-}

+ 12 - 8
kernel/src/filesystem/devfs/mod.rs

@@ -4,11 +4,12 @@ pub mod zero_dev;
 
 use super::vfs::{
     core::{generate_inode_id, ROOT_INODE},
-    FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus, file::FileMode,
+    file::FileMode,
+    FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus,
 };
 use crate::{
     include::bindings::bindings::{EEXIST, EISDIR, ENOENT, ENOTDIR, ENOTSUP},
-    kdebug, kerror,
+    kerror,
     libs::spinlock::{SpinLock, SpinLockGuard},
     time::TimeSpec,
 };
@@ -231,7 +232,7 @@ impl DevFSInode {
 
 impl LockedDevFSInode {
     pub fn add_dir(&self, name: &str) -> Result<(), i32> {
-        let guard:SpinLockGuard<DevFSInode> = self.0.lock();
+        let guard: SpinLockGuard<DevFSInode> = self.0.lock();
 
         if guard.children.contains_key(name) {
             return Err(-(EEXIST as i32));
@@ -270,10 +271,14 @@ impl LockedDevFSInode {
         return Ok(());
     }
 
-    fn do_create_with_data(&self, mut guard: SpinLockGuard<DevFSInode>,_name: &str,
+    fn do_create_with_data(
+        &self,
+        mut guard: SpinLockGuard<DevFSInode>,
+        _name: &str,
         _file_type: FileType,
         _mode: u32,
-        _data: usize,) -> Result<Arc<dyn IndexNode>, i32>{
+        _data: usize,
+    ) -> Result<Arc<dyn IndexNode>, i32> {
         if guard.metadata.file_type != FileType::Dir {
             return Err(-(ENOTDIR as i32));
         }
@@ -313,7 +318,6 @@ impl LockedDevFSInode {
         // 将子inode插入父inode的B树中
         guard.children.insert(String::from(_name), result.clone());
         return Ok(result);
-
     }
 }
 
@@ -329,7 +333,7 @@ impl IndexNode for LockedDevFSInode {
     fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), i32> {
         return Ok(());
     }
-    
+
     fn create_with_data(
         &self,
         name: &str,
@@ -338,7 +342,7 @@ impl IndexNode for LockedDevFSInode {
         data: usize,
     ) -> Result<Arc<dyn IndexNode>, i32> {
         // 获取当前inode
-        let guard:SpinLockGuard<DevFSInode> = self.0.lock();
+        let guard: SpinLockGuard<DevFSInode> = self.0.lock();
         // 如果当前inode不是文件夹,则返回
         return self.do_create_with_data(guard, name, file_type, mode, data);
     }

+ 4 - 4
kernel/src/filesystem/fat/fs.rs

@@ -10,14 +10,15 @@ use alloc::{
 
 use crate::{
     filesystem::vfs::{
-        core::generate_inode_id, file::{FilePrivateData, FileMode}, FileSystem, FileType, IndexNode, InodeId,
-        Metadata, PollStatus,
+        core::generate_inode_id,
+        file::{FileMode, FilePrivateData},
+        FileSystem, FileType, IndexNode, InodeId, Metadata, PollStatus,
     },
     include::bindings::bindings::{
         EFAULT, EINVAL, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY, ENOTSUP, EPERM, EROFS,
     },
     io::{device::LBA_SIZE, disk_info::Partition, SeekFrom},
-    kdebug, kerror,
+    kerror,
     libs::{
         spinlock::{SpinLock, SpinLockGuard},
         vec_cursor::VecCursor,
@@ -1539,7 +1540,6 @@ impl IndexNode for LockedFATInode {
         let r = dir.remove(guard.fs.upgrade().unwrap().clone(), name, true);
         drop(target_guard);
         return r;
-        
     }
 
     fn rmdir(&self, name: &str) -> Result<(), i32> {

+ 2 - 1
kernel/src/libs/mod.rs

@@ -11,5 +11,6 @@ pub mod semaphore;
 pub mod spinlock;
 pub mod vec_cursor;
 #[macro_use]
-pub mod volatile_io;
+pub mod volatile;
 pub mod wait_queue;
+

+ 72 - 3
kernel/src/driver/virtio/volatile.rs → kernel/src/libs/volatile.rs

@@ -1,8 +1,76 @@
-/// An MMIO register which can only be read from.
+macro_rules! volatile_read {
+    ($data: expr) => {
+        unsafe { core::ptr::read_volatile(core::ptr::addr_of!($data)) }
+    };
+}
+
+macro_rules! volatile_write {
+    ($data: expr, $value: expr) => {
+        unsafe { core::ptr::write_volatile(core::ptr::addr_of_mut!($data), $value) }
+    };
+}
+
+/// @brief: 用于volatile设置某些bits
+/// @param val: 设置这些位
+/// @param flag: true表示设置这些位为1; false表示设置这些位为0;
+macro_rules! volatile_set_bit {
+    ($data: expr, $val: expr, $flag: expr) => {
+        volatile_write!(
+            $data,
+            match $flag {
+                true => core::ptr::read_volatile(core::ptr::addr_of!($data)) | $val,
+                false => core::ptr::read_volatile(core::ptr::addr_of!($data)) & (!$val),
+            }
+        )
+    };
+}
+
+/// @param data: volatile变量
+/// @param bits: 置1的位才有效,表示写这些位
+/// @param val: 要写的值
+/// 比如: 写 x 的 2至8bit, 为 10, 可以这么写 volatile_write_bit(x, (1<<8)-(1<<2), 10<<2);    
+macro_rules! volatile_write_bit {
+    ($data: expr, $bits: expr, $val: expr) => {
+        volatile_set_bit!($data, $bits, false);
+        volatile_set_bit!($data, ($val) & ($bits), true);
+    };
+}
+
+/// 以下代码来自于virtio-drivers 0.2.0
+/// 在对已经MMIO映射对虚拟地址的寄存器的操作中,我们经常遇到有的寄存器是只读或可读写的
+/// 那么我们就可以使用结构体ReadOnly WriteOnly Volatile对其进行区分
+/// 例:
+/// #[repr(C)]
+/// struct CommonCfg {
+///     device_feature_select: Volatile<u32>,
+///     device_feature: ReadOnly<u32>,
+///     driver_feature_select: Volatile<u32>,
+///     driver_feature: Volatile<u32>,
+///     msix_config: Volatile<u16>,
+///     num_queues: ReadOnly<u16>,
+///     device_status: Volatile<u8>,
+///     config_generation: ReadOnly<u8>,
+///     queue_select: Volatile<u16>,
+///     queue_size: Volatile<u16>,
+///     queue_msix_vector: Volatile<u16>,
+///     queue_enable: Volatile<u16>,
+///     queue_notify_off: Volatile<u16>,
+///     queue_desc: Volatile<u64>,
+///     queue_driver: Volatile<u64>,
+///     queue_device: Volatile<u64>,
+/// }
+/// 
+/// 对CommonCfg里面的某个寄存器进行读写:
+/// volwrite!(self.common_cfg, queue_enable, 0);
+/// 
+/// 这样做不仅使代码的可读性提高了,也避免了对只读寄存器进行写入的误操作
+
+/// 只读寄存器
 #[derive(Default)]
 #[repr(transparent)]
 pub struct ReadOnly<T: Copy>(T);
 
+#[allow(dead_code)]
 impl<T: Copy> ReadOnly<T> {
     /// Construct a new instance for testing.
     pub fn new(value: T) -> Self {
@@ -10,16 +78,17 @@ impl<T: Copy> ReadOnly<T> {
     }
 }
 
-/// An MMIO register which can only be written to.
+/// 只写寄存器
 #[derive(Default)]
 #[repr(transparent)]
 pub struct WriteOnly<T: Copy>(T);
 
-/// An MMIO register which may be both read and written.
+/// 写读寄存器
 #[derive(Default)]
 #[repr(transparent)]
 pub struct Volatile<T: Copy>(T);
 
+#[allow(dead_code)]
 impl<T: Copy> Volatile<T> {
     /// Construct a new instance for testing.
     pub fn new(value: T) -> Self {

+ 0 - 37
kernel/src/libs/volatile_io.rs

@@ -1,37 +0,0 @@
-macro_rules! volatile_read {
-    ($data: expr) => {
-        unsafe { core::ptr::read_volatile(core::ptr::addr_of!($data)) }
-    };
-}
-
-macro_rules! volatile_write {
-    ($data: expr, $value: expr) => {
-        unsafe { core::ptr::write_volatile(core::ptr::addr_of_mut!($data), $value) }
-    };
-}
-
-/// @brief: 用于volatile设置某些bits
-/// @param val: 设置这些位
-/// @param flag: true表示设置这些位为1; false表示设置这些位为0;
-macro_rules! volatile_set_bit {
-    ($data: expr, $val: expr, $flag: expr) => {
-        volatile_write!(
-            $data,
-            match $flag {
-                true => core::ptr::read_volatile(core::ptr::addr_of!($data)) | $val,
-                false => core::ptr::read_volatile(core::ptr::addr_of!($data)) & (!$val),
-            }
-        )
-    };
-}
-
-/// @param data: volatile变量
-/// @param bits: 置1的位才有效,表示写这些位
-/// @param val: 要写的值
-/// 比如: 写 x 的 2至8bit, 为 10, 可以这么写 volatile_write_bit(x, (1<<8)-(1<<2), 10<<2);    
-macro_rules! volatile_write_bit {
-    ($data: expr, $bits: expr, $val: expr) => {
-        volatile_set_bit!($data, $bits, false);
-        volatile_set_bit!($data, ($val) & ($bits), true);
-    };
-}

+ 5 - 5
tools/run-qemu.sh

@@ -9,7 +9,7 @@ ARCH="x86_64"
 # 请根据自己的需要,在-d 后方加入所需的trace事件
 
 # 标准的trace events
-qemu_trace_std=cpu_reset,guest_errors,exec,cpu
+qemu_trace_std=cpu_reset,guest_errors,exec,cpu,trace:virtio*
 # 调试usb的trace
 qemu_trace_usb=trace:usb_xhci_reset,trace:usb_xhci_run,trace:usb_xhci_stop,trace:usb_xhci_irq_msi,trace:usb_xhci_irq_msix,trace:usb_xhci_port_reset,trace:msix_write_config,trace:usb_xhci_irq_msix,trace:usb_xhci_irq_msix_use,trace:usb_xhci_irq_msix_unuse,trace:usb_xhci_irq_msi,trace:usb_xhci_*
 qemu_accel=kvm
@@ -29,7 +29,7 @@ QEMU_RTC_CLOCK="clock=host,base=localtime"
 QEMU_SERIAL="file:../serial_opt.txt"
 QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
 
-QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,model=virtio -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel}"
+QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -nic user,model=virtio  -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel}"
 
 QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
 
@@ -42,13 +42,13 @@ if [ $flag_can_run -eq 1 ]; then
       case "$2" in
               uefi) #uefi启动新增ovmf.fd固件
               if [ ${ARCH} == x86_64 ] ;then
-              ${QEMU} -bios arch/x86_64/efi/OVMF-pure-efi.fd ${QEMU_ARGUMENT}
+              sudo ${QEMU} -bios arch/x86_64/efi/OVMF-pure-efi.fd ${QEMU_ARGUMENT}
               elif [ ${ARCH} == i386 ] ;then
-              ${QEMU} -bios arch/i386/efi/OVMF-pure-efi.fd ${QEMU_ARGUMENT}
+              sudo ${QEMU} -bios arch/i386/efi/OVMF-pure-efi.fd ${QEMU_ARGUMENT}
               fi
             ;;
               legacy)
-              ${QEMU} ${QEMU_ARGUMENT}
+              sudo ${QEMU} ${QEMU_ARGUMENT}
               ;;
             esac