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 fw->size = b_fw->size; 57 fw->data = b_fw->data; 58 return true; 59 } 60 } 61 62 return false; 63 } 64 EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, TEST_FIRMWARE); 65 66 /** 67 * firmware_request_builtin_buf() - load builtin firmware into optional buffer 68 * @fw: pointer to firmware struct 69 * @name: name of firmware file 70 * @buf: If set this lets you use a pre-allocated buffer so that the built-in 71 * firmware into is copied into. This field can be NULL. It is used by 72 * callers such as request_firmware_into_buf() and 73 * request_partial_firmware_into_buf() 74 * @size: if buf was provided, the max size of the allocated buffer available. 75 * If the built-in firmware does not fit into the pre-allocated @buf this 76 * call will fail. 77 * 78 * This looks for the firmware in the built-in kernel. Only if the kernel was 79 * built-in with the firmware you are looking for will this call possibly 80 * succeed. If you passed a @buf the firmware will be copied into it *iff* the 81 * built-in firmware fits into the pre-allocated buffer size specified in 82 * @size. 83 * 84 * This caller is to be used internally by the firmware_loader only. 85 **/ 86 bool firmware_request_builtin_buf(struct firmware *fw, const char *name, 87 void *buf, size_t size) 88 { 89 if (!firmware_request_builtin(fw, name)) 90 return false; 91 92 return fw_copy_to_prealloc_buf(fw, buf, size); 93 } 94 95 bool firmware_is_builtin(const struct firmware *fw) 96 { 97 struct builtin_fw *b_fw; 98 99 for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) 100 if (fw->data == b_fw->data) 101 return true; 102 103 return false; 104 } 105 106 #endif 107