root/tools/testing/selftests/powerpc/vphn/vphn.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vphn_unpack_associativity
  2. hcall_vphn

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <asm/byteorder.h>
   3 #include <asm/lppaca.h>
   4 
   5 /*
   6  * The associativity domain numbers are returned from the hypervisor as a
   7  * stream of mixed 16-bit and 32-bit fields. The stream is terminated by the
   8  * special value of "all ones" (aka. 0xffff) and its size may not exceed 48
   9  * bytes.
  10  *
  11  *    --- 16-bit fields -->
  12  *  _________________________
  13  *  |  0  |  1  |  2  |  3  |   be_packed[0]
  14  *  ------+-----+-----+------
  15  *  _________________________
  16  *  |  4  |  5  |  6  |  7  |   be_packed[1]
  17  *  -------------------------
  18  *            ...
  19  *  _________________________
  20  *  | 20  | 21  | 22  | 23  |   be_packed[5]
  21  *  -------------------------
  22  *
  23  * Convert to the sequence they would appear in the ibm,associativity property.
  24  */
  25 static int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
  26 {
  27         __be64 be_packed[VPHN_REGISTER_COUNT];
  28         int i, nr_assoc_doms = 0;
  29         const __be16 *field = (const __be16 *) be_packed;
  30         u16 last = 0;
  31         bool is_32bit = false;
  32 
  33 #define VPHN_FIELD_UNUSED       (0xffff)
  34 #define VPHN_FIELD_MSB          (0x8000)
  35 #define VPHN_FIELD_MASK         (~VPHN_FIELD_MSB)
  36 
  37         /* Let's fix the values returned by plpar_hcall9() */
  38         for (i = 0; i < VPHN_REGISTER_COUNT; i++)
  39                 be_packed[i] = cpu_to_be64(packed[i]);
  40 
  41         for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) {
  42                 u16 new = be16_to_cpup(field++);
  43 
  44                 if (is_32bit) {
  45                         /*
  46                          * Let's concatenate the 16 bits of this field to the
  47                          * 15 lower bits of the previous field
  48                          */
  49                         unpacked[++nr_assoc_doms] =
  50                                 cpu_to_be32(last << 16 | new);
  51                         is_32bit = false;
  52                 } else if (new == VPHN_FIELD_UNUSED)
  53                         /* This is the list terminator */
  54                         break;
  55                 else if (new & VPHN_FIELD_MSB) {
  56                         /* Data is in the lower 15 bits of this field */
  57                         unpacked[++nr_assoc_doms] =
  58                                 cpu_to_be32(new & VPHN_FIELD_MASK);
  59                 } else {
  60                         /*
  61                          * Data is in the lower 15 bits of this field
  62                          * concatenated with the next 16 bit field
  63                          */
  64                         last = new;
  65                         is_32bit = true;
  66                 }
  67         }
  68 
  69         /* The first cell contains the length of the property */
  70         unpacked[0] = cpu_to_be32(nr_assoc_doms);
  71 
  72         return nr_assoc_doms;
  73 }
  74 
  75 /* NOTE: This file is included by a selftest and built in userspace. */
  76 #ifdef __KERNEL__
  77 #include <asm/hvcall.h>
  78 
  79 long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity)
  80 {
  81         long rc;
  82         long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
  83 
  84         rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, cpu);
  85         vphn_unpack_associativity(retbuf, associativity);
  86 
  87         return rc;
  88 }
  89 #endif

/* [<][>][^][v][top][bottom][index][help] */