From patchwork Mon Apr 25 20:06:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Fleming X-Patchwork-Id: 66626 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp1235766qge; Mon, 25 Apr 2016 13:13:39 -0700 (PDT) X-Received: by 10.98.89.28 with SMTP id n28mr20969640pfb.41.1461615219839; Mon, 25 Apr 2016 13:13:39 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id pg8si626766pab.40.2016.04.25.13.13.39; Mon, 25 Apr 2016 13:13:39 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeblueprint-co-uk.20150623.gappssmtp.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965106AbcDYUNh (ORCPT + 29 others); Mon, 25 Apr 2016 16:13:37 -0400 Received: from mail-wm0-f49.google.com ([74.125.82.49]:35465 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965004AbcDYUH6 (ORCPT ); Mon, 25 Apr 2016 16:07:58 -0400 Received: by mail-wm0-f49.google.com with SMTP id e201so98086789wme.0 for ; Mon, 25 Apr 2016 13:07:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeblueprint-co-uk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KwqOXzF2sr0+XgJlOoEN+xSGGNqrSjxi3y/1gdku+Hk=; b=IhM14OnYT7ws7KKYAyNBS/PGUOr4t32tVIFPjd2h4Xfm3bgEPuOkMhhRO84wYVsr2Z o9ROLAj8h3ofF+kYBODgTky4oRI3SvYzEMXwIEyJdVfAvqKxwcaailVjgMopfTKsX9hP 52T8AKz/pNUmLw9BXlcV+zpdMIo9dhs70qBew3i+jC58BjrrcrvYNvPJ/VKCHkJ3sczC MM/ultK3JC/SVHrFQKWaknWrkTNu4/ErPmtHyI8IH+DN91Wd84ZSe6tgkhtfkPzrWpgN FEbDLFt5UP6QBKQHjy/TBItM+xvPohG8hgg5t7XlwSPy7os4hxXQsbIgZsDiMlY96Mhn ia1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KwqOXzF2sr0+XgJlOoEN+xSGGNqrSjxi3y/1gdku+Hk=; b=QQ5ykVSf2vfx8hNPfQ6lkb5HXuUnO2XiRNANUdUai4d7i0owUrZbA0ia5/FzPtNDbb gxa1097prcJVZNK4nI4X2sbCOiM8NXKfDbsMHgCFE0cr4w0gNQB47QaNQ5dugFZy+ibv sQ99yub2L+WwmfZheMWJ0vMXx2ElIk+de9LeFq7UQnhDqXNLS0F929AbrBNWEBYyWMFs 8Gx7jqJEiAFGqp7c5LNCQ04Cy7OOBemvB99OKLjcc29KLpZ9VWRC7ffKKkbwdRaFbvS0 iREXqs2RtT+RJWJGzHMRlqt5AWyvY/4UHyvM4zWfNFwJc/Okr+nBsiHCt3aHCMeS6J9K WV+w== X-Gm-Message-State: AOPr4FXzGAYbLAbDe1ytuQYK1+agM7u/nr/UELp7S/lrr2vik0Ldqcrg1xbXRZs1ZKCnaQ== X-Received: by 10.28.146.135 with SMTP id u129mr13598326wmd.8.1461614877508; Mon, 25 Apr 2016 13:07:57 -0700 (PDT) Received: from localhost (bcdc58e5.skybroadband.com. [188.220.88.229]) by smtp.gmail.com with ESMTPSA id r75sm19771464wme.18.2016.04.25.13.07.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Apr 2016 13:07:56 -0700 (PDT) From: Matt Fleming To: Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, Matt Fleming , David Herrmann , Mark Rutland , Peter Jones , Will Deacon Subject: [PATCH 21/40] efi/arm: libstub: Make screen_info accessible to the UEFI stub Date: Mon, 25 Apr 2016 21:06:53 +0100 Message-Id: <1461614832-17633-22-git-send-email-matt@codeblueprint.co.uk> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1461614832-17633-1-git-send-email-matt@codeblueprint.co.uk> References: <1461614832-17633-1-git-send-email-matt@codeblueprint.co.uk> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ard Biesheuvel In order to hand over the framebuffer described by the GOP protocol and discovered by the UEFI stub, make struct screen_info accessible by the stub. This involves allocating a loader data buffer and passing it to the kernel proper via a UEFI Configuration Table, since the UEFI stub executes in the context of the decompressor, and cannot access the kernel's copy of struct screen_info directly. Signed-off-by: Ard Biesheuvel Cc: Mark Rutland Cc: Will Deacon Cc: David Herrmann Cc: Peter Jones Signed-off-by: Matt Fleming --- arch/arm/include/asm/efi.h | 3 +++ arch/arm/kernel/setup.c | 3 ++- drivers/firmware/efi/arm-init.c | 34 +++++++++++++++++++++++++++- drivers/firmware/efi/efi.c | 5 +++-- drivers/firmware/efi/libstub/arm32-stub.c | 37 +++++++++++++++++++++++++++++++ include/linux/efi.h | 11 ++++++++- 6 files changed, 88 insertions(+), 5 deletions(-) -- 2.7.3 diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index dc30d89a1ed3..25f8b1162c2e 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -64,6 +64,9 @@ void efi_virtmap_unload(void); #define __efi_call_early(f, ...) f(__VA_ARGS__) #define efi_is_64bit() (false) +struct screen_info *alloc_screen_info(efi_system_table_t *sys_table_arg); +void free_screen_info(efi_system_table_t *sys_table, struct screen_info *si); + /* * A reasonable upper bound for the uncompressed kernel size is 32 MBytes, * so we will reserve that amount of memory. We have no easy way to tell what diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a28fce0bdbbe..180f528ec318 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -883,7 +883,8 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) request_resource(&ioport_resource, &lp2); } -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) || \ + defined(CONFIG_EFI) struct screen_info screen_info = { .orig_video_lines = 30, .orig_video_cols = 80, diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 909d974d35d9..ac95dd8b119f 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -11,12 +11,15 @@ * */ +#define pr_fmt(fmt) "efi: " fmt + #include #include #include #include #include #include +#include #include @@ -51,6 +54,32 @@ static phys_addr_t efi_to_phys(unsigned long addr) return addr; } +static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR; + +static __initdata efi_config_table_type_t arch_tables[] = { + {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, NULL, &screen_info_table}, + {NULL_GUID, NULL, NULL} +}; + +static void __init init_screen_info(void) +{ + struct screen_info *si; + + if (screen_info_table != EFI_INVALID_TABLE_ADDR) { + si = early_memremap_ro(screen_info_table, sizeof(*si)); + if (!si) { + pr_err("Could not map screen_info config table\n"); + return; + } + screen_info = *si; + early_memunmap(si, sizeof(*si)); + + /* dummycon on ARM needs non-zero values for columns/lines */ + screen_info.orig_video_cols = 80; + screen_info.orig_video_lines = 25; + } +} + static int __init uefi_init(void) { efi_char16_t *c16; @@ -108,7 +137,8 @@ static int __init uefi_init(void) goto out; } retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, - sizeof(efi_config_table_t), NULL); + sizeof(efi_config_table_t), + arch_tables); early_memunmap(config_tables, table_size); out: @@ -223,4 +253,6 @@ void __init efi_init(void) PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK))); } + + init_screen_info(); } diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 583e647912a5..4991371012b4 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -353,8 +353,9 @@ static __init int match_config_table(efi_guid_t *guid, for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) { if (!efi_guidcmp(*guid, table_types[i].guid)) { *(table_types[i].ptr) = table; - pr_cont(" %s=0x%lx ", - table_types[i].name, table); + if (table_types[i].name) + pr_cont(" %s=0x%lx ", + table_types[i].name, table); return 1; } } diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index 6f42be4d0084..e1f0b28e1dcb 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -26,6 +26,43 @@ efi_status_t check_platform_features(efi_system_table_t *sys_table_arg) return EFI_SUCCESS; } +static efi_guid_t screen_info_guid = LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID; + +struct screen_info *alloc_screen_info(efi_system_table_t *sys_table_arg) +{ + struct screen_info *si; + efi_status_t status; + + /* + * Unlike on arm64, where we can directly fill out the screen_info + * structure from the stub, we need to allocate a buffer to hold + * its contents while we hand over to the kernel proper from the + * decompressor. + */ + status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA, + sizeof(*si), (void **)&si); + + if (status != EFI_SUCCESS) + return NULL; + + status = efi_call_early(install_configuration_table, + &screen_info_guid, si); + if (status == EFI_SUCCESS) + return si; + + efi_call_early(free_pool, si); + return NULL; +} + +void free_screen_info(efi_system_table_t *sys_table_arg, struct screen_info *si) +{ + if (!si) + return; + + efi_call_early(install_configuration_table, &screen_info_guid, NULL); + efi_call_early(free_pool, si); +} + efi_status_t handle_kernel_image(efi_system_table_t *sys_table, unsigned long *image_addr, unsigned long *image_size, diff --git a/include/linux/efi.h b/include/linux/efi.h index 9203bbb28887..e53458842245 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -286,7 +286,7 @@ typedef struct { efi_status_t (*locate_handle)(int, efi_guid_t *, void *, unsigned long *, efi_handle_t *); void *locate_device_path; - void *install_configuration_table; + efi_status_t (*install_configuration_table)(efi_guid_t *, void *); void *load_image; void *start_image; void *exit; @@ -633,6 +633,15 @@ void efi_native_runtime_setup(void); EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, \ 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) +/* + * This GUID is used to pass to the kernel proper the struct screen_info + * structure that was populated by the stub based on the GOP protocol instance + * associated with ConOut + */ +#define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID \ + EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, \ + 0xb9, 0xe, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) + typedef struct { efi_guid_t guid; u64 table;