@@ -140,7 +140,9 @@ struct mem_map_entry {
140
140
141
141
typedef u32 cell_t ;
142
142
143
- extern void __start (unsigned long r3 , unsigned long r4 , unsigned long r5 );
143
+ extern void __start (unsigned long r3 , unsigned long r4 , unsigned long r5 ,
144
+ unsigned long r6 , unsigned long r7 , unsigned long r8 ,
145
+ unsigned long r9 );
144
146
145
147
#ifdef CONFIG_PPC64
146
148
extern int enter_prom (struct prom_args * args , unsigned long entry );
@@ -1293,6 +1295,11 @@ static int __initdata prom_rtas_start_cpu;
1293
1295
static u64 __initdata prom_rtas_data ;
1294
1296
static u64 __initdata prom_rtas_entry ;
1295
1297
1298
+ #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1299
+ static u64 __initdata prom_opal_base ;
1300
+ static u64 __initdata prom_opal_entry ;
1301
+ #endif
1302
+
1296
1303
/* XXX Don't change this structure without updating opal-takeover.S */
1297
1304
static struct opal_secondary_data {
1298
1305
s64 ack ; /* 0 */
@@ -1468,6 +1475,76 @@ static void prom_opal_takeover(void)
1468
1475
for (;;)
1469
1476
opal_do_takeover (args );
1470
1477
}
1478
+
1479
+ /*
1480
+ * Allocate room for and instantiate OPAL
1481
+ */
1482
+ static void __init prom_instantiate_opal (void )
1483
+ {
1484
+ phandle opal_node ;
1485
+ ihandle opal_inst ;
1486
+ u64 base , entry ;
1487
+ u64 size = 0 , align = 0x10000 ;
1488
+ u32 rets [2 ];
1489
+
1490
+ prom_debug ("prom_instantiate_opal: start...\n" );
1491
+
1492
+ opal_node = call_prom ("finddevice" , 1 , 1 , ADDR ("/ibm,opal" ));
1493
+ prom_debug ("opal_node: %x\n" , opal_node );
1494
+ if (!PHANDLE_VALID (opal_node ))
1495
+ return ;
1496
+
1497
+ prom_getprop (opal_node , "opal-runtime-size" , & size , sizeof (size ));
1498
+ if (size == 0 )
1499
+ return ;
1500
+ prom_getprop (opal_node , "opal-runtime-alignment" , & align ,
1501
+ sizeof (align ));
1502
+
1503
+ base = alloc_down (size , align , 0 );
1504
+ if (base == 0 ) {
1505
+ prom_printf ("OPAL allocation failed !\n" );
1506
+ return ;
1507
+ }
1508
+
1509
+ opal_inst = call_prom ("open" , 1 , 1 , ADDR ("/ibm,opal" ));
1510
+ if (!IHANDLE_VALID (opal_inst )) {
1511
+ prom_printf ("opening opal package failed (%x)\n" , opal_inst );
1512
+ return ;
1513
+ }
1514
+
1515
+ prom_printf ("instantiating opal at 0x%x..." , base );
1516
+
1517
+ if (call_prom_ret ("call-method" , 4 , 3 , rets ,
1518
+ ADDR ("load-opal-runtime" ),
1519
+ opal_inst ,
1520
+ base >> 32 , base & 0xffffffff ) != 0
1521
+ || (rets [0 ] == 0 && rets [1 ] == 0 )) {
1522
+ prom_printf (" failed\n" );
1523
+ return ;
1524
+ }
1525
+ entry = (((u64 )rets [0 ]) << 32 ) | rets [1 ];
1526
+
1527
+ prom_printf (" done\n" );
1528
+
1529
+ reserve_mem (base , size );
1530
+
1531
+ prom_debug ("opal base = 0x%x\n" , base );
1532
+ prom_debug ("opal align = 0x%x\n" , align );
1533
+ prom_debug ("opal entry = 0x%x\n" , entry );
1534
+ prom_debug ("opal size = 0x%x\n" , (long )size );
1535
+
1536
+ prom_setprop (opal_node , "/ibm,opal" , "opal-base-address" ,
1537
+ & base , sizeof (base ));
1538
+ prom_setprop (opal_node , "/ibm,opal" , "opal-entry-address" ,
1539
+ & entry , sizeof (entry ));
1540
+
1541
+ #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
1542
+ RELOC (prom_opal_base ) = base ;
1543
+ RELOC (prom_opal_entry ) = entry ;
1544
+ #endif
1545
+ prom_debug ("prom_instantiate_opal: end...\n" );
1546
+ }
1547
+
1471
1548
#endif /* CONFIG_PPC_POWERNV */
1472
1549
1473
1550
/*
@@ -1863,7 +1940,7 @@ static int __init prom_find_machine_type(void)
1863
1940
int x ;
1864
1941
#endif
1865
1942
1866
- /* Look for a PowerMac */
1943
+ /* Look for a PowerMac or a Cell */
1867
1944
len = prom_getprop (_prom -> root , "compatible" ,
1868
1945
compat , sizeof (compat )- 1 );
1869
1946
if (len > 0 ) {
@@ -1889,7 +1966,11 @@ static int __init prom_find_machine_type(void)
1889
1966
}
1890
1967
}
1891
1968
#ifdef CONFIG_PPC64
1892
- /* If not a mac, try to figure out if it's an IBM pSeries or any other
1969
+ /* Try to detect OPAL */
1970
+ if (PHANDLE_VALID (call_prom ("finddevice" , 1 , 1 , ADDR ("/ibm,opal" ))))
1971
+ return PLATFORM_OPAL ;
1972
+
1973
+ /* Try to figure out if it's an IBM pSeries or any other
1893
1974
* PAPR compliant platform. We assume it is if :
1894
1975
* - /device_type is "chrp" (please, do NOT use that for future
1895
1976
* non-IBM designs !
@@ -2116,7 +2197,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2116
2197
unsigned long soff ;
2117
2198
unsigned char * valp ;
2118
2199
static char pname [MAX_PROPERTY_NAME ];
2119
- int l , room ;
2200
+ int l , room , has_phandle = 0 ;
2120
2201
2121
2202
dt_push_token (OF_DT_BEGIN_NODE , mem_start , mem_end );
2122
2203
@@ -2200,19 +2281,26 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
2200
2281
valp = make_room (mem_start , mem_end , l , 4 );
2201
2282
call_prom ("getprop" , 4 , 1 , node , RELOC (pname ), valp , l );
2202
2283
* mem_start = _ALIGN (* mem_start , 4 );
2284
+
2285
+ if (!strcmp (RELOC (pname ), RELOC ("phandle" )))
2286
+ has_phandle = 1 ;
2203
2287
}
2204
2288
2205
- /* Add a "linux,phandle" property. */
2206
- soff = dt_find_string (RELOC ("linux,phandle" ));
2207
- if (soff == 0 )
2208
- prom_printf ("WARNING: Can't find string index for"
2209
- " <linux-phandle> node %s\n" , path );
2210
- else {
2211
- dt_push_token (OF_DT_PROP , mem_start , mem_end );
2212
- dt_push_token (4 , mem_start , mem_end );
2213
- dt_push_token (soff , mem_start , mem_end );
2214
- valp = make_room (mem_start , mem_end , 4 , 4 );
2215
- * (u32 * )valp = node ;
2289
+ /* Add a "linux,phandle" property if no "phandle" property already
2290
+ * existed (can happen with OPAL)
2291
+ */
2292
+ if (!has_phandle ) {
2293
+ soff = dt_find_string (RELOC ("linux,phandle" ));
2294
+ if (soff == 0 )
2295
+ prom_printf ("WARNING: Can't find string index for"
2296
+ " <linux-phandle> node %s\n" , path );
2297
+ else {
2298
+ dt_push_token (OF_DT_PROP , mem_start , mem_end );
2299
+ dt_push_token (4 , mem_start , mem_end );
2300
+ dt_push_token (soff , mem_start , mem_end );
2301
+ valp = make_room (mem_start , mem_end , 4 , 4 );
2302
+ * (u32 * )valp = node ;
2303
+ }
2216
2304
}
2217
2305
2218
2306
/* do all our children */
@@ -2746,6 +2834,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2746
2834
* between pSeries SMP and pSeries LPAR
2747
2835
*/
2748
2836
RELOC (of_platform ) = prom_find_machine_type ();
2837
+ prom_printf ("Detected machine type: %x\n" , RELOC (of_platform ));
2749
2838
2750
2839
#ifndef CONFIG_RELOCATABLE
2751
2840
/* Bail if this is a kdump kernel. */
@@ -2807,7 +2896,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2807
2896
* On non-powermacs, try to instantiate RTAS. PowerMacs don't
2808
2897
* have a usable RTAS implementation.
2809
2898
*/
2810
- if (RELOC (of_platform ) != PLATFORM_POWERMAC )
2899
+ if (RELOC (of_platform ) != PLATFORM_POWERMAC &&
2900
+ RELOC (of_platform ) != PLATFORM_OPAL )
2811
2901
prom_instantiate_rtas ();
2812
2902
2813
2903
#ifdef CONFIG_PPC_POWERNV
@@ -2818,15 +2908,17 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2818
2908
prom_opal_hold_cpus ();
2819
2909
prom_opal_takeover ();
2820
2910
}
2821
- }
2911
+ } else if (RELOC (of_platform ) == PLATFORM_OPAL )
2912
+ prom_instantiate_opal ();
2822
2913
#endif
2823
2914
2824
2915
/*
2825
2916
* On non-powermacs, put all CPUs in spin-loops.
2826
2917
*
2827
2918
* PowerMacs use a different mechanism to spin CPUs
2828
2919
*/
2829
- if (RELOC (of_platform ) != PLATFORM_POWERMAC )
2920
+ if (RELOC (of_platform ) != PLATFORM_POWERMAC &&
2921
+ RELOC (of_platform ) != PLATFORM_OPAL )
2830
2922
prom_hold_cpus ();
2831
2923
2832
2924
/*
@@ -2894,7 +2986,13 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2894
2986
reloc_got2 (- offset );
2895
2987
#endif
2896
2988
2897
- __start (hdr , kbase , 0 );
2989
+ #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
2990
+ /* OPAL early debug gets the OPAL base & entry in r8 and r9 */
2991
+ __start (hdr , kbase , 0 , 0 , 0 ,
2992
+ RELOC (prom_opal_base ), RELOC (prom_opal_entry ));
2993
+ #else
2994
+ __start (hdr , kbase , 0 , 0 , 0 , 0 , 0 );
2995
+ #endif
2898
2996
2899
2997
return 0 ;
2900
2998
}
0 commit comments