^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * PowerPC version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * and Cort Dougan (PReP) (cort@cs.nmt.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 1996 Paul Mackerras
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Derived from "arch/i386/mm/init.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/initrd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/hugetlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/btext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/tlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/hugetlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/kup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/kasan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <mm/mmu_decl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #if (CONFIG_LOWMEM_SIZE > (0xF0000000 - PAGE_OFFSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_KERNEL_START"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) phys_addr_t total_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) phys_addr_t total_lowmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #ifdef CONFIG_RELOCATABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Used in __va()/__pa() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) long long virt_phys_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) EXPORT_SYMBOL(virt_phys_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) phys_addr_t lowmem_end_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int boot_mapsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #ifdef CONFIG_PPC_PMAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long agp_special_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) EXPORT_SYMBOL(agp_special_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) void MMU_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * this tells the system to map all of ram with the segregs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * (i.e. page tables) instead of the bats.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * -- Cort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int __map_without_bats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int __map_without_ltlbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* max amount of low RAM to map in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned long __max_low_memory = MAX_LOW_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Check for command-line options that affect what MMU_init will do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static void __init MMU_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Check for nobats option (used in mapin_ram). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (strstr(boot_command_line, "nobats")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) __map_without_bats = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (strstr(boot_command_line, "noltlbs")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) __map_without_ltlbs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (IS_ENABLED(CONFIG_PPC_8xx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (debug_pagealloc_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) __map_without_ltlbs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (strict_kernel_rwx_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __map_without_ltlbs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * MMU_init sets up the basic memory mappings for the kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * including both RAM and possibly some I/O regions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * and sets up the page tables and the MMU hardware ready to go.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void __init MMU_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (ppc_md.progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ppc_md.progress("MMU:enter", 0x111);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* parse args from command line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) MMU_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Reserve gigantic pages for hugetlb. This MUST occur before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * lowmem_end_addr is initialized below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (memblock.memory.cnt > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #ifndef CONFIG_WII
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) memblock_enforce_memory_limit(memblock.memory.regions[0].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pr_warn("Only using first contiguous memory region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) wii_memory_fixups();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) total_lowmem = total_memory = memblock_end_of_DRAM() - memstart_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) lowmem_end_addr = memstart_addr + total_lowmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #ifdef CONFIG_FSL_BOOKE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * entries, so we need to adjust lowmem to match the amount we can map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * in the fixed entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) adjust_total_lowmem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #endif /* CONFIG_FSL_BOOKE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (total_lowmem > __max_low_memory) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) total_lowmem = __max_low_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) lowmem_end_addr = memstart_addr + total_lowmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #ifndef CONFIG_HIGHMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) total_memory = total_lowmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) memblock_enforce_memory_limit(total_lowmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #endif /* CONFIG_HIGHMEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* Initialize the MMU hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (ppc_md.progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ppc_md.progress("MMU:hw init", 0x300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) MMU_init_hw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Map in all of RAM starting at KERNELBASE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (ppc_md.progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ppc_md.progress("MMU:mapin", 0x301);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mapin_ram();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Initialize early top-down ioremap allocator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ioremap_bot = IOREMAP_TOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ppc_md.progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ppc_md.progress("MMU:exit", 0x211);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* From now on, btext is no longer BAT mapped if it was at all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #ifdef CONFIG_BOOTX_TEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) btext_unmap();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) kasan_mmu_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) setup_kup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Shortly after that, the entire linear mapping will be available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) memblock_set_current_limit(lowmem_end_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }