aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/prom.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-04-16 18:24:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:24:36 -0400
commit187335a4ec72c9bc7f3f168d6858a41fcfb63302 (patch)
treed5f1ae0d320e6325ed056469773e855fc635c53d /arch/ppc64/kernel/prom.c
parent547ee84cea37696d25c93306e909378a87db2f66 (diff)
[PATCH] ppc64: Detect altivec via firmware on unknown CPUs
This patch adds detection of the Altivec capability of the CPU via the firmware in addition to the cpu table. This allows newer CPUs that aren't in the table to still have working altivec support in the kernel. It also fixes a problem where if a CPU isn't recognized as having altivec features, and takes an altivec unavailable exception due to userland issuing altivec instructions, the kernel would happily enable it and context switch the registers ... but not all of them (it would basically forget vrsave). With this patch, the kernel will refuse to enable altivec when the feature isn't detected for the CPU (SIGILL). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/kernel/prom.c')
-rw-r--r--arch/ppc64/kernel/prom.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 01739d5c47c7..b08aac68baff 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -885,6 +885,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
885 const char *full_path, void *data) 885 const char *full_path, void *data)
886{ 886{
887 char *type = get_flat_dt_prop(node, "device_type", NULL); 887 char *type = get_flat_dt_prop(node, "device_type", NULL);
888 u32 *prop;
888 889
889 /* We are scanning "cpu" nodes only */ 890 /* We are scanning "cpu" nodes only */
890 if (type == NULL || strcmp(type, "cpu") != 0) 891 if (type == NULL || strcmp(type, "cpu") != 0)
@@ -916,6 +917,20 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
916 } 917 }
917 } 918 }
918 919
920 /* Check if we have a VMX and eventually update CPU features */
921 prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL);
922 if (prop && (*prop) > 0) {
923 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
924 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
925 }
926
927 /* Same goes for Apple's "altivec" property */
928 prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
929 if (prop) {
930 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
931 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
932 }
933
919 return 0; 934 return 0;
920} 935}
921 936
@@ -1104,7 +1119,9 @@ void __init early_init_devtree(void *params)
1104 1119
1105 DBG("Scanning CPUs ...\n"); 1120 DBG("Scanning CPUs ...\n");
1106 1121
1107 /* Retreive hash table size from flattened tree */ 1122 /* Retreive hash table size from flattened tree plus other
1123 * CPU related informations (altivec support, boot CPU ID, ...)
1124 */
1108 scan_flat_dt(early_init_dt_scan_cpus, NULL); 1125 scan_flat_dt(early_init_dt_scan_cpus, NULL);
1109 1126
1110 /* If hash size wasn't obtained above, we calculate it now based on 1127 /* If hash size wasn't obtained above, we calculate it now based on