The branch main has been updated by mav:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=62ff619dcc3540659a319be71c9a489f1659e14a

commit 62ff619dcc3540659a319be71c9a489f1659e14a
Author:     Alexander Motin <m...@freebsd.org>
AuthorDate: 2022-05-30 18:07:31 +0000
Commit:     Alexander Motin <m...@freebsd.org>
CommitDate: 2022-05-30 18:10:21 +0000

    libpmc: jevents: Sync with the latest Linux kernel.
    
    commit f4df0dbbe62ee8e4405a57b27ccd54393971c773
    Date:   Wed May 25 22:04:10 2022 +0800
    
    MFC after:      1 month
---
 .../pmu-events/arch/test/arch-std-events.json      |   8 +
 .../pmu-events/arch/test/test_soc/cpu/branch.json  |  12 +
 .../pmu-events/arch/test/test_soc/cpu/cache.json   |   5 +
 .../pmu-events/arch/test/test_soc/cpu/other.json   |  26 +
 .../pmu-events/arch/test/test_soc/cpu/uncore.json  |  58 ++
 .../pmu-events/arch/test/test_soc/sys/uncore.json  |  16 +
 lib/libpmc/pmu-events/jevents.c                    | 599 +++++++++++++--------
 lib/libpmc/pmu-events/jevents.h                    |  14 -
 lib/libpmc/pmu-events/jsmn.c                       |  43 +-
 lib/libpmc/pmu-events/pmu-events.h                 |  21 +-
 10 files changed, 569 insertions(+), 233 deletions(-)

diff --git a/lib/libpmc/pmu-events/arch/test/arch-std-events.json 
b/lib/libpmc/pmu-events/arch/test/arch-std-events.json
new file mode 100644
index 000000000000..43f6f729d6ae
--- /dev/null
+++ b/lib/libpmc/pmu-events/arch/test/arch-std-events.json
@@ -0,0 +1,8 @@
+[
+    {
+        "PublicDescription": "Attributable Level 3 cache access, read",
+        "EventCode": "0x40",
+        "EventName": "L3_CACHE_RD",
+        "BriefDescription": "L3 cache access, read"
+    }
+]
diff --git a/lib/libpmc/pmu-events/arch/test/test_soc/cpu/branch.json 
b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/branch.json
new file mode 100644
index 000000000000..93ddfd8053ca
--- /dev/null
+++ b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/branch.json
@@ -0,0 +1,12 @@
+[
+  {
+    "EventName": "bp_l1_btb_correct",
+    "EventCode": "0x8a",
+    "BriefDescription": "L1 BTB Correction."
+  },
+  {
+    "EventName": "bp_l2_btb_correct",
+    "EventCode": "0x8b",
+    "BriefDescription": "L2 BTB Correction."
+  }
+]
diff --git a/lib/libpmc/pmu-events/arch/test/test_soc/cpu/cache.json 
b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/cache.json
new file mode 100644
index 000000000000..036d0efdb2bb
--- /dev/null
+++ b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/cache.json
@@ -0,0 +1,5 @@
+[
+    {
+        "ArchStdEvent": "L3_CACHE_RD"
+    }
+]
\ No newline at end of file
diff --git a/lib/libpmc/pmu-events/arch/test/test_soc/cpu/other.json 
b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/other.json
new file mode 100644
index 000000000000..7d53d7ecd723
--- /dev/null
+++ b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/other.json
@@ -0,0 +1,26 @@
+[
+    {
+        "EventCode": "0x6",
+        "Counter": "0,1",
+        "UMask": "0x80",
+        "EventName": "SEGMENT_REG_LOADS.ANY",
+        "SampleAfterValue": "200000",
+        "BriefDescription": "Number of segment register loads."
+    },
+    {
+        "EventCode": "0x9",
+        "Counter": "0,1",
+        "UMask": "0x20",
+        "EventName": "DISPATCH_BLOCKED.ANY",
+        "SampleAfterValue": "200000",
+        "BriefDescription": "Memory cluster signals to block micro-op dispatch 
for any reason"
+    },
+    {
+        "EventCode": "0x3A",
+        "Counter": "0,1",
+        "UMask": "0x0",
+        "EventName": "EIST_TRANS",
+        "SampleAfterValue": "200000",
+        "BriefDescription": "Number of Enhanced Intel SpeedStep(R) Technology 
(EIST) transitions"
+    }
+]
\ No newline at end of file
diff --git a/lib/libpmc/pmu-events/arch/test/test_soc/cpu/uncore.json 
b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/uncore.json
new file mode 100644
index 000000000000..41bac1c6a008
--- /dev/null
+++ b/lib/libpmc/pmu-events/arch/test/test_soc/cpu/uncore.json
@@ -0,0 +1,58 @@
+[
+ {
+           "EventCode": "0x02",
+           "EventName": "uncore_hisi_ddrc.flux_wcmd",
+           "BriefDescription": "DDRC write commands",
+           "PublicDescription": "DDRC write commands",
+           "Unit": "hisi_sccl,ddrc"
+   },
+   {
+           "Unit": "CBO",
+           "EventCode": "0x22",
+           "UMask": "0x81",
+           "EventName": "UNC_CBO_XSNP_RESPONSE.MISS_EVICTION",
+           "BriefDescription": "A cross-core snoop resulted from L3 Eviction 
which misses in some processor core.",
+           "PublicDescription": "A cross-core snoop resulted from L3 Eviction 
which misses in some processor core.",
+           "Counter": "0,1",
+           "CounterMask": "0",
+           "Invert": "0",
+           "EdgeDetect": "0"
+  },
+  {
+           "Unit": "CBO",
+           "EventCode": "0xE0",
+           "UMask": "0x00",
+           "EventName": "event-hyphen",
+           "BriefDescription": "UNC_CBO_HYPHEN",
+           "PublicDescription": "UNC_CBO_HYPHEN"
+  },
+  {
+           "Unit": "CBO",
+           "EventCode": "0xC0",
+           "UMask": "0x00",
+           "EventName": "event-two-hyph",
+           "BriefDescription": "UNC_CBO_TWO_HYPH",
+           "PublicDescription": "UNC_CBO_TWO_HYPH"
+  },
+  {
+           "EventCode": "0x7",
+           "EventName": "uncore_hisi_l3c.rd_hit_cpipe",
+           "BriefDescription": "Total read hits",
+           "PublicDescription": "Total read hits",
+           "Unit": "hisi_sccl,l3c"
+  },
+  {
+           "EventCode": "0x12",
+           "EventName": "uncore_imc_free_running.cache_miss",
+           "BriefDescription": "Total cache misses",
+           "PublicDescription": "Total cache misses",
+           "Unit": "imc_free_running"
+  },
+  {
+           "EventCode": "0x34",
+           "EventName": "uncore_imc.cache_hits",
+           "BriefDescription": "Total cache hits",
+           "PublicDescription": "Total cache hits",
+           "Unit": "imc"
+  }
+]
diff --git a/lib/libpmc/pmu-events/arch/test/test_soc/sys/uncore.json 
b/lib/libpmc/pmu-events/arch/test/test_soc/sys/uncore.json
new file mode 100644
index 000000000000..c7e7528db315
--- /dev/null
+++ b/lib/libpmc/pmu-events/arch/test/test_soc/sys/uncore.json
@@ -0,0 +1,16 @@
+[
+  {
+           "BriefDescription": "ddr write-cycles event",
+           "EventCode": "0x2b",
+           "EventName": "sys_ddr_pmu.write_cycles",
+           "Unit": "sys_ddr_pmu",
+           "Compat": "v8"
+   },
+   {
+           "BriefDescription": "ccn read-cycles event",
+           "ConfigCode": "0x2c",
+           "EventName": "sys_ccn_pmu.read_cycles",
+           "Unit": "sys_ccn_pmu",
+           "Compat": "0x01"
+   }
+]
diff --git a/lib/libpmc/pmu-events/jevents.c b/lib/libpmc/pmu-events/jevents.c
index b411329dd35a..5a296031451e 100644
--- a/lib/libpmc/pmu-events/jevents.c
+++ b/lib/libpmc/pmu-events/jevents.c
@@ -26,9 +26,6 @@
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- *
 */
 
 #include <sys/param.h>
@@ -50,17 +47,64 @@
 #include "list.h"
 #include "jsmn.h"
 #include "json.h"
-#include "jevents.h"
+#include "pmu-events.h"
 
 static int
 nftw_ordered(const char *path, int (*fn)(const char *, const struct stat *, 
int,
        struct FTW *), int nfds, int ftwflags);
+#define        nftw nftw_ordered
 
 _Noreturn void  _Exit(int);
+char *get_cpu_str(void);
 
 int verbose;
 static char *prog;
 
+struct json_event {
+       char *name;
+       char *compat;
+       char *event;
+       char *desc;
+       char *long_desc;
+       char *pmu;
+       char *unit;
+       char *perpkg;
+       char *aggr_mode;
+       char *metric_expr;
+       char *metric_name;
+       char *metric_group;
+       char *deprecated;
+       char *metric_constraint;
+};
+
+static enum aggr_mode_class convert(const char *aggr_mode)
+{
+       if (!strcmp(aggr_mode, "PerCore"))
+               return PerCore;
+       else if (!strcmp(aggr_mode, "PerChip"))
+               return PerChip;
+
+       pr_err("%s: Wrong AggregationMode value '%s'\n", prog, aggr_mode);
+       return -1;
+}
+
+static LIST_HEAD(sys_event_tables);
+
+struct sys_event_table {
+       struct list_head list;
+       char *soc_id;
+};
+
+static void free_sys_event_tables(void)
+{
+       struct sys_event_table *et, *next;
+
+       list_for_each_entry_safe(et, next, &sys_event_tables, list) {
+               free(et->soc_id);
+               free(et);
+       }
+}
+
 int eprintf(int level, int var, const char *fmt, ...)
 {
 
@@ -79,11 +123,6 @@ int eprintf(int level, int var, const char *fmt, ...)
        return ret;
 }
 
-__attribute__((weak)) char *get_cpu_str(void)
-{
-       return NULL;
-}
-
 static void addfield(char *map, char **dst, const char *sep,
                     const char *a, jsmntok_t *bt)
 {
@@ -145,7 +184,7 @@ static char *fixregex(char *s)
                return s;
 
        /* allocate space for a new string */
-       fixed = (char *) malloc(len + 1);
+       fixed = (char *) malloc(len + esc_count + 1);
        if (!fixed)
                return NULL;
 
@@ -174,23 +213,6 @@ static struct msrmap {
        { NULL, NULL }
 };
 
-static struct field {
-       const char *field;
-       const char *kernel;
-} fields[] = {
-       { "UMask",      "umask=" },
-       { "CounterMask", "cmask=" },
-       { "Invert",     "inv=" },
-       { "AnyThread",  "any=" },
-       { "EdgeDetect", "edge=" },
-       { "SampleAfterValue", "period=" },
-       { "FCMask",     "fc_mask=" },
-       { "PortMask",   "ch_mask=" },
-       { "L3ThreadMask", "l3_thread_mask=" },
-       { "L3SliceMask", "l3_slice_mask=" },
-       { NULL, NULL }
-};
-
 static void cut_comma(char *map, jsmntok_t *newval)
 {
        int i;
@@ -202,21 +224,6 @@ static void cut_comma(char *map, jsmntok_t *newval)
        }
 }
 
-static int match_field(char *map, jsmntok_t *field, int nz,
-                      char **event, jsmntok_t *val)
-{
-       struct field *f;
-       jsmntok_t newval = *val;
-
-       for (f = fields; f->field; f++)
-               if (json_streq(map, field, f->field) && nz) {
-                       cut_comma(map, &newval);
-                       addfield(map, event, ",", f->kernel, &newval);
-                       return 1;
-               }
-       return 0;
-}
-
 static struct msrmap *lookup_msr(char *map, jsmntok_t *val)
 {
        jsmntok_t newval = *val;
@@ -243,7 +250,15 @@ static struct map {
        { "QPI LL", "uncore_qpi" },
        { "SBO", "uncore_sbox" },
        { "iMPH-U", "uncore_arb" },
+       { "CPU-M-CF", "cpum_cf" },
+       { "CPU-M-SF", "cpum_sf" },
        { "UPI LL", "uncore_upi" },
+       { "hisi_sicl,cpa", "hisi_sicl,cpa"},
+       { "hisi_sccl,ddrc", "hisi_sccl,ddrc" },
+       { "hisi_sccl,hha", "hisi_sccl,hha" },
+       { "hisi_sccl,l3c", "hisi_sccl,l3c" },
+       /* it's not realistic to keep adding these, we need something more 
scalable ... */
+       { "imx8_ddr", "imx8_ddr" },
        { "L3PMC", "amd_l3" },
        { "DFPMC", "amd_df" },
        { "cpu_core", "cpu_core" },
@@ -301,7 +316,7 @@ static char *get_topic(void)
        return tp;
 }
 
-static int add_topic(const char *bname)
+static int add_topic(char *bname)
 {
        free(topic);
        topic = strdup(bname);
@@ -322,19 +337,15 @@ static int close_table;
 
 static void print_events_table_prefix(FILE *fp, const char *tblname)
 {
-       fprintf(fp, "static struct pmu_event %s[] = {\n", tblname);
+       fprintf(fp, "static const struct pmu_event %s[] = {\n", tblname);
        close_table = 1;
 }
 
-static int print_events_table_entry(void *data, char *name, const char *event,
-                                   char *desc, char *long_desc,
-                                   char *pmu, char *unit, char *perpkg,
-                                   char *metric_expr,
-                                   char *metric_name, char *metric_group)
+static int print_events_table_entry(void *data, struct json_event *je)
 {
        struct perf_entry_data *pd = data;
        FILE *outfp = pd->outfp;
-       char *etopic = pd->topic;
+       char *topic_local = pd->topic;
 
        /*
         * TODO: Remove formatting chars after debugging to reduce
@@ -342,26 +353,34 @@ static int print_events_table_entry(void *data, char 
*name, const char *event,
         */
        fprintf(outfp, "{\n");
 
-       if (name)
-               fprintf(outfp, "\t.name = \"%s\",\n", name);
-       if (event)
-               fprintf(outfp, "\t.event = \"%s\",\n", event);
-       fprintf(outfp, "\t.desc = \"%s\",\n", desc);
-       fprintf(outfp, "\t.topic = \"%s\",\n", etopic);
-       if (long_desc && long_desc[0])
-               fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc);
-       if (pmu)
-               fprintf(outfp, "\t.pmu = \"%s\",\n", pmu);
-       if (unit)
-               fprintf(outfp, "\t.unit = \"%s\",\n", unit);
-       if (perpkg)
-               fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg);
-       if (metric_expr)
-               fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr);
-       if (metric_name)
-               fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name);
-       if (metric_group)
-               fprintf(outfp, "\t.metric_group = \"%s\",\n", metric_group);
+       if (je->name)
+               fprintf(outfp, "\t.name = \"%s\",\n", je->name);
+       if (je->event)
+               fprintf(outfp, "\t.event = \"%s\",\n", je->event);
+       fprintf(outfp, "\t.desc = \"%s\",\n", je->desc);
+       if (je->compat)
+               fprintf(outfp, "\t.compat = \"%s\",\n", je->compat);
+       fprintf(outfp, "\t.topic = \"%s\",\n", topic_local);
+       if (je->long_desc && je->long_desc[0])
+               fprintf(outfp, "\t.long_desc = \"%s\",\n", je->long_desc);
+       if (je->pmu)
+               fprintf(outfp, "\t.pmu = \"%s\",\n", je->pmu);
+       if (je->unit)
+               fprintf(outfp, "\t.unit = \"%s\",\n", je->unit);
+       if (je->perpkg)
+               fprintf(outfp, "\t.perpkg = \"%s\",\n", je->perpkg);
+       if (je->aggr_mode)
+               fprintf(outfp, "\t.aggr_mode = \"%d\",\n", 
convert(je->aggr_mode));
+       if (je->metric_expr)
+               fprintf(outfp, "\t.metric_expr = \"%s\",\n", je->metric_expr);
+       if (je->metric_name)
+               fprintf(outfp, "\t.metric_name = \"%s\",\n", je->metric_name);
+       if (je->metric_group)
+               fprintf(outfp, "\t.metric_group = \"%s\",\n", je->metric_group);
+       if (je->deprecated)
+               fprintf(outfp, "\t.deprecated = \"%s\",\n", je->deprecated);
+       if (je->metric_constraint)
+               fprintf(outfp, "\t.metric_constraint = \"%s\",\n", 
je->metric_constraint);
        fprintf(outfp, "},\n");
 
        return 0;
@@ -371,27 +390,31 @@ struct event_struct {
        struct list_head list;
        char *name;
        char *event;
+       char *compat;
        char *desc;
        char *long_desc;
        char *pmu;
        char *unit;
        char *perpkg;
+       char *aggr_mode;
        char *metric_expr;
        char *metric_name;
        char *metric_group;
+       char *deprecated;
+       char *metric_constraint;
 };
 
-#define ADD_EVENT_FIELD(field) do { if (field) {               \
-       es->field = strdup(field);                              \
+#define ADD_EVENT_FIELD(field) do { if (je->field) {           \
+       es->field = strdup(je->field);                          \
        if (!es->field)                                         \
                goto out_free;                                  \
 } } while (0)
 
 #define FREE_EVENT_FIELD(field) free(es->field)
 
-#define TRY_FIXUP_FIELD(field) do { if (es->field && !*field) {\
-       *field = strdup(es->field);                             \
-       if (!*field)                                            \
+#define TRY_FIXUP_FIELD(field) do { if (es->field && !je->field) {\
+       je->field = strdup(es->field);                          \
+       if (!je->field)                                         \
                return -ENOMEM;                                 \
 } } while (0)
 
@@ -403,9 +426,11 @@ struct event_struct {
        op(pmu);                                                \
        op(unit);                                               \
        op(perpkg);                                             \
+       op(aggr_mode);                                          \
        op(metric_expr);                                        \
        op(metric_name);                                        \
        op(metric_group);                                       \
+       op(deprecated);                                         \
 } while (0)
 
 static LIST_HEAD(arch_std_events);
@@ -416,15 +441,12 @@ static void free_arch_std_events(void)
 
        list_for_each_entry_safe(es, next, &arch_std_events, list) {
                FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD);
-               list_del(&es->list);
+               list_del_init(&es->list);
                free(es);
        }
 }
 
-static int save_arch_std_events(void *data __unused, char *name, const char 
*event,
-                               char *desc, char *long_desc, char *pmu,
-                               char *unit, char *perpkg, char *metric_expr,
-                               char *metric_name, char *metric_group)
+static int save_arch_std_events(void *data __unused, struct json_event *je)
 {
        struct event_struct *es;
 
@@ -458,18 +480,19 @@ static struct fixed {
        const char *name;
        const char *event;
 } fixed[] = {
-       { "inst_retired.any", "event=0xc0" },
-       { "inst_retired.any_p", "event=0xc0" },
-       { "cpu_clk_unhalted.ref", "event=0x0,umask=0x03" },
-       { "cpu_clk_unhalted.thread", "event=0x3c" },
-       { "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" },
+       { "inst_retired.any", "event=0xc0,period=2000003" },
+       { "inst_retired.any_p", "event=0xc0,period=2000003" },
+       { "cpu_clk_unhalted.ref", "event=0x0,umask=0x03,period=2000003" },
+       { "cpu_clk_unhalted.thread", "event=0x3c,period=2000003" },
+       { "cpu_clk_unhalted.core", "event=0x3c,period=2000003" },
+       { "cpu_clk_unhalted.thread_any", "event=0x3c,any=1,period=2000003" },
        { NULL, NULL},
 };
 
 /*
  * Handle different fixed counter encodings between JSON and perf.
  */
-static const char *real_event(const char *name, char *event)
+static char *real_event(const char *name, char *event)
 {
        int i;
 
@@ -478,27 +501,20 @@ static const char *real_event(const char *name, char 
*event)
 
        for (i = 0; fixed[i].name; i++)
                if (!strcasecmp(name, fixed[i].name))
-                       return fixed[i].event;
+                       return (char *)fixed[i].event;
        return event;
 }
 
 static int
-try_fixup(const char *fn, char *arch_std, char **event, char **desc,
-         char **name, char **long_desc, char **pmu, char **filter __unused,
-         char **perpkg, char **unit, char **metric_expr, char **metric_name,
-         char **metric_group, unsigned long long eventcode)
+try_fixup(const char *fn, char *arch_std, struct json_event *je, char **event)
 {
        /* try to find matching event from arch standard values */
        struct event_struct *es;
 
        list_for_each_entry(es, &arch_std_events, list) {
                if (!strcmp(arch_std, es->name)) {
-                       if (!eventcode && es->event) {
-                               /* allow EventCode to be overridden */
-                               free(*event);
-                               *event = NULL;
-                       }
                        FOR_ALL_EVENT_STRUCT_FIELDS(TRY_FIXUP_FIELD);
+                       *event = je->event;
                        return 0;
                }
        }
@@ -509,13 +525,9 @@ try_fixup(const char *fn, char *arch_std, char **event, 
char **desc,
 }
 
 /* Call func with each event in the json file */
-int json_events(const char *fn,
-         int (*func)(void *data, char *name, const char *event, char *desc,
-                     char *long_desc,
-                     char *pmu, char *unit, char *perpkg,
-                     char *metric_expr,
-                     char *metric_name, char *metric_group),
-         void *data)
+static int json_events(const char *fn,
+               int (*func)(void *data, struct json_event *je),
+                       void *data)
 {
        int err;
        size_t size;
@@ -533,22 +545,26 @@ int json_events(const char *fn,
        EXPECT(tokens->type == JSMN_ARRAY, tokens, "expected top level array");
        tok = tokens + 1;
        for (i = 0; i < tokens->size; i++) {
-               char *event = NULL, *desc = NULL, *name = NULL;
-               char *long_desc = NULL;
+               char *event = NULL;
                char *extra_desc = NULL;
-               char *pmu = NULL;
                char *filter = NULL;
-               char *perpkg = NULL;
-               char *unit = NULL;
-               char *metric_expr = NULL;
-               char *metric_name = NULL;
-               char *metric_group = NULL;
+               struct json_event je = {};
                char *arch_std = NULL;
                unsigned long long eventcode = 0;
+               unsigned long long configcode = 0;
                struct msrmap *msr = NULL;
                jsmntok_t *msrval = NULL;
                jsmntok_t *precise = NULL;
                jsmntok_t *obj = tok++;
+               bool configcode_present = false;
+               char *umask = NULL;
+               char *cmask = NULL;
+               char *inv = NULL;
+               char *any = NULL;
+               char *edge = NULL;
+               char *period = NULL;
+               char *fc_mask = NULL;
+               char *ch_mask = NULL;
 
                EXPECT(obj->type == JSMN_OBJECT, obj, "expected object");
                for (j = 0; j < obj->size; j += 2) {
@@ -564,27 +580,50 @@ int json_events(const char *fn,
                               "Expected string value");
 
                        nz = !json_streq(map, val, "0");
-                       if (match_field(map, field, nz, &event, val)) {
-                               /* ok */
+                       /* match_field */
+                       if (json_streq(map, field, "UMask") && nz) {
+                               addfield(map, &umask, "", "umask=", val);
+                       } else if (json_streq(map, field, "CounterMask") && nz) 
{
+                               addfield(map, &cmask, "", "cmask=", val);
+                       } else if (json_streq(map, field, "Invert") && nz) {
+                               addfield(map, &inv, "", "inv=", val);
+                       } else if (json_streq(map, field, "AnyThread") && nz) {
+                               addfield(map, &any, "", "any=", val);
+                       } else if (json_streq(map, field, "EdgeDetect") && nz) {
+                               addfield(map, &edge, "", "edge=", val);
+                       } else if (json_streq(map, field, "SampleAfterValue") 
&& nz) {
+                               addfield(map, &period, "", "period=", val);
+                       } else if (json_streq(map, field, "FCMask") && nz) {
+                               addfield(map, &fc_mask, "", "fc_mask=", val);
+                       } else if (json_streq(map, field, "PortMask") && nz) {
+                               addfield(map, &ch_mask, "", "ch_mask=", val);
                        } else if (json_streq(map, field, "EventCode")) {
                                char *code = NULL;
                                addfield(map, &code, "", "", val);
                                eventcode |= strtoul(code, NULL, 0);
                                free(code);
+                       } else if (json_streq(map, field, "ConfigCode")) {
+                               char *code = NULL;
+                               addfield(map, &code, "", "", val);
+                               configcode |= strtoul(code, NULL, 0);
+                               free(code);
+                               configcode_present = true;
                        } else if (json_streq(map, field, "ExtSel")) {
                                char *code = NULL;
                                addfield(map, &code, "", "", val);
-                               eventcode |= strtoul(code, NULL, 0) << 21;
+                               eventcode |= strtoul(code, NULL, 0) << 8;
                                free(code);
                        } else if (json_streq(map, field, "EventName")) {
-                               addfield(map, &name, "", "", val);
+                               addfield(map, &je.name, "", "", val);
+                       } else if (json_streq(map, field, "Compat")) {
+                               addfield(map, &je.compat, "", "", val);
                        } else if (json_streq(map, field, "BriefDescription")) {
-                               addfield(map, &desc, "", "", val);
-                               fixdesc(desc);
+                               addfield(map, &je.desc, "", "", val);
+                               fixdesc(je.desc);
                        } else if (json_streq(map, field,
                                             "PublicDescription")) {
-                               addfield(map, &long_desc, "", "", val);
-                               fixdesc(long_desc);
+                               addfield(map, &je.long_desc, "", "", val);
+                               fixdesc(je.long_desc);
                        } else if (json_streq(map, field, "PEBS") && nz) {
                                precise = val;
                        } else if (json_streq(map, field, "MSRIndex") && nz) {
@@ -604,31 +643,32 @@ int json_events(const char *fn,
 
                                ppmu = field_to_perf(unit_to_pmu, map, val);
                                if (ppmu) {
-                                       pmu = strdup(ppmu);
+                                       je.pmu = strdup(ppmu);
                                } else {
-                                       if (!pmu)
-                                               pmu = strdup("uncore_");
-                                       addfield(map, &pmu, "", "", val);
-                                       for (s = pmu; *s; s++)
+                                       if (!je.pmu)
+                                               je.pmu = strdup("uncore_");
+                                       addfield(map, &je.pmu, "", "", val);
+                                       for (s = je.pmu; *s; s++)
                                                *s = tolower(*s);
                                }
-                               addfield(map, &desc, ". ", "Unit: ", NULL);
-                               addfield(map, &desc, "", pmu, NULL);
-                               addfield(map, &desc, "", " ", NULL);
                        } else if (json_streq(map, field, "Filter")) {
                                addfield(map, &filter, "", "", val);
                        } else if (json_streq(map, field, "ScaleUnit")) {
-                               addfield(map, &unit, "", "", val);
+                               addfield(map, &je.unit, "", "", val);
                        } else if (json_streq(map, field, "PerPkg")) {
-                               addfield(map, &perpkg, "", "", val);
+                               addfield(map, &je.perpkg, "", "", val);
+                       } else if (json_streq(map, field, "AggregationMode")) {
+                               addfield(map, &je.aggr_mode, "", "", val);
+                       } else if (json_streq(map, field, "Deprecated")) {
+                               addfield(map, &je.deprecated, "", "", val);
                        } else if (json_streq(map, field, "MetricName")) {
-                               addfield(map, &metric_name, "", "", val);
+                               addfield(map, &je.metric_name, "", "", val);
                        } else if (json_streq(map, field, "MetricGroup")) {
-                               addfield(map, &metric_group, "", "", val);
+                               addfield(map, &je.metric_group, "", "", val);
+                       } else if (json_streq(map, field, "MetricConstraint")) {
+                               addfield(map, &je.metric_constraint, "", "", 
val);
                        } else if (json_streq(map, field, "MetricExpr")) {
-                               addfield(map, &metric_expr, "", "", val);
-                               for (s = metric_expr; *s; s++)
-                                       *s = tolower(*s);
+                               addfield(map, &je.metric_expr, "", "", val);
                        } else if (json_streq(map, field, "ArchStdEvent")) {
                                addfield(map, &arch_std, "", "", val);
                                for (s = arch_std; *s; s++)
@@ -636,7 +676,7 @@ int json_events(const char *fn,
                        }
                        /* ignore unknown fields */
                }
-               if (precise && desc && !strstr(desc, "(Precise Event)")) {
+               if (precise && je.desc && !strstr(je.desc, "(Precise Event)")) {
                        if (json_streq(map, precise, "2"))
                                addfield(map, &extra_desc, " ",
                                                "(Must be precise)", NULL);
@@ -644,46 +684,80 @@ int json_events(const char *fn,
                                addfield(map, &extra_desc, " ",
                                                "(Precise event)", NULL);
                }
-               snprintf(buf, sizeof(buf), "event=%#llx", eventcode);
+               if (configcode_present)
+                       snprintf(buf, sizeof buf, "config=%#llx", configcode);
+               else
+                       snprintf(buf, sizeof buf, "event=%#llx", eventcode);
                addfield(map, &event, ",", buf, NULL);
-               if (desc && extra_desc)
-                       addfield(map, &desc, " ", extra_desc, NULL);
-               if (long_desc && extra_desc)
-                       addfield(map, &long_desc, " ", extra_desc, NULL);
+               if (any)
+                       addfield(map, &event, ",", any, NULL);
+               if (ch_mask)
+                       addfield(map, &event, ",", ch_mask, NULL);
+               if (cmask)
+                       addfield(map, &event, ",", cmask, NULL);
+               if (edge)
+                       addfield(map, &event, ",", edge, NULL);
+               if (fc_mask)
+                       addfield(map, &event, ",", fc_mask, NULL);
+               if (inv)
+                       addfield(map, &event, ",", inv, NULL);
+               if (period)
+                       addfield(map, &event, ",", period, NULL);
+               if (umask)
+                       addfield(map, &event, ",", umask, NULL);
+
+               if (je.desc && extra_desc)
+                       addfield(map, &je.desc, " ", extra_desc, NULL);
+               if (je.long_desc && extra_desc)
+                       addfield(map, &je.long_desc, " ", extra_desc, NULL);
+               if (je.pmu) {
+                       addfield(map, &je.desc, ". ", "Unit: ", NULL);
+                       addfield(map, &je.desc, "", je.pmu, NULL);
+                       addfield(map, &je.desc, "", " ", NULL);
+               }
                if (filter)
                        addfield(map, &event, ",", filter, NULL);
                if (msr != NULL)
                        addfield(map, &event, ",", msr->pname, msrval);
-               if (name)
-                       fixname(name);
+               if (je.name)
+                       fixname(je.name);
 
                if (arch_std) {
                        /*
                         * An arch standard event is referenced, so try to
                         * fixup any unassigned values.
                         */
-                       err = try_fixup(fn, arch_std, &event, &desc, &name,
-                                       &long_desc, &pmu, &filter, &perpkg,
-                                       &unit, &metric_expr, &metric_name,
-                                       &metric_group, eventcode);
+                       err = try_fixup(fn, arch_std, &je, &event);
                        if (err)
                                goto free_strings;
                }
-               err = func(data, name, real_event(name, event), desc, long_desc,
-                          pmu, unit, perpkg, metric_expr, metric_name, 
metric_group);
+               je.event = real_event(je.name, event);
+               err = func(data, &je);
 free_strings:
+               free(umask);
+               free(cmask);
+               free(inv);
+               free(any);
+               free(edge);
+               free(period);
+               free(fc_mask);
+               free(ch_mask);
                free(event);
-               free(desc);
-               free(name);
-               free(long_desc);
+               free(je.desc);
+               free(je.name);
+               free(je.compat);
+               free(je.long_desc);
                free(extra_desc);
-               free(pmu);
+               free(je.pmu);
                free(filter);
-               free(perpkg);
-               free(unit);
-               free(metric_expr);
-               free(metric_name);
-               free(metric_group);
+               free(je.perpkg);
+               free(je.aggr_mode);
+               free(je.deprecated);
+               free(je.unit);
+               free(je.metric_expr);
+               free(je.metric_name);
+               free(je.metric_group);
+               free(je.metric_constraint);
                free(arch_std);
 
                if (err)
@@ -697,14 +771,13 @@ out_free:
        return err;
 }
 
-static char *file_name_to_table_name(const char *fname)
+static char *file_name_to_table_name(char *fname)
 {
        unsigned int i;
        int n;
        int c;
        char *tblname;
 
-
        /*
         * Ensure tablename starts with alphabetic character.
         * Derive rest of table name from basename of the JSON file,
@@ -726,11 +799,9 @@ static char *file_name_to_table_name(const char *fname)
                        tblname[i] = '\0';
                        break;
                } else if (!isalnum(c) && c != '_') {
-                       char *tmp = strdup(fname);
-                       pr_err("%s: Invalid character '%c' in file name %s\n",
-                                       prog, c, basename(tmp));
+                       pr_err("%s: Invalid character '%c' in file name '%s'\n",
+                                       prog, c, fname);
                        free(tblname);
-                       free(tmp);
                        tblname = NULL;
                        break;
                }
@@ -739,9 +810,18 @@ static char *file_name_to_table_name(const char *fname)
        return tblname;
 }
 
+static bool is_sys_dir(char *fname)
+{
+       size_t len = strlen(fname), len2 = strlen("/sys");
+
+       if (len2 > len)
+               return false;
+       return !strcmp(fname+len-len2, "/sys");
+}
+
 static void print_mapping_table_prefix(FILE *outfp)
 {
-       fprintf(outfp, "struct pmu_events_map pmu_events_map[] = {\n");
+       fprintf(outfp, "const struct pmu_events_map pmu_events_map[] = {\n");
 }
 
 static void print_mapping_table_suffix(FILE *outfp)
@@ -760,6 +840,47 @@ static void print_mapping_table_suffix(FILE *outfp)
        fprintf(outfp, "};\n");
 }
 
+static void print_mapping_test_table(FILE *outfp)
+{
+       /*
+        * Print the terminating, NULL entry.
+        */
+       fprintf(outfp, "{\n");
+       fprintf(outfp, "\t.cpuid = \"testcpu\",\n");
+       fprintf(outfp, "\t.version = \"v1\",\n");
+       fprintf(outfp, "\t.type = \"core\",\n");
+       fprintf(outfp, "\t.table = pme_test_soc_cpu,\n");
+       fprintf(outfp, "},\n");
+}
+
+static void print_system_event_mapping_table_prefix(FILE *outfp)
+{
+       fprintf(outfp, "\nconst struct pmu_sys_events pmu_sys_event_tables[] = 
{");
+}
+
+static void print_system_event_mapping_table_suffix(FILE *outfp)
+{
+       fprintf(outfp, "\n\t{\n\t\t.table = 0\n\t},");
+       fprintf(outfp, "\n};\n");
+}
+
+static int process_system_event_tables(FILE *outfp)
+{
+       struct sys_event_table *sys_event_table;
+
+       print_system_event_mapping_table_prefix(outfp);
+
+       list_for_each_entry(sys_event_table, &sys_event_tables, list) {
+               fprintf(outfp, "\n\t{\n\t\t.table = %s,\n\t\t.name = 
\"%s\",\n\t},",
+                       sys_event_table->soc_id,
+                       sys_event_table->soc_id);
+       }
+
+       print_system_event_mapping_table_suffix(outfp);
+
+       return 0;
+}
+
 static int process_mapfile(FILE *outfp, char *fpath)
 {
        int n = 16384;
@@ -768,6 +889,7 @@ static int process_mapfile(FILE *outfp, char *fpath)
        char *line, *p;
        int line_num;
        char *tblname;
+       int ret = 0;
 
        pr_info("%s: Processing mapfile %s\n", prog, fpath);
 
@@ -806,9 +928,8 @@ static int process_mapfile(FILE *outfp, char *fpath)
                        /* TODO Deal with lines longer than 16K */
                        pr_info("%s: Mapfile %s: line %d too long, aborting\n",
                                        prog, fpath, line_num);
-                       free(line);
-                       fclose(mapfp);
-                       return -1;
+                       ret = -1;
+                       goto out;
                }
                line[strlen(line)-1] = '\0';
 
@@ -837,10 +958,11 @@ static int process_mapfile(FILE *outfp, char *fpath)
        }
 
 out:
+       print_mapping_test_table(outfp);
        print_mapping_table_suffix(outfp);
-       free(line);
        fclose(mapfp);
-       return 0;
+       free(line);
+       return ret;
 }
 
 /*
@@ -864,6 +986,8 @@ static void create_empty_mapping(const char *output_file)
        fprintf(outfp, "#include \"pmu-events/pmu-events.h\"\n");
        print_mapping_table_prefix(outfp);
        print_mapping_table_suffix(outfp);
+       print_system_event_mapping_table_prefix(outfp);
+       print_system_event_mapping_table_suffix(outfp);
        fclose(outfp);
 }
 
@@ -908,8 +1032,7 @@ static int is_leaf_dir(const char *fpath)
                        char path[PATH_MAX];
                        struct stat st;
 
-                       snprintf(path, sizeof(path), "%s/%s", fpath,
-                           dir->d_name);
+                       snprintf(path, sizeof(path), "%s/%s", fpath, 
dir->d_name);
                        if (stat(path, &st))
                                break;
*** 441 LINES SKIPPED ***

Reply via email to