diff options
Diffstat (limited to 'arch/arm/mm/init.c')
| -rw-r--r-- | arch/arm/mm/init.c | 178 | 
1 files changed, 55 insertions, 123 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index febaee7ca57..659c75d808d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -17,13 +17,13 @@  #include <linux/nodemask.h>  #include <linux/initrd.h>  #include <linux/of_fdt.h> -#include <linux/of_reserved_mem.h>  #include <linux/highmem.h>  #include <linux/gfp.h>  #include <linux/memblock.h>  #include <linux/dma-contiguous.h>  #include <linux/sizes.h> +#include <asm/cp15.h>  #include <asm/mach-types.h>  #include <asm/memblock.h>  #include <asm/prom.h> @@ -37,6 +37,14 @@  #include "mm.h" +#ifdef CONFIG_CPU_CP15_MMU +unsigned long __init __clear_cr(unsigned long mask) +{ +	cr_alignment = cr_alignment & ~mask; +	return cr_alignment; +} +#endif +  static phys_addr_t phys_initrd_start __initdata = 0;  static unsigned long phys_initrd_size __initdata = 0; @@ -77,40 +85,26 @@ static int __init parse_tag_initrd2(const struct tag *tag)  __tagtable(ATAG_INITRD2, parse_tag_initrd2); -#ifdef CONFIG_OF_FLATTREE -void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) -{ -	phys_initrd_start = start; -	phys_initrd_size = end - start; -} -#endif /* CONFIG_OF_FLATTREE */ -  /*   * This keeps memory configuration data used by a couple memory   * initialization functions, as well as show_mem() for the skipping   * of holes in the memory map.  It is populated by arm_add_memory().   */ -struct meminfo meminfo; -  void show_mem(unsigned int filter)  {  	int free = 0, total = 0, reserved = 0; -	int shared = 0, cached = 0, slab = 0, i; -	struct meminfo * mi = &meminfo; +	int shared = 0, cached = 0, slab = 0; +	struct memblock_region *reg;  	printk("Mem-info:\n");  	show_free_areas(filter); -	if (filter & SHOW_MEM_FILTER_PAGE_COUNT) -		return; - -	for_each_bank (i, mi) { -		struct membank *bank = &mi->bank[i]; +	for_each_memblock (memory, reg) {  		unsigned int pfn1, pfn2;  		struct page *page, *end; -		pfn1 = bank_pfn_start(bank); -		pfn2 = bank_pfn_end(bank); +		pfn1 = memblock_region_memory_base_pfn(reg); +		pfn2 = memblock_region_memory_end_pfn(reg);  		page = pfn_to_page(pfn1);  		end  = pfn_to_page(pfn2 - 1) + 1; @@ -127,8 +121,9 @@ void show_mem(unsigned int filter)  				free++;  			else  				shared += page_count(page) - 1; -			page++; -		} while (page < end); +			pfn1++; +			page = pfn_to_page(pfn1); +		} while (pfn1 < pfn2);  	}  	printk("%d pages of RAM\n", total); @@ -142,68 +137,9 @@ void show_mem(unsigned int filter)  static void __init find_limits(unsigned long *min, unsigned long *max_low,  			       unsigned long *max_high)  { -	struct meminfo *mi = &meminfo; -	int i; - -	/* This assumes the meminfo array is properly sorted */ -	*min = bank_pfn_start(&mi->bank[0]); -	for_each_bank (i, mi) -		if (mi->bank[i].highmem) -				break; -	*max_low = bank_pfn_end(&mi->bank[i - 1]); -	*max_high = bank_pfn_end(&mi->bank[mi->nr_banks - 1]); -} - -static void __init arm_bootmem_init(unsigned long start_pfn, -	unsigned long end_pfn) -{ -	struct memblock_region *reg; -	unsigned int boot_pages; -	phys_addr_t bitmap; -	pg_data_t *pgdat; - -	/* -	 * Allocate the bootmem bitmap page.  This must be in a region -	 * of memory which has already been mapped. -	 */ -	boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn); -	bitmap = memblock_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES, -				__pfn_to_phys(end_pfn)); - -	/* -	 * Initialise the bootmem allocator, handing the -	 * memory banks over to bootmem. -	 */ -	node_set_online(0); -	pgdat = NODE_DATA(0); -	init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn); - -	/* Free the lowmem regions from memblock into bootmem. */ -	for_each_memblock(memory, reg) { -		unsigned long start = memblock_region_memory_base_pfn(reg); -		unsigned long end = memblock_region_memory_end_pfn(reg); - -		if (end >= end_pfn) -			end = end_pfn; -		if (start >= end) -			break; - -		free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT); -	} - -	/* Reserve the lowmem memblock reserved regions in bootmem. */ -	for_each_memblock(reserved, reg) { -		unsigned long start = memblock_region_reserved_base_pfn(reg); -		unsigned long end = memblock_region_reserved_end_pfn(reg); - -		if (end >= end_pfn) -			end = end_pfn; -		if (start >= end) -			break; - -		reserve_bootmem(__pfn_to_phys(start), -			        (end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT); -	} +	*max_low = PFN_DOWN(memblock_get_current_limit()); +	*min = PFN_UP(memblock_start_of_DRAM()); +	*max_high = PFN_DOWN(memblock_end_of_DRAM());  }  #ifdef CONFIG_ZONE_DMA @@ -218,6 +154,7 @@ EXPORT_SYMBOL(arm_dma_zone_size);   * so a successful GFP_DMA allocation will always satisfy this.   */  phys_addr_t arm_dma_limit; +unsigned long arm_dma_pfn_limit;  static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,  	unsigned long dma_size) @@ -240,10 +177,11 @@ void __init setup_dma_zone(const struct machine_desc *mdesc)  		arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;  	} else  		arm_dma_limit = 0xffffffff; +	arm_dma_pfn_limit = arm_dma_limit >> PAGE_SHIFT;  #endif  } -static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, +static void __init zone_sizes_init(unsigned long min, unsigned long max_low,  	unsigned long max_high)  {  	unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; @@ -336,14 +274,8 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)  	return phys;  } -void __init arm_memblock_init(struct meminfo *mi, -	const struct machine_desc *mdesc) +void __init arm_memblock_init(const struct machine_desc *mdesc)  { -	int i; - -	for (i = 0; i < mi->nr_banks; i++) -		memblock_add(mi->bank[i].start, mi->bank[i].size); -  	/* Register the kernel text, kernel data and initrd with memblock. */  #ifdef CONFIG_XIP_KERNEL  	memblock_reserve(__pa(_sdata), _end - _sdata); @@ -351,6 +283,12 @@ void __init arm_memblock_init(struct meminfo *mi,  	memblock_reserve(__pa(_stext), _end - _stext);  #endif  #ifdef CONFIG_BLK_DEV_INITRD +	/* FDT scan will populate initrd_start */ +	if (initrd_start && !phys_initrd_size) { +		phys_initrd_start = __virt_to_phys(initrd_start); +		phys_initrd_size = initrd_end - initrd_start; +	} +	initrd_start = initrd_end = 0;  	if (phys_initrd_size &&  	    !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {  		pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n", @@ -373,13 +311,12 @@ void __init arm_memblock_init(struct meminfo *mi,  #endif  	arm_mm_memblock_reserve(); -	arm_dt_memblock_reserve();  	/* reserve any platform specific memblock areas */  	if (mdesc->reserve)  		mdesc->reserve(); -	early_init_dt_scan_reserved_mem(); +	early_init_fdt_scan_reserved_mem();  	/*  	 * reserve memory for DMA contigouos allocations, @@ -388,7 +325,6 @@ void __init arm_memblock_init(struct meminfo *mi,  	dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));  	arm_memblock_steal_permitted = false; -	memblock_allow_resize();  	memblock_dump_all();  } @@ -396,12 +332,11 @@ void __init bootmem_init(void)  {  	unsigned long min, max_low, max_high; +	memblock_allow_resize();  	max_low = max_high = 0;  	find_limits(&min, &max_low, &max_high); -	arm_bootmem_init(min, max_low); -  	/*  	 * Sparsemem tries to allocate bootmem in memory_present(),  	 * so must be done after the fixed reservations @@ -418,18 +353,16 @@ void __init bootmem_init(void)  	 * the sparse mem_map arrays initialized by sparse_init()  	 * for memmap_init_zone(), otherwise all PFNs are invalid.  	 */ -	arm_bootmem_free(min, max_low, max_high); +	zone_sizes_init(min, max_low, max_high);  	/*  	 * This doesn't seem to be used by the Linux memory manager any  	 * more, but is used by ll_rw_block.  If we can get rid of it, we  	 * also get rid of some of the stuff above as well. -	 * -	 * Note: max_low_pfn and max_pfn reflect the number of _pages_ in -	 * the system, not the maximum PFN.  	 */ -	max_low_pfn = max_low - PHYS_PFN_OFFSET; -	max_pfn = max_high - PHYS_PFN_OFFSET; +	min_low_pfn = min; +	max_low_pfn = max_low; +	max_pfn = max_high;  }  /* @@ -467,60 +400,59 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)  	 * free the section of the memmap array.  	 */  	if (pg < pgend) -		free_bootmem(pg, pgend - pg); +		memblock_free_early(pg, pgend - pg);  }  /*   * The mem_map array can get very big.  Free the unused area of the memory map.   */ -static void __init free_unused_memmap(struct meminfo *mi) +static void __init free_unused_memmap(void)  { -	unsigned long bank_start, prev_bank_end = 0; -	unsigned int i; +	unsigned long start, prev_end = 0; +	struct memblock_region *reg;  	/*  	 * This relies on each bank being in address order.  	 * The banks are sorted previously in bootmem_init().  	 */ -	for_each_bank(i, mi) { -		struct membank *bank = &mi->bank[i]; - -		bank_start = bank_pfn_start(bank); +	for_each_memblock(memory, reg) { +		start = memblock_region_memory_base_pfn(reg);  #ifdef CONFIG_SPARSEMEM  		/*  		 * Take care not to free memmap entries that don't exist  		 * due to SPARSEMEM sections which aren't present.  		 */ -		bank_start = min(bank_start, -				 ALIGN(prev_bank_end, PAGES_PER_SECTION)); +		start = min(start, +				 ALIGN(prev_end, PAGES_PER_SECTION));  #else  		/*  		 * Align down here since the VM subsystem insists that the  		 * memmap entries are valid from the bank start aligned to  		 * MAX_ORDER_NR_PAGES.  		 */ -		bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES); +		start = round_down(start, MAX_ORDER_NR_PAGES);  #endif  		/*  		 * If we had a previous bank, and there is a space  		 * between the current bank and the previous, free it.  		 */ -		if (prev_bank_end && prev_bank_end < bank_start) -			free_memmap(prev_bank_end, bank_start); +		if (prev_end && prev_end < start) +			free_memmap(prev_end, start);  		/*  		 * Align up here since the VM subsystem insists that the  		 * memmap entries are valid from the bank end aligned to  		 * MAX_ORDER_NR_PAGES.  		 */ -		prev_bank_end = ALIGN(bank_pfn_end(bank), MAX_ORDER_NR_PAGES); +		prev_end = ALIGN(memblock_region_memory_end_pfn(reg), +				 MAX_ORDER_NR_PAGES);  	}  #ifdef CONFIG_SPARSEMEM -	if (!IS_ALIGNED(prev_bank_end, PAGES_PER_SECTION)) -		free_memmap(prev_bank_end, -			    ALIGN(prev_bank_end, PAGES_PER_SECTION)); +	if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION)) +		free_memmap(prev_end, +			    ALIGN(prev_end, PAGES_PER_SECTION));  #endif  } @@ -535,7 +467,7 @@ static inline void free_area_high(unsigned long pfn, unsigned long end)  static void __init free_highpages(void)  {  #ifdef CONFIG_HIGHMEM -	unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET; +	unsigned long max_low = max_low_pfn;  	struct memblock_region *mem, *res;  	/* set highmem page free */ @@ -593,10 +525,10 @@ void __init mem_init(void)  	extern u32 itcm_end;  #endif -	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; +	set_max_mapnr(pfn_to_page(max_pfn) - mem_map);  	/* this will put all unused low memory onto the freelists */ -	free_unused_memmap(&meminfo); +	free_unused_memmap();  	free_all_bootmem();  #ifdef CONFIG_SA1111  | 
