diff options
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 269 |
1 files changed, 163 insertions, 106 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 607902424e73..7b6391b68fb8 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -107,10 +107,10 @@ int of_workarounds; | |||
107 | typedef u32 prom_arg_t; | 107 | typedef u32 prom_arg_t; |
108 | 108 | ||
109 | struct prom_args { | 109 | struct prom_args { |
110 | u32 service; | 110 | __be32 service; |
111 | u32 nargs; | 111 | __be32 nargs; |
112 | u32 nret; | 112 | __be32 nret; |
113 | prom_arg_t args[10]; | 113 | __be32 args[10]; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct prom_t { | 116 | struct prom_t { |
@@ -123,11 +123,11 @@ struct prom_t { | |||
123 | }; | 123 | }; |
124 | 124 | ||
125 | struct mem_map_entry { | 125 | struct mem_map_entry { |
126 | u64 base; | 126 | __be64 base; |
127 | u64 size; | 127 | __be64 size; |
128 | }; | 128 | }; |
129 | 129 | ||
130 | typedef u32 cell_t; | 130 | typedef __be32 cell_t; |
131 | 131 | ||
132 | extern void __start(unsigned long r3, unsigned long r4, unsigned long r5, | 132 | extern void __start(unsigned long r3, unsigned long r4, unsigned long r5, |
133 | unsigned long r6, unsigned long r7, unsigned long r8, | 133 | unsigned long r6, unsigned long r7, unsigned long r8, |
@@ -219,13 +219,13 @@ static int __init call_prom(const char *service, int nargs, int nret, ...) | |||
219 | struct prom_args args; | 219 | struct prom_args args; |
220 | va_list list; | 220 | va_list list; |
221 | 221 | ||
222 | args.service = ADDR(service); | 222 | args.service = cpu_to_be32(ADDR(service)); |
223 | args.nargs = nargs; | 223 | args.nargs = cpu_to_be32(nargs); |
224 | args.nret = nret; | 224 | args.nret = cpu_to_be32(nret); |
225 | 225 | ||
226 | va_start(list, nret); | 226 | va_start(list, nret); |
227 | for (i = 0; i < nargs; i++) | 227 | for (i = 0; i < nargs; i++) |
228 | args.args[i] = va_arg(list, prom_arg_t); | 228 | args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t)); |
229 | va_end(list); | 229 | va_end(list); |
230 | 230 | ||
231 | for (i = 0; i < nret; i++) | 231 | for (i = 0; i < nret; i++) |
@@ -234,7 +234,7 @@ static int __init call_prom(const char *service, int nargs, int nret, ...) | |||
234 | if (enter_prom(&args, prom_entry) < 0) | 234 | if (enter_prom(&args, prom_entry) < 0) |
235 | return PROM_ERROR; | 235 | return PROM_ERROR; |
236 | 236 | ||
237 | return (nret > 0) ? args.args[nargs] : 0; | 237 | return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0; |
238 | } | 238 | } |
239 | 239 | ||
240 | static int __init call_prom_ret(const char *service, int nargs, int nret, | 240 | static int __init call_prom_ret(const char *service, int nargs, int nret, |
@@ -244,13 +244,13 @@ static int __init call_prom_ret(const char *service, int nargs, int nret, | |||
244 | struct prom_args args; | 244 | struct prom_args args; |
245 | va_list list; | 245 | va_list list; |
246 | 246 | ||
247 | args.service = ADDR(service); | 247 | args.service = cpu_to_be32(ADDR(service)); |
248 | args.nargs = nargs; | 248 | args.nargs = cpu_to_be32(nargs); |
249 | args.nret = nret; | 249 | args.nret = cpu_to_be32(nret); |
250 | 250 | ||
251 | va_start(list, rets); | 251 | va_start(list, rets); |
252 | for (i = 0; i < nargs; i++) | 252 | for (i = 0; i < nargs; i++) |
253 | args.args[i] = va_arg(list, prom_arg_t); | 253 | args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t)); |
254 | va_end(list); | 254 | va_end(list); |
255 | 255 | ||
256 | for (i = 0; i < nret; i++) | 256 | for (i = 0; i < nret; i++) |
@@ -261,9 +261,9 @@ static int __init call_prom_ret(const char *service, int nargs, int nret, | |||
261 | 261 | ||
262 | if (rets != NULL) | 262 | if (rets != NULL) |
263 | for (i = 1; i < nret; ++i) | 263 | for (i = 1; i < nret; ++i) |
264 | rets[i-1] = args.args[nargs+i]; | 264 | rets[i-1] = be32_to_cpu(args.args[nargs+i]); |
265 | 265 | ||
266 | return (nret > 0) ? args.args[nargs] : 0; | 266 | return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0; |
267 | } | 267 | } |
268 | 268 | ||
269 | 269 | ||
@@ -527,7 +527,7 @@ static int __init prom_setprop(phandle node, const char *nodename, | |||
527 | #define islower(c) ('a' <= (c) && (c) <= 'z') | 527 | #define islower(c) ('a' <= (c) && (c) <= 'z') |
528 | #define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c)) | 528 | #define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c)) |
529 | 529 | ||
530 | unsigned long prom_strtoul(const char *cp, const char **endp) | 530 | static unsigned long prom_strtoul(const char *cp, const char **endp) |
531 | { | 531 | { |
532 | unsigned long result = 0, base = 10, value; | 532 | unsigned long result = 0, base = 10, value; |
533 | 533 | ||
@@ -552,7 +552,7 @@ unsigned long prom_strtoul(const char *cp, const char **endp) | |||
552 | return result; | 552 | return result; |
553 | } | 553 | } |
554 | 554 | ||
555 | unsigned long prom_memparse(const char *ptr, const char **retptr) | 555 | static unsigned long prom_memparse(const char *ptr, const char **retptr) |
556 | { | 556 | { |
557 | unsigned long ret = prom_strtoul(ptr, retptr); | 557 | unsigned long ret = prom_strtoul(ptr, retptr); |
558 | int shift = 0; | 558 | int shift = 0; |
@@ -724,7 +724,8 @@ unsigned char ibm_architecture_vec[] = { | |||
724 | 724 | ||
725 | }; | 725 | }; |
726 | 726 | ||
727 | /* Old method - ELF header with PT_NOTE sections */ | 727 | /* Old method - ELF header with PT_NOTE sections only works on BE */ |
728 | #ifdef __BIG_ENDIAN__ | ||
728 | static struct fake_elf { | 729 | static struct fake_elf { |
729 | Elf32_Ehdr elfhdr; | 730 | Elf32_Ehdr elfhdr; |
730 | Elf32_Phdr phdr[2]; | 731 | Elf32_Phdr phdr[2]; |
@@ -810,6 +811,7 @@ static struct fake_elf { | |||
810 | } | 811 | } |
811 | } | 812 | } |
812 | }; | 813 | }; |
814 | #endif /* __BIG_ENDIAN__ */ | ||
813 | 815 | ||
814 | static int __init prom_count_smt_threads(void) | 816 | static int __init prom_count_smt_threads(void) |
815 | { | 817 | { |
@@ -852,9 +854,9 @@ static int __init prom_count_smt_threads(void) | |||
852 | 854 | ||
853 | static void __init prom_send_capabilities(void) | 855 | static void __init prom_send_capabilities(void) |
854 | { | 856 | { |
855 | ihandle elfloader, root; | 857 | ihandle root; |
856 | prom_arg_t ret; | 858 | prom_arg_t ret; |
857 | u32 *cores; | 859 | __be32 *cores; |
858 | 860 | ||
859 | root = call_prom("open", 1, 1, ADDR("/")); | 861 | root = call_prom("open", 1, 1, ADDR("/")); |
860 | if (root != 0) { | 862 | if (root != 0) { |
@@ -864,15 +866,15 @@ static void __init prom_send_capabilities(void) | |||
864 | * (we assume this is the same for all cores) and use it to | 866 | * (we assume this is the same for all cores) and use it to |
865 | * divide NR_CPUS. | 867 | * divide NR_CPUS. |
866 | */ | 868 | */ |
867 | cores = (u32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]; | 869 | cores = (__be32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]; |
868 | if (*cores != NR_CPUS) { | 870 | if (be32_to_cpup(cores) != NR_CPUS) { |
869 | prom_printf("WARNING ! " | 871 | prom_printf("WARNING ! " |
870 | "ibm_architecture_vec structure inconsistent: %lu!\n", | 872 | "ibm_architecture_vec structure inconsistent: %lu!\n", |
871 | *cores); | 873 | be32_to_cpup(cores)); |
872 | } else { | 874 | } else { |
873 | *cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()); | 875 | *cores = cpu_to_be32(DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads())); |
874 | prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n", | 876 | prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n", |
875 | *cores, NR_CPUS); | 877 | be32_to_cpup(cores), NR_CPUS); |
876 | } | 878 | } |
877 | 879 | ||
878 | /* try calling the ibm,client-architecture-support method */ | 880 | /* try calling the ibm,client-architecture-support method */ |
@@ -893,17 +895,24 @@ static void __init prom_send_capabilities(void) | |||
893 | prom_printf(" not implemented\n"); | 895 | prom_printf(" not implemented\n"); |
894 | } | 896 | } |
895 | 897 | ||
896 | /* no ibm,client-architecture-support call, try the old way */ | 898 | #ifdef __BIG_ENDIAN__ |
897 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); | 899 | { |
898 | if (elfloader == 0) { | 900 | ihandle elfloader; |
899 | prom_printf("couldn't open /packages/elf-loader\n"); | 901 | |
900 | return; | 902 | /* no ibm,client-architecture-support call, try the old way */ |
903 | elfloader = call_prom("open", 1, 1, | ||
904 | ADDR("/packages/elf-loader")); | ||
905 | if (elfloader == 0) { | ||
906 | prom_printf("couldn't open /packages/elf-loader\n"); | ||
907 | return; | ||
908 | } | ||
909 | call_prom("call-method", 3, 1, ADDR("process-elf-header"), | ||
910 | elfloader, ADDR(&fake_elf)); | ||
911 | call_prom("close", 1, 0, elfloader); | ||
901 | } | 912 | } |
902 | call_prom("call-method", 3, 1, ADDR("process-elf-header"), | 913 | #endif /* __BIG_ENDIAN__ */ |
903 | elfloader, ADDR(&fake_elf)); | ||
904 | call_prom("close", 1, 0, elfloader); | ||
905 | } | 914 | } |
906 | #endif | 915 | #endif /* #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */ |
907 | 916 | ||
908 | /* | 917 | /* |
909 | * Memory allocation strategy... our layout is normally: | 918 | * Memory allocation strategy... our layout is normally: |
@@ -1050,11 +1059,11 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp) | |||
1050 | p++; | 1059 | p++; |
1051 | s--; | 1060 | s--; |
1052 | } | 1061 | } |
1053 | r = *p++; | 1062 | r = be32_to_cpu(*p++); |
1054 | #ifdef CONFIG_PPC64 | 1063 | #ifdef CONFIG_PPC64 |
1055 | if (s > 1) { | 1064 | if (s > 1) { |
1056 | r <<= 32; | 1065 | r <<= 32; |
1057 | r |= *(p++); | 1066 | r |= be32_to_cpu(*(p++)); |
1058 | } | 1067 | } |
1059 | #endif | 1068 | #endif |
1060 | *cellp = p; | 1069 | *cellp = p; |
@@ -1087,8 +1096,8 @@ static void __init reserve_mem(u64 base, u64 size) | |||
1087 | 1096 | ||
1088 | if (cnt >= (MEM_RESERVE_MAP_SIZE - 1)) | 1097 | if (cnt >= (MEM_RESERVE_MAP_SIZE - 1)) |
1089 | prom_panic("Memory reserve map exhausted !\n"); | 1098 | prom_panic("Memory reserve map exhausted !\n"); |
1090 | mem_reserve_map[cnt].base = base; | 1099 | mem_reserve_map[cnt].base = cpu_to_be64(base); |
1091 | mem_reserve_map[cnt].size = size; | 1100 | mem_reserve_map[cnt].size = cpu_to_be64(size); |
1092 | mem_reserve_cnt = cnt + 1; | 1101 | mem_reserve_cnt = cnt + 1; |
1093 | } | 1102 | } |
1094 | 1103 | ||
@@ -1102,6 +1111,7 @@ static void __init prom_init_mem(void) | |||
1102 | char *path, type[64]; | 1111 | char *path, type[64]; |
1103 | unsigned int plen; | 1112 | unsigned int plen; |
1104 | cell_t *p, *endp; | 1113 | cell_t *p, *endp; |
1114 | __be32 val; | ||
1105 | u32 rac, rsc; | 1115 | u32 rac, rsc; |
1106 | 1116 | ||
1107 | /* | 1117 | /* |
@@ -1109,12 +1119,14 @@ static void __init prom_init_mem(void) | |||
1109 | * 1) top of RMO (first node) | 1119 | * 1) top of RMO (first node) |
1110 | * 2) top of memory | 1120 | * 2) top of memory |
1111 | */ | 1121 | */ |
1112 | rac = 2; | 1122 | val = cpu_to_be32(2); |
1113 | prom_getprop(prom.root, "#address-cells", &rac, sizeof(rac)); | 1123 | prom_getprop(prom.root, "#address-cells", &val, sizeof(val)); |
1114 | rsc = 1; | 1124 | rac = be32_to_cpu(val); |
1115 | prom_getprop(prom.root, "#size-cells", &rsc, sizeof(rsc)); | 1125 | val = cpu_to_be32(1); |
1116 | prom_debug("root_addr_cells: %x\n", (unsigned long) rac); | 1126 | prom_getprop(prom.root, "#size-cells", &val, sizeof(rsc)); |
1117 | prom_debug("root_size_cells: %x\n", (unsigned long) rsc); | 1127 | rsc = be32_to_cpu(val); |
1128 | prom_debug("root_addr_cells: %x\n", rac); | ||
1129 | prom_debug("root_size_cells: %x\n", rsc); | ||
1118 | 1130 | ||
1119 | prom_debug("scanning memory:\n"); | 1131 | prom_debug("scanning memory:\n"); |
1120 | path = prom_scratch; | 1132 | path = prom_scratch; |
@@ -1222,25 +1234,23 @@ static void __init prom_init_mem(void) | |||
1222 | 1234 | ||
1223 | static void __init prom_close_stdin(void) | 1235 | static void __init prom_close_stdin(void) |
1224 | { | 1236 | { |
1225 | ihandle val; | 1237 | __be32 val; |
1238 | ihandle stdin; | ||
1226 | 1239 | ||
1227 | if (prom_getprop(prom.chosen, "stdin", &val, sizeof(val)) > 0) | 1240 | if (prom_getprop(prom.chosen, "stdin", &val, sizeof(val)) > 0) { |
1228 | call_prom("close", 1, 0, val); | 1241 | stdin = be32_to_cpu(val); |
1242 | call_prom("close", 1, 0, stdin); | ||
1243 | } | ||
1229 | } | 1244 | } |
1230 | 1245 | ||
1231 | #ifdef CONFIG_PPC_POWERNV | 1246 | #ifdef CONFIG_PPC_POWERNV |
1232 | 1247 | ||
1233 | static u64 __initdata prom_opal_size; | ||
1234 | static u64 __initdata prom_opal_align; | ||
1235 | static int __initdata prom_rtas_start_cpu; | ||
1236 | static u64 __initdata prom_rtas_data; | ||
1237 | static u64 __initdata prom_rtas_entry; | ||
1238 | |||
1239 | #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL | 1248 | #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL |
1240 | static u64 __initdata prom_opal_base; | 1249 | static u64 __initdata prom_opal_base; |
1241 | static u64 __initdata prom_opal_entry; | 1250 | static u64 __initdata prom_opal_entry; |
1242 | #endif | 1251 | #endif |
1243 | 1252 | ||
1253 | #ifdef __BIG_ENDIAN__ | ||
1244 | /* XXX Don't change this structure without updating opal-takeover.S */ | 1254 | /* XXX Don't change this structure without updating opal-takeover.S */ |
1245 | static struct opal_secondary_data { | 1255 | static struct opal_secondary_data { |
1246 | s64 ack; /* 0 */ | 1256 | s64 ack; /* 0 */ |
@@ -1248,6 +1258,12 @@ static struct opal_secondary_data { | |||
1248 | struct opal_takeover_args args; /* 16 */ | 1258 | struct opal_takeover_args args; /* 16 */ |
1249 | } opal_secondary_data; | 1259 | } opal_secondary_data; |
1250 | 1260 | ||
1261 | static u64 __initdata prom_opal_align; | ||
1262 | static u64 __initdata prom_opal_size; | ||
1263 | static int __initdata prom_rtas_start_cpu; | ||
1264 | static u64 __initdata prom_rtas_data; | ||
1265 | static u64 __initdata prom_rtas_entry; | ||
1266 | |||
1251 | extern char opal_secondary_entry; | 1267 | extern char opal_secondary_entry; |
1252 | 1268 | ||
1253 | static void __init prom_query_opal(void) | 1269 | static void __init prom_query_opal(void) |
@@ -1265,6 +1281,7 @@ static void __init prom_query_opal(void) | |||
1265 | } | 1281 | } |
1266 | 1282 | ||
1267 | prom_printf("Querying for OPAL presence... "); | 1283 | prom_printf("Querying for OPAL presence... "); |
1284 | |||
1268 | rc = opal_query_takeover(&prom_opal_size, | 1285 | rc = opal_query_takeover(&prom_opal_size, |
1269 | &prom_opal_align); | 1286 | &prom_opal_align); |
1270 | prom_debug("(rc = %ld) ", rc); | 1287 | prom_debug("(rc = %ld) ", rc); |
@@ -1425,6 +1442,7 @@ static void __init prom_opal_takeover(void) | |||
1425 | for (;;) | 1442 | for (;;) |
1426 | opal_do_takeover(args); | 1443 | opal_do_takeover(args); |
1427 | } | 1444 | } |
1445 | #endif /* __BIG_ENDIAN__ */ | ||
1428 | 1446 | ||
1429 | /* | 1447 | /* |
1430 | * Allocate room for and instantiate OPAL | 1448 | * Allocate room for and instantiate OPAL |
@@ -1435,6 +1453,7 @@ static void __init prom_instantiate_opal(void) | |||
1435 | ihandle opal_inst; | 1453 | ihandle opal_inst; |
1436 | u64 base, entry; | 1454 | u64 base, entry; |
1437 | u64 size = 0, align = 0x10000; | 1455 | u64 size = 0, align = 0x10000; |
1456 | __be64 val64; | ||
1438 | u32 rets[2]; | 1457 | u32 rets[2]; |
1439 | 1458 | ||
1440 | prom_debug("prom_instantiate_opal: start...\n"); | 1459 | prom_debug("prom_instantiate_opal: start...\n"); |
@@ -1444,11 +1463,14 @@ static void __init prom_instantiate_opal(void) | |||
1444 | if (!PHANDLE_VALID(opal_node)) | 1463 | if (!PHANDLE_VALID(opal_node)) |
1445 | return; | 1464 | return; |
1446 | 1465 | ||
1447 | prom_getprop(opal_node, "opal-runtime-size", &size, sizeof(size)); | 1466 | val64 = 0; |
1467 | prom_getprop(opal_node, "opal-runtime-size", &val64, sizeof(val64)); | ||
1468 | size = be64_to_cpu(val64); | ||
1448 | if (size == 0) | 1469 | if (size == 0) |
1449 | return; | 1470 | return; |
1450 | prom_getprop(opal_node, "opal-runtime-alignment", &align, | 1471 | val64 = 0; |
1451 | sizeof(align)); | 1472 | prom_getprop(opal_node, "opal-runtime-alignment", &val64,sizeof(val64)); |
1473 | align = be64_to_cpu(val64); | ||
1452 | 1474 | ||
1453 | base = alloc_down(size, align, 0); | 1475 | base = alloc_down(size, align, 0); |
1454 | if (base == 0) { | 1476 | if (base == 0) { |
@@ -1505,6 +1527,7 @@ static void __init prom_instantiate_rtas(void) | |||
1505 | phandle rtas_node; | 1527 | phandle rtas_node; |
1506 | ihandle rtas_inst; | 1528 | ihandle rtas_inst; |
1507 | u32 base, entry = 0; | 1529 | u32 base, entry = 0; |
1530 | __be32 val; | ||
1508 | u32 size = 0; | 1531 | u32 size = 0; |
1509 | 1532 | ||
1510 | prom_debug("prom_instantiate_rtas: start...\n"); | 1533 | prom_debug("prom_instantiate_rtas: start...\n"); |
@@ -1514,7 +1537,9 @@ static void __init prom_instantiate_rtas(void) | |||
1514 | if (!PHANDLE_VALID(rtas_node)) | 1537 | if (!PHANDLE_VALID(rtas_node)) |
1515 | return; | 1538 | return; |
1516 | 1539 | ||
1517 | prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); | 1540 | val = 0; |
1541 | prom_getprop(rtas_node, "rtas-size", &val, sizeof(size)); | ||
1542 | size = be32_to_cpu(val); | ||
1518 | if (size == 0) | 1543 | if (size == 0) |
1519 | return; | 1544 | return; |
1520 | 1545 | ||
@@ -1541,12 +1566,14 @@ static void __init prom_instantiate_rtas(void) | |||
1541 | 1566 | ||
1542 | reserve_mem(base, size); | 1567 | reserve_mem(base, size); |
1543 | 1568 | ||
1569 | val = cpu_to_be32(base); | ||
1544 | prom_setprop(rtas_node, "/rtas", "linux,rtas-base", | 1570 | prom_setprop(rtas_node, "/rtas", "linux,rtas-base", |
1545 | &base, sizeof(base)); | 1571 | &val, sizeof(val)); |
1572 | val = cpu_to_be32(entry); | ||
1546 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", | 1573 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", |
1547 | &entry, sizeof(entry)); | 1574 | &val, sizeof(val)); |
1548 | 1575 | ||
1549 | #ifdef CONFIG_PPC_POWERNV | 1576 | #if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__) |
1550 | /* PowerVN takeover hack */ | 1577 | /* PowerVN takeover hack */ |
1551 | prom_rtas_data = base; | 1578 | prom_rtas_data = base; |
1552 | prom_rtas_entry = entry; | 1579 | prom_rtas_entry = entry; |
@@ -1620,6 +1647,7 @@ static void __init prom_instantiate_sml(void) | |||
1620 | /* | 1647 | /* |
1621 | * Allocate room for and initialize TCE tables | 1648 | * Allocate room for and initialize TCE tables |
1622 | */ | 1649 | */ |
1650 | #ifdef __BIG_ENDIAN__ | ||
1623 | static void __init prom_initialize_tce_table(void) | 1651 | static void __init prom_initialize_tce_table(void) |
1624 | { | 1652 | { |
1625 | phandle node; | 1653 | phandle node; |
@@ -1748,7 +1776,8 @@ static void __init prom_initialize_tce_table(void) | |||
1748 | /* Flag the first invalid entry */ | 1776 | /* Flag the first invalid entry */ |
1749 | prom_debug("ending prom_initialize_tce_table\n"); | 1777 | prom_debug("ending prom_initialize_tce_table\n"); |
1750 | } | 1778 | } |
1751 | #endif | 1779 | #endif /* __BIG_ENDIAN__ */ |
1780 | #endif /* CONFIG_PPC64 */ | ||
1752 | 1781 | ||
1753 | /* | 1782 | /* |
1754 | * With CHRP SMP we need to use the OF to start the other processors. | 1783 | * With CHRP SMP we need to use the OF to start the other processors. |
@@ -1777,7 +1806,6 @@ static void __init prom_initialize_tce_table(void) | |||
1777 | static void __init prom_hold_cpus(void) | 1806 | static void __init prom_hold_cpus(void) |
1778 | { | 1807 | { |
1779 | unsigned long i; | 1808 | unsigned long i; |
1780 | unsigned int reg; | ||
1781 | phandle node; | 1809 | phandle node; |
1782 | char type[64]; | 1810 | char type[64]; |
1783 | unsigned long *spinloop | 1811 | unsigned long *spinloop |
@@ -1803,6 +1831,9 @@ static void __init prom_hold_cpus(void) | |||
1803 | 1831 | ||
1804 | /* look for cpus */ | 1832 | /* look for cpus */ |
1805 | for (node = 0; prom_next_node(&node); ) { | 1833 | for (node = 0; prom_next_node(&node); ) { |
1834 | unsigned int cpu_no; | ||
1835 | __be32 reg; | ||
1836 | |||
1806 | type[0] = 0; | 1837 | type[0] = 0; |
1807 | prom_getprop(node, "device_type", type, sizeof(type)); | 1838 | prom_getprop(node, "device_type", type, sizeof(type)); |
1808 | if (strcmp(type, "cpu") != 0) | 1839 | if (strcmp(type, "cpu") != 0) |
@@ -1813,10 +1844,11 @@ static void __init prom_hold_cpus(void) | |||
1813 | if (strcmp(type, "okay") != 0) | 1844 | if (strcmp(type, "okay") != 0) |
1814 | continue; | 1845 | continue; |
1815 | 1846 | ||
1816 | reg = -1; | 1847 | reg = cpu_to_be32(-1); /* make sparse happy */ |
1817 | prom_getprop(node, "reg", ®, sizeof(reg)); | 1848 | prom_getprop(node, "reg", ®, sizeof(reg)); |
1849 | cpu_no = be32_to_cpu(reg); | ||
1818 | 1850 | ||
1819 | prom_debug("cpu hw idx = %lu\n", reg); | 1851 | prom_debug("cpu hw idx = %lu\n", cpu_no); |
1820 | 1852 | ||
1821 | /* Init the acknowledge var which will be reset by | 1853 | /* Init the acknowledge var which will be reset by |
1822 | * the secondary cpu when it awakens from its OF | 1854 | * the secondary cpu when it awakens from its OF |
@@ -1824,24 +1856,24 @@ static void __init prom_hold_cpus(void) | |||
1824 | */ | 1856 | */ |
1825 | *acknowledge = (unsigned long)-1; | 1857 | *acknowledge = (unsigned long)-1; |
1826 | 1858 | ||
1827 | if (reg != prom.cpu) { | 1859 | if (cpu_no != prom.cpu) { |
1828 | /* Primary Thread of non-boot cpu or any thread */ | 1860 | /* Primary Thread of non-boot cpu or any thread */ |
1829 | prom_printf("starting cpu hw idx %lu... ", reg); | 1861 | prom_printf("starting cpu hw idx %lu... ", cpu_no); |
1830 | call_prom("start-cpu", 3, 0, node, | 1862 | call_prom("start-cpu", 3, 0, node, |
1831 | secondary_hold, reg); | 1863 | secondary_hold, cpu_no); |
1832 | 1864 | ||
1833 | for (i = 0; (i < 100000000) && | 1865 | for (i = 0; (i < 100000000) && |
1834 | (*acknowledge == ((unsigned long)-1)); i++ ) | 1866 | (*acknowledge == ((unsigned long)-1)); i++ ) |
1835 | mb(); | 1867 | mb(); |
1836 | 1868 | ||
1837 | if (*acknowledge == reg) | 1869 | if (*acknowledge == cpu_no) |
1838 | prom_printf("done\n"); | 1870 | prom_printf("done\n"); |
1839 | else | 1871 | else |
1840 | prom_printf("failed: %x\n", *acknowledge); | 1872 | prom_printf("failed: %x\n", *acknowledge); |
1841 | } | 1873 | } |
1842 | #ifdef CONFIG_SMP | 1874 | #ifdef CONFIG_SMP |
1843 | else | 1875 | else |
1844 | prom_printf("boot cpu hw idx %lu\n", reg); | 1876 | prom_printf("boot cpu hw idx %lu\n", cpu_no); |
1845 | #endif /* CONFIG_SMP */ | 1877 | #endif /* CONFIG_SMP */ |
1846 | } | 1878 | } |
1847 | 1879 | ||
@@ -1895,6 +1927,7 @@ static void __init prom_find_mmu(void) | |||
1895 | prom.memory = call_prom("open", 1, 1, ADDR("/memory")); | 1927 | prom.memory = call_prom("open", 1, 1, ADDR("/memory")); |
1896 | prom_getprop(prom.chosen, "mmu", &prom.mmumap, | 1928 | prom_getprop(prom.chosen, "mmu", &prom.mmumap, |
1897 | sizeof(prom.mmumap)); | 1929 | sizeof(prom.mmumap)); |
1930 | prom.mmumap = be32_to_cpu(prom.mmumap); | ||
1898 | if (!IHANDLE_VALID(prom.memory) || !IHANDLE_VALID(prom.mmumap)) | 1931 | if (!IHANDLE_VALID(prom.memory) || !IHANDLE_VALID(prom.mmumap)) |
1899 | of_workarounds &= ~OF_WA_CLAIM; /* hmmm */ | 1932 | of_workarounds &= ~OF_WA_CLAIM; /* hmmm */ |
1900 | } | 1933 | } |
@@ -1906,17 +1939,19 @@ static void __init prom_init_stdout(void) | |||
1906 | { | 1939 | { |
1907 | char *path = of_stdout_device; | 1940 | char *path = of_stdout_device; |
1908 | char type[16]; | 1941 | char type[16]; |
1909 | u32 val; | 1942 | phandle stdout_node; |
1943 | __be32 val; | ||
1910 | 1944 | ||
1911 | if (prom_getprop(prom.chosen, "stdout", &val, sizeof(val)) <= 0) | 1945 | if (prom_getprop(prom.chosen, "stdout", &val, sizeof(val)) <= 0) |
1912 | prom_panic("cannot find stdout"); | 1946 | prom_panic("cannot find stdout"); |
1913 | 1947 | ||
1914 | prom.stdout = val; | 1948 | prom.stdout = be32_to_cpu(val); |
1915 | 1949 | ||
1916 | /* Get the full OF pathname of the stdout device */ | 1950 | /* Get the full OF pathname of the stdout device */ |
1917 | memset(path, 0, 256); | 1951 | memset(path, 0, 256); |
1918 | call_prom("instance-to-path", 3, 1, prom.stdout, path, 255); | 1952 | call_prom("instance-to-path", 3, 1, prom.stdout, path, 255); |
1919 | val = call_prom("instance-to-package", 1, 1, prom.stdout); | 1953 | stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout); |
1954 | val = cpu_to_be32(stdout_node); | ||
1920 | prom_setprop(prom.chosen, "/chosen", "linux,stdout-package", | 1955 | prom_setprop(prom.chosen, "/chosen", "linux,stdout-package", |
1921 | &val, sizeof(val)); | 1956 | &val, sizeof(val)); |
1922 | prom_printf("OF stdout device is: %s\n", of_stdout_device); | 1957 | prom_printf("OF stdout device is: %s\n", of_stdout_device); |
@@ -1925,9 +1960,9 @@ static void __init prom_init_stdout(void) | |||
1925 | 1960 | ||
1926 | /* If it's a display, note it */ | 1961 | /* If it's a display, note it */ |
1927 | memset(type, 0, sizeof(type)); | 1962 | memset(type, 0, sizeof(type)); |
1928 | prom_getprop(val, "device_type", type, sizeof(type)); | 1963 | prom_getprop(stdout_node, "device_type", type, sizeof(type)); |
1929 | if (strcmp(type, "display") == 0) | 1964 | if (strcmp(type, "display") == 0) |
1930 | prom_setprop(val, path, "linux,boot-display", NULL, 0); | 1965 | prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0); |
1931 | } | 1966 | } |
1932 | 1967 | ||
1933 | static int __init prom_find_machine_type(void) | 1968 | static int __init prom_find_machine_type(void) |
@@ -2082,6 +2117,22 @@ static void __init prom_check_displays(void) | |||
2082 | clut[2]) != 0) | 2117 | clut[2]) != 0) |
2083 | break; | 2118 | break; |
2084 | #endif /* CONFIG_LOGO_LINUX_CLUT224 */ | 2119 | #endif /* CONFIG_LOGO_LINUX_CLUT224 */ |
2120 | |||
2121 | #ifdef CONFIG_PPC_EARLY_DEBUG_BOOTX | ||
2122 | if (prom_getprop(node, "linux,boot-display", NULL, 0) != | ||
2123 | PROM_ERROR) { | ||
2124 | u32 width, height, pitch, addr; | ||
2125 | |||
2126 | prom_printf("Setting btext !\n"); | ||
2127 | prom_getprop(node, "width", &width, 4); | ||
2128 | prom_getprop(node, "height", &height, 4); | ||
2129 | prom_getprop(node, "linebytes", &pitch, 4); | ||
2130 | prom_getprop(node, "address", &addr, 4); | ||
2131 | prom_printf("W=%d H=%d LB=%d addr=0x%x\n", | ||
2132 | width, height, pitch, addr); | ||
2133 | btext_setup_display(width, height, 8, pitch, addr); | ||
2134 | } | ||
2135 | #endif /* CONFIG_PPC_EARLY_DEBUG_BOOTX */ | ||
2085 | } | 2136 | } |
2086 | } | 2137 | } |
2087 | 2138 | ||
@@ -2117,8 +2168,10 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, | |||
2117 | return ret; | 2168 | return ret; |
2118 | } | 2169 | } |
2119 | 2170 | ||
2120 | #define dt_push_token(token, mem_start, mem_end) \ | 2171 | #define dt_push_token(token, mem_start, mem_end) do { \ |
2121 | do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0) | 2172 | void *room = make_room(mem_start, mem_end, 4, 4); \ |
2173 | *(__be32 *)room = cpu_to_be32(token); \ | ||
2174 | } while(0) | ||
2122 | 2175 | ||
2123 | static unsigned long __init dt_find_string(char *str) | 2176 | static unsigned long __init dt_find_string(char *str) |
2124 | { | 2177 | { |
@@ -2291,7 +2344,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
2291 | dt_push_token(4, mem_start, mem_end); | 2344 | dt_push_token(4, mem_start, mem_end); |
2292 | dt_push_token(soff, mem_start, mem_end); | 2345 | dt_push_token(soff, mem_start, mem_end); |
2293 | valp = make_room(mem_start, mem_end, 4, 4); | 2346 | valp = make_room(mem_start, mem_end, 4, 4); |
2294 | *(u32 *)valp = node; | 2347 | *(__be32 *)valp = cpu_to_be32(node); |
2295 | } | 2348 | } |
2296 | } | 2349 | } |
2297 | 2350 | ||
@@ -2364,16 +2417,16 @@ static void __init flatten_device_tree(void) | |||
2364 | dt_struct_end = PAGE_ALIGN(mem_start); | 2417 | dt_struct_end = PAGE_ALIGN(mem_start); |
2365 | 2418 | ||
2366 | /* Finish header */ | 2419 | /* Finish header */ |
2367 | hdr->boot_cpuid_phys = prom.cpu; | 2420 | hdr->boot_cpuid_phys = cpu_to_be32(prom.cpu); |
2368 | hdr->magic = OF_DT_HEADER; | 2421 | hdr->magic = cpu_to_be32(OF_DT_HEADER); |
2369 | hdr->totalsize = dt_struct_end - dt_header_start; | 2422 | hdr->totalsize = cpu_to_be32(dt_struct_end - dt_header_start); |
2370 | hdr->off_dt_struct = dt_struct_start - dt_header_start; | 2423 | hdr->off_dt_struct = cpu_to_be32(dt_struct_start - dt_header_start); |
2371 | hdr->off_dt_strings = dt_string_start - dt_header_start; | 2424 | hdr->off_dt_strings = cpu_to_be32(dt_string_start - dt_header_start); |
2372 | hdr->dt_strings_size = dt_string_end - dt_string_start; | 2425 | hdr->dt_strings_size = cpu_to_be32(dt_string_end - dt_string_start); |
2373 | hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - dt_header_start; | 2426 | hdr->off_mem_rsvmap = cpu_to_be32(((unsigned long)rsvmap) - dt_header_start); |
2374 | hdr->version = OF_DT_VERSION; | 2427 | hdr->version = cpu_to_be32(OF_DT_VERSION); |
2375 | /* Version 16 is not backward compatible */ | 2428 | /* Version 16 is not backward compatible */ |
2376 | hdr->last_comp_version = 0x10; | 2429 | hdr->last_comp_version = cpu_to_be32(0x10); |
2377 | 2430 | ||
2378 | /* Copy the reserve map in */ | 2431 | /* Copy the reserve map in */ |
2379 | memcpy(rsvmap, mem_reserve_map, sizeof(mem_reserve_map)); | 2432 | memcpy(rsvmap, mem_reserve_map, sizeof(mem_reserve_map)); |
@@ -2384,8 +2437,8 @@ static void __init flatten_device_tree(void) | |||
2384 | prom_printf("reserved memory map:\n"); | 2437 | prom_printf("reserved memory map:\n"); |
2385 | for (i = 0; i < mem_reserve_cnt; i++) | 2438 | for (i = 0; i < mem_reserve_cnt; i++) |
2386 | prom_printf(" %x - %x\n", | 2439 | prom_printf(" %x - %x\n", |
2387 | mem_reserve_map[i].base, | 2440 | be64_to_cpu(mem_reserve_map[i].base), |
2388 | mem_reserve_map[i].size); | 2441 | be64_to_cpu(mem_reserve_map[i].size)); |
2389 | } | 2442 | } |
2390 | #endif | 2443 | #endif |
2391 | /* Bump mem_reserve_cnt to cause further reservations to fail | 2444 | /* Bump mem_reserve_cnt to cause further reservations to fail |
@@ -2397,7 +2450,6 @@ static void __init flatten_device_tree(void) | |||
2397 | dt_string_start, dt_string_end); | 2450 | dt_string_start, dt_string_end); |
2398 | prom_printf("Device tree struct 0x%x -> 0x%x\n", | 2451 | prom_printf("Device tree struct 0x%x -> 0x%x\n", |
2399 | dt_struct_start, dt_struct_end); | 2452 | dt_struct_start, dt_struct_end); |
2400 | |||
2401 | } | 2453 | } |
2402 | 2454 | ||
2403 | #ifdef CONFIG_PPC_MAPLE | 2455 | #ifdef CONFIG_PPC_MAPLE |
@@ -2730,18 +2782,19 @@ static void __init fixup_device_tree(void) | |||
2730 | 2782 | ||
2731 | static void __init prom_find_boot_cpu(void) | 2783 | static void __init prom_find_boot_cpu(void) |
2732 | { | 2784 | { |
2733 | u32 getprop_rval; | 2785 | __be32 rval; |
2734 | ihandle prom_cpu; | 2786 | ihandle prom_cpu; |
2735 | phandle cpu_pkg; | 2787 | phandle cpu_pkg; |
2736 | 2788 | ||
2737 | prom.cpu = 0; | 2789 | rval = 0; |
2738 | if (prom_getprop(prom.chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0) | 2790 | if (prom_getprop(prom.chosen, "cpu", &rval, sizeof(rval)) <= 0) |
2739 | return; | 2791 | return; |
2792 | prom_cpu = be32_to_cpu(rval); | ||
2740 | 2793 | ||
2741 | cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu); | 2794 | cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu); |
2742 | 2795 | ||
2743 | prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval)); | 2796 | prom_getprop(cpu_pkg, "reg", &rval, sizeof(rval)); |
2744 | prom.cpu = getprop_rval; | 2797 | prom.cpu = be32_to_cpu(rval); |
2745 | 2798 | ||
2746 | prom_debug("Booting CPU hw index = %lu\n", prom.cpu); | 2799 | prom_debug("Booting CPU hw index = %lu\n", prom.cpu); |
2747 | } | 2800 | } |
@@ -2750,15 +2803,15 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4) | |||
2750 | { | 2803 | { |
2751 | #ifdef CONFIG_BLK_DEV_INITRD | 2804 | #ifdef CONFIG_BLK_DEV_INITRD |
2752 | if (r3 && r4 && r4 != 0xdeadbeef) { | 2805 | if (r3 && r4 && r4 != 0xdeadbeef) { |
2753 | unsigned long val; | 2806 | __be64 val; |
2754 | 2807 | ||
2755 | prom_initrd_start = is_kernel_addr(r3) ? __pa(r3) : r3; | 2808 | prom_initrd_start = is_kernel_addr(r3) ? __pa(r3) : r3; |
2756 | prom_initrd_end = prom_initrd_start + r4; | 2809 | prom_initrd_end = prom_initrd_start + r4; |
2757 | 2810 | ||
2758 | val = prom_initrd_start; | 2811 | val = cpu_to_be64(prom_initrd_start); |
2759 | prom_setprop(prom.chosen, "/chosen", "linux,initrd-start", | 2812 | prom_setprop(prom.chosen, "/chosen", "linux,initrd-start", |
2760 | &val, sizeof(val)); | 2813 | &val, sizeof(val)); |
2761 | val = prom_initrd_end; | 2814 | val = cpu_to_be64(prom_initrd_end); |
2762 | prom_setprop(prom.chosen, "/chosen", "linux,initrd-end", | 2815 | prom_setprop(prom.chosen, "/chosen", "linux,initrd-end", |
2763 | &val, sizeof(val)); | 2816 | &val, sizeof(val)); |
2764 | 2817 | ||
@@ -2915,7 +2968,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2915 | */ | 2968 | */ |
2916 | prom_check_displays(); | 2969 | prom_check_displays(); |
2917 | 2970 | ||
2918 | #ifdef CONFIG_PPC64 | 2971 | #if defined(CONFIG_PPC64) && defined(__BIG_ENDIAN__) |
2919 | /* | 2972 | /* |
2920 | * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else | 2973 | * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else |
2921 | * that uses the allocator, we need to make sure we get the top of memory | 2974 | * that uses the allocator, we need to make sure we get the top of memory |
@@ -2934,6 +2987,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2934 | prom_instantiate_rtas(); | 2987 | prom_instantiate_rtas(); |
2935 | 2988 | ||
2936 | #ifdef CONFIG_PPC_POWERNV | 2989 | #ifdef CONFIG_PPC_POWERNV |
2990 | #ifdef __BIG_ENDIAN__ | ||
2937 | /* Detect HAL and try instanciating it & doing takeover */ | 2991 | /* Detect HAL and try instanciating it & doing takeover */ |
2938 | if (of_platform == PLATFORM_PSERIES_LPAR) { | 2992 | if (of_platform == PLATFORM_PSERIES_LPAR) { |
2939 | prom_query_opal(); | 2993 | prom_query_opal(); |
@@ -2941,9 +2995,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2941 | prom_opal_hold_cpus(); | 2995 | prom_opal_hold_cpus(); |
2942 | prom_opal_takeover(); | 2996 | prom_opal_takeover(); |
2943 | } | 2997 | } |
2944 | } else if (of_platform == PLATFORM_OPAL) | 2998 | } else |
2999 | #endif /* __BIG_ENDIAN__ */ | ||
3000 | if (of_platform == PLATFORM_OPAL) | ||
2945 | prom_instantiate_opal(); | 3001 | prom_instantiate_opal(); |
2946 | #endif | 3002 | #endif /* CONFIG_PPC_POWERNV */ |
2947 | 3003 | ||
2948 | #ifdef CONFIG_PPC64 | 3004 | #ifdef CONFIG_PPC64 |
2949 | /* instantiate sml */ | 3005 | /* instantiate sml */ |
@@ -2962,10 +3018,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
2962 | /* | 3018 | /* |
2963 | * Fill in some infos for use by the kernel later on | 3019 | * Fill in some infos for use by the kernel later on |
2964 | */ | 3020 | */ |
2965 | if (prom_memory_limit) | 3021 | if (prom_memory_limit) { |
3022 | __be64 val = cpu_to_be64(prom_memory_limit); | ||
2966 | prom_setprop(prom.chosen, "/chosen", "linux,memory-limit", | 3023 | prom_setprop(prom.chosen, "/chosen", "linux,memory-limit", |
2967 | &prom_memory_limit, | 3024 | &val, sizeof(val)); |
2968 | sizeof(prom_memory_limit)); | 3025 | } |
2969 | #ifdef CONFIG_PPC64 | 3026 | #ifdef CONFIG_PPC64 |
2970 | if (prom_iommu_off) | 3027 | if (prom_iommu_off) |
2971 | prom_setprop(prom.chosen, "/chosen", "linux,iommu-off", | 3028 | prom_setprop(prom.chosen, "/chosen", "linux,iommu-off", |