Skip to content
Snippets Groups Projects
efi_boottime.c 31.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • 		  no_handles, buffer);
    
    
    	if (!no_handles || !buffer) {
    		r = EFI_INVALID_PARAMETER;
    		goto out;
    	}
    	*no_handles = 0;
    	*buffer = NULL;
    	r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
    			      *buffer);
    	if (r != EFI_BUFFER_TOO_SMALL)
    		goto out;
    	r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, buffer_size,
    			      (void **)buffer);
    	if (r != EFI_SUCCESS)
    		goto out;
    	r = efi_locate_handle(search_type, protocol, search_key, &buffer_size,
    			      *buffer);
    	if (r == EFI_SUCCESS)
    		*no_handles = buffer_size / sizeof(void *);
    out:
    	return EFI_EXIT(r);
    
    }
    
    static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol,
    					       void *registration,
    					       void **protocol_interface)
    {
    
    	struct list_head *lhandle;
    
    	int i;
    
    	EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface);
    
    
    	if (!protocol || !protocol_interface)
    		return EFI_EXIT(EFI_INVALID_PARAMETER);
    
    
    	EFI_PRINT_GUID("protocol", protocol);
    
    
    	list_for_each(lhandle, &efi_obj_list) {
    		struct efi_object *efiobj;
    
    		efiobj = list_entry(lhandle, struct efi_object, link);
    		for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
    			struct efi_handler *handler = &efiobj->protocols[i];
    
    			if (!handler->guid)
    				continue;
    			if (!guidcmp(handler->guid, protocol)) {
    				*protocol_interface =
    					handler->protocol_interface;
    				return EFI_EXIT(EFI_SUCCESS);
    			}
    
    	*protocol_interface = NULL;
    
    
    	return EFI_EXIT(EFI_NOT_FOUND);
    }
    
    static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
    			void **handle, ...)
    {
    	EFI_ENTRY("%p", handle);
    
    
    	va_list argptr;
    	efi_guid_t *protocol;
    	void *protocol_interface;
    	efi_status_t r = EFI_SUCCESS;
    	int i = 0;
    
    	if (!handle)
    		return EFI_EXIT(EFI_INVALID_PARAMETER);
    
    	va_start(argptr, handle);
    	for (;;) {
    		protocol = va_arg(argptr, efi_guid_t*);
    		if (!protocol)
    			break;
    		protocol_interface = va_arg(argptr, void*);
    		r = efi_install_protocol_interface(handle, protocol,
    						   EFI_NATIVE_INTERFACE,
    						   protocol_interface);
    		if (r != EFI_SUCCESS)
    			break;
    		i++;
    	}
    	va_end(argptr);
    	if (r == EFI_SUCCESS)
    		return EFI_EXIT(r);
    
    	/* If an error occured undo all changes. */
    	va_start(argptr, handle);
    	for (; i; --i) {
    		protocol = va_arg(argptr, efi_guid_t*);
    		protocol_interface = va_arg(argptr, void*);
    		efi_uninstall_protocol_interface(handle, protocol,
    						 protocol_interface);
    	}
    	va_end(argptr);
    
    	return EFI_EXIT(r);
    
    }
    
    static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
    			void *handle, ...)
    {
    	EFI_ENTRY("%p", handle);
    	return EFI_EXIT(EFI_INVALID_PARAMETER);
    }
    
    static efi_status_t EFIAPI efi_calculate_crc32(void *data,
    					       unsigned long data_size,
    					       uint32_t *crc32_p)
    {
    	EFI_ENTRY("%p, %ld", data, data_size);
    	*crc32_p = crc32(0, data, data_size);
    	return EFI_EXIT(EFI_SUCCESS);
    }
    
    static void EFIAPI efi_copy_mem(void *destination, void *source,
    				unsigned long length)
    {
    	EFI_ENTRY("%p, %p, %ld", destination, source, length);
    	memcpy(destination, source, length);
    }
    
    static void EFIAPI efi_set_mem(void *buffer, unsigned long size, uint8_t value)
    {
    	EFI_ENTRY("%p, %ld, 0x%x", buffer, size, value);
    	memset(buffer, value, size);
    }
    
    static efi_status_t EFIAPI efi_open_protocol(
    			void *handle, efi_guid_t *protocol,
    			void **protocol_interface, void *agent_handle,
    			void *controller_handle, uint32_t attributes)
    {
    	struct list_head *lhandle;
    	int i;
    
    	efi_status_t r = EFI_INVALID_PARAMETER;
    
    
    	EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol,
    		  protocol_interface, agent_handle, controller_handle,
    		  attributes);
    
    	if (!handle || !protocol ||
    	    (!protocol_interface && attributes !=
    	     EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {
    		goto out;
    	}
    
    
    	EFI_PRINT_GUID("protocol", protocol);
    
    
    	switch (attributes) {
    	case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
    	case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
    	case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
    		break;
    	case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
    		if (controller_handle == handle)
    			goto out;
    	case EFI_OPEN_PROTOCOL_BY_DRIVER:
    	case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
    		if (controller_handle == NULL)
    			goto out;
    	case EFI_OPEN_PROTOCOL_EXCLUSIVE:
    		if (agent_handle == NULL)
    			goto out;
    		break;
    	default:
    
    	list_for_each(lhandle, &efi_obj_list) {
    		struct efi_object *efiobj;
    		efiobj = list_entry(lhandle, struct efi_object, link);
    
    		if (efiobj->handle != handle)
    			continue;
    
    		for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) {
    			struct efi_handler *handler = &efiobj->protocols[i];
    			const efi_guid_t *hprotocol = handler->guid;
    			if (!hprotocol)
    
    			if (!guidcmp(hprotocol, protocol)) {
    
    				if (attributes !=
    				    EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
    					*protocol_interface =
    						handler->protocol_interface;
    				}
    				r = EFI_SUCCESS;
    
    unsupported:
    	r = EFI_UNSUPPORTED;
    
    out:
    	return EFI_EXIT(r);
    }
    
    static efi_status_t EFIAPI efi_handle_protocol(void *handle,
    					       efi_guid_t *protocol,
    					       void **protocol_interface)
    {
    
    	return efi_open_protocol(handle, protocol, protocol_interface, NULL,
    				 NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
    
    }
    
    static const struct efi_boot_services efi_boot_services = {
    	.hdr = {
    		.headersize = sizeof(struct efi_table_hdr),
    	},
    	.raise_tpl = efi_raise_tpl,
    	.restore_tpl = efi_restore_tpl,
    	.allocate_pages = efi_allocate_pages_ext,
    	.free_pages = efi_free_pages_ext,
    	.get_memory_map = efi_get_memory_map_ext,
    
    	.allocate_pool = efi_allocate_pool_ext,
    
    	.free_pool = efi_free_pool_ext,
    
    	.create_event = efi_create_event_ext,
    
    	.set_timer = efi_set_timer_ext,
    
    	.wait_for_event = efi_wait_for_event,
    
    	.signal_event = efi_signal_event_ext,
    
    	.close_event = efi_close_event,
    	.check_event = efi_check_event,
    
    	.install_protocol_interface = efi_install_protocol_interface_ext,
    
    	.reinstall_protocol_interface = efi_reinstall_protocol_interface,
    
    	.uninstall_protocol_interface = efi_uninstall_protocol_interface_ext,
    
    	.handle_protocol = efi_handle_protocol,
    	.reserved = NULL,
    	.register_protocol_notify = efi_register_protocol_notify,
    
    	.locate_handle = efi_locate_handle_ext,
    
    	.locate_device_path = efi_locate_device_path,
    
    	.install_configuration_table = efi_install_configuration_table_ext,
    
    	.load_image = efi_load_image,
    	.start_image = efi_start_image,
    
    	.exit = efi_exit,
    
    	.unload_image = efi_unload_image,
    	.exit_boot_services = efi_exit_boot_services,
    	.get_next_monotonic_count = efi_get_next_monotonic_count,
    	.stall = efi_stall,
    	.set_watchdog_timer = efi_set_watchdog_timer,
    	.connect_controller = efi_connect_controller,
    	.disconnect_controller = efi_disconnect_controller,
    	.open_protocol = efi_open_protocol,
    	.close_protocol = efi_close_protocol,
    	.open_protocol_information = efi_open_protocol_information,
    	.protocols_per_handle = efi_protocols_per_handle,
    	.locate_handle_buffer = efi_locate_handle_buffer,
    	.locate_protocol = efi_locate_protocol,
    	.install_multiple_protocol_interfaces = efi_install_multiple_protocol_interfaces,
    	.uninstall_multiple_protocol_interfaces = efi_uninstall_multiple_protocol_interfaces,
    	.calculate_crc32 = efi_calculate_crc32,
    	.copy_mem = efi_copy_mem,
    	.set_mem = efi_set_mem,
    };
    
    
    
    static uint16_t __efi_runtime_data firmware_vendor[] =
    
    	{ 'D','a','s',' ','U','-','b','o','o','t',0 };
    
    
    struct efi_system_table __efi_runtime_data systab = {
    
    	.hdr = {
    		.signature = EFI_SYSTEM_TABLE_SIGNATURE,
    		.revision = 0x20005, /* 2.5 */
    		.headersize = sizeof(struct efi_table_hdr),
    	},
    	.fw_vendor = (long)firmware_vendor,
    	.con_in = (void*)&efi_con_in,
    	.con_out = (void*)&efi_con_out,
    	.std_err = (void*)&efi_con_out,
    	.runtime = (void*)&efi_runtime_services,
    	.boottime = (void*)&efi_boot_services,
    	.nr_tables = 0,
    	.tables = (void*)efi_conf_table,
    };