[PATCH] ppc64: Detect altivec via firmware on unknown CPUs

Benjamin Herrenschmidt benh at kernel.crashing.org
Wed Apr 6 16:05:28 EST 2005


Hi !

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 at kernel.crashing.org>

Index: linux-work/arch/ppc64/kernel/prom.c
===================================================================
--- linux-work.orig/arch/ppc64/kernel/prom.c	2005-04-06 10:22:10.000000000 +1000
+++ linux-work/arch/ppc64/kernel/prom.c	2005-04-06 15:26:23.000000000 +1000
@@ -885,6 +885,7 @@
 					  const char *full_path, void *data)
 {
 	char *type = get_flat_dt_prop(node, "device_type", NULL);
+	u32 *prop;
 
 	/* We are scanning "cpu" nodes only */
 	if (type == NULL || strcmp(type, "cpu") != 0)
@@ -916,6 +917,20 @@
 		}
 	}
 
+	/* Check if we have a VMX and eventually update CPU features */
+	prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL);
+	if (prop && (*prop) > 0) {
+		cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+		cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+	}
+
+	/* Same goes for Apple's "altivec" property */
+	prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
+	if (prop) {
+		cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
+		cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+	}
+
 	return 0;
 }
 
@@ -1104,7 +1119,9 @@
 
 	DBG("Scanning CPUs ...\n");
 
-	/* Retreive hash table size from flattened tree */
+	/* Retreive hash table size from flattened tree plus other
+	 * CPU related informations (altivec support, boot CPU ID, ...)
+	 */
 	scan_flat_dt(early_init_dt_scan_cpus, NULL);
 
 	/* If hash size wasn't obtained above, we calculate it now based on
Index: linux-work/arch/ppc64/kernel/head.S
===================================================================
--- linux-work.orig/arch/ppc64/kernel/head.S	2005-04-03 10:02:55.000000000 +1000
+++ linux-work/arch/ppc64/kernel/head.S	2005-04-06 14:27:19.000000000 +1000
@@ -922,7 +922,9 @@
 altivec_unavailable_common:
 	EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
 #ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
 	bne	.load_up_altivec	/* if from user, just load it up */
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD





More information about the Linuxppc64-dev mailing list