Skip to content

Commit 8f3a2b4

Browse files
avpatelpalmer-dabbelt
authored andcommitted
RISC-V: Move DT mapping outof fixmap
Currently, RISC-V reserves 1MB of fixmap memory for device tree. However, it maps only single PMD (2MB) space for fixmap which leaves only < 1MB space left for other kernel features such as early ioremap which requires fixmap as well. The fixmap size can be increased by another 2MB but it brings additional complexity and changes the virtual memory layout as well. If we require some additional feature requiring fixmap again, it has to be moved again. Technically, DT doesn't need a fixmap as the memory occupied by the DT is only used during boot. That's why, We map device tree in early page table using two consecutive PGD mappings at lower addresses (< PAGE_OFFSET). This frees lot of space in fixmap and also makes maximum supported device tree size supported as PGDIR_SIZE. Thus, init memory section can be used for the same purpose as well. This simplifies fixmap implementation. Signed-off-by: Anup Patel <[email protected]> Signed-off-by: Atish Patra <[email protected]> Reviewed-by: Palmer Dabbelt <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 8a3f30c commit 8f3a2b4

File tree

6 files changed

+20
-22
lines changed

6 files changed

+20
-22
lines changed

arch/riscv/include/asm/fixmap.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
*/
2323
enum fixed_addresses {
2424
FIX_HOLE,
25-
#define FIX_FDT_SIZE SZ_1M
26-
FIX_FDT_END,
27-
FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
2825
FIX_PTE,
2926
FIX_PMD,
3027
FIX_TEXT_POKE1,

arch/riscv/include/asm/pgtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ static inline void __kernel_map_pages(struct page *page, int numpages, int enabl
464464
#define kern_addr_valid(addr) (1) /* FIXME */
465465

466466
extern void *dtb_early_va;
467+
extern uintptr_t dtb_early_pa;
467468
void setup_bootmem(void);
468469
void paging_init(void);
469470

arch/riscv/kernel/head.S

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ clear_bss_done:
258258
#endif
259259
/* Start the kernel */
260260
call soc_early_init
261-
call parse_dtb
262261
tail start_kernel
263262

264263
.Lsecondary_start:

arch/riscv/kernel/head.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,4 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa);
1616
extern void *__cpu_up_stack_pointer[];
1717
extern void *__cpu_up_task_pointer[];
1818

19-
void __init parse_dtb(void);
20-
2119
#endif /* __ASM_HEAD_H */

arch/riscv/kernel/setup.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ atomic_t hart_lottery __section(.sdata);
4848
unsigned long boot_cpu_hartid;
4949
static DEFINE_PER_CPU(struct cpu, cpu_devices);
5050

51-
void __init parse_dtb(void)
51+
static void __init parse_dtb(void)
5252
{
53+
/* Early scan of device tree from init memory */
5354
if (early_init_dt_scan(dtb_early_va))
5455
return;
5556

@@ -62,6 +63,7 @@ void __init parse_dtb(void)
6263

6364
void __init setup_arch(char **cmdline_p)
6465
{
66+
parse_dtb();
6567
init_mm.start_code = (unsigned long) _stext;
6668
init_mm.end_code = (unsigned long) _etext;
6769
init_mm.end_data = (unsigned long) _edata;
@@ -76,7 +78,10 @@ void __init setup_arch(char **cmdline_p)
7678
#if IS_ENABLED(CONFIG_BUILTIN_DTB)
7779
unflatten_and_copy_device_tree();
7880
#else
79-
unflatten_device_tree();
81+
if (early_init_dt_verify(__va(dtb_early_pa)))
82+
unflatten_device_tree();
83+
else
84+
pr_err("No DTB found in kernel mappings\n");
8085
#endif
8186

8287
#ifdef CONFIG_SWIOTLB

arch/riscv/mm/init.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
2828
EXPORT_SYMBOL(empty_zero_page);
2929

3030
extern char _start[];
31-
void *dtb_early_va;
31+
#define DTB_EARLY_BASE_VA PGDIR_SIZE
32+
void *dtb_early_va __initdata;
33+
uintptr_t dtb_early_pa __initdata;
3234

3335
static void __init zone_sizes_init(void)
3436
{
@@ -141,8 +143,6 @@ static void __init setup_initrd(void)
141143
}
142144
#endif /* CONFIG_BLK_DEV_INITRD */
143145

144-
static phys_addr_t dtb_early_pa __initdata;
145-
146146
void __init setup_bootmem(void)
147147
{
148148
struct memblock_region *reg;
@@ -399,7 +399,7 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
399399

400400
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
401401
{
402-
uintptr_t va, end_va;
402+
uintptr_t va, pa, end_va;
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);
@@ -448,16 +448,13 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
448448
load_pa + (va - PAGE_OFFSET),
449449
map_size, PAGE_KERNEL_EXEC);
450450

451-
/* Create fixed mapping for early FDT parsing */
452-
end_va = __fix_to_virt(FIX_FDT) + FIX_FDT_SIZE;
453-
for (va = __fix_to_virt(FIX_FDT); va < end_va; va += PAGE_SIZE)
454-
create_pte_mapping(fixmap_pte, va,
455-
dtb_pa + (va - __fix_to_virt(FIX_FDT)),
456-
PAGE_SIZE, PAGE_KERNEL);
457-
458-
/* Save pointer to DTB for early FDT parsing */
459-
dtb_early_va = (void *)fix_to_virt(FIX_FDT) + (dtb_pa & ~PAGE_MASK);
460-
/* Save physical address for memblock reservation */
451+
/* Create two consecutive PGD mappings for FDT early scan */
452+
pa = dtb_pa & ~(PGDIR_SIZE - 1);
453+
create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
454+
pa, PGDIR_SIZE, PAGE_KERNEL);
455+
create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE,
456+
pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL);
457+
dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1));
461458
dtb_early_pa = dtb_pa;
462459
}
463460

@@ -516,6 +513,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
516513
#else
517514
dtb_early_va = (void *)dtb_pa;
518515
#endif
516+
dtb_early_pa = dtb_pa;
519517
}
520518

521519
static inline void setup_vm_final(void)

0 commit comments

Comments
 (0)