Commit a51ad547 authored by yangqiming's avatar yangqiming Committed by Hongchen Zhang
Browse files

LoongArch: Support loader and kernel interface V40

LoongArch inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6BWFP



--------------------------------

1. LoongArch uses the new interface parameter form:
a0: efi flag, a1: command line, a2: system table
2. Boot memmap and initrd are passed to kernel via GUID.

Signed-off-by: default avatarQiming Yang <yangqiming@loongson.cn>
Signed-off-by: default avatarJianmin Lv <lvjianmin@loongson.cn>
Change-Id: I193db4238e28962bdc4ae82a232d0c343f4f32f3
parent 4e992fb1
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -18,6 +18,23 @@ void __init efi_runtime_init(void);
#define EFI_ALLOC_ALIGN		SZ_64K
#define EFI_RT_VIRTUAL_OFFSET	CSR_DMW0_BASE

#define LINUX_EFI_INITRD_MEDIA_GUID		EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
#define LINUX_EFI_NEW_MEMMAP_GUID		EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)

struct linux_efi_initrd {
	unsigned long	base;
	unsigned long	size;
};

struct efi_new_memmap {
	unsigned long		map_size;
	unsigned long		desc_size;
	u32			desc_ver;
	unsigned long		map_key;
	unsigned long		buff_size;
	efi_memory_desc_t	map[];
};

static inline struct screen_info *alloc_screen_info(void)
{
	return &screen_info;
+54 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/memblock.h>
#include <linux/reboot.h>
#include <linux/uaccess.h>
#include <linux/initrd.h>

#include <asm/early_ioremap.h>
#include <asm/efi.h>
@@ -27,11 +28,18 @@
#include <asm/loongson.h>
#include "legacy_boot.h"

static __initdata unsigned long new_memmap = EFI_INVALID_TABLE_ADDR;
static __initdata unsigned long initrd = EFI_INVALID_TABLE_ADDR;

static unsigned long efi_nr_tables;
static unsigned long efi_config_table;

static efi_system_table_t *efi_systab;
static efi_config_table_type_t arch_tables[] __initdata = {{},};
static efi_config_table_type_t arch_tables[] __initdata = {
	{LINUX_EFI_NEW_MEMMAP_GUID, &new_memmap, "NEWMEM"},
	{LINUX_EFI_INITRD_MEDIA_GUID, &initrd, "INITRD"},
	{},
};
static __initdata pgd_t *pgd_efi;

static int __init efimap_populate_hugepages(
@@ -184,6 +192,9 @@ static int __init set_virtual_map(void)
			(efi_memory_desc_t *)TO_PHYS((unsigned long)runtime_map));

	efi_unmap_pgt();
	if (status != EFI_SUCCESS)
		return -1;

	return 0;
}

@@ -213,6 +224,44 @@ void __init efi_runtime_init(void)
	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
}

static void __init get_initrd(void)
{
	if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) &&
		initrd != EFI_INVALID_TABLE_ADDR && phys_initrd_size == 0) {
		struct linux_efi_initrd *tbl;

		tbl = early_memremap(initrd, sizeof(*tbl));
		if (tbl) {
			phys_initrd_start = tbl->base;
			phys_initrd_size = tbl->size;
			early_memunmap(tbl, sizeof(*tbl));
		}
	}
}

static void __init init_new_memmap(void)
{
	struct efi_new_memmap *tbl;

	if (new_memmap == EFI_INVALID_TABLE_ADDR)
		return;

	tbl = early_memremap_ro(new_memmap, sizeof(*tbl));
	if (tbl) {
		struct efi_memory_map_data data;

		data.phys_map           = new_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));
	}
}

void __init loongson_efi_init(void)
{
	int size;
@@ -237,6 +286,10 @@ void __init loongson_efi_init(void)
	efi_config_parse_tables(config_tables, efi_systab->nr_tables, arch_tables);
	early_memunmap(config_tables, efi_nr_tables * size);

	get_initrd();

	init_new_memmap();

	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI)
		memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
}
+16 −1
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@ void __init init_environ(void)
{
	int efi_boot = fw_arg0;
	struct efi_memory_map_data data;
	void *fdt_ptr = early_memremap_ro(fw_arg1, SZ_64K);
	char *cmdline;
	void *fdt_ptr;

	if (efi_bp)
		return;
@@ -32,6 +33,20 @@ void __init init_environ(void)
	else
		clear_bit(EFI_BOOT, &efi.flags);

	if (fw_arg2 == 0)
		goto parse_fdt;

	cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE);
	strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
	early_memunmap(cmdline, COMMAND_LINE_SIZE);

	efi_system_table = fw_arg2;

	return;

parse_fdt:
	fdt_ptr = early_memremap_ro(fw_arg1, SZ_64K);

	early_init_dt_scan(fdt_ptr);
	early_init_fdt_reserve_self();
	efi_system_table = efi_get_fdt_params(&data);
+1 −1
Original line number Diff line number Diff line
@@ -525,7 +525,7 @@ unsigned long legacy_boot_init(unsigned long argc, unsigned long cmdptr, unsigne
{
	int ret;

	if (!bpi)
	if (!bpi || (argc < 2))
		return -1;
	efi_bp = (struct boot_params *)bpi;
	bpi_version = get_bpi_version(&efi_bp->signature);
+1 −1
Original line number Diff line number Diff line
@@ -216,7 +216,6 @@ static void __init set_pcie_wakeup(void)

void __init platform_init(void)
{
	loongson_efi_init();
#ifdef CONFIG_ACPI_TABLE_UPGRADE
	acpi_table_upgrade();
#endif
@@ -378,6 +377,7 @@ void __init setup_arch(char **cmdline_p)
	legacy_boot_init(fw_arg0, fw_arg1, fw_arg2);

	init_environ();
	loongson_efi_init();
	memblock_init();
	pagetable_init();
	parse_early_param();