mm: don't include asm/pgtable.h if linux/mm.h is already included
[platform/kernel/linux-starfive.git] / arch / powerpc / mm / nohash / fsl_booke.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
4  * E500 Book E processors.
5  *
6  * Copyright 2004,2010 Freescale Semiconductor, Inc.
7  *
8  * This file contains the routines for initializing the MMU
9  * on the 4xx series of chips.
10  *  -- paulus
11  *
12  *  Derived from arch/ppc/mm/init.c:
13  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
14  *
15  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
16  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
17  *    Copyright (C) 1996 Paul Mackerras
18  *
19  *  Derived from "arch/i386/mm/init.c"
20  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
21  */
22
23 #include <linux/signal.h>
24 #include <linux/sched.h>
25 #include <linux/kernel.h>
26 #include <linux/errno.h>
27 #include <linux/string.h>
28 #include <linux/types.h>
29 #include <linux/ptrace.h>
30 #include <linux/mman.h>
31 #include <linux/mm.h>
32 #include <linux/swap.h>
33 #include <linux/stddef.h>
34 #include <linux/vmalloc.h>
35 #include <linux/init.h>
36 #include <linux/delay.h>
37 #include <linux/highmem.h>
38 #include <linux/memblock.h>
39
40 #include <asm/pgalloc.h>
41 #include <asm/prom.h>
42 #include <asm/io.h>
43 #include <asm/mmu_context.h>
44 #include <asm/mmu.h>
45 #include <linux/uaccess.h>
46 #include <asm/smp.h>
47 #include <asm/machdep.h>
48 #include <asm/setup.h>
49 #include <asm/paca.h>
50
51 #include <mm/mmu_decl.h>
52
53 unsigned int tlbcam_index;
54
55 #define NUM_TLBCAMS     (64)
56 struct tlbcam TLBCAM[NUM_TLBCAMS];
57
58 struct tlbcamrange {
59         unsigned long start;
60         unsigned long limit;
61         phys_addr_t phys;
62 } tlbcam_addrs[NUM_TLBCAMS];
63
64 unsigned long tlbcam_sz(int idx)
65 {
66         return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1;
67 }
68
69 #ifdef CONFIG_FSL_BOOKE
70 /*
71  * Return PA for this VA if it is mapped by a CAM, or 0
72  */
73 phys_addr_t v_block_mapped(unsigned long va)
74 {
75         int b;
76         for (b = 0; b < tlbcam_index; ++b)
77                 if (va >= tlbcam_addrs[b].start && va < tlbcam_addrs[b].limit)
78                         return tlbcam_addrs[b].phys + (va - tlbcam_addrs[b].start);
79         return 0;
80 }
81
82 /*
83  * Return VA for a given PA or 0 if not mapped
84  */
85 unsigned long p_block_mapped(phys_addr_t pa)
86 {
87         int b;
88         for (b = 0; b < tlbcam_index; ++b)
89                 if (pa >= tlbcam_addrs[b].phys
90                         && pa < (tlbcam_addrs[b].limit-tlbcam_addrs[b].start)
91                               +tlbcam_addrs[b].phys)
92                         return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys);
93         return 0;
94 }
95 #endif
96
97 /*
98  * Set up a variable-size TLB entry (tlbcam). The parameters are not checked;
99  * in particular size must be a power of 4 between 4k and the max supported by
100  * an implementation; max may further be limited by what can be represented in
101  * an unsigned long (for example, 32-bit implementations cannot support a 4GB
102  * size).
103  */
104 static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
105                 unsigned long size, unsigned long flags, unsigned int pid)
106 {
107         unsigned int tsize;
108
109         tsize = __ilog2(size) - 10;
110
111 #if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
112         if ((flags & _PAGE_NO_CACHE) == 0)
113                 flags |= _PAGE_COHERENT;
114 #endif
115
116         TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1);
117         TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
118         TLBCAM[index].MAS2 = virt & PAGE_MASK;
119
120         TLBCAM[index].MAS2 |= (flags & _PAGE_WRITETHRU) ? MAS2_W : 0;
121         TLBCAM[index].MAS2 |= (flags & _PAGE_NO_CACHE) ? MAS2_I : 0;
122         TLBCAM[index].MAS2 |= (flags & _PAGE_COHERENT) ? MAS2_M : 0;
123         TLBCAM[index].MAS2 |= (flags & _PAGE_GUARDED) ? MAS2_G : 0;
124         TLBCAM[index].MAS2 |= (flags & _PAGE_ENDIAN) ? MAS2_E : 0;
125
126         TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SX | MAS3_SR;
127         TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
128         if (mmu_has_feature(MMU_FTR_BIG_PHYS))
129                 TLBCAM[index].MAS7 = (u64)phys >> 32;
130
131         /* Below is unlikely -- only for large user pages or similar */
132         if (pte_user(__pte(flags))) {
133            TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
134            TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
135         }
136
137         tlbcam_addrs[index].start = virt;
138         tlbcam_addrs[index].limit = virt + size - 1;
139         tlbcam_addrs[index].phys = phys;
140 }
141
142 unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
143                           phys_addr_t phys)
144 {
145         unsigned int camsize = __ilog2(ram);
146         unsigned int align = __ffs(virt | phys);
147         unsigned long max_cam;
148
149         if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
150                 /* Convert (4^max) kB to (2^max) bytes */
151                 max_cam = ((mfspr(SPRN_TLB1CFG) >> 16) & 0xf) * 2 + 10;
152                 camsize &= ~1U;
153                 align &= ~1U;
154         } else {
155                 /* Convert (2^max) kB to (2^max) bytes */
156                 max_cam = __ilog2(mfspr(SPRN_TLB1PS)) + 10;
157         }
158
159         if (camsize > align)
160                 camsize = align;
161         if (camsize > max_cam)
162                 camsize = max_cam;
163
164         return 1UL << camsize;
165 }
166
167 static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
168                                         unsigned long ram, int max_cam_idx,
169                                         bool dryrun)
170 {
171         int i;
172         unsigned long amount_mapped = 0;
173
174         /* Calculate CAM values */
175         for (i = 0; ram && i < max_cam_idx; i++) {
176                 unsigned long cam_sz;
177
178                 cam_sz = calc_cam_sz(ram, virt, phys);
179                 if (!dryrun)
180                         settlbcam(i, virt, phys, cam_sz,
181                                   pgprot_val(PAGE_KERNEL_X), 0);
182
183                 ram -= cam_sz;
184                 amount_mapped += cam_sz;
185                 virt += cam_sz;
186                 phys += cam_sz;
187         }
188
189         if (dryrun)
190                 return amount_mapped;
191
192         loadcam_multi(0, i, max_cam_idx);
193         tlbcam_index = i;
194
195 #ifdef CONFIG_PPC64
196         get_paca()->tcd.esel_next = i;
197         get_paca()->tcd.esel_max = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
198         get_paca()->tcd.esel_first = i;
199 #endif
200
201         return amount_mapped;
202 }
203
204 unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun)
205 {
206         unsigned long virt = PAGE_OFFSET;
207         phys_addr_t phys = memstart_addr;
208
209         return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx, dryrun);
210 }
211
212 #ifdef CONFIG_PPC32
213
214 #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
215 #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
216 #endif
217
218 unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
219 {
220         return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1;
221 }
222
223 /*
224  * MMU_init_hw does the chip-specific initialization of the MMU hardware.
225  */
226 void __init MMU_init_hw(void)
227 {
228         flush_instruction_cache();
229 }
230
231 void __init adjust_total_lowmem(void)
232 {
233         unsigned long ram;
234         int i;
235
236         /* adjust lowmem size to __max_low_memory */
237         ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
238
239         i = switch_to_as1();
240         __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, false);
241         restore_to_as0(i, 0, 0, 1);
242
243         pr_info("Memory CAM mapping: ");
244         for (i = 0; i < tlbcam_index - 1; i++)
245                 pr_cont("%lu/", tlbcam_sz(i) >> 20);
246         pr_cont("%lu Mb, residual: %dMb\n", tlbcam_sz(tlbcam_index - 1) >> 20,
247                 (unsigned int)((total_lowmem - __max_low_memory) >> 20));
248
249         memblock_set_current_limit(memstart_addr + __max_low_memory);
250 }
251
252 void setup_initial_memory_limit(phys_addr_t first_memblock_base,
253                                 phys_addr_t first_memblock_size)
254 {
255         phys_addr_t limit = first_memblock_base + first_memblock_size;
256
257         /* 64M mapped initially according to head_fsl_booke.S */
258         memblock_set_current_limit(min_t(u64, limit, 0x04000000));
259 }
260
261 #ifdef CONFIG_RELOCATABLE
262 int __initdata is_second_reloc;
263 notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start)
264 {
265         unsigned long base = kernstart_virt_addr;
266         phys_addr_t size;
267
268         kernstart_addr = start;
269         if (is_second_reloc) {
270                 virt_phys_offset = PAGE_OFFSET - memstart_addr;
271                 kaslr_late_init();
272                 return;
273         }
274
275         /*
276          * Relocatable kernel support based on processing of dynamic
277          * relocation entries. Before we get the real memstart_addr,
278          * We will compute the virt_phys_offset like this:
279          * virt_phys_offset = stext.run - kernstart_addr
280          *
281          * stext.run = (KERNELBASE & ~0x3ffffff) +
282          *                              (kernstart_addr & 0x3ffffff)
283          * When we relocate, we have :
284          *
285          *      (kernstart_addr & 0x3ffffff) = (stext.run & 0x3ffffff)
286          *
287          * hence:
288          *  virt_phys_offset = (KERNELBASE & ~0x3ffffff) -
289          *                              (kernstart_addr & ~0x3ffffff)
290          *
291          */
292         start &= ~0x3ffffff;
293         base &= ~0x3ffffff;
294         virt_phys_offset = base - start;
295         early_get_first_memblock_info(__va(dt_ptr), &size);
296         /*
297          * We now get the memstart_addr, then we should check if this
298          * address is the same as what the PAGE_OFFSET map to now. If
299          * not we have to change the map of PAGE_OFFSET to memstart_addr
300          * and do a second relocation.
301          */
302         if (start != memstart_addr) {
303                 int n;
304                 long offset = start - memstart_addr;
305
306                 is_second_reloc = 1;
307                 n = switch_to_as1();
308                 /* map a 64M area for the second relocation */
309                 if (memstart_addr > start)
310                         map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM,
311                                         false);
312                 else
313                         map_mem_in_cams_addr(start, PAGE_OFFSET + offset,
314                                         0x4000000, CONFIG_LOWMEM_CAM_NUM,
315                                         false);
316                 restore_to_as0(n, offset, __va(dt_ptr), 1);
317                 /* We should never reach here */
318                 panic("Relocation error");
319         }
320
321         kaslr_early_init(__va(dt_ptr), size);
322 }
323 #endif
324 #endif