Blackfin arch: SMP supporting patchset: Blackfin kernel and memory management code
[deliverable/linux.git] / arch / blackfin / mm / init.c
CommitLineData
1394f032
BW
1/*
2 * File: arch/blackfin/mm/init.c
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
321f6e0f 10 * Copyright 2004-2007 Analog Devices Inc.
1394f032
BW
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>
1f83b8f1 32#include <linux/uaccess.h>
1394f032 33#include <asm/bfin-global.h>
8f65873e
GY
34#include <asm/pda.h>
35#include <asm/cplbinit.h>
1394f032
BW
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 */
51static unsigned long empty_bad_page_table;
52
53static unsigned long empty_bad_page;
54
55unsigned long empty_zero_page;
56
8f65873e
GY
57extern unsigned long exception_stack[NR_CPUS][1024];
58
59struct blackfin_pda cpu_pda[NR_CPUS];
60EXPORT_SYMBOL(cpu_pda);
61
1394f032
BW
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 */
321f6e0f 68void __init paging_init(void)
1394f032
BW
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
e3defffe
AL
98 zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
99 zones_size[ZONE_NORMAL] = 0;
1394f032
BW
100#ifdef CONFIG_HIGHMEM
101 zones_size[ZONE_HIGHMEM] = 0;
102#endif
103 free_area_init(zones_size);
104 }
105}
106
8f65873e
GY
107asmlinkage void 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_MPU
123#else
124 cpu_pda[cpu].ipdt = ipdt_tables[cpu];
125 cpu_pda[cpu].dpdt = dpdt_tables[cpu];
126#ifdef CONFIG_CPLB_INFO
127 cpu_pda[cpu].ipdt_swapcount = ipdt_swapcount_tables[cpu];
128 cpu_pda[cpu].dpdt_swapcount = dpdt_swapcount_tables[cpu];
129#endif
130#endif
131
132#ifdef CONFIG_SMP
133 cpu_pda[cpu].imask = 0x1f;
134#endif
135}
136
137void __cpuinit reserve_pda(void)
138{
139 printk(KERN_INFO "PDA for CPU%u reserved at %p\n", smp_processor_id(),
140 &cpu_pda[smp_processor_id()]);
141}
142
321f6e0f 143void __init mem_init(void)
1394f032
BW
144{
145 unsigned int codek = 0, datak = 0, initk = 0;
ee7883b7 146 unsigned int reservedpages = 0, freepages = 0;
1394f032 147 unsigned long tmp;
1394f032
BW
148 unsigned long start_mem = memory_start;
149 unsigned long end_mem = memory_end;
150
151 end_mem &= PAGE_MASK;
152 high_memory = (void *)end_mem;
153
154 start_mem = PAGE_ALIGN(start_mem);
155 max_mapnr = num_physpages = MAP_NR(high_memory);
856783b3 156 printk(KERN_DEBUG "Kernel managed physical pages: %lu\n", num_physpages);
1394f032
BW
157
158 /* This will put all memory onto the freelists. */
159 totalram_pages = free_all_bootmem();
160
ee7883b7
YL
161 reservedpages = 0;
162 for (tmp = 0; tmp < max_mapnr; tmp++)
163 if (PageReserved(pfn_to_page(tmp)))
164 reservedpages++;
165 freepages = max_mapnr - reservedpages;
166
167 /* do not count in kernel image between _rambase and _ramstart */
168 reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT;
169#if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
856783b3 170 reservedpages += (_ramend - memory_end - DMA_UNCACHED_REGION) >> PAGE_SHIFT;
ee7883b7
YL
171#endif
172
1394f032 173 codek = (_etext - _stext) >> 10;
1394f032 174 initk = (__init_end - __init_begin) >> 10;
ee7883b7 175 datak = ((_ramstart - _rambase) >> 10) - codek - initk;
1394f032 176
1394f032 177 printk(KERN_INFO
ee7883b7 178 "Memory available: %luk/%luk RAM, "
856783b3 179 "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n",
ee7883b7 180 (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10,
856783b3 181 initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10)));
5d481f49
SZ
182}
183
184static int __init sram_init(void)
185{
1394f032 186 /* Initialize the blackfin L1 Memory. */
5d481f49 187 bfin_sram_init();
1394f032 188
8f65873e
GY
189 /* Reserve the PDA space for the boot CPU right after we
190 * initialized the scratch memory allocator.
191 */
192 reserve_pda();
5d481f49 193 return 0;
1394f032 194}
5d481f49 195pure_initcall(sram_init);
1394f032 196
c051489d 197static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end)
1394f032 198{
1d189474
MF
199 unsigned long addr;
200 /* next to check that the page we free is not a partial page */
201 for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) {
202 ClearPageReserved(virt_to_page(addr));
203 init_page_count(virt_to_page(addr));
204 free_page(addr);
1394f032 205 totalram_pages++;
1394f032 206 }
1d189474
MF
207 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
208}
209
210#ifdef CONFIG_BLK_DEV_INITRD
211void __init free_initrd_mem(unsigned long start, unsigned long end)
212{
b97b8a99 213#ifndef CONFIG_MPU
1d189474 214 free_init_pages("initrd memory", start, end);
b97b8a99 215#endif
1394f032
BW
216}
217#endif
218
c051489d 219void __init_refok free_initmem(void)
1394f032 220{
b97b8a99 221#if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU
1d189474
MF
222 free_init_pages("unused kernel memory",
223 (unsigned long)(&__init_begin),
224 (unsigned long)(&__init_end));
1394f032
BW
225#endif
226}
This page took 0.256435 seconds and 5 git commands to generate.