selftests/powerpc/pmu: Add mask/shift bits for extracting threshold compare field
authorKajol Jain <kjain@linux.ibm.com>
Fri, 10 Jun 2022 13:40:39 +0000 (19:10 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 28 Jun 2022 13:56:37 +0000 (23:56 +1000)
In power10, threshold compare field is not part of the raw event code
and provided via event attribute config1. Hence add the mask and shift
bits based on event attribute config1, to extract the threshold compare
value for power10

Also add a new function called get_thresh_cmp_val to compute and return
the threshold compare field for a given platform, since incase of
power10, threshold compare value provided is decimal.

Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220610134113.62991-2-atrajeev@linux.vnet.ibm.com
tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c
tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h

index c01a31d5f4eeedbdf74e061c08ebc4f2bc545b39..b984d1e162ac4325c2c00dcb73c35ad4c5abe435 100644 (file)
@@ -60,6 +60,8 @@ static void init_ev_encodes(void)
 
        switch (pvr) {
        case POWER10:
+               ev_mask_thd_cmp = 0x3ffff;
+               ev_shift_thd_cmp = 0;
                ev_mask_rsq = 1;
                ev_shift_rsq = 9;
                ev_mask_comb = 3;
@@ -410,3 +412,45 @@ u64 get_reg_value(u64 *intr_regs, char *register_name)
 
        return *(intr_regs + register_bit_position);
 }
+
+int get_thresh_cmp_val(struct event event)
+{
+       int exp = 0;
+       u64 result = 0;
+       u64 value;
+
+       if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1))
+               return EV_CODE_EXTRACT(event.attr.config, thd_cmp);
+
+       value = EV_CODE_EXTRACT(event.attr.config1, thd_cmp);
+
+       if (!value)
+               return value;
+
+       /*
+        * Incase of P10, thresh_cmp value is not part of raw event code
+        * and provided via attr.config1 parameter. To program threshold in MMCRA,
+        * take a 18 bit number N and shift right 2 places and increment
+        * the exponent E by 1 until the upper 10 bits of N are zero.
+        * Write E to the threshold exponent and write the lower 8 bits of N
+        * to the threshold mantissa.
+        * The max threshold that can be written is 261120.
+        */
+       if (value > 261120)
+               value = 261120;
+       while ((64 - __builtin_clzl(value)) > 8) {
+               exp++;
+               value >>= 2;
+       }
+
+       /*
+        * Note that it is invalid to write a mantissa with the
+        * upper 2 bits of mantissa being zero, unless the
+        * exponent is also zero.
+        */
+       if (!(value & 0xC0) && exp)
+               result = -1;
+       else
+               result = (exp << 8) | value;
+       return result;
+}
index 7675f31777251b94057874b817d9352270e0542c..078120883fdef386f6cc48bb2cd6d48d067d4b20 100644 (file)
@@ -52,6 +52,7 @@ void *__event_read_samples(void *sample_buff, size_t *size, u64 *sample_count);
 int collect_samples(void *sample_buff);
 u64 *get_intr_regs(struct event *event, void *sample_buff);
 u64 get_reg_value(u64 *intr_regs, char *register_name);
+int get_thresh_cmp_val(struct event event);
 
 static inline int get_mmcr0_fc56(u64 mmcr0, int pmc)
 {