arch/riscv/mm/init.c

Source file repositories/reference/linux-study-clean/arch/riscv/mm/init.c

File Facts

System
Linux kernel
Corpus path
arch/riscv/mm/init.c
Extension
.c
Size
48299 bytes
Lines
1745
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static void print_vm_layout(void) { }
#endif /* CONFIG_DEBUG_VM */

void __init arch_mm_preinit(void)
{
	bool swiotlb = max_pfn > PFN_DOWN(dma32_phys_limit);
#ifdef CONFIG_FLATMEM
	BUG_ON(!mem_map);
#endif /* CONFIG_FLATMEM */

	if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb &&
	    dma_cache_alignment != 1) {
		/*
		 * If no bouncing needed for ZONE_DMA, allocate 1MB swiotlb
		 * buffer per 1GB of RAM for kmalloc() bouncing on
		 * non-coherent platforms.
		 */
		unsigned long size =
			DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
		swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
		swiotlb = true;
	}

	swiotlb_init(swiotlb, SWIOTLB_VERBOSE);

	print_vm_layout();
}

/* Limit the memory size via mem. */
static phys_addr_t memory_limit;

static int __init early_mem(char *p)
{
	u64 size;

	if (!p)
		return 1;

	size = memparse(p, &p) & PAGE_MASK;
	memory_limit = min_t(u64, size, memory_limit);

	pr_notice("Memory limited to %lldMB\n", (u64)memory_limit >> 20);

	return 0;
}
early_param("mem", early_mem);

static void __init setup_bootmem(void)
{
	phys_addr_t vmlinux_end = __pa_symbol(&_end);
	phys_addr_t max_mapped_addr;
	phys_addr_t phys_ram_end, vmlinux_start;

	vmlinux_start = __pa_symbol(&_start);

	memblock_enforce_memory_limit(memory_limit);

	/*
	 * 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.
	 */
	if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
		vmlinux_end = (vmlinux_end + PMD_SIZE - 1) & PMD_MASK;
	/*
	 * Reserve from the start of the kernel to the end of the kernel
	 */
	memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);

	/*
	 * Make sure we align the start of the memory on a PMD boundary so that
	 * at worst, we map the linear mapping with PMD mappings.
	 */
	phys_ram_base = memblock_start_of_DRAM() & PMD_MASK;
#ifdef CONFIG_SPARSEMEM_VMEMMAP
	vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
#endif

	/*
	 * In 64-bit, any use of __va/__pa before this point is wrong as we
	 * did not know the start of DRAM before.
	 */
	if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU))
		kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;

	/*
	 * The size of the linear page mapping may restrict the amount of
	 * usable RAM.
	 */
	if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) {

Annotation

Implementation Notes