xref: /linux/rust/kernel/firmware.rs (revision fdc290ff4ab19c7e0dde36c4cd1e2771b61f6bf5)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Firmware abstraction
4 //!
5 //! C header: [`include/linux/firmware.h`](srctree/include/linux/firmware.h)
6 
7 use crate::{
8     bindings,
9     device::Device,
10     error::to_result,
11     ffi,
12     prelude::*,
13     str::{CStr, CStrExt as _},
14 };
15 use core::ptr::NonNull;
16 
17 /// # Invariants
18 ///
19 /// One of the following: `bindings::request_firmware`, `bindings::firmware_request_nowarn`,
20 /// `bindings::firmware_request_platform`, `bindings::request_firmware_direct`.
21 struct FwFunc(
22     unsafe extern "C" fn(
23         *mut *const bindings::firmware,
24         *const ffi::c_char,
25         *mut bindings::device,
26     ) -> i32,
27 );
28 
29 impl FwFunc {
30     fn request() -> Self {
31         Self(bindings::request_firmware)
32     }
33 
34     fn request_nowarn() -> Self {
35         Self(bindings::firmware_request_nowarn)
36     }
37 }
38 
39 /// Abstraction around a C `struct firmware`.
40 ///
41 /// This is a simple abstraction around the C firmware API. Just like with the C API, firmware can
42 /// be requested. Once requested the abstraction provides direct access to the firmware buffer as
43 /// `&[u8]`. The firmware is released once [`Firmware`] is dropped.
44 ///
45 /// # Invariants
46 ///
47 /// The pointer is valid, and has ownership over the instance of `struct firmware`.
48 ///
49 /// The `Firmware`'s backing buffer is not modified.
50 ///
51 /// # Examples
52 ///
53 /// ```no_run
54 /// # use kernel::{device::Device, firmware::Firmware};
55 ///
56 /// # fn no_run() -> Result<(), Error> {
57 /// # // SAFETY: *NOT* safe, just for the example to get an `ARef<Device>` instance
58 /// # let dev = unsafe { Device::get_device(core::ptr::null_mut()) };
59 ///
60 /// let fw = Firmware::request(c"path/to/firmware.bin", &dev)?;
61 /// let blob = fw.data();
62 ///
63 /// # Ok(())
64 /// # }
65 /// ```
66 pub struct Firmware(NonNull<bindings::firmware>);
67 
68 impl Firmware {
69     fn request_internal(name: &CStr, dev: &Device, func: FwFunc) -> Result<Self> {
70         let mut fw: *mut bindings::firmware = core::ptr::null_mut();
71         let pfw: *mut *mut bindings::firmware = &mut fw;
72         let pfw: *mut *const bindings::firmware = pfw.cast();
73 
74         // SAFETY: `pfw` is a valid pointer to a NULL initialized `bindings::firmware` pointer.
75         // `name` and `dev` are valid as by their type invariants.
76         let ret = unsafe { func.0(pfw, name.as_char_ptr(), dev.as_raw()) };
77         if ret != 0 {
78             return Err(Error::from_errno(ret));
79         }
80 
81         // SAFETY: `func` not bailing out with a non-zero error code, guarantees that `fw` is a
82         // valid pointer to `bindings::firmware`.
83         Ok(Firmware(unsafe { NonNull::new_unchecked(fw) }))
84     }
85 
86     /// Send a firmware request and wait for it. See also `bindings::request_firmware`.
87     pub fn request(name: &CStr, dev: &Device) -> Result<Self> {
88         Self::request_internal(name, dev, FwFunc::request())
89     }
90 
91     /// Send a request for an optional firmware module. See also
92     /// `bindings::firmware_request_nowarn`.
93     pub fn request_nowarn(name: &CStr, dev: &Device) -> Result<Self> {
94         Self::request_internal(name, dev, FwFunc::request_nowarn())
95     }
96 
97     fn as_raw(&self) -> *mut bindings::firmware {
98         self.0.as_ptr()
99     }
100 
101     /// Returns the size of the requested firmware in bytes.
102     pub fn size(&self) -> usize {
103         // SAFETY: `self.as_raw()` is valid by the type invariant.
104         unsafe { (*self.as_raw()).size }
105     }
106 
107     /// Returns the requested firmware as `&[u8]`.
108     pub fn data(&self) -> &[u8] {
109         // SAFETY: `self.as_raw()` is valid by the type invariant. Additionally,
110         // `bindings::firmware` guarantees, if successfully requested, that
111         // `bindings::firmware::data` has a size of `bindings::firmware::size` bytes.
112         unsafe { core::slice::from_raw_parts((*self.as_raw()).data, self.size()) }
113     }
114 }
115 
116 impl Drop for Firmware {
117     fn drop(&mut self) {
118         // SAFETY: `self.as_raw()` is valid by the type invariant.
119         unsafe { bindings::release_firmware(self.as_raw()) };
120     }
121 }
122 
123 /// Load firmware directly into the caller-provided `buf`.
124 ///
125 /// On success the firmware image has been copied into `buf`; the caller accesses the data
126 /// through `buf` itself.
127 ///
128 /// This is intentionally a stand-alone function rather than a `Firmware` constructor. For
129 /// the `into_buf` path, the firmware data lives in the caller's `buf`, not in a
130 /// kernel-owned buffer, so returning a `Firmware` would expose `Firmware::data()` as a
131 /// second handle aliasing `buf` (and `release_firmware()` does not free `buf` anyway).
132 pub fn request_into_buf(name: &CStr, dev: &Device, buf: &mut [u8]) -> Result {
133     // `as_mut_ptr()` on an empty slice returns a non-NULL pointer to
134     // memory which the loader does not own. Passing that pointer with `size == 0`
135     // makes the loader believe that it is buffer it allocated itself, so when
136     // `release_firmware()` is called, it will vfree the pointer and trigger a
137     // bug. Reject empty slices to avoid this situation.
138     if buf.is_empty() {
139         return Err(EINVAL);
140     }
141 
142     let mut fw: *const bindings::firmware = core::ptr::null();
143 
144     // SAFETY: `&raw mut fw` is a valid pointer to a NULL initialized `bindings::firmware` pointer.
145     // `name` and `dev` are valid as by their type invariants. `buf` is a valid writable
146     // buffer of `buf.len()` bytes.
147     to_result(unsafe {
148         bindings::request_firmware_into_buf(
149             &raw mut fw,
150             name.as_char_ptr(),
151             dev.as_raw(),
152             buf.as_mut_ptr().cast(),
153             buf.len(),
154         )
155     })?;
156 
157     // The firmware bytes are now in `buf`, which the caller owns, so we don't need
158     // the kernel to hang on to it any more.
159     // SAFETY: `fw` is a valid pointer returned by `request_firmware_into_buf`.
160     unsafe { bindings::release_firmware(fw) };
161 
162     Ok(())
163 }
164 
165 // SAFETY: `Firmware` only holds a pointer to a C `struct firmware`, which is safe to be used from
166 // any thread.
167 unsafe impl Send for Firmware {}
168 
169 // SAFETY: `Firmware` only holds a pointer to a C `struct firmware`, references to which are safe to
170 // be used from any thread.
171 unsafe impl Sync for Firmware {}
172 
173 /// Create firmware .modinfo entries.
174 ///
175 /// This macro is the counterpart of the C macro `MODULE_FIRMWARE()`, but instead of taking a
176 /// simple string literals, which is already covered by the `firmware` field of
177 /// [`crate::prelude::module!`], it allows the caller to pass a builder type, based on the
178 /// [`ModInfoBuilder`], which can create the firmware modinfo strings in a more flexible way.
179 ///
180 /// Drivers should extend the [`ModInfoBuilder`] with their own driver specific builder type.
181 ///
182 /// The `builder` argument must be a type which implements the following function.
183 ///
184 /// `const fn create(module_name: &'static CStr) -> ModInfoBuilder`
185 ///
186 /// `create` should pass the `module_name` to the [`ModInfoBuilder`] and, with the help of
187 /// it construct the corresponding firmware modinfo.
188 ///
189 /// Typically, such contracts would be enforced by a trait, however traits do not (yet) support
190 /// const functions.
191 ///
192 /// # Examples
193 ///
194 /// ```
195 /// # mod module_firmware_test {
196 /// # use kernel::firmware;
197 /// # use kernel::prelude::*;
198 /// #
199 /// # struct MyModule;
200 /// #
201 /// # impl kernel::Module for MyModule {
202 /// #     fn init(_module: &'static ThisModule) -> Result<Self> {
203 /// #         Ok(Self)
204 /// #     }
205 /// # }
206 /// #
207 /// #
208 /// struct Builder<const N: usize>;
209 ///
210 /// impl<const N: usize> Builder<N> {
211 ///     const DIR: &'static str = "vendor/chip/";
212 ///     const FILES: [&'static str; 3] = [ "foo", "bar", "baz" ];
213 ///
214 ///     const fn create(module_name: &'static kernel::str::CStr) -> firmware::ModInfoBuilder<N> {
215 ///         let mut builder = firmware::ModInfoBuilder::new(module_name);
216 ///
217 ///         let mut i = 0;
218 ///         while i < Self::FILES.len() {
219 ///             builder = builder.new_entry()
220 ///                 .push(Self::DIR)
221 ///                 .push(Self::FILES[i])
222 ///                 .push(".bin");
223 ///
224 ///                 i += 1;
225 ///         }
226 ///
227 ///         builder
228 ///      }
229 /// }
230 ///
231 /// module! {
232 ///    type: MyModule,
233 ///    name: "module_firmware_test",
234 ///    authors: ["Rust for Linux"],
235 ///    description: "module_firmware! test module",
236 ///    license: "GPL",
237 /// }
238 ///
239 /// kernel::module_firmware!(Builder);
240 /// # }
241 /// ```
242 #[macro_export]
243 macro_rules! module_firmware {
244     // The argument is the builder type without the const generic, since it's deferred from within
245     // this macro. Hence, we can neither use `expr` nor `ty`.
246     ($($builder:tt)*) => {
247         const _: () = {
248             const __MODULE_FIRMWARE_PREFIX: &'static $crate::str::CStr = if cfg!(MODULE) {
249                 c""
250             } else {
251                 <LocalModule as $crate::ModuleMetadata>::NAME
252             };
253 
254             #[link_section = ".modinfo"]
255             #[used(compiler)]
256             static __MODULE_FIRMWARE: [u8; $($builder)*::create(__MODULE_FIRMWARE_PREFIX)
257                 .build_length()] = $($builder)*::create(__MODULE_FIRMWARE_PREFIX).build();
258         };
259     };
260 }
261 
262 /// Builder for firmware module info.
263 ///
264 /// [`ModInfoBuilder`] is a helper component to flexibly compose firmware paths strings for the
265 /// .modinfo section in const context.
266 ///
267 /// Therefore the [`ModInfoBuilder`] provides the methods [`ModInfoBuilder::new_entry`] and
268 /// [`ModInfoBuilder::push`], where the latter is used to push path components and the former to
269 /// mark the beginning of a new path string.
270 ///
271 /// [`ModInfoBuilder`] is meant to be used in combination with [`kernel::module_firmware!`].
272 ///
273 /// The const generic `N` as well as the `module_name` parameter of [`ModInfoBuilder::new`] is an
274 /// internal implementation detail and supplied through the above macro.
275 pub struct ModInfoBuilder<const N: usize> {
276     buf: [u8; N],
277     n: usize,
278     module_name: &'static CStr,
279 }
280 
281 impl<const N: usize> ModInfoBuilder<N> {
282     /// Create an empty builder instance.
283     pub const fn new(module_name: &'static CStr) -> Self {
284         Self {
285             buf: [0; N],
286             n: 0,
287             module_name,
288         }
289     }
290 
291     const fn push_internal(mut self, bytes: &[u8]) -> Self {
292         let mut j = 0;
293 
294         if N == 0 {
295             self.n += bytes.len();
296             return self;
297         }
298 
299         while j < bytes.len() {
300             if self.n < N {
301                 self.buf[self.n] = bytes[j];
302             }
303             self.n += 1;
304             j += 1;
305         }
306         self
307     }
308 
309     /// Push an additional path component.
310     ///
311     /// Append path components to the [`ModInfoBuilder`] instance. Paths need to be separated
312     /// with [`ModInfoBuilder::new_entry`].
313     ///
314     /// # Examples
315     ///
316     /// ```
317     /// use kernel::firmware::ModInfoBuilder;
318     ///
319     /// # const DIR: &str = "vendor/chip/";
320     /// # const fn no_run<const N: usize>(builder: ModInfoBuilder<N>) {
321     /// let builder = builder.new_entry()
322     ///     .push(DIR)
323     ///     .push("foo.bin")
324     ///     .new_entry()
325     ///     .push(DIR)
326     ///     .push("bar.bin");
327     /// # }
328     /// ```
329     pub const fn push(self, s: &str) -> Self {
330         // Check whether there has been an initial call to `next_entry()`.
331         if N != 0 && self.n == 0 {
332             crate::build_error!("Must call next_entry() before push().");
333         }
334 
335         self.push_internal(s.as_bytes())
336     }
337 
338     const fn push_module_name(self) -> Self {
339         let mut this = self;
340         let module_name = this.module_name;
341 
342         if !this.module_name.is_empty() {
343             this = this.push_internal(module_name.to_bytes_with_nul());
344 
345             if N != 0 {
346                 // Re-use the space taken by the NULL terminator and swap it with the '.' separator.
347                 this.buf[this.n - 1] = b'.';
348             }
349         }
350 
351         this
352     }
353 
354     /// Prepare the [`ModInfoBuilder`] for the next entry.
355     ///
356     /// This method acts as a separator between module firmware path entries.
357     ///
358     /// Must be called before constructing a new entry with subsequent calls to
359     /// [`ModInfoBuilder::push`].
360     ///
361     /// See [`ModInfoBuilder::push`] for an example.
362     pub const fn new_entry(self) -> Self {
363         self.push_internal(b"\0")
364             .push_module_name()
365             .push_internal(b"firmware=")
366     }
367 
368     /// Build the byte array.
369     pub const fn build(self) -> [u8; N] {
370         // Add the final NULL terminator.
371         let this = self.push_internal(b"\0");
372 
373         if this.n == N {
374             this.buf
375         } else {
376             crate::build_error!("Length mismatch.");
377         }
378     }
379 }
380 
381 impl ModInfoBuilder<0> {
382     /// Return the length of the byte array to build.
383     pub const fn build_length(self) -> usize {
384         // Compensate for the NULL terminator added by `build`.
385         self.n + 1
386     }
387 }
388