Skip to content

Commit 6262f66

Browse files
atishp04palmer-dabbelt
authored andcommitted
RISC-V: Add early ioremap support
UEFI uses early IO or memory mappings for runtime services before normal ioremap() is usable. Add the necessary fixmap bindings and pmd mappings for generic ioremap support to work. Signed-off-by: Atish Patra <[email protected]> Reviewed-by: Anup Patel <[email protected]> Reviewed-by: Palmer Dabbelt <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 8f3a2b4 commit 6262f66

File tree

6 files changed

+51
-0
lines changed

6 files changed

+51
-0
lines changed

arch/riscv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ config RISCV
3737
select GENERIC_ARCH_TOPOLOGY if SMP
3838
select GENERIC_ATOMIC64 if !64BIT
3939
select GENERIC_CLOCKEVENTS
40+
select GENERIC_EARLY_IOREMAP
4041
select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
4142
select GENERIC_IOREMAP
4243
select GENERIC_IRQ_MULTI_HANDLER

arch/riscv/include/asm/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
2+
generic-y += early_ioremap.h
23
generic-y += extable.h
34
generic-y += flat.h
45
generic-y += kvm_para.h

arch/riscv/include/asm/fixmap.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ enum fixed_addresses {
2727
FIX_TEXT_POKE1,
2828
FIX_TEXT_POKE0,
2929
FIX_EARLYCON_MEM_BASE,
30+
31+
__end_of_permanent_fixed_addresses,
32+
/*
33+
* Temporary boot-time mappings, used by early_ioremap(),
34+
* before ioremap() is functional.
35+
*/
36+
#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
37+
#define FIX_BTMAPS_SLOTS 7
38+
#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
39+
40+
FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
41+
FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
42+
3043
__end_of_fixed_addresses
3144
};
3245

arch/riscv/include/asm/io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/types.h>
1515
#include <linux/pgtable.h>
1616
#include <asm/mmiowb.h>
17+
#include <asm/early_ioremap.h>
1718

1819
/*
1920
* MMIO access functions are separated out to break dependency cycles

arch/riscv/kernel/setup.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/smp.h>
2020

2121
#include <asm/cpu_ops.h>
22+
#include <asm/early_ioremap.h>
2223
#include <asm/setup.h>
2324
#include <asm/sections.h>
2425
#include <asm/sbi.h>
@@ -71,6 +72,7 @@ void __init setup_arch(char **cmdline_p)
7172

7273
*cmdline_p = boot_command_line;
7374

75+
early_ioremap_setup();
7476
parse_early_param();
7577

7678
setup_bootmem();

arch/riscv/mm/init.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
403403
uintptr_t load_pa = (uintptr_t)(&_start);
404404
uintptr_t load_sz = (uintptr_t)(&_end) - load_pa;
405405
uintptr_t map_size = best_map_size(load_pa, MAX_EARLY_MAPPING_SIZE);
406+
#ifndef __PAGETABLE_PMD_FOLDED
407+
pmd_t fix_bmap_spmd, fix_bmap_epmd;
408+
#endif
406409

407410
va_pa_offset = PAGE_OFFSET - load_pa;
408411
pfn_base = PFN_DOWN(load_pa);
@@ -456,6 +459,36 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
456459
pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL);
457460
dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1));
458461
dtb_early_pa = dtb_pa;
462+
463+
/*
464+
* Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap
465+
* range can not span multiple pmds.
466+
*/
467+
BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
468+
!= (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
469+
470+
#ifndef __PAGETABLE_PMD_FOLDED
471+
/*
472+
* Early ioremap fixmap is already created as it lies within first 2MB
473+
* of fixmap region. We always map PMD_SIZE. Thus, both FIX_BTMAP_END
474+
* FIX_BTMAP_BEGIN should lie in the same pmd. Verify that and warn
475+
* the user if not.
476+
*/
477+
fix_bmap_spmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_BEGIN))];
478+
fix_bmap_epmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_END))];
479+
if (pmd_val(fix_bmap_spmd) != pmd_val(fix_bmap_epmd)) {
480+
WARN_ON(1);
481+
pr_warn("fixmap btmap start [%08lx] != end [%08lx]\n",
482+
pmd_val(fix_bmap_spmd), pmd_val(fix_bmap_epmd));
483+
pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
484+
fix_to_virt(FIX_BTMAP_BEGIN));
485+
pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n",
486+
fix_to_virt(FIX_BTMAP_END));
487+
488+
pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
489+
pr_warn("FIX_BTMAP_BEGIN: %d\n", FIX_BTMAP_BEGIN);
490+
}
491+
#endif
459492
}
460493

461494
static void __init setup_vm_final(void)

0 commit comments

Comments
 (0)