diff options
author | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 2008-04-08 17:43:46 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-06-05 13:13:14 -0400 |
commit | 2bf8ec2d8137e66998435ddf6d4060a558e2f727 (patch) | |
tree | bacc3456ba775541306d11ce34f5fcccfb76404c /arch/mips/sgi-ip27/ip27-memory.c | |
parent | c2719d93836b0b0cdf1725449d87705da6ede9a5 (diff) |
[MIPS] IP27: Fix bootmem memory setup
Changes in the generic bootmem code broke memory setup for IP27. This
patch fixes this by replacing lots of special IP27 code with generic
bootmon code. This has been tested only on a single node.
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/sgi-ip27/ip27-memory.c')
-rw-r--r-- | arch/mips/sgi-ip27/ip27-memory.c | 117 |
1 files changed, 22 insertions, 95 deletions
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index bf438d02366e..42cd10956306 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
@@ -33,10 +33,6 @@ | |||
33 | #define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT) | 33 | #define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT) |
34 | #define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT) | 34 | #define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT) |
35 | 35 | ||
36 | #define SLOT_IGNORED 0xffff | ||
37 | |||
38 | static short __initdata slot_lastfilled_cache[MAX_COMPACT_NODES]; | ||
39 | static unsigned short __initdata slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS]; | ||
40 | static struct bootmem_data __initdata plat_node_bdata[MAX_COMPACT_NODES]; | 36 | static struct bootmem_data __initdata plat_node_bdata[MAX_COMPACT_NODES]; |
41 | 37 | ||
42 | struct node_data *__node_data[MAX_COMPACT_NODES]; | 38 | struct node_data *__node_data[MAX_COMPACT_NODES]; |
@@ -267,51 +263,6 @@ static pfn_t __init slot_getbasepfn(cnodeid_t cnode, int slot) | |||
267 | return ((pfn_t)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT); | 263 | return ((pfn_t)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT); |
268 | } | 264 | } |
269 | 265 | ||
270 | /* | ||
271 | * Return the number of pages of memory provided by the given slot | ||
272 | * on the specified node. | ||
273 | */ | ||
274 | static pfn_t __init slot_getsize(cnodeid_t node, int slot) | ||
275 | { | ||
276 | return (pfn_t) slot_psize_cache[node][slot]; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * Return highest slot filled | ||
281 | */ | ||
282 | static int __init node_getlastslot(cnodeid_t node) | ||
283 | { | ||
284 | return (int) slot_lastfilled_cache[node]; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Return the pfn of the last free page of memory on a node. | ||
289 | */ | ||
290 | static pfn_t __init node_getmaxclick(cnodeid_t node) | ||
291 | { | ||
292 | pfn_t slot_psize; | ||
293 | int slot; | ||
294 | |||
295 | /* | ||
296 | * Start at the top slot. When we find a slot with memory in it, | ||
297 | * that's the winner. | ||
298 | */ | ||
299 | for (slot = (MAX_MEM_SLOTS - 1); slot >= 0; slot--) { | ||
300 | if ((slot_psize = slot_getsize(node, slot))) { | ||
301 | if (slot_psize == SLOT_IGNORED) | ||
302 | continue; | ||
303 | /* Return the basepfn + the slot size, minus 1. */ | ||
304 | return slot_getbasepfn(node, slot) + slot_psize - 1; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * If there's no memory on the node, return 0. This is likely | ||
310 | * to cause problems. | ||
311 | */ | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static pfn_t __init slot_psize_compute(cnodeid_t node, int slot) | 266 | static pfn_t __init slot_psize_compute(cnodeid_t node, int slot) |
316 | { | 267 | { |
317 | nasid_t nasid; | 268 | nasid_t nasid; |
@@ -404,13 +355,13 @@ static void __init mlreset(void) | |||
404 | static void __init szmem(void) | 355 | static void __init szmem(void) |
405 | { | 356 | { |
406 | pfn_t slot_psize, slot0sz = 0, nodebytes; /* Hack to detect problem configs */ | 357 | pfn_t slot_psize, slot0sz = 0, nodebytes; /* Hack to detect problem configs */ |
407 | int slot, ignore; | 358 | int slot; |
408 | cnodeid_t node; | 359 | cnodeid_t node; |
409 | 360 | ||
410 | num_physpages = 0; | 361 | num_physpages = 0; |
411 | 362 | ||
412 | for_each_online_node(node) { | 363 | for_each_online_node(node) { |
413 | ignore = nodebytes = 0; | 364 | nodebytes = 0; |
414 | for (slot = 0; slot < MAX_MEM_SLOTS; slot++) { | 365 | for (slot = 0; slot < MAX_MEM_SLOTS; slot++) { |
415 | slot_psize = slot_psize_compute(node, slot); | 366 | slot_psize = slot_psize_compute(node, slot); |
416 | if (slot == 0) | 367 | if (slot == 0) |
@@ -420,21 +371,20 @@ static void __init szmem(void) | |||
420 | * kernel text. | 371 | * kernel text. |
421 | */ | 372 | */ |
422 | nodebytes += (1LL << SLOT_SHIFT); | 373 | nodebytes += (1LL << SLOT_SHIFT); |
374 | |||
375 | if (!slot_psize) | ||
376 | continue; | ||
377 | |||
423 | if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > | 378 | if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > |
424 | (slot0sz << PAGE_SHIFT)) | 379 | (slot0sz << PAGE_SHIFT)) { |
425 | ignore = 1; | ||
426 | if (ignore && slot_psize) { | ||
427 | printk("Ignoring slot %d onwards on node %d\n", | 380 | printk("Ignoring slot %d onwards on node %d\n", |
428 | slot, node); | 381 | slot, node); |
429 | slot_psize_cache[node][slot] = SLOT_IGNORED; | ||
430 | slot = MAX_MEM_SLOTS; | 382 | slot = MAX_MEM_SLOTS; |
431 | continue; | 383 | continue; |
432 | } | 384 | } |
433 | num_physpages += slot_psize; | 385 | num_physpages += slot_psize; |
434 | slot_psize_cache[node][slot] = | 386 | add_active_range(node, slot_getbasepfn(node, slot), |
435 | (unsigned short) slot_psize; | 387 | slot_getbasepfn(node, slot) + slot_psize); |
436 | if (slot_psize) | ||
437 | slot_lastfilled_cache[node] = slot; | ||
438 | } | 388 | } |
439 | } | 389 | } |
440 | } | 390 | } |
@@ -442,18 +392,20 @@ static void __init szmem(void) | |||
442 | static void __init node_mem_init(cnodeid_t node) | 392 | static void __init node_mem_init(cnodeid_t node) |
443 | { | 393 | { |
444 | pfn_t slot_firstpfn = slot_getbasepfn(node, 0); | 394 | pfn_t slot_firstpfn = slot_getbasepfn(node, 0); |
445 | pfn_t slot_lastpfn = slot_firstpfn + slot_getsize(node, 0); | ||
446 | pfn_t slot_freepfn = node_getfirstfree(node); | 395 | pfn_t slot_freepfn = node_getfirstfree(node); |
447 | struct pglist_data *pd; | ||
448 | unsigned long bootmap_size; | 396 | unsigned long bootmap_size; |
397 | pfn_t start_pfn, end_pfn; | ||
398 | |||
399 | get_pfn_range_for_nid(node, &start_pfn, &end_pfn); | ||
449 | 400 | ||
450 | /* | 401 | /* |
451 | * Allocate the node data structures on the node first. | 402 | * Allocate the node data structures on the node first. |
452 | */ | 403 | */ |
453 | __node_data[node] = __va(slot_freepfn << PAGE_SHIFT); | 404 | __node_data[node] = __va(slot_freepfn << PAGE_SHIFT); |
454 | 405 | ||
455 | pd = NODE_DATA(node); | 406 | NODE_DATA(node)->bdata = &plat_node_bdata[node]; |
456 | pd->bdata = &plat_node_bdata[node]; | 407 | NODE_DATA(node)->node_start_pfn = start_pfn; |
408 | NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; | ||
457 | 409 | ||
458 | cpus_clear(hub_data(node)->h_cpus); | 410 | cpus_clear(hub_data(node)->h_cpus); |
459 | 411 | ||
@@ -461,12 +413,12 @@ static void __init node_mem_init(cnodeid_t node) | |||
461 | sizeof(struct hub_data)); | 413 | sizeof(struct hub_data)); |
462 | 414 | ||
463 | bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, | 415 | bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, |
464 | slot_firstpfn, slot_lastpfn); | 416 | start_pfn, end_pfn); |
465 | free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, | 417 | free_bootmem_with_active_regions(node, end_pfn); |
466 | (slot_lastpfn - slot_firstpfn) << PAGE_SHIFT); | ||
467 | reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, | 418 | reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, |
468 | ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size, | 419 | ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size, |
469 | BOOTMEM_DEFAULT); | 420 | BOOTMEM_DEFAULT); |
421 | sparse_memory_present_with_active_regions(node); | ||
470 | } | 422 | } |
471 | 423 | ||
472 | /* | 424 | /* |
@@ -515,16 +467,15 @@ void __init paging_init(void) | |||
515 | pagetable_init(); | 467 | pagetable_init(); |
516 | 468 | ||
517 | for_each_online_node(node) { | 469 | for_each_online_node(node) { |
518 | pfn_t start_pfn = slot_getbasepfn(node, 0); | 470 | pfn_t start_pfn, end_pfn; |
519 | pfn_t end_pfn = node_getmaxclick(node) + 1; | ||
520 | 471 | ||
521 | zones_size[ZONE_NORMAL] = end_pfn - start_pfn; | 472 | get_pfn_range_for_nid(node, &start_pfn, &end_pfn); |
522 | free_area_init_node(node, NODE_DATA(node), | ||
523 | zones_size, start_pfn, NULL); | ||
524 | 473 | ||
525 | if (end_pfn > max_low_pfn) | 474 | if (end_pfn > max_low_pfn) |
526 | max_low_pfn = end_pfn; | 475 | max_low_pfn = end_pfn; |
527 | } | 476 | } |
477 | zones_size[ZONE_NORMAL] = max_low_pfn; | ||
478 | free_area_init_nodes(zones_size); | ||
528 | } | 479 | } |
529 | 480 | ||
530 | void __init mem_init(void) | 481 | void __init mem_init(void) |
@@ -535,34 +486,10 @@ void __init mem_init(void) | |||
535 | high_memory = (void *) __va(num_physpages << PAGE_SHIFT); | 486 | high_memory = (void *) __va(num_physpages << PAGE_SHIFT); |
536 | 487 | ||
537 | for_each_online_node(node) { | 488 | for_each_online_node(node) { |
538 | unsigned slot, numslots; | ||
539 | struct page *end, *p; | ||
540 | |||
541 | /* | 489 | /* |
542 | * This will free up the bootmem, ie, slot 0 memory. | 490 | * This will free up the bootmem, ie, slot 0 memory. |
543 | */ | 491 | */ |
544 | totalram_pages += free_all_bootmem_node(NODE_DATA(node)); | 492 | totalram_pages += free_all_bootmem_node(NODE_DATA(node)); |
545 | |||
546 | /* | ||
547 | * We need to manually do the other slots. | ||
548 | */ | ||
549 | numslots = node_getlastslot(node); | ||
550 | for (slot = 1; slot <= numslots; slot++) { | ||
551 | p = nid_page_nr(node, slot_getbasepfn(node, slot) - | ||
552 | slot_getbasepfn(node, 0)); | ||
553 | |||
554 | /* | ||
555 | * Free valid memory in current slot. | ||
556 | */ | ||
557 | for (end = p + slot_getsize(node, slot); p < end; p++) { | ||
558 | /* if (!page_is_ram(pgnr)) continue; */ | ||
559 | /* commented out until page_is_ram works */ | ||
560 | ClearPageReserved(p); | ||
561 | init_page_count(p); | ||
562 | __free_page(p); | ||
563 | totalram_pages++; | ||
564 | } | ||
565 | } | ||
566 | } | 493 | } |
567 | 494 | ||
568 | totalram_pages -= setup_zero_pages(); /* This comes from node 0 */ | 495 | totalram_pages -= setup_zero_pages(); /* This comes from node 0 */ |