aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2015-10-28 09:36:10 -0400
committerVineet Gupta <vgupta@synopsys.com>2015-10-28 10:20:26 -0400
commit29e332261d2ae0900e3befffd90cd70594cd7a84 (patch)
treea55f6160b622b245d6de1c776edf4dbd9c060203
parent45890f6d34e70d9dd194bd1729eba3ff72cabf78 (diff)
ARC: mm: HIGHMEM: populate high memory from DT
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r--arch/arc/boot/dts/nsim_hs.dts12
-rw-r--r--arch/arc/mm/init.c70
2 files changed, 74 insertions, 8 deletions
diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts
index 911f069e0540..b0eb0e7fe21d 100644
--- a/arch/arc/boot/dts/nsim_hs.dts
+++ b/arch/arc/boot/dts/nsim_hs.dts
@@ -11,8 +11,16 @@
11 11
12/ { 12/ {
13 compatible = "snps,nsim_hs"; 13 compatible = "snps,nsim_hs";
14 #address-cells = <2>;
15 #size-cells = <2>;
14 interrupt-parent = <&core_intc>; 16 interrupt-parent = <&core_intc>;
15 17
18 memory {
19 device_type = "memory";
20 reg = <0x0 0x80000000 0x0 0x40000000 /* 1 GB low mem */
21 0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */
22 };
23
16 chosen { 24 chosen {
17 bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8"; 25 bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8";
18 }; 26 };
@@ -26,8 +34,8 @@
26 #address-cells = <1>; 34 #address-cells = <1>;
27 #size-cells = <1>; 35 #size-cells = <1>;
28 36
29 /* child and parent address space 1:1 mapped */ 37 /* only perip space at end of low mem accessible */
30 ranges; 38 ranges = <0x80000000 0x0 0x80000000 0x80000000>;
31 39
32 core_intc: core-interrupt-controller { 40 core_intc: core-interrupt-controller {
33 compatible = "snps,archs-intc"; 41 compatible = "snps,archs-intc";
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index a726a229baf6..a9305b5a2cd4 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -15,6 +15,7 @@
15#endif 15#endif
16#include <linux/swap.h> 16#include <linux/swap.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/highmem.h>
18#include <asm/page.h> 19#include <asm/page.h>
19#include <asm/pgalloc.h> 20#include <asm/pgalloc.h>
20#include <asm/sections.h> 21#include <asm/sections.h>
@@ -27,6 +28,12 @@ EXPORT_SYMBOL(empty_zero_page);
27static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE; 28static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE;
28static unsigned long low_mem_sz; 29static unsigned long low_mem_sz;
29 30
31#ifdef CONFIG_HIGHMEM
32static unsigned long min_high_pfn;
33static u64 high_mem_start;
34static u64 high_mem_sz;
35#endif
36
30/* User can over-ride above with "mem=nnn[KkMm]" in cmdline */ 37/* User can over-ride above with "mem=nnn[KkMm]" in cmdline */
31static int __init setup_mem_sz(char *str) 38static int __init setup_mem_sz(char *str)
32{ 39{
@@ -41,10 +48,22 @@ early_param("mem", setup_mem_sz);
41 48
42void __init early_init_dt_add_memory_arch(u64 base, u64 size) 49void __init early_init_dt_add_memory_arch(u64 base, u64 size)
43{ 50{
44 low_mem_sz = size; 51 int in_use = 0;
45 BUG_ON(base != low_mem_start); 52
53 if (!low_mem_sz) {
54 BUG_ON(base != low_mem_start);
55 low_mem_sz = size;
56 in_use = 1;
57 } else {
58#ifdef CONFIG_HIGHMEM
59 high_mem_start = base;
60 high_mem_sz = size;
61 in_use = 1;
62#endif
63 }
46 64
47 pr_info("Memory @ %llx of %ldM\n", base, TO_MB(size)); 65 pr_info("Memory @ %llx [%lldM] %s\n",
66 base, TO_MB(size), !in_use ? "Not used":"");
48} 67}
49 68
50#ifdef CONFIG_BLK_DEV_INITRD 69#ifdef CONFIG_BLK_DEV_INITRD
@@ -74,6 +93,7 @@ early_param("initrd", early_initrd);
74void __init setup_arch_memory(void) 93void __init setup_arch_memory(void)
75{ 94{
76 unsigned long zones_size[MAX_NR_ZONES]; 95 unsigned long zones_size[MAX_NR_ZONES];
96 unsigned long zones_holes[MAX_NR_ZONES];
77 97
78 init_mm.start_code = (unsigned long)_text; 98 init_mm.start_code = (unsigned long)_text;
79 init_mm.end_code = (unsigned long)_etext; 99 init_mm.end_code = (unsigned long)_etext;
@@ -86,9 +106,26 @@ void __init setup_arch_memory(void)
86 /* Last usable page of low mem */ 106 /* Last usable page of low mem */
87 max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz); 107 max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz);
88 108
89 max_mapnr = max_low_pfn - min_low_pfn; 109#ifdef CONFIG_HIGHMEM
110 min_high_pfn = PFN_DOWN(high_mem_start);
111 max_pfn = PFN_DOWN(high_mem_start + high_mem_sz);
112#endif
113
114 max_mapnr = max_pfn - min_low_pfn;
90 115
91 /*------------- bootmem allocator setup -----------------------*/ 116 /*------------- bootmem allocator setup -----------------------*/
117
118 /*
119 * seed the bootmem allocator after any DT memory node parsing or
120 * "mem=xxx" cmdline overrides have potentially updated @arc_mem_sz
121 *
122 * Only low mem is added, otherwise we have crashes when allocating
123 * mem_map[] itself. NO_BOOTMEM allocates mem_map[] at the end of
124 * avail memory, ending in highmem with a > 32-bit address. However
125 * it then tries to memset it with a truncaed 32-bit handle, causing
126 * the crash
127 */
128
92 memblock_add(low_mem_start, low_mem_sz); 129 memblock_add(low_mem_start, low_mem_sz);
93 memblock_reserve(low_mem_start, __pa(_end) - low_mem_start); 130 memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
94 131
@@ -101,7 +138,17 @@ void __init setup_arch_memory(void)
101 138
102 /*----------------- node/zones setup --------------------------*/ 139 /*----------------- node/zones setup --------------------------*/
103 memset(zones_size, 0, sizeof(zones_size)); 140 memset(zones_size, 0, sizeof(zones_size));
141 memset(zones_holes, 0, sizeof(zones_holes));
142
104 zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; 143 zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
144 zones_holes[ZONE_NORMAL] = 0;
145
146#ifdef CONFIG_HIGHMEM
147 zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
148
149 /* This handles the peripheral address space hole */
150 zones_holes[ZONE_HIGHMEM] = min_high_pfn - max_low_pfn;
151#endif
105 152
106 /* 153 /*
107 * We can't use the helper free_area_init(zones[]) because it uses 154 * We can't use the helper free_area_init(zones[]) because it uses
@@ -112,9 +159,12 @@ void __init setup_arch_memory(void)
112 free_area_init_node(0, /* node-id */ 159 free_area_init_node(0, /* node-id */
113 zones_size, /* num pages per zone */ 160 zones_size, /* num pages per zone */
114 min_low_pfn, /* first pfn of node */ 161 min_low_pfn, /* first pfn of node */
115 NULL); /* NO holes */ 162 zones_holes); /* holes */
116 163
117 high_memory = (void *)end_mem; 164#ifdef CONFIG_HIGHMEM
165 high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
166 kmap_init();
167#endif
118} 168}
119 169
120/* 170/*
@@ -125,6 +175,14 @@ void __init setup_arch_memory(void)
125 */ 175 */
126void __init mem_init(void) 176void __init mem_init(void)
127{ 177{
178#ifdef CONFIG_HIGHMEM
179 unsigned long tmp;
180
181 reset_all_zones_managed_pages();
182 for (tmp = min_high_pfn; tmp < max_pfn; tmp++)
183 free_highmem_page(pfn_to_page(tmp));
184#endif
185
128 free_all_bootmem(); 186 free_all_bootmem();
129 mem_init_print_info(NULL); 187 mem_init_print_info(NULL);
130} 188}