================================================涉及的其他类
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. Java实现HTTP文件下载(转)
  2. 跨域问题的前后端解决方案
  3. [费用流]数字配对,新生舞会
  4. JavaScript中有关数据结构和算法的最佳书籍
  5. eclipse远程调试tomcat
  6. bzoj 4129 Haruna’s Breakfast 树上莫队
  7. 最长公共子序列 (nyoj36) [动态规划]
  8. 黑苹果固态硬盘_苹果SSD固态硬盘不完全详解
  9. 嵌入式Linux使用TFT屏幕:使用TinyDRM点亮ST7789V屏幕
  10. 社区版pycharm的django创建app失败问题解决
  11. uni-app 输入框类型
  12. 小米误删userdata分区,userdata分区无法还原,安卓误删分区,且能进twrp,刷机卡米的情况,重新分区教程
  13. P4720 【模板】扩展卢卡斯
  14. 华为手机linux连接网络设置ip地址,华为路由器(Huawei)默认登录IP地址是多少
  15. excel锁定单元格不能修改_EXCEL/WPS如何保护特定的数据不被更改?
  16. Flex一些总结以及遇到的一些面试题
  17. win10之定时关机
  18. Smartbi自定义生成报表-制作流程
  19. 用于通过声波捕获显示视觉,触觉和音频的全息显示(A volumetric display for visual, tactile and audio presentation using acous)
  20. 华为鸿蒙是开源式系统,全面开源!华为自研操作系统鸿蒙正式亮相

热门文章

  1. c语言大学教程答案pdf,C++大学教程(第九版) 保罗·戴特尔(Paul Deitel)等著 完整中文pdf扫描版[197MB]...
  2. 网络安全岗位介绍——等级保护测评师
  3. 读《卧底经济学(珍藏版)》- 专家是一致对外的
  4. vue-cli使用element-ui分页组件
  5. 「分布式专题」分布式事务 就这?太简单了吧
  6. 谷歌提出Flan-T5,一个模型解决所有NLP任务
  7. “融晶保肾调代谢”公益健康大讲堂(第二期)在贵阳强直医院开展
  8. 基于c扩展框架php,深入Php底层,用c为php编写拓展
  9. C++程序避免触发 Win7下的程序兼容助手
  10. 什么是switch语句?