aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/prom.c')
-rw-r--r--arch/ppc64/kernel/prom.c94
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 */
638static int __init scan_flat_dt(int (*it)(unsigned long node, 638int __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 */
698static void* __init get_flat_dt_prop(unsigned long node, const char *name, 698void* __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)
996static int __init early_init_dt_scan_cpus(unsigned long node, 996static 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)
1161static int __init early_init_dt_scan_memory(unsigned long node, 1154static 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