================================================涉及的其他类
class PciDevice
PCI设备基类,存储pci设备状态,提供ReadBar、WriteBar虚接口函数。
ReadConfig
    ReadConfigWord //读配置空间寄存器
WriteConfig //写配置寄存器空间
Interrupt //如果有pci pending中断则调用pcibus的中断处理
    bus_->Interrupt
set_capabilities
SetupBarTraps
    guest->CreateMapping //将bar的地址空间加入到guest的IoMappingList中,并设置访问trap为ZX_GUEST_TRAP_MEM(陷出).同时设置IoHandler为PciBar(实现Read和Write函数)
ReadConfigWord //从pci配置空间读取4字节对齐的值
ReadCapability
FindCapability

class PciBus
继承自PlatformDevice,成员变量包含:guest_(虚拟机)、config_addr_(pci配置空间)、device_(包含的pcidevice)、interrupt_controller_(中断控制器)、mmio_base_(mmio基地址)等
Interrupt
    interrupt_controller_->Interrupt //调用中断控制器的中断处理(arm64为gic distributer)
ConfigureDtb //判断dtb中是否与pci-host-ecam-generic兼容的配置

class VirtioPci
VirtioPci //利用传入的VirtioDeviceConfig对象,初始化device_config_成员和父类的Attributes成员
ReadBar //只处理BAR0;
    ConfigBarRead
WriteBar
    ConfigBarWrite //BAR0,pcibar
    NotifyBarWrite //BAR1,notifybar
        device_config_->notify_queue //貌似virtionet中直接返回ZX_OK
add_isr_flags //Sets the given flags in the ISR register
// ISR flag values.
enum IsrFlags : uint8_t {
    // Interrupt is caused by a queue.
    ISR_QUEUE = 1 << 0,
    // Interrupt is caused by a device config change.
    ISR_CONFIG = 1 << 1,
};
ConfigBarRead
    CommonCfgRead //通用配置读取
    value->u8 = isr_status_;//中断状态配置
    kVirtioPciDeviceCfgBase//Device-specific configuration
ConfigBarWrite //对common cfg和device specific cfg进行写配置
CommonCfgRead //通用配置读取,偏移从0x0~0x34
CommonCfgWrite
NotifyBarWrite
SetupCaps
queue_sel

struct VirtioDeviceConfig {
  mutable std::mutex mutex;

// Virtio device ID.
  const uint16_t device_id = 0;

// Virtio device features.
  const uint32_t device_features = 0;

// Pointer to device configuration.
  void* config __TA_GUARDED(mutex) = nullptr;

// Number of bytes used for this device's configuration space.
  const uint64_t config_size = 0;

// Virtio queues for this device.
  VirtioQueueConfig* const queue_configs __TA_GUARDED(mutex) = nullptr;

// Number of Virtio queues.
  const uint16_t num_queues = 0;

// Invoked when the driver has made a change to the queue configuration.
  using ConfigQueueFn =
      fit::function<zx_status_t(uint16_t queue, uint16_t size, zx_gpaddr_t desc,
                                zx_gpaddr_t avail, zx_gpaddr_t used)>;
  const ConfigQueueFn config_queue;

// Invoked when the driver sends notifications on a queue to the device.
  using NotifyQueueFn = fit::function<zx_status_t(uint16_t queue)>;
  const NotifyQueueFn notify_queue;

// Invoked when the driver has made a change to the device configuration.
  using ConfigDeviceFn =
      fit::function<zx_status_t(uint64_t addr, const IoValue& value)>;
  const ConfigDeviceFn config_device;

// Invoked when the driver has accepted features and set the device into a
  // 'Ready' state.
  using ReadyDeviceFn =
      fit::function<zx_status_t(uint32_t negotiated_features)>;
  const ReadyDeviceFn ready_device;
};

static constexpr uint16_t kDefaultVirtioQueueSize = 128;
struct VirtioQueueConfig
{
  union {
    struct {
      uint64_t desc;
      uint64_t avail;
      uint64_t used;
    };

// Software will access these using 32 bit operations. Provide a
    // convenience interface for these use cases.
    uint32_t words[6] = {};
  };

uint16_t size = kDefaultVirtioQueueSize;
}

===========
class VirtioQueue
VirtioQueue::VirtioQueue //创建event_对象
VirtioQueue::Configure //配置ring的size、描述符表、可用ring和已用ring。used_event_addr指向可用ring的后面2字节;avail_event_addr指向已用ring的后面2个字节(event是怎么分配的?与used ring和available ring正好相反!?)
VirtioQueue::NextChain //根据”可用ring项“构造VirtioChain对象返回
VirtioQueue::NextAvailLocked //获取下一个可用ring索引;更新avail_event(什么时候用??);如果没有可用ring,则调用event_.signal(SIGNAL_QUEUE_AVAIL, 0)发送ZX_USER_SIGNAL_0的清除信号(原型:signal(uint32_t clear_mask, uint32_t set_mask))
VirtioQueue::Notify //有可用ring时,调用event_.signal(0, SIGNAL_QUEUE_AVAIL)(通知前端?)
VirtioQueue::ReadDesc //取出guest的desc地址,映射到本地
VirtioQueue::Return //将index和len填入used ring,更新idx+1;如果use_event_index_为0,且ring_.used->flags为0则注入中断,否则如果ring_.used_event有值,且used->idx和used_event值相等则注入中断。

class VirtioChain
VirtioChain::NextDescriptor //调用VirtioQueue的ReadDesc
VirtioChain::Return //调用VirtioQueue的Return

struct VirtioDescriptor:virtio描述符结构体,包含了vring_desc的信息和更高层次的抽象。
// A higher-level API for vring_desc.
struct VirtioDescriptor {
  // Pointer to the buffer in our address space.
  void* addr;
  // Number of bytes at addr.
  uint32_t len;
  // Only valid if has_next is true.
  // TODO(abdulla): Remove this.
  uint16_t next;
  // Is there another buffer after this one?
  // TODO(abdulla): Remove this.
  bool has_next;
  // If true, this buffer must only be written to (no reads). Otherwise this
  // buffer must only be read from (no writes).
  bool writable;
};

struct VirtioRing:包含vring的抽象
// Stores the Virtio queue based on the ring provided by the guest.
// NOTE(abdulla): This structure points to guest-controlled memory.
struct VirtioRing {
  // Number of entries in the descriptor table.
  uint16_t size;
  uint16_t index; //指示当前处理的desc的idx

const struct vring_desc* desc;  // guest-controlled

const struct vring_avail* avail;  // guest-controlled
  const uint16_t* used_event;       // guest-controlled

struct vring_used* used;  // guest-controlled
  uint16_t* avail_event;    // guest-controlled
};

========vring(虚拟队列)
每个虚拟队列由3部分组成:
1.描述符表
2.可用环
3.已用环
说明:描述符表只有一个,但是可以由多个描述符指向的buffer构成一个list(或者叫chain),而这个list可以从描述符表任意一个desc作为head开始(目前实现中list长度为1,并没利用起来)。
struct vring {
    uint32_t num;
    uint32_t num_mask;

uint16_t free_list; /* head of a free list of descriptors per ring. 0xffff is NULL */
    uint16_t free_count;

uint16_t last_used;

struct vring_desc* desc;

struct vring_avail* avail;

struct vring_used* used;
};

/* This marks a buffer as continuing via the next field. */
#define VRING_DESC_F_NEXT 1
/* This marks a buffer as write-only (otherwise read-only). */
#define VRING_DESC_F_WRITE 2
/* This means the buffer contains a list of buffer descriptors. */
#define VRING_DESC_F_INDIRECT 4
/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
struct vring_desc {
    /* Address (guest-physical). */
    uint64_t addr;
    /* Length. */
    uint32_t len;
    /* The flags as indicated above. */
    uint16_t flags;
    /* We chain unused descriptors via this, too */
    uint16_t next;
};

struct vring_avail {
    uint16_t flags;
    uint16_t idx;
    uint16_t ring[];
};

/* u32 is used here for ids for padding reasons. */
struct vring_used_elem {
    /* Index of start of used descriptor chain. */
    uint32_t id;
    /* Total length of the descriptor chain which was used (written to) */
    uint32_t len;
};
struct vring_used {
    uint16_t flags;
    uint16_t idx;
    struct vring_used_elem ring[];
};

fuchsia中virtio 后端实现相关推荐

  1. virtio后端驱动详解

    virtIO是一种半虚拟化驱动,广泛用于在XEN平台和KVM虚拟化平台,用于提高客户机IO的效率,事实证明,virtIO极大的提高了VM IO 效率,配备virtIO前后端驱动的情况下,客户机IO效率 ...

  2. KVM中Virtio网络的演化之路

    作为一个开放的标准接口,virtio一直在云计算与虚拟化中扮演着重要的角色.而virtio网络接口,作为virtio标准支持下最复杂的接口之一,在虚拟机/容器网络加速.混合云加速中一直扮演着重要角色. ...

  3. VIRTIO后端框架QEMU与VHOST分析

    VIRTIO设备的前端是GUEST的内核驱动,后端由QEMU或者DPU实现.不论是原来的QEMU-VIRTIO框架还是现在的DPU,VIRTIO的控制面和数据面都是相对独立的设计.本文主要针对QEMU ...

  4. cucumber测试_如何在Cucumber中进行后端测试

    cucumber测试 Cucumber是一种规范语言的执行框架. 它并不是要成为测试语言,而是用于创建测试自动化. Cucumber最适合出现一些实际参与者互动并取得某种成果的情况. 当可以从用户的角 ...

  5. 如何在黄瓜中进行后端测试

    黄瓜是一种规范语言的执行框架. 它并不是要成为测试语言,而是用于创建测试自动化. 黄瓜最适合出现一些现实世界中的参与者互动并取得某种成果的情况. 当可以从用户的角度编写它时,它特别有用. Given ...

  6. 交通外场及内场设备 前端中端后端设备

    最近,做了一些横向,对于实际工程中的交通行业有了更深的认识,项目主要是做智慧交通的可研.其中便涉及很多很多的智慧交通设施设备,在此记录一些常用的叫法. 1.交通外场及内场设备 与城市智能交通相关的设施 ...

  7. 7nm工艺中的后端设计挑战

    最近开始做一个7nm的项目,发现对于后端来说,有一些东西和之前的工艺有些不同,因此希望借此机会和大家分享一下. 目前虽然号称拥有或将要研发7nm工艺的有多家工艺厂商,但是具有实际流片能力的可能只有TS ...

  8. SLAM | 视觉SLAM中的后端:后端优化算法与建图模板

    点击上方"AI算法修炼营",选择加星标或"置顶" 标题以下,全是干货 前面的话 前面系列一中我们介绍了,VSLAM 是利用多视图几何理论,根据相机拍摄的图像信息 ...

  9. 游戏开发学习记录01-关于在Unity开发的游戏中部署后端云的选择

    目前我还是一名在校学生,而且现在还没有学习数据库方面的知识,所以目前我不具备后端搭建服务器和数据库的知识.所以在之前学习安卓开发过程中,了解到了现在有一种服务-后端云,可以不用费时的去完成后端的开发, ...

最新文章

  1. 噩耗...............
  2. 从古希腊神话说起,讲讲英语里的偏旁部首
  3. php 网站速度慢,php – 个人用户网站速度慢,但他们可以切换浏览器?
  4. NIO核心之Channel,Buffer和Selector简介
  5. 云南大学网络课程作业计算机,云南大学842计算机程序设计考研复习经验
  6. ERROR: Could not read unit serial number!
  7. Win32 一个helloworld对话框
  8. 数据科学 IPython 笔记本 8.10 自定义颜色条
  9. 计算机中汉字的顺序用什么牌,最常用汉字频率排序
  10. 迈信EP100伺服驱动器方案
  11. 移动硬盘显示拒绝访问文件怎样找到
  12. AID数据集的均值和方差
  13. 职通未来 The Next One——赴一场不一样的招聘会
  14. 腾讯云乐固客户端加固打包上线流程
  15. 3D游戏-作业三-空间与运动
  16. 微信公众平台-服务号:网页授权域名 设置
  17. IntelliJ IDEA设置类注释和方法注释模板
  18. 建立与输出一元多项式
  19. node python做游戏服务哪个适合做服务端_当前的几种开源游戏服务端介绍
  20. 图说大型网站的技术架构

热门文章

  1. redis之python(二):zadd命令出现错误:AttributeError: 'str' object has no attribute 'iteritems'
  2. 刷脸支付帮商户降低人力成本引流圈客
  3. js+html+css+jQuery实现简单购物车
  4. [开发工具] STM32算法的翅膀之MATLAB
  5. [WARNING]:登录失败:密码错误或账号被冻结
  6. win10更新失败 无法安装 Windows,因为这台电脑的磁盘布局不受UEFI固件支持
  7. UEFI.源码分析.DXE阶段的执行
  8. 划分数,分苹果问题·计算机算法·动态规划·C/C++
  9. 制作京东快报页面html,京东快报.html
  10. 牛逼的Android UI