1 // SPDX-License-Identifier: GPL-2.0 2 /* Builtin firmware support */ 3 4 #include <linux/firmware.h> 5 #include "../firmware.h" 6 7 /* Only if FW_LOADER=y */ 8 #ifdef CONFIG_FW_LOADER 9 10 struct builtin_fw { 11 char *name; 12 void *data; 13 unsigned long size; 14 }; 15 16 extern struct builtin_fw __start_builtin_fw[]; 17 extern struct builtin_fw __end_builtin_fw[]; 18 19 static bool fw_copy_to_prealloc_buf(struct firmware *fw, 20 void *buf, size_t size) 21 { 22 if (!buf) 23 return true; 24 if (size < fw->size) 25 return false; 26 memcpy(buf, fw->data, fw->size); 27 return true; 28 } 29 30 /** 31 * firmware_request_builtin() - load builtin firmware 32 * @fw: pointer to firmware struct 33 * @name: name of firmware file 34 * 35 * Some use cases in the kernel have a requirement so that no memory allocator 36 * is involved as these calls take place early in boot process. An example is 37 * the x86 CPU microcode loader. In these cases all the caller wants is to see 38 * if the firmware was built-in and if so use it right away. This can be used 39 * for such cases. 40 * 41 * This looks for the firmware in the built-in kernel. Only if the kernel was 42 * built-in with the firmware you are looking for will this return successfully. 43 * 44 * Callers of this API do not need to use release_firmware() as the pointer to 45 * the firmware is expected to be provided locally on the stack of the caller. 46 **/ 47 bool firmware_request_builtin(struct firmware *fw, const char *name) 48 { 49 struct builtin_fw *b_fw; 50 51 if (!fw) 52 return false; 53 54 for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { 55 if (strcmp(name, b_fw->name) == 0) { 56 if (b_fw->size == 0) 57 return false; 58 fw->size = b_fw->size; 59 fw->data = b_fw->data; 60 return true; 61 } 62 } 63 64 return false; 65 } 66 EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, "TEST_FIRMWARE"); 67 68 /** 69 * firmware_request_builtin_buf() - load builtin firmware into optional buffer 70 * @fw: pointer to firmware struct 71 * @name: name of firmware file 72 * @buf: If set this lets you use a pre-allocated buffer so that the built-in 73 * firmware into is copied into. This field can be NULL. It is used by 74 * callers such as request_firmware_into_buf() and 75 * request_partial_firmware_into_buf() 76 * @size: if buf was provided, the max size of the allocated buffer available. 77 * If the built-in firmware does not fit into the pre-allocated @buf this 78 * call will fail. 79 * 80 * This looks for the firmware in the built-in kernel. Only if the kernel was 81 * built-in with the firmware you are looking for will this call possibly 82 * succeed. If you passed a @buf the firmware will be copied into it *iff* the 83 * built-in firmware fits into the pre-allocated buffer size specified in 84 * @size. 85 * 86 * This caller is to be used internally by the firmware_loader only. 87 **/ 88 bool firmware_request_builtin_buf(struct firmware *fw, const char *name, 89 void *buf, size_t size) 90 { 91 if (!firmware_request_builtin(fw, name)) 92 return false; 93 94 return fw_copy_to_prealloc_buf(fw, buf, size); 95 } 96 97 bool firmware_is_builtin(const struct firmware *fw) 98 { 99 struct builtin_fw *b_fw; 100 101 for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) 102 if (fw->data == b_fw->data) 103 return true; 104 105 return false; 106 } 107 108 #endif 109