• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * File:         arch/blackfin/mm/init.c
3  * Based on:
4  * Author:
5  *
6  * Created:
7  * Description:
8  *
9  * Modified:
10  *               Copyright 2004-2007 Analog Devices Inc.
11  *
12  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, see the file COPYING, or write
26  * to the Free Software Foundation, Inc.,
27  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28  */
29 
30 #include <linux/swap.h>
31 #include <linux/bootmem.h>
32 #include <linux/uaccess.h>
33 #include <asm/bfin-global.h>
34 #include <asm/pda.h>
35 #include <asm/cplbinit.h>
36 #include "blackfin_sram.h"
37 
38 /*
39  * BAD_PAGE is the page that is used for page faults when linux
40  * is out-of-memory. Older versions of linux just did a
41  * do_exit(), but using this instead means there is less risk
42  * for a process dying in kernel mode, possibly leaving a inode
43  * unused etc..
44  *
45  * BAD_PAGETABLE is the accompanying page-table: it is initialized
46  * to point to BAD_PAGE entries.
47  *
48  * ZERO_PAGE is a special page that is used for zero-initialized
49  * data and COW.
50  */
51 static unsigned long empty_bad_page_table;
52 
53 static unsigned long empty_bad_page;
54 
55 unsigned long empty_zero_page;
56 
57 extern unsigned long exception_stack[NR_CPUS][1024];
58 
59 struct blackfin_pda cpu_pda[NR_CPUS];
60 EXPORT_SYMBOL(cpu_pda);
61 
62 /*
63  * paging_init() continues the virtual memory environment setup which
64  * was begun by the code in arch/head.S.
65  * The parameters are pointers to where to stick the starting and ending
66  * addresses  of available kernel virtual memory.
67  */
paging_init(void)68 void __init paging_init(void)
69 {
70 	/*
71 	 * make sure start_mem is page aligned,  otherwise bootmem and
72 	 * page_alloc get different views og the world
73 	 */
74 	unsigned long end_mem = memory_end & PAGE_MASK;
75 
76 	pr_debug("start_mem is %#lx   virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem);
77 
78 	/*
79 	 * initialize the bad page table and bad page to point
80 	 * to a couple of allocated pages
81 	 */
82 	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
83 	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
84 	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
85 	memset((void *)empty_zero_page, 0, PAGE_SIZE);
86 
87 	/*
88 	 * Set up SFC/DFC registers (user data space)
89 	 */
90 	set_fs(KERNEL_DS);
91 
92 	pr_debug("free_area_init -> start_mem is %#lx   virtual_end is %#lx\n",
93 	        PAGE_ALIGN(memory_start), end_mem);
94 
95 	{
96 		unsigned long zones_size[MAX_NR_ZONES] = { 0, };
97 
98 		zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
99 		zones_size[ZONE_NORMAL] = 0;
100 #ifdef CONFIG_HIGHMEM
101 		zones_size[ZONE_HIGHMEM] = 0;
102 #endif
103 		free_area_init(zones_size);
104 	}
105 }
106 
init_pda(void)107 asmlinkage void __init init_pda(void)
108 {
109 	unsigned int cpu = raw_smp_processor_id();
110 
111 	/* Initialize the PDA fields holding references to other parts
112 	   of the memory. The content of such memory is still
113 	   undefined at the time of the call, we are only setting up
114 	   valid pointers to it. */
115 	memset(&cpu_pda[cpu], 0, sizeof(cpu_pda[cpu]));
116 
117 	cpu_pda[0].next = &cpu_pda[1];
118 	cpu_pda[1].next = &cpu_pda[0];
119 
120 	cpu_pda[cpu].ex_stack = exception_stack[cpu + 1];
121 
122 #ifdef CONFIG_SMP
123 	cpu_pda[cpu].imask = 0x1f;
124 #endif
125 }
126 
reserve_pda(void)127 void __cpuinit reserve_pda(void)
128 {
129 	printk(KERN_INFO "PDA for CPU%u reserved at %p\n", smp_processor_id(),
130 					&cpu_pda[smp_processor_id()]);
131 }
132 
mem_init(void)133 void __init mem_init(void)
134 {
135 	unsigned int codek = 0, datak = 0, initk = 0;
136 	unsigned int reservedpages = 0, freepages = 0;
137 	unsigned long tmp;
138 	unsigned long start_mem = memory_start;
139 	unsigned long end_mem = memory_end;
140 
141 	end_mem &= PAGE_MASK;
142 	high_memory = (void *)end_mem;
143 
144 	start_mem = PAGE_ALIGN(start_mem);
145 	max_mapnr = num_physpages = MAP_NR(high_memory);
146 	printk(KERN_DEBUG "Kernel managed physical pages: %lu\n", num_physpages);
147 
148 	/* This will put all memory onto the freelists. */
149 	totalram_pages = free_all_bootmem();
150 
151 	reservedpages = 0;
152 	for (tmp = 0; tmp < max_mapnr; tmp++)
153 		if (PageReserved(pfn_to_page(tmp)))
154 			reservedpages++;
155 	freepages =  max_mapnr - reservedpages;
156 
157 	/* do not count in kernel image between _rambase and _ramstart */
158 	reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT;
159 #if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
160 	reservedpages += (_ramend - memory_end - DMA_UNCACHED_REGION) >> PAGE_SHIFT;
161 #endif
162 
163 	codek = (_etext - _stext) >> 10;
164 	initk = (__init_end - __init_begin) >> 10;
165 	datak = ((_ramstart - _rambase) >> 10) - codek - initk;
166 
167 	printk(KERN_INFO
168 	     "Memory available: %luk/%luk RAM, "
169 		"(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n",
170 		(unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10,
171 		initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10)));
172 }
173 
sram_init(void)174 static int __init sram_init(void)
175 {
176 	/* Initialize the blackfin L1 Memory. */
177 	bfin_sram_init();
178 
179 	/* Reserve the PDA space for the boot CPU right after we
180 	 * initialized the scratch memory allocator.
181 	 */
182 	reserve_pda();
183 	return 0;
184 }
185 pure_initcall(sram_init);
186 
free_init_pages(const char * what,unsigned long begin,unsigned long end)187 static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end)
188 {
189 	unsigned long addr;
190 	/* next to check that the page we free is not a partial page */
191 	for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) {
192 		ClearPageReserved(virt_to_page(addr));
193 		init_page_count(virt_to_page(addr));
194 		free_page(addr);
195 		totalram_pages++;
196 	}
197 	printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
198 }
199 
200 #ifdef CONFIG_BLK_DEV_INITRD
free_initrd_mem(unsigned long start,unsigned long end)201 void __init free_initrd_mem(unsigned long start, unsigned long end)
202 {
203 #ifndef CONFIG_MPU
204 	free_init_pages("initrd memory", start, end);
205 #endif
206 }
207 #endif
208 
free_initmem(void)209 void __init_refok free_initmem(void)
210 {
211 #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU
212 	free_init_pages("unused kernel memory",
213 			(unsigned long)(&__init_begin),
214 			(unsigned long)(&__init_end));
215 #endif
216 }
217