diff options
Diffstat (limited to 'arch/ppc64/kernel/prom.c')
-rw-r--r-- | arch/ppc64/kernel/prom.c | 94 |
1 files changed, 33 insertions, 61 deletions
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 97bfceb5353b..dece31e58bc4 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -635,10 +635,10 @@ static inline char *find_flat_dt_string(u32 offset) | |||
635 | * used to extract the memory informations at boot before we can | 635 | * used to extract the memory informations at boot before we can |
636 | * unflatten the tree | 636 | * unflatten the tree |
637 | */ | 637 | */ |
638 | static int __init scan_flat_dt(int (*it)(unsigned long node, | 638 | int __init of_scan_flat_dt(int (*it)(unsigned long node, |
639 | const char *uname, int depth, | 639 | const char *uname, int depth, |
640 | void *data), | 640 | void *data), |
641 | void *data) | 641 | void *data) |
642 | { | 642 | { |
643 | unsigned long p = ((unsigned long)initial_boot_params) + | 643 | unsigned long p = ((unsigned long)initial_boot_params) + |
644 | initial_boot_params->off_dt_struct; | 644 | initial_boot_params->off_dt_struct; |
@@ -695,8 +695,8 @@ static int __init scan_flat_dt(int (*it)(unsigned long node, | |||
695 | * This function can be used within scan_flattened_dt callback to get | 695 | * This function can be used within scan_flattened_dt callback to get |
696 | * access to properties | 696 | * access to properties |
697 | */ | 697 | */ |
698 | static void* __init get_flat_dt_prop(unsigned long node, const char *name, | 698 | void* __init of_get_flat_dt_prop(unsigned long node, const char *name, |
699 | unsigned long *size) | 699 | unsigned long *size) |
700 | { | 700 | { |
701 | unsigned long p = node; | 701 | unsigned long p = node; |
702 | 702 | ||
@@ -996,7 +996,7 @@ void __init unflatten_device_tree(void) | |||
996 | static int __init early_init_dt_scan_cpus(unsigned long node, | 996 | static int __init early_init_dt_scan_cpus(unsigned long node, |
997 | const char *uname, int depth, void *data) | 997 | const char *uname, int depth, void *data) |
998 | { | 998 | { |
999 | char *type = get_flat_dt_prop(node, "device_type", NULL); | 999 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
1000 | u32 *prop; | 1000 | u32 *prop; |
1001 | unsigned long size; | 1001 | unsigned long size; |
1002 | 1002 | ||
@@ -1004,17 +1004,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
1004 | if (type == NULL || strcmp(type, "cpu") != 0) | 1004 | if (type == NULL || strcmp(type, "cpu") != 0) |
1005 | return 0; | 1005 | return 0; |
1006 | 1006 | ||
1007 | /* On LPAR, look for the first ibm,pft-size property for the hash table size | ||
1008 | */ | ||
1009 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) { | ||
1010 | u32 *pft_size; | ||
1011 | pft_size = (u32 *)get_flat_dt_prop(node, "ibm,pft-size", NULL); | ||
1012 | if (pft_size != NULL) { | ||
1013 | /* pft_size[0] is the NUMA CEC cookie */ | ||
1014 | ppc64_pft_size = pft_size[1]; | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | if (initial_boot_params && initial_boot_params->version >= 2) { | 1007 | if (initial_boot_params && initial_boot_params->version >= 2) { |
1019 | /* version 2 of the kexec param format adds the phys cpuid | 1008 | /* version 2 of the kexec param format adds the phys cpuid |
1020 | * of booted proc. | 1009 | * of booted proc. |
@@ -1023,8 +1012,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
1023 | boot_cpuid = 0; | 1012 | boot_cpuid = 0; |
1024 | } else { | 1013 | } else { |
1025 | /* Check if it's the boot-cpu, set it's hw index in paca now */ | 1014 | /* Check if it's the boot-cpu, set it's hw index in paca now */ |
1026 | if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) { | 1015 | if (of_get_flat_dt_prop(node, "linux,boot-cpu", NULL) |
1027 | u32 *prop = get_flat_dt_prop(node, "reg", NULL); | 1016 | != NULL) { |
1017 | u32 *prop = of_get_flat_dt_prop(node, "reg", NULL); | ||
1028 | set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop); | 1018 | set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop); |
1029 | boot_cpuid_phys = get_hard_smp_processor_id(0); | 1019 | boot_cpuid_phys = get_hard_smp_processor_id(0); |
1030 | } | 1020 | } |
@@ -1032,14 +1022,14 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
1032 | 1022 | ||
1033 | #ifdef CONFIG_ALTIVEC | 1023 | #ifdef CONFIG_ALTIVEC |
1034 | /* Check if we have a VMX and eventually update CPU features */ | 1024 | /* Check if we have a VMX and eventually update CPU features */ |
1035 | prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL); | 1025 | prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL); |
1036 | if (prop && (*prop) > 0) { | 1026 | if (prop && (*prop) > 0) { |
1037 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; | 1027 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; |
1038 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | 1028 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; |
1039 | } | 1029 | } |
1040 | 1030 | ||
1041 | /* Same goes for Apple's "altivec" property */ | 1031 | /* Same goes for Apple's "altivec" property */ |
1042 | prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL); | 1032 | prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL); |
1043 | if (prop) { | 1033 | if (prop) { |
1044 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; | 1034 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; |
1045 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | 1035 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; |
@@ -1051,7 +1041,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
1051 | * this by looking at the size of the ibm,ppc-interrupt-server#s | 1041 | * this by looking at the size of the ibm,ppc-interrupt-server#s |
1052 | * property | 1042 | * property |
1053 | */ | 1043 | */ |
1054 | prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", | 1044 | prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", |
1055 | &size); | 1045 | &size); |
1056 | cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; | 1046 | cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; |
1057 | if (prop && ((size / sizeof(u32)) > 1)) | 1047 | if (prop && ((size / sizeof(u32)) > 1)) |
@@ -1072,26 +1062,26 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
1072 | return 0; | 1062 | return 0; |
1073 | 1063 | ||
1074 | /* get platform type */ | 1064 | /* get platform type */ |
1075 | prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL); | 1065 | prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); |
1076 | if (prop == NULL) | 1066 | if (prop == NULL) |
1077 | return 0; | 1067 | return 0; |
1078 | systemcfg->platform = *prop; | 1068 | systemcfg->platform = *prop; |
1079 | 1069 | ||
1080 | /* check if iommu is forced on or off */ | 1070 | /* check if iommu is forced on or off */ |
1081 | if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) | 1071 | if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) |
1082 | iommu_is_off = 1; | 1072 | iommu_is_off = 1; |
1083 | if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL) | 1073 | if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL) |
1084 | iommu_force_on = 1; | 1074 | iommu_force_on = 1; |
1085 | 1075 | ||
1086 | prop64 = (u64*)get_flat_dt_prop(node, "linux,memory-limit", NULL); | 1076 | prop64 = (u64*)of_get_flat_dt_prop(node, "linux,memory-limit", NULL); |
1087 | if (prop64) | 1077 | if (prop64) |
1088 | memory_limit = *prop64; | 1078 | memory_limit = *prop64; |
1089 | 1079 | ||
1090 | prop64 = (u64*)get_flat_dt_prop(node, "linux,tce-alloc-start", NULL); | 1080 | prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-start",NULL); |
1091 | if (prop64) | 1081 | if (prop64) |
1092 | tce_alloc_start = *prop64; | 1082 | tce_alloc_start = *prop64; |
1093 | 1083 | ||
1094 | prop64 = (u64*)get_flat_dt_prop(node, "linux,tce-alloc-end", NULL); | 1084 | prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL); |
1095 | if (prop64) | 1085 | if (prop64) |
1096 | tce_alloc_end = *prop64; | 1086 | tce_alloc_end = *prop64; |
1097 | 1087 | ||
@@ -1102,9 +1092,12 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
1102 | { | 1092 | { |
1103 | u64 *basep, *entryp; | 1093 | u64 *basep, *entryp; |
1104 | 1094 | ||
1105 | basep = (u64*)get_flat_dt_prop(node, "linux,rtas-base", NULL); | 1095 | basep = (u64*)of_get_flat_dt_prop(node, |
1106 | entryp = (u64*)get_flat_dt_prop(node, "linux,rtas-entry", NULL); | 1096 | "linux,rtas-base", NULL); |
1107 | prop = (u32*)get_flat_dt_prop(node, "linux,rtas-size", NULL); | 1097 | entryp = (u64*)of_get_flat_dt_prop(node, |
1098 | "linux,rtas-entry", NULL); | ||
1099 | prop = (u32*)of_get_flat_dt_prop(node, | ||
1100 | "linux,rtas-size", NULL); | ||
1108 | if (basep && entryp && prop) { | 1101 | if (basep && entryp && prop) { |
1109 | rtas.base = *basep; | 1102 | rtas.base = *basep; |
1110 | rtas.entry = *entryp; | 1103 | rtas.entry = *entryp; |
@@ -1125,11 +1118,11 @@ static int __init early_init_dt_scan_root(unsigned long node, | |||
1125 | if (depth != 0) | 1118 | if (depth != 0) |
1126 | return 0; | 1119 | return 0; |
1127 | 1120 | ||
1128 | prop = (u32 *)get_flat_dt_prop(node, "#size-cells", NULL); | 1121 | prop = (u32 *)of_get_flat_dt_prop(node, "#size-cells", NULL); |
1129 | dt_root_size_cells = (prop == NULL) ? 1 : *prop; | 1122 | dt_root_size_cells = (prop == NULL) ? 1 : *prop; |
1130 | DBG("dt_root_size_cells = %x\n", dt_root_size_cells); | 1123 | DBG("dt_root_size_cells = %x\n", dt_root_size_cells); |
1131 | 1124 | ||
1132 | prop = (u32 *)get_flat_dt_prop(node, "#address-cells", NULL); | 1125 | prop = (u32 *)of_get_flat_dt_prop(node, "#address-cells", NULL); |
1133 | dt_root_addr_cells = (prop == NULL) ? 2 : *prop; | 1126 | dt_root_addr_cells = (prop == NULL) ? 2 : *prop; |
1134 | DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells); | 1127 | DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells); |
1135 | 1128 | ||
@@ -1161,7 +1154,7 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) | |||
1161 | static int __init early_init_dt_scan_memory(unsigned long node, | 1154 | static int __init early_init_dt_scan_memory(unsigned long node, |
1162 | const char *uname, int depth, void *data) | 1155 | const char *uname, int depth, void *data) |
1163 | { | 1156 | { |
1164 | char *type = get_flat_dt_prop(node, "device_type", NULL); | 1157 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
1165 | cell_t *reg, *endp; | 1158 | cell_t *reg, *endp; |
1166 | unsigned long l; | 1159 | unsigned long l; |
1167 | 1160 | ||
@@ -1169,7 +1162,7 @@ static int __init early_init_dt_scan_memory(unsigned long node, | |||
1169 | if (type == NULL || strcmp(type, "memory") != 0) | 1162 | if (type == NULL || strcmp(type, "memory") != 0) |
1170 | return 0; | 1163 | return 0; |
1171 | 1164 | ||
1172 | reg = (cell_t *)get_flat_dt_prop(node, "reg", &l); | 1165 | reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); |
1173 | if (reg == NULL) | 1166 | if (reg == NULL) |
1174 | return 0; | 1167 | return 0; |
1175 | 1168 | ||
@@ -1225,19 +1218,16 @@ void __init early_init_devtree(void *params) | |||
1225 | /* Setup flat device-tree pointer */ | 1218 | /* Setup flat device-tree pointer */ |
1226 | initial_boot_params = params; | 1219 | initial_boot_params = params; |
1227 | 1220 | ||
1228 | /* By default, hash size is not set */ | ||
1229 | ppc64_pft_size = 0; | ||
1230 | |||
1231 | /* Retreive various informations from the /chosen node of the | 1221 | /* Retreive various informations from the /chosen node of the |
1232 | * device-tree, including the platform type, initrd location and | 1222 | * device-tree, including the platform type, initrd location and |
1233 | * size, TCE reserve, and more ... | 1223 | * size, TCE reserve, and more ... |
1234 | */ | 1224 | */ |
1235 | scan_flat_dt(early_init_dt_scan_chosen, NULL); | 1225 | of_scan_flat_dt(early_init_dt_scan_chosen, NULL); |
1236 | 1226 | ||
1237 | /* Scan memory nodes and rebuild LMBs */ | 1227 | /* Scan memory nodes and rebuild LMBs */ |
1238 | lmb_init(); | 1228 | lmb_init(); |
1239 | scan_flat_dt(early_init_dt_scan_root, NULL); | 1229 | of_scan_flat_dt(early_init_dt_scan_root, NULL); |
1240 | scan_flat_dt(early_init_dt_scan_memory, NULL); | 1230 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); |
1241 | lmb_enforce_memory_limit(memory_limit); | 1231 | lmb_enforce_memory_limit(memory_limit); |
1242 | lmb_analyze(); | 1232 | lmb_analyze(); |
1243 | systemcfg->physicalMemorySize = lmb_phys_mem_size(); | 1233 | systemcfg->physicalMemorySize = lmb_phys_mem_size(); |
@@ -1253,26 +1243,8 @@ void __init early_init_devtree(void *params) | |||
1253 | /* Retreive hash table size from flattened tree plus other | 1243 | /* Retreive hash table size from flattened tree plus other |
1254 | * CPU related informations (altivec support, boot CPU ID, ...) | 1244 | * CPU related informations (altivec support, boot CPU ID, ...) |
1255 | */ | 1245 | */ |
1256 | scan_flat_dt(early_init_dt_scan_cpus, NULL); | 1246 | of_scan_flat_dt(early_init_dt_scan_cpus, NULL); |
1257 | |||
1258 | /* If hash size wasn't obtained above, we calculate it now based on | ||
1259 | * the total RAM size | ||
1260 | */ | ||
1261 | if (ppc64_pft_size == 0) { | ||
1262 | unsigned long rnd_mem_size, pteg_count; | ||
1263 | |||
1264 | /* round mem_size up to next power of 2 */ | ||
1265 | rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize); | ||
1266 | if (rnd_mem_size < systemcfg->physicalMemorySize) | ||
1267 | rnd_mem_size <<= 1; | ||
1268 | |||
1269 | /* # pages / 2 */ | ||
1270 | pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11); | ||
1271 | |||
1272 | ppc64_pft_size = __ilog2(pteg_count << 7); | ||
1273 | } | ||
1274 | 1247 | ||
1275 | DBG("Hash pftSize: %x\n", (int)ppc64_pft_size); | ||
1276 | DBG(" <- early_init_devtree()\n"); | 1248 | DBG(" <- early_init_devtree()\n"); |
1277 | } | 1249 | } |
1278 | 1250 | ||