xref: /OK3568_Linux_fs/kernel/arch/m68k/mm/sun3mmu.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * linux/arch/m68k/mm/sun3mmu.c
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Implementations of mm routines specific to the sun3 MMU.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Moved here 8/20/1999 Sam Creasey
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/signal.h>
12*4882a593Smuzhiyun #include <linux/sched.h>
13*4882a593Smuzhiyun #include <linux/mm.h>
14*4882a593Smuzhiyun #include <linux/swap.h>
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/string.h>
17*4882a593Smuzhiyun #include <linux/types.h>
18*4882a593Smuzhiyun #include <linux/init.h>
19*4882a593Smuzhiyun #include <linux/memblock.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include <asm/setup.h>
22*4882a593Smuzhiyun #include <linux/uaccess.h>
23*4882a593Smuzhiyun #include <asm/page.h>
24*4882a593Smuzhiyun #include <asm/machdep.h>
25*4882a593Smuzhiyun #include <asm/io.h>
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun extern void mmu_emu_init (unsigned long bootmem_end);
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun extern unsigned long num_pages;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* For the sun3 we try to follow the i386 paging_init() more closely */
34*4882a593Smuzhiyun /* start_mem and end_mem have PAGE_OFFSET added already */
35*4882a593Smuzhiyun /* now sets up tables using sun3 PTEs rather than i386 as before. --m */
paging_init(void)36*4882a593Smuzhiyun void __init paging_init(void)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun 	pgd_t * pg_dir;
39*4882a593Smuzhiyun 	pte_t * pg_table;
40*4882a593Smuzhiyun 	int i;
41*4882a593Smuzhiyun 	unsigned long address;
42*4882a593Smuzhiyun 	unsigned long next_pgtable;
43*4882a593Smuzhiyun 	unsigned long bootmem_end;
44*4882a593Smuzhiyun 	unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, };
45*4882a593Smuzhiyun 	unsigned long size;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
48*4882a593Smuzhiyun 	if (!empty_zero_page)
49*4882a593Smuzhiyun 		panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
50*4882a593Smuzhiyun 		      __func__, PAGE_SIZE, PAGE_SIZE);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	address = PAGE_OFFSET;
53*4882a593Smuzhiyun 	pg_dir = swapper_pg_dir;
54*4882a593Smuzhiyun 	memset (swapper_pg_dir, 0, sizeof (swapper_pg_dir));
55*4882a593Smuzhiyun 	memset (kernel_pg_dir,  0, sizeof (kernel_pg_dir));
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	size = num_pages * sizeof(pte_t);
58*4882a593Smuzhiyun 	size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	next_pgtable = (unsigned long)memblock_alloc(size, PAGE_SIZE);
61*4882a593Smuzhiyun 	if (!next_pgtable)
62*4882a593Smuzhiyun 		panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
63*4882a593Smuzhiyun 		      __func__, size, PAGE_SIZE);
64*4882a593Smuzhiyun 	bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	/* Map whole memory from PAGE_OFFSET (0x0E000000) */
67*4882a593Smuzhiyun 	pg_dir += PAGE_OFFSET >> PGDIR_SHIFT;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	while (address < (unsigned long)high_memory) {
70*4882a593Smuzhiyun 		pg_table = (pte_t *) __pa (next_pgtable);
71*4882a593Smuzhiyun 		next_pgtable += PTRS_PER_PTE * sizeof (pte_t);
72*4882a593Smuzhiyun 		pgd_val(*pg_dir) = (unsigned long) pg_table;
73*4882a593Smuzhiyun 		pg_dir++;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 		/* now change pg_table to kernel virtual addresses */
76*4882a593Smuzhiyun 		pg_table = (pte_t *) __va ((unsigned long) pg_table);
77*4882a593Smuzhiyun 		for (i=0; i<PTRS_PER_PTE; ++i, ++pg_table) {
78*4882a593Smuzhiyun 			pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
79*4882a593Smuzhiyun 			if (address >= (unsigned long)high_memory)
80*4882a593Smuzhiyun 				pte_val (pte) = 0;
81*4882a593Smuzhiyun 			set_pte (pg_table, pte);
82*4882a593Smuzhiyun 			address += PAGE_SIZE;
83*4882a593Smuzhiyun 		}
84*4882a593Smuzhiyun 	}
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	mmu_emu_init(bootmem_end);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	current->mm = NULL;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	/* memory sizing is a hack stolen from motorola.c..  hope it works for us */
91*4882a593Smuzhiyun 	max_zone_pfn[ZONE_DMA] = ((unsigned long)high_memory) >> PAGE_SHIFT;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	/* I really wish I knew why the following change made things better...  -- Sam */
94*4882a593Smuzhiyun 	free_area_init(max_zone_pfn);
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun }
98