QEMU源码全解析 —— PCI设备模拟(6)

接前一篇文章:

上一回讲到了pci_edu_realize函数中的pci_register_bar函数,本回对于其进行详细解析。

再次贴出pci_register_bar函数源码,在hw/pci/pci.c中,代码如下:

void pci_register_bar(PCIDevice *pci_dev, int region_num,uint8_t type, MemoryRegion *memory)
{PCIIORegion *r;uint32_t addr; /* offset in pci config space */uint64_t wmask;pcibus_t size = memory_region_size(memory);uint8_t hdr_type;assert(!pci_is_vf(pci_dev)); /* VFs must use pcie_sriov_vf_register_bar */assert(region_num >= 0);assert(region_num < PCI_NUM_REGIONS);assert(is_power_of_2(size));/* A PCI bridge device (with Type 1 header) may only have at most 2 BARs */hdr_type =pci_dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;assert(hdr_type != PCI_HEADER_TYPE_BRIDGE || region_num < 2);r = &pci_dev->io_regions[region_num];r->addr = PCI_BAR_UNMAPPED;r->size = size;r->type = type;r->memory = memory;r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO? pci_get_bus(pci_dev)->address_space_io: pci_get_bus(pci_dev)->address_space_mem;wmask = ~(size - 1);if (region_num == PCI_ROM_SLOT) {/* ROM enable bit is writable */wmask |= PCI_ROM_ADDRESS_ENABLE;}addr = pci_bar(pci_dev, region_num);pci_set_long(pci_dev->config + addr, type);if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {pci_set_quad(pci_dev->wmask + addr, wmask);pci_set_quad(pci_dev->cmask + addr, ~0ULL);} else {pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);pci_set_long(pci_dev->cmask + addr, 0xffffffff);}
}

(1)首先根据region_num找到PCIDevice->io_regions数组中对应的项。PCI设备的MMIO存放在PCIIORegion结构体中,结构体中保存了MMIO的地址、大小、类型等信息。

代码片段如下:

    r = &pci_dev->io_regions[region_num];

(2)得到region_num表示的PCIIORegion之后,进行一些初始化设置。

    r->addr = PCI_BAR_UNMAPPED;r->size = size;r->type = type;r->memory = memory;r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO? pci_get_bus(pci_dev)->address_space_io: pci_get_bus(pci_dev)->address_space_mem;

(3)然后将该region的type写到相应PCI配置空间对应BAR的地址处。代码片段如下:

    r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO? pci_get_bus(pci_dev)->address_space_io: pci_get_bus(pci_dev)->address_space_mem;

(4)最后设置PCI Device中wmask和cmask的值。代码片段如下:

    wmask = ~(size - 1);if (region_num == PCI_ROM_SLOT) {/* ROM enable bit is writable */wmask |= PCI_ROM_ADDRESS_ENABLE;}addr = pci_bar(pci_dev, region_num);pci_set_long(pci_dev->config + addr, type);if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {pci_set_quad(pci_dev->wmask + addr, wmask);pci_set_quad(pci_dev->cmask + addr, ~0ULL);} else {pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);pci_set_long(pci_dev->cmask + addr, 0xffffffff);}

操作系统与PCI设备交互的主要方式是PIO和MMIO。MMIO虽然是一段内存,但是其没有EPT映射,在虚拟机访问设备的MMIO时,会产生VM Exit;KVM识别此MMIO访问并且将该访问分派到应用层QEMU中;QEMU根据内存虚拟化的步骤进行分派,找到设备注册的MMIO读写回调函数;设备的MMIO读写回调函数根据设备的功能进行模拟,完成模拟之后可能会发送中断到虚拟机中,从而完成一些MMIO访问。

下一回将开始解析edu设备的MMIO读写函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/617403.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Java中正确使用Optional

Optional类是在Java 8中引入的&#xff0c;用于解决NullPointerException的问题。 java.util.Optional类是一个泛型类型的类&#xff0c;只包含一个类型为T的值。其目的是提供对可能为null的类型T的引用对象的更安全的替代方案。但是&#xff0c;只有在正确使用的情况下&#…

HarmonyOS开发FA应用模型下多个页面的声明方式

目录 方式1 方式2 HarmonyOS配套的IDE是DevEco Studio&#xff0c;目前的版本是3.1。官网可以直接下载 HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 ​ 方式1 ​在DevEco Studio如果是在pages目录通过右键New->ArkTS File生成的文件&#xff0c;需要注意&…

Android 13(T) - Media框架(3)- mediaserver

上一节我们了解到android_media_MediaPlayer.cpp中封装的是MediaPlayer native实现&#xff0c;这一节我们就来了解它的内部实现。 1、MediaPlayer MediaPlayer native代码位于frameworks/av/media/libmedia/mediaplayer.cpp 先来看MediaPlayer的声明&#xff0c;它继承于BnM…

鸿蒙原生应用再添新丁!天眼查 入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;天眼查 入局鸿蒙 来自 HarmonyOS 微博1月12日消息&#xff0c;#天眼查启动鸿蒙原生应用开发#作为累计用户数超6亿的头部商业信息查询平台&#xff0c;天眼查可以为商家企业&#xff0c;职场人士以及普通消费者等用户便捷和安全地提供查询海量…

Vue高级

一 ref属性 被用来给元素或子组件注册引用信息&#xff08;id的替代者&#xff09; 应用在html标签上获取的是真实DOM元素&#xff0c;应用在组件标签上是组件实例对象&#xff08;vc&#xff09; 使用方式&#xff1a; 打标识&#xff1a; ...... 或 获取&#xff1a;this.…

ubuntu安装mysql(tar.xz)

1&#xff1a;下载地址 MySQL &#xff1a;&#xff1a; 下载 MySQL 社区服务器 2&#xff1a;上传文件到服务器 3:解压 mkdir mysqlmv mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz /mysqlcd /mysqltar -xvf mysql-8.0.13-linux-glibc2.12-x86_64.tar.xzmv /mysql/mysql-8.…

【Spring类路径Bean定义信息扫描】

Spring类路径Bean定义信息扫描 1. ClassPathBeanDefinitionScanner作用2. 类声明3. 属性4. 构造器5. 扫描方法6. 真正扫描方法7. postProcessBeanDefinition8. 注册bean定义 1. ClassPathBeanDefinitionScanner作用 扫描类路径下的类注册为bean定义。2. 类声明 public class …

后端获取来访url

先说一下&#xff1a;后端是没有办法获取前端来访路径的&#xff1a;a.com访问到b.com&#xff0c;你的程序是b.com&#xff0c;你想获取a.com这个路径&#xff0c;在java后端是获取不到的&#xff0c;反正我网上搜了好久&#xff0c;用了好多种方法都没有获取到&#xff0c;如…

【期末不挂科-C++考前速过系列P3】大二C++第3次过程考核(20道选择题&12道判断题&2道代码题)【解析,注释】

前言 大家好吖&#xff0c;欢迎来到 YY 滴C考前速过系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《…

行为型设计模式——状态模式

状态模式 状态模式是比较简单的设计模式&#xff0c;它的主要作用是减少代码中大量的 if-else 或者 switch-case 等逻辑判断&#xff08;俗称屎山&#xff09;。它将每个状态定义为一个类&#xff0c;而每个状态类有自己对应的方法&#xff0c;因此当需要根据状态执行逻辑代码…

开源Bluespec bsc编译器和可重用示例设计

这篇介绍Bluespec以及设计示例的文章&#xff0c;是在2021年ICCAD&#xff08;International Conference On Computer-Aided Design&#xff09;发布的论文。达坦科技的open-rdma项目和推广的MIT体系结构学习社区都用到Bluespec&#xff0c;因此将此论文翻译成中文&#xff0c;…

app跳转小程序免登录

app跳转小程序二次登录&#xff1a; app跳转小程序&#xff0c;第一种做法是 点击 app 页面 --> 跳转到对应小程序的路径 --> 登录小程序 --> 使用功能。这种做法&#xff0c;在 app跳转小程序后&#xff0c;需要二次登录&#xff0c;用户体验不是很好。 app跳转小…

【JVM】垃圾回收 GC

一、前言 垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;是由 Java 虚拟机&#xff08;JVM&#xff09;垃圾回收器提供的一种对内存回收的一种机制&#xff0c;它一般会在内存空闲或者内存占用过高的时候对那些没有任何引用的对象不定时地进行回收。以避免…

C#进阶-IIS服务器发布ASP.NET项目

对于云服务器&#xff0c;程序员一般不会陌生&#xff0c;如果项目需要发布到现网&#xff0c;那么服务器是必不可缺的一项硬性条件&#xff0c;那么如何在云服务器上部署一个项目&#xff0c;需要做哪些配置准备&#xff0c;下面就由本文档为大家讲解&#xff0c;本篇以 IIS服…

封装数据访问通用类DbHelper

为什么要封装通用类&#xff1f; 数据交互&#xff1a;增上改查 相同的事情&#xff1a;连接 T-SQL命令&#xff0c;Command 执行命令&#xff0c;选择执行方式 得到相应结果 关闭连接 将一些从重复的逻辑进行封装&#xff0c;达到通用的目的 提高复用率…

WPF Converter转换器

在 WPF 中&#xff0c;Converter 通常用于在数据绑定过程中执行值的转换。你可以创建自定义的 Converter 类来实现数据的转换逻辑&#xff0c;然后在 XAML 中使用这个转换器。 创建一个继承自 ValueConverter接口的转换器类&#xff0c;实现 Convert 和 ConvertBack 方法。 /…

AUTOSAR从入门到精通-Autosar 中断机制(五)

目录 知识储备 OS嵌入式操作系统-任务Tasks 4.1 Scheduling 调度 4.2 Basic and Extended Tasks 基本和扩展任务

[redis] redis高可用之持久化

一、Redis 高可用的相关知识 1.1 什么是高可用 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;…

windows环境下使用CLion+MinGW配置fltk开发环境

操作系统&#xff1a;windows 10 CLion版本&#xff1a;2023.3.1 使用CLion Bundled MinGW Version&#xff1a;11.0 w64 CMake version&#xff1a;3.27.0 G version&#xff1a;13.1.0 1 编译fltk静态库 这里使用的fltk版本为1.4.0。 下载到fltk源码后&#xff0c;通过命令…

kylinV10-SP1 安装 QT 5.12

kylinV10-SP1 安装 QT 1. 安装前的准备 1.1 判断 gcc 是否安装 gcc -v # 没有安装的话就安装 gcc sudo apt install gcc1.2 判断 g 是否安装 g -v # 没有安装的话就安装 g sudo apt install g1.3 判断 clang 是否安装 clang -v # 没有安装的话就安装 clang sudo apt insta…