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