]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arc/mm/init.c
ARC: mm: preps ahead of HIGHMEM support #2
[karo-tx-linux.git] / arch / arc / mm / init.c
1 /*
2  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/mm.h>
11 #include <linux/bootmem.h>
12 #include <linux/memblock.h>
13 #ifdef CONFIG_BLK_DEV_INITRD
14 #include <linux/initrd.h>
15 #endif
16 #include <linux/swap.h>
17 #include <linux/module.h>
18 #include <asm/page.h>
19 #include <asm/pgalloc.h>
20 #include <asm/sections.h>
21 #include <asm/arcregs.h>
22
23 pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
24 char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE);
25 EXPORT_SYMBOL(empty_zero_page);
26
27 static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE;
28 static unsigned long low_mem_sz;
29
30 /* User can over-ride above with "mem=nnn[KkMm]" in cmdline */
31 static int __init setup_mem_sz(char *str)
32 {
33         low_mem_sz = memparse(str, NULL) & PAGE_MASK;
34
35         /* early console might not be setup yet - it will show up later */
36         pr_info("\"mem=%s\": mem sz set to %ldM\n", str, TO_MB(low_mem_sz));
37
38         return 0;
39 }
40 early_param("mem", setup_mem_sz);
41
42 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
43 {
44         low_mem_sz = size;
45         BUG_ON(base != low_mem_start);
46
47         pr_info("Memory @ %llx of %ldM\n", base, TO_MB(size));
48 }
49
50 #ifdef CONFIG_BLK_DEV_INITRD
51 static int __init early_initrd(char *p)
52 {
53         unsigned long start, size;
54         char *endp;
55
56         start = memparse(p, &endp);
57         if (*endp == ',') {
58                 size = memparse(endp + 1, NULL);
59
60                 initrd_start = (unsigned long)__va(start);
61                 initrd_end = (unsigned long)__va(start + size);
62         }
63         return 0;
64 }
65 early_param("initrd", early_initrd);
66 #endif
67
68 /*
69  * First memory setup routine called from setup_arch()
70  * 1. setup swapper's mm @init_mm
71  * 2. Count the pages we have and setup bootmem allocator
72  * 3. zone setup
73  */
74 void __init setup_arch_memory(void)
75 {
76         unsigned long zones_size[MAX_NR_ZONES];
77
78         init_mm.start_code = (unsigned long)_text;
79         init_mm.end_code = (unsigned long)_etext;
80         init_mm.end_data = (unsigned long)_edata;
81         init_mm.brk = (unsigned long)_end;
82
83         /* first page of system - kernel .vector starts here */
84         min_low_pfn = ARCH_PFN_OFFSET;
85
86         /* Last usable page of low mem */
87         max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz);
88
89         max_mapnr = max_low_pfn - min_low_pfn;
90
91         /*------------- bootmem allocator setup -----------------------*/
92         memblock_add(low_mem_start, low_mem_sz);
93         memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
94
95 #ifdef CONFIG_BLK_DEV_INITRD
96         if (initrd_start)
97                 memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
98 #endif
99
100         memblock_dump_all();
101
102         /*----------------- node/zones setup --------------------------*/
103         memset(zones_size, 0, sizeof(zones_size));
104         zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
105
106         /*
107          * We can't use the helper free_area_init(zones[]) because it uses
108          * PAGE_OFFSET to compute the @min_low_pfn which would be wrong
109          * when our kernel doesn't start at PAGE_OFFSET, i.e.
110          * PAGE_OFFSET != CONFIG_LINUX_LINK_BASE
111          */
112         free_area_init_node(0,                  /* node-id */
113                             zones_size,         /* num pages per zone */
114                             min_low_pfn,        /* first pfn of node */
115                             NULL);              /* NO holes */
116
117         high_memory = (void *)end_mem;
118 }
119
120 /*
121  * mem_init - initializes memory
122  *
123  * Frees up bootmem
124  * Calculates and displays memory available/used
125  */
126 void __init mem_init(void)
127 {
128         free_all_bootmem();
129         mem_init_print_info(NULL);
130 }
131
132 /*
133  * free_initmem: Free all the __init memory.
134  */
135 void __init_refok free_initmem(void)
136 {
137         free_initmem_default(-1);
138 }
139
140 #ifdef CONFIG_BLK_DEV_INITRD
141 void __init free_initrd_mem(unsigned long start, unsigned long end)
142 {
143         free_reserved_area((void *)start, (void *)end, -1, "initrd");
144 }
145 #endif