任务列表

任务可能包含以下字段

  • Complexity: 描述所需的 Rust 熟悉程度和/或相应的内核 API 或子系统。 有四种不同的复杂度,BeginnerIntermediateAdvancedExpert

  • Reference: 对其他任务的引用。

  • Link: 外部资源的链接。

  • Contact: 可以联系以获取有关任务更多信息的人员。

启用 (Rust)

与 nova-core 没有直接关系,但却是所需 API 方面的前提条件的任务。

FromPrimitive API

有时需要将数字转换为枚举或结构的值。

nova-core 中的一个很好的例子是 Chipset 枚举类型,它定义了值 AD102。 当探测 GPU 时,可以从某个寄存器中读取值 0x192,指示芯片组 AD102。 因此,应该从数字 0x192 导出枚举值 AD102。 目前,nova-core 使用自定义实现(对于此,使用 Chipset::from_u32)。

相反,最好拥有类似于来自 num crate 的 FromPrimitive 特征 [1]。

拥有这种泛化也有助于实现一个通用宏,该宏自动生成值和数字之间的相应映射。

通用寄存器抽象

研究如何通过通用宏自动生成寄存器常量和结构。

例子

register!(BOOT0, 0x0, u32, pci::Bar<SIZE>, Fields [
   MINOR_REVISION(3:0, RO),
   MAJOR_REVISION(7:4, RO),
   REVISION(7:0, RO), // Virtual register combining major and minor rev.
])

这可以扩展成类似的东西

const BOOT0_OFFSET: usize = 0x00000000;
const BOOT0_MINOR_REVISION_SHIFT: u8 = 0;
const BOOT0_MINOR_REVISION_MASK: u32 = 0x0000000f;
const BOOT0_MAJOR_REVISION_SHIFT: u8 = 4;
const BOOT0_MAJOR_REVISION_MASK: u32 = 0x000000f0;
const BOOT0_REVISION_SHIFT: u8 = BOOT0_MINOR_REVISION_SHIFT;
const BOOT0_REVISION_MASK: u32 = BOOT0_MINOR_REVISION_MASK | BOOT0_MAJOR_REVISION_MASK;

struct Boot0(u32);

impl Boot0 {
   #[inline]
   fn read(bar: &RevocableGuard<'_, pci::Bar<SIZE>>) -> Self {
      Self(bar.readl(BOOT0_OFFSET))
   }

   #[inline]
   fn minor_revision(&self) -> u32 {
      (self.0 & BOOT0_MINOR_REVISION_MASK) >> BOOT0_MINOR_REVISION_SHIFT
   }

   #[inline]
   fn major_revision(&self) -> u32 {
      (self.0 & BOOT0_MAJOR_REVISION_MASK) >> BOOT0_MAJOR_REVISION_SHIFT
   }

   #[inline]
   fn revision(&self) -> u32 {
      (self.0 & BOOT0_REVISION_MASK) >> BOOT0_REVISION_SHIFT
   }
}

用法

let bar = bar.try_access().ok_or(ENXIO)?;

let boot0 = Boot0::read(&bar);
pr_info!("Revision: {}\n", boot0.revision());

注意:一个正在进行中的实现目前位于 drivers/gpu/nova-core/regs/macros.rs 中,并在 nova-core 中使用。 如果能改进它(可能使用 proc 宏)并将其移动到 kernel crate,以便其他组件也可以使用它,那就太好了。

复杂度:高级
联系人:Alexandre Courbot

延迟/睡眠抽象

内核 delay() 和 sleep() 函数的 Rust 抽象。

FUJITA Tomonori 计划处理 read_poll_timeout_atomic()(及其朋友)[1] 的抽象。

IRQ 抽象

IRQ 处理的 Rust 抽象。

Daniel Almeida [1] 正在积极进行 “核心” 抽象以请求 IRQ。

除了可选的审查和测试工作外,还需要研究围绕这些核心抽象的所需的 pci::Device 代码。

复杂度:中级
联系人:Daniel Almeida

外部页面的页面抽象

由 Rust 页面抽象创建的、没有直接所有权的页面的 Rust 抽象。

Abdiel Janulgue [1] 和 Lina [2] 正在积极进行中。

Scatterlist / sg_table 抽象

scatterlist / sg_table 的 Rust 抽象。

Abdiel Janulgue 先前做过一些工作,但尚未发布到邮件列表。

复杂度:中级
联系人:Abdiel Janulgue

ELF 工具

ELF 标头表示的 Rust 实现,用于从 ELF 格式的映像中检索节标头表、名称和数据。

Abdiel Janulgue 先前做过一些工作,但尚未发布到邮件列表。

复杂度:初级
联系人:Abdiel Janulgue

PCI MISC API

通过 SR-IOV、配置空间、功能、MSI API 抽象来扩展现有的 PCI 设备/驱动程序抽象。

复杂度:初级

辅助总线抽象

辅助总线 API 的 Rust 抽象。

这是将 nova-core 连接到 nova-drm 驱动程序所必需的。

复杂度:中级

Debugfs 抽象

debugfs API 的 Rust 抽象。

参考:导出 GSP 日志缓冲区
复杂度:中级

GPU(通用)

解析固件标头

解析从文件系统加载的固件文件中的 ELF 标头。

参考:ELF 工具
复杂度:初级
联系人:Abdiel Janulgue

构建 radix3 页表

构建 radix3 页表以映射固件。

复杂度:中级
联系人:Abdiel Janulgue

vBIOS 支持

解析 vBIOS 并探测驱动程序初始化所需的结构。

联系人:Dave Airlie
参考:Vec 扩展
复杂度:中级

初始 Devinit 支持

实现 BIOS 设备初始化,即内存大小调整、等待、PLL 配置。

联系人:Dave Airlie
复杂度:初级

引导 Falcon 控制器

加载和执行 falcon (sec2) 固件映像的基础架构; 处理 GSP falcon 处理器和 fwsec 加载。

复杂度:高级
联系人:Dave Airlie

GPU 定时器支持

支持 GPU 的内部定时器外设。

复杂度:初级
联系人:Dave Airlie

MMU / PT 管理

研究 MMU / 页表管理的架构。

我们需要考虑 nova-drm 需要相当精细的控制,尤其是在锁定方面,以便能够实现异步 Vulkan 队列。

虽然通常共享相应的代码是可取的,但需要评估共享相应的代码如何(以及是否)是 expedient。

复杂度:专家

VRAM 内存分配器

调查 VRAM 内存分配器的选项。

一些可能的选项
  • Rust 抽象 - RB 树(区间树)/ drm_mm - maple_tree

  • 本机 Rust 集合

复杂度:高级

实例内存

实现对用于存储页表的 instmem (bar2) 的支持。

复杂度:中级
联系人:Dave Airlie

GPU 系统处理器 (GSP)

导出 GSP 日志缓冲区

Timur Tabi [1] 最近的补丁增加了通过 debugfs 公开 GSP-RM 日志缓冲区(即使在未能探测驱动程序之后)的支持。

对于 nova-core 来说,这在早期也是一个有趣的功能。

参考:Debugfs 抽象
复杂度:中级

GSP 固件抽象

GSP-RM 固件 API 不稳定,并且可能在数据结构和语义方面从版本到版本不兼容地更改。

这个问题是使用 Rust 作为 nova-core 的一大动机之一,因为事实证明 Rust 的过程宏功能提供了一种相当优雅的方式来解决这个问题

  1. 从 C 标头在每个版本的单独命名空间中生成 Rust 结构

  2. 构建实现固件接口的抽象结构(在通用命名空间中); 使用版本标识符注释实现中的差异

  3. 使用过程宏从此抽象中生成每个版本的实际实现

  4. 在运行时实例化正确的版本类型(可以确保所有类型都具有相同的接口,因为它由通用特征定义)

在 nova-core PoC 驱动程序的上下文中,存在此模式的 PoC 实现。

此任务旨在改进该功能并最好将其通用化,以便其他驱动程序也可以使用它。

复杂度:专家

GSP 消息队列

实现用于内核驱动程序和 GSP 之间通信的低级别 GSP 消息队列(命令、状态)。

复杂度:高级
联系人:Dave Airlie

引导 GSP

调用引导固件以引导 GSP 处理器; 执行初始控制消息。

复杂度:中级
联系人:Dave Airlie

客户端/设备 API

实现用于客户端/设备分配的 GSP 消息接口以及相应的客户端和设备分配 API。

复杂度:中级
联系人:Dave Airlie

Bar PDE 处理

同步内核驱动程序和 GSP 之间的 BAR 页表处理。

复杂度:初级
联系人:Dave Airlie

FIFO 引擎

实现对 FIFO 引擎的支持,即相应的 GSP 消息接口,并提供用于 chid 分配和通道处理的 API。

复杂度:高级
联系人:Dave Airlie

GR 引擎

实现对图形引擎的支持,即相应的 GSP 消息接口,并提供用于(黄金)上下文创建和提升的 API。

复杂度:高级
联系人:Dave Airlie

CE 引擎

实现对复制引擎的支持,即相应的 GSP 消息接口。

复杂度:中级
联系人:Dave Airlie

VFN IRQ 控制器

支持 VFN 中断控制器。

复杂度:中级
联系人:Dave Airlie

外部 API

nova-core 基本 API

研究连接二级驱动程序(即 vGPU 管理器和 nova-drm)的 API 的常见部分。

复杂度:高级

vGPU 管理器 API

研究 vGPU 管理器所需的、基本 API 未涵盖的 API 部分。

复杂度:高级

nova-core C API

为 vGPU 管理器驱动程序所需的 API 实现一个 C 包装器。

复杂度:中级

测试

CI 管道

调查持续集成测试的选项。

这可以从运行 KUnit 测试到运行(图形)CTS,再到启动(多个)访客虚拟机以测试 VFIO 用例。

还值得考虑引入一个新的测试套件,直接位于 uAPI 之上,以进行更有针对性的测试和调试。 可以选择与 Mesa 项目进行协作/共享代码。

复杂度:高级