diff options
| -rw-r--r-- | arch/powerpc/kernel/machine_kexec_64.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/kernel/prom.c | 89 | ||||
| -rw-r--r-- | arch/powerpc/kernel/prom_init.c | 55 | ||||
| -rw-r--r-- | arch/powerpc/kernel/setup_64.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/mm/lmb.c | 43 | ||||
| -rw-r--r-- | arch/powerpc/platforms/iseries/setup.c | 22 | ||||
| -rw-r--r-- | include/asm-powerpc/kexec.h | 13 |
7 files changed, 100 insertions, 130 deletions
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index ee166c586642..1ccb188ba40d 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
| @@ -339,3 +339,8 @@ void __init kexec_setup(void) | |||
| 339 | { | 339 | { |
| 340 | export_htab_values(); | 340 | export_htab_values(); |
| 341 | } | 341 | } |
| 342 | |||
| 343 | int overlaps_crashkernel(unsigned long start, unsigned long size) | ||
| 344 | { | ||
| 345 | return (start + size) > crashk_res.start && start <= crashk_res.end; | ||
| 346 | } | ||
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 4ca608c9cd72..a04f726d3bab 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #include <asm/machdep.h> | 50 | #include <asm/machdep.h> |
| 51 | #include <asm/pSeries_reconfig.h> | 51 | #include <asm/pSeries_reconfig.h> |
| 52 | #include <asm/pci-bridge.h> | 52 | #include <asm/pci-bridge.h> |
| 53 | #include <asm/kexec.h> | ||
| 53 | 54 | ||
| 54 | #ifdef DEBUG | 55 | #ifdef DEBUG |
| 55 | #define DBG(fmt...) printk(KERN_ERR fmt) | 56 | #define DBG(fmt...) printk(KERN_ERR fmt) |
| @@ -836,6 +837,42 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, | |||
| 836 | return mem; | 837 | return mem; |
| 837 | } | 838 | } |
| 838 | 839 | ||
| 840 | static int __init early_parse_mem(char *p) | ||
| 841 | { | ||
| 842 | if (!p) | ||
| 843 | return 1; | ||
| 844 | |||
| 845 | memory_limit = PAGE_ALIGN(memparse(p, &p)); | ||
| 846 | DBG("memory limit = 0x%lx\n", memory_limit); | ||
| 847 | |||
| 848 | return 0; | ||
| 849 | } | ||
| 850 | early_param("mem", early_parse_mem); | ||
| 851 | |||
| 852 | /* | ||
| 853 | * The device tree may be allocated below our memory limit, or inside the | ||
| 854 | * crash kernel region for kdump. If so, move it out now. | ||
| 855 | */ | ||
| 856 | static void move_device_tree(void) | ||
| 857 | { | ||
| 858 | unsigned long start, size; | ||
| 859 | void *p; | ||
| 860 | |||
| 861 | DBG("-> move_device_tree\n"); | ||
| 862 | |||
| 863 | start = __pa(initial_boot_params); | ||
| 864 | size = initial_boot_params->totalsize; | ||
| 865 | |||
| 866 | if ((memory_limit && (start + size) > memory_limit) || | ||
| 867 | overlaps_crashkernel(start, size)) { | ||
| 868 | p = __va(lmb_alloc_base(size, PAGE_SIZE, lmb.rmo_size)); | ||
| 869 | memcpy(p, initial_boot_params, size); | ||
| 870 | initial_boot_params = (struct boot_param_header *)p; | ||
| 871 | DBG("Moved device tree to 0x%p\n", p); | ||
| 872 | } | ||
| 873 | |||
| 874 | DBG("<- move_device_tree\n"); | ||
| 875 | } | ||
| 839 | 876 | ||
| 840 | /** | 877 | /** |
| 841 | * unflattens the device-tree passed by the firmware, creating the | 878 | * unflattens the device-tree passed by the firmware, creating the |
| @@ -1070,6 +1107,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
| 1070 | iommu_force_on = 1; | 1107 | iommu_force_on = 1; |
| 1071 | #endif | 1108 | #endif |
| 1072 | 1109 | ||
| 1110 | /* mem=x on the command line is the preferred mechanism */ | ||
| 1073 | lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL); | 1111 | lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL); |
| 1074 | if (lprop) | 1112 | if (lprop) |
| 1075 | memory_limit = *lprop; | 1113 | memory_limit = *lprop; |
| @@ -1123,17 +1161,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
| 1123 | 1161 | ||
| 1124 | DBG("Command line is: %s\n", cmd_line); | 1162 | DBG("Command line is: %s\n", cmd_line); |
| 1125 | 1163 | ||
| 1126 | if (strstr(cmd_line, "mem=")) { | ||
| 1127 | char *p, *q; | ||
| 1128 | |||
| 1129 | for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { | ||
| 1130 | q = p + 4; | ||
| 1131 | if (p > cmd_line && p[-1] != ' ') | ||
| 1132 | continue; | ||
| 1133 | memory_limit = memparse(q, &q); | ||
| 1134 | } | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | /* break now */ | 1164 | /* break now */ |
| 1138 | return 1; | 1165 | return 1; |
| 1139 | } | 1166 | } |
| @@ -1297,11 +1324,6 @@ void __init early_init_devtree(void *params) | |||
| 1297 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); | 1324 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); |
| 1298 | parse_early_param(); | 1325 | parse_early_param(); |
| 1299 | 1326 | ||
| 1300 | lmb_enforce_memory_limit(memory_limit); | ||
| 1301 | lmb_analyze(); | ||
| 1302 | |||
| 1303 | DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); | ||
| 1304 | |||
| 1305 | /* Reserve LMB regions used by kernel, initrd, dt, etc... */ | 1327 | /* Reserve LMB regions used by kernel, initrd, dt, etc... */ |
| 1306 | lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); | 1328 | lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); |
| 1307 | #ifdef CONFIG_CRASH_DUMP | 1329 | #ifdef CONFIG_CRASH_DUMP |
| @@ -1309,6 +1331,15 @@ void __init early_init_devtree(void *params) | |||
| 1309 | #endif | 1331 | #endif |
| 1310 | early_reserve_mem(); | 1332 | early_reserve_mem(); |
| 1311 | 1333 | ||
| 1334 | lmb_enforce_memory_limit(memory_limit); | ||
| 1335 | lmb_analyze(); | ||
| 1336 | |||
| 1337 | DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); | ||
| 1338 | |||
| 1339 | /* We may need to relocate the flat tree, do it now. | ||
| 1340 | * FIXME .. and the initrd too? */ | ||
| 1341 | move_device_tree(); | ||
| 1342 | |||
| 1312 | DBG("Scanning CPUs ...\n"); | 1343 | DBG("Scanning CPUs ...\n"); |
| 1313 | 1344 | ||
| 1314 | /* Retreive CPU related informations from the flat tree | 1345 | /* Retreive CPU related informations from the flat tree |
| @@ -2058,29 +2089,3 @@ int prom_update_property(struct device_node *np, | |||
| 2058 | return 0; | 2089 | return 0; |
| 2059 | } | 2090 | } |
| 2060 | 2091 | ||
| 2061 | #ifdef CONFIG_KEXEC | ||
| 2062 | /* We may have allocated the flat device tree inside the crash kernel region | ||
| 2063 | * in prom_init. If so we need to move it out into regular memory. */ | ||
| 2064 | void kdump_move_device_tree(void) | ||
| 2065 | { | ||
| 2066 | unsigned long start, end; | ||
| 2067 | struct boot_param_header *new; | ||
| 2068 | |||
| 2069 | start = __pa((unsigned long)initial_boot_params); | ||
| 2070 | end = start + initial_boot_params->totalsize; | ||
| 2071 | |||
| 2072 | if (end < crashk_res.start || start > crashk_res.end) | ||
| 2073 | return; | ||
| 2074 | |||
| 2075 | new = (struct boot_param_header*) | ||
| 2076 | __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE)); | ||
| 2077 | |||
| 2078 | memcpy(new, initial_boot_params, initial_boot_params->totalsize); | ||
| 2079 | |||
| 2080 | initial_boot_params = new; | ||
| 2081 | |||
| 2082 | DBG("Flat device tree blob moved to %p\n", initial_boot_params); | ||
| 2083 | |||
| 2084 | /* XXX should we unreserve the old DT? */ | ||
| 2085 | } | ||
| 2086 | #endif /* CONFIG_KEXEC */ | ||
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 078fb5533541..a52377c68fc6 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -194,8 +194,6 @@ static int __initdata of_platform; | |||
| 194 | 194 | ||
| 195 | static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; | 195 | static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; |
| 196 | 196 | ||
| 197 | static unsigned long __initdata prom_memory_limit; | ||
| 198 | |||
| 199 | static unsigned long __initdata alloc_top; | 197 | static unsigned long __initdata alloc_top; |
| 200 | static unsigned long __initdata alloc_top_high; | 198 | static unsigned long __initdata alloc_top_high; |
| 201 | static unsigned long __initdata alloc_bottom; | 199 | static unsigned long __initdata alloc_bottom; |
| @@ -594,16 +592,6 @@ static void __init early_cmdline_parse(void) | |||
| 594 | } | 592 | } |
| 595 | #endif | 593 | #endif |
| 596 | 594 | ||
| 597 | opt = strstr(RELOC(prom_cmd_line), RELOC("mem=")); | ||
| 598 | if (opt) { | ||
| 599 | opt += 4; | ||
| 600 | RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt); | ||
| 601 | #ifdef CONFIG_PPC64 | ||
| 602 | /* Align to 16 MB == size of ppc64 large page */ | ||
| 603 | RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); | ||
| 604 | #endif | ||
| 605 | } | ||
| 606 | |||
| 607 | #ifdef CONFIG_KEXEC | 595 | #ifdef CONFIG_KEXEC |
| 608 | /* | 596 | /* |
| 609 | * crashkernel=size@addr specifies the location to reserve for | 597 | * crashkernel=size@addr specifies the location to reserve for |
| @@ -1115,29 +1103,6 @@ static void __init prom_init_mem(void) | |||
| 1115 | } | 1103 | } |
| 1116 | 1104 | ||
| 1117 | /* | 1105 | /* |
| 1118 | * If prom_memory_limit is set we reduce the upper limits *except* for | ||
| 1119 | * alloc_top_high. This must be the real top of RAM so we can put | ||
| 1120 | * TCE's up there. | ||
| 1121 | */ | ||
| 1122 | |||
| 1123 | RELOC(alloc_top_high) = RELOC(ram_top); | ||
| 1124 | |||
| 1125 | if (RELOC(prom_memory_limit)) { | ||
| 1126 | if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) { | ||
| 1127 | prom_printf("Ignoring mem=%x <= alloc_bottom.\n", | ||
| 1128 | RELOC(prom_memory_limit)); | ||
| 1129 | RELOC(prom_memory_limit) = 0; | ||
| 1130 | } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) { | ||
| 1131 | prom_printf("Ignoring mem=%x >= ram_top.\n", | ||
| 1132 | RELOC(prom_memory_limit)); | ||
| 1133 | RELOC(prom_memory_limit) = 0; | ||
| 1134 | } else { | ||
| 1135 | RELOC(ram_top) = RELOC(prom_memory_limit); | ||
| 1136 | RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit)); | ||
| 1137 | } | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | /* | ||
| 1141 | * Setup our top alloc point, that is top of RMO or top of | 1106 | * Setup our top alloc point, that is top of RMO or top of |
| 1142 | * segment 0 when running non-LPAR. | 1107 | * segment 0 when running non-LPAR. |
| 1143 | * Some RS64 machines have buggy firmware where claims up at | 1108 | * Some RS64 machines have buggy firmware where claims up at |
| @@ -1149,9 +1114,9 @@ static void __init prom_init_mem(void) | |||
| 1149 | RELOC(rmo_top) = RELOC(ram_top); | 1114 | RELOC(rmo_top) = RELOC(ram_top); |
| 1150 | RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top)); | 1115 | RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top)); |
| 1151 | RELOC(alloc_top) = RELOC(rmo_top); | 1116 | RELOC(alloc_top) = RELOC(rmo_top); |
| 1117 | RELOC(alloc_top_high) = RELOC(ram_top); | ||
| 1152 | 1118 | ||
| 1153 | prom_printf("memory layout at init:\n"); | 1119 | prom_printf("memory layout at init:\n"); |
| 1154 | prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit)); | ||
| 1155 | prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom)); | 1120 | prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom)); |
| 1156 | prom_printf(" alloc_top : %x\n", RELOC(alloc_top)); | 1121 | prom_printf(" alloc_top : %x\n", RELOC(alloc_top)); |
| 1157 | prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); | 1122 | prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); |
| @@ -1348,16 +1313,10 @@ static void __init prom_initialize_tce_table(void) | |||
| 1348 | 1313 | ||
| 1349 | reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom); | 1314 | reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom); |
| 1350 | 1315 | ||
| 1351 | if (RELOC(prom_memory_limit)) { | 1316 | /* These are only really needed if there is a memory limit in |
| 1352 | /* | 1317 | * effect, but we don't know so export them always. */ |
| 1353 | * We align the start to a 16MB boundary so we can map | 1318 | RELOC(prom_tce_alloc_start) = local_alloc_bottom; |
| 1354 | * the TCE area using large pages if possible. | 1319 | RELOC(prom_tce_alloc_end) = local_alloc_top; |
| 1355 | * The end should be the top of RAM so no need to align it. | ||
| 1356 | */ | ||
| 1357 | RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, | ||
| 1358 | 0x1000000); | ||
| 1359 | RELOC(prom_tce_alloc_end) = local_alloc_top; | ||
| 1360 | } | ||
| 1361 | 1320 | ||
| 1362 | /* Flag the first invalid entry */ | 1321 | /* Flag the first invalid entry */ |
| 1363 | prom_debug("ending prom_initialize_tce_table\n"); | 1322 | prom_debug("ending prom_initialize_tce_table\n"); |
| @@ -2265,10 +2224,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
| 2265 | /* | 2224 | /* |
| 2266 | * Fill in some infos for use by the kernel later on | 2225 | * Fill in some infos for use by the kernel later on |
| 2267 | */ | 2226 | */ |
| 2268 | if (RELOC(prom_memory_limit)) | ||
| 2269 | prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit", | ||
| 2270 | &RELOC(prom_memory_limit), | ||
| 2271 | sizeof(prom_memory_limit)); | ||
| 2272 | #ifdef CONFIG_PPC64 | 2227 | #ifdef CONFIG_PPC64 |
| 2273 | if (RELOC(ppc64_iommu_off)) | 2228 | if (RELOC(ppc64_iommu_off)) |
| 2274 | prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off", | 2229 | prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off", |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 6224624c3d38..59773d9044ba 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -347,9 +347,6 @@ void __init setup_system(void) | |||
| 347 | { | 347 | { |
| 348 | DBG(" -> setup_system()\n"); | 348 | DBG(" -> setup_system()\n"); |
| 349 | 349 | ||
| 350 | #ifdef CONFIG_KEXEC | ||
| 351 | kdump_move_device_tree(); | ||
| 352 | #endif | ||
| 353 | /* | 350 | /* |
| 354 | * Unflatten the device-tree passed by prom_init or kexec | 351 | * Unflatten the device-tree passed by prom_init or kexec |
| 355 | */ | 352 | */ |
diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c index 417d58518558..8b6f522655a6 100644 --- a/arch/powerpc/mm/lmb.c +++ b/arch/powerpc/mm/lmb.c | |||
| @@ -89,20 +89,25 @@ static long __init lmb_regions_adjacent(struct lmb_region *rgn, | |||
| 89 | return lmb_addrs_adjacent(base1, size1, base2, size2); | 89 | return lmb_addrs_adjacent(base1, size1, base2, size2); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* Assumption: base addr of region 1 < base addr of region 2 */ | 92 | static void __init lmb_remove_region(struct lmb_region *rgn, unsigned long r) |
| 93 | static void __init lmb_coalesce_regions(struct lmb_region *rgn, | ||
| 94 | unsigned long r1, unsigned long r2) | ||
| 95 | { | 93 | { |
| 96 | unsigned long i; | 94 | unsigned long i; |
| 97 | 95 | ||
| 98 | rgn->region[r1].size += rgn->region[r2].size; | 96 | for (i = r; i < rgn->cnt - 1; i++) { |
| 99 | for (i=r2; i < rgn->cnt-1; i++) { | 97 | rgn->region[i].base = rgn->region[i + 1].base; |
| 100 | rgn->region[i].base = rgn->region[i+1].base; | 98 | rgn->region[i].size = rgn->region[i + 1].size; |
| 101 | rgn->region[i].size = rgn->region[i+1].size; | ||
| 102 | } | 99 | } |
| 103 | rgn->cnt--; | 100 | rgn->cnt--; |
| 104 | } | 101 | } |
| 105 | 102 | ||
| 103 | /* Assumption: base addr of region 1 < base addr of region 2 */ | ||
| 104 | static void __init lmb_coalesce_regions(struct lmb_region *rgn, | ||
| 105 | unsigned long r1, unsigned long r2) | ||
| 106 | { | ||
| 107 | rgn->region[r1].size += rgn->region[r2].size; | ||
| 108 | lmb_remove_region(rgn, r2); | ||
| 109 | } | ||
| 110 | |||
| 106 | /* This routine called with relocation disabled. */ | 111 | /* This routine called with relocation disabled. */ |
| 107 | void __init lmb_init(void) | 112 | void __init lmb_init(void) |
| 108 | { | 113 | { |
| @@ -294,17 +299,16 @@ unsigned long __init lmb_end_of_DRAM(void) | |||
| 294 | return (lmb.memory.region[idx].base + lmb.memory.region[idx].size); | 299 | return (lmb.memory.region[idx].base + lmb.memory.region[idx].size); |
| 295 | } | 300 | } |
| 296 | 301 | ||
| 297 | /* | 302 | /* You must call lmb_analyze() after this. */ |
| 298 | * Truncate the lmb list to memory_limit if it's set | ||
| 299 | * You must call lmb_analyze() after this. | ||
| 300 | */ | ||
| 301 | void __init lmb_enforce_memory_limit(unsigned long memory_limit) | 303 | void __init lmb_enforce_memory_limit(unsigned long memory_limit) |
| 302 | { | 304 | { |
| 303 | unsigned long i, limit; | 305 | unsigned long i, limit; |
| 306 | struct lmb_property *p; | ||
| 304 | 307 | ||
| 305 | if (! memory_limit) | 308 | if (! memory_limit) |
| 306 | return; | 309 | return; |
| 307 | 310 | ||
| 311 | /* Truncate the lmb regions to satisfy the memory limit. */ | ||
| 308 | limit = memory_limit; | 312 | limit = memory_limit; |
| 309 | for (i = 0; i < lmb.memory.cnt; i++) { | 313 | for (i = 0; i < lmb.memory.cnt; i++) { |
| 310 | if (limit > lmb.memory.region[i].size) { | 314 | if (limit > lmb.memory.region[i].size) { |
| @@ -316,4 +320,21 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit) | |||
| 316 | lmb.memory.cnt = i + 1; | 320 | lmb.memory.cnt = i + 1; |
| 317 | break; | 321 | break; |
| 318 | } | 322 | } |
| 323 | |||
| 324 | lmb.rmo_size = lmb.memory.region[0].size; | ||
| 325 | |||
| 326 | /* And truncate any reserves above the limit also. */ | ||
| 327 | for (i = 0; i < lmb.reserved.cnt; i++) { | ||
| 328 | p = &lmb.reserved.region[i]; | ||
| 329 | |||
| 330 | if (p->base > memory_limit) | ||
| 331 | p->size = 0; | ||
| 332 | else if ((p->base + p->size) > memory_limit) | ||
| 333 | p->size = memory_limit - p->base; | ||
| 334 | |||
| 335 | if (p->size == 0) { | ||
| 336 | lmb_remove_region(&lmb.reserved, i); | ||
| 337 | i--; | ||
| 338 | } | ||
| 339 | } | ||
| 319 | } | 340 | } |
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 074d1d949708..fd6d0ebe8ddd 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
| @@ -90,8 +90,6 @@ extern unsigned long embedded_sysmap_end; | |||
| 90 | extern unsigned long iSeries_recal_tb; | 90 | extern unsigned long iSeries_recal_tb; |
| 91 | extern unsigned long iSeries_recal_titan; | 91 | extern unsigned long iSeries_recal_titan; |
| 92 | 92 | ||
| 93 | static unsigned long cmd_mem_limit; | ||
| 94 | |||
| 95 | struct MemoryBlock { | 93 | struct MemoryBlock { |
| 96 | unsigned long absStart; | 94 | unsigned long absStart; |
| 97 | unsigned long absEnd; | 95 | unsigned long absEnd; |
| @@ -1026,8 +1024,6 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) | |||
| 1026 | /* /chosen */ | 1024 | /* /chosen */ |
| 1027 | dt_start_node(dt, "chosen"); | 1025 | dt_start_node(dt, "chosen"); |
| 1028 | dt_prop_str(dt, "bootargs", cmd_line); | 1026 | dt_prop_str(dt, "bootargs", cmd_line); |
| 1029 | if (cmd_mem_limit) | ||
| 1030 | dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit); | ||
| 1031 | dt_end_node(dt); | 1027 | dt_end_node(dt); |
| 1032 | 1028 | ||
| 1033 | dt_cpus(dt); | 1029 | dt_cpus(dt); |
| @@ -1053,29 +1049,11 @@ void * __init iSeries_early_setup(void) | |||
| 1053 | 1049 | ||
| 1054 | iSeries_get_cmdline(); | 1050 | iSeries_get_cmdline(); |
| 1055 | 1051 | ||
| 1056 | /* Save unparsed command line copy for /proc/cmdline */ | ||
| 1057 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); | ||
| 1058 | |||
| 1059 | /* Parse early parameters, in particular mem=x */ | ||
| 1060 | parse_early_param(); | ||
| 1061 | |||
| 1062 | build_flat_dt(&iseries_dt, phys_mem_size); | 1052 | build_flat_dt(&iseries_dt, phys_mem_size); |
| 1063 | 1053 | ||
| 1064 | return (void *) __pa(&iseries_dt); | 1054 | return (void *) __pa(&iseries_dt); |
| 1065 | } | 1055 | } |
| 1066 | 1056 | ||
| 1067 | /* | ||
| 1068 | * On iSeries we just parse the mem=X option from the command line. | ||
| 1069 | * On pSeries it's a bit more complicated, see prom_init_mem() | ||
| 1070 | */ | ||
| 1071 | static int __init early_parsemem(char *p) | ||
| 1072 | { | ||
| 1073 | if (p) | ||
| 1074 | cmd_mem_limit = ALIGN(memparse(p, &p), PAGE_SIZE); | ||
| 1075 | return 0; | ||
| 1076 | } | ||
| 1077 | early_param("mem", early_parsemem); | ||
| 1078 | |||
| 1079 | static void hvputc(char c) | 1057 | static void hvputc(char c) |
| 1080 | { | 1058 | { |
| 1081 | if (c == '\n') | 1059 | if (c == '\n') |
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h index 6a2af2f6853b..0a1afced173f 100644 --- a/include/asm-powerpc/kexec.h +++ b/include/asm-powerpc/kexec.h | |||
| @@ -31,9 +31,10 @@ | |||
| 31 | #define KEXEC_ARCH KEXEC_ARCH_PPC | 31 | #define KEXEC_ARCH KEXEC_ARCH_PPC |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | #ifndef __ASSEMBLY__ | ||
| 35 | |||
| 34 | #ifdef CONFIG_KEXEC | 36 | #ifdef CONFIG_KEXEC |
| 35 | 37 | ||
| 36 | #ifndef __ASSEMBLY__ | ||
| 37 | #ifdef __powerpc64__ | 38 | #ifdef __powerpc64__ |
| 38 | /* | 39 | /* |
| 39 | * This function is responsible for capturing register states if coming | 40 | * This function is responsible for capturing register states if coming |
| @@ -123,8 +124,16 @@ extern int default_machine_kexec_prepare(struct kimage *image); | |||
| 123 | extern void default_machine_crash_shutdown(struct pt_regs *regs); | 124 | extern void default_machine_crash_shutdown(struct pt_regs *regs); |
| 124 | 125 | ||
| 125 | extern void machine_kexec_simple(struct kimage *image); | 126 | extern void machine_kexec_simple(struct kimage *image); |
| 127 | extern int overlaps_crashkernel(unsigned long start, unsigned long size); | ||
| 128 | |||
| 129 | #else /* !CONFIG_KEXEC */ | ||
| 130 | |||
| 131 | static inline int overlaps_crashkernel(unsigned long start, unsigned long size) | ||
| 132 | { | ||
| 133 | return 0; | ||
| 134 | } | ||
| 126 | 135 | ||
| 127 | #endif /* ! __ASSEMBLY__ */ | ||
| 128 | #endif /* CONFIG_KEXEC */ | 136 | #endif /* CONFIG_KEXEC */ |
| 137 | #endif /* ! __ASSEMBLY__ */ | ||
| 129 | #endif /* __KERNEL__ */ | 138 | #endif /* __KERNEL__ */ |
| 130 | #endif /* _ASM_POWERPC_KEXEC_H */ | 139 | #endif /* _ASM_POWERPC_KEXEC_H */ |
