aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/prom_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/prom_init.c')
-rw-r--r--arch/ppc64/kernel/prom_init.c115
1 files changed, 114 insertions, 1 deletions
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 8dffa9ae2623..35ec42de962e 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -493,6 +493,113 @@ static void __init early_cmdline_parse(void)
493} 493}
494 494
495/* 495/*
496 * To tell the firmware what our capabilities are, we have to pass
497 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
498 * that contain structures that contain the actual values.
499 */
500static struct fake_elf {
501 Elf32_Ehdr elfhdr;
502 Elf32_Phdr phdr[2];
503 struct chrpnote {
504 u32 namesz;
505 u32 descsz;
506 u32 type;
507 char name[8]; /* "PowerPC" */
508 struct chrpdesc {
509 u32 real_mode;
510 u32 real_base;
511 u32 real_size;
512 u32 virt_base;
513 u32 virt_size;
514 u32 load_base;
515 } chrpdesc;
516 } chrpnote;
517 struct rpanote {
518 u32 namesz;
519 u32 descsz;
520 u32 type;
521 char name[24]; /* "IBM,RPA-Client-Config" */
522 struct rpadesc {
523 u32 lpar_affinity;
524 u32 min_rmo_size;
525 u32 min_rmo_percent;
526 u32 max_pft_size;
527 u32 splpar;
528 u32 min_load;
529 u32 new_mem_def;
530 u32 ignore_me;
531 } rpadesc;
532 } rpanote;
533} fake_elf = {
534 .elfhdr = {
535 .e_ident = { 0x7f, 'E', 'L', 'F',
536 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
537 .e_type = ET_EXEC, /* yeah right */
538 .e_machine = EM_PPC,
539 .e_version = EV_CURRENT,
540 .e_phoff = offsetof(struct fake_elf, phdr),
541 .e_phentsize = sizeof(Elf32_Phdr),
542 .e_phnum = 2
543 },
544 .phdr = {
545 [0] = {
546 .p_type = PT_NOTE,
547 .p_offset = offsetof(struct fake_elf, chrpnote),
548 .p_filesz = sizeof(struct chrpnote)
549 }, [1] = {
550 .p_type = PT_NOTE,
551 .p_offset = offsetof(struct fake_elf, rpanote),
552 .p_filesz = sizeof(struct rpanote)
553 }
554 },
555 .chrpnote = {
556 .namesz = sizeof("PowerPC"),
557 .descsz = sizeof(struct chrpdesc),
558 .type = 0x1275,
559 .name = "PowerPC",
560 .chrpdesc = {
561 .real_mode = ~0U, /* ~0 means "don't care" */
562 .real_base = ~0U,
563 .real_size = ~0U,
564 .virt_base = ~0U,
565 .virt_size = ~0U,
566 .load_base = ~0U
567 },
568 },
569 .rpanote = {
570 .namesz = sizeof("IBM,RPA-Client-Config"),
571 .descsz = sizeof(struct rpadesc),
572 .type = 0x12759999,
573 .name = "IBM,RPA-Client-Config",
574 .rpadesc = {
575 .lpar_affinity = 0,
576 .min_rmo_size = 64, /* in megabytes */
577 .min_rmo_percent = 0,
578 .max_pft_size = 48, /* 2^48 bytes max PFT size */
579 .splpar = 1,
580 .min_load = ~0U,
581 .new_mem_def = 0
582 }
583 }
584};
585
586static void __init prom_send_capabilities(void)
587{
588 unsigned long offset = reloc_offset();
589 ihandle elfloader;
590 int ret;
591
592 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
593 if (elfloader == 0) {
594 prom_printf("couldn't open /packages/elf-loader\n");
595 return;
596 }
597 ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"),
598 elfloader, ADDR(&fake_elf));
599 call_prom("close", 1, 0, elfloader);
600}
601
602/*
496 * Memory allocation strategy... our layout is normally: 603 * Memory allocation strategy... our layout is normally:
497 * 604 *
498 * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd 605 * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd
@@ -1448,6 +1555,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
1448 } 1555 }
1449} 1556}
1450 1557
1558/*
1559 * The Open Firmware 1275 specification states properties must be 31 bytes or
1560 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1561 */
1562#define MAX_PROPERTY_NAME 64
1563
1451static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, 1564static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1452 unsigned long *mem_end) 1565 unsigned long *mem_end)
1453{ 1566{
@@ -1457,7 +1570,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1457 unsigned long soff; 1570 unsigned long soff;
1458 unsigned char *valp; 1571 unsigned char *valp;
1459 unsigned long offset = reloc_offset(); 1572 unsigned long offset = reloc_offset();
1460 char pname[32]; 1573 char pname[MAX_PROPERTY_NAME];
1461 char *path; 1574 char *path;
1462 1575
1463 path = RELOC(prom_scratch); 1576 path = RELOC(prom_scratch);