aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r--arch/powerpc/kernel/prom_init.c165
1 files changed, 155 insertions, 10 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index d66c5e77fcff..41e9ab40cd54 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -636,10 +636,96 @@ static void __init early_cmdline_parse(void)
636 636
637#ifdef CONFIG_PPC_PSERIES 637#ifdef CONFIG_PPC_PSERIES
638/* 638/*
639 * To tell the firmware what our capabilities are, we have to pass 639 * There are two methods for telling firmware what our capabilities are.
640 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections 640 * Newer machines have an "ibm,client-architecture-support" method on the
641 * that contain structures that contain the actual values. 641 * root node. For older machines, we have to call the "process-elf-header"
642 * method in the /packages/elf-loader node, passing it a fake 32-bit
643 * ELF header containing a couple of PT_NOTE sections that contain
644 * structures that contain various information.
642 */ 645 */
646
647/*
648 * New method - extensible architecture description vector.
649 *
650 * Because the description vector contains a mix of byte and word
651 * values, we declare it as an unsigned char array, and use this
652 * macro to put word values in.
653 */
654#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
655 ((x) >> 8) & 0xff, (x) & 0xff
656
657/* Option vector bits - generic bits in byte 1 */
658#define OV_IGNORE 0x80 /* ignore this vector */
659#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
660
661/* Option vector 1: processor architectures supported */
662#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
663#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
664#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
665#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
666#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
667#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
668
669/* Option vector 2: Open Firmware options supported */
670#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
671
672/* Option vector 3: processor options supported */
673#define OV3_FP 0x80 /* floating point */
674#define OV3_VMX 0x40 /* VMX/Altivec */
675
676/* Option vector 5: PAPR/OF options supported */
677#define OV5_LPAR 0x80 /* logical partitioning supported */
678#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
679/* ibm,dynamic-reconfiguration-memory property supported */
680#define OV5_DRCONF_MEMORY 0x20
681#define OV5_LARGE_PAGES 0x10 /* large pages supported */
682
683/*
684 * The architecture vector has an array of PVR mask/value pairs,
685 * followed by # option vectors - 1, followed by the option vectors.
686 */
687static unsigned char ibm_architecture_vec[] = {
688 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
689 W(0xffff0000), W(0x003e0000), /* POWER6 */
690 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
691 5 - 1, /* 5 option vectors */
692
693 /* option vector 1: processor architectures supported */
694 3 - 1, /* length */
695 0, /* don't ignore, don't halt */
696 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
697 OV1_PPC_2_04 | OV1_PPC_2_05,
698
699 /* option vector 2: Open Firmware options supported */
700 34 - 1, /* length */
701 OV2_REAL_MODE,
702 0, 0,
703 W(0xffffffff), /* real_base */
704 W(0xffffffff), /* real_size */
705 W(0xffffffff), /* virt_base */
706 W(0xffffffff), /* virt_size */
707 W(0xffffffff), /* load_base */
708 W(64), /* 128MB min RMA */
709 W(0xffffffff), /* full client load */
710 0, /* min RMA percentage of total RAM */
711 48, /* max log_2(hash table size) */
712
713 /* option vector 3: processor options supported */
714 3 - 1, /* length */
715 0, /* don't ignore, don't halt */
716 OV3_FP | OV3_VMX,
717
718 /* option vector 4: IBM PAPR implementation */
719 2 - 1, /* length */
720 0, /* don't halt */
721
722 /* option vector 5: PAPR/OF options */
723 3 - 1, /* length */
724 0, /* don't ignore, don't halt */
725 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
726};
727
728/* Old method - ELF header with PT_NOTE sections */
643static struct fake_elf { 729static struct fake_elf {
644 Elf32_Ehdr elfhdr; 730 Elf32_Ehdr elfhdr;
645 Elf32_Phdr phdr[2]; 731 Elf32_Phdr phdr[2];
@@ -728,8 +814,26 @@ static struct fake_elf {
728 814
729static void __init prom_send_capabilities(void) 815static void __init prom_send_capabilities(void)
730{ 816{
731 ihandle elfloader; 817 ihandle elfloader, root;
818 prom_arg_t ret;
819
820 root = call_prom("open", 1, 1, ADDR("/"));
821 if (root != 0) {
822 /* try calling the ibm,client-architecture-support method */
823 if (call_prom_ret("call-method", 3, 2, &ret,
824 ADDR("ibm,client-architecture-support"),
825 ADDR(ibm_architecture_vec)) == 0) {
826 /* the call exists... */
827 if (ret)
828 prom_printf("WARNING: ibm,client-architecture"
829 "-support call FAILED!\n");
830 call_prom("close", 1, 0, root);
831 return;
832 }
833 call_prom("close", 1, 0, root);
834 }
732 835
836 /* no ibm,client-architecture-support call, try the old way */
733 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); 837 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
734 if (elfloader == 0) { 838 if (elfloader == 0) {
735 prom_printf("couldn't open /packages/elf-loader\n"); 839 prom_printf("couldn't open /packages/elf-loader\n");
@@ -1528,12 +1632,11 @@ static int __init prom_find_machine_type(void)
1528 * non-IBM designs ! 1632 * non-IBM designs !
1529 * - it has /rtas 1633 * - it has /rtas
1530 */ 1634 */
1531 len = prom_getprop(_prom->root, "model", 1635 len = prom_getprop(_prom->root, "device_type",
1532 compat, sizeof(compat)-1); 1636 compat, sizeof(compat)-1);
1533 if (len <= 0) 1637 if (len <= 0)
1534 return PLATFORM_GENERIC; 1638 return PLATFORM_GENERIC;
1535 compat[len] = 0; 1639 if (strcmp(compat, RELOC("chrp")))
1536 if (strcmp(compat, "chrp"))
1537 return PLATFORM_GENERIC; 1640 return PLATFORM_GENERIC;
1538 1641
1539 /* Default to pSeries. We need to know if we are running LPAR */ 1642 /* Default to pSeries. We need to know if we are running LPAR */
@@ -1954,10 +2057,45 @@ static void __init flatten_device_tree(void)
1954 2057
1955} 2058}
1956 2059
1957 2060#ifdef CONFIG_PPC_MAPLE
1958static void __init fixup_device_tree(void) 2061/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
2062 * The values are bad, and it doesn't even have the right number of cells. */
2063static void __init fixup_device_tree_maple(void)
1959{ 2064{
2065 phandle isa;
2066 u32 isa_ranges[6];
2067
2068 isa = call_prom("finddevice", 1, 1, ADDR("/ht@0/isa@4"));
2069 if (!PHANDLE_VALID(isa))
2070 return;
2071
2072 if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
2073 == PROM_ERROR)
2074 return;
2075
2076 if (isa_ranges[0] != 0x1 ||
2077 isa_ranges[1] != 0xf4000000 ||
2078 isa_ranges[2] != 0x00010000)
2079 return;
2080
2081 prom_printf("fixing up bogus ISA range on Maple...\n");
2082
2083 isa_ranges[0] = 0x1;
2084 isa_ranges[1] = 0x0;
2085 isa_ranges[2] = 0x01002000; /* IO space; PCI device = 4 */
2086 isa_ranges[3] = 0x0;
2087 isa_ranges[4] = 0x0;
2088 isa_ranges[5] = 0x00010000;
2089 prom_setprop(isa, "/ht@0/isa@4", "ranges",
2090 isa_ranges, sizeof(isa_ranges));
2091}
2092#else
2093#define fixup_device_tree_maple()
2094#endif
2095
1960#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC) 2096#if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
2097static void __init fixup_device_tree_pmac(void)
2098{
1961 phandle u3, i2c, mpic; 2099 phandle u3, i2c, mpic;
1962 u32 u3_rev; 2100 u32 u3_rev;
1963 u32 interrupts[2]; 2101 u32 interrupts[2];
@@ -1994,9 +2132,16 @@ static void __init fixup_device_tree(void)
1994 parent = (u32)mpic; 2132 parent = (u32)mpic;
1995 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent", 2133 prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
1996 &parent, sizeof(parent)); 2134 &parent, sizeof(parent));
1997#endif
1998} 2135}
2136#else
2137#define fixup_device_tree_pmac()
2138#endif
1999 2139
2140static void __init fixup_device_tree(void)
2141{
2142 fixup_device_tree_maple();
2143 fixup_device_tree_pmac();
2144}
2000 2145
2001static void __init prom_find_boot_cpu(void) 2146static void __init prom_find_boot_cpu(void)
2002{ 2147{