diff --git a/arch/efi/Kconfig b/arch/efi/Kconfig index 01301c0..561aac2 100644 --- a/arch/efi/Kconfig +++ b/arch/efi/Kconfig @@ -4,6 +4,7 @@ select HAS_DEBUG_LL select HAS_KALLSYMS select EFI_GUID + select EFI_BOOTUP select EFI_DEVICEPATH select PRINTF_UUID select GENERIC_FIND_NEXT_BIT diff --git a/arch/efi/efi/Makefile b/arch/efi/efi/Makefile index 51db60b..ef19969 100644 --- a/arch/efi/efi/Makefile +++ b/arch/efi/efi/Makefile @@ -1,4 +1,3 @@ obj-y += efi.o -obj-y += efi-device.o obj-y += efi-image.o bbenv-y += env-efi diff --git a/arch/efi/efi/efi-device.c b/arch/efi/efi/efi-device.c deleted file mode 100644 index 678a283..0000000 --- a/arch/efi/efi/efi-device.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * efi-device.c - barebox EFI payload support - * - * Copyright (c) 2014 Sascha Hauer , Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int efi_locate_handle(enum efi_locate_search_type search_type, - efi_guid_t *protocol, - void *search_key, - unsigned long *no_handles, - efi_handle_t **buffer) -{ - efi_status_t efiret; - unsigned long buffer_size = 0; - efi_handle_t *buf; - - efiret = BS->locate_handle(search_type, protocol, search_key, &buffer_size, - NULL); - if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) - return -efi_errno(efiret); - - buf = malloc(buffer_size); - if (!buf) - return -ENOMEM; - - efiret = BS->locate_handle(search_type, protocol, search_key, &buffer_size, - buf); - if (EFI_ERROR(efiret)) { - free(buf); - return -efi_errno(efiret); - } - - *no_handles = buffer_size / sizeof(efi_handle_t); - *buffer = buf; - - return 0; -} - -static struct efi_device *efi_find_device(efi_handle_t *handle) -{ - struct device_d *dev; - struct efi_device *efidev; - - bus_for_each_device(&efi_bus, dev) { - efidev = container_of(dev, struct efi_device, dev); - - if (efidev->handle == handle) - return efidev; - } - - return NULL; -} - -static void efi_devinfo(struct device_d *dev) -{ - struct efi_device *efidev = to_efi_device(dev); - int i; - - printf("Protocols:\n"); - - for (i = 0; i < efidev->num_guids; i++) - printf(" %d: %pUl: %s\n", i, &efidev->guids[i], - efi_guid_string(&efidev->guids[i])); -} - -static efi_handle_t *efi_find_parent(efi_handle_t *handle) -{ - unsigned long handle_count = 0; - efi_handle_t *handles = NULL, *parent; - unsigned long num_guids; - efi_guid_t **guids; - int ret, i, j, k; - efi_status_t efiret; - struct efi_open_protocol_information_entry *entry_buffer; - unsigned long entry_count; - - ret = efi_locate_handle(all_handles, NULL, NULL, &handle_count, &handles); - if (ret) - return NULL; - - /* - * Normally one would expect a function/pointer to retrieve the parent. - * With EFI we have to: - * - get all handles - * - for each handle get the registered protocols - * - for each protocol get the users - * - the user which matches the input handle is the parent - */ - for (i = 0; i < handle_count; i++) { - efiret = BS->open_protocol(handles[i], &efi_device_path_protocol_guid, - NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); - if (EFI_ERROR(efiret)) - continue; - - BS->protocols_per_handle(handles[i], &guids, &num_guids); - for (j = 0; j < num_guids; j++) { - efiret = BS->open_protocol_information(handles[i], guids[j], - &entry_buffer, &entry_count); - for (k = 0; k < entry_count; k++) { - if (entry_buffer[k].controller_handle == NULL) - continue; - if (entry_buffer[k].controller_handle == handles[i]) - continue; - if (entry_buffer[k].controller_handle == handle) { - parent = handles[i]; - goto out; - } - } - } - } - - parent = NULL; - - free(handles); -out: - return parent; -} - -static struct efi_device *efi_add_device(efi_handle_t *handle, efi_guid_t **guids, - int num_guids) -{ - struct efi_device *efidev; - int i; - efi_guid_t *guidarr; - efi_status_t efiret; - void *devpath; - - efidev = efi_find_device(handle); - if (efidev) - return ERR_PTR(-EEXIST); - - efiret = BS->open_protocol(handle, &efi_device_path_protocol_guid, - NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); - if (EFI_ERROR(efiret)) - return ERR_PTR(-EINVAL); - - guidarr = malloc(sizeof(efi_guid_t) * num_guids); - - for (i = 0; i < num_guids; i++) - memcpy(&guidarr[i], guids[i], sizeof(efi_guid_t)); - - efiret = BS->open_protocol(handle, &efi_device_path_protocol_guid, - &devpath, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (EFI_ERROR(efiret)) { - free(guidarr); - return ERR_PTR(-EINVAL); - } - - efidev = xzalloc(sizeof(*efidev)); - - efidev->guids = guidarr; - efidev->num_guids = num_guids; - efidev->handle = handle; - efidev->dev.bus = &efi_bus; - efidev->dev.id = DEVICE_ID_SINGLE; - efidev->dev.info = efi_devinfo; - efidev->devpath = devpath; - - BS->handle_protocol(handle, &guidarr[0], &efidev->protocol); - - sprintf(efidev->dev.name, "handle-%p", handle); - - efidev->parent_handle = efi_find_parent(efidev->handle); - - return efidev; -} - - -static int efi_register_device(struct efi_device *efidev) -{ - char *dev_path_str; - struct efi_device *parent; - int ret; - - if (efi_find_device(efidev->handle)) - return -EEXIST; - - if (efidev->parent_handle) { - parent = efi_find_device(efidev->parent_handle); - if (!parent) - return -EINVAL; - - efidev->dev.parent = &parent->dev; - } - - ret = register_device(&efidev->dev); - if (ret) - return ret; - - dev_path_str = device_path_to_str(efidev->devpath); - if (dev_path_str) { - dev_add_param_fixed(&efidev->dev, "devpath", dev_path_str); - free(dev_path_str); - } - - debug("registered efi device %s\n", dev_name(&efidev->dev)); - - return 0; -} - -/** - * efi_register_devices - iterate over all EFI handles and register - * the devices found - * - * in barebox we treat all EFI handles which support the device_path - * protocol as devices. This function iterates over all handles and - * registers the corresponding devices. efi_register_devices is safe - * to call multiple times. Already registered devices will be ignored. - * - */ -void efi_register_devices(void) -{ - unsigned long handle_count = 0; - efi_handle_t *handles = NULL; - unsigned long num_guids; - efi_guid_t **guids; - int ret, i; - struct efi_device **efidevs; - int registered; - - ret = efi_locate_handle(all_handles, NULL, NULL, &handle_count, &handles); - if (ret) - return; - - efidevs = xzalloc(handle_count * sizeof(struct efi_device *)); - - for (i = 0; i < handle_count; i++) { - BS->protocols_per_handle(handles[i], &guids, &num_guids); - - efidevs[i] = efi_add_device(handles[i], guids, num_guids); - } - - /* - * We have a list of devices we want to register, but can only - * register a device when all parents are registered already. - * Do this by continiously iterating over the list until no - * further devices are registered. - */ - do { - registered = 0; - - for (i = 0; i < handle_count; i++) { - if (IS_ERR(efidevs[i])) - continue; - - ret = efi_register_device(efidevs[i]); - if (!ret) { - efidevs[i] = ERR_PTR(-EEXIST); - registered = 1; - } - } - } while (registered); - - free(efidevs); - free(handles); -} - -int efi_connect_all(void) -{ - efi_status_t efiret; - unsigned long handle_count; - efi_handle_t *handle_buffer; - int i; - - efiret = BS->locate_handle_buffer(all_handles, NULL, NULL, &handle_count, - &handle_buffer); - if (EFI_ERROR(efiret)) - return -efi_errno(efiret); - - for (i = 0; i < handle_count; i++) - efiret = BS->connect_controller(handle_buffer[i], NULL, NULL, true); - - if (handle_buffer) - BS->free_pool(handle_buffer); - - return 0; -} - -static int efi_bus_match(struct device_d *dev, struct driver_d *drv) -{ - struct efi_driver *efidrv = to_efi_driver(drv); - struct efi_device *efidev = to_efi_device(dev); - int i; - - for (i = 0; i < efidev->num_guids; i++) { - if (!memcmp(&efidrv->guid, &efidev->guids[i], sizeof(efi_guid_t))) - return 0; - } - - return 1; -} - -static int efi_bus_probe(struct device_d *dev) -{ - struct efi_driver *efidrv = to_efi_driver(dev->driver); - struct efi_device *efidev = to_efi_device(dev); - - return efidrv->probe(efidev); -} - -static void efi_bus_remove(struct device_d *dev) -{ - struct efi_driver *efidrv = to_efi_driver(dev->driver); - struct efi_device *efidev = to_efi_device(dev); - - if (efidrv->remove) - efidrv->remove(efidev); -} - -struct bus_type efi_bus = { - .name = "efi", - .match = efi_bus_match, - .probe = efi_bus_probe, - .remove = efi_bus_remove, -}; - -static int efi_init_devices(void) -{ - bus_register(&efi_bus); - - efi_register_devices(); - - return 0; -} -core_initcall(efi_init_devices); diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c index 27f3c1b..885348d 100644 --- a/arch/efi/efi/efi-image.c +++ b/arch/efi/efi/efi-image.c @@ -36,8 +36,8 @@ #include #include #include -#include -#include +#include +#include struct linux_kernel_header { /* first sector of the image */ diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c index 36ac016..b14e1e8 100644 --- a/arch/efi/efi/efi.c +++ b/arch/efi/efi/efi.c @@ -38,8 +38,8 @@ #include #include #include -#include -#include +#include +#include efi_runtime_services_t *RT; efi_boot_services_t *BS; diff --git a/arch/efi/include/mach/debug_ll.h b/arch/efi/include/mach/debug_ll.h index 0fb2cb8..4ca72de 100644 --- a/arch/efi/include/mach/debug_ll.h +++ b/arch/efi/include/mach/debug_ll.h @@ -5,7 +5,7 @@ #define EFI_DEBUG_CLEAR_MEMORY 0 #include -#include +#include static inline void PUTC_LL(char c) { diff --git a/arch/efi/include/mach/efi-device.h b/arch/efi/include/mach/efi-device.h deleted file mode 100644 index fe074a4..0000000 --- a/arch/efi/include/mach/efi-device.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __MACH_EFI_DEVICE_H -#define __MACH_EFI_DEVICE_H - -struct efi_device { - struct device_d dev; - efi_guid_t *guids; - int num_guids; - efi_handle_t handle; - efi_handle_t parent_handle; - void *protocol; - struct efi_device_path *devpath; -}; - -struct efi_driver { - struct driver_d driver; - int (*probe)(struct efi_device *efidev); - void (*remove)(struct efi_device *efidev); - efi_guid_t guid; -}; - -extern struct bus_type efi_bus; - -static inline struct efi_device *to_efi_device(struct device_d *dev) -{ - return container_of(dev, struct efi_device, dev); -} - -static inline struct efi_driver *to_efi_driver(struct driver_d *drv) -{ - return container_of(drv, struct efi_driver, driver); -} - -#define device_efi_driver(drv) \ - register_driver_macro(device, efi, drv) - -static inline int efi_driver_register(struct efi_driver *efidrv) -{ - efidrv->driver.bus = &efi_bus; - return register_driver(&efidrv->driver); -} - -int efi_connect_all(void); -void efi_register_devices(void); - -#endif /* __MACH_EFI_DEVICE_H */ diff --git a/arch/efi/include/mach/efi.h b/arch/efi/include/mach/efi.h deleted file mode 100644 index 2b25cf1..0000000 --- a/arch/efi/include/mach/efi.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __MACH_EFI_H -#define __MACH_EFI_H - -#include - -const char *efi_strerror(efi_status_t err); - -extern efi_system_table_t *efi_sys_table; -extern efi_handle_t efi_parent_image; -extern struct efi_device_path *efi_device_path; -extern efi_loaded_image_t *efi_loaded_image; - -int efi_errno(efi_status_t err); - -int efi_clocksource_init(void); - -void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size); - -static inline void *efi_get_global_var(char *name, int *var_size) -{ - return efi_get_variable(name, &efi_global_variable_guid, var_size); -} - -int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, - void *buf, unsigned long size); -int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec); - -#endif /* __MACH_EFI_H */ diff --git a/drivers/Kconfig b/drivers/Kconfig index cc086ac..bf31115 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -1,5 +1,6 @@ menu "Drivers" +source "drivers/efi/Kconfig" source "drivers/of/Kconfig" source "drivers/aiodev/Kconfig" source "drivers/amba/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 9ff261a..0fadf4e 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -1,6 +1,7 @@ obj-y += base/ obj-y += block/ obj-$(CONFIG_ARM_AMBA) += amba/ +obj-$(CONFIG_EFI_BOOTUP) += efi/ obj-y += net/ obj-y += serial/ obj-y += mtd/ diff --git a/drivers/block/efi-block-io.c b/drivers/block/efi-block-io.c index e02d3b4..a4d9d3a 100644 --- a/drivers/block/efi-block-io.c +++ b/drivers/block/efi-block-io.c @@ -12,8 +12,8 @@ #include #include #include -#include -#include +#include +#include #define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001 #define EFI_BLOCK_IO_PROTOCOL_REVISION3 ((2<<16) | (31)) diff --git a/drivers/clocksource/efi.c b/drivers/clocksource/efi.c index c92c35b..59fd991 100644 --- a/drivers/clocksource/efi.c +++ b/drivers/clocksource/efi.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #ifdef __x86_64__ diff --git a/drivers/efi/Kconfig b/drivers/efi/Kconfig new file mode 100644 index 0000000..2cd9dd5 --- /dev/null +++ b/drivers/efi/Kconfig @@ -0,0 +1,2 @@ +config EFI_BOOTUP + bool diff --git a/drivers/efi/Makefile b/drivers/efi/Makefile new file mode 100644 index 0000000..de31212 --- /dev/null +++ b/drivers/efi/Makefile @@ -0,0 +1 @@ +obj-y += efi-device.o diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c new file mode 100644 index 0000000..2864d0c --- /dev/null +++ b/drivers/efi/efi-device.c @@ -0,0 +1,352 @@ +/* + * efi-device.c - barebox EFI payload support + * + * Copyright (c) 2014 Sascha Hauer , Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int efi_locate_handle(enum efi_locate_search_type search_type, + efi_guid_t *protocol, + void *search_key, + unsigned long *no_handles, + efi_handle_t **buffer) +{ + efi_status_t efiret; + unsigned long buffer_size = 0; + efi_handle_t *buf; + + efiret = BS->locate_handle(search_type, protocol, search_key, &buffer_size, + NULL); + if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) + return -efi_errno(efiret); + + buf = malloc(buffer_size); + if (!buf) + return -ENOMEM; + + efiret = BS->locate_handle(search_type, protocol, search_key, &buffer_size, + buf); + if (EFI_ERROR(efiret)) { + free(buf); + return -efi_errno(efiret); + } + + *no_handles = buffer_size / sizeof(efi_handle_t); + *buffer = buf; + + return 0; +} + +static struct efi_device *efi_find_device(efi_handle_t *handle) +{ + struct device_d *dev; + struct efi_device *efidev; + + bus_for_each_device(&efi_bus, dev) { + efidev = container_of(dev, struct efi_device, dev); + + if (efidev->handle == handle) + return efidev; + } + + return NULL; +} + +static void efi_devinfo(struct device_d *dev) +{ + struct efi_device *efidev = to_efi_device(dev); + int i; + + printf("Protocols:\n"); + + for (i = 0; i < efidev->num_guids; i++) + printf(" %d: %pUl: %s\n", i, &efidev->guids[i], + efi_guid_string(&efidev->guids[i])); +} + +static efi_handle_t *efi_find_parent(efi_handle_t *handle) +{ + unsigned long handle_count = 0; + efi_handle_t *handles = NULL, *parent; + unsigned long num_guids; + efi_guid_t **guids; + int ret, i, j, k; + efi_status_t efiret; + struct efi_open_protocol_information_entry *entry_buffer; + unsigned long entry_count; + + ret = efi_locate_handle(all_handles, NULL, NULL, &handle_count, &handles); + if (ret) + return NULL; + + /* + * Normally one would expect a function/pointer to retrieve the parent. + * With EFI we have to: + * - get all handles + * - for each handle get the registered protocols + * - for each protocol get the users + * - the user which matches the input handle is the parent + */ + for (i = 0; i < handle_count; i++) { + efiret = BS->open_protocol(handles[i], &efi_device_path_protocol_guid, + NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); + if (EFI_ERROR(efiret)) + continue; + + BS->protocols_per_handle(handles[i], &guids, &num_guids); + for (j = 0; j < num_guids; j++) { + efiret = BS->open_protocol_information(handles[i], guids[j], + &entry_buffer, &entry_count); + for (k = 0; k < entry_count; k++) { + if (entry_buffer[k].controller_handle == NULL) + continue; + if (entry_buffer[k].controller_handle == handles[i]) + continue; + if (entry_buffer[k].controller_handle == handle) { + parent = handles[i]; + goto out; + } + } + } + } + + parent = NULL; + + free(handles); +out: + return parent; +} + +static struct efi_device *efi_add_device(efi_handle_t *handle, efi_guid_t **guids, + int num_guids) +{ + struct efi_device *efidev; + int i; + efi_guid_t *guidarr; + efi_status_t efiret; + void *devpath; + + efidev = efi_find_device(handle); + if (efidev) + return ERR_PTR(-EEXIST); + + efiret = BS->open_protocol(handle, &efi_device_path_protocol_guid, + NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL); + if (EFI_ERROR(efiret)) + return ERR_PTR(-EINVAL); + + guidarr = malloc(sizeof(efi_guid_t) * num_guids); + + for (i = 0; i < num_guids; i++) + memcpy(&guidarr[i], guids[i], sizeof(efi_guid_t)); + + efiret = BS->open_protocol(handle, &efi_device_path_protocol_guid, + &devpath, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(efiret)) { + free(guidarr); + return ERR_PTR(-EINVAL); + } + + efidev = xzalloc(sizeof(*efidev)); + + efidev->guids = guidarr; + efidev->num_guids = num_guids; + efidev->handle = handle; + efidev->dev.bus = &efi_bus; + efidev->dev.id = DEVICE_ID_SINGLE; + efidev->dev.info = efi_devinfo; + efidev->devpath = devpath; + + BS->handle_protocol(handle, &guidarr[0], &efidev->protocol); + + sprintf(efidev->dev.name, "handle-%p", handle); + + efidev->parent_handle = efi_find_parent(efidev->handle); + + return efidev; +} + + +static int efi_register_device(struct efi_device *efidev) +{ + char *dev_path_str; + struct efi_device *parent; + int ret; + + if (efi_find_device(efidev->handle)) + return -EEXIST; + + if (efidev->parent_handle) { + parent = efi_find_device(efidev->parent_handle); + if (!parent) + return -EINVAL; + + efidev->dev.parent = &parent->dev; + } + + ret = register_device(&efidev->dev); + if (ret) + return ret; + + dev_path_str = device_path_to_str(efidev->devpath); + if (dev_path_str) { + dev_add_param_fixed(&efidev->dev, "devpath", dev_path_str); + free(dev_path_str); + } + + debug("registered efi device %s\n", dev_name(&efidev->dev)); + + return 0; +} + +/** + * efi_register_devices - iterate over all EFI handles and register + * the devices found + * + * in barebox we treat all EFI handles which support the device_path + * protocol as devices. This function iterates over all handles and + * registers the corresponding devices. efi_register_devices is safe + * to call multiple times. Already registered devices will be ignored. + * + */ +void efi_register_devices(void) +{ + unsigned long handle_count = 0; + efi_handle_t *handles = NULL; + unsigned long num_guids; + efi_guid_t **guids; + int ret, i; + struct efi_device **efidevs; + int registered; + + ret = efi_locate_handle(all_handles, NULL, NULL, &handle_count, &handles); + if (ret) + return; + + efidevs = xzalloc(handle_count * sizeof(struct efi_device *)); + + for (i = 0; i < handle_count; i++) { + BS->protocols_per_handle(handles[i], &guids, &num_guids); + + efidevs[i] = efi_add_device(handles[i], guids, num_guids); + } + + /* + * We have a list of devices we want to register, but can only + * register a device when all parents are registered already. + * Do this by continiously iterating over the list until no + * further devices are registered. + */ + do { + registered = 0; + + for (i = 0; i < handle_count; i++) { + if (IS_ERR(efidevs[i])) + continue; + + ret = efi_register_device(efidevs[i]); + if (!ret) { + efidevs[i] = ERR_PTR(-EEXIST); + registered = 1; + } + } + } while (registered); + + free(efidevs); + free(handles); +} + +int efi_connect_all(void) +{ + efi_status_t efiret; + unsigned long handle_count; + efi_handle_t *handle_buffer; + int i; + + efiret = BS->locate_handle_buffer(all_handles, NULL, NULL, &handle_count, + &handle_buffer); + if (EFI_ERROR(efiret)) + return -efi_errno(efiret); + + for (i = 0; i < handle_count; i++) + efiret = BS->connect_controller(handle_buffer[i], NULL, NULL, true); + + if (handle_buffer) + BS->free_pool(handle_buffer); + + return 0; +} + +static int efi_bus_match(struct device_d *dev, struct driver_d *drv) +{ + struct efi_driver *efidrv = to_efi_driver(drv); + struct efi_device *efidev = to_efi_device(dev); + int i; + + for (i = 0; i < efidev->num_guids; i++) { + if (!memcmp(&efidrv->guid, &efidev->guids[i], sizeof(efi_guid_t))) + return 0; + } + + return 1; +} + +static int efi_bus_probe(struct device_d *dev) +{ + struct efi_driver *efidrv = to_efi_driver(dev->driver); + struct efi_device *efidev = to_efi_device(dev); + + return efidrv->probe(efidev); +} + +static void efi_bus_remove(struct device_d *dev) +{ + struct efi_driver *efidrv = to_efi_driver(dev->driver); + struct efi_device *efidev = to_efi_device(dev); + + if (efidrv->remove) + efidrv->remove(efidev); +} + +struct bus_type efi_bus = { + .name = "efi", + .match = efi_bus_match, + .probe = efi_bus_probe, + .remove = efi_bus_remove, +}; + +static int efi_init_devices(void) +{ + bus_register(&efi_bus); + + efi_register_devices(); + + return 0; +} +core_initcall(efi_init_devices); diff --git a/drivers/net/efi-snp.c b/drivers/net/efi-snp.c index 963d539..23edc9f 100644 --- a/drivers/net/efi-snp.c +++ b/drivers/net/efi-snp.c @@ -23,8 +23,8 @@ #include #include #include -#include -#include +#include +#include struct efi_network_statistics { uint64_t RxTotalFrames; diff --git a/drivers/serial/efi-stdio.c b/drivers/serial/efi-stdio.c index 5ab9173..0703f72 100644 --- a/drivers/serial/efi-stdio.c +++ b/drivers/serial/efi-stdio.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #define EFI_SHIFT_STATE_VALID 0x80000000 #define EFI_RIGHT_CONTROL_PRESSED 0x00000004 diff --git a/fs/efi.c b/fs/efi.c index 7310d7d..0c0f52e 100644 --- a/fs/efi.c +++ b/fs/efi.c @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include #include /* Open modes */ diff --git a/fs/efivarfs.c b/fs/efivarfs.c index 86cdcf0..bf7351e 100644 --- a/fs/efivarfs.c +++ b/fs/efivarfs.c @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include struct efivarfs_inode { s16 *name; diff --git a/include/efi/efi-device.h b/include/efi/efi-device.h new file mode 100644 index 0000000..8f5f1f3 --- /dev/null +++ b/include/efi/efi-device.h @@ -0,0 +1,45 @@ +#ifndef __EFI_EFI_DEVICE_H +#define __EFI_EFI_DEVICE_H + +struct efi_device { + struct device_d dev; + efi_guid_t *guids; + int num_guids; + efi_handle_t handle; + efi_handle_t parent_handle; + void *protocol; + struct efi_device_path *devpath; +}; + +struct efi_driver { + struct driver_d driver; + int (*probe)(struct efi_device *efidev); + void (*remove)(struct efi_device *efidev); + efi_guid_t guid; +}; + +extern struct bus_type efi_bus; + +static inline struct efi_device *to_efi_device(struct device_d *dev) +{ + return container_of(dev, struct efi_device, dev); +} + +static inline struct efi_driver *to_efi_driver(struct driver_d *drv) +{ + return container_of(drv, struct efi_driver, driver); +} + +#define device_efi_driver(drv) \ + register_driver_macro(device, efi, drv) + +static inline int efi_driver_register(struct efi_driver *efidrv) +{ + efidrv->driver.bus = &efi_bus; + return register_driver(&efidrv->driver); +} + +int efi_connect_all(void); +void efi_register_devices(void); + +#endif /* __EFI_EFI_DEVICE_H */ diff --git a/include/efi/efi.h b/include/efi/efi.h new file mode 100644 index 0000000..2b25cf1 --- /dev/null +++ b/include/efi/efi.h @@ -0,0 +1,28 @@ +#ifndef __MACH_EFI_H +#define __MACH_EFI_H + +#include + +const char *efi_strerror(efi_status_t err); + +extern efi_system_table_t *efi_sys_table; +extern efi_handle_t efi_parent_image; +extern struct efi_device_path *efi_device_path; +extern efi_loaded_image_t *efi_loaded_image; + +int efi_errno(efi_status_t err); + +int efi_clocksource_init(void); + +void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size); + +static inline void *efi_get_global_var(char *name, int *var_size) +{ + return efi_get_variable(name, &efi_global_variable_guid, var_size); +} + +int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes, + void *buf, unsigned long size); +int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec); + +#endif /* __MACH_EFI_H */