Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2
3//! Contains structures and functions dedicated to the parsing, building and patching of firmwares
4//! to be loaded into a given execution unit.
5
6use kernel::device;
7use kernel::firmware;
8use kernel::prelude::*;
9use kernel::str::CString;
10
11use crate::gpu;
12use crate::gpu::Chipset;
13
14pub(crate) const FIRMWARE_VERSION: &str = "535.113.01";
15
16/// Structure encapsulating the firmware blobs required for the GPU to operate.
17#[expect(dead_code)]
18pub(crate) struct Firmware {
19 booter_load: firmware::Firmware,
20 booter_unload: firmware::Firmware,
21 bootloader: firmware::Firmware,
22 gsp: firmware::Firmware,
23}
24
25impl Firmware {
26 pub(crate) fn new(dev: &device::Device, chipset: Chipset, ver: &str) -> Result<Firmware> {
27 let mut chip_name = CString::try_from_fmt(fmt!("{}", chipset))?;
28 chip_name.make_ascii_lowercase();
29
30 let request = |name_| {
31 CString::try_from_fmt(fmt!("nvidia/{}/gsp/{}-{}.bin", &*chip_name, name_, ver))
32 .and_then(|path| firmware::Firmware::request(&path, dev))
33 };
34
35 Ok(Firmware {
36 booter_load: request("booter_load")?,
37 booter_unload: request("booter_unload")?,
38 bootloader: request("bootloader")?,
39 gsp: request("gsp")?,
40 })
41 }
42}
43
44pub(crate) struct ModInfoBuilder<const N: usize>(firmware::ModInfoBuilder<N>);
45
46impl<const N: usize> ModInfoBuilder<N> {
47 const fn make_entry_file(self, chipset: &str, fw: &str) -> Self {
48 ModInfoBuilder(
49 self.0
50 .new_entry()
51 .push("nvidia/")
52 .push(chipset)
53 .push("/gsp/")
54 .push(fw)
55 .push("-")
56 .push(FIRMWARE_VERSION)
57 .push(".bin"),
58 )
59 }
60
61 const fn make_entry_chipset(self, chipset: &str) -> Self {
62 self.make_entry_file(chipset, "booter_load")
63 .make_entry_file(chipset, "booter_unload")
64 .make_entry_file(chipset, "bootloader")
65 .make_entry_file(chipset, "gsp")
66 }
67
68 pub(crate) const fn create(
69 module_name: &'static kernel::str::CStr,
70 ) -> firmware::ModInfoBuilder<N> {
71 let mut this = Self(firmware::ModInfoBuilder::new(module_name));
72 let mut i = 0;
73
74 while i < gpu::Chipset::NAMES.len() {
75 this = this.make_entry_chipset(gpu::Chipset::NAMES[i]);
76 i += 1;
77 }
78
79 this.0
80 }
81}