|
@@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
22
|
22
|
#include <string.h>
|
23
|
23
|
#include <errno.h>
|
24
|
24
|
#include <ipxe/efi/efi.h>
|
|
25
|
+#include <ipxe/efi/efi_driver.h>
|
25
|
26
|
#include <ipxe/efi/Protocol/LoadedImage.h>
|
26
|
27
|
#include <ipxe/efi/Protocol/DevicePath.h>
|
27
|
28
|
#include <ipxe/uuid.h>
|
|
@@ -50,6 +51,64 @@ static EFI_GUID efi_loaded_image_device_path_protocol_guid
|
50
|
51
|
/** Event used to signal shutdown */
|
51
|
52
|
static EFI_EVENT efi_shutdown_event;
|
52
|
53
|
|
|
54
|
+/* Forward declarations */
|
|
55
|
+static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle );
|
|
56
|
+
|
|
57
|
+/**
|
|
58
|
+ * Check to see if driver supports a device
|
|
59
|
+ *
|
|
60
|
+ * @v driver EFI driver
|
|
61
|
+ * @v device EFI device
|
|
62
|
+ * @v child Path to child device, if any
|
|
63
|
+ * @ret efirc EFI status code
|
|
64
|
+ */
|
|
65
|
+static EFI_STATUS EFIAPI
|
|
66
|
+efi_image_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
|
67
|
+ EFI_HANDLE device __unused,
|
|
68
|
+ EFI_DEVICE_PATH_PROTOCOL *child __unused ) {
|
|
69
|
+
|
|
70
|
+ return EFI_UNSUPPORTED;
|
|
71
|
+}
|
|
72
|
+
|
|
73
|
+/**
|
|
74
|
+ * Attach driver to device
|
|
75
|
+ *
|
|
76
|
+ * @v driver EFI driver
|
|
77
|
+ * @v device EFI device
|
|
78
|
+ * @v child Path to child device, if any
|
|
79
|
+ * @ret efirc EFI status code
|
|
80
|
+ */
|
|
81
|
+static EFI_STATUS EFIAPI
|
|
82
|
+efi_image_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
|
83
|
+ EFI_HANDLE device __unused,
|
|
84
|
+ EFI_DEVICE_PATH_PROTOCOL *child __unused ) {
|
|
85
|
+
|
|
86
|
+ return EFI_UNSUPPORTED;
|
|
87
|
+}
|
|
88
|
+
|
|
89
|
+/**
|
|
90
|
+ * Detach driver from device
|
|
91
|
+ *
|
|
92
|
+ * @v driver EFI driver
|
|
93
|
+ * @v device EFI device
|
|
94
|
+ * @v pci PCI device
|
|
95
|
+ * @v num_children Number of child devices
|
|
96
|
+ * @v children List of child devices
|
|
97
|
+ * @ret efirc EFI status code
|
|
98
|
+ */
|
|
99
|
+static EFI_STATUS EFIAPI
|
|
100
|
+efi_image_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
|
101
|
+ EFI_HANDLE device __unused, UINTN num_children __unused,
|
|
102
|
+ EFI_HANDLE *children __unused ) {
|
|
103
|
+
|
|
104
|
+ return EFI_UNSUPPORTED;
|
|
105
|
+}
|
|
106
|
+
|
|
107
|
+/** EFI loaded image driver */
|
|
108
|
+static struct efi_driver efi_image_driver =
|
|
109
|
+ EFI_DRIVER_INIT ( NULL, efi_image_supported, efi_image_start,
|
|
110
|
+ efi_image_stop );
|
|
111
|
+
|
53
|
112
|
/**
|
54
|
113
|
* Shut down in preparation for booting an OS.
|
55
|
114
|
*
|
|
@@ -189,5 +248,43 @@ EFI_STATUS efi_init ( EFI_HANDLE image_handle,
|
189
|
248
|
return efirc;
|
190
|
249
|
}
|
191
|
250
|
|
|
251
|
+ /* Install an EFI driver on the image handle, to allow the
|
|
252
|
+ * driver to be subsequently unloaded.
|
|
253
|
+ */
|
|
254
|
+ efi_image_driver.driver.DriverBindingHandle = image_handle;
|
|
255
|
+ if ( ( rc = efi_driver_install ( &efi_image_driver ) ) != 0 ) {
|
|
256
|
+ DBGC ( systab, "EFI could not install loaded image driver: "
|
|
257
|
+ "%s\n", strerror ( rc ) );
|
|
258
|
+ return EFIRC ( rc );
|
|
259
|
+ }
|
|
260
|
+
|
|
261
|
+ /* Install image unload method */
|
|
262
|
+ efi_loaded_image->Unload = efi_unload;
|
|
263
|
+
|
|
264
|
+ return 0;
|
|
265
|
+}
|
|
266
|
+
|
|
267
|
+/**
|
|
268
|
+ * Shut down EFI environment
|
|
269
|
+ *
|
|
270
|
+ * @v image_handle Image handle
|
|
271
|
+ */
|
|
272
|
+static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle __unused ) {
|
|
273
|
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
|
274
|
+ EFI_SYSTEM_TABLE *systab = efi_systab;
|
|
275
|
+
|
|
276
|
+ DBGC ( systab, "EFI image unloading\n" );
|
|
277
|
+
|
|
278
|
+ /* Shut down */
|
|
279
|
+ shutdown_exit();
|
|
280
|
+
|
|
281
|
+ /* Uninstall exit boot services event */
|
|
282
|
+ bs->CloseEvent ( efi_shutdown_event );
|
|
283
|
+
|
|
284
|
+ /* Uninstall loaded image driver */
|
|
285
|
+ efi_driver_uninstall ( &efi_image_driver );
|
|
286
|
+
|
|
287
|
+ DBGC ( systab, "EFI image unloaded\n" );
|
|
288
|
+
|
192
|
289
|
return 0;
|
193
|
290
|
}
|