[RFC , PATCH] support for the ibm,pa_features cpu property
Paul Mackerras
paulus at samba.org
Sat Apr 29 12:20:42 EST 2006
Will Schmidt writes:
> This is an initial pass at the functionality. This has been tested in
> the case where the property is missing, but still needs to be tested
> against a system where the property actually exists. :-o
Some random comments, and a modified version of your patch...
- We may want to make a table giving the correspondence between
pa-features byte/bit numbers and our feature bits, and then just
have code that walks through the table and sets/clears feature bits
as appropriate.
- If we are setting/clearing feature bits that are used with the asm
feature macros, we'll have to do this much earlier, in prom.c,
before the device tree is unflattened.
Paul.
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 4467c49..022b9b3 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -106,6 +106,78 @@ static struct notifier_block ppc64_panic
.priority = INT_MIN /* may not return; must be done last */
};
+/*
+ * ibm,pa-features is a per-cpu property that contains a string of
+ * attribute descriptors, each of which has a 2 byte header plus up
+ * to 254 bytes worth of processor attribute bits. First header
+ * byte specifies the number of bytes following the header.
+ * Second header byte is an "attribute-specifier" type, of which
+ * zero is the only currently-defined value.
+ * Implementation: Pass in the byte and bit offset for the feature
+ * that we are interested in. The function will return -1 if the
+ * pa-features property is missing, or a 1/0 to indicate if the feature
+ * is supported/not supported. Note that the bit numbers are
+ * big-endian to match the definition in PAPR.
+ */
+static int get_pa_feature(int pabyte, int pabit)
+{
+ struct device_node *cpu;
+ unsigned char *pa_feature_table;
+ int tablelen;
+ int ret = -1;
+
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu == NULL)
+ return -1;
+
+ pa_feature_table = get_property(cpu, "ibm,pa-features", &tablelen);
+ if (pa_feature_table == NULL)
+ goto out;
+
+ /* find descriptor with type == 0 */
+ for (;;) {
+ if (tablelen < 3 || tablelen < 2 + pa_feature_table[1])
+ goto out; /* not found */
+ if (pa_feature_table[0] == 0)
+ break;
+ tablelen -= 2 + pa_feature_table[1];
+ pa_feature_table += 2 + pa_feature_table[1];
+ }
+
+ /* check if the specifier is long enough */
+ if (pabyte >= pa_feature_table[1])
+ goto out;
+
+ ret = (pa_feature_table[2 + pabyte] >> (7 - pabit)) & 1;
+
+ out:
+ of_node_put(cpu);
+ return ret;
+}
+
+/*
+ * set values within the cur_cpu_spec table according to
+ * the ibm,pa_features property.
+ * potential entries include:
+ * Byte 0, bit 1 - FPU available
+ * Byte 1, bit 2 - cache-inhibited large pages supported
+ * Byte 2, bit 3 - DAR set on alignment interrupt.
+ */
+static void check_cpu_features(void)
+{
+ int hasit;
+
+ /* test for support of cache-inhibited large pages */
+ hasit = get_pa_feature(1, 2);
+ if (hasit >= 0)
+ if (hasit)
+ cur_cpu_spec->cpu_features |= CPU_FTR_CI_LARGE_PAGE;
+ else
+ cur_cpu_spec->cpu_features &= ~CPU_FTR_CI_LARGE_PAGE;
+
+ /* add more here in future... */
+}
+
#ifdef CONFIG_SMP
static int smt_enabled_cmdline;
@@ -425,6 +497,8 @@ #endif
parse_early_param();
+ check_cpu_features();
+
check_smt_enabled();
smp_setup_cpu_maps();
More information about the Linuxppc-dev
mailing list