diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2015-10-28 09:36:10 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-10-28 10:20:26 -0400 |
commit | 29e332261d2ae0900e3befffd90cd70594cd7a84 (patch) | |
tree | a55f6160b622b245d6de1c776edf4dbd9c060203 | |
parent | 45890f6d34e70d9dd194bd1729eba3ff72cabf78 (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.dts | 12 | ||||
-rw-r--r-- | arch/arc/mm/init.c | 70 |
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); | |||
27 | static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE; | 28 | static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE; |
28 | static unsigned long low_mem_sz; | 29 | static unsigned long low_mem_sz; |
29 | 30 | ||
31 | #ifdef CONFIG_HIGHMEM | ||
32 | static unsigned long min_high_pfn; | ||
33 | static u64 high_mem_start; | ||
34 | static 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 */ |
31 | static int __init setup_mem_sz(char *str) | 38 | static int __init setup_mem_sz(char *str) |
32 | { | 39 | { |
@@ -41,10 +48,22 @@ early_param("mem", setup_mem_sz); | |||
41 | 48 | ||
42 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | 49 | void __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); | |||
74 | void __init setup_arch_memory(void) | 93 | void __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 | */ |
126 | void __init mem_init(void) | 176 | void __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 | } |