mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
b8466fe82b
After the vga console no longer relies on global screen_info, there are only two remaining use cases: - on the x86 architecture, it is used for multiple boot methods (bzImage, EFI, Xen, kexec) to commucate the initial VGA or framebuffer settings to a number of device drivers. - on other architectures, it is only used as part of the EFI stub, and only for the three sysfb framebuffers (simpledrm, simplefb, efifb). Remove the duplicate data structure definitions by moving it into the efi-init.c file that sets it up initially for the EFI case, leaving x86 as an exception that retains its own definition for non-EFI boots. The added #ifdefs here are optional, I added them to further limit the reach of screen_info to configurations that have at least one of the users enabled. Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Helge Deller <deller@gmx.de> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Link: https://lore.kernel.org/r/20231017093947.3627976-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
144 lines
3.5 KiB
C
144 lines
3.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* EFI initialization
|
|
*
|
|
* Author: Jianmin Lv <lvjianmin@loongson.cn>
|
|
* Huacai Chen <chenhuacai@loongson.cn>
|
|
*
|
|
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
|
*/
|
|
|
|
#include <linux/acpi.h>
|
|
#include <linux/efi.h>
|
|
#include <linux/efi-bgrt.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/export.h>
|
|
#include <linux/io.h>
|
|
#include <linux/kobject.h>
|
|
#include <linux/memblock.h>
|
|
#include <linux/reboot.h>
|
|
#include <linux/screen_info.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
#include <asm/early_ioremap.h>
|
|
#include <asm/efi.h>
|
|
#include <asm/loongson.h>
|
|
|
|
static unsigned long efi_nr_tables;
|
|
static unsigned long efi_config_table;
|
|
|
|
static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR;
|
|
static unsigned long __initdata fdt_pointer = EFI_INVALID_TABLE_ADDR;
|
|
|
|
static efi_system_table_t *efi_systab;
|
|
static efi_config_table_type_t arch_tables[] __initdata = {
|
|
{LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" },
|
|
{DEVICE_TREE_GUID, &fdt_pointer, "FDTPTR" },
|
|
{},
|
|
};
|
|
|
|
void __init *efi_fdt_pointer(void)
|
|
{
|
|
if (!efi_systab)
|
|
return NULL;
|
|
|
|
if (fdt_pointer == EFI_INVALID_TABLE_ADDR)
|
|
return NULL;
|
|
|
|
return early_memremap_ro(fdt_pointer, SZ_64K);
|
|
}
|
|
|
|
void __init efi_runtime_init(void)
|
|
{
|
|
if (!efi_enabled(EFI_BOOT) || !efi_systab->runtime)
|
|
return;
|
|
|
|
if (efi_runtime_disabled()) {
|
|
pr_info("EFI runtime services will be disabled.\n");
|
|
return;
|
|
}
|
|
|
|
efi.runtime = (efi_runtime_services_t *)efi_systab->runtime;
|
|
efi.runtime_version = (unsigned int)efi.runtime->hdr.revision;
|
|
|
|
efi_native_runtime_setup();
|
|
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
|
|
}
|
|
|
|
unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
|
|
|
|
#if defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)
|
|
struct screen_info screen_info __section(".data");
|
|
EXPORT_SYMBOL_GPL(screen_info);
|
|
#endif
|
|
|
|
static void __init init_screen_info(void)
|
|
{
|
|
struct screen_info *si;
|
|
|
|
if (screen_info_table == EFI_INVALID_TABLE_ADDR)
|
|
return;
|
|
|
|
si = early_memremap(screen_info_table, sizeof(*si));
|
|
if (!si) {
|
|
pr_err("Could not map screen_info config table\n");
|
|
return;
|
|
}
|
|
screen_info = *si;
|
|
memset(si, 0, sizeof(*si));
|
|
early_memunmap(si, sizeof(*si));
|
|
|
|
memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
|
|
}
|
|
|
|
void __init efi_init(void)
|
|
{
|
|
int size;
|
|
void *config_tables;
|
|
struct efi_boot_memmap *tbl;
|
|
|
|
if (!efi_system_table)
|
|
return;
|
|
|
|
efi_systab = (efi_system_table_t *)early_memremap_ro(efi_system_table, sizeof(*efi_systab));
|
|
if (!efi_systab) {
|
|
pr_err("Can't find EFI system table.\n");
|
|
return;
|
|
}
|
|
|
|
efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor);
|
|
|
|
set_bit(EFI_64BIT, &efi.flags);
|
|
efi_nr_tables = efi_systab->nr_tables;
|
|
efi_config_table = (unsigned long)efi_systab->tables;
|
|
|
|
size = sizeof(efi_config_table_t);
|
|
config_tables = early_memremap(efi_config_table, efi_nr_tables * size);
|
|
efi_config_parse_tables(config_tables, efi_systab->nr_tables, arch_tables);
|
|
early_memunmap(config_tables, efi_nr_tables * size);
|
|
|
|
set_bit(EFI_CONFIG_TABLES, &efi.flags);
|
|
|
|
if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB))
|
|
init_screen_info();
|
|
|
|
if (boot_memmap == EFI_INVALID_TABLE_ADDR)
|
|
return;
|
|
|
|
tbl = early_memremap_ro(boot_memmap, sizeof(*tbl));
|
|
if (tbl) {
|
|
struct efi_memory_map_data data;
|
|
|
|
data.phys_map = boot_memmap + sizeof(*tbl);
|
|
data.size = tbl->map_size;
|
|
data.desc_size = tbl->desc_size;
|
|
data.desc_version = tbl->desc_ver;
|
|
|
|
if (efi_memmap_init_early(&data) < 0)
|
|
panic("Unable to map EFI memory map.\n");
|
|
|
|
early_memunmap(tbl, sizeof(*tbl));
|
|
}
|
|
}
|