• Hans de Goede's avatar
    efi: Add embedded peripheral firmware support · f0df68d5
    Hans de Goede authored
    Just like with PCI options ROMs, which we save in the setup_efi_pci*
    functions from arch/x86/boot/compressed/eboot.c, the EFI code / ROM itself
    sometimes may contain data which is useful/necessary for peripheral drivers
    to have access to.
    
    Specifically the EFI code may contain an embedded copy of firmware which
    needs to be (re)loaded into the peripheral. Normally such firmware would be
    part of linux-firmware, but in some cases this is not feasible, for 2
    reasons:
    
    1) The firmware is customized for a specific use-case of the chipset / use
    with a specific hardware model, so we cannot have a single firmware file
    for the chipset. E.g. touchscreen controller firmwares are compiled
    specifically for the hardware model they are used with, as they are
    calibrated for a specific model digitizer.
    
    2) Despite repeated attempts we have failed to get permission to
    redistribute the firmware. This is especially a problem with customized
    firmwares, these get created by the chip vendor for a specific ODM and the
    copyright may partially belong with the ODM, so the chip vendor cannot
    give a blanket permission to distribute these.
    
    This commit adds support for finding peripheral firmware embedded in the
    EFI code and makes the found firmware available through the new
    efi_get_embedded_fw() function.
    
    Support for loading these firmwares through the standard firmware loading
    mechanism is added in a follow-up commit in this patch-series.
    
    Note we check the EFI_BOOT_SERVICES_CODE for embedded firmware near the end
    of start_kernel(), just before calling rest_init(), this is on purpose
    because the typical EFI_BOOT_SERVICES_CODE memory-segment is too large for
    early_memremap(), so the check must be done after mm_init(). This relies
    on EFI_BOOT_SERVICES_CODE not being free-ed until efi_free_boot_services()
    is called, which means that this will only work on x86 for now.
    Reported-by: default avatarDave Olsthoorn <dave@bewaar.me>
    Suggested-by: default avatarPeter Jones <pjones@redhat.com>
    Acked-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
    Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
    Link: https://lore.kernel.org/r/20200115163554.101315-3-hdegoede@redhat.comSigned-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
    f0df68d5
efi.h 51.6 KB