libdrm全解析八 —— 源码全解析(5)

接前一篇文章:libdrm全解析七 —— 源码全解析(4)

本文参考以下博文:

DRM 驱动程序开发(VKMS)

特此致谢!

 本文继续对include/drm/drm.h中实际功能宏定义进行讲解。

7. DRM_IOCTL_GET_STATS

第7个宏是DRM_IOCTL_GET_STATS,相应代码如下:

#define DRM_IOCTL_GET_STATS             DRM_IOR( 0x06, struct drm_stats)

结合之前文章中的_IOR(type,nr,size)的最终定义,得到如下代码:

#define DRM_IOCTL_GET_STATS		( ((2)  << 30) | (('d') << 8) | ((0x06)   << 0) | ((sizeof(struct drm_stats)) << 16) )

struct drm_stats在同文件(include/drm/drm.h)中定义,代码如下:

/** DRM_IOCTL_GET_STATS ioctl argument type.*/
struct drm_stats {unsigned long count;struct {unsigned long value;enum drm_stat_type type;} data[15];
};

drm_stat_type的定义就在上边,代码如下:

enum drm_stat_type {_DRM_STAT_LOCK,_DRM_STAT_OPENS,_DRM_STAT_CLOSES,_DRM_STAT_IOCTLS,_DRM_STAT_LOCKS,_DRM_STAT_UNLOCKS,_DRM_STAT_VALUE,	/**< Generic value */_DRM_STAT_BYTE,		/**< Generic byte counter (1024bytes/K) */个_DRM_STAT_COUNT,	/**< Generic non-byte counter (1000/k) */_DRM_STAT_IRQ,		/**< IRQ */_DRM_STAT_PRIMARY,	/**< Primary DMA bytes */_DRM_STAT_SECONDARY,	/**< Secondary DMA bytes */_DRM_STAT_DMA,		/**< DMA */_DRM_STAT_SPECIAL,	/**< Special DMA (e.g., priority or polled) */_DRM_STAT_MISSED	/**< Missed DMA opportunity *//* Add to the *END* of the list */
};

DRM_IOCTL_GET_STATS对应的Userspace API为:drmGetStats()。该函数也是在xf86drm.c中,代码如下:

drm_public int drmGetStats(int fd, drmStatsT *stats)
{drm_stats_t s;unsigned    i;memclear(s);if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))return -errno;stats->count = 0;memset(stats, 0, sizeof(*stats));if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))return -1;#define SET_VALUE                              \stats->data[i].long_format = "%-20.20s";   \stats->data[i].rate_format = "%8.8s";      \stats->data[i].isvalue     = 1;            \stats->data[i].verbose     = 0#define SET_COUNT                              \stats->data[i].long_format = "%-20.20s";   \stats->data[i].rate_format = "%5.5s";      \stats->data[i].isvalue     = 0;            \stats->data[i].mult_names  = "kgm";        \stats->data[i].mult        = 1000;         \stats->data[i].verbose     = 0#define SET_BYTE                               \stats->data[i].long_format = "%-20.20s";   \stats->data[i].rate_format = "%5.5s";      \stats->data[i].isvalue     = 0;            \stats->data[i].mult_names  = "KGM";        \stats->data[i].mult        = 1024;         \stats->data[i].verbose     = 0stats->count = s.count;for (i = 0; i < s.count; i++) {stats->data[i].value = s.data[i].value;switch (s.data[i].type) {case _DRM_STAT_LOCK:stats->data[i].long_name = "Lock";stats->data[i].rate_name = "Lock";SET_VALUE;break;case _DRM_STAT_OPENS:stats->data[i].long_name = "Opens";stats->data[i].rate_name = "O";SET_COUNT;stats->data[i].verbose   = 1;break;case _DRM_STAT_CLOSES:stats->data[i].long_name = "Closes";stats->data[i].rate_name = "Lock";SET_COUNT;stats->data[i].verbose   = 1;break;case _DRM_STAT_IOCTLS:stats->data[i].long_name = "Ioctls";stats->data[i].rate_name = "Ioc/s";SET_COUNT;break;case _DRM_STAT_LOCKS:stats->data[i].long_name = "Locks";stats->data[i].rate_name = "Lck/s";SET_COUNT;break;case _DRM_STAT_UNLOCKS:stats->data[i].long_name = "Unlocks";stats->data[i].rate_name = "Unl/s";SET_COUNT;break;case _DRM_STAT_IRQ:stats->data[i].long_name = "IRQs";stats->data[i].rate_name = "IRQ/s";SET_COUNT;break;case _DRM_STAT_PRIMARY:stats->data[i].long_name = "Primary Bytes";stats->data[i].rate_name = "PB/s";SET_BYTE;break;case _DRM_STAT_SECONDARY:stats->data[i].long_name = "Secondary Bytes";stats->data[i].rate_name = "SB/s";SET_BYTE;break;case _DRM_STAT_DMA:stats->data[i].long_name = "DMA";stats->data[i].rate_name = "DMA/s";SET_COUNT;break;case _DRM_STAT_SPECIAL:stats->data[i].long_name = "Special DMA";stats->data[i].rate_name = "dma/s";SET_COUNT;break;case _DRM_STAT_MISSED:stats->data[i].long_name = "Miss";stats->data[i].rate_name = "Ms/s";SET_COUNT;break;case _DRM_STAT_VALUE:stats->data[i].long_name = "Value";stats->data[i].rate_name = "Value";SET_VALUE;break;case _DRM_STAT_BYTE:stats->data[i].long_name = "Bytes";stats->data[i].rate_name = "B/s";SET_BYTE;break;case _DRM_STAT_COUNT:default:stats->data[i].long_name = "Count";stats->data[i].rate_name = "Cnt/s";SET_COUNT;break;}}return 0;
}

函数的作用是从中获取各种状态(stat)的相关信息,包括IRQs、DMA、Locks、Unlocks等等。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。

8. DRM_IOCTL_SET_VERSION

第8个宏是DRM_IOCTL_SET_VERSION,相应代码如下:

#define DRM_IOCTL_SET_VERSION		DRM_IOWR(0x07, struct drm_set_version)

结合之前文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:

#define DRM_IOCTL_SET_VERSION		( ((3)  << 30) | (('d') << 8) | ((0x07)   << 0) | ((sizeof(struct drm_set_version)) << 16) )

struct drm_set_version在同文件(include/drm/drm.h)中定义,代码如下:

/** DRM_IOCTL_SET_VERSION ioctl argument type.*/
struct drm_set_version {int drm_di_major;int drm_di_minor;int drm_dd_major;int drm_dd_minor;
};

DRM_IOCTL_SET_VERSION对应的Userspace API为:drmSetInterfaceVersion()。该函数也是在xf86drm.c中,代码如下:

/*** Issue a set-version ioctl.** \param fd file descriptor.* \param drmCommandIndex command index* \param data source pointer of the data to be read and written.* \param size size of the data to be read and written.** \return zero on success, or a negative value on failure.** \internal* It issues a read-write ioctl given by* \code DRM_COMMAND_BASE + drmCommandIndex \endcode.*/
drm_public int drmSetInterfaceVersion(int fd, drmSetVersion *version)
{int retcode = 0;drm_set_version_t sv;memclear(sv);sv.drm_di_major = version->drm_di_major;sv.drm_di_minor = version->drm_di_minor;sv.drm_dd_major = version->drm_dd_major;sv.drm_dd_minor = version->drm_dd_minor;if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {retcode = -errno;}version->drm_di_major = sv.drm_di_major;version->drm_di_minor = sv.drm_di_minor;version->drm_dd_major = sv.drm_dd_major;version->drm_dd_minor = sv.drm_dd_minor;return retcode;
}

函数的作用是设置当前DRM接口的版本号。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。

其余宏定义将在后续文章中继续解析。

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

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

相关文章

HarmonyOS开发第一步,熟知开发工具DevEco Studio

俗话说的好&#xff0c;工欲善其事&#xff0c;必先利其器&#xff0c;走进HarmonyOS第一步&#xff0c;开发工具必须先行&#xff0c;当然了&#xff0c;关于开发工具的使用&#xff0c;官网和其他的博客也有很多的讲解&#xff0c;但是并没有按照常用的功能进行概述&#xff…

C++信息学奥赛2049:【例5.19】字符串判等

这段代码的功能是比较两个输入的字符串是否相等&#xff08;忽略大小写和空格&#xff09;&#xff0c;并输出 “YES” 或 “NO”。 解析注释后的代码如下&#xff1a; #include<bits/stdc.h> using namespace std; int main() {string arr; // 定义字符串变量arr&…

solidity0.8.0的应用案例9:代理合约

代码由OpenZeppelin的Proxy合约简化而来。 代理模式 Solidity合约部署在链上之后,代码是不可变的(immutable)。这样既有优点,也有缺点: 优点:安全,用户知道会发生什么(大部分时候)。坏处:就算合约中存在bug,也不能修改或升级,只能部署新合约。但是新合约的地址与…

Hive 导入csv文件,数据中包含逗号的问题

问题 今天 Hive 导入 csv 文件时&#xff0c;开始时建表语句如下&#xff1a; CREATE TABLE IF NOT EXISTS test.student (name STRING COMMENT 姓名,age STRING COMMENT 年龄,gender STRING COMMENT 性别,other_info STRING COMMENT 其他信息 ) COMMENT 学生信息表 ROW FORM…

T362598 Glaciaxion

Glaciaxion 题目描述 冰封的世界可以看作是 $ n $ 块初始时冷冻的冰川&#xff0c;这些冰川被编号为 1 ∼ n 1 \sim n 1∼n。 探测器抵达后的 $ m $ 秒&#xff0c;每秒都会探测到一块冰川融化。 当一块冰川第一次融化时&#xff0c;探测器返回 N&#xff0c;否则返回 Y。…

Keepalive+LVS群集部署

一、Keepalive概述 keepalived 软件起初是专为 LVS 负载均衡软件设计的&#xff0c;用来管理并监控 LVS集群中各个服务节点的状态&#xff0c;后来又加入了可以实现高可用的 VRRP 功能。因此&#xff0c;keepalived 除了能够管理 LVS集群外&#xff0c;还可以为其他服务&#…

内网安全:WMI协议与SMB协议横向移动

目录 网络拓扑图 网络环境说明 WMI协议 SMB协议 域内信息收集 WMI协议 - 横向移动 利用方式一&#xff1a;wmic命令 利用方式一&#xff1a;cscript 利用方式一&#xff1a;impacket SMB协议 - 横向移动 利用方式一&#xff1a;psexec 利用方式二&#xff1a;psexe…

debian apt error: Package ‘xxx‘ has no installation candidate

新的debian虚拟机可能会出现这个问题。 修改apt的source.list&#xff0c;位于/etc/apt/source.list&#xff0c;添加两行&#xff1a; deb http://deb.debian.org/debian bullseye main deb-src http://deb.debian.org/debian bullseye main执行&#xff1a; sudo apt-get u…

Linux下的Shell编程——正则表达式入门(四)

前言&#xff1a; 正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里&#xff0c;正则表达式通常被用来检索、替换那些符合某个模式的文本。 在Linux 中&#xff0c;grep&#xff0c;sed&#xff0c;awk 等文本处理工具都支持…

Ubuntu inotify

inotify 是一个用于监视文件系统事件的机制。它允许你监视文件或目录的变化,如文件的创建、修改、删除、移动等,以及目录的访问权限变化。 安装 在 Ubuntu 中,你需要安装 inotify-tools 包,这是一个包含 inotifywait 和 inotifywatch 等实用工具的软件包。你可以使用以下命…

golang 协程的实现原理

核心概念 要理解协程的实现, 首先需要了解go中的三个非常重要的概念, 它们分别是G, M和P, 没有看过golang源代码的可能会对它们感到陌生, 这三项是协程最主要的组成部分, 它们在golang的源代码中无处不在. G (goroutine) G是goroutine的头文字, goroutine可以解释为受管理的…

MFC为控件添加背景图片

1、 添加选择Bitmap导入图片&#xff0c;图片文件最好放在项目res目录中&#xff0c;同时是BMP格式。上传后的图片在资源视图&#xff0c;命名为IDB_BITMAP_M_BACK。 2、在cpp的C***Dlg::OnPaint()函数下添加如下代码 void C***Dlg::OnPaint() {CPaintDC dc(this); // device…

科技项目验收检测报告获取有哪些注意事项,作用都有哪些?

验收测试报告 软件从研发到结束是一个很长的周期&#xff0c;对于软件想要完成上市或者是交付到用户手中之前我们还需要进行一次全面检测&#xff0c;也就是科技项目验收测试&#xff0c;此测试有着严格的要求&#xff0c;需要第三方软件测评机构来完成&#xff0c;并出具科技…

软件配置安装(破解)--- maven下载配置

检查环境是否已有 首先检查一下电脑里有无maven环境&#xff0c;有的话就不用安装了 查看path环境中没有maven&#xff0c;开始准备接下来的重头戏 下载maven 下载bin.zip版 解压mavenxxxbin.zip &#xff08;建议把解压的文件放在一个文件夹内&#xff0c;命名英文的env…

spring boot集成mqtt协议发送和订阅数据

maven的pom.xml引入包 <!--mqtt--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId><version>2.3.6.RELEASE</version></dependency><dependency…

Python使用pymysql和sqlalchemy访问MySQL的区别

Python使用pymysql和sqlalchemy访问MySQL的区别 1. 两个数据库连接工具的对比 pymysql和sqlalchemy是两个Python中经常用于与MySQL数据库交互的库。都可以连接MySQL数据库&#xff0c;但它们有明显的区别。 &#xff08;1&#xff09;特点 pymysql是一个Python模块&#xf…

C++,类的特殊函数练习

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream> using namespace std;cla…

无类别域间路由(Classless Inter-Domain Routing, CIDR):理解IP网络和子网划分(传统的IP地址类ABCDE:分类网络)

文章目录 无类别域间路由&#xff08;CIDR&#xff09;&#xff1a;理解IP网络和子网划分引言传统的IP地址类关于“IP地址的浪费” IP地址与CIDRIP地址概述网络号与主机号CIDR记法&#xff08;网络 网络地址/子网掩码&#xff09;网络和广播地址 CIDR的优势减少路由表项缓解IP…

leetcode做题笔记91. 解码方法

一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; A -> "1" B -> "2" ... Z -> "26" 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种方法&#xff…

PDF校对:追求文档的精准与完美

随着数字化时代的到来&#xff0c;PDF已经成为了多数机构和个人首选的文件格式&#xff0c;原因在于它的稳定性、跨平台特性以及统一的显示效果。但是&#xff0c;对于任何需要公开或正式发布的文档&#xff0c;确保其内容的准确性是至关重要的&#xff0c;这就是PDF校对显得尤…