diff options
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 813c2cd194c2..d66c5e77fcff 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -180,6 +180,16 @@ static unsigned long __initdata prom_tce_alloc_start; | |||
180 | static unsigned long __initdata prom_tce_alloc_end; | 180 | static unsigned long __initdata prom_tce_alloc_end; |
181 | #endif | 181 | #endif |
182 | 182 | ||
183 | /* Platforms codes are now obsolete in the kernel. Now only used within this | ||
184 | * file and ultimately gone too. Feel free to change them if you need, they | ||
185 | * are not shared with anything outside of this file anymore | ||
186 | */ | ||
187 | #define PLATFORM_PSERIES 0x0100 | ||
188 | #define PLATFORM_PSERIES_LPAR 0x0101 | ||
189 | #define PLATFORM_LPAR 0x0001 | ||
190 | #define PLATFORM_POWERMAC 0x0400 | ||
191 | #define PLATFORM_GENERIC 0x0500 | ||
192 | |||
183 | static int __initdata of_platform; | 193 | static int __initdata of_platform; |
184 | 194 | ||
185 | static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; | 195 | static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; |
@@ -397,6 +407,11 @@ static void __init __attribute__((noreturn)) prom_panic(const char *reason) | |||
397 | reason = PTRRELOC(reason); | 407 | reason = PTRRELOC(reason); |
398 | #endif | 408 | #endif |
399 | prom_print(reason); | 409 | prom_print(reason); |
410 | /* Do not call exit because it clears the screen on pmac | ||
411 | * it also causes some sort of double-fault on early pmacs */ | ||
412 | if (RELOC(of_platform) == PLATFORM_POWERMAC) | ||
413 | asm("trap\n"); | ||
414 | |||
400 | /* ToDo: should put up an SRC here on p/iSeries */ | 415 | /* ToDo: should put up an SRC here on p/iSeries */ |
401 | call_prom("exit", 0, 0); | 416 | call_prom("exit", 0, 0); |
402 | 417 | ||
@@ -1487,7 +1502,10 @@ static int __init prom_find_machine_type(void) | |||
1487 | int len, i = 0; | 1502 | int len, i = 0; |
1488 | #ifdef CONFIG_PPC64 | 1503 | #ifdef CONFIG_PPC64 |
1489 | phandle rtas; | 1504 | phandle rtas; |
1505 | int x; | ||
1490 | #endif | 1506 | #endif |
1507 | |||
1508 | /* Look for a PowerMac */ | ||
1491 | len = prom_getprop(_prom->root, "compatible", | 1509 | len = prom_getprop(_prom->root, "compatible", |
1492 | compat, sizeof(compat)-1); | 1510 | compat, sizeof(compat)-1); |
1493 | if (len > 0) { | 1511 | if (len > 0) { |
@@ -1500,28 +1518,36 @@ static int __init prom_find_machine_type(void) | |||
1500 | if (strstr(p, RELOC("Power Macintosh")) || | 1518 | if (strstr(p, RELOC("Power Macintosh")) || |
1501 | strstr(p, RELOC("MacRISC"))) | 1519 | strstr(p, RELOC("MacRISC"))) |
1502 | return PLATFORM_POWERMAC; | 1520 | return PLATFORM_POWERMAC; |
1503 | #ifdef CONFIG_PPC64 | ||
1504 | if (strstr(p, RELOC("Momentum,Maple"))) | ||
1505 | return PLATFORM_MAPLE; | ||
1506 | if (strstr(p, RELOC("IBM,CPB"))) | ||
1507 | return PLATFORM_CELL; | ||
1508 | #endif | ||
1509 | i += sl + 1; | 1521 | i += sl + 1; |
1510 | } | 1522 | } |
1511 | } | 1523 | } |
1512 | #ifdef CONFIG_PPC64 | 1524 | #ifdef CONFIG_PPC64 |
1525 | /* If not a mac, try to figure out if it's an IBM pSeries or any other | ||
1526 | * PAPR compliant platform. We assume it is if : | ||
1527 | * - /device_type is "chrp" (please, do NOT use that for future | ||
1528 | * non-IBM designs ! | ||
1529 | * - it has /rtas | ||
1530 | */ | ||
1531 | len = prom_getprop(_prom->root, "model", | ||
1532 | compat, sizeof(compat)-1); | ||
1533 | if (len <= 0) | ||
1534 | return PLATFORM_GENERIC; | ||
1535 | compat[len] = 0; | ||
1536 | if (strcmp(compat, "chrp")) | ||
1537 | return PLATFORM_GENERIC; | ||
1538 | |||
1513 | /* Default to pSeries. We need to know if we are running LPAR */ | 1539 | /* Default to pSeries. We need to know if we are running LPAR */ |
1514 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); | 1540 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); |
1515 | if (PHANDLE_VALID(rtas)) { | 1541 | if (!PHANDLE_VALID(rtas)) |
1516 | int x = prom_getproplen(rtas, "ibm,hypertas-functions"); | 1542 | return PLATFORM_GENERIC; |
1517 | if (x != PROM_ERROR) { | 1543 | x = prom_getproplen(rtas, "ibm,hypertas-functions"); |
1518 | prom_printf("Hypertas detected, assuming LPAR !\n"); | 1544 | if (x != PROM_ERROR) { |
1519 | return PLATFORM_PSERIES_LPAR; | 1545 | prom_printf("Hypertas detected, assuming LPAR !\n"); |
1520 | } | 1546 | return PLATFORM_PSERIES_LPAR; |
1521 | } | 1547 | } |
1522 | return PLATFORM_PSERIES; | 1548 | return PLATFORM_PSERIES; |
1523 | #else | 1549 | #else |
1524 | return PLATFORM_CHRP; | 1550 | return PLATFORM_GENERIC; |
1525 | #endif | 1551 | #endif |
1526 | } | 1552 | } |
1527 | 1553 | ||
@@ -2029,7 +2055,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2029 | { | 2055 | { |
2030 | struct prom_t *_prom; | 2056 | struct prom_t *_prom; |
2031 | unsigned long hdr; | 2057 | unsigned long hdr; |
2032 | u32 getprop_rval; | ||
2033 | unsigned long offset = reloc_offset(); | 2058 | unsigned long offset = reloc_offset(); |
2034 | 2059 | ||
2035 | #ifdef CONFIG_PPC32 | 2060 | #ifdef CONFIG_PPC32 |
@@ -2060,6 +2085,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2060 | */ | 2085 | */ |
2061 | prom_init_stdout(); | 2086 | prom_init_stdout(); |
2062 | 2087 | ||
2088 | /* | ||
2089 | * Get default machine type. At this point, we do not differentiate | ||
2090 | * between pSeries SMP and pSeries LPAR | ||
2091 | */ | ||
2092 | RELOC(of_platform) = prom_find_machine_type(); | ||
2093 | |||
2063 | /* Bail if this is a kdump kernel. */ | 2094 | /* Bail if this is a kdump kernel. */ |
2064 | if (PHYSICAL_START > 0) | 2095 | if (PHYSICAL_START > 0) |
2065 | prom_panic("Error: You can't boot a kdump kernel from OF!\n"); | 2096 | prom_panic("Error: You can't boot a kdump kernel from OF!\n"); |
@@ -2069,15 +2100,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2069 | */ | 2100 | */ |
2070 | prom_check_initrd(r3, r4); | 2101 | prom_check_initrd(r3, r4); |
2071 | 2102 | ||
2072 | /* | ||
2073 | * Get default machine type. At this point, we do not differentiate | ||
2074 | * between pSeries SMP and pSeries LPAR | ||
2075 | */ | ||
2076 | RELOC(of_platform) = prom_find_machine_type(); | ||
2077 | getprop_rval = RELOC(of_platform); | ||
2078 | prom_setprop(_prom->chosen, "/chosen", "linux,platform", | ||
2079 | &getprop_rval, sizeof(getprop_rval)); | ||
2080 | |||
2081 | #ifdef CONFIG_PPC_PSERIES | 2103 | #ifdef CONFIG_PPC_PSERIES |
2082 | /* | 2104 | /* |
2083 | * On pSeries, inform the firmware about our capabilities | 2105 | * On pSeries, inform the firmware about our capabilities |