diff options
Diffstat (limited to 'arch/s390/kernel/setup.c')
-rw-r--r-- | arch/s390/kernel/setup.c | 88 |
1 files changed, 42 insertions, 46 deletions
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 6f6350826c81..ed183c2c6168 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -102,16 +102,6 @@ EXPORT_SYMBOL(lowcore_ptr); | |||
102 | 102 | ||
103 | #include <asm/setup.h> | 103 | #include <asm/setup.h> |
104 | 104 | ||
105 | static struct resource code_resource = { | ||
106 | .name = "Kernel code", | ||
107 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
108 | }; | ||
109 | |||
110 | static struct resource data_resource = { | ||
111 | .name = "Kernel data", | ||
112 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
113 | }; | ||
114 | |||
115 | /* | 105 | /* |
116 | * condev= and conmode= setup parameter. | 106 | * condev= and conmode= setup parameter. |
117 | */ | 107 | */ |
@@ -436,21 +426,43 @@ setup_lowcore(void) | |||
436 | lowcore_ptr[0] = lc; | 426 | lowcore_ptr[0] = lc; |
437 | } | 427 | } |
438 | 428 | ||
439 | static void __init | 429 | static struct resource code_resource = { |
440 | setup_resources(void) | 430 | .name = "Kernel code", |
431 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
432 | }; | ||
433 | |||
434 | static struct resource data_resource = { | ||
435 | .name = "Kernel data", | ||
436 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
437 | }; | ||
438 | |||
439 | static struct resource bss_resource = { | ||
440 | .name = "Kernel bss", | ||
441 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
442 | }; | ||
443 | |||
444 | static struct resource __initdata *standard_resources[] = { | ||
445 | &code_resource, | ||
446 | &data_resource, | ||
447 | &bss_resource, | ||
448 | }; | ||
449 | |||
450 | static void __init setup_resources(void) | ||
441 | { | 451 | { |
442 | struct resource *res, *sub_res; | 452 | struct resource *res, *std_res, *sub_res; |
443 | int i; | 453 | int i, j; |
444 | 454 | ||
445 | code_resource.start = (unsigned long) &_text; | 455 | code_resource.start = (unsigned long) &_text; |
446 | code_resource.end = (unsigned long) &_etext - 1; | 456 | code_resource.end = (unsigned long) &_etext - 1; |
447 | data_resource.start = (unsigned long) &_etext; | 457 | data_resource.start = (unsigned long) &_etext; |
448 | data_resource.end = (unsigned long) &_edata - 1; | 458 | data_resource.end = (unsigned long) &_edata - 1; |
459 | bss_resource.start = (unsigned long) &__bss_start; | ||
460 | bss_resource.end = (unsigned long) &__bss_stop - 1; | ||
449 | 461 | ||
450 | for (i = 0; i < MEMORY_CHUNKS; i++) { | 462 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
451 | if (!memory_chunk[i].size) | 463 | if (!memory_chunk[i].size) |
452 | continue; | 464 | continue; |
453 | res = alloc_bootmem_low(sizeof(struct resource)); | 465 | res = alloc_bootmem_low(sizeof(*res)); |
454 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | 466 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; |
455 | switch (memory_chunk[i].type) { | 467 | switch (memory_chunk[i].type) { |
456 | case CHUNK_READ_WRITE: | 468 | case CHUNK_READ_WRITE: |
@@ -464,40 +476,24 @@ setup_resources(void) | |||
464 | res->name = "reserved"; | 476 | res->name = "reserved"; |
465 | } | 477 | } |
466 | res->start = memory_chunk[i].addr; | 478 | res->start = memory_chunk[i].addr; |
467 | res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; | 479 | res->end = res->start + memory_chunk[i].size - 1; |
468 | request_resource(&iomem_resource, res); | 480 | request_resource(&iomem_resource, res); |
469 | 481 | ||
470 | if (code_resource.start >= res->start && | 482 | for (j = 0; j < ARRAY_SIZE(standard_resources); j++) { |
471 | code_resource.start <= res->end && | 483 | std_res = standard_resources[j]; |
472 | code_resource.end > res->end) { | 484 | if (std_res->start < res->start || |
473 | sub_res = alloc_bootmem_low(sizeof(struct resource)); | 485 | std_res->start > res->end) |
474 | memcpy(sub_res, &code_resource, | 486 | continue; |
475 | sizeof(struct resource)); | 487 | if (std_res->end > res->end) { |
476 | sub_res->end = res->end; | 488 | sub_res = alloc_bootmem_low(sizeof(*sub_res)); |
477 | code_resource.start = res->end + 1; | 489 | *sub_res = *std_res; |
478 | request_resource(res, sub_res); | 490 | sub_res->end = res->end; |
479 | } | 491 | std_res->start = res->end + 1; |
480 | 492 | request_resource(res, sub_res); | |
481 | if (code_resource.start >= res->start && | 493 | } else { |
482 | code_resource.start <= res->end && | 494 | request_resource(res, std_res); |
483 | code_resource.end <= res->end) | 495 | } |
484 | request_resource(res, &code_resource); | ||
485 | |||
486 | if (data_resource.start >= res->start && | ||
487 | data_resource.start <= res->end && | ||
488 | data_resource.end > res->end) { | ||
489 | sub_res = alloc_bootmem_low(sizeof(struct resource)); | ||
490 | memcpy(sub_res, &data_resource, | ||
491 | sizeof(struct resource)); | ||
492 | sub_res->end = res->end; | ||
493 | data_resource.start = res->end + 1; | ||
494 | request_resource(res, sub_res); | ||
495 | } | 496 | } |
496 | |||
497 | if (data_resource.start >= res->start && | ||
498 | data_resource.start <= res->end && | ||
499 | data_resource.end <= res->end) | ||
500 | request_resource(res, &data_resource); | ||
501 | } | 497 | } |
502 | } | 498 | } |
503 | 499 | ||