efi linux arm,代码阅读 - Linux\kernel\linux-5.0\drivers\firmware\efi\arm-runtime.c

/*

* Extensible Firmware Interface

*

* Based on Extensible Firmware Interface Specification version 2.4

*

* Copyright (C) 2013, 2014 Linaro Ltd.

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License version 2 as

* published by the Free Software Foundation.

*

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

extern u64 efi_system_table;

#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS

#include

static struct ptdump_info efi_ptdump_info = {

.mm= &efi_mm,

.markers= (struct addr_marker[]){

{ 0,"UEFI runtime start" },

{ DEFAULT_MAP_WINDOW_64,"UEFI runtime end" },

{ -1,NULL }

},

.base_addr= 0,

};

static int __init ptdump_init(void)

{

if (!efi_enabled(EFI_RUNTIME_SERVICES))

return 0;

return ptdump_debugfs_register(&efi_ptdump_info, "efi_page_tables");

}

device_initcall(ptdump_init);

#endif

static bool __init efi_virtmap_init(void)

{

efi_memory_desc_t *md;

bool systab_found;

efi_mm.pgd = pgd_alloc(&efi_mm);

mm_init_cpumask(&efi_mm);

init_new_context(NULL, &efi_mm);

systab_found = false;

for_each_efi_memory_desc(md) {

phys_addr_t phys = md->phys_addr;

int ret;

if (!(md->attribute & EFI_MEMORY_RUNTIME))

continue;

if (md->virt_addr == 0)

return false;

ret = efi_create_mapping(&efi_mm, md);

if (ret) {

pr_warn(" EFI remap %pa: failed to create mapping (%d)\n",

&phys, ret);

return false;

}

/*

* If this entry covers the address of the UEFI system table,

* calculate and record its virtual address.

*/

if (efi_system_table >= phys &&

efi_system_table < phys + (md->num_pages * EFI_PAGE_SIZE)) {

efi.systab = (void *)(unsigned long)(efi_system_table -

phys + md->virt_addr);

systab_found = true;

}

}

if (!systab_found) {

pr_err("No virtual mapping found for the UEFI System Table\n");

return false;

}

if (efi_memattr_apply_permissions(&efi_mm, efi_set_mapping_permissions))

return false;

return true;

}

/*

* Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,

* non-early mapping of the UEFI system table and virtual mappings for all

* EFI_MEMORY_RUNTIME regions.

*/

static int __init arm_enable_runtime_services(void)

{

u64 mapsize;

if (!efi_enabled(EFI_BOOT)) {

pr_info("EFI services will not be available.\n");

return 0;

}

efi_memmap_unmap();

mapsize = efi.memmap.desc_size * efi.memmap.nr_map;

if (efi_memmap_init_late(efi.memmap.phys_map, mapsize)) {

pr_err("Failed to remap EFI memory map\n");

return 0;

}

if (efi_runtime_disabled()) {

pr_info("EFI runtime services will be disabled.\n");

return 0;

}

if (efi_enabled(EFI_RUNTIME_SERVICES)) {

pr_info("EFI runtime services access via paravirt.\n");

return 0;

}

pr_info("Remapping and enabling EFI services.\n");

if (!efi_virtmap_init()) {

pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n");

return -ENOMEM;

}

/* Set up runtime services function pointers */

efi_native_runtime_setup();

set_bit(EFI_RUNTIME_SERVICES, &efi.flags);

return 0;

}

early_initcall(arm_enable_runtime_services);

void efi_virtmap_load(void)

{

preempt_disable();

efi_set_pgd(&efi_mm);

}

void efi_virtmap_unload(void)

{

efi_set_pgd(current->active_mm);

preempt_enable();

}

static int __init arm_dmi_init(void)

{

/*

* On arm64/ARM, DMI depends on UEFI, and dmi_scan_machine() needs to

* be called early because dmi_id_init(), which is an arch_initcall

* itself, depends on dmi_scan_machine() having been called already.

*/

dmi_scan_machine();

if (dmi_available)

dmi_set_dump_stack_arch_desc();

return 0;

}

core_initcall(arm_dmi_init);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值