hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/Documentation/driver-api/firmware/fallback-mechanisms.rst
....@@ -42,6 +42,7 @@
4242 supported for request_firmware_into_buf().
4343
4444 * Firmware is not accessible through typical means:
45
+
4546 * It cannot be installed into the root filesystem
4647 * The firmware provides very unique device specific data tailored for
4748 the unit gathered with local information. An example is calibration
....@@ -202,3 +203,106 @@
202203
203204 If you echo 0 into it means MAX_JIFFY_OFFSET will be used. The data type
204205 for the timeout is an int.
206
+
207
+EFI embedded firmware fallback mechanism
208
+========================================
209
+
210
+On some devices the system's EFI code / ROM may contain an embedded copy
211
+of firmware for some of the system's integrated peripheral devices and
212
+the peripheral's Linux device-driver needs to access this firmware.
213
+
214
+Device drivers which need such firmware can use the
215
+firmware_request_platform() function for this, note that this is a
216
+separate fallback mechanism from the other fallback mechanisms and
217
+this does not use the sysfs interface.
218
+
219
+A device driver which needs this can describe the firmware it needs
220
+using an efi_embedded_fw_desc struct:
221
+
222
+.. kernel-doc:: include/linux/efi_embedded_fw.h
223
+ :functions: efi_embedded_fw_desc
224
+
225
+The EFI embedded-fw code works by scanning all EFI_BOOT_SERVICES_CODE memory
226
+segments for an eight byte sequence matching prefix; if the prefix is found it
227
+then does a sha256 over length bytes and if that matches makes a copy of length
228
+bytes and adds that to its list with found firmwares.
229
+
230
+To avoid doing this somewhat expensive scan on all systems, dmi matching is
231
+used. Drivers are expected to export a dmi_system_id array, with each entries'
232
+driver_data pointing to an efi_embedded_fw_desc.
233
+
234
+To register this array with the efi-embedded-fw code, a driver needs to:
235
+
236
+1. Always be builtin to the kernel or store the dmi_system_id array in a
237
+ separate object file which always gets builtin.
238
+
239
+2. Add an extern declaration for the dmi_system_id array to
240
+ include/linux/efi_embedded_fw.h.
241
+
242
+3. Add the dmi_system_id array to the embedded_fw_table in
243
+ drivers/firmware/efi/embedded-firmware.c wrapped in a #ifdef testing that
244
+ the driver is being builtin.
245
+
246
+4. Add "select EFI_EMBEDDED_FIRMWARE if EFI_STUB" to its Kconfig entry.
247
+
248
+The firmware_request_platform() function will always first try to load firmware
249
+with the specified name directly from the disk, so the EFI embedded-fw can
250
+always be overridden by placing a file under /lib/firmware.
251
+
252
+Note that:
253
+
254
+1. The code scanning for EFI embedded-firmware runs near the end
255
+ of start_kernel(), just before calling rest_init(). For normal drivers and
256
+ subsystems using subsys_initcall() to register themselves this does not
257
+ matter. This means that code running earlier cannot use EFI
258
+ embedded-firmware.
259
+
260
+2. At the moment the EFI embedded-fw code assumes that firmwares always start at
261
+ an offset which is a multiple of 8 bytes, if this is not true for your case
262
+ send in a patch to fix this.
263
+
264
+3. At the moment the EFI embedded-fw code only works on x86 because other archs
265
+ free EFI_BOOT_SERVICES_CODE before the EFI embedded-fw code gets a chance to
266
+ scan it.
267
+
268
+4. The current brute-force scanning of EFI_BOOT_SERVICES_CODE is an ad-hoc
269
+ brute-force solution. There has been discussion to use the UEFI Platform
270
+ Initialization (PI) spec's Firmware Volume protocol. This has been rejected
271
+ because the FV Protocol relies on *internal* interfaces of the PI spec, and:
272
+ 1. The PI spec does not define peripheral firmware at all
273
+ 2. The internal interfaces of the PI spec do not guarantee any backward
274
+ compatibility. Any implementation details in FV may be subject to change,
275
+ and may vary system to system. Supporting the FV Protocol would be
276
+ difficult as it is purposely ambiguous.
277
+
278
+Example how to check for and extract embedded firmware
279
+------------------------------------------------------
280
+
281
+To check for, for example Silead touchscreen controller embedded firmware,
282
+do the following:
283
+
284
+1. Boot the system with efi=debug on the kernel commandline
285
+
286
+2. cp /sys/kernel/debug/efi/boot_services_code? to your home dir
287
+
288
+3. Open the boot_services_code? files in a hex-editor, search for the
289
+ magic prefix for Silead firmware: F0 00 00 00 02 00 00 00, this gives you
290
+ the beginning address of the firmware inside the boot_services_code? file.
291
+
292
+4. The firmware has a specific pattern, it starts with a 8 byte page-address,
293
+ typically F0 00 00 00 02 00 00 00 for the first page followed by 32-bit
294
+ word-address + 32-bit value pairs. With the word-address incrementing 4
295
+ bytes (1 word) for each pair until a page is complete. A complete page is
296
+ followed by a new page-address, followed by more word + value pairs. This
297
+ leads to a very distinct pattern. Scroll down until this pattern stops,
298
+ this gives you the end of the firmware inside the boot_services_code? file.
299
+
300
+5. "dd if=boot_services_code? of=firmware bs=1 skip=<begin-addr> count=<len>"
301
+ will extract the firmware for you. Inspect the firmware file in a
302
+ hexeditor to make sure you got the dd parameters correct.
303
+
304
+6. Copy it to /lib/firmware under the expected name to test it.
305
+
306
+7. If the extracted firmware works, you can use the found info to fill an
307
+ efi_embedded_fw_desc struct to describe it, run "sha256sum firmware"
308
+ to get the sha256sum to put in the sha256 field.