1 /*
2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <errno.h>
22 #include <gpxe/efi/efi.h>
23 #include <gpxe/image.h>
24 #include <gpxe/features.h>
25
26 FEATURE ( FEATURE_IMAGE, "EFI", DHCP_EB_FEATURE_EFI, 1 );
27
28 struct image_type efi_image_type __image_type ( PROBE_NORMAL );
29
30 /**
31 * Execute EFI image
32 *
33 * @v image EFI image
34 * @ret rc Return status code
35 */
efi_image_exec(struct image * image)36 static int efi_image_exec ( struct image *image ) {
37 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
38 EFI_HANDLE handle;
39 UINTN exit_data_size;
40 CHAR16 *exit_data;
41 EFI_STATUS efirc;
42
43 /* Attempt loading image */
44 if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, NULL,
45 user_to_virt ( image->data, 0 ),
46 image->len, &handle ) ) != 0 ) {
47 /* Not an EFI image */
48 DBGC ( image, "EFIIMAGE %p could not load: %s\n",
49 image, efi_strerror ( efirc ) );
50 return -ENOEXEC;
51 }
52
53 /* Start the image */
54 if ( ( efirc = bs->StartImage ( handle, &exit_data_size,
55 &exit_data ) ) != 0 ) {
56 DBGC ( image, "EFIIMAGE %p returned with status %s\n",
57 image, efi_strerror ( efirc ) );
58 goto done;
59 }
60
61 done:
62 /* Unload the image. We can't leave it loaded, because we
63 * have no "unload" operation.
64 */
65 bs->UnloadImage ( handle );
66
67 return EFIRC_TO_RC ( efirc );
68 }
69
70 /**
71 * Load EFI image into memory
72 *
73 * @v image EFI file
74 * @ret rc Return status code
75 */
efi_image_load(struct image * image)76 static int efi_image_load ( struct image *image ) {
77 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
78 EFI_HANDLE handle;
79 EFI_STATUS efirc;
80
81 /* Attempt loading image */
82 if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, NULL,
83 user_to_virt ( image->data, 0 ),
84 image->len, &handle ) ) != 0 ) {
85 /* Not an EFI image */
86 DBGC ( image, "EFIIMAGE %p could not load: %s\n",
87 image, efi_strerror ( efirc ) );
88 return -ENOEXEC;
89 }
90
91 /* This is an EFI image */
92 if ( ! image->type )
93 image->type = &efi_image_type;
94
95 /* Unload the image. We can't leave it loaded, because we
96 * have no "unload" operation.
97 */
98 bs->UnloadImage ( handle );
99
100 return 0;
101 }
102
103 /** EFI image type */
104 struct image_type efi_image_type __image_type ( PROBE_NORMAL ) = {
105 .name = "EFI",
106 .load = efi_image_load,
107 .exec = efi_image_exec,
108 };
109