aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom.c
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2006-03-25 01:25:17 -0500
committerPaul Mackerras <paulus@samba.org>2006-03-26 22:48:48 -0500
commit4df20460a3ff0d60280738b094945c56cb5567a5 (patch)
tree39f831cf5f778b14a08b3453a8f798b2b8be8813 /arch/powerpc/kernel/prom.c
parentb4f382a3e5e20ba867e7aa5b01189a3fd40eea2c (diff)
[PATCH] powerpc: Allow non zero boot cpuids
We currently have a hack to flip the boot cpu and its secondary thread to logical cpuid 0 and 1. This means the logical - physical mapping will differ depending on which cpu is boot cpu. This is most apparent on kexec, where we might kexec on any cpu and therefore change the mapping from boot to boot. The patch below does a first pass early on to work out the logical cpuid of the boot thread. We then fix up some paca structures to match. Ive also removed the boot_cpuid_phys variable for ppc64, to be consistent we use get_hard_smp_processor_id(boot_cpuid) everywhere. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r--arch/powerpc/kernel/prom.c83
1 files changed, 56 insertions, 27 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index d63cd562d9d5..5a24415a2e3c 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -854,35 +854,70 @@ void __init unflatten_device_tree(void)
854 DBG(" <- unflatten_device_tree()\n"); 854 DBG(" <- unflatten_device_tree()\n");
855} 855}
856 856
857
858static int __init early_init_dt_scan_cpus(unsigned long node, 857static int __init early_init_dt_scan_cpus(unsigned long node,
859 const char *uname, int depth, void *data) 858 const char *uname, int depth,
859 void *data)
860{ 860{
861 u32 *prop; 861 static int logical_cpuid = 0;
862 unsigned long size; 862 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
863 char *type = of_get_flat_dt_prop(node, "device_type", &size); 863 u32 *prop, *intserv;
864 int i, nthreads;
865 unsigned long len;
866 int found = 0;
864 867
865 /* We are scanning "cpu" nodes only */ 868 /* We are scanning "cpu" nodes only */
866 if (type == NULL || strcmp(type, "cpu") != 0) 869 if (type == NULL || strcmp(type, "cpu") != 0)
867 return 0; 870 return 0;
868 871
869 boot_cpuid = 0; 872 /* Get physical cpuid */
870 boot_cpuid_phys = 0; 873 intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
871 if (initial_boot_params && initial_boot_params->version >= 2) { 874 if (intserv) {
872 /* version 2 of the kexec param format adds the phys cpuid 875 nthreads = len / sizeof(int);
873 * of booted proc.
874 */
875 boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
876 } else { 876 } else {
877 /* Check if it's the boot-cpu, set it's hw index now */ 877 intserv = of_get_flat_dt_prop(node, "reg", NULL);
878 if (of_get_flat_dt_prop(node, 878 nthreads = 1;
879 }
880
881 /*
882 * Now see if any of these threads match our boot cpu.
883 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
884 */
885 for (i = 0; i < nthreads; i++) {
886 /*
887 * version 2 of the kexec param format adds the phys cpuid of
888 * booted proc.
889 */
890 if (initial_boot_params && initial_boot_params->version >= 2) {
891 if (intserv[i] ==
892 initial_boot_params->boot_cpuid_phys) {
893 found = 1;
894 break;
895 }
896 } else {
897 /*
898 * Check if it's the boot-cpu, set it's hw index now,
899 * unfortunately this format did not support booting
900 * off secondary threads.
901 */
902 if (of_get_flat_dt_prop(node,
879 "linux,boot-cpu", NULL) != NULL) { 903 "linux,boot-cpu", NULL) != NULL) {
880 prop = of_get_flat_dt_prop(node, "reg", NULL); 904 found = 1;
881 if (prop != NULL) 905 break;
882 boot_cpuid_phys = *prop; 906 }
883 } 907 }
908
909#ifdef CONFIG_SMP
910 /* logical cpu id is always 0 on UP kernels */
911 logical_cpuid++;
912#endif
913 }
914
915 if (found) {
916 DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
917 intserv[i]);
918 boot_cpuid = logical_cpuid;
919 set_hard_smp_processor_id(boot_cpuid, intserv[i]);
884 } 920 }
885 set_hard_smp_processor_id(0, boot_cpuid_phys);
886 921
887#ifdef CONFIG_ALTIVEC 922#ifdef CONFIG_ALTIVEC
888 /* Check if we have a VMX and eventually update CPU features */ 923 /* Check if we have a VMX and eventually update CPU features */
@@ -901,16 +936,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
901#endif /* CONFIG_ALTIVEC */ 936#endif /* CONFIG_ALTIVEC */
902 937
903#ifdef CONFIG_PPC_PSERIES 938#ifdef CONFIG_PPC_PSERIES
904 /* 939 if (nthreads > 1)
905 * Check for an SMT capable CPU and set the CPU feature. We do
906 * this by looking at the size of the ibm,ppc-interrupt-server#s
907 * property
908 */
909 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
910 &size);
911 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
912 if (prop && ((size / sizeof(u32)) > 1))
913 cur_cpu_spec->cpu_features |= CPU_FTR_SMT; 940 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
941 else
942 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
914#endif 943#endif
915 944
916 return 0; 945 return 0;