1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  For the code moved from cmd/bootefi.c
4  *  Copyright (c) 2016 Alexander Graf
5  */
6 
7 #define LOG_CATEGORY LOGC_EFI
8 
9 #include <bootflow.h>
10 #include <charset.h>
11 #include <dm.h>
12 #include <efi.h>
13 #include <efi_device_path.h>
14 #include <efi_loader.h>
15 #include <env.h>
16 #include <image.h>
17 #include <log.h>
18 #include <malloc.h>
19 #include <mapmem.h>
20 #include <net.h>
21 
22 static struct efi_device_path *bootefi_image_path;
23 static struct efi_device_path *bootefi_device_path;
24 static void *image_addr;
25 static size_t image_size;
26 
27 /**
28  * efi_get_image_parameters() - return image parameters
29  *
30  * @img_addr:		address of loaded image in memory
31  * @img_size:		size of loaded image
32  */
efi_get_image_parameters(void ** img_addr,size_t * img_size)33 void efi_get_image_parameters(void **img_addr, size_t *img_size)
34 {
35 	*img_addr = image_addr;
36 	*img_size = image_size;
37 }
38 
39 /**
40  * efi_clear_bootdev() - clear boot device
41  */
efi_clear_bootdev(void)42 void efi_clear_bootdev(void)
43 {
44 	efi_free_pool(bootefi_device_path);
45 	efi_free_pool(bootefi_image_path);
46 	bootefi_device_path = NULL;
47 	bootefi_image_path = NULL;
48 	image_addr = NULL;
49 	image_size = 0;
50 }
51 
52 /**
53  * calculate_paths() - Calculate the device and image patch from strings
54  *
55  * @dev:		device, e.g. "MMC"
56  * @devnr:		number of the device, e.g. "1:2"
57  * @path:		path to file loaded
58  * @device_pathp:	returns EFI device path
59  * @image_pathp:	returns EFI image path
60  * Return: EFI_SUCCESS on success, else error code
61  */
calculate_paths(const char * dev,const char * devnr,const char * path,struct efi_device_path ** device_pathp,struct efi_device_path ** image_pathp)62 static efi_status_t calculate_paths(const char *dev, const char *devnr,
63 				    const char *path,
64 				    struct efi_device_path **device_pathp,
65 				    struct efi_device_path **image_pathp)
66 {
67 	struct efi_device_path *image, *device;
68 	efi_status_t ret;
69 
70 #if IS_ENABLED(CONFIG_NETDEVICES)
71 	if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) {
72 		ret = efi_net_new_dp(dev, devnr, eth_get_dev());
73 		if (ret != EFI_SUCCESS)
74 			return ret;
75 	}
76 #endif
77 
78 	ret = efi_dp_from_name(dev, devnr, path, &device, &image);
79 	if (ret != EFI_SUCCESS)
80 		return ret;
81 
82 	*device_pathp = device;
83 	if (image) {
84 		/* FIXME: image should not contain device */
85 		struct efi_device_path *image_tmp = image;
86 
87 		efi_dp_split_file_path(image, &device, &image);
88 		efi_free_pool(image_tmp);
89 	}
90 	*image_pathp = image;
91 	log_debug("- boot device %pD\n", device);
92 	if (image)
93 		log_debug("- image %pD\n", image);
94 
95 	return EFI_SUCCESS;
96 }
97 
98 /**
99  * efi_set_bootdev() - set boot device
100  *
101  * This function is called when a file is loaded, e.g. via the 'load' command.
102  * We use the path to this file to inform the UEFI binary about the boot device.
103  *
104  * For a valid image, it sets:
105  *    - image_addr to the provided buffer
106  *    - image_size to the provided buffer_size
107  *    - bootefi_device_path to the EFI device-path
108  *    - bootefi_image_path to the EFI image-path
109  *
110  * @dev:		device, e.g. "MMC"
111  * @devnr:		number of the device, e.g. "1:2"
112  * @path:		path to file loaded
113  * @buffer:		buffer with file loaded
114  * @buffer_size:	size of file loaded
115  */
efi_set_bootdev(const char * dev,const char * devnr,const char * path,void * buffer,size_t buffer_size)116 void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
117 		     void *buffer, size_t buffer_size)
118 {
119 	efi_status_t ret;
120 
121 	log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev,
122 		  devnr, path, buffer, buffer_size);
123 
124 	/* Forget overwritten image */
125 	if (buffer + buffer_size >= image_addr &&
126 	    image_addr + image_size >= buffer)
127 		efi_clear_bootdev();
128 
129 	/* Remember only PE-COFF and FIT images */
130 	if (efi_check_pe(buffer, buffer_size, NULL) != EFI_SUCCESS) {
131 		if (IS_ENABLED(CONFIG_FIT) &&
132 		    !fit_check_format(buffer, IMAGE_SIZE_INVAL)) {
133 			/*
134 			 * FIT images of type EFI_OS are started via command
135 			 * bootm. We should not use their boot device with the
136 			 * bootefi command.
137 			 */
138 			buffer = 0;
139 			buffer_size = 0;
140 		} else {
141 			log_debug("- not remembering image\n");
142 			return;
143 		}
144 	}
145 
146 	/* efi_set_bootdev() is typically called repeatedly, recover memory */
147 	efi_clear_bootdev();
148 
149 	image_addr = buffer;
150 	image_size = buffer_size;
151 
152 	ret = calculate_paths(dev, devnr, path, &bootefi_device_path,
153 			      &bootefi_image_path);
154 	if (ret) {
155 		log_debug("- efi_dp_from_name() failed, err=%lx\n", ret);
156 		efi_clear_bootdev();
157 	}
158 }
159 
160 /**
161  * efi_run_image() - run loaded UEFI image
162  *
163  * @source_buffer:	memory address of the UEFI image
164  * @source_size:	size of the UEFI image
165  * @dp_dev:		EFI device-path
166  * @dp_img:		EFI image-path
167  * Return:		status code
168  */
efi_run_image(void * source_buffer,efi_uintn_t source_size,struct efi_device_path * dp_dev,struct efi_device_path * dp_img)169 static efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size,
170 				  struct efi_device_path *dp_dev,
171 				  struct efi_device_path *dp_img)
172 {
173 	efi_handle_t handle;
174 	struct efi_device_path *msg_path, *file_path;
175 	efi_status_t ret;
176 	u16 *load_options;
177 
178 	file_path = efi_dp_concat(dp_dev, dp_img, 0);
179 	msg_path = dp_img;
180 
181 	log_info("Booting %pD\n", msg_path);
182 
183 	ret = EFI_CALL(efi_load_image(false, efi_root, file_path, source_buffer,
184 				      source_size, &handle));
185 	if (ret != EFI_SUCCESS) {
186 		log_err("Loading image failed\n");
187 		goto out;
188 	}
189 
190 	/* Transfer environment variable as load options */
191 	ret = efi_env_set_load_options(handle, "bootargs", &load_options);
192 	if (ret != EFI_SUCCESS)
193 		goto out;
194 
195 	ret = do_bootefi_exec(handle, load_options);
196 
197 out:
198 
199 	return ret;
200 }
201 
202 /**
203  * efi_binary_run_dp() - run loaded UEFI image
204  *
205  * @image:	memory address of the UEFI image
206  * @size:	size of the UEFI image
207  * @fdt:	device-tree
208  * @initrd:	initrd
209  * @initrd_sz:	initrd size
210  * @dp_dev:	EFI device-path
211  * @dp_img:	EFI image-path
212  *
213  * Execute an EFI binary image loaded at @image.
214  * @size may be zero if the binary is loaded with U-Boot load command.
215  *
216  * Return:	status code
217  */
efi_binary_run_dp(void * image,size_t size,void * fdt,void * initrd,size_t initrd_sz,struct efi_device_path * dp_dev,struct efi_device_path * dp_img)218 static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt,
219 				      void *initrd, size_t initrd_sz,
220 				      struct efi_device_path *dp_dev,
221 				      struct efi_device_path *dp_img)
222 {
223 	efi_status_t ret;
224 
225 	/* Initialize EFI drivers */
226 	ret = efi_init_obj_list();
227 	if (ret != EFI_SUCCESS) {
228 		log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
229 			ret & ~EFI_ERROR_MASK);
230 		return -1;
231 	}
232 
233 	ret = efi_install_fdt(fdt);
234 	if (ret != EFI_SUCCESS)
235 		return ret;
236 
237 	ret = efi_install_initrd(initrd, initrd_sz);
238 	if (ret != EFI_SUCCESS)
239 		return ret;
240 
241 	return efi_run_image(image, size, dp_dev, dp_img);
242 }
243 
244 /**
245  * efi_binary_run() - run loaded UEFI image
246  *
247  * @image:	memory address of the UEFI image
248  * @size:	size of the UEFI image
249  * @fdt:	device-tree
250  * @initrd:	initrd
251  * @initrd_sz:	initrd size
252  *
253  * Execute an EFI binary image loaded at @image.
254  * @size may be zero if the binary is loaded with U-Boot load command.
255  *
256  * Return:	status code
257  */
efi_binary_run(void * image,size_t size,void * fdt,void * initrd,size_t initrd_sz)258 efi_status_t efi_binary_run(void *image, size_t size, void *fdt, void *initrd, size_t initrd_sz)
259 {
260 	efi_handle_t mem_handle = NULL;
261 	struct efi_device_path *file_path = NULL;
262 	efi_status_t ret;
263 
264 	if (!bootefi_device_path || !bootefi_image_path) {
265 		log_debug("Not loaded from disk\n");
266 		/*
267 		 * Special case for efi payload not loaded from disk,
268 		 * such as 'bootefi hello' or for example payload
269 		 * loaded directly into memory via JTAG, etc:
270 		 */
271 		file_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
272 					    (uintptr_t)image, size);
273 		/*
274 		 * Make sure that device for device_path exist
275 		 * in load_image(). Otherwise, shell and grub will fail.
276 		 */
277 		ret = efi_install_multiple_protocol_interfaces(&mem_handle,
278 							       &efi_guid_device_path,
279 							       file_path, NULL);
280 		if (ret != EFI_SUCCESS)
281 			goto out;
282 
283 		bootefi_device_path = file_path;
284 		bootefi_image_path = NULL;
285 	} else {
286 		log_debug("Loaded from disk\n");
287 	}
288 
289 	ret = efi_binary_run_dp(image, size, fdt, initrd, initrd_sz, bootefi_device_path,
290 				bootefi_image_path);
291 out:
292 	if (mem_handle) {
293 		efi_status_t r;
294 
295 		r = efi_uninstall_multiple_protocol_interfaces(mem_handle,
296 					&efi_guid_device_path, file_path, NULL);
297 		if (r != EFI_SUCCESS)
298 			log_err("Uninstalling protocol interfaces failed\n");
299 	}
300 	efi_free_pool(file_path);
301 
302 	return ret;
303 }
304 
305 /**
306  * calc_dev_name() - Calculate the device name to give to EFI
307  *
308  * If not supported, this shows an error.
309  *
310  * Return name, or NULL if not supported
311  */
calc_dev_name(struct bootflow * bflow)312 static const char *calc_dev_name(struct bootflow *bflow)
313 {
314 	const struct udevice *media_dev;
315 
316 	media_dev = dev_get_parent(bflow->dev);
317 
318 	if (!bflow->blk) {
319 		if (device_get_uclass_id(media_dev) == UCLASS_ETH)
320 			return "Net";
321 
322 		log_err("Cannot boot EFI app on media '%s'\n",
323 			dev_get_uclass_name(media_dev));
324 
325 		return NULL;
326 	}
327 
328 	if (device_get_uclass_id(media_dev) == UCLASS_MASS_STORAGE)
329 		return "usb";
330 
331 	return blk_get_uclass_name(device_get_uclass_id(media_dev));
332 }
333 
efi_bootflow_run(struct bootflow * bflow)334 efi_status_t efi_bootflow_run(struct bootflow *bflow)
335 {
336 	struct efi_device_path *device, *image;
337 	const struct udevice *media_dev;
338 	struct blk_desc *desc = NULL;
339 	const char *dev_name;
340 	char devnum_str[9];
341 	efi_status_t ret;
342 	void *fdt;
343 
344 	media_dev = dev_get_parent(bflow->dev);
345 	if (bflow->blk) {
346 		desc = dev_get_uclass_plat(bflow->blk);
347 
348 		snprintf(devnum_str, sizeof(devnum_str), "%x:%x",
349 			 desc ? desc->devnum : dev_seq(media_dev), bflow->part);
350 	} else {
351 		*devnum_str = '\0';
352 	}
353 
354 	dev_name = calc_dev_name(bflow);
355 	log_debug("dev_name '%s' devnum_str '%s' fname '%s' media_dev '%s'\n",
356 		  dev_name, devnum_str, bflow->fname, media_dev->name);
357 	if (!dev_name)
358 		return EFI_UNSUPPORTED;
359 	ret = calculate_paths(dev_name, devnum_str, bflow->fname, &device,
360 			      &image);
361 	if (ret)
362 		return EFI_UNSUPPORTED;
363 
364 	if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) {
365 		log_debug("Booting with built-in fdt\n");
366 		fdt = EFI_FDT_USE_INTERNAL;
367 	} else {
368 		log_debug("Booting with external fdt\n");
369 		fdt = map_sysmem(bflow->fdt_addr, 0);
370 	}
371 	ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, NULL, 0, device, image);
372 
373 	return ret;
374 }
375