summaryrefslogtreecommitdiffstats
path: root/src/interface/efi/efi_driver.c
Commit message (Collapse)AuthorAgeFilesLines
* [efi] Avoid dropping below TPL as at entry to iPXEMichael Brown2020-11-201-8/+7Star
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | iPXE will currently drop to TPL_APPLICATION whenever the current system time is obtained via currticks(), since the system time mechanism relies on a timer that can fire only when the TPL is below TPL_CALLBACK. This can cause unexpected behaviour if the system time is obtained in the middle of an API call into iPXE by external code. For example, MnpDxe sets up a 10ms periodic timer running at TPL_CALLBACK to poll the underling EFI_SIMPLE_NETWORK_PROTOCOL device for received packets. If the resulting poll within iPXE happens to hit a code path that requires obtaining the current system time (e.g. due to reception of an STP packet, which affects iPXE's blocked link timer), then iPXE will end up temporarily dropping to TPL_APPLICATION. This can potentially result in retriggering the MnpDxe periodic timer, causing code to be unexpectedly re-entered. Fix by recording the external TPL at any entry point into iPXE and dropping only as far as this external TPL, rather than dropping unconditionally to TPL_APPLICATION. The side effect of this change is that iPXE's view of the current system time will be frozen for the duration of any API calls made into iPXE by external code at TPL_CALLBACK or above. Since any such external code is already responsible for allowing execution at TPL_APPLICATION to occur, then this should not cause a problem in practice. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Split device path functions out to efi_path.cMichael Brown2020-10-161-2/+2
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Always enable recursion when calling ConnectController()Michael Brown2020-10-021-2/+2
| | | | | | | | There appears to be no reason for avoiding recursion when calling ConnectController(), and recursion provides the least surprising behaviour. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Attempt to connect our driver directly if ConnectController failsMichael Brown2020-06-111-1/+10
| | | | | | | | | | | | | | | | | Some platforms (observed with an AMI BIOS on an Apollo Lake system) will spuriously fail the call to ConnectController() when the UEFI network stack is disabled. This appears to be a BIOS bug that also affects attempts to connect any non-iPXE driver to the NIC controller handle via the UEFI shell "connect" utility. Work around this BIOS bug by falling back to calling our efi_driver_start() directly if the call to ConnectController() fails. This bypasses any BIOS policy in terms of deciding which driver to connect but still cooperates with the UEFI driver model in terms of handle ownership, since the use of EFI_OPEN_PROTOCOL_BY_DRIVER ensures that the BIOS is aware of our ownership claim. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Disambiguate errors returned by ConnectControllerMichael Brown2020-03-141-1/+15
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Return only registered EFI devices from efidev_parent()Michael Brown2019-07-151-3/+6
| | | | | | | | | | | efidev_parent() currently assumes that any device with BUS_TYPE_EFI is part of a struct efi_device. This assumption is not valid, since the code in efi_device_info() may also create a device with BUS_TYPE_EFI. Fix by searching through the list of registered EFI devices when looking for a match, instead of relying on the bus type value. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Do not raise TPL within EFI_DRIVER_BINDING_PROTOCOL.Supported()Michael Brown2018-03-261-7/+0Star
| | | | | | | | | | | | When booting some versions of the UEFI shell, our driver binding protocol's Supported() entry point is called at TPL_NOTIFY for no discernible reason. Attempting to raise to TPL_CALLBACK triggers an immediate assertion failure in the firmware. Since our Supported() method can run at any TPL, fix by simply not attempting to raise the TPL within this method. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Raise TPL within EFI_DRIVER_BINDING_PROTOCOL entry pointsMichael Brown2018-03-151-0/+19
| | | | | Debugged-by: Rob Taglang <rob@privatemachines.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Inhibit our driver Start() method during disconnection attemptsMichael Brown2017-09-221-0/+16
| | | | | | | | | | | | | | | | | | Some HP BIOSes (observed with a Z840) seem to attempt to connect our drivers in the middle of our call to DisconnectController(). The precise chain of events is unclear, but the symptom is that we see several calls to our Supported() and Start() methods, followed by a system lock-up. Work around this dubious BIOS behaviour by explicitly failing calls to our Start() method while we are in the middle of attempting to disconnect drivers. Reported-by: Jordan Wright <jordan.m.wright@disney.com> Debugged-by: Adrian Lucrèce Céleste <adrianlucrececeleste@airmail.cc> Debugged-by: Christian Nilsson <nikize@gmail.com> Tested-by: Jordan Wright <jordan.m.wright@disney.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Continue to connect remaining handles after connection errorsMichael Brown2017-09-131-3/+5
| | | | | | | | | | | | Some UEFI BIOSes will deliberately break the implementation of ConnectController() to return errors for devices that have been "disabled" via the BIOS setup screen. (As an added bonus, such BIOSes may return garbage EFI_STATUS values such as 0xff.) Work around these broken UEFI BIOSes by ignoring failures and continuing to attempt to connect any remaining handles. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Avoid infinite loops when asked to stop non-existent devicesMichael Brown2015-09-281-1/+1
| | | | | | | | | | | | | | | Calling EDK2's OpenProtocol() with attributes BY_DRIVER|EXCLUSIVE will call DisconnectController() in a loop to attempt to dislodge any existing openers with attributes BY_DRIVER. The loop will continue indefinitely until either no such openers remain, or until DisconnectController() returns an error. If our driver binding protocol's Stop() method is ever called to disconnect a device that we are not in fact driving, then return EFI_DEVICE_ERROR rather than EFI_SUCCESS, in order to break this potentially infinite loop. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Include a copy of the device path within struct efi_deviceMichael Brown2015-09-131-1/+34
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow efidev_parent() to traverse multiple device generationsMichael Brown2015-09-071-10/+8Star
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Remove raw EFI_HANDLE values from debug messagesMichael Brown2015-08-271-42/+38Star
| | | | | | | | | The raw EFI_HANDLE value is almost never useful to know, and simply adds noise to the already verbose debug messages. Improve the legibility of debug messages by using only the name generated by efi_handle_name(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Move abstract device path and handle functions to efi_utils.cMichael Brown2014-08-061-74/+1Star
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Open device path protocol only at point of useMichael Brown2014-08-061-27/+0Star
| | | | | | | | | | | | Some EFI 1.10 systems (observed on an Apple iMac) do not allow us to open the device path protocol with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER and so we cannot maintain a safe, long-lived pointer to the device path. Work around this by instead opening the device path protocol with an attribute of EFI_OPEN_PROTOCOL_GET_PROTOCOL whenever we need to use it. Debugged-by: Curtis Larsen <larsen@dixie.edu> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Provide centralised definitions of commonly-used GUIDsMichael Brown2014-08-061-12/+0Star
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Report errors from attempting to disconnect existing driversCurtis Larsen2014-08-051-1/+8
| | | | | Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Dump handle information around connect/disconnect attemptsMichael Brown2014-07-311-0/+9
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Dump existing openers when we are unable to open a protocolMichael Brown2014-07-311-0/+4
| | | | | | | | Dump the existing openers of a protocol whenever we are unable to open a protocol using attributes of BY_DEVICE, EXCLUSIVE, or BY_CHILD_CONTROLLER. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Use efi_handle_name() instead of efi_handle_devpath_text()Michael Brown2014-07-311-25/+24Star
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Report exact failure when unable to open the device pathMichael Brown2014-07-301-2/+4
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Fix incorrect debug message level when device has no device pathMichael Brown2014-07-301-2/+2
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Attempt to start only drivers claiming support for a deviceMichael Brown2014-07-081-0/+7
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow network devices to be created on top of arbitrary SNP devicesMichael Brown2014-07-031-9/+181
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Restructure EFI driver modelMichael Brown2014-06-251-85/+261
| | | | | | | | | | | | | | | | | | | | | | | | | | | Provide a single instance of EFI_DRIVER_BINDING_PROTOCOL (attached to our image handle); this matches the expectations scattered throughout the EFI specification. Open the underlying hardware device using EFI_OPEN_PROTOCOL_BY_DRIVER and EFI_OPEN_PROTOCOL_EXCLUSIVE, to prevent other drivers from attaching to the same device. Do not automatically connect to devices when being loaded as a driver; leave this task to the platform firmware (or to the user, if loading directly from the EFI shell). When running as an application, forcibly disconnect any existing drivers from devices that we want to control, and reconnect them on exit. Provide a meaningful driver version number (based on the build timestamp), to allow platform firmware to automatically load newer versions of iPXE drivers if multiple drivers are present. Include device paths within debug messages where possible, to aid in debugging. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Expose build timestamp, build name, and product namesMichael Brown2014-06-241-2/+2
| | | | | | | | Expose the build timestamp (measured in seconds since the Epoch) and the build name (e.g. "rtl8139.rom" or "ipxe.efi"), and provide the product name and product short name in a single centralised location. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Connect driver to devices as part of installationMichael Brown2014-03-121-20/+69
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow driver to be unloadedMichael Brown2014-03-101-2/+44
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Perform meaningful error code conversionsMichael Brown2013-04-191-3/+7
| | | | | | | | Exploit the redefinition of iPXE error codes to include a "platform error code" to allow for meaningful conversion of EFI_STATUS values to iPXE errors and vice versa. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Delegate to child device's EFI_COMPONENT_NAME2_PROTOCOL, if presentMichael Brown2012-11-211-5/+22
| | | | | | | | | | EFI's device naming model requires drivers to provide names for child devices. Allow the driver's GetControllerName() method to delegate to an instance of EFI_COMPONENT_NAME2_PROTOCOL installed on the child device itself (if present); this allows the SNP device to expose its own device name via the PCI driver's GetControllerName() method. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [legal] Update FSF mailing address in GPL licence textsMichael Brown2012-07-201-1/+2
| | | | | Suggested-by: Daniel P. Berrange <berrange@redhat.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Add EFI string formatting functionsMichael Brown2011-04-081-8/+5Star
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow EFI to control PCI bus enumerationMichael Brown2011-02-171-0/+143
EFI performs its own PCI bus enumeration. Respect this, and start controlling devices only when instructed to do so by EFI. As a side benefit, we should now correctly create multiple SNP instances for multi-port devices. This should also fix the problem of failing to enumerate devices because the PCI bridges have not yet been enabled at the time the iPXE driver is loaded. Signed-off-by: Michael Brown <mcb30@ipxe.org>