diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
index de7efa2cebd1..e940cef73d2b 100644
--- a/tools/perf/pmu-events/README
+++ b/tools/perf/pmu-events/README
@@ -1,6 +1,7 @@
 
 The contents of this directory allow users to specify PMU events in their
-CPUs by their symbolic names rather than raw event codes (see example below).
+CPUs or other PMUs in the system by their symbolic names rather than raw
+event codes (see example below).
 
 The main program in this directory, is the 'jevents', which is built and
 executed _BEFORE_ the perf binary itself is built.
@@ -12,7 +13,12 @@ tree tools/perf/pmu-events/arch/foo.
 	  JSON files, each of which describes a set of PMU events.
 
 	- The CSV file that maps a specific CPU to its set of PMU events is to
-	  be named 'mapfile.csv' (see below for mapfile format).
+	  be named 'mapfile.csv'.
+
+	  An additional optional CSV file maps specific PMU to its set of PMU
+	  events is to be named 'mapfile_sys.csv'.
+
+	  See below for mapfile formats.
 
 	- Directories are traversed, but all other files are ignored.
 
@@ -22,10 +28,10 @@ tree tools/perf/pmu-events/arch/foo.
 	  Architecture standard JSONs must be located in the architecture root
 	  folder. Matching is based on the "EventName" field.
 
-The PMU events supported by a CPU model are expected to grouped into topics
-such as Pipelining, Cache, Memory, Floating-point etc. All events for a topic
-should be placed in a separate JSON file - where the file name identifies
-the topic. Eg: "Floating-point.json".
+The PMU events supported by a CPU model or PMU are expected to grouped into
+topics such as Pipelining, Cache, Memory, Floating-point etc. All events for
+a topic should be placed in a separate JSON file - where the file name
+identifies the topic. Eg: "Floating-point.json".
 
 All the topic JSON files for a CPU model/family should be in a separate
 sub directory. Thus for the Silvermont X86 CPU:
@@ -38,7 +44,11 @@ The JSONs folder for a CPU model/family may be placed in the root arch
 folder, or may be placed in a vendor sub-folder under the arch folder
 for instances where the arch and vendor are not the same.
 
-Using the JSON files and the mapfile, 'jevents' generates the C source file,
+The JSONS folder for a system PMU should be placed in a subfolder for
+the platform, separate to the CPU events folder. The reason is that different
+matching mechanism could be used for detecting CPU and system PMUs.
+
+Using the JSON files and the mapfile(s), 'jevents' generates the C source file,
 'pmu-events.c', which encodes the two sets of tables:
 
 	- Set of 'PMU events tables' for all known CPUs in the architecture,
@@ -83,11 +93,11 @@ NOTES:
 	2. The 'pmu-events.h' has an extern declaration for the mapping table
 	   and the generated 'pmu-events.c' defines this table.
 
-	3. _All_ known CPU tables for architecture are included in the perf
-	   binary.
+	3. _All_ known CPU and system tables for architecture are included in
+	   the perf binary.
 
-At run time, perf determines the actual CPU it is running on, finds the
-matching events table and builds aliases for those events. This allows
+At run time, perf determines the actual CPU or system it is running on, finds
+the matching events table and builds aliases for those events. This allows
 users to specify events by their name:
 
 	$ perf stat -e pm_1plus_ppc_cmpl sleep 1
@@ -150,3 +160,18 @@ where:
 
 	i.e the three CPU models use the JSON files (i.e PMU events) listed
 	in the directory 'tools/perf/pmu-events/arch/x86/silvermont'.
+
+The mapfile_sys.csv format is slightly different, in that it contains a SYSID
+instead of the CPUID:
+
+	Header line
+	SYSID,Version,Dir/path/name,Type
+
+where, same as mapfile.csv, except:
+
+	SYSID:
+		SYSID is a platform specific char string, that can be used
+		to identify thr system.
+
+	Type:
+		Should always be sys
diff --git a/tools/perf/pmu-events/arch/arm64/mapfile_sys.csv b/tools/perf/pmu-events/arch/arm64/mapfile_sys.csv
new file mode 100644
index 000000000000..701d8ff67354
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/mapfile_sys.csv
@@ -0,0 +1,13 @@
+# Format:
+#	SYS ID,Version,JSON/file/pathname,Type
+#
+# where
+#	SYS ID	Unique identifier for the system
+#		Could be DT machine ID, ACPI OEM ID, etc
+#	Version could be used to track version of of JSON file
+#		but currently unused.
+#	JSON/file/pathname is the path to JSON file, relative
+#		to tools/perf/pmu-events/arch/arm64/.
+#	Type is sys
+#
+#Family-model,Version,Filename,EventType
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 8af05b94a37d..da6430c0d184 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -755,6 +755,7 @@ static void print_mapping_table_suffix(FILE *outfp)
 	 */
 	fprintf(outfp, "{\n");
 	fprintf(outfp, "\t.cpuid = 0,\n");
+	fprintf(outfp, "\t.sysid = 0,\n");
 	fprintf(outfp, "\t.version = 0,\n");
 	fprintf(outfp, "\t.type = 0,\n");
 	fprintf(outfp, "\t.table = 0,\n");
@@ -771,7 +772,7 @@ static int process_mapfile(FILE *outfp, char *fpath)
 	char *save = NULL;
 	char *line, *p;
 	int line_num;
-	char *tblname;
+	char *tblname, *table_id;
 	int ret = 0;
 
 	pr_info("%s: Processing mapfile %s\n", prog, fpath);
@@ -788,8 +789,6 @@ static int process_mapfile(FILE *outfp, char *fpath)
 		return -1;
 	}
 
-	print_mapping_table_prefix(outfp);
-
 	/* Skip first line (header) */
 	p = fgets(line, n, mapfp);
 	if (!p)
@@ -797,7 +796,7 @@ static int process_mapfile(FILE *outfp, char *fpath)
 
 	line_num = 1;
 	while (1) {
-		char *cpuid, *version, *type, *fname;
+		char *id, *version, *type, *fname;
 
 		line_num++;
 		p = fgets(line, n, mapfp);
@@ -816,14 +815,21 @@ static int process_mapfile(FILE *outfp, char *fpath)
 		}
 		line[strlen(line)-1] = '\0';
 
-		cpuid = fixregex(strtok_r(p, ",", &save));
+		id = fixregex(strtok_r(p, ",", &save));
 		version = strtok_r(NULL, ",", &save);
 		fname = strtok_r(NULL, ",", &save);
 		type = strtok_r(NULL, ",", &save);
 
+		/* We treat uncore as "cpu" events */
+		if (!strcmp(type, "core") || !strcmp(type, "uncore"))
+			table_id = "cpuid";
+		else if (!strcmp(type, "sys"))
+			table_id = "sysid";
+		else
+			table_id = "unknown";
 		tblname = file_name_to_table_name(fname);
 		fprintf(outfp, "{\n");
-		fprintf(outfp, "\t.cpuid = \"%s\",\n", cpuid);
+		fprintf(outfp, "\t.%s = \"%s\",\n", table_id, id);
 		fprintf(outfp, "\t.version = \"%s\",\n", version);
 		fprintf(outfp, "\t.type = \"%s\",\n", type);
 
@@ -841,12 +847,36 @@ static int process_mapfile(FILE *outfp, char *fpath)
 	}
 
 out:
-	print_mapping_table_suffix(outfp);
 	fclose(mapfp);
 	free(line);
 	return ret;
 }
 
+static int process_mapfiles(FILE *outfp, char *fpath, char *fpath_sys)
+{
+	char *save = NULL;
+	int line_num;
+	char *tblname;
+	char *table_id;
+	int ret;
+
+	pr_info("%s: Processing mapfiles %s fpath_sys=%s\n", prog, fpath, fpath_sys);
+
+	print_mapping_table_prefix(outfp);
+
+	ret = process_mapfile(outfp, fpath);
+	if (ret)
+		goto out;
+
+	if (fpath_sys)
+		ret = process_mapfile(outfp, fpath_sys);
+
+out:
+	print_mapping_table_suffix(outfp);
+
+	return ret;
+}
+
 /*
  * If we fail to locate/process JSON and map files, create a NULL mapping
  * table. This would at least allow perf to build even if we can't find/use
@@ -887,6 +917,7 @@ static int get_maxfds(void)
  */
 static FILE *eventsfp;
 static char *mapfile;
+static char *mapfile_sys;
 
 static int is_leaf_dir(const char *fpath)
 {
@@ -1024,6 +1055,11 @@ static int process_one_file(const char *fpath, const struct stat *sb,
 			return 0;
 		}
 
+		if (!strcmp(bname, "mapfile_sys.csv")) {
+			mapfile_sys = strdup(fpath);
+			return 0;
+		}
+
 		pr_info("%s: Ignoring file %s\n", prog, fpath);
 		return 0;
 	}
@@ -1174,7 +1210,7 @@ int main(int argc, char *argv[])
 		goto empty_map;
 	}
 
-	if (process_mapfile(eventsfp, mapfile)) {
+	if (process_mapfiles(eventsfp, mapfile, mapfile_sys)) {
 		pr_info("%s: Error processing mapfile %s\n", prog, mapfile);
 		/* Make build fail */
 		fclose(eventsfp);
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
index caeb577d36c9..9964bdd2f6e1 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -31,6 +31,7 @@ struct pmu_event {
  */
 struct pmu_events_map {
 	const char *cpuid;
+	const char *sysid;
 	const char *version;
 	const char *type;		/* core, uncore etc */
 	struct pmu_event *table;
