10 #include <linux/kernel.h>
11 #include <linux/errno.h>
15 #include <linux/mman.h>
16 #include <linux/export.h>
27 #include <asm/memblock.h>
29 #include <asm/sections.h>
30 #include <asm/setup.h>
32 #include <asm/fixmap.h>
39 static unsigned long phys_initrd_start
__initdata = 0;
40 static unsigned long phys_initrd_size
__initdata = 0;
42 static int __init early_initrd(
char *
p)
51 phys_initrd_start =
start;
52 phys_initrd_size =
size;
58 static int __init parse_tag_initrd(
const struct tag *
tag)
61 "please update your bootloader.\n");
63 phys_initrd_size = tag->
u.
initrd.size;
69 static int __init parse_tag_initrd2(
const struct tag *
tag)
71 phys_initrd_start = tag->
u.
initrd.start;
72 phys_initrd_size = tag->
u.
initrd.size;
78 #ifdef CONFIG_OF_FLATTREE
81 phys_initrd_start =
start;
82 phys_initrd_size = end -
start;
104 unsigned int pfn1, pfn2;
115 if (PageReserved(page))
117 else if (PageSwapCache(page))
119 else if (PageSlab(page))
121 else if (!page_count(page))
124 shared += page_count(page) - 1;
126 }
while (page < end);
129 printk(
"%d pages of RAM\n", total);
130 printk(
"%d free pages\n", free);
133 printk(
"%d pages shared\n", shared);
137 static void __init find_limits(
unsigned long *
min,
unsigned long *max_low,
138 unsigned long *max_high)
152 static
void __init arm_bootmem_init(
unsigned long start_pfn,
153 unsigned long end_pfn)
155 struct memblock_region *
reg;
156 unsigned int boot_pages;
177 for_each_memblock(
memory, reg) {
178 unsigned long start = memblock_region_memory_base_pfn(reg);
179 unsigned long end = memblock_region_memory_end_pfn(reg);
191 unsigned long start = memblock_region_reserved_base_pfn(reg);
192 unsigned long end = memblock_region_reserved_end_pfn(reg);
204 #ifdef CONFIG_ZONE_DMA
217 static void __init arm_adjust_dma_zone(
unsigned long *size,
unsigned long *
hole,
218 unsigned long dma_size)
220 if (size[0] <= dma_size)
224 size[ZONE_DMA] = dma_size;
232 #ifdef CONFIG_ZONE_DMA
233 if (mdesc->dma_zone_size) {
234 arm_dma_zone_size = mdesc->dma_zone_size;
235 arm_dma_limit =
PHYS_OFFSET + arm_dma_zone_size - 1;
237 arm_dma_limit = 0xffffffff;
241 static void __init arm_bootmem_free(
unsigned long min,
unsigned long max_low,
242 unsigned long max_high)
244 unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
245 struct memblock_region *
reg;
250 memset(zone_size, 0,
sizeof(zone_size));
257 zone_size[0] = max_low -
min;
258 #ifdef CONFIG_HIGHMEM
259 zone_size[ZONE_HIGHMEM] = max_high - max_low;
266 memcpy(zhole_size, zone_size,
sizeof(zhole_size));
267 for_each_memblock(
memory, reg) {
268 unsigned long start = memblock_region_memory_base_pfn(reg);
269 unsigned long end = memblock_region_memory_end_pfn(reg);
271 if (start < max_low) {
272 unsigned long low_end =
min(end, max_low);
273 zhole_size[0] -= low_end -
start;
275 #ifdef CONFIG_HIGHMEM
277 unsigned long high_start =
max(start, max_low);
278 zhole_size[ZONE_HIGHMEM] -= end - high_start;
283 #ifdef CONFIG_ZONE_DMA
288 if (arm_dma_zone_size)
289 arm_adjust_dma_zone(zone_size, zhole_size,
296 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
304 #ifndef CONFIG_SPARSEMEM
305 static void __init arm_memory_present(
void)
309 static void __init arm_memory_present(
void)
311 struct memblock_region *
reg;
313 for_each_memblock(
memory, reg)
315 memblock_region_memory_end_pfn(reg));
319 static bool arm_memblock_steal_permitted =
true;
325 BUG_ON(!arm_memblock_steal_permitted);
342 #ifdef CONFIG_XIP_KERNEL
347 #ifdef CONFIG_BLK_DEV_INITRD
348 if (phys_initrd_size &&
350 pr_err(
"INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
351 phys_initrd_start, phys_initrd_size);
352 phys_initrd_start = phys_initrd_size = 0;
354 if (phys_initrd_size &&
356 pr_err(
"INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
357 phys_initrd_start, phys_initrd_size);
358 phys_initrd_start = phys_initrd_size = 0;
360 if (phys_initrd_size) {
382 arm_memblock_steal_permitted =
false;
389 unsigned long min, max_low, max_high;
391 max_low = max_high = 0;
393 find_limits(&min, &max_low, &max_high);
395 arm_bootmem_init(min, max_low);
401 arm_memory_present();
413 arm_bootmem_free(min, max_low, max_high);
427 static inline int free_area(
unsigned long pfn,
unsigned long end,
char *
s)
431 for (; pfn <
end; pfn++) {
433 ClearPageReserved(page);
434 init_page_count(page);
449 static inline void poison_init_mem(
void *s,
size_t count)
452 for (; count != 0; count -= 4)
457 free_memmap(
unsigned long start_pfn,
unsigned long end_pfn)
459 struct page *start_pg, *end_pg;
460 unsigned long pg, pgend;
488 unsigned long bank_start, prev_bank_end = 0;
500 #ifdef CONFIG_SPARSEMEM
505 bank_start =
min(bank_start,
506 ALIGN(prev_bank_end, PAGES_PER_SECTION));
519 if (prev_bank_end && prev_bank_end < bank_start)
520 free_memmap(prev_bank_end, bank_start);
530 #ifdef CONFIG_SPARSEMEM
531 if (!
IS_ALIGNED(prev_bank_end, PAGES_PER_SECTION))
532 free_memmap(prev_bank_end,
533 ALIGN(prev_bank_end, PAGES_PER_SECTION));
537 static void __init free_highpages(
void)
539 #ifdef CONFIG_HIGHMEM
541 struct memblock_region *
mem, *
res;
544 for_each_memblock(
memory, mem) {
545 unsigned long start = memblock_region_memory_base_pfn(mem);
546 unsigned long end = memblock_region_memory_end_pfn(mem);
558 unsigned long res_start, res_end;
560 res_start = memblock_region_reserved_base_pfn(res);
561 res_end = memblock_region_reserved_end_pfn(res);
565 if (res_start < start)
571 if (res_start != start)
595 struct memblock_region *
reg;
597 #ifdef CONFIG_HAVE_TCM
612 totalram_pages +=
free_area(PHYS_PFN_OFFSET,
618 reserved_pages = free_pages = 0;
622 unsigned int pfn1, pfn2;
632 if (PageReserved(page))
634 else if (!page_count(page))
637 }
while (page < end);
646 for_each_memblock(
memory, reg) {
647 unsigned long pages = memblock_region_memory_end_pfn(reg) -
648 memblock_region_memory_base_pfn(reg);
660 #define MLK(b, t) b, t, ((t) - (b)) >> 10
661 #define MLM(b, t) b, t, ((t) - (b)) >> 20
662 #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
665 " vector : 0x%08lx - 0x%08lx (%4ld kB)\n"
666 #ifdef CONFIG_HAVE_TCM
667 " DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
668 " ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
670 " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
671 " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
672 " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
673 #ifdef CONFIG_HIGHMEM
674 " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
676 #ifdef CONFIG_MODULES
677 " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
679 " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
680 " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
681 " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
682 " .bss : 0x%p" " - 0x%p" " (%4d kB)\n",
684 MLK(
UL(CONFIG_VECTORS_BASE),
UL(CONFIG_VECTORS_BASE) +
686 #ifdef CONFIG_HAVE_TCM
687 MLK(DTCM_OFFSET, (
unsigned long) dtcm_end),
688 MLK(ITCM_OFFSET, (
unsigned long) itcm_end),
693 #ifdef CONFIG_HIGHMEM
697 #ifdef CONFIG_MODULES
719 #ifdef CONFIG_HIGHMEM
737 #ifdef CONFIG_HAVE_TCM
738 extern char __tcm_start, __tcm_end;
740 poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start);
747 if (!machine_is_integrator() && !machine_is_cintegrator())
753 #ifdef CONFIG_BLK_DEV_INITRD
755 static int keep_initrd;
760 poison_init_mem((
void *)start,
PAGE_ALIGN(end) - start);
773 __setup(
"keepinitrd", keepinitrd_setup);