diff mbox

[8/8] efi/arm: populate screen_info based on data provided by the UEFI stub

Message ID 1457588408-19309-9-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel March 10, 2016, 5:40 a.m. UTC
Unlike on arm64, where we can simply access the screen_info struct directly,
ARM requires an intermediate step to get the information discovered by the
GOP code in the UEFI stub into the screen_info struct.

So retrieve the dedicated config table we invented for this purpose, and
put its contents into the core kernel's copy of struct screen_info.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---
 arch/arm/kernel/efi.c           | 24 ++++++++++++++++++++
 drivers/firmware/efi/arm-init.c |  6 +++++
 2 files changed, 30 insertions(+)

-- 
1.9.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Comments

Ard Biesheuvel March 18, 2016, 11:57 a.m. UTC | #1
On 18 March 2016 at 12:53, Matt Fleming <matt@codeblueprint.co.uk> wrote:
> On Thu, 10 Mar, at 12:40:08PM, Ard Biesheuvel wrote:

>> Unlike on arm64, where we can simply access the screen_info struct directly,

>> ARM requires an intermediate step to get the information discovered by the

>> GOP code in the UEFI stub into the screen_info struct.

>>

>> So retrieve the dedicated config table we invented for this purpose, and

>> put its contents into the core kernel's copy of struct screen_info.

>>

>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> ---

>>  arch/arm/kernel/efi.c           | 24 ++++++++++++++++++++

>>  drivers/firmware/efi/arm-init.c |  6 +++++

>>  2 files changed, 30 insertions(+)

>

> [...]

>

>> diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c

>> index eca9b4f826ee..689bf65f8ddf 100644

>> --- a/drivers/firmware/efi/arm-init.c

>> +++ b/drivers/firmware/efi/arm-init.c

>> @@ -112,6 +112,12 @@ static int __init uefi_init(void)

>>       retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,

>>                                        sizeof(efi_config_table_t), NULL);

>>

>> +     if (IS_ENABLED(CONFIG_ARM)) {

>> +             extern void efi_find_screen_info(efi_config_table_t *, u32);

>> +

>> +             efi_find_screen_info(config_tables, efi.systab->nr_tables);

>> +     }

>> +

>>       early_memunmap(config_tables, table_size);

>>  out:

>>       early_memunmap(efi.systab,  sizeof(efi_system_table_t));

>

> It's unfortunate that this is the first example of putting

> arch-specific things in arm-init.c. Is there anyway we can move it out

> into arch/arm?

>

> If not, because efi_find_screen_info() uses all standard data types

> and function calls, I wouldn't be opposed to just sticking this in

> efi_config_parse_tables() like we do for EFI_PROPERTIES_TABLE. It's

> certainly nice to have all config table code in one place.

>

> Also, it would save ARM the effort of looping over the config tables

> twice.


I'd actually prefer that, especially since -at some point- we may
expose the stub-to-kernel interface as an ABI, for things like Xen
dom0 that expose a 'sanitized' EFI environment, and don't boot the
dom0 kernel via the stub. There, this config table would be the only
way to populate screen_info, and the fact that arm64 *may* do it
directly becomes an implementation detail of the stub.

So in v2, I will rename the GUID to drop the ARMxx part, and move its
handling into the generic code.

-- 
Ard.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff mbox

Patch

diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
index ff8a9d8acfac..8d1119259654 100644
--- a/arch/arm/kernel/efi.c
+++ b/arch/arm/kernel/efi.c
@@ -6,11 +6,35 @@ 
  * published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt)     "efi: " fmt
+
 #include <linux/efi.h>
+#include <linux/screen_info.h>
 #include <asm/efi.h>
 #include <asm/mach/map.h>
 #include <asm/mmu_context.h>
 
+static const efi_guid_t __initconst si_tbl = LINUX_ARM32_SCREEN_INFO_TABLE_GUID;
+
+void __init efi_find_screen_info(efi_config_table_t *tbl, u32 num_tables)
+{
+	struct screen_info *si;
+
+	while (num_tables--) {
+		if (efi_guidcmp(tbl->guid, si_tbl) == 0) {
+			si = early_memremap_ro(tbl->table, sizeof(*si));
+			if (!si) {
+				pr_warn("Failed to remap screen_info config table\n");
+				return;
+			}
+			screen_info = *si;
+			early_memunmap(si, sizeof(*si));
+			break;
+		}
+		tbl++;
+	}
+}
+
 int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
 {
 	struct map_desc desc = {
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index eca9b4f826ee..689bf65f8ddf 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -112,6 +112,12 @@  static int __init uefi_init(void)
 	retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
 					 sizeof(efi_config_table_t), NULL);
 
+	if (IS_ENABLED(CONFIG_ARM)) {
+		extern void efi_find_screen_info(efi_config_table_t *, u32);
+
+		efi_find_screen_info(config_tables, efi.systab->nr_tables);
+	}
+
 	early_memunmap(config_tables, table_size);
 out:
 	early_memunmap(efi.systab,  sizeof(efi_system_table_t));