init.c 25.0 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-only
P
Palmer Dabbelt 已提交
2 3
/*
 * Copyright (C) 2012 Regents of the University of California
4
 * Copyright (C) 2019 Western Digital Corporation or its affiliates.
N
Nick Kossifidis 已提交
5 6
 * Copyright (C) 2020 FORTH-ICS/CARV
 *  Nick Kossifidis <mick@ics.forth.gr>
P
Palmer Dabbelt 已提交
7 8 9 10 11
 */

#include <linux/init.h>
#include <linux/mm.h>
#include <linux/memblock.h>
M
Mike Rapoport 已提交
12
#include <linux/initrd.h>
P
Palmer Dabbelt 已提交
13
#include <linux/swap.h>
C
Christoph Hellwig 已提交
14
#include <linux/sizes.h>
15
#include <linux/of_fdt.h>
16
#include <linux/of_reserved_mem.h>
17
#include <linux/libfdt.h>
Z
Zong Li 已提交
18
#include <linux/set_memory.h>
K
Kefeng Wang 已提交
19
#include <linux/dma-map-ops.h>
N
Nick Kossifidis 已提交
20
#include <linux/crash_dump.h>
P
Palmer Dabbelt 已提交
21

22
#include <asm/fixmap.h>
P
Palmer Dabbelt 已提交
23 24
#include <asm/tlbflush.h>
#include <asm/sections.h>
25
#include <asm/soc.h>
P
Palmer Dabbelt 已提交
26
#include <asm/io.h>
Z
Zong Li 已提交
27
#include <asm/ptdump.h>
28
#include <asm/numa.h>
P
Palmer Dabbelt 已提交
29

30 31
#include "../kernel/head.h"

32 33
unsigned long kernel_virt_addr = KERNEL_LINK_ADDR;
EXPORT_SYMBOL(kernel_virt_addr);
V
Vitaly Wool 已提交
34 35 36
#ifdef CONFIG_XIP_KERNEL
#define kernel_virt_addr       (*((unsigned long *)XIP_FIXUP(&kernel_virt_addr)))
#endif
37

38 39 40 41
unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
							__page_aligned_bss;
EXPORT_SYMBOL(empty_zero_page);

42
extern char _start[];
A
Anup Patel 已提交
43
#define DTB_EARLY_BASE_VA      PGDIR_SIZE
V
Vitaly Wool 已提交
44 45
void *_dtb_early_va __initdata;
uintptr_t _dtb_early_pa __initdata;
46

47 48 49 50 51 52 53 54
struct pt_alloc_ops {
	pte_t *(*get_pte_virt)(phys_addr_t pa);
	phys_addr_t (*alloc_pte)(uintptr_t va);
#ifndef __PAGETABLE_PMD_FOLDED
	pmd_t *(*get_pmd_virt)(phys_addr_t pa);
	phys_addr_t (*alloc_pmd)(uintptr_t va);
#endif
};
55

K
Kefeng Wang 已提交
56 57
static phys_addr_t dma32_phys_limit __ro_after_init;

P
Palmer Dabbelt 已提交
58 59
static void __init zone_sizes_init(void)
{
C
Christoph Hellwig 已提交
60
	unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, };
P
Palmer Dabbelt 已提交
61

62
#ifdef CONFIG_ZONE_DMA32
K
Kefeng Wang 已提交
63
	max_zone_pfns[ZONE_DMA32] = PFN_DOWN(dma32_phys_limit);
64
#endif
C
Christoph Hellwig 已提交
65 66
	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;

67
	free_area_init(max_zone_pfns);
P
Palmer Dabbelt 已提交
68 69
}

70
static void __init setup_zero_page(void)
P
Palmer Dabbelt 已提交
71 72 73 74
{
	memset((void *)empty_zero_page, 0, PAGE_SIZE);
}

75
#if defined(CONFIG_MMU) && defined(CONFIG_DEBUG_VM)
Y
Yash Shah 已提交
76 77 78 79 80 81 82 83 84 85 86 87
static inline void print_mlk(char *name, unsigned long b, unsigned long t)
{
	pr_notice("%12s : 0x%08lx - 0x%08lx   (%4ld kB)\n", name, b, t,
		  (((t) - (b)) >> 10));
}

static inline void print_mlm(char *name, unsigned long b, unsigned long t)
{
	pr_notice("%12s : 0x%08lx - 0x%08lx   (%4ld MB)\n", name, b, t,
		  (((t) - (b)) >> 20));
}

88
static void __init print_vm_layout(void)
Y
Yash Shah 已提交
89 90 91 92 93 94 95 96 97 98 99 100
{
	pr_notice("Virtual kernel memory layout:\n");
	print_mlk("fixmap", (unsigned long)FIXADDR_START,
		  (unsigned long)FIXADDR_TOP);
	print_mlm("pci io", (unsigned long)PCI_IO_START,
		  (unsigned long)PCI_IO_END);
	print_mlm("vmemmap", (unsigned long)VMEMMAP_START,
		  (unsigned long)VMEMMAP_END);
	print_mlm("vmalloc", (unsigned long)VMALLOC_START,
		  (unsigned long)VMALLOC_END);
	print_mlm("lowmem", (unsigned long)PAGE_OFFSET,
		  (unsigned long)high_memory);
101 102 103 104
#ifdef CONFIG_64BIT
	print_mlm("kernel", (unsigned long)KERNEL_LINK_ADDR,
		  (unsigned long)ADDRESS_SPACE_END);
#endif
Y
Yash Shah 已提交
105 106 107 108 109
}
#else
static void print_vm_layout(void) { }
#endif /* CONFIG_DEBUG_VM */

P
Palmer Dabbelt 已提交
110 111 112 113 114 115 116
void __init mem_init(void)
{
#ifdef CONFIG_FLATMEM
	BUG_ON(!mem_map);
#endif /* CONFIG_FLATMEM */

	high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
117
	memblock_free_all();
P
Palmer Dabbelt 已提交
118

Y
Yash Shah 已提交
119
	print_vm_layout();
P
Palmer Dabbelt 已提交
120 121
}

122 123
void __init setup_bootmem(void)
{
124 125
	phys_addr_t vmlinux_end = __pa_symbol(&_end);
	phys_addr_t vmlinux_start = __pa_symbol(&_start);
K
Kefeng Wang 已提交
126
	phys_addr_t dram_end = memblock_end_of_DRAM();
A
Atish Patra 已提交
127
	phys_addr_t max_mapped_addr = __pa(~(ulong)0);
128

V
Vitaly Wool 已提交
129 130 131 132
#ifdef CONFIG_XIP_KERNEL
	vmlinux_start = __pa_symbol(&_sdata);
#endif

K
Kefeng Wang 已提交
133
	/* The maximal physical memory size is -PAGE_OFFSET. */
134
	memblock_enforce_memory_limit(-PAGE_OFFSET);
135

136 137 138 139 140 141 142
	/*
	 * Reserve from the start of the kernel to the end of the kernel
	 * and make sure we align the reservation on PMD_SIZE since we will
	 * map the kernel in the linear mapping as read-only: we do not want
	 * any allocation to happen between _end and the next pmd aligned page.
	 */
	memblock_reserve(vmlinux_start, (vmlinux_end - vmlinux_start + PMD_SIZE - 1) & PMD_MASK);
143

A
Atish Patra 已提交
144 145 146 147 148 149 150 151 152
	/*
	 * memblock allocator is not aware of the fact that last 4K bytes of
	 * the addressable memory can not be mapped because of IS_ERR_VALUE
	 * macro. Make sure that last 4k bytes are not usable by memblock
	 * if end of dram is equal to maximum addressable memory.
	 */
	if (max_mapped_addr == (dram_end - 1))
		memblock_set_current_limit(max_mapped_addr - 4096);

K
Kefeng Wang 已提交
153 154 155
	min_low_pfn = PFN_UP(memblock_start_of_DRAM());
	max_low_pfn = max_pfn = PFN_DOWN(dram_end);

K
Kefeng Wang 已提交
156
	dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
157
	set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
158

159
	reserve_initrd_mem();
160
	/*
161 162 163
	 * If DTB is built in, no need to reserve its memblock.
	 * Otherwise, do reserve it but avoid using
	 * early_init_fdt_reserve_self() since __pa() does
164 165
	 * not work for DTB pointers that are fixmap addresses
	 */
166 167
	if (!IS_ENABLED(CONFIG_BUILTIN_DTB))
		memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
168

169
	early_init_fdt_scan_reserved_mem();
K
Kefeng Wang 已提交
170
	dma_contiguous_reserve(dma32_phys_limit);
171 172
	memblock_allow_resize();
}
173

V
Vitaly Wool 已提交
174 175 176 177 178 179 180
#ifdef CONFIG_XIP_KERNEL

extern char _xiprom[], _exiprom[];
extern char _sdata[], _edata[];

#endif /* CONFIG_XIP_KERNEL */

C
Christoph Hellwig 已提交
181
#ifdef CONFIG_MMU
V
Vitaly Wool 已提交
182 183 184 185 186 187 188
static struct pt_alloc_ops _pt_ops __ro_after_init;

#ifdef CONFIG_XIP_KERNEL
#define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&_pt_ops))
#else
#define pt_ops _pt_ops
#endif
189

190
/* Offset between linear mapping virtual address and kernel load address */
191
unsigned long va_pa_offset __ro_after_init;
192
EXPORT_SYMBOL(va_pa_offset);
V
Vitaly Wool 已提交
193 194 195
#ifdef CONFIG_XIP_KERNEL
#define va_pa_offset   (*((unsigned long *)XIP_FIXUP(&va_pa_offset)))
#endif
196
/* Offset between kernel mapping virtual address and kernel load address */
V
Vitaly Wool 已提交
197
#ifdef CONFIG_64BIT
198 199 200
unsigned long va_kernel_pa_offset;
EXPORT_SYMBOL(va_kernel_pa_offset);
#endif
V
Vitaly Wool 已提交
201 202 203 204 205 206 207 208
#ifdef CONFIG_XIP_KERNEL
#define va_kernel_pa_offset    (*((unsigned long *)XIP_FIXUP(&va_kernel_pa_offset)))
#endif
unsigned long va_kernel_xip_pa_offset;
EXPORT_SYMBOL(va_kernel_xip_pa_offset);
#ifdef CONFIG_XIP_KERNEL
#define va_kernel_xip_pa_offset        (*((unsigned long *)XIP_FIXUP(&va_kernel_xip_pa_offset)))
#endif
209
unsigned long pfn_base __ro_after_init;
210 211
EXPORT_SYMBOL(pfn_base);

212
pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
213 214
pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
215

216
pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
217

V
Vitaly Wool 已提交
218 219 220 221 222 223
#ifdef CONFIG_XIP_KERNEL
#define trampoline_pg_dir      ((pgd_t *)XIP_FIXUP(trampoline_pg_dir))
#define fixmap_pte             ((pte_t *)XIP_FIXUP(fixmap_pte))
#define early_pg_dir           ((pgd_t *)XIP_FIXUP(early_pg_dir))
#endif /* CONFIG_XIP_KERNEL */

224 225 226 227 228 229 230 231 232
void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
{
	unsigned long addr = __fix_to_virt(idx);
	pte_t *ptep;

	BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses);

	ptep = &fixmap_pte[pte_index(addr)];

233
	if (pgprot_val(prot))
234
		set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
235
	else
236
		pte_clear(&init_mm, addr, ptep);
237
	local_flush_tlb_page(addr);
238 239
}

240
static inline pte_t *__init get_pte_virt_early(phys_addr_t pa)
241
{
242
	return (pte_t *)((uintptr_t)pa);
243 244
}

245 246 247 248 249 250 251 252 253 254 255 256
static inline pte_t *__init get_pte_virt_fixmap(phys_addr_t pa)
{
	clear_fixmap(FIX_PTE);
	return (pte_t *)set_fixmap_offset(FIX_PTE, pa);
}

static inline pte_t *get_pte_virt_late(phys_addr_t pa)
{
	return (pte_t *) __va(pa);
}

static inline phys_addr_t __init alloc_pte_early(uintptr_t va)
257 258 259 260 261
{
	/*
	 * We only create PMD or PGD early mappings so we
	 * should never reach here with MMU disabled.
	 */
262 263
	BUG();
}
264

265 266
static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va)
{
267 268 269
	return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}

270 271 272 273 274
static phys_addr_t alloc_pte_late(uintptr_t va)
{
	unsigned long vaddr;

	vaddr = __get_free_page(GFP_KERNEL);
275 276
	BUG_ON(!vaddr || !pgtable_pte_page_ctor(virt_to_page(vaddr)));

277 278 279
	return __pa(vaddr);
}

280 281 282 283
static void __init create_pte_mapping(pte_t *ptep,
				      uintptr_t va, phys_addr_t pa,
				      phys_addr_t sz, pgprot_t prot)
{
284
	uintptr_t pte_idx = pte_index(va);
285 286 287

	BUG_ON(sz != PAGE_SIZE);

288 289
	if (pte_none(ptep[pte_idx]))
		ptep[pte_idx] = pfn_pte(PFN_DOWN(pa), prot);
290 291 292 293 294 295
}

#ifndef __PAGETABLE_PMD_FOLDED

pmd_t trampoline_pmd[PTRS_PER_PMD] __page_aligned_bss;
pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss;
296
pmd_t early_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
297
pmd_t early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
298

V
Vitaly Wool 已提交
299 300 301 302 303 304
#ifdef CONFIG_XIP_KERNEL
#define trampoline_pmd ((pmd_t *)XIP_FIXUP(trampoline_pmd))
#define fixmap_pmd     ((pmd_t *)XIP_FIXUP(fixmap_pmd))
#define early_pmd      ((pmd_t *)XIP_FIXUP(early_pmd))
#endif /* CONFIG_XIP_KERNEL */

305
static pmd_t *__init get_pmd_virt_early(phys_addr_t pa)
306
{
307 308
	/* Before MMU is enabled */
	return (pmd_t *)((uintptr_t)pa);
309 310
}

311
static pmd_t *__init get_pmd_virt_fixmap(phys_addr_t pa)
312
{
313 314 315
	clear_fixmap(FIX_PMD);
	return (pmd_t *)set_fixmap_offset(FIX_PMD, pa);
}
316

317 318 319 320
static pmd_t *get_pmd_virt_late(phys_addr_t pa)
{
	return (pmd_t *) __va(pa);
}
321

322 323
static phys_addr_t __init alloc_pmd_early(uintptr_t va)
{
324
	BUG_ON((va - kernel_virt_addr) >> PGDIR_SHIFT);
325

326
	return (uintptr_t)early_pmd;
327 328
}

329 330 331 332 333 334 335 336 337 338 339 340 341 342
static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va)
{
	return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}

static phys_addr_t alloc_pmd_late(uintptr_t va)
{
	unsigned long vaddr;

	vaddr = __get_free_page(GFP_KERNEL);
	BUG_ON(!vaddr);
	return __pa(vaddr);
}

343 344 345 346 347 348
static void __init create_pmd_mapping(pmd_t *pmdp,
				      uintptr_t va, phys_addr_t pa,
				      phys_addr_t sz, pgprot_t prot)
{
	pte_t *ptep;
	phys_addr_t pte_phys;
349
	uintptr_t pmd_idx = pmd_index(va);
350 351

	if (sz == PMD_SIZE) {
352 353
		if (pmd_none(pmdp[pmd_idx]))
			pmdp[pmd_idx] = pfn_pmd(PFN_DOWN(pa), prot);
354 355 356
		return;
	}

357
	if (pmd_none(pmdp[pmd_idx])) {
358
		pte_phys = pt_ops.alloc_pte(va);
359
		pmdp[pmd_idx] = pfn_pmd(PFN_DOWN(pte_phys), PAGE_TABLE);
360
		ptep = pt_ops.get_pte_virt(pte_phys);
361 362
		memset(ptep, 0, PAGE_SIZE);
	} else {
363
		pte_phys = PFN_PHYS(_pmd_pfn(pmdp[pmd_idx]));
364
		ptep = pt_ops.get_pte_virt(pte_phys);
365 366 367 368 369 370
	}

	create_pte_mapping(ptep, va, pa, sz, prot);
}

#define pgd_next_t		pmd_t
371 372
#define alloc_pgd_next(__va)	pt_ops.alloc_pmd(__va)
#define get_pgd_next_virt(__pa)	pt_ops.get_pmd_virt(__pa)
373 374 375 376 377
#define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot)	\
	create_pmd_mapping(__nextp, __va, __pa, __sz, __prot)
#define fixmap_pgd_next		fixmap_pmd
#else
#define pgd_next_t		pte_t
378 379
#define alloc_pgd_next(__va)	pt_ops.alloc_pte(__va)
#define get_pgd_next_virt(__pa)	pt_ops.get_pte_virt(__pa)
380 381 382 383 384
#define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot)	\
	create_pte_mapping(__nextp, __va, __pa, __sz, __prot)
#define fixmap_pgd_next		fixmap_pte
#endif

A
Atish Patra 已提交
385
void __init create_pgd_mapping(pgd_t *pgdp,
386 387 388 389 390
				      uintptr_t va, phys_addr_t pa,
				      phys_addr_t sz, pgprot_t prot)
{
	pgd_next_t *nextp;
	phys_addr_t next_phys;
391
	uintptr_t pgd_idx = pgd_index(va);
392 393

	if (sz == PGDIR_SIZE) {
394 395
		if (pgd_val(pgdp[pgd_idx]) == 0)
			pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(pa), prot);
396 397 398
		return;
	}

399
	if (pgd_val(pgdp[pgd_idx]) == 0) {
400
		next_phys = alloc_pgd_next(va);
401
		pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(next_phys), PAGE_TABLE);
402 403 404
		nextp = get_pgd_next_virt(next_phys);
		memset(nextp, 0, PAGE_SIZE);
	} else {
405
		next_phys = PFN_PHYS(_pgd_pfn(pgdp[pgd_idx]));
406 407 408 409 410 411 412 413
		nextp = get_pgd_next_virt(next_phys);
	}

	create_pgd_next_mapping(nextp, va, pa, sz, prot);
}

static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
{
414 415 416
	/* Upgrade to PMD_SIZE mappings whenever possible */
	if ((base & (PMD_SIZE - 1)) || (size & (PMD_SIZE - 1)))
		return PAGE_SIZE;
417

418
	return PMD_SIZE;
419 420
}

V
Vitaly Wool 已提交
421 422 423 424 425 426 427 428 429 430 431 432 433
#ifdef CONFIG_XIP_KERNEL
/* called from head.S with MMU off */
asmlinkage void __init __copy_data(void)
{
	void *from = (void *)(&_sdata);
	void *end = (void *)(&_end);
	void *to = (void *)CONFIG_PHYS_RAM_BASE;
	size_t sz = (size_t)(end - from + 1);

	memcpy(to, from, sz);
}
#endif

434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
/*
 * setup_vm() is called from head.S with MMU-off.
 *
 * Following requirements should be honoured for setup_vm() to work
 * correctly:
 * 1) It should use PC-relative addressing for accessing kernel symbols.
 *    To achieve this we always use GCC cmodel=medany.
 * 2) The compiler instrumentation for FTRACE will not work for setup_vm()
 *    so disable compiler instrumentation when FTRACE is enabled.
 *
 * Currently, the above requirements are honoured by using custom CFLAGS
 * for init.o in mm/Makefile.
 */

#ifndef __riscv_cmodel_medany
449
#error "setup_vm() is called from head.S before relocate so it should not use absolute addressing."
450 451
#endif

452
uintptr_t load_pa, load_sz;
V
Vitaly Wool 已提交
453 454 455 456
#ifdef CONFIG_XIP_KERNEL
#define load_pa        (*((uintptr_t *)XIP_FIXUP(&load_pa)))
#define load_sz        (*((uintptr_t *)XIP_FIXUP(&load_sz)))
#endif
457

V
Vitaly Wool 已提交
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
#ifdef CONFIG_XIP_KERNEL
uintptr_t xiprom, xiprom_sz;
#define xiprom_sz      (*((uintptr_t *)XIP_FIXUP(&xiprom_sz)))
#define xiprom         (*((uintptr_t *)XIP_FIXUP(&xiprom)))

static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size)
{
	uintptr_t va, end_va;

	/* Map the flash resident part */
	end_va = kernel_virt_addr + xiprom_sz;
	for (va = kernel_virt_addr; va < end_va; va += map_size)
		create_pgd_mapping(pgdir, va,
				   xiprom + (va - kernel_virt_addr),
				   map_size, PAGE_KERNEL_EXEC);

	/* Map the data in RAM */
	end_va = kernel_virt_addr + XIP_OFFSET + load_sz;
	for (va = kernel_virt_addr + XIP_OFFSET; va < end_va; va += map_size)
		create_pgd_mapping(pgdir, va,
				   load_pa + (va - (kernel_virt_addr + XIP_OFFSET)),
				   map_size, PAGE_KERNEL);
}
#else
482 483 484 485 486 487 488 489 490 491
static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size)
{
	uintptr_t va, end_va;

	end_va = kernel_virt_addr + load_sz;
	for (va = kernel_virt_addr; va < end_va; va += map_size)
		create_pgd_mapping(pgdir, va,
				   load_pa + (va - kernel_virt_addr),
				   map_size, PAGE_KERNEL_EXEC);
}
V
Vitaly Wool 已提交
492
#endif
493

494
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
495
{
V
Vitaly Wool 已提交
496
	uintptr_t __maybe_unused pa;
497
	uintptr_t map_size;
A
Atish Patra 已提交
498 499 500
#ifndef __PAGETABLE_PMD_FOLDED
	pmd_t fix_bmap_spmd, fix_bmap_epmd;
#endif
501

V
Vitaly Wool 已提交
502 503 504 505 506 507 508 509 510
#ifdef CONFIG_XIP_KERNEL
	xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR;
	xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom);

	load_pa = (uintptr_t)CONFIG_PHYS_RAM_BASE;
	load_sz = (uintptr_t)(&_end) - (uintptr_t)(&_sdata);

	va_kernel_xip_pa_offset = kernel_virt_addr - xiprom;
#else
511 512
	load_pa = (uintptr_t)(&_start);
	load_sz = (uintptr_t)(&_end) - load_pa;
V
Vitaly Wool 已提交
513
#endif
514 515

	va_pa_offset = PAGE_OFFSET - load_pa;
516 517 518 519
#ifdef CONFIG_64BIT
	va_kernel_pa_offset = kernel_virt_addr - load_pa;
#endif

520
	pfn_base = PFN_DOWN(load_pa);
521

522 523 524 525
	/*
	 * Enforce boot alignment requirements of RV32 and
	 * RV64 by only allowing PMD or PGD mappings.
	 */
526
	map_size = PMD_SIZE;
527 528 529

	/* Sanity check alignment and size */
	BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0);
530 531
	BUG_ON((load_pa % map_size) != 0);

532 533 534 535 536 537
	pt_ops.alloc_pte = alloc_pte_early;
	pt_ops.get_pte_virt = get_pte_virt_early;
#ifndef __PAGETABLE_PMD_FOLDED
	pt_ops.alloc_pmd = alloc_pmd_early;
	pt_ops.get_pmd_virt = get_pmd_virt_early;
#endif
538 539 540
	/* Setup early PGD for fixmap */
	create_pgd_mapping(early_pg_dir, FIXADDR_START,
			   (uintptr_t)fixmap_pgd_next, PGDIR_SIZE, PAGE_TABLE);
541 542

#ifndef __PAGETABLE_PMD_FOLDED
543 544 545 546
	/* Setup fixmap PMD */
	create_pmd_mapping(fixmap_pmd, FIXADDR_START,
			   (uintptr_t)fixmap_pte, PMD_SIZE, PAGE_TABLE);
	/* Setup trampoline PGD and PMD */
547
	create_pgd_mapping(trampoline_pg_dir, kernel_virt_addr,
548
			   (uintptr_t)trampoline_pmd, PGDIR_SIZE, PAGE_TABLE);
V
Vitaly Wool 已提交
549 550 551 552
#ifdef CONFIG_XIP_KERNEL
	create_pmd_mapping(trampoline_pmd, kernel_virt_addr,
			   xiprom, PMD_SIZE, PAGE_KERNEL_EXEC);
#else
553
	create_pmd_mapping(trampoline_pmd, kernel_virt_addr,
554
			   load_pa, PMD_SIZE, PAGE_KERNEL_EXEC);
V
Vitaly Wool 已提交
555
#endif
556 557
#else
	/* Setup trampoline PGD */
558
	create_pgd_mapping(trampoline_pg_dir, kernel_virt_addr,
559 560
			   load_pa, PGDIR_SIZE, PAGE_KERNEL_EXEC);
#endif
561

562
	/*
563
	 * Setup early PGD covering entire kernel which will allow
564 565 566
	 * us to reach paging_init(). We map all memory banks later
	 * in setup_vm_final() below.
	 */
567
	create_kernel_page_table(early_pg_dir, map_size);
568

569 570 571 572
#ifndef __PAGETABLE_PMD_FOLDED
	/* Setup early PMD for DTB */
	create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
			   (uintptr_t)early_dtb_pmd, PGDIR_SIZE, PAGE_TABLE);
573
#ifndef CONFIG_BUILTIN_DTB
574 575 576 577 578 579 580
	/* Create two consecutive PMD mappings for FDT early scan */
	pa = dtb_pa & ~(PMD_SIZE - 1);
	create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA,
			   pa, PMD_SIZE, PAGE_KERNEL);
	create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE,
			   pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
	dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1));
581
#else /* CONFIG_BUILTIN_DTB */
582 583 584 585 586 587
#ifdef CONFIG_64BIT
	/*
	 * __va can't be used since it would return a linear mapping address
	 * whereas dtb_early_va will be used before setup_vm_final installs
	 * the linear mapping.
	 */
V
Vitaly Wool 已提交
588
	dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa));
589
#else
590
	dtb_early_va = __va(dtb_pa);
591
#endif /* CONFIG_64BIT */
592
#endif /* CONFIG_BUILTIN_DTB */
593
#else
594
#ifndef CONFIG_BUILTIN_DTB
A
Anup Patel 已提交
595 596 597 598 599 600 601
	/* Create two consecutive PGD mappings for FDT early scan */
	pa = dtb_pa & ~(PGDIR_SIZE - 1);
	create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
			   pa, PGDIR_SIZE, PAGE_KERNEL);
	create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE,
			   pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL);
	dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1));
602
#else /* CONFIG_BUILTIN_DTB */
603
#ifdef CONFIG_64BIT
V
Vitaly Wool 已提交
604
	dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa));
605
#else
606
	dtb_early_va = __va(dtb_pa);
607
#endif /* CONFIG_64BIT */
608
#endif /* CONFIG_BUILTIN_DTB */
609
#endif
610
	dtb_early_pa = dtb_pa;
A
Atish Patra 已提交
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640

	/*
	 * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap
	 * range can not span multiple pmds.
	 */
	BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
		     != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));

#ifndef __PAGETABLE_PMD_FOLDED
	/*
	 * Early ioremap fixmap is already created as it lies within first 2MB
	 * of fixmap region. We always map PMD_SIZE. Thus, both FIX_BTMAP_END
	 * FIX_BTMAP_BEGIN should lie in the same pmd. Verify that and warn
	 * the user if not.
	 */
	fix_bmap_spmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_BEGIN))];
	fix_bmap_epmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_END))];
	if (pmd_val(fix_bmap_spmd) != pmd_val(fix_bmap_epmd)) {
		WARN_ON(1);
		pr_warn("fixmap btmap start [%08lx] != end [%08lx]\n",
			pmd_val(fix_bmap_spmd), pmd_val(fix_bmap_epmd));
		pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
			fix_to_virt(FIX_BTMAP_BEGIN));
		pr_warn("fix_to_virt(FIX_BTMAP_END):   %08lx\n",
			fix_to_virt(FIX_BTMAP_END));

		pr_warn("FIX_BTMAP_END:       %d\n", FIX_BTMAP_END);
		pr_warn("FIX_BTMAP_BEGIN:     %d\n", FIX_BTMAP_BEGIN);
	}
#endif
641
}
642

V
Vitaly Wool 已提交
643
#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
void protect_kernel_linear_mapping_text_rodata(void)
{
	unsigned long text_start = (unsigned long)lm_alias(_start);
	unsigned long init_text_start = (unsigned long)lm_alias(__init_text_begin);
	unsigned long rodata_start = (unsigned long)lm_alias(__start_rodata);
	unsigned long data_start = (unsigned long)lm_alias(_data);

	set_memory_ro(text_start, (init_text_start - text_start) >> PAGE_SHIFT);
	set_memory_nx(text_start, (init_text_start - text_start) >> PAGE_SHIFT);

	set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
	set_memory_nx(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
}
#endif

659 660 661 662
static void __init setup_vm_final(void)
{
	uintptr_t va, map_size;
	phys_addr_t pa, start, end;
663
	u64 i;
664

665 666 667 668 669 670 671 672 673 674
	/**
	 * MMU is enabled at this point. But page table setup is not complete yet.
	 * fixmap page table alloc functions should be used at this point
	 */
	pt_ops.alloc_pte = alloc_pte_fixmap;
	pt_ops.get_pte_virt = get_pte_virt_fixmap;
#ifndef __PAGETABLE_PMD_FOLDED
	pt_ops.alloc_pmd = alloc_pmd_fixmap;
	pt_ops.get_pmd_virt = get_pmd_virt_fixmap;
#endif
675 676
	/* Setup swapper PGD for fixmap */
	create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
677
			   __pa_symbol(fixmap_pgd_next),
678
			   PGDIR_SIZE, PAGE_TABLE);
679

680
	/* Map all memory banks in the linear mapping */
681
	for_each_mem_range(i, &start, &end) {
682 683 684 685 686 687 688 689 690 691
		if (start >= end)
			break;
		if (start <= __pa(PAGE_OFFSET) &&
		    __pa(PAGE_OFFSET) < end)
			start = __pa(PAGE_OFFSET);

		map_size = best_map_size(start, end - start);
		for (pa = start; pa < end; pa += map_size) {
			va = (uintptr_t)__va(pa);
			create_pgd_mapping(swapper_pg_dir, va, pa,
692 693 694 695 696 697 698 699
					   map_size,
#ifdef CONFIG_64BIT
					   PAGE_KERNEL
#else
					   PAGE_KERNEL_EXEC
#endif
					);

700
		}
701
	}
702

703 704 705 706 707
#ifdef CONFIG_64BIT
	/* Map the kernel */
	create_kernel_page_table(swapper_pg_dir, PMD_SIZE);
#endif

708 709 710 711 712
	/* Clear fixmap PTE and PMD mappings */
	clear_fixmap(FIX_PTE);
	clear_fixmap(FIX_PMD);

	/* Move to swapper page table */
713
	csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE);
714
	local_flush_tlb_all();
715 716 717 718 719 720 721 722

	/* generic page allocation functions must be used to setup page table */
	pt_ops.alloc_pte = alloc_pte_late;
	pt_ops.get_pte_virt = get_pte_virt_late;
#ifndef __PAGETABLE_PMD_FOLDED
	pt_ops.alloc_pmd = alloc_pmd_late;
	pt_ops.get_pmd_virt = get_pmd_virt_late;
#endif
723
}
C
Christoph Hellwig 已提交
724 725 726 727
#else
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
{
	dtb_early_va = (void *)dtb_pa;
728
	dtb_early_pa = dtb_pa;
C
Christoph Hellwig 已提交
729 730 731 732 733 734
}

static inline void setup_vm_final(void)
{
}
#endif /* CONFIG_MMU */
735

Z
Zong Li 已提交
736
#ifdef CONFIG_STRICT_KERNEL_RWX
737
void __init protect_kernel_text_data(void)
Z
Zong Li 已提交
738
{
739 740 741
	unsigned long text_start = (unsigned long)_start;
	unsigned long init_text_start = (unsigned long)__init_text_begin;
	unsigned long init_data_start = (unsigned long)__init_data_begin;
Z
Zong Li 已提交
742 743 744 745
	unsigned long rodata_start = (unsigned long)__start_rodata;
	unsigned long data_start = (unsigned long)_data;
	unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn)));

746 747 748 749
	set_memory_ro(text_start, (init_text_start - text_start) >> PAGE_SHIFT);
	set_memory_ro(init_text_start, (init_data_start - init_text_start) >> PAGE_SHIFT);
	set_memory_nx(init_data_start, (rodata_start - init_data_start) >> PAGE_SHIFT);
	/* rodata section is marked readonly in mark_rodata_ro */
Z
Zong Li 已提交
750 751 752 753
	set_memory_nx(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
	set_memory_nx(data_start, (max_low - data_start) >> PAGE_SHIFT);
}

754
void mark_rodata_ro(void)
755
{
756 757
	unsigned long rodata_start = (unsigned long)__start_rodata;
	unsigned long data_start = (unsigned long)_data;
758

759
	set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
760

Z
Zong Li 已提交
761
	debug_checkwx();
762
}
Z
Zong Li 已提交
763
#endif
764

N
Nick Kossifidis 已提交
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
#ifdef CONFIG_KEXEC_CORE
/*
 * reserve_crashkernel() - reserves memory for crash kernel
 *
 * This function reserves memory area given in "crashkernel=" kernel command
 * line parameter. The memory reserved is used by dump capture kernel when
 * primary kernel is crashing.
 */
static void __init reserve_crashkernel(void)
{
	unsigned long long crash_base = 0;
	unsigned long long crash_size = 0;
	unsigned long search_start = memblock_start_of_DRAM();
	unsigned long search_end = memblock_end_of_DRAM();

	int ret = 0;

782 783 784 785 786 787 788 789 790 791 792 793
	/*
	 * Don't reserve a region for a crash kernel on a crash kernel
	 * since it doesn't make much sense and we have limited memory
	 * resources.
	 */
#ifdef CONFIG_CRASH_DUMP
	if (is_kdump_kernel()) {
		pr_info("crashkernel: ignoring reservation request\n");
		return;
	}
#endif

N
Nick Kossifidis 已提交
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841
	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
				&crash_size, &crash_base);
	if (ret || !crash_size)
		return;

	crash_size = PAGE_ALIGN(crash_size);

	if (crash_base == 0) {
		/*
		 * Current riscv boot protocol requires 2MB alignment for
		 * RV64 and 4MB alignment for RV32 (hugepage size)
		 */
		crash_base = memblock_find_in_range(search_start, search_end,
						    crash_size, PMD_SIZE);

		if (crash_base == 0) {
			pr_warn("crashkernel: couldn't allocate %lldKB\n",
				crash_size >> 10);
			return;
		}
	} else {
		/* User specifies base address explicitly. */
		if (!memblock_is_region_memory(crash_base, crash_size)) {
			pr_warn("crashkernel: requested region is not memory\n");
			return;
		}

		if (memblock_is_region_reserved(crash_base, crash_size)) {
			pr_warn("crashkernel: requested region is reserved\n");
			return;
		}


		if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
			pr_warn("crashkernel: requested region is misaligned\n");
			return;
		}
	}
	memblock_reserve(crash_base, crash_size);

	pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
		crash_base, crash_base + crash_size, crash_size >> 20);

	crashk_res.start = crash_base;
	crashk_res.end = crash_base + crash_size - 1;
}
#endif /* CONFIG_KEXEC_CORE */

842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
#ifdef CONFIG_CRASH_DUMP
/*
 * We keep track of the ELF core header of the crashed
 * kernel with a reserved-memory region with compatible
 * string "linux,elfcorehdr". Here we register a callback
 * to populate elfcorehdr_addr/size when this region is
 * present. Note that this region will be marked as
 * reserved once we call early_init_fdt_scan_reserved_mem()
 * later on.
 */
static int elfcore_hdr_setup(struct reserved_mem *rmem)
{
	elfcorehdr_addr = rmem->base;
	elfcorehdr_size = rmem->size;
	return 0;
}

RESERVEDMEM_OF_DECLARE(elfcorehdr, "linux,elfcorehdr", elfcore_hdr_setup);
#endif

862 863 864 865
void __init paging_init(void)
{
	setup_vm_final();
	setup_zero_page();
866 867 868 869
}

void __init misc_mem_init(void)
{
K
Kefeng Wang 已提交
870
	early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT);
871
	arch_numa_init();
872
	sparse_init();
873
	zone_sizes_init();
N
Nick Kossifidis 已提交
874 875 876
#ifdef CONFIG_KEXEC_CORE
	reserve_crashkernel();
#endif
877
	memblock_dump_all();
878
}
L
Logan Gunthorpe 已提交
879

880
#ifdef CONFIG_SPARSEMEM_VMEMMAP
L
Logan Gunthorpe 已提交
881 882 883
int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
			       struct vmem_altmap *altmap)
{
884
	return vmemmap_populate_basepages(start, end, node, NULL);
L
Logan Gunthorpe 已提交
885 886
}
#endif