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

news/2024/12/23 4:26:25/

接前一篇文章: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.ppmy.cn/news/1057065.html

相关文章

PyTorch深度学习实战(13)——可视化神经网络中间层输出

PyTorch深度学习实战&#xff08;13&#xff09;——可视化神经网络中间层输出 0. 前言1. 可视化特征学习的结果2. 可视化第一个卷积层的输出3. 可视化不同网络层的特征图小结系列链接 0. 前言 随着深度学习的快速发展&#xff0c;神经网络已成为解决各种复杂任务的重要工具。…

FinalShell报错:Swap file “.docker-compose.yml.swp“ already exists

FinalShell中编辑docker-compose.yml文件&#xff0c;保存时报错&#xff1a;Swap file ".docker-compose.yml.swp" already exists&#xff1b;报错信息截图如下&#xff1a; 问题原因&#xff1a;有人正在编辑docker-compose.yml文件或者上次编辑没有保存&#xff…

Docker 搭建 LNMP + Wordpress(详细步骤)

目录 一、项目模拟 1. 项目环境 2. 服务器环境 3.任务需求 二、Linux 系统基础镜像 三、Nginx 1. 建立工作目录 2. 编写 Dockerfile 脚本 3. 准备 nginx.conf 配置文件 4. 生成镜像 5. 创建自定义网络 6. 启动镜像容器 7. 验证 nginx 四、Mysql 1.…

Mysql 设置表字段自动赋值创建时间,以及自动更新某一个字段的更新时间

使用场景 一般表设计中记录都有创建时间以及更新时间&#xff0c;而 Mysql 也支持了这种通用的设计需求。 即&#xff1a;可以通过默认值来给时间字段自动赋值&#xff0c;在创建时的默认值就是当前时间也就是记录的创建时间。 记录更新&#xff1a;即某一记录更新时我们要更…

0基础学习VR全景平台篇 第88篇:智慧眼-成员管理

一、功能说明 成员管理&#xff0c;是指管理智慧眼项目的成员&#xff0c;拥有相关权限的人可以进行添加成员、分配成员角色、设置成员分类、修改成员以及删除成员五项操作。但是仅限于管理自己的下级成员&#xff0c;上级成员无权管理。 二、前台操作页面 登录智慧眼后台操…

Qt双击某一文件通过自己实现的程序打开,并加载文件显示

双击启动 简述方法一方法二注意 简述 在Windows系统中&#xff0c;双击某类扩展名的文件&#xff0c;通过自己实现的程序打开文件&#xff0c;并正确加载及显示文件。有两种方式可以到达这个目的。 对于系统不知道的扩展名的文件&#xff0c;第一次打开时&#xff0c;需要自行…

前端面试:【TypeScript】静态类型检查与编译时类型检查

TypeScript是一种由Microsoft开发的编程语言&#xff0c;它在JavaScript的基础上添加了强大的静态类型系统。在本文中&#xff0c;我们将深入探讨TypeScript的静态类型检查和编译时类型检查&#xff0c;以及它们如何提高代码的可靠性和可维护性。 1. 静态类型检查&#xff08;S…

ctfshow-web12

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 国际惯例看一下返回包&#xff0c;是不是有注释 然后做一下测试&#xff0c;看是命令执行还是代码执行 通过phpinfo看到可以执行代码 然后尝试执行命令&#xff0c;无法&#xff0c;发现存在disable_function…