Skip to content

Commit fe45ffa

Browse files
AlexGhitipalmer-dabbelt
authored andcommitted
riscv: Move early fdt mapping creation in its own function
The code that handles the early fdt mapping is hard to read and does not create the same mapping size depending on the kernel: - for 64-bit, 2 PMD entries are used which amounts to a 4MB mapping - for 32-bit, 2 PGDIR entries are used which amounts to a 8MB mapping So keep using 2 PMD entries for 64-bit and use only one PGD entry for 32-bit needed to cover 4MB. Move that into a new function called create_fdt_early_page_table which, using the same naming as create_kernel_page_table. Signed-off-by: Alexandre Ghiti <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 977765c commit fe45ffa

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

arch/riscv/mm/init.c

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
222222
static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
223223

224224
pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
225+
static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
225226

226227
#ifdef CONFIG_XIP_KERNEL
227228
#define trampoline_pg_dir ((pgd_t *)XIP_FIXUP(trampoline_pg_dir))
@@ -302,7 +303,6 @@ static void __init create_pte_mapping(pte_t *ptep,
302303
static pmd_t trampoline_pmd[PTRS_PER_PMD] __page_aligned_bss;
303304
static pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss;
304305
static pmd_t early_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
305-
static pmd_t early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
306306

307307
#ifdef CONFIG_XIP_KERNEL
308308
#define trampoline_pmd ((pmd_t *)XIP_FIXUP(trampoline_pmd))
@@ -388,6 +388,7 @@ static void __init create_pmd_mapping(pmd_t *pmdp,
388388
#define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \
389389
create_pte_mapping(__nextp, __va, __pa, __sz, __prot)
390390
#define fixmap_pgd_next fixmap_pte
391+
#define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot)
391392
#endif
392393

393394
void __init create_pgd_mapping(pgd_t *pgdp,
@@ -529,9 +530,44 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
529530
}
530531
#endif
531532

533+
/*
534+
* Setup a 4MB mapping that encompasses the device tree: for 64-bit kernel,
535+
* this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR
536+
* entry.
537+
*/
538+
static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa)
539+
{
540+
#ifndef CONFIG_BUILTIN_DTB
541+
uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1);
542+
543+
create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
544+
IS_ENABLED(CONFIG_64BIT) ? (uintptr_t)early_dtb_pmd : pa,
545+
PGDIR_SIZE,
546+
IS_ENABLED(CONFIG_64BIT) ? PAGE_TABLE : PAGE_KERNEL);
547+
548+
if (IS_ENABLED(CONFIG_64BIT)) {
549+
create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA,
550+
pa, PMD_SIZE, PAGE_KERNEL);
551+
create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE,
552+
pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
553+
}
554+
555+
dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1));
556+
#else
557+
/*
558+
* For 64-bit kernel, __va can't be used since it would return a linear
559+
* mapping address whereas dtb_early_va will be used before
560+
* setup_vm_final installs the linear mapping. For 32-bit kernel, as the
561+
* kernel is mapped in the linear mapping, that makes no difference.
562+
*/
563+
dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa));
564+
#endif
565+
566+
dtb_early_pa = dtb_pa;
567+
}
568+
532569
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
533570
{
534-
uintptr_t __maybe_unused pa;
535571
pmd_t __maybe_unused fix_bmap_spmd, fix_bmap_epmd;
536572

537573
kernel_map.virt_addr = KERNEL_LINK_ADDR;
@@ -594,40 +630,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
594630
*/
595631
create_kernel_page_table(early_pg_dir, true);
596632

597-
#ifndef __PAGETABLE_PMD_FOLDED
598-
/* Setup early PMD for DTB */
599-
create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
600-
(uintptr_t)early_dtb_pmd, PGDIR_SIZE, PAGE_TABLE);
601-
#ifndef CONFIG_BUILTIN_DTB
602-
/* Create two consecutive PMD mappings for FDT early scan */
603-
pa = dtb_pa & ~(PMD_SIZE - 1);
604-
create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA,
605-
pa, PMD_SIZE, PAGE_KERNEL);
606-
create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE,
607-
pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
608-
dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1));
609-
#else /* CONFIG_BUILTIN_DTB */
610-
/*
611-
* __va can't be used since it would return a linear mapping address
612-
* whereas dtb_early_va will be used before setup_vm_final installs
613-
* the linear mapping.
614-
*/
615-
dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa));
616-
#endif /* CONFIG_BUILTIN_DTB */
617-
#else /* __PAGETABLE_PMD_FOLDED */
618-
#ifndef CONFIG_BUILTIN_DTB
619-
/* Create two consecutive PGD mappings for FDT early scan */
620-
pa = dtb_pa & ~(PGDIR_SIZE - 1);
621-
create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
622-
pa, PGDIR_SIZE, PAGE_KERNEL);
623-
create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE,
624-
pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL);
625-
dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1));
626-
#else /* CONFIG_BUILTIN_DTB */
627-
dtb_early_va = __va(dtb_pa);
628-
#endif /* CONFIG_BUILTIN_DTB */
629-
#endif /* __PAGETABLE_PMD_FOLDED */
630-
dtb_early_pa = dtb_pa;
633+
/* Setup early mapping for FDT early scan */
634+
create_fdt_early_page_table(early_pg_dir, dtb_pa);
631635

632636
/*
633637
* Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap

0 commit comments

Comments
 (0)