diff options
author | Greg Kurz <gkurz@linux.vnet.ibm.com> | 2015-02-23 16:14:31 +0100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-03-18 10:48:59 +1100 |
commit | 4b6cfb2a8cd7520e8a747718e5c1da047697ca31 (patch) | |
tree | 4c11bb5e691f12eec899ae7350a743920541e96b /arch/powerpc/mm/vphn.c | |
parent | b1fc9484aa339c19bd57702dc88fb046702b6092 (diff) |
powerpc/vphn: move VPHN parsing logic to a separate file
The goal behind this patch is to be able to write userland tests for the
VPHN parsing code.
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/mm/vphn.c')
-rw-r--r-- | arch/powerpc/mm/vphn.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/arch/powerpc/mm/vphn.c b/arch/powerpc/mm/vphn.c new file mode 100644 index 000000000000..c49ed519c381 --- /dev/null +++ b/arch/powerpc/mm/vphn.c @@ -0,0 +1,50 @@ +#include <asm/byteorder.h> +#include "vphn.h" + +/* + * Convert the associativity domain numbers returned from the hypervisor + * to the sequence they would appear in the ibm,associativity property. + */ +int vphn_unpack_associativity(const long *packed, __be32 *unpacked) +{ + __be64 be_packed[VPHN_REGISTER_COUNT]; + int i, nr_assoc_doms = 0; + const __be16 *field = (const __be16 *) be_packed; + +#define VPHN_FIELD_UNUSED (0xffff) +#define VPHN_FIELD_MSB (0x8000) +#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB) + + /* Let's recreate the original stream. */ + for (i = 0; i < VPHN_REGISTER_COUNT; i++) + be_packed[i] = cpu_to_be64(packed[i]); + + for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) { + if (be16_to_cpup(field) == VPHN_FIELD_UNUSED) { + /* All significant fields processed, and remaining + * fields contain the reserved value of all 1's. + * Just store them. + */ + unpacked[i] = *((__be32 *)field); + field += 2; + } else if (be16_to_cpup(field) & VPHN_FIELD_MSB) { + /* Data is in the lower 15 bits of this field */ + unpacked[i] = cpu_to_be32( + be16_to_cpup(field) & VPHN_FIELD_MASK); + field++; + nr_assoc_doms++; + } else { + /* Data is in the lower 15 bits of this field + * concatenated with the next 16 bit field + */ + unpacked[i] = *((__be32 *)field); + field += 2; + nr_assoc_doms++; + } + } + + /* The first cell contains the length of the property */ + unpacked[0] = cpu_to_be32(nr_assoc_doms); + + return nr_assoc_doms; +} |