Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb91540d

Browse files
atishp04palmer-dabbelt
authored andcommitted
RISC-V: Add EFI runtime services
This patch adds EFI runtime service support for RISC-V.Signed-off-by: Atish Patra <atish.patra@wdc.com>[ardb: - Remove the page check]Signed-off-by: Ard Biesheuvel <ardb@kernel.org>Acked-by: Ard Biesheuvel <ardb@kernel.org>Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
1 parentd707174 commitb91540d

File tree

11 files changed

+287
-4
lines changed

11 files changed

+287
-4
lines changed

‎arch/riscv/Kconfig‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,9 @@ config EFI
412412
select EFI_PARAMS_FROM_FDT
413413
select EFI_STUB
414414
select EFI_GENERIC_STUB
415+
select EFI_RUNTIME_WRAPPERS
415416
select RISCV_ISA_C
417+
depends on MMU
416418
default y
417419
help
418420
This option provides support for runtime services provided

‎arch/riscv/include/asm/efi.h‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,28 @@
55
#ifndef_ASM_EFI_H
66
#define_ASM_EFI_H
77

8+
#include<asm/csr.h>
89
#include<asm/io.h>
910
#include<asm/mmu_context.h>
1011
#include<asm/ptrace.h>
1112
#include<asm/tlbflush.h>
1213

14+
#ifdefCONFIG_EFI
15+
externvoidefi_init(void);
16+
#else
17+
#defineefi_init()
18+
#endif
19+
20+
intefi_create_mapping(structmm_struct*mm,efi_memory_desc_t*md);
21+
intefi_set_mapping_permissions(structmm_struct*mm,efi_memory_desc_t*md);
22+
23+
#definearch_efi_call_virt_setup() efi_virtmap_load()
24+
#definearch_efi_call_virt_teardown() efi_virtmap_unload()
25+
26+
#definearch_efi_call_virt(p,f,args...) p->f(args)
27+
28+
#defineARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE)
29+
1330
/* on RISC-V, the FDT may be located anywhere in system RAM */
1431
staticinlineunsigned longefi_get_max_fdt_addr(unsigned longimage_addr)
1532
{
@@ -32,4 +49,7 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt)
3249
{
3350
}
3451

52+
voidefi_virtmap_load(void);
53+
voidefi_virtmap_unload(void);
54+
3555
#endif/* _ASM_EFI_H */

‎arch/riscv/include/asm/mmu.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ typedef struct {
2020
#endif
2121
}mm_context_t;
2222

23+
void__initcreate_pgd_mapping(pgd_t*pgdp,uintptr_tva,phys_addr_tpa,
24+
phys_addr_tsz,pgprot_tprot);
2325
#endif/* __ASSEMBLY__ */
2426

2527
#endif/* _ASM_RISCV_MMU_H */

‎arch/riscv/include/asm/pgtable.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100

101101
#definePAGE_KERNEL__pgprot(_PAGE_KERNEL)
102102
#definePAGE_KERNEL_EXEC__pgprot(_PAGE_KERNEL | _PAGE_EXEC)
103+
#definePAGE_KERNEL_READ__pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
104+
#definePAGE_KERNEL_EXEC__pgprot(_PAGE_KERNEL | _PAGE_EXEC)
105+
#definePAGE_KERNEL_READ_EXEC__pgprot((_PAGE_KERNEL & ~_PAGE_WRITE) \
106+
| _PAGE_EXEC)
103107

104108
#definePAGE_TABLE__pgprot(_PAGE_TABLE)
105109

‎arch/riscv/kernel/Makefile‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@ obj-$(CONFIG_KGDB)+= kgdb.o
5555

5656
obj-$(CONFIG_JUMP_LABEL)+= jump_label.o
5757

58+
obj-$(CONFIG_EFI)+= efi.o
59+
5860
clean:

‎arch/riscv/kernel/efi.c‎

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (C) 2020 Western Digital Corporation or its affiliates.
4+
* Adapted from arch/arm64/kernel/efi.c
5+
*/
6+
7+
#include<linux/efi.h>
8+
#include<linux/init.h>
9+
10+
#include<asm/efi.h>
11+
#include<asm/pgtable.h>
12+
#include<asm/pgtable-bits.h>
13+
14+
/*
15+
* Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
16+
* executable, everything else can be mapped with the XN bits
17+
* set. Also take the new (optional) RO/XP bits into account.
18+
*/
19+
static__initpgprot_tefimem_to_pgprot_map(efi_memory_desc_t*md)
20+
{
21+
u64attr=md->attribute;
22+
u32type=md->type;
23+
24+
if (type==EFI_MEMORY_MAPPED_IO)
25+
returnPAGE_KERNEL;
26+
27+
/* R-- */
28+
if ((attr& (EFI_MEMORY_XP |EFI_MEMORY_RO))==
29+
(EFI_MEMORY_XP |EFI_MEMORY_RO))
30+
returnPAGE_KERNEL_READ;
31+
32+
/* R-X */
33+
if (attr&EFI_MEMORY_RO)
34+
returnPAGE_KERNEL_READ_EXEC;
35+
36+
/* RW- */
37+
if (((attr& (EFI_MEMORY_RP |EFI_MEMORY_WP |EFI_MEMORY_XP))==
38+
EFI_MEMORY_XP)||
39+
type!=EFI_RUNTIME_SERVICES_CODE)
40+
returnPAGE_KERNEL;
41+
42+
/* RWX */
43+
returnPAGE_KERNEL_EXEC;
44+
}
45+
46+
int__initefi_create_mapping(structmm_struct*mm,efi_memory_desc_t*md)
47+
{
48+
pgprot_tprot=__pgprot(pgprot_val(efimem_to_pgprot_map(md))&
49+
~(_PAGE_GLOBAL));
50+
inti;
51+
52+
/* RISC-V maps one page at a time */
53+
for (i=0;i<md->num_pages;i++)
54+
create_pgd_mapping(mm->pgd,md->virt_addr+i*PAGE_SIZE,
55+
md->phys_addr+i*PAGE_SIZE,
56+
PAGE_SIZE,prot);
57+
return0;
58+
}
59+
60+
staticint__initset_permissions(pte_t*ptep,unsigned longaddr,void*data)
61+
{
62+
efi_memory_desc_t*md=data;
63+
pte_tpte=READ_ONCE(*ptep);
64+
unsigned longval;
65+
66+
if (md->attribute&EFI_MEMORY_RO) {
67+
val=pte_val(pte)& ~_PAGE_WRITE;
68+
val=pte_val(pte) |_PAGE_READ;
69+
pte=__pte(val);
70+
}
71+
if (md->attribute&EFI_MEMORY_XP) {
72+
val=pte_val(pte)& ~_PAGE_EXEC;
73+
pte=__pte(val);
74+
}
75+
set_pte(ptep,pte);
76+
77+
return0;
78+
}
79+
80+
int__initefi_set_mapping_permissions(structmm_struct*mm,
81+
efi_memory_desc_t*md)
82+
{
83+
BUG_ON(md->type!=EFI_RUNTIME_SERVICES_CODE&&
84+
md->type!=EFI_RUNTIME_SERVICES_DATA);
85+
86+
/*
87+
* Calling apply_to_page_range() is only safe on regions that are
88+
* guaranteed to be mapped down to pages. Since we are only called
89+
* for regions that have been mapped using efi_create_mapping() above
90+
* (and this is checked by the generic Memory Attributes table parsing
91+
* routines), there is no need to check that again here.
92+
*/
93+
returnapply_to_page_range(mm,md->virt_addr,
94+
md->num_pages <<EFI_PAGE_SHIFT,
95+
set_permissions,md);
96+
}

‎arch/riscv/kernel/setup.c‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include<linux/sched/task.h>
1818
#include<linux/swiotlb.h>
1919
#include<linux/smp.h>
20+
#include<linux/efi.h>
2021

2122
#include<asm/cpu_ops.h>
2223
#include<asm/early_ioremap.h>
@@ -26,11 +27,12 @@
2627
#include<asm/tlbflush.h>
2728
#include<asm/thread_info.h>
2829
#include<asm/kasan.h>
30+
#include<asm/efi.h>
2931

3032
#include"head.h"
3133

32-
#ifdefCONFIG_DUMMY_CONSOLE
33-
structscreen_infoscreen_info= {
34+
#if defined(CONFIG_DUMMY_CONSOLE)|| defined(CONFIG_EFI)
35+
structscreen_infoscreen_info__section(.data)= {
3436
.orig_video_lines=30,
3537
.orig_video_cols=80,
3638
.orig_video_mode=0,
@@ -75,6 +77,7 @@ void __init setup_arch(char **cmdline_p)
7577
early_ioremap_setup();
7678
parse_early_param();
7779

80+
efi_init();
7881
setup_bootmem();
7982
paging_init();
8083
#ifIS_ENABLED(CONFIG_BUILTIN_DTB)

‎arch/riscv/mm/init.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ static void __init create_pmd_mapping(pmd_t *pmdp,
390390
#definefixmap_pgd_nextfixmap_pte
391391
#endif
392392

393-
staticvoid__initcreate_pgd_mapping(pgd_t*pgdp,
393+
void__initcreate_pgd_mapping(pgd_t*pgdp,
394394
uintptr_tva,phys_addr_tpa,
395395
phys_addr_tsz,pgprot_tprot)
396396
{

‎drivers/firmware/efi/Makefile‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ fake_map-$(CONFIG_X86)+= x86_fake_mem.o
3535
arm-obj-$(CONFIG_EFI):= efi-init.o arm-runtime.o
3636
obj-$(CONFIG_ARM)+=$(arm-obj-y)
3737
obj-$(CONFIG_ARM64)+=$(arm-obj-y)
38+
riscv-obj-$(CONFIG_EFI):= efi-init.o riscv-runtime.o
39+
obj-$(CONFIG_RISCV)+=$(riscv-obj-y)
3840
obj-$(CONFIG_EFI_CAPSULE_LOADER)+= capsule-loader.o
3941
obj-$(CONFIG_EFI_EARLYCON)+= earlycon.o
4042
obj-$(CONFIG_UEFI_CPER_ARM)+= cper-arm.o

‎drivers/firmware/efi/libstub/efi-stub.c‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,23 @@
1717

1818
/*
1919
* This is the base address at which to start allocating virtual memory ranges
20-
* for UEFI Runtime Services. This is in the low TTBR0 range so that we can use
20+
* for UEFI Runtime Services.
21+
*
22+
* For ARM/ARM64:
23+
* This is in the low TTBR0 range so that we can use
2124
* any allocation we choose, and eliminate the risk of a conflict after kexec.
2225
* The value chosen is the largest non-zero power of 2 suitable for this purpose
2326
* both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can
2427
* be mapped efficiently.
2528
* Since 32-bit ARM could potentially execute with a 1G/3G user/kernel split,
2629
* map everything below 1 GB. (512 MB is a reasonable upper bound for the
2730
* entire footprint of the UEFI runtime services memory regions)
31+
*
32+
* For RISC-V:
33+
* There is no specific reason for which, this address (512MB) can't be used
34+
* EFI runtime virtual address for RISC-V. It also helps to use EFI runtime
35+
* services on both RV32/RV64. Keep the same runtime virtual address for RISC-V
36+
* as well to minimize the code churn.
2837
*/
2938
#defineEFI_RT_VIRTUAL_BASESZ_512M
3039
#defineEFI_RT_VIRTUAL_SIZESZ_512M

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp