diff options
| -rw-r--r-- | arch/s390/kernel/setup.c | 385 | ||||
| -rw-r--r-- | arch/s390/mm/init.c | 15 |
2 files changed, 224 insertions, 176 deletions
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index c879c40aa7a5..f0679be4f96f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -60,6 +60,8 @@ struct { | |||
| 60 | #define CHUNK_READ_WRITE 0 | 60 | #define CHUNK_READ_WRITE 0 |
| 61 | #define CHUNK_READ_ONLY 1 | 61 | #define CHUNK_READ_ONLY 1 |
| 62 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ | 62 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ |
| 63 | unsigned long __initdata zholes_size[MAX_NR_ZONES]; | ||
| 64 | static unsigned long __initdata memory_end; | ||
| 63 | 65 | ||
| 64 | /* | 66 | /* |
| 65 | * Setup options | 67 | * Setup options |
| @@ -78,11 +80,15 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; | |||
| 78 | 80 | ||
| 79 | static struct resource code_resource = { | 81 | static struct resource code_resource = { |
| 80 | .name = "Kernel code", | 82 | .name = "Kernel code", |
| 83 | .start = (unsigned long) &_text, | ||
| 84 | .end = (unsigned long) &_etext - 1, | ||
| 81 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | 85 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, |
| 82 | }; | 86 | }; |
| 83 | 87 | ||
| 84 | static struct resource data_resource = { | 88 | static struct resource data_resource = { |
| 85 | .name = "Kernel data", | 89 | .name = "Kernel data", |
| 90 | .start = (unsigned long) &_etext, | ||
| 91 | .end = (unsigned long) &_edata - 1, | ||
| 86 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | 92 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, |
| 87 | }; | 93 | }; |
| 88 | 94 | ||
| @@ -310,90 +316,50 @@ void machine_power_off(void) | |||
| 310 | 316 | ||
| 311 | EXPORT_SYMBOL(machine_power_off); | 317 | EXPORT_SYMBOL(machine_power_off); |
| 312 | 318 | ||
| 313 | /* | 319 | static void __init |
| 314 | * Setup function called from init/main.c just after the banner | 320 | add_memory_hole(unsigned long start, unsigned long end) |
| 315 | * was printed. | ||
| 316 | */ | ||
| 317 | extern char _pstart, _pend, _stext; | ||
| 318 | |||
| 319 | void __init setup_arch(char **cmdline_p) | ||
| 320 | { | 321 | { |
| 321 | unsigned long bootmap_size; | 322 | unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; |
| 322 | unsigned long memory_start, memory_end; | 323 | |
| 323 | char c = ' ', cn, *to = command_line, *from = COMMAND_LINE; | 324 | if (end <= dma_pfn) |
| 324 | unsigned long start_pfn, end_pfn; | 325 | zholes_size[ZONE_DMA] += end - start + 1; |
| 325 | static unsigned int smptrap=0; | 326 | else if (start > dma_pfn) |
| 326 | unsigned long delay = 0; | 327 | zholes_size[ZONE_NORMAL] += end - start + 1; |
| 327 | struct _lowcore *lc; | 328 | else { |
| 328 | int i; | 329 | zholes_size[ZONE_DMA] += dma_pfn - start + 1; |
| 330 | zholes_size[ZONE_NORMAL] += end - dma_pfn; | ||
| 331 | } | ||
| 332 | } | ||
| 329 | 333 | ||
| 330 | if (smptrap) | 334 | static void __init |
| 331 | return; | 335 | parse_cmdline_early(char **cmdline_p) |
| 332 | smptrap=1; | 336 | { |
| 337 | char c = ' ', cn, *to = command_line, *from = COMMAND_LINE; | ||
| 338 | unsigned long delay = 0; | ||
| 333 | 339 | ||
| 334 | /* | 340 | /* Save unparsed command line copy for /proc/cmdline */ |
| 335 | * print what head.S has found out about the machine | 341 | memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); |
| 336 | */ | 342 | saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; |
| 337 | #ifndef CONFIG_ARCH_S390X | ||
| 338 | printk((MACHINE_IS_VM) ? | ||
| 339 | "We are running under VM (31 bit mode)\n" : | ||
| 340 | "We are running native (31 bit mode)\n"); | ||
| 341 | printk((MACHINE_HAS_IEEE) ? | ||
| 342 | "This machine has an IEEE fpu\n" : | ||
| 343 | "This machine has no IEEE fpu\n"); | ||
| 344 | #else /* CONFIG_ARCH_S390X */ | ||
| 345 | printk((MACHINE_IS_VM) ? | ||
| 346 | "We are running under VM (64 bit mode)\n" : | ||
| 347 | "We are running native (64 bit mode)\n"); | ||
| 348 | #endif /* CONFIG_ARCH_S390X */ | ||
| 349 | 343 | ||
| 350 | ROOT_DEV = Root_RAM0; | 344 | for (;;) { |
| 351 | memory_start = (unsigned long) &_end; /* fixit if use $CODELO etc*/ | 345 | /* |
| 352 | #ifndef CONFIG_ARCH_S390X | 346 | * "mem=XXX[kKmM]" sets memsize |
| 353 | memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */ | 347 | */ |
| 354 | /* | 348 | if (c == ' ' && strncmp(from, "mem=", 4) == 0) { |
| 355 | * We need some free virtual space to be able to do vmalloc. | 349 | memory_end = simple_strtoul(from+4, &from, 0); |
| 356 | * On a machine with 2GB memory we make sure that we have at | 350 | if ( *from == 'K' || *from == 'k' ) { |
| 357 | * least 128 MB free space for vmalloc. | 351 | memory_end = memory_end << 10; |
| 358 | */ | 352 | from++; |
| 359 | if (memory_end > 1920*1024*1024) | 353 | } else if ( *from == 'M' || *from == 'm' ) { |
| 360 | memory_end = 1920*1024*1024; | 354 | memory_end = memory_end << 20; |
| 361 | #else /* CONFIG_ARCH_S390X */ | 355 | from++; |
| 362 | memory_end = memory_size & ~0x200000UL; /* detected in head.s */ | 356 | } |
| 363 | #endif /* CONFIG_ARCH_S390X */ | 357 | } |
| 364 | init_mm.start_code = PAGE_OFFSET; | 358 | /* |
| 365 | init_mm.end_code = (unsigned long) &_etext; | 359 | * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes |
| 366 | init_mm.end_data = (unsigned long) &_edata; | 360 | */ |
| 367 | init_mm.brk = (unsigned long) &_end; | 361 | if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) { |
| 368 | 362 | delay = simple_strtoul(from+9, &from, 0); | |
| 369 | code_resource.start = (unsigned long) &_text; | ||
| 370 | code_resource.end = (unsigned long) &_etext - 1; | ||
| 371 | data_resource.start = (unsigned long) &_etext; | ||
| 372 | data_resource.end = (unsigned long) &_edata - 1; | ||
| 373 | |||
| 374 | /* Save unparsed command line copy for /proc/cmdline */ | ||
| 375 | memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); | ||
| 376 | saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; | ||
| 377 | |||
| 378 | for (;;) { | ||
| 379 | /* | ||
| 380 | * "mem=XXX[kKmM]" sets memsize | ||
| 381 | */ | ||
| 382 | if (c == ' ' && strncmp(from, "mem=", 4) == 0) { | ||
| 383 | memory_end = simple_strtoul(from+4, &from, 0); | ||
| 384 | if ( *from == 'K' || *from == 'k' ) { | ||
| 385 | memory_end = memory_end << 10; | ||
| 386 | from++; | ||
| 387 | } else if ( *from == 'M' || *from == 'm' ) { | ||
| 388 | memory_end = memory_end << 20; | ||
| 389 | from++; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | /* | ||
| 393 | * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes | ||
| 394 | */ | ||
| 395 | if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) { | ||
| 396 | delay = simple_strtoul(from+9, &from, 0); | ||
| 397 | if (*from == 's' || *from == 'S') { | 363 | if (*from == 's' || *from == 'S') { |
| 398 | delay = delay*1000000; | 364 | delay = delay*1000000; |
| 399 | from++; | 365 | from++; |
| @@ -403,24 +369,110 @@ void __init setup_arch(char **cmdline_p) | |||
| 403 | } | 369 | } |
| 404 | /* now wait for the requested amount of time */ | 370 | /* now wait for the requested amount of time */ |
| 405 | udelay(delay); | 371 | udelay(delay); |
| 406 | } | 372 | } |
| 407 | cn = *(from++); | 373 | cn = *(from++); |
| 408 | if (!cn) | 374 | if (!cn) |
| 409 | break; | 375 | break; |
| 410 | if (cn == '\n') | 376 | if (cn == '\n') |
| 411 | cn = ' '; /* replace newlines with space */ | 377 | cn = ' '; /* replace newlines with space */ |
| 412 | if (cn == 0x0d) | 378 | if (cn == 0x0d) |
| 413 | cn = ' '; /* replace 0x0d with space */ | 379 | cn = ' '; /* replace 0x0d with space */ |
| 414 | if (cn == ' ' && c == ' ') | 380 | if (cn == ' ' && c == ' ') |
| 415 | continue; /* remove additional spaces */ | 381 | continue; /* remove additional spaces */ |
| 416 | c = cn; | 382 | c = cn; |
| 417 | if (to - command_line >= COMMAND_LINE_SIZE) | 383 | if (to - command_line >= COMMAND_LINE_SIZE) |
| 418 | break; | 384 | break; |
| 419 | *(to++) = c; | 385 | *(to++) = c; |
| 420 | } | 386 | } |
| 421 | if (c == ' ' && to > command_line) to--; | 387 | if (c == ' ' && to > command_line) to--; |
| 422 | *to = '\0'; | 388 | *to = '\0'; |
| 423 | *cmdline_p = command_line; | 389 | *cmdline_p = command_line; |
| 390 | } | ||
| 391 | |||
| 392 | static void __init | ||
| 393 | setup_lowcore(void) | ||
| 394 | { | ||
| 395 | struct _lowcore *lc; | ||
| 396 | int lc_pages; | ||
| 397 | |||
| 398 | /* | ||
| 399 | * Setup lowcore for boot cpu | ||
| 400 | */ | ||
| 401 | lc_pages = sizeof(void *) == 8 ? 2 : 1; | ||
| 402 | lc = (struct _lowcore *) | ||
| 403 | __alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0); | ||
| 404 | memset(lc, 0, lc_pages * PAGE_SIZE); | ||
| 405 | lc->restart_psw.mask = PSW_BASE_BITS; | ||
| 406 | lc->restart_psw.addr = | ||
| 407 | PSW_ADDR_AMODE | (unsigned long) restart_int_handler; | ||
| 408 | lc->external_new_psw.mask = PSW_KERNEL_BITS; | ||
| 409 | lc->external_new_psw.addr = | ||
| 410 | PSW_ADDR_AMODE | (unsigned long) ext_int_handler; | ||
| 411 | lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT; | ||
| 412 | lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; | ||
| 413 | lc->program_new_psw.mask = PSW_KERNEL_BITS; | ||
| 414 | lc->program_new_psw.addr = | ||
| 415 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; | ||
| 416 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | ||
| 417 | lc->mcck_new_psw.addr = | ||
| 418 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; | ||
| 419 | lc->io_new_psw.mask = PSW_KERNEL_BITS; | ||
| 420 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; | ||
| 421 | lc->ipl_device = S390_lowcore.ipl_device; | ||
| 422 | lc->jiffy_timer = -1LL; | ||
| 423 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | ||
| 424 | lc->async_stack = (unsigned long) | ||
| 425 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | ||
| 426 | #ifdef CONFIG_CHECK_STACK | ||
| 427 | lc->panic_stack = (unsigned long) | ||
| 428 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; | ||
| 429 | #endif | ||
| 430 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; | ||
| 431 | lc->thread_info = (unsigned long) &init_thread_union; | ||
| 432 | #ifdef CONFIG_ARCH_S390X | ||
| 433 | if (MACHINE_HAS_DIAG44) | ||
| 434 | lc->diag44_opcode = 0x83000044; | ||
| 435 | else | ||
| 436 | lc->diag44_opcode = 0x07000700; | ||
| 437 | #endif /* CONFIG_ARCH_S390X */ | ||
| 438 | set_prefix((u32)(unsigned long) lc); | ||
| 439 | } | ||
| 440 | |||
| 441 | static void __init | ||
| 442 | setup_resources(void) | ||
| 443 | { | ||
| 444 | struct resource *res; | ||
| 445 | int i; | ||
| 446 | |||
| 447 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { | ||
| 448 | res = alloc_bootmem_low(sizeof(struct resource)); | ||
| 449 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | ||
| 450 | switch (memory_chunk[i].type) { | ||
| 451 | case CHUNK_READ_WRITE: | ||
| 452 | res->name = "System RAM"; | ||
| 453 | break; | ||
| 454 | case CHUNK_READ_ONLY: | ||
| 455 | res->name = "System ROM"; | ||
| 456 | res->flags |= IORESOURCE_READONLY; | ||
| 457 | break; | ||
| 458 | default: | ||
| 459 | res->name = "reserved"; | ||
| 460 | } | ||
| 461 | res->start = memory_chunk[i].addr; | ||
| 462 | res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; | ||
| 463 | request_resource(&iomem_resource, res); | ||
| 464 | request_resource(res, &code_resource); | ||
| 465 | request_resource(res, &data_resource); | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 469 | static void __init | ||
| 470 | setup_memory(void) | ||
| 471 | { | ||
| 472 | unsigned long bootmap_size; | ||
| 473 | unsigned long start_pfn, end_pfn; | ||
| 474 | unsigned long last_rw_end; | ||
| 475 | int i; | ||
| 424 | 476 | ||
| 425 | /* | 477 | /* |
| 426 | * partially used pages are not usable - thus | 478 | * partially used pages are not usable - thus |
| @@ -437,6 +489,8 @@ void __init setup_arch(char **cmdline_p) | |||
| 437 | /* | 489 | /* |
| 438 | * Register RAM areas with the bootmem allocator. | 490 | * Register RAM areas with the bootmem allocator. |
| 439 | */ | 491 | */ |
| 492 | last_rw_end = start_pfn; | ||
| 493 | |||
| 440 | for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { | 494 | for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { |
| 441 | unsigned long start_chunk, end_chunk; | 495 | unsigned long start_chunk, end_chunk; |
| 442 | 496 | ||
| @@ -450,102 +504,91 @@ void __init setup_arch(char **cmdline_p) | |||
| 450 | start_chunk = start_pfn; | 504 | start_chunk = start_pfn; |
| 451 | if (end_chunk > end_pfn) | 505 | if (end_chunk > end_pfn) |
| 452 | end_chunk = end_pfn; | 506 | end_chunk = end_pfn; |
| 453 | if (start_chunk < end_chunk) | 507 | if (start_chunk < end_chunk) { |
| 454 | free_bootmem(start_chunk << PAGE_SHIFT, | 508 | free_bootmem(start_chunk << PAGE_SHIFT, |
| 455 | (end_chunk - start_chunk) << PAGE_SHIFT); | 509 | (end_chunk - start_chunk) << PAGE_SHIFT); |
| 510 | if (last_rw_end < start_chunk) | ||
| 511 | add_memory_hole(last_rw_end, start_chunk - 1); | ||
| 512 | last_rw_end = end_chunk; | ||
| 513 | } | ||
| 456 | } | 514 | } |
| 457 | 515 | ||
| 458 | /* | 516 | if (last_rw_end < end_pfn - 1) |
| 459 | * Reserve the bootmem bitmap itself as well. We do this in two | 517 | add_memory_hole(last_rw_end, end_pfn - 1); |
| 460 | * steps (first step was init_bootmem()) because this catches | 518 | |
| 461 | * the (very unlikely) case of us accidentally initializing the | 519 | /* |
| 462 | * bootmem allocator with an invalid RAM area. | 520 | * Reserve the bootmem bitmap itself as well. We do this in two |
| 463 | */ | 521 | * steps (first step was init_bootmem()) because this catches |
| 464 | reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); | 522 | * the (very unlikely) case of us accidentally initializing the |
| 523 | * bootmem allocator with an invalid RAM area. | ||
| 524 | */ | ||
| 525 | reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); | ||
| 465 | 526 | ||
| 466 | #ifdef CONFIG_BLK_DEV_INITRD | 527 | #ifdef CONFIG_BLK_DEV_INITRD |
| 467 | if (INITRD_START) { | 528 | if (INITRD_START) { |
| 468 | if (INITRD_START + INITRD_SIZE <= memory_end) { | 529 | if (INITRD_START + INITRD_SIZE <= memory_end) { |
| 469 | reserve_bootmem(INITRD_START, INITRD_SIZE); | 530 | reserve_bootmem(INITRD_START, INITRD_SIZE); |
| 470 | initrd_start = INITRD_START; | 531 | initrd_start = INITRD_START; |
| 471 | initrd_end = initrd_start + INITRD_SIZE; | 532 | initrd_end = initrd_start + INITRD_SIZE; |
| 472 | } else { | 533 | } else { |
| 473 | printk("initrd extends beyond end of memory " | 534 | printk("initrd extends beyond end of memory " |
| 474 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", | 535 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", |
| 475 | initrd_start + INITRD_SIZE, memory_end); | 536 | initrd_start + INITRD_SIZE, memory_end); |
| 476 | initrd_start = initrd_end = 0; | 537 | initrd_start = initrd_end = 0; |
| 477 | } | 538 | } |
| 478 | } | 539 | } |
| 479 | #endif | 540 | #endif |
| 541 | } | ||
| 480 | 542 | ||
| 481 | for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { | 543 | /* |
| 482 | struct resource *res; | 544 | * Setup function called from init/main.c just after the banner |
| 483 | 545 | * was printed. | |
| 484 | res = alloc_bootmem_low(sizeof(struct resource)); | 546 | */ |
| 485 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | ||
| 486 | |||
| 487 | switch (memory_chunk[i].type) { | ||
| 488 | case CHUNK_READ_WRITE: | ||
| 489 | res->name = "System RAM"; | ||
| 490 | break; | ||
| 491 | case CHUNK_READ_ONLY: | ||
| 492 | res->name = "System ROM"; | ||
| 493 | res->flags |= IORESOURCE_READONLY; | ||
| 494 | break; | ||
| 495 | default: | ||
| 496 | res->name = "reserved"; | ||
| 497 | } | ||
| 498 | res->start = memory_chunk[i].addr; | ||
| 499 | res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; | ||
| 500 | request_resource(&iomem_resource, res); | ||
| 501 | request_resource(res, &code_resource); | ||
| 502 | request_resource(res, &data_resource); | ||
| 503 | } | ||
| 504 | 547 | ||
| 548 | void __init | ||
| 549 | setup_arch(char **cmdline_p) | ||
| 550 | { | ||
| 505 | /* | 551 | /* |
| 506 | * Setup lowcore for boot cpu | 552 | * print what head.S has found out about the machine |
| 507 | */ | 553 | */ |
| 508 | #ifndef CONFIG_ARCH_S390X | 554 | #ifndef CONFIG_ARCH_S390X |
| 509 | lc = (struct _lowcore *) __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); | 555 | printk((MACHINE_IS_VM) ? |
| 510 | memset(lc, 0, PAGE_SIZE); | 556 | "We are running under VM (31 bit mode)\n" : |
| 557 | "We are running native (31 bit mode)\n"); | ||
| 558 | printk((MACHINE_HAS_IEEE) ? | ||
| 559 | "This machine has an IEEE fpu\n" : | ||
| 560 | "This machine has no IEEE fpu\n"); | ||
| 511 | #else /* CONFIG_ARCH_S390X */ | 561 | #else /* CONFIG_ARCH_S390X */ |
| 512 | lc = (struct _lowcore *) __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0); | 562 | printk((MACHINE_IS_VM) ? |
| 513 | memset(lc, 0, 2*PAGE_SIZE); | 563 | "We are running under VM (64 bit mode)\n" : |
| 564 | "We are running native (64 bit mode)\n"); | ||
| 514 | #endif /* CONFIG_ARCH_S390X */ | 565 | #endif /* CONFIG_ARCH_S390X */ |
| 515 | lc->restart_psw.mask = PSW_BASE_BITS; | 566 | |
| 516 | lc->restart_psw.addr = | 567 | ROOT_DEV = Root_RAM0; |
| 517 | PSW_ADDR_AMODE | (unsigned long) restart_int_handler; | 568 | #ifndef CONFIG_ARCH_S390X |
| 518 | lc->external_new_psw.mask = PSW_KERNEL_BITS; | 569 | memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */ |
| 519 | lc->external_new_psw.addr = | 570 | /* |
| 520 | PSW_ADDR_AMODE | (unsigned long) ext_int_handler; | 571 | * We need some free virtual space to be able to do vmalloc. |
| 521 | lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT; | 572 | * On a machine with 2GB memory we make sure that we have at |
| 522 | lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; | 573 | * least 128 MB free space for vmalloc. |
| 523 | lc->program_new_psw.mask = PSW_KERNEL_BITS; | 574 | */ |
| 524 | lc->program_new_psw.addr = | 575 | if (memory_end > 1920*1024*1024) |
| 525 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; | 576 | memory_end = 1920*1024*1024; |
| 526 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | 577 | #else /* CONFIG_ARCH_S390X */ |
| 527 | lc->mcck_new_psw.addr = | 578 | memory_end = memory_size & ~0x200000UL; /* detected in head.s */ |
| 528 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; | ||
| 529 | lc->io_new_psw.mask = PSW_KERNEL_BITS; | ||
| 530 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; | ||
| 531 | lc->ipl_device = S390_lowcore.ipl_device; | ||
| 532 | lc->jiffy_timer = -1LL; | ||
| 533 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | ||
| 534 | lc->async_stack = (unsigned long) | ||
| 535 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | ||
| 536 | #ifdef CONFIG_CHECK_STACK | ||
| 537 | lc->panic_stack = (unsigned long) | ||
| 538 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; | ||
| 539 | #endif | ||
| 540 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; | ||
| 541 | lc->thread_info = (unsigned long) &init_thread_union; | ||
| 542 | #ifdef CONFIG_ARCH_S390X | ||
| 543 | if (MACHINE_HAS_DIAG44) | ||
| 544 | lc->diag44_opcode = 0x83000044; | ||
| 545 | else | ||
| 546 | lc->diag44_opcode = 0x07000700; | ||
| 547 | #endif /* CONFIG_ARCH_S390X */ | 579 | #endif /* CONFIG_ARCH_S390X */ |
| 548 | set_prefix((u32)(unsigned long) lc); | 580 | |
| 581 | init_mm.start_code = PAGE_OFFSET; | ||
| 582 | init_mm.end_code = (unsigned long) &_etext; | ||
| 583 | init_mm.end_data = (unsigned long) &_edata; | ||
| 584 | init_mm.brk = (unsigned long) &_end; | ||
| 585 | |||
| 586 | parse_cmdline_early(cmdline_p); | ||
| 587 | |||
| 588 | setup_memory(); | ||
| 589 | setup_resources(); | ||
| 590 | setup_lowcore(); | ||
| 591 | |||
| 549 | cpu_init(); | 592 | cpu_init(); |
| 550 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; | 593 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; |
| 551 | 594 | ||
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 8e723bc7f795..6ec5cd981e74 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
| @@ -101,6 +101,7 @@ extern unsigned long _end; | |||
| 101 | extern unsigned long __init_begin; | 101 | extern unsigned long __init_begin; |
| 102 | extern unsigned long __init_end; | 102 | extern unsigned long __init_end; |
| 103 | 103 | ||
| 104 | extern unsigned long __initdata zholes_size[]; | ||
| 104 | /* | 105 | /* |
| 105 | * paging_init() sets up the page tables | 106 | * paging_init() sets up the page tables |
| 106 | */ | 107 | */ |
| @@ -163,10 +164,13 @@ void __init paging_init(void) | |||
| 163 | local_flush_tlb(); | 164 | local_flush_tlb(); |
| 164 | 165 | ||
| 165 | { | 166 | { |
| 166 | unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0}; | 167 | unsigned long zones_size[MAX_NR_ZONES]; |
| 167 | 168 | ||
| 169 | memset(zones_size, 0, sizeof(zones_size)); | ||
| 168 | zones_size[ZONE_DMA] = max_low_pfn; | 170 | zones_size[ZONE_DMA] = max_low_pfn; |
| 169 | free_area_init(zones_size); | 171 | free_area_init_node(0, &contig_page_data, zones_size, |
| 172 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, | ||
| 173 | zholes_size); | ||
| 170 | } | 174 | } |
| 171 | return; | 175 | return; |
| 172 | } | 176 | } |
| @@ -184,9 +188,10 @@ void __init paging_init(void) | |||
| 184 | _KERN_REGION_TABLE; | 188 | _KERN_REGION_TABLE; |
| 185 | static const int ssm_mask = 0x04000000L; | 189 | static const int ssm_mask = 0x04000000L; |
| 186 | 190 | ||
| 187 | unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; | 191 | unsigned long zones_size[MAX_NR_ZONES]; |
| 188 | unsigned long dma_pfn, high_pfn; | 192 | unsigned long dma_pfn, high_pfn; |
| 189 | 193 | ||
| 194 | memset(zones_size, 0, sizeof(zones_size)); | ||
| 190 | dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; | 195 | dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; |
| 191 | high_pfn = max_low_pfn; | 196 | high_pfn = max_low_pfn; |
| 192 | 197 | ||
| @@ -198,8 +203,8 @@ void __init paging_init(void) | |||
| 198 | } | 203 | } |
| 199 | 204 | ||
| 200 | /* Initialize mem_map[]. */ | 205 | /* Initialize mem_map[]. */ |
| 201 | free_area_init(zones_size); | 206 | free_area_init_node(0, &contig_page_data, zones_size, |
| 202 | 207 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); | |
| 203 | 208 | ||
| 204 | /* | 209 | /* |
| 205 | * map whole physical memory to virtual memory (identity mapping) | 210 | * map whole physical memory to virtual memory (identity mapping) |
