diff --git a/arch/loongarch/include/asm/efi.h b/arch/loongarch/include/asm/efi.h index 85176fc629b0d88790dd828eac3015c47252f363..9499abaa6baf300f2a79ac0d21fc075e9b4bc353 100644 --- a/arch/loongarch/include/asm/efi.h +++ b/arch/loongarch/include/asm/efi.h @@ -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; diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index f48ef0d8d51802d0aae14a29dee3e44e4767e479..7cf4a11732d3f4f50145d05432b338e816774e4b 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -27,11 +28,18 @@ #include #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); } diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c index 596e6635368ed8a0f2bda6d37a481cc93a4521a3..64490a2764d2e3e796ed1e72f96c5e8186263963 100644 --- a/arch/loongarch/kernel/env.c +++ b/arch/loongarch/kernel/env.c @@ -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); diff --git a/arch/loongarch/kernel/legacy_boot.c b/arch/loongarch/kernel/legacy_boot.c index d8f749653939869200eaac9d2ad65a8d898b3e33..99b69173460d856ed0acc6bccc0e257f772f7f80 100644 --- a/arch/loongarch/kernel/legacy_boot.c +++ b/arch/loongarch/kernel/legacy_boot.c @@ -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); diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 887ae4a9243801f33e2f8ec99f88836285fc6ea3..35d99525485b3ea5259d7663cf4c950a55170618 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -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();