Commit 732ea9db authored by Ard Biesheuvel's avatar Ard Biesheuvel
Browse files

efi: libstub: Move screen_info handling to common code



Currently, arm64, RISC-V and LoongArch rely on the fact that struct
screen_info can be accessed directly, due to the fact that the EFI stub
and the core kernel are part of the same image. This will change after a
future patch, so let's ensure that the screen_info handling is able to
deal with this, by adopting the arm32 approach of passing it as a
configuration table. While at it, switch to ACPI reclaim memory to hold
the screen_info data, which is more appropriate for this kind of
allocation.

Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 06064800
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -43,9 +43,6 @@ void efi_virtmap_unload(void);

/* arch specific definitions used by the stub code */

struct screen_info *alloc_screen_info(void);
void free_screen_info(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
+5 −26
Original line number Diff line number Diff line
@@ -75,38 +75,13 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
	return 0;
}

static unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata cpu_state_table = EFI_INVALID_TABLE_ADDR;

const efi_config_table_type_t efi_arch_tables[] __initconst = {
	{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table},
	{LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table},
	{}
};

static void __init load_screen_info_table(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;

		if (memblock_is_map_memory(screen_info.lfb_base))
			memblock_mark_nomap(screen_info.lfb_base,
					    screen_info.lfb_size);
	}
}

static void __init load_cpu_state_table(void)
{
	if (cpu_state_table != EFI_INVALID_TABLE_ADDR) {
@@ -145,7 +120,11 @@ void __init arm_efi_init(void)
{
	efi_init();

	load_screen_info_table();
	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) {
		/* dummycon on ARM needs non-zero values for columns/lines */
		screen_info.orig_video_cols = 80;
		screen_info.orig_video_lines = 25;
	}

	/* ARM does not permit early mappings to persist across paging_init() */
	efi_memmap_unmap();
+0 −6
Original line number Diff line number Diff line
@@ -84,12 +84,6 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
	return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
}

#define alloc_screen_info(x...)		&screen_info

static inline void free_screen_info(struct screen_info *si)
{
}

#define EFI_ALLOC_ALIGN		SZ_64K

/*
+0 −9
Original line number Diff line number Diff line
@@ -19,15 +19,6 @@ void efifb_setup_from_dmi(struct screen_info *si, const char *opt);
#define EFI_ALLOC_ALIGN		SZ_64K
#define EFI_RT_VIRTUAL_OFFSET	CSR_DMW0_BASE

static inline struct screen_info *alloc_screen_info(void)
{
	return &screen_info;
}

static inline void free_screen_info(struct screen_info *si)
{
}

static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
{
	return ULONG_MAX;
+22 −2
Original line number Diff line number Diff line
@@ -52,6 +52,27 @@ void __init efi_runtime_init(void)
	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
}

unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;

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;
@@ -80,8 +101,7 @@ void __init efi_init(void)

	set_bit(EFI_CONFIG_TABLES, &efi.flags);

	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI)
		memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
	init_screen_info();

	if (boot_memmap == EFI_INVALID_TABLE_ADDR)
		return;
Loading