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