]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - arch/arc/mm/init.c
ARC: [DeviceTree] Basic support
[mirror_ubuntu-hirsute-kernel.git] / arch / arc / mm / init.c
CommitLineData
c121c506
VG
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_BLOCK_DEV_RAM
14#include <linux/blk.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
23pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
24char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE);
25EXPORT_SYMBOL(empty_zero_page);
26
27/* Default tot mem from .config */
28static unsigned long arc_mem_sz = CONFIG_ARC_PLAT_SDRAM_SIZE;
29
30/* User can over-ride above with "mem=nnn[KkMm]" in cmdline */
31static int __init setup_mem_sz(char *str)
32{
33 arc_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(arc_mem_sz));
37
38 return 0;
39}
40early_param("mem", setup_mem_sz);
41
999159a5
VG
42void __init early_init_dt_add_memory_arch(u64 base, u64 size)
43{
44 pr_err("%s(%llx, %llx)\n", __func__, base, size);
45}
46
c121c506
VG
47/*
48 * First memory setup routine called from setup_arch()
49 * 1. setup swapper's mm @init_mm
50 * 2. Count the pages we have and setup bootmem allocator
51 * 3. zone setup
52 */
53void __init setup_arch_memory(void)
54{
55 unsigned long zones_size[MAX_NR_ZONES] = { 0, 0 };
56 unsigned long end_mem = CONFIG_LINUX_LINK_BASE + arc_mem_sz;
57
58 init_mm.start_code = (unsigned long)_text;
59 init_mm.end_code = (unsigned long)_etext;
60 init_mm.end_data = (unsigned long)_edata;
61 init_mm.brk = (unsigned long)_end;
62
63 /*
64 * We do it here, so that memory is correctly instantiated
65 * even if "mem=xxx" cmline over-ride is not given
66 */
67 memblock_add(CONFIG_LINUX_LINK_BASE, arc_mem_sz);
68
69 /*------------- externs in mm need setting up ---------------*/
70
71 /* first page of system - kernel .vector starts here */
72 min_low_pfn = PFN_DOWN(CONFIG_LINUX_LINK_BASE);
73
74 /* Last usable page of low mem (no HIGHMEM yet for ARC port) */
75 max_low_pfn = max_pfn = PFN_DOWN(end_mem);
76
77 max_mapnr = num_physpages = max_low_pfn - min_low_pfn;
78
79 /*------------- reserve kernel image -----------------------*/
80 memblock_reserve(CONFIG_LINUX_LINK_BASE,
81 __pa(_end) - CONFIG_LINUX_LINK_BASE);
82
83 memblock_dump_all();
84
85 /*-------------- node setup --------------------------------*/
86 memset(zones_size, 0, sizeof(zones_size));
87 zones_size[ZONE_NORMAL] = num_physpages;
88
89 /*
90 * We can't use the helper free_area_init(zones[]) because it uses
91 * PAGE_OFFSET to compute the @min_low_pfn which would be wrong
92 * when our kernel doesn't start at PAGE_OFFSET, i.e.
93 * PAGE_OFFSET != CONFIG_LINUX_LINK_BASE
94 */
95 free_area_init_node(0, /* node-id */
96 zones_size, /* num pages per zone */
97 min_low_pfn, /* first pfn of node */
98 NULL); /* NO holes */
99}
100
101/*
102 * mem_init - initializes memory
103 *
104 * Frees up bootmem
105 * Calculates and displays memory available/used
106 */
107void __init mem_init(void)
108{
109 int codesize, datasize, initsize, reserved_pages, free_pages;
110 int tmp;
111
112 high_memory = (void *)(CONFIG_LINUX_LINK_BASE + arc_mem_sz);
113
114 totalram_pages = free_all_bootmem();
115
116 /* count all reserved pages [kernel code/data/mem_map..] */
117 reserved_pages = 0;
118 for (tmp = 0; tmp < max_mapnr; tmp++)
119 if (PageReserved(mem_map + tmp))
120 reserved_pages++;
121
122 /* XXX: nr_free_pages() is equivalent */
123 free_pages = max_mapnr - reserved_pages;
124
125 /*
126 * For the purpose of display below, split the "reserve mem"
127 * kernel code/data is already shown explicitly,
128 * Show any other reservations (mem_map[ ] et al)
129 */
130 reserved_pages -= (((unsigned int)_end - CONFIG_LINUX_LINK_BASE) >>
131 PAGE_SHIFT);
132
133 codesize = _etext - _text;
134 datasize = _end - _etext;
135 initsize = __init_end - __init_begin;
136
137 pr_info("Memory Available: %dM / %ldM (%dK code, %dK data, %dK init, %dK reserv)\n",
138 PAGES_TO_MB(free_pages),
139 TO_MB(arc_mem_sz),
140 TO_KB(codesize), TO_KB(datasize), TO_KB(initsize),
141 PAGES_TO_KB(reserved_pages));
142}
143
144static void __init free_init_pages(const char *what, unsigned long begin,
145 unsigned long end)
146{
147 unsigned long addr;
148
149 pr_info("Freeing %s: %ldk [%lx] to [%lx]\n",
150 what, TO_KB(end - begin), begin, end);
151
152 /* need to check that the page we free is not a partial page */
153 for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) {
154 ClearPageReserved(virt_to_page(addr));
155 init_page_count(virt_to_page(addr));
156 free_page(addr);
157 totalram_pages++;
158 }
159}
160
161/*
162 * free_initmem: Free all the __init memory.
163 */
164void __init_refok free_initmem(void)
165{
166 free_init_pages("unused kernel memory",
167 (unsigned long)__init_begin,
168 (unsigned long)__init_end);
169}
170
171#ifdef CONFIG_BLK_DEV_INITRD
172void __init free_initrd_mem(unsigned long start, unsigned long end)
173{
174 free_init_pages("initrd memory", start, end);
175}
176#endif
999159a5
VG
177
178#ifdef CONFIG_OF_FLATTREE
179void __init early_init_dt_setup_initrd_arch(unsigned long start,
180 unsigned long end)
181{
182 pr_err("%s(%lx, %lx)\n", __func__, start, end);
183}
184#endif /* CONFIG_OF_FLATTREE */