summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xREADME_Streamline.txt51
-rw-r--r--daemon/Android.mk6
-rw-r--r--daemon/Application.mk1
-rw-r--r--daemon/Buffer.cpp36
-rw-r--r--daemon/Buffer.h11
-rw-r--r--daemon/CapturedXML.cpp11
-rw-r--r--daemon/CapturedXML.h2
-rw-r--r--daemon/Child.cpp45
-rw-r--r--daemon/Child.h2
-rw-r--r--daemon/ConfigurationXML.cpp10
-rw-r--r--daemon/Counter.h4
-rw-r--r--daemon/DriverSource.cpp53
-rw-r--r--daemon/DriverSource.h5
-rw-r--r--daemon/EventsXML.cpp16
-rw-r--r--daemon/EventsXML.h5
-rw-r--r--daemon/ExternalSource.cpp177
-rw-r--r--daemon/ExternalSource.h11
-rw-r--r--daemon/FSDriver.cpp212
-rw-r--r--daemon/FSDriver.h44
-rw-r--r--daemon/Fifo.h2
-rw-r--r--daemon/Hwmon.cpp16
-rw-r--r--daemon/KMod.cpp11
-rw-r--r--daemon/LocalCapture.h2
-rw-r--r--daemon/Logging.h2
-rw-r--r--daemon/Makefile8
-rw-r--r--daemon/Makefile_aarch649
-rw-r--r--daemon/MaliVideoDriver.cpp253
-rw-r--r--daemon/MaliVideoDriver.h50
-rw-r--r--daemon/Monitor.cpp11
-rw-r--r--daemon/Monitor.h1
-rw-r--r--daemon/OlySocket.cpp77
-rw-r--r--daemon/OlySocket.h14
-rw-r--r--daemon/PerfDriver.cpp92
-rw-r--r--daemon/PerfDriver.h6
-rw-r--r--daemon/PerfGroup.cpp28
-rw-r--r--daemon/PerfGroup.h2
-rw-r--r--daemon/PerfSource.cpp14
-rw-r--r--daemon/Proc.cpp106
-rw-r--r--daemon/Proc.h2
-rw-r--r--daemon/Sender.h2
-rw-r--r--daemon/SessionData.cpp55
-rw-r--r--daemon/SessionData.h17
-rw-r--r--daemon/SessionXML.cpp8
-rw-r--r--daemon/StreamlineSetup.cpp2
-rw-r--r--daemon/StreamlineSetup.h4
-rw-r--r--daemon/UEvent.cpp6
-rw-r--r--daemon/UserSpaceSource.cpp14
-rw-r--r--daemon/UserSpaceSource.h2
-rw-r--r--daemon/c++.cpp40
-rw-r--r--daemon/common.mk16
-rw-r--r--daemon/defaults.xml5
-rw-r--r--daemon/escape.c2
-rw-r--r--daemon/events-CCI-400.xml21
-rw-r--r--daemon/events-CCN-504.xml9
-rw-r--r--daemon/events-Cortex-A53.xml84
-rw-r--r--daemon/events-Cortex-A57.xml84
-rw-r--r--daemon/events-Filesystem.xml11
-rw-r--r--daemon/events-L2C-310.xml30
-rw-r--r--daemon/events-Linux.xml5
-rw-r--r--daemon/events-Mali-4xx.xml126
-rw-r--r--daemon/events-Mali-T6xx.xml26
-rw-r--r--daemon/events-Mali-T6xx_hw.xml33
-rw-r--r--daemon/events-Mali-V500.xml29
-rw-r--r--daemon/main.cpp260
-rw-r--r--driver/Makefile15
-rw-r--r--driver/gator.h6
-rw-r--r--driver/gator_backtrace.c2
-rw-r--r--driver/gator_buffer.c6
-rw-r--r--driver/gator_events_armv7.c4
-rw-r--r--driver/gator_events_block.c12
-rw-r--r--driver/gator_events_mali_4xx.c144
-rw-r--r--driver/gator_events_mali_common.c36
-rw-r--r--driver/gator_events_mali_common.h20
-rw-r--r--driver/gator_events_mali_t6xx.c5
-rw-r--r--driver/gator_events_mali_t6xx_hw.c183
-rw-r--r--driver/gator_events_mmapped.c26
-rw-r--r--driver/gator_events_perf_pmu.c6
-rw-r--r--driver/gator_events_scorpion.c4
-rw-r--r--driver/gator_events_threads.c115
-rw-r--r--driver/gator_iks.c2
-rw-r--r--driver/gator_main.c77
-rw-r--r--driver/gator_marshaling.c101
-rw-r--r--driver/gator_trace_gpu.c142
-rw-r--r--driver/gator_trace_power.c4
-rw-r--r--driver/gator_trace_sched.c85
-rw-r--r--driver/mali/mali_dd_gator_api.h40
-rw-r--r--driver/mali_t6xx.mk4
87 files changed, 2281 insertions, 1057 deletions
diff --git a/README_Streamline.txt b/README_Streamline.txt
index df3f923..54791c0 100755
--- a/README_Streamline.txt
+++ b/README_Streamline.txt
@@ -2,7 +2,7 @@
2*** Purpose *** 2*** Purpose ***
3 3
4Instructions on setting up ARM Streamline on the target. 4Instructions on setting up ARM Streamline on the target.
5The gator driver and gator daemon are required to run on the ARM Linux target in order for ARM Streamline to operate. A new early access feature allows the gator daemon can run without the gator driver by using userspace APIs with reduced functionality when using Linux 3.12 or later. 5The gator driver and gator daemon are required to run on the ARM Linux target in order for ARM Streamline to operate. A new early access feature allows the gator daemon can run without the gator driver by using userspace APIs with reduced functionality when using Linux 3.4 or later.
6The driver should be built as a module and the daemon must run with root permissions on the target. 6The driver should be built as a module and the daemon must run with root permissions on the target.
7 7
8*** Introduction *** 8*** Introduction ***
@@ -14,7 +14,7 @@ A Linux development environment with cross compiling tools is most likely requir
14 -First, check if the kernel has the proper configuration options (see below). Profiling cannot occur using a kernel that is not configured properly, a new kernel must be created. See if /proc/config.gz exists on the target. 14 -First, check if the kernel has the proper configuration options (see below). Profiling cannot occur using a kernel that is not configured properly, a new kernel must be created. See if /proc/config.gz exists on the target.
15 -Second, given a properly configured kernel, check if the filesystem contains the kernel source/headers, which can be used to re-create the gator driver. These files may be located in different areas, but common locations are /lib/modules/ and /usr/src. 15 -Second, given a properly configured kernel, check if the filesystem contains the kernel source/headers, which can be used to re-create the gator driver. These files may be located in different areas, but common locations are /lib/modules/ and /usr/src.
16 -If the kernel is not properly configured or sources/headers are not available, the developer is on their own and kernel creation is beyond the scope of this document. Note: It is possible for a module to work when compiled against a similar kernel source code, though this is not guaranteed to work due to differences in kernel structures, exported symbols and incompatible configuration parameters. 16 -If the kernel is not properly configured or sources/headers are not available, the developer is on their own and kernel creation is beyond the scope of this document. Note: It is possible for a module to work when compiled against a similar kernel source code, though this is not guaranteed to work due to differences in kernel structures, exported symbols and incompatible configuration parameters.
17 -If the target is running Linux 3.12 or later the kernel driver is not required and userspace APIs will be used instead. 17 -If the target is running Linux 3.4 or later the kernel driver is not required and userspace APIs will be used instead.
18 18
19*** Kernel configuration *** 19*** Kernel configuration ***
20 20
@@ -59,8 +59,7 @@ If a device tree is used it must include the pmu bindings, see Documentation/dev
59*** Building the gator module *** 59*** Building the gator module ***
60 60
61To create the gator.ko module, 61To create the gator.ko module,
62 cd /path/to/gator/driver-src 62 tar xzf /path/to/DS-5/arm/gator/driver-src/gator-driver.tar.gz
63 tar xzf gator-driver.tar.gz
64 cd gator-driver 63 cd gator-driver
65 make -C <kernel_build_dir> M=`pwd` ARCH=arm CROSS_COMPILE=<...> modules 64 make -C <kernel_build_dir> M=`pwd` ARCH=arm CROSS_COMPILE=<...> modules
66for example when using the linaro-toolchain-binaries 65for example when using the linaro-toolchain-binaries
@@ -78,10 +77,14 @@ Edit Kconfig in the kernel drivers folder and add this before the last endmenu
78 source "drivers/gator/Kconfig" 77 source "drivers/gator/Kconfig"
79You can now select gator when using menuconfig while configuring the kernel and rebuild as directed 78You can now select gator when using menuconfig while configuring the kernel and rebuild as directed
80 79
80*** Use the prebuilt gator daemon ***
81
82A prebuilt gator daemon is provided at /path/to/DS-5/arm/gator/gatord. This gator daemon should work in most cases so building the gator daemon is only required if the prebuilt gator daemon doesn't work.
83To improve portablility gatord is statically compiled against musl libc from http://www.musl-libc.org/releases/musl-1.0.2.tar.gz instead of glibc. The gator daemon will work correctly with either glibc or musl.
84
81*** Building the gator daemon *** 85*** Building the gator daemon ***
82 86
83cd /path/to/gator/daemon-src 87tar -xzf /path/to/DS-5/arm/gator/daemon-src/gator-daemon.tar.gz
84tar -xzf gator-daemon.tar.gz (may need to issue with 'sudo')
85For Linux targets, 88For Linux targets,
86 cd gator-daemon 89 cd gator-daemon
87 make CROSS_COMPILE=<...> # For ARMv7 targets 90 make CROSS_COMPILE=<...> # For ARMv7 targets
@@ -105,7 +108,7 @@ gator.ko must be located in the same directory as gatord on the target or the lo
105With root privileges, run the daemon 108With root privileges, run the daemon
106 sudo ./gatord & 109 sudo ./gatord &
107Note: gatord requires libstdc++.so.6 which is usually supplied by the Linux distribution on the target. A copy of libstdc++.so.6 is available in the DS-5 Linux example distribution. 110Note: gatord requires libstdc++.so.6 which is usually supplied by the Linux distribution on the target. A copy of libstdc++.so.6 is available in the DS-5 Linux example distribution.
108If gator.ko is not loaded and is not in the same directory as gatord when using Linux 3.12 or later, gatord can run without gator.ko by using userspace APIs. Not all features are supported by userspace gator. If /dev/gator/version does not exist after starting gatord it is running userspace gator. 111If gator.ko is not loaded and is not in the same directory as gatord when using Linux 3.4 or later, gatord can run without gator.ko by using userspace APIs. Not all features are supported by userspace gator. If /dev/gator/version does not exist after starting gatord it is running userspace gator.
109 112
110*** Customizing the l2c-310 Counter *** 113*** Customizing the l2c-310 Counter ***
111 114
@@ -123,7 +126,7 @@ CCN-504 is disabled by default. To enable CCN-504, insmod gator module with the
123Recommended compiler settings: 126Recommended compiler settings:
124 "-g": Debug information, such as line numbers, needed for best analysis results. 127 "-g": Debug information, such as line numbers, needed for best analysis results.
125 "-fno-inline": Speed improvement when processing the image files and most accurate analysis results. 128 "-fno-inline": Speed improvement when processing the image files and most accurate analysis results.
126 "-fno-omit-frame-pointer": ARM EABI frame pointers (Code Sourcery cross compiler) allow recording of the call stack with each sample taken when in ARM state (i.e. not -mthumb). 129 "-fno-omit-frame-pointer": ARM EABI frame pointers allow recording of the call stack with each sample taken when in ARM state (i.e. not -mthumb).
127 "-marm": This option is required if your compiler is configured with --with-mode=thumb, otherwise call stack unwinding will not work. 130 "-marm": This option is required if your compiler is configured with --with-mode=thumb, otherwise call stack unwinding will not work.
128 131
129*** Hardfloat EABI *** 132*** Hardfloat EABI ***
@@ -132,6 +135,35 @@ To compile for non-hardfloat targets it is necessary to add options '-marm -marc
132The armv5t_mtx filesystem is provided as part of the "DS-5 Linux Example Distribution" package which can be downloaded from the DS-5 Downloads page. 135The armv5t_mtx filesystem is provided as part of the "DS-5 Linux Example Distribution" package which can be downloaded from the DS-5 Downloads page.
133Attempting to run an incompatible binary often results in the confusing error message "No such file or directory" when clearly the file exists. 136Attempting to run an incompatible binary often results in the confusing error message "No such file or directory" when clearly the file exists.
134 137
138*** Mali GPU ***
139
140Streamline supports Mali-400, 450, T6xx, and T7xx series GPUs with hardware activity charts, hardware & software counters and an optional 'film strip' showing periodic framebuffer snapshots. Support is chosen at build time and only one type of GPU (and version of driver) is supported at once. For best results build gator in-tree at .../drivers/gator and use the menuconfig options. Details of what these mean or how to build out of tree below.
141
142Mali-4xx:
143 ___To add Mali-4xx support to gator___
144 GATOR_WITH_MALI_SUPPORT=MALI_4xx # Set by CONFIG_GATOR_MALI_4XXMP
145 CONFIG_GATOR_MALI_PATH=".../path/to/Mali_DDK_kernel_files/src/devicedrv/mali" # gator source needs to #include "linux/mali_linux_trace.h"
146 GATOR_MALI_INTERFACE_STYLE=<3|4> # 3=Mali-400 DDK >= r3p0-04rel0 and < r3p2-01rel3
147 # 4=Mali-400 DDK >= r3p2-01rel3
148 # (default of 4 set in gator-driver/gator_events_mali_4xx.c)
149 ___To add the corresponding support to Mali___
150 Userspace needs MALI_TIMELINE_PROFILING_ENABLED=1 MALI_FRAMEBUFFER_DUMP_ENABLED=1 MALI_SW_COUNTERS_ENABLED=1
151 Kernel driver needs USING_PROFILING=1 # Sets CONFIG_MALI400_PROFILING=y
152 See the DDK integration guide for more details (the above are the default in later driver versions)
153
154Mali-T6xx/T7xx:
155 ___To add Mali-T6xx support to gator___
156 GATOR_WITH_MALI_SUPPORT=MALI_T6xx # Set by CONFIG_GATOR_MALI_T6XX
157 DDK_DIR=".../path/to/Mali_DDK_kernel_files" # gator source needs access to headers under .../kernel/drivers/gpu/arm/...
158 # (default of . suitable for in-tree builds)
159 ___To add the corresponding support to Mali___
160 Userspace (scons) needs gator=1
161 Kernel driver needs CONFIG_MALI_GATOR_SUPPORT=y
162 See the DDK integration guide for more details
163
164*** Polling /dev, /sys and /proc files ***
165Gator supports reading arbitrary /dev, /sys and /proc files 10 times a second. It will either interpret the file contents as a number or use a POSIX extended regex to extract the number, see events-Filesystem.xml for examples.
166
135*** Bugs *** 167*** Bugs ***
136 168
137There is a bug in some Linux kernels where perf misidentifies the CPU type. To see if you are affected by this, run ls /sys/bus/event_source/devices/ and verify the listed processor type matches what is expected. For example, an A9 should show the following. 169There is a bug in some Linux kernels where perf misidentifies the CPU type. To see if you are affected by this, run ls /sys/bus/event_source/devices/ and verify the listed processor type matches what is expected. For example, an A9 should show the following.
@@ -139,7 +171,7 @@ There is a bug in some Linux kernels where perf misidentifies the CPU type. To s
139 ARMv7_Cortex_A9 breakpoint software tracepoint 171 ARMv7_Cortex_A9 breakpoint software tracepoint
140To work around the issue try upgrading to a later kernel or comment out the gator_events_perf_pmu_cpu_init(gator_cpu, type); call in gator_events_perf_pmu.c 172To work around the issue try upgrading to a later kernel or comment out the gator_events_perf_pmu_cpu_init(gator_cpu, type); call in gator_events_perf_pmu.c
141 173
142There is a bug in some Linux kernels where an Oops may occurs when using userspace gator and a core is offlined. The fix was merged into mainline in 3.14-rc5, see http://git.kernel.org/tip/e3703f8cdfcf39c25c4338c3ad8e68891cca3731, and as been backported to older kernels. 174There is a bug in some Linux kernels where an Oops may occur when using userspace gator and a core is offlined. The fix was merged into mainline in 3.14-rc5, see http://git.kernel.org/tip/e3703f8cdfcf39c25c4338c3ad8e68891cca3731, and as been backported to older kernels.
143 175
144If you see this error when using SELinux, ex: Android 4.4 or later 176If you see this error when using SELinux, ex: Android 4.4 or later
145 # ./gatord 177 # ./gatord
@@ -172,3 +204,4 @@ update-rc.d rungator.sh defaults
172*** GPL License *** 204*** GPL License ***
173 205
174For license information, please see the file LICENSE after unzipping driver-src/gator-driver.tar.gz. 206For license information, please see the file LICENSE after unzipping driver-src/gator-driver.tar.gz.
207The prebuilt gatord uses musl from http://www.musl-libc.org/releases/musl-1.0.2.tar.gz for musl license information see the COPYRIGHT file in the musl tar file.
diff --git a/daemon/Android.mk b/daemon/Android.mk
index 045d028..44c069c 100644
--- a/daemon/Android.mk
+++ b/daemon/Android.mk
@@ -3,7 +3,7 @@ include $(CLEAR_VARS)
3 3
4XML_H := $(shell cd $(LOCAL_PATH) && make events_xml.h defaults_xml.h) 4XML_H := $(shell cd $(LOCAL_PATH) && make events_xml.h defaults_xml.h)
5 5
6LOCAL_CFLAGS += -Wall -O3 -mthumb-interwork -fno-exceptions -DETCDIR=\"/etc\" -Ilibsensors 6LOCAL_CFLAGS += -Wall -O3 -mthumb-interwork -fno-exceptions -pthread -DETCDIR=\"/etc\" -Ilibsensors
7 7
8LOCAL_SRC_FILES := \ 8LOCAL_SRC_FILES := \
9 Buffer.cpp \ 9 Buffer.cpp \
@@ -15,12 +15,14 @@ LOCAL_SRC_FILES := \
15 DynBuf.cpp \ 15 DynBuf.cpp \
16 EventsXML.cpp \ 16 EventsXML.cpp \
17 ExternalSource.cpp \ 17 ExternalSource.cpp \
18 FSDriver.cpp \
18 Fifo.cpp \ 19 Fifo.cpp \
19 Hwmon.cpp \ 20 Hwmon.cpp \
20 KMod.cpp \ 21 KMod.cpp \
21 LocalCapture.cpp \ 22 LocalCapture.cpp \
22 Logging.cpp \ 23 Logging.cpp \
23 main.cpp \ 24 main.cpp \
25 MaliVideoDriver.cpp \
24 Monitor.cpp \ 26 Monitor.cpp \
25 OlySocket.cpp \ 27 OlySocket.cpp \
26 OlyUtility.cpp \ 28 OlyUtility.cpp \
@@ -55,7 +57,7 @@ LOCAL_SRC_FILES := \
55 mxml/mxml-set.c \ 57 mxml/mxml-set.c \
56 mxml/mxml-string.c 58 mxml/mxml-string.c
57 59
58LOCAL_C_INCLUDES := $(LOCAL_PATH) 60LOCAL_C_INCLUDES := $(LOCAL_PATH)
59 61
60LOCAL_MODULE := gatord 62LOCAL_MODULE := gatord
61LOCAL_MODULE_TAGS := optional 63LOCAL_MODULE_TAGS := optional
diff --git a/daemon/Application.mk b/daemon/Application.mk
new file mode 100644
index 0000000..631ba54
--- /dev/null
+++ b/daemon/Application.mk
@@ -0,0 +1 @@
APP_PLATFORM := android-8
diff --git a/daemon/Buffer.cpp b/daemon/Buffer.cpp
index 93557da..dd19f7f 100644
--- a/daemon/Buffer.cpp
+++ b/daemon/Buffer.cpp
@@ -15,11 +15,12 @@
15#define mask (mSize - 1) 15#define mask (mSize - 1)
16 16
17enum { 17enum {
18 CODE_PEA = 1, 18 CODE_PEA = 1,
19 CODE_KEYS = 2, 19 CODE_KEYS = 2,
20 CODE_FORMAT = 3, 20 CODE_FORMAT = 3,
21 CODE_MAPS = 4, 21 CODE_MAPS = 4,
22 CODE_COMM = 5, 22 CODE_COMM = 5,
23 CODE_KEYS_OLD = 6,
23}; 24};
24 25
25// Summary Frame Messages 26// Summary Frame Messages
@@ -167,7 +168,7 @@ void Buffer::check(const uint64_t time) {
167 } 168 }
168} 169}
169 170
170void Buffer::packInt(int32_t x) { 171void Buffer::packInt(char *const buf, const int size, int &writePos, int32_t x) {
171 int packedBytes = 0; 172 int packedBytes = 0;
172 int more = true; 173 int more = true;
173 while (more) { 174 while (more) {
@@ -181,11 +182,15 @@ void Buffer::packInt(int32_t x) {
181 b |= 0x80; 182 b |= 0x80;
182 } 183 }
183 184
184 mBuf[(mWritePos + packedBytes) & mask] = b; 185 buf[(writePos + packedBytes) & /*mask*/(size - 1)] = b;
185 packedBytes++; 186 packedBytes++;
186 } 187 }
187 188
188 mWritePos = (mWritePos + packedBytes) & mask; 189 writePos = (writePos + packedBytes) & /*mask*/(size - 1);
190}
191
192void Buffer::packInt(int32_t x) {
193 packInt(mBuf, mSize, mWritePos, x);
189} 194}
190 195
191void Buffer::packInt64(int64_t x) { 196void Buffer::packInt64(int64_t x) {
@@ -320,6 +325,21 @@ void Buffer::keys(const int count, const __u64 *const ids, const int *const keys
320 check(1); 325 check(1);
321} 326}
322 327
328void Buffer::keysOld(const int keyCount, const int *const keys, const int bytes, const char *const buf) {
329 if (checkSpace((2 + keyCount) * MAXSIZE_PACK32 + bytes)) {
330 packInt(CODE_KEYS_OLD);
331 packInt(keyCount);
332 for (int i = 0; i < keyCount; ++i) {
333 packInt(keys[i]);
334 }
335 writeBytes(buf, bytes);
336 } else {
337 logg->logError(__FILE__, __LINE__, "Ran out of buffer space for perf attrs");
338 handleException();
339 }
340 check(1);
341}
342
323void Buffer::format(const int length, const char *const format) { 343void Buffer::format(const int length, const char *const format) {
324 if (checkSpace(MAXSIZE_PACK32 + length + 1)) { 344 if (checkSpace(MAXSIZE_PACK32 + length + 1)) {
325 packInt(CODE_FORMAT); 345 packInt(CODE_FORMAT);
diff --git a/daemon/Buffer.h b/daemon/Buffer.h
index 5023777..2de1b97 100644
--- a/daemon/Buffer.h
+++ b/daemon/Buffer.h
@@ -54,6 +54,7 @@ public:
54 // Perf Attrs messages 54 // Perf Attrs messages
55 void pea(const struct perf_event_attr *const pea, int key); 55 void pea(const struct perf_event_attr *const pea, int key);
56 void keys(const int count, const __u64 *const ids, const int *const keys); 56 void keys(const int count, const __u64 *const ids, const int *const keys);
57 void keysOld(const int keyCount, const int *const keys, const int bytes, const char *const buf);
57 void format(const int length, const char *const format); 58 void format(const int length, const char *const format);
58 void maps(const int pid, const int tid, const char *const maps); 59 void maps(const int pid, const int tid, const char *const maps);
59 void comm(const int pid, const int tid, const char *const image, const char *const comm); 60 void comm(const int pid, const int tid, const char *const image, const char *const comm);
@@ -64,6 +65,11 @@ public:
64 // Prefer a new member to using these functions if possible 65 // Prefer a new member to using these functions if possible
65 char *getWritePos() { return mBuf + mWritePos; } 66 char *getWritePos() { return mBuf + mWritePos; }
66 void advanceWrite(int bytes) { mWritePos = (mWritePos + bytes) & /*mask*/(mSize - 1); } 67 void advanceWrite(int bytes) { mWritePos = (mWritePos + bytes) & /*mask*/(mSize - 1); }
68 static void packInt(char *const buf, const int size, int &writePos, int32_t x);
69 void packInt(int32_t x);
70 void packInt64(int64_t x);
71 void writeBytes(const void *const data, size_t count);
72 void writeString(const char *const str);
67 73
68 static void writeLEInt(unsigned char *buf, int v) { 74 static void writeLEInt(unsigned char *buf, int v) {
69 buf[0] = (v >> 0) & 0xFF; 75 buf[0] = (v >> 0) & 0xFF;
@@ -76,11 +82,6 @@ private:
76 bool commitReady() const; 82 bool commitReady() const;
77 bool checkSpace(int bytes); 83 bool checkSpace(int bytes);
78 84
79 void packInt(int32_t x);
80 void packInt64(int64_t x);
81 void writeBytes(const void *const data, size_t count);
82 void writeString(const char *const str);
83
84 const int32_t mCore; 85 const int32_t mCore;
85 const int32_t mBufType; 86 const int32_t mBufType;
86 const int mSize; 87 const int mSize;
diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp
index cf79b72..4a11415 100644
--- a/daemon/CapturedXML.cpp
+++ b/daemon/CapturedXML.cpp
@@ -33,7 +33,7 @@ mxml_node_t* CapturedXML::getTree(bool includeTime) {
33 captured = mxmlNewElement(xml, "captured"); 33 captured = mxmlNewElement(xml, "captured");
34 mxmlElementSetAttr(captured, "version", "1"); 34 mxmlElementSetAttr(captured, "version", "1");
35 if (gSessionData->perf.isSetup()) { 35 if (gSessionData->perf.isSetup()) {
36 mxmlElementSetAttr(captured, "type", "Perf"); 36 mxmlElementSetAttr(captured, "type", "Perf");
37 } 37 }
38 mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION); 38 mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION);
39 if (includeTime) { // Send the following only after the capture is complete 39 if (includeTime) { // Send the following only after the capture is complete
@@ -66,10 +66,15 @@ mxml_node_t* CapturedXML::getTree(bool includeTime) {
66 mxml_node_t *const node = mxmlNewElement(counters, "counter"); 66 mxml_node_t *const node = mxmlNewElement(counters, "counter");
67 mxmlElementSetAttrf(node, "key", "0x%x", counter.getKey()); 67 mxmlElementSetAttrf(node, "key", "0x%x", counter.getKey());
68 mxmlElementSetAttr(node, "type", counter.getType()); 68 mxmlElementSetAttr(node, "type", counter.getType());
69 mxmlElementSetAttrf(node, "event", "0x%x", counter.getEvent()); 69 if (counter.getEvent() != -1) {
70 mxmlElementSetAttrf(node, "event", "0x%x", counter.getEvent());
71 }
70 if (counter.getCount() > 0) { 72 if (counter.getCount() > 0) {
71 mxmlElementSetAttrf(node, "count", "%d", counter.getCount()); 73 mxmlElementSetAttrf(node, "count", "%d", counter.getCount());
72 } 74 }
75 if (counter.getCores() > 0) {
76 mxmlElementSetAttrf(node, "cores", "%d", counter.getCores());
77 }
73 } 78 }
74 } 79 }
75 80
@@ -89,7 +94,7 @@ void CapturedXML::write(char* path) {
89 94
90 // Set full path 95 // Set full path
91 snprintf(file, PATH_MAX, "%s/captured.xml", path); 96 snprintf(file, PATH_MAX, "%s/captured.xml", path);
92 97
93 char* xml = getXML(true); 98 char* xml = getXML(true);
94 if (util->writeToDisk(file, xml) < 0) { 99 if (util->writeToDisk(file, xml) < 0) {
95 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); 100 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
diff --git a/daemon/CapturedXML.h b/daemon/CapturedXML.h
index efc1e52..ed08c44 100644
--- a/daemon/CapturedXML.h
+++ b/daemon/CapturedXML.h
@@ -23,4 +23,4 @@ private:
23 23
24const char * mxmlWhitespaceCB(mxml_node_t *node, int where); 24const char * mxmlWhitespaceCB(mxml_node_t *node, int where);
25 25
26#endif //__CAPTURED_XML_H__ 26#endif //__CAPTURED_XML_H__
diff --git a/daemon/Child.cpp b/daemon/Child.cpp
index ca33561..1901ecc 100644
--- a/daemon/Child.cpp
+++ b/daemon/Child.cpp
@@ -26,13 +26,13 @@
26#include "Driver.h" 26#include "Driver.h"
27#include "PerfSource.h" 27#include "PerfSource.h"
28#include "DriverSource.h" 28#include "DriverSource.h"
29#include "UserSpaceSource.h"
30#include "ExternalSource.h" 29#include "ExternalSource.h"
30#include "UserSpaceSource.h"
31 31
32static sem_t haltPipeline, senderThreadStarted, startProfile, senderSem; // Shared by Child and spawned threads 32static sem_t haltPipeline, senderThreadStarted, startProfile, senderSem; // Shared by Child and spawned threads
33static Source *primarySource = NULL; 33static Source *primarySource = NULL;
34static Source *userSpaceSource = NULL;
35static Source *externalSource = NULL; 34static Source *externalSource = NULL;
35static Source *userSpaceSource = NULL;
36static Sender* sender = NULL; // Shared by Child.cpp and spawned threads 36static Sender* sender = NULL; // Shared by Child.cpp and spawned threads
37Child* child = NULL; // shared by Child.cpp and main.cpp 37Child* child = NULL; // shared by Child.cpp and main.cpp
38 38
@@ -147,16 +147,16 @@ static void *senderThread(void *) {
147 prctl(PR_SET_NAME, (unsigned long)&"gatord-sender", 0, 0, 0); 147 prctl(PR_SET_NAME, (unsigned long)&"gatord-sender", 0, 0, 0);
148 sem_wait(&haltPipeline); 148 sem_wait(&haltPipeline);
149 149
150 while (!primarySource->isDone() || (userSpaceSource != NULL && !userSpaceSource->isDone()) || (externalSource != NULL && !externalSource->isDone())) { 150 while (!primarySource->isDone() ||
151 !externalSource->isDone() ||
152 (userSpaceSource != NULL && !userSpaceSource->isDone())) {
151 sem_wait(&senderSem); 153 sem_wait(&senderSem);
152 154
153 primarySource->write(sender); 155 primarySource->write(sender);
156 externalSource->write(sender);
154 if (userSpaceSource != NULL) { 157 if (userSpaceSource != NULL) {
155 userSpaceSource->write(sender); 158 userSpaceSource->write(sender);
156 } 159 }
157 if (externalSource != NULL) {
158 externalSource->write(sender);
159 }
160 } 160 }
161 161
162 // write end-of-capture sequence 162 // write end-of-capture sequence
@@ -202,6 +202,10 @@ void Child::initialization() {
202void Child::endSession() { 202void Child::endSession() {
203 gSessionData->mSessionIsActive = false; 203 gSessionData->mSessionIsActive = false;
204 primarySource->interrupt(); 204 primarySource->interrupt();
205 externalSource->interrupt();
206 if (userSpaceSource != NULL) {
207 userSpaceSource->interrupt();
208 }
205 sem_post(&haltPipeline); 209 sem_post(&haltPipeline);
206} 210}
207 211
@@ -227,9 +231,9 @@ void Child::run() {
227 231
228 // Set up the driver; must be done after gSessionData->mPerfCounterType[] is populated 232 // Set up the driver; must be done after gSessionData->mPerfCounterType[] is populated
229 if (!gSessionData->perf.isSetup()) { 233 if (!gSessionData->perf.isSetup()) {
230 primarySource = new DriverSource(&senderSem, &startProfile); 234 primarySource = new DriverSource(&senderSem, &startProfile);
231 } else { 235 } else {
232 primarySource = new PerfSource(&senderSem, &startProfile); 236 primarySource = new PerfSource(&senderSem, &startProfile);
233 } 237 }
234 238
235 // Initialize all drivers 239 // Initialize all drivers
@@ -280,11 +284,18 @@ void Child::run() {
280 thread_creation_success = false; 284 thread_creation_success = false;
281 } else if (socket && pthread_create(&stopThreadID, NULL, stopThread, NULL)) { 285 } else if (socket && pthread_create(&stopThreadID, NULL, stopThread, NULL)) {
282 thread_creation_success = false; 286 thread_creation_success = false;
283 } else if (pthread_create(&senderThreadID, NULL, senderThread, NULL)){ 287 } else if (pthread_create(&senderThreadID, NULL, senderThread, NULL)) {
284 thread_creation_success = false; 288 thread_creation_success = false;
285 } 289 }
286 290
287 if (gSessionData->hwmon.countersEnabled()) { 291 externalSource = new ExternalSource(&senderSem);
292 if (!externalSource->prepare()) {
293 logg->logError(__FILE__, __LINE__, "Unable to prepare for capture");
294 handleException();
295 }
296 externalSource->start();
297
298 if (gSessionData->hwmon.countersEnabled() || gSessionData->fsDriver.countersEnabled()) {
288 userSpaceSource = new UserSpaceSource(&senderSem); 299 userSpaceSource = new UserSpaceSource(&senderSem);
289 if (!userSpaceSource->prepare()) { 300 if (!userSpaceSource->prepare()) {
290 logg->logError(__FILE__, __LINE__, "Unable to prepare for capture"); 301 logg->logError(__FILE__, __LINE__, "Unable to prepare for capture");
@@ -292,14 +303,6 @@ void Child::run() {
292 } 303 }
293 userSpaceSource->start(); 304 userSpaceSource->start();
294 } 305 }
295 if (access("/tmp/gator", F_OK) == 0) {
296 externalSource = new ExternalSource(&senderSem);
297 if (!externalSource->prepare()) {
298 logg->logError(__FILE__, __LINE__, "Unable to prepare for capture");
299 handleException();
300 }
301 externalSource->start();
302 }
303 306
304 if (!thread_creation_success) { 307 if (!thread_creation_success) {
305 logg->logError(__FILE__, __LINE__, "Failed to create gator threads"); 308 logg->logError(__FILE__, __LINE__, "Failed to create gator threads");
@@ -312,12 +315,10 @@ void Child::run() {
312 // Start profiling 315 // Start profiling
313 primarySource->run(); 316 primarySource->run();
314 317
315 if (externalSource != NULL) {
316 externalSource->join();
317 }
318 if (userSpaceSource != NULL) { 318 if (userSpaceSource != NULL) {
319 userSpaceSource->join(); 319 userSpaceSource->join();
320 } 320 }
321 externalSource->join();
321 322
322 // Wait for the other threads to exit 323 // Wait for the other threads to exit
323 pthread_join(senderThreadID, NULL); 324 pthread_join(senderThreadID, NULL);
@@ -337,8 +338,8 @@ void Child::run() {
337 338
338 logg->logMessage("Profiling ended."); 339 logg->logMessage("Profiling ended.");
339 340
340 delete externalSource;
341 delete userSpaceSource; 341 delete userSpaceSource;
342 delete externalSource;
342 delete primarySource; 343 delete primarySource;
343 delete sender; 344 delete sender;
344 delete localCapture; 345 delete localCapture;
diff --git a/daemon/Child.h b/daemon/Child.h
index 9e206d7..a306a77 100644
--- a/daemon/Child.h
+++ b/daemon/Child.h
@@ -30,4 +30,4 @@ private:
30 Child &operator=(const Child &); 30 Child &operator=(const Child &);
31}; 31};
32 32
33#endif //__CHILD_H__ 33#endif //__CHILD_H__
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp
index fd479f2..6590dd3 100644
--- a/daemon/ConfigurationXML.cpp
+++ b/daemon/ConfigurationXML.cpp
@@ -21,12 +21,13 @@ static const char* ATTR_COUNTER = "counter";
21static const char* ATTR_REVISION = "revision"; 21static const char* ATTR_REVISION = "revision";
22static const char* ATTR_EVENT = "event"; 22static const char* ATTR_EVENT = "event";
23static const char* ATTR_COUNT = "count"; 23static const char* ATTR_COUNT = "count";
24static const char* ATTR_CORES = "cores";
24 25
25ConfigurationXML::ConfigurationXML() { 26ConfigurationXML::ConfigurationXML() {
26 const char * configuration_xml; 27 const char * configuration_xml;
27 unsigned int configuration_xml_len; 28 unsigned int configuration_xml_len;
28 getDefaultConfigurationXml(configuration_xml, configuration_xml_len); 29 getDefaultConfigurationXml(configuration_xml, configuration_xml_len);
29 30
30 char path[PATH_MAX]; 31 char path[PATH_MAX];
31 32
32 getPath(path); 33 getPath(path);
@@ -53,7 +54,7 @@ ConfigurationXML::ConfigurationXML() {
53 54
54 break; 55 break;
55 } 56 }
56 57
57 validate(); 58 validate();
58} 59}
59 60
@@ -82,7 +83,7 @@ int ConfigurationXML::parse(const char* configurationXML) {
82 node = mxmlGetFirstChild(tree); 83 node = mxmlGetFirstChild(tree);
83 while (node && mxmlGetType(node) != MXML_ELEMENT) 84 while (node && mxmlGetType(node) != MXML_ELEMENT)
84 node = mxmlWalkNext(node, tree, MXML_NO_DESCEND); 85 node = mxmlWalkNext(node, tree, MXML_NO_DESCEND);
85 86
86 ret = configurationsTag(node); 87 ret = configurationsTag(node);
87 88
88 node = mxmlGetFirstChild(node); 89 node = mxmlGetFirstChild(node);
@@ -127,7 +128,7 @@ void ConfigurationXML::validate(void) {
127#define CONFIGURATION_REVISION 3 128#define CONFIGURATION_REVISION 3
128int ConfigurationXML::configurationsTag(mxml_node_t *node) { 129int ConfigurationXML::configurationsTag(mxml_node_t *node) {
129 const char* revision_string; 130 const char* revision_string;
130 131
131 revision_string = mxmlElementGetAttr(node, ATTR_REVISION); 132 revision_string = mxmlElementGetAttr(node, ATTR_REVISION);
132 if (!revision_string) { 133 if (!revision_string) {
133 return 1; //revision issue; 134 return 1; //revision issue;
@@ -158,6 +159,7 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
158 if (mxmlElementGetAttr(node, ATTR_COUNTER)) counter.setType(mxmlElementGetAttr(node, ATTR_COUNTER)); 159 if (mxmlElementGetAttr(node, ATTR_COUNTER)) counter.setType(mxmlElementGetAttr(node, ATTR_COUNTER));
159 if (mxmlElementGetAttr(node, ATTR_EVENT)) counter.setEvent(strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16)); 160 if (mxmlElementGetAttr(node, ATTR_EVENT)) counter.setEvent(strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16));
160 if (mxmlElementGetAttr(node, ATTR_COUNT)) counter.setCount(strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10)); 161 if (mxmlElementGetAttr(node, ATTR_COUNT)) counter.setCount(strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10));
162 if (mxmlElementGetAttr(node, ATTR_CORES)) counter.setCores(strtol(mxmlElementGetAttr(node, ATTR_CORES), NULL, 10));
161 if (counter.getCount() > 0) { 163 if (counter.getCount() > 0) {
162 gSessionData->mIsEBS = true; 164 gSessionData->mIsEBS = true;
163 } 165 }
diff --git a/daemon/Counter.h b/daemon/Counter.h
index 6891745..5202aa0 100644
--- a/daemon/Counter.h
+++ b/daemon/Counter.h
@@ -27,6 +27,7 @@ public:
27 mEnabled = false; 27 mEnabled = false;
28 mEvent = -1; 28 mEvent = -1;
29 mCount = 0; 29 mCount = 0;
30 mCores = -1;
30 mKey = 0; 31 mKey = 0;
31 mDriver = NULL; 32 mDriver = NULL;
32 } 33 }
@@ -35,6 +36,7 @@ public:
35 void setEnabled(const bool enabled) { mEnabled = enabled; } 36 void setEnabled(const bool enabled) { mEnabled = enabled; }
36 void setEvent(const int event) { mEvent = event; } 37 void setEvent(const int event) { mEvent = event; }
37 void setCount(const int count) { mCount = count; } 38 void setCount(const int count) { mCount = count; }
39 void setCores(const int cores) { mCores = cores; }
38 void setKey(const int key) { mKey = key; } 40 void setKey(const int key) { mKey = key; }
39 void setDriver(Driver *const driver) { mDriver = driver; } 41 void setDriver(Driver *const driver) { mDriver = driver; }
40 42
@@ -42,6 +44,7 @@ public:
42 bool isEnabled() const { return mEnabled; } 44 bool isEnabled() const { return mEnabled; }
43 int getEvent() const { return mEvent; } 45 int getEvent() const { return mEvent; }
44 int getCount() const { return mCount; } 46 int getCount() const { return mCount; }
47 int getCores() const { return mCores; }
45 int getKey() const { return mKey; } 48 int getKey() const { return mKey; }
46 Driver *getDriver() const { return mDriver; } 49 Driver *getDriver() const { return mDriver; }
47 50
@@ -54,6 +57,7 @@ private:
54 bool mEnabled; 57 bool mEnabled;
55 int mEvent; 58 int mEvent;
56 int mCount; 59 int mCount;
60 int mCores;
57 int mKey; 61 int mKey;
58 Driver *mDriver; 62 Driver *mDriver;
59}; 63};
diff --git a/daemon/DriverSource.cpp b/daemon/DriverSource.cpp
index f78ec6b..11d3095 100644
--- a/daemon/DriverSource.cpp
+++ b/daemon/DriverSource.cpp
@@ -12,19 +12,24 @@
12 12
13#include <fcntl.h> 13#include <fcntl.h>
14#include <inttypes.h> 14#include <inttypes.h>
15#include <sys/prctl.h>
15#include <unistd.h> 16#include <unistd.h>
16 17
18#include "Buffer.h"
17#include "Child.h" 19#include "Child.h"
20#include "DynBuf.h"
18#include "Fifo.h" 21#include "Fifo.h"
19#include "Logging.h" 22#include "Logging.h"
23#include "Proc.h"
20#include "Sender.h" 24#include "Sender.h"
21#include "SessionData.h" 25#include "SessionData.h"
22 26
23extern Child *child; 27extern Child *child;
24 28
25DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mFifo(NULL), mSenderSem(senderSem), mStartProfile(startProfile), mBufferSize(0), mBufferFD(0), mLength(1) { 29DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mBuffer(NULL), mFifo(NULL), mSenderSem(senderSem), mStartProfile(startProfile), mBufferSize(0), mBufferFD(0), mLength(1) {
26 int driver_version = 0; 30 int driver_version = 0;
27 31
32 mBuffer = new Buffer(0, FRAME_PERF_ATTRS, 4*1024*1024, senderSem);
28 if (readIntDriver("/dev/gator/version", &driver_version) == -1) { 33 if (readIntDriver("/dev/gator/version", &driver_version) == -1) {
29 logg->logError(__FILE__, __LINE__, "Error reading gator driver version"); 34 logg->logError(__FILE__, __LINE__, "Error reading gator driver version");
30 handleException(); 35 handleException();
@@ -43,7 +48,7 @@ DriverSource::DriverSource(sem_t *senderSem, sem_t *startProfile) : mFifo(NULL),
43 handleException(); 48 handleException();
44 } else { 49 } else {
45 // Release version mismatch 50 // Release version mismatch
46 logg->logError(__FILE__, __LINE__, 51 logg->logError(__FILE__, __LINE__,
47 "gator driver version \"%d\" is different than gator daemon version \"%d\".\n" 52 "gator driver version \"%d\" is different than gator daemon version \"%d\".\n"
48 ">> Please upgrade the driver and daemon to the latest versions.", driver_version, PROTOCOL_VERSION); 53 ">> Please upgrade the driver and daemon to the latest versions.", driver_version, PROTOCOL_VERSION);
49 handleException(); 54 handleException();
@@ -87,6 +92,28 @@ bool DriverSource::prepare() {
87 return true; 92 return true;
88} 93}
89 94
95void DriverSource::bootstrapThread() {
96 prctl(PR_SET_NAME, (unsigned long)&"gatord-bootstrap", 0, 0, 0);
97
98 DynBuf printb;
99 DynBuf b1;
100 DynBuf b2;
101 DynBuf b3;
102
103 if (!readProc(mBuffer, false, &printb, &b1, &b2, &b3)) {
104 logg->logMessage("%s(%s:%i): readProc failed", __FUNCTION__, __FILE__, __LINE__);
105 handleException();
106 }
107
108 mBuffer->commit(1);
109 mBuffer->setDone();
110}
111
112void *DriverSource::bootstrapThreadStatic(void *arg) {
113 static_cast<DriverSource *>(arg)->bootstrapThread();
114 return NULL;
115}
116
90void DriverSource::run() { 117void DriverSource::run() {
91 // Get the initial pointer to the collect buffer 118 // Get the initial pointer to the collect buffer
92 char *collectBuffer = mFifo->start(); 119 char *collectBuffer = mFifo->start();
@@ -138,6 +165,12 @@ void DriverSource::run() {
138 165
139 sem_post(mStartProfile); 166 sem_post(mStartProfile);
140 167
168 pthread_t bootstrapThreadID;
169 if (pthread_create(&bootstrapThreadID, NULL, bootstrapThreadStatic, this) != 0) {
170 logg->logError(__FILE__, __LINE__, "Unable to start the gator_bootstrap thread");
171 handleException();
172 }
173
141 // Collect Data 174 // Collect Data
142 do { 175 do {
143 // This command will stall until data is received from the driver 176 // This command will stall until data is received from the driver
@@ -164,6 +197,8 @@ void DriverSource::run() {
164 } while (bytesCollected > 0); 197 } while (bytesCollected > 0);
165 198
166 logg->logMessage("Exit collect data loop"); 199 logg->logMessage("Exit collect data loop");
200
201 pthread_join(bootstrapThreadID, NULL);
167} 202}
168 203
169void DriverSource::interrupt() { 204void DriverSource::interrupt() {
@@ -174,7 +209,7 @@ void DriverSource::interrupt() {
174} 209}
175 210
176bool DriverSource::isDone() { 211bool DriverSource::isDone() {
177 return mLength <= 0; 212 return mLength <= 0 && (mBuffer == NULL || mBuffer->isDone());
178} 213}
179 214
180void DriverSource::write(Sender *sender) { 215void DriverSource::write(Sender *sender) {
@@ -182,6 +217,16 @@ void DriverSource::write(Sender *sender) {
182 if (data != NULL) { 217 if (data != NULL) {
183 sender->writeData(data, mLength, RESPONSE_APC_DATA); 218 sender->writeData(data, mLength, RESPONSE_APC_DATA);
184 mFifo->release(); 219 mFifo->release();
220 // Assume the summary packet is in the first block received from the driver
221 gSessionData->mSentSummary = true;
222 }
223 if (mBuffer != NULL && !mBuffer->isDone()) {
224 mBuffer->write(sender);
225 if (mBuffer->isDone()) {
226 Buffer *buf = mBuffer;
227 mBuffer = NULL;
228 delete buf;
229 }
185 } 230 }
186} 231}
187 232
@@ -227,7 +272,7 @@ int DriverSource::readInt64Driver(const char *fullpath, int64_t *value) {
227 char *endptr; 272 char *endptr;
228 errno = 0; 273 errno = 0;
229 *value = strtoll(data, &endptr, 10); 274 *value = strtoll(data, &endptr, 10);
230 if (errno != 0 || *endptr != '\n') { 275 if (errno != 0 || (*endptr != '\n' && *endptr != '\0')) {
231 logg->logMessage("Invalid value in file %s", fullpath); 276 logg->logMessage("Invalid value in file %s", fullpath);
232 return -1; 277 return -1;
233 } 278 }
diff --git a/daemon/DriverSource.h b/daemon/DriverSource.h
index dcf1078..ec27b08 100644
--- a/daemon/DriverSource.h
+++ b/daemon/DriverSource.h
@@ -14,6 +14,7 @@
14 14
15#include "Source.h" 15#include "Source.h"
16 16
17class Buffer;
17class Fifo; 18class Fifo;
18 19
19class DriverSource : public Source { 20class DriverSource : public Source {
@@ -37,6 +38,10 @@ public:
37 static int writeReadDriver(const char *path, int64_t *value); 38 static int writeReadDriver(const char *path, int64_t *value);
38 39
39private: 40private:
41 static void *bootstrapThreadStatic(void *arg);
42 void bootstrapThread();
43
44 Buffer *mBuffer;
40 Fifo *mFifo; 45 Fifo *mFifo;
41 sem_t *const mSenderSem; 46 sem_t *const mSenderSem;
42 sem_t *const mStartProfile; 47 sem_t *const mStartProfile;
diff --git a/daemon/EventsXML.cpp b/daemon/EventsXML.cpp
index a07a046..cf0192e 100644
--- a/daemon/EventsXML.cpp
+++ b/daemon/EventsXML.cpp
@@ -13,7 +13,7 @@
13#include "OlyUtility.h" 13#include "OlyUtility.h"
14#include "SessionData.h" 14#include "SessionData.h"
15 15
16char* EventsXML::getXML() { 16mxml_node_t *EventsXML::getTree() {
17#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len 17#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len
18 char path[PATH_MAX]; 18 char path[PATH_MAX];
19 mxml_node_t *xml; 19 mxml_node_t *xml;
@@ -38,6 +38,12 @@ char* EventsXML::getXML() {
38 xml = mxmlLoadString(NULL, (const char *)events_xml, MXML_NO_CALLBACK); 38 xml = mxmlLoadString(NULL, (const char *)events_xml, MXML_NO_CALLBACK);
39 } 39 }
40 40
41 return xml;
42}
43
44char *EventsXML::getXML() {
45 mxml_node_t *xml = getTree();
46
41 // Add dynamic events from the drivers 47 // Add dynamic events from the drivers
42 mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND); 48 mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND);
43 if (!events) { 49 if (!events) {
@@ -48,19 +54,19 @@ char* EventsXML::getXML() {
48 driver->writeEvents(events); 54 driver->writeEvents(events);
49 } 55 }
50 56
51 char* string = mxmlSaveAllocString(xml, mxmlWhitespaceCB); 57 char *string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
52 mxmlDelete(xml); 58 mxmlDelete(xml);
53 59
54 return string; 60 return string;
55} 61}
56 62
57void EventsXML::write(const char* path) { 63void EventsXML::write(const char *path) {
58 char file[PATH_MAX]; 64 char file[PATH_MAX];
59 65
60 // Set full path 66 // Set full path
61 snprintf(file, PATH_MAX, "%s/events.xml", path); 67 snprintf(file, PATH_MAX, "%s/events.xml", path);
62 68
63 char* buf = getXML(); 69 char *buf = getXML();
64 if (util->writeToDisk(file, buf) < 0) { 70 if (util->writeToDisk(file, buf) < 0) {
65 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); 71 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
66 handleException(); 72 handleException();
diff --git a/daemon/EventsXML.h b/daemon/EventsXML.h
index 6cd1560..ff7a02f 100644
--- a/daemon/EventsXML.h
+++ b/daemon/EventsXML.h
@@ -9,9 +9,12 @@
9#ifndef EVENTS_XML 9#ifndef EVENTS_XML
10#define EVENTS_XML 10#define EVENTS_XML
11 11
12#include "mxml/mxml.h"
13
12class EventsXML { 14class EventsXML {
13public: 15public:
14 char* getXML(); 16 mxml_node_t *getTree();
17 char *getXML();
15 void write(const char* path); 18 void write(const char* path);
16}; 19};
17 20
diff --git a/daemon/ExternalSource.cpp b/daemon/ExternalSource.cpp
index fe5824b..b6ec301 100644
--- a/daemon/ExternalSource.cpp
+++ b/daemon/ExternalSource.cpp
@@ -8,41 +8,195 @@
8 8
9#include "ExternalSource.h" 9#include "ExternalSource.h"
10 10
11#include <fcntl.h>
11#include <sys/prctl.h> 12#include <sys/prctl.h>
13#include <unistd.h>
12 14
13#include "Logging.h" 15#include "Logging.h"
14#include "OlySocket.h" 16#include "OlySocket.h"
15#include "SessionData.h" 17#include "SessionData.h"
16 18
17ExternalSource::ExternalSource(sem_t *senderSem) : mBuffer(0, FRAME_EXTERNAL, 1024, senderSem), mSock("/tmp/gator") { 19static const char MALI_VIDEO[] = "\0mali-video";
20static const char MALI_VIDEO_STARTUP[] = "\0mali-video-startup";
21static const char MALI_VIDEO_V1[] = "MALI_VIDEO 1\n";
22
23static bool setNonblock(const int fd) {
24 int flags;
25
26 flags = fcntl(fd, F_GETFL);
27 if (flags < 0) {
28 logg->logMessage("fcntl getfl failed");
29 return false;
30 }
31
32 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
33 logg->logMessage("fcntl setfl failed");
34 return false;
35 }
36
37 return true;
38}
39
40ExternalSource::ExternalSource(sem_t *senderSem) : mBuffer(0, FRAME_EXTERNAL, 128*1024, senderSem), mMonitor(), mMveStartupUds(MALI_VIDEO_STARTUP, sizeof(MALI_VIDEO_STARTUP)), mInterruptFd(-1), mMveUds(-1) {
41 sem_init(&mBufferSem, 0, 0);
18} 42}
19 43
20ExternalSource::~ExternalSource() { 44ExternalSource::~ExternalSource() {
21} 45}
22 46
47void ExternalSource::waitFor(const uint64_t currTime, const int bytes) {
48 while (mBuffer.bytesAvailable() <= bytes) {
49 mBuffer.check(currTime);
50 sem_wait(&mBufferSem);
51 }
52}
53
54void ExternalSource::configureConnection(const int fd, const char *const handshake, size_t size) {
55 if (!setNonblock(fd)) {
56 logg->logError(__FILE__, __LINE__, "Unable to set nonblock on fh");
57 handleException();
58 }
59
60 if (!mMonitor.add(fd)) {
61 logg->logError(__FILE__, __LINE__, "Unable to add fh to monitor");
62 handleException();
63 }
64
65 // Write the handshake to the circular buffer
66 waitFor(1, Buffer::MAXSIZE_PACK32 + 4 + size - 1);
67 mBuffer.packInt(fd);
68 mBuffer.writeLEInt((unsigned char *)mBuffer.getWritePos(), size - 1);
69 mBuffer.advanceWrite(4);
70 mBuffer.writeBytes(handshake, size - 1);
71}
72
73bool ExternalSource::connectMve() {
74 if (!gSessionData->maliVideo.countersEnabled()) {
75 return true;
76 }
77
78 mMveUds = OlySocket::connect(MALI_VIDEO, sizeof(MALI_VIDEO));
79 if (mMveUds < 0) {
80 return false;
81 }
82
83 if (!gSessionData->maliVideo.start(mMveUds)) {
84 return false;
85 }
86
87 configureConnection(mMveUds, MALI_VIDEO_V1, sizeof(MALI_VIDEO_V1));
88
89 return true;
90}
91
23bool ExternalSource::prepare() { 92bool ExternalSource::prepare() {
93 if (!mMonitor.init() || !setNonblock(mMveStartupUds.getFd()) || !mMonitor.add(mMveStartupUds.getFd())) {
94 return false;
95 }
96
97 connectMve();
98
24 return true; 99 return true;
25} 100}
26 101
27void ExternalSource::run() { 102void ExternalSource::run() {
28 prctl(PR_SET_NAME, (unsigned long)&"gatord-uds", 0, 0, 0); 103 int pipefd[2];
104
105 prctl(PR_SET_NAME, (unsigned long)&"gatord-external", 0, 0, 0);
106
107 if (pipe(pipefd) != 0) {
108 logg->logError(__FILE__, __LINE__, "pipe failed");
109 handleException();
110 }
111 mInterruptFd = pipefd[1];
112
113 if (!mMonitor.add(pipefd[0])) {
114 logg->logError(__FILE__, __LINE__, "Monitor::add failed");
115 handleException();
116 }
29 117
30 while (gSessionData->mSessionIsActive) { 118 while (gSessionData->mSessionIsActive) {
31 // Will be aborted when the socket is closed at the end of the capture 119 struct epoll_event events[16];
32 int length = mSock.receive(mBuffer.getWritePos(), mBuffer.contiguousSpaceAvailable()); 120 // Clear any pending sem posts
33 if (length <= 0) { 121 while (sem_trywait(&mBufferSem) == 0);
34 break; 122 int ready = mMonitor.wait(events, ARRAY_LENGTH(events), -1);
123 if (ready < 0) {
124 logg->logError(__FILE__, __LINE__, "Monitor::wait failed");
125 handleException();
35 } 126 }
36 127
37 mBuffer.advanceWrite(length); 128 const uint64_t currTime = getTime();
38 mBuffer.check(0); 129
130 for (int i = 0; i < ready; ++i) {
131 const int fd = events[i].data.fd;
132 if (fd == mMveStartupUds.getFd()) {
133 // Mali Video Engine says it's alive
134 int client = mMveStartupUds.acceptConnection();
135 // Don't read from this connection, establish a new connection to Mali-V500
136 close(client);
137 if (!connectMve()) {
138 logg->logError(__FILE__, __LINE__, "Unable to configure incoming Mali video connection");
139 handleException();
140 }
141 } else if (fd == pipefd[0]) {
142 // Means interrupt has been called and mSessionIsActive should be reread
143 } else {
144 while (true) {
145 waitFor(currTime, Buffer::MAXSIZE_PACK32 + 4);
146
147 mBuffer.packInt(fd);
148 char *const bytesPos = mBuffer.getWritePos();
149 mBuffer.advanceWrite(4);
150 const int contiguous = mBuffer.contiguousSpaceAvailable();
151 const int bytes = read(fd, mBuffer.getWritePos(), contiguous);
152 if (bytes < 0) {
153 if (errno == EAGAIN) {
154 // Nothing left to read, and Buffer convention dictates that writePos can't go backwards
155 mBuffer.writeLEInt((unsigned char *)bytesPos, 0);
156 break;
157 }
158 // Something else failed, close the socket
159 mBuffer.writeLEInt((unsigned char *)bytesPos, -1);
160 close(fd);
161 break;
162 } else if (bytes == 0) {
163 // The other side is closed
164 mBuffer.writeLEInt((unsigned char *)bytesPos, -1);
165 close(fd);
166 break;
167 }
168
169 mBuffer.writeLEInt((unsigned char *)bytesPos, bytes);
170 mBuffer.advanceWrite(bytes);
171
172 // Short reads also mean nothing is left to read
173 if (bytes < contiguous) {
174 break;
175 }
176 }
177 }
178 }
179
180 // Only call mBufferCheck once per iteration
181 mBuffer.check(currTime);
39 } 182 }
40 183
41 mBuffer.setDone(); 184 mBuffer.setDone();
185
186 mInterruptFd = -1;
187 close(pipefd[0]);
188 close(pipefd[1]);
42} 189}
43 190
44void ExternalSource::interrupt() { 191void ExternalSource::interrupt() {
45 // Do nothing 192 if (mInterruptFd >= 0) {
193 int8_t c = 0;
194 // Write to the pipe to wake the monitor which will cause mSessionIsActive to be reread
195 if (::write(mInterruptFd, &c, sizeof(c)) != sizeof(c)) {
196 logg->logError(__FILE__, __LINE__, "write failed");
197 handleException();
198 }
199 }
46} 200}
47 201
48bool ExternalSource::isDone() { 202bool ExternalSource::isDone() {
@@ -50,7 +204,12 @@ bool ExternalSource::isDone() {
50} 204}
51 205
52void ExternalSource::write(Sender *sender) { 206void ExternalSource::write(Sender *sender) {
207 // Don't send external data until the summary packet is sent so that monotonic delta is available
208 if (!gSessionData->mSentSummary) {
209 return;
210 }
53 if (!mBuffer.isDone()) { 211 if (!mBuffer.isDone()) {
54 mBuffer.write(sender); 212 mBuffer.write(sender);
213 sem_post(&mBufferSem);
55 } 214 }
56} 215}
diff --git a/daemon/ExternalSource.h b/daemon/ExternalSource.h
index 2052bdf..2e7ed27 100644
--- a/daemon/ExternalSource.h
+++ b/daemon/ExternalSource.h
@@ -12,6 +12,7 @@
12#include <semaphore.h> 12#include <semaphore.h>
13 13
14#include "Buffer.h" 14#include "Buffer.h"
15#include "Monitor.h"
15#include "OlySocket.h" 16#include "OlySocket.h"
16#include "Source.h" 17#include "Source.h"
17 18
@@ -29,8 +30,16 @@ public:
29 void write(Sender *sender); 30 void write(Sender *sender);
30 31
31private: 32private:
33 void waitFor(const uint64_t currTime, const int bytes);
34 void configureConnection(const int fd, const char *const handshake, size_t size);
35 bool connectMve();
36
37 sem_t mBufferSem;
32 Buffer mBuffer; 38 Buffer mBuffer;
33 OlySocket mSock; 39 Monitor mMonitor;
40 OlyServerSocket mMveStartupUds;
41 int mInterruptFd;
42 int mMveUds;
34 43
35 // Intentionally unimplemented 44 // Intentionally unimplemented
36 ExternalSource(const ExternalSource &); 45 ExternalSource(const ExternalSource &);
diff --git a/daemon/FSDriver.cpp b/daemon/FSDriver.cpp
new file mode 100644
index 0000000..40c8df1
--- /dev/null
+++ b/daemon/FSDriver.cpp
@@ -0,0 +1,212 @@
1/**
2 * Copyright (C) ARM Limited 2014. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include "FSDriver.h"
10
11#include <fcntl.h>
12#include <regex.h>
13#include <sys/stat.h>
14#include <sys/types.h>
15#include <unistd.h>
16
17#include "Buffer.h"
18#include "Counter.h"
19#include "DriverSource.h"
20#include "Logging.h"
21#include "SessionData.h"
22
23class FSCounter {
24public:
25 FSCounter(FSCounter *next, char *name, const char *regex);
26 ~FSCounter();
27
28 FSCounter *getNext() const { return next; }
29 int getKey() const { return key; }
30 bool isEnabled() const { return enabled; }
31 void setEnabled(const bool enabled) { this->enabled = enabled; }
32 const char *getName() const { return name; }
33 int64_t read();
34
35private:
36 FSCounter *const next;
37 regex_t reg;
38 char *name;
39 const int key;
40 int enabled : 1,
41 useRegex : 1;
42
43 // Intentionally unimplemented
44 FSCounter(const FSCounter &);
45 FSCounter &operator=(const FSCounter &);
46};
47
48FSCounter::FSCounter(FSCounter *next, char *name, const char *regex) : next(next), name(name), key(getEventKey()), enabled(false), useRegex(regex != NULL) {
49 if (useRegex) {
50 int result = regcomp(&reg, regex, REG_EXTENDED);
51 if (result != 0) {
52 char buf[128];
53 regerror(result, &reg, buf, sizeof(buf));
54 logg->logError(__FILE__, __LINE__, "Invalid regex '%s': %s", regex, buf);
55 handleException();
56 }
57 }
58}
59
60FSCounter::~FSCounter() {
61 free(name);
62 if (useRegex) {
63 regfree(&reg);
64 }
65}
66
67int64_t FSCounter::read() {
68 int64_t value;
69 if (useRegex) {
70 char buf[4096];
71 size_t pos = 0;
72 const int fd = open(name, O_RDONLY);
73 if (fd < 0) {
74 goto fail;
75 }
76 while (pos < sizeof(buf) - 1) {
77 const ssize_t bytes = ::read(fd, buf + pos, sizeof(buf) - pos - 1);
78 if (bytes < 0) {
79 goto fail;
80 } else if (bytes == 0) {
81 break;
82 }
83 pos += bytes;
84 }
85 close(fd);
86 buf[pos] = '\0';
87
88 regmatch_t match[2];
89 int result = regexec(&reg, buf, 2, match, 0);
90 if (result != 0) {
91 regerror(result, &reg, buf, sizeof(buf));
92 logg->logError(__FILE__, __LINE__, "Parsing %s failed: %s", name, buf);
93 handleException();
94 }
95
96 if (match[1].rm_so < 0) {
97 logg->logError(__FILE__, __LINE__, "Parsing %s failed", name);
98 handleException();
99 }
100 char *endptr;
101 errno = 0;
102 value = strtoll(buf + match[1].rm_so, &endptr, 0);
103 if (errno != 0) {
104 logg->logError(__FILE__, __LINE__, "Parsing %s failed: %s", name, strerror(errno));
105 handleException();
106 }
107 } else {
108 if (DriverSource::readInt64Driver(name, &value) != 0) {
109 goto fail;
110 }
111 }
112 return value;
113
114 fail:
115 logg->logError(__FILE__, __LINE__, "Unable to read %s", name);
116 handleException();
117}
118
119FSDriver::FSDriver() : counters(NULL) {
120}
121
122FSDriver::~FSDriver() {
123 while (counters != NULL) {
124 FSCounter * counter = counters;
125 counters = counter->getNext();
126 delete counter;
127 }
128}
129
130void FSDriver::setup(mxml_node_t *const xml) {
131 // fs driver does not currently work with perf
132 if (gSessionData->perf.isSetup()) {
133 return;
134 }
135
136 mxml_node_t *node = xml;
137 while (true) {
138 node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
139 if (node == NULL) {
140 break;
141 }
142 const char *counter = mxmlElementGetAttr(node, "counter");
143 if ((counter != NULL) && (counter[0] == '/')) {
144 const char *regex = mxmlElementGetAttr(node, "regex");
145 counters = new FSCounter(counters, strdup(counter), regex);
146 }
147 }
148}
149
150FSCounter *FSDriver::findCounter(const Counter &counter) const {
151 for (FSCounter * fsCounter = counters; fsCounter != NULL; fsCounter = fsCounter->getNext()) {
152 if (strcmp(fsCounter->getName(), counter.getType()) == 0) {
153 return fsCounter;
154 }
155 }
156
157 return NULL;
158}
159
160bool FSDriver::claimCounter(const Counter &counter) const {
161 return findCounter(counter) != NULL;
162}
163
164bool FSDriver::countersEnabled() const {
165 for (FSCounter *counter = counters; counter != NULL; counter = counter->getNext()) {
166 if (counter->isEnabled()) {
167 return true;
168 }
169 }
170 return false;
171}
172
173void FSDriver::resetCounters() {
174 for (FSCounter * counter = counters; counter != NULL; counter = counter->getNext()) {
175 counter->setEnabled(false);
176 }
177}
178
179void FSDriver::setupCounter(Counter &counter) {
180 FSCounter *const fsCounter = findCounter(counter);
181 if (fsCounter == NULL) {
182 counter.setEnabled(false);
183 return;
184 }
185 fsCounter->setEnabled(true);
186 counter.setKey(fsCounter->getKey());
187}
188
189int FSDriver::writeCounters(mxml_node_t *root) const {
190 int count = 0;
191 for (FSCounter * counter = counters; counter != NULL; counter = counter->getNext()) {
192 if (access(counter->getName(), R_OK) == 0) {
193 mxml_node_t *node = mxmlNewElement(root, "counter");
194 mxmlElementSetAttr(node, "name", counter->getName());
195 ++count;
196 }
197 }
198
199 return count;
200}
201
202void FSDriver::start() {
203}
204
205void FSDriver::read(Buffer * const buffer) {
206 for (FSCounter * counter = counters; counter != NULL; counter = counter->getNext()) {
207 if (!counter->isEnabled()) {
208 continue;
209 }
210 buffer->event(counter->getKey(), counter->read());
211 }
212}
diff --git a/daemon/FSDriver.h b/daemon/FSDriver.h
new file mode 100644
index 0000000..ef39553
--- /dev/null
+++ b/daemon/FSDriver.h
@@ -0,0 +1,44 @@
1/**
2 * Copyright (C) ARM Limited 2014. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef FSDRIVER_H
10#define FSDRIVER_H
11
12#include "Driver.h"
13
14class Buffer;
15class FSCounter;
16
17class FSDriver : public Driver {
18public:
19 FSDriver();
20 ~FSDriver();
21
22 void setup(mxml_node_t *const xml);
23
24 bool claimCounter(const Counter &counter) const;
25 bool countersEnabled() const;
26 void resetCounters();
27 void setupCounter(Counter &counter);
28
29 int writeCounters(mxml_node_t *root) const;
30
31 void start();
32 void read(Buffer * buffer);
33
34private:
35 FSCounter *findCounter(const Counter &counter) const;
36
37 FSCounter *counters;
38
39 // Intentionally unimplemented
40 FSDriver(const FSDriver &);
41 FSDriver &operator=(const FSDriver &);
42};
43
44#endif // FSDRIVER_H
diff --git a/daemon/Fifo.h b/daemon/Fifo.h
index 7dd7426..bdda3f5 100644
--- a/daemon/Fifo.h
+++ b/daemon/Fifo.h
@@ -45,4 +45,4 @@ private:
45 Fifo &operator=(const Fifo &); 45 Fifo &operator=(const Fifo &);
46}; 46};
47 47
48#endif //__FIFO_H__ 48#endif //__FIFO_H__
diff --git a/daemon/Hwmon.cpp b/daemon/Hwmon.cpp
index 778f307..e444247 100644
--- a/daemon/Hwmon.cpp
+++ b/daemon/Hwmon.cpp
@@ -28,6 +28,7 @@ public:
28 const char *getTitle() const { return title; } 28 const char *getTitle() const { return title; }
29 bool isDuplicate() const { return duplicate; } 29 bool isDuplicate() const { return duplicate; }
30 const char *getDisplay() const { return display; } 30 const char *getDisplay() const { return display; }
31 const char *getCounterClass() const { return counter_class; }
31 const char *getUnit() const { return unit; } 32 const char *getUnit() const { return unit; }
32 int getModifier() const { return modifier; } 33 int getModifier() const { return modifier; }
33 34
@@ -58,6 +59,7 @@ private:
58 char *label; 59 char *label;
59 const char *title; 60 const char *title;
60 const char *display; 61 const char *display;
62 const char *counter_class;
61 const char *unit; 63 const char *unit;
62 int modifier; 64 int modifier;
63 double previous_value; 65 double previous_value;
@@ -87,7 +89,8 @@ HwmonCounter::HwmonCounter(HwmonCounter *next, const sensors_chip_name *chip, co
87 case SENSORS_FEATURE_IN: 89 case SENSORS_FEATURE_IN:
88 title = "Voltage"; 90 title = "Voltage";
89 input = SENSORS_SUBFEATURE_IN_INPUT; 91 input = SENSORS_SUBFEATURE_IN_INPUT;
90 display = "average"; 92 display = "maximum";
93 counter_class = "absolute";
91 unit = "V"; 94 unit = "V";
92 modifier = 1000; 95 modifier = 1000;
93 monotonic = false; 96 monotonic = false;
@@ -96,6 +99,7 @@ HwmonCounter::HwmonCounter(HwmonCounter *next, const sensors_chip_name *chip, co
96 title = "Fan"; 99 title = "Fan";
97 input = SENSORS_SUBFEATURE_FAN_INPUT; 100 input = SENSORS_SUBFEATURE_FAN_INPUT;
98 display = "average"; 101 display = "average";
102 counter_class = "absolute";
99 unit = "RPM"; 103 unit = "RPM";
100 modifier = 1; 104 modifier = 1;
101 monotonic = false; 105 monotonic = false;
@@ -104,6 +108,7 @@ HwmonCounter::HwmonCounter(HwmonCounter *next, const sensors_chip_name *chip, co
104 title = "Temperature"; 108 title = "Temperature";
105 input = SENSORS_SUBFEATURE_TEMP_INPUT; 109 input = SENSORS_SUBFEATURE_TEMP_INPUT;
106 display = "maximum"; 110 display = "maximum";
111 counter_class = "absolute";
107 unit = "°C"; 112 unit = "°C";
108 modifier = 1000; 113 modifier = 1000;
109 monotonic = false; 114 monotonic = false;
@@ -111,7 +116,8 @@ HwmonCounter::HwmonCounter(HwmonCounter *next, const sensors_chip_name *chip, co
111 case SENSORS_FEATURE_POWER: 116 case SENSORS_FEATURE_POWER:
112 title = "Power"; 117 title = "Power";
113 input = SENSORS_SUBFEATURE_POWER_INPUT; 118 input = SENSORS_SUBFEATURE_POWER_INPUT;
114 display = "average"; 119 display = "maximum";
120 counter_class = "absolute";
115 unit = "W"; 121 unit = "W";
116 modifier = 1000000; 122 modifier = 1000000;
117 monotonic = false; 123 monotonic = false;
@@ -120,6 +126,7 @@ HwmonCounter::HwmonCounter(HwmonCounter *next, const sensors_chip_name *chip, co
120 title = "Energy"; 126 title = "Energy";
121 input = SENSORS_SUBFEATURE_ENERGY_INPUT; 127 input = SENSORS_SUBFEATURE_ENERGY_INPUT;
122 display = "accumulate"; 128 display = "accumulate";
129 counter_class = "delta";
123 unit = "J"; 130 unit = "J";
124 modifier = 1000000; 131 modifier = 1000000;
125 monotonic = true; 132 monotonic = true;
@@ -127,7 +134,8 @@ HwmonCounter::HwmonCounter(HwmonCounter *next, const sensors_chip_name *chip, co
127 case SENSORS_FEATURE_CURR: 134 case SENSORS_FEATURE_CURR:
128 title = "Current"; 135 title = "Current";
129 input = SENSORS_SUBFEATURE_CURR_INPUT; 136 input = SENSORS_SUBFEATURE_CURR_INPUT;
130 display = "average"; 137 display = "maximum";
138 counter_class = "absolute";
131 unit = "A"; 139 unit = "A";
132 modifier = 1000; 140 modifier = 1000;
133 monotonic = false; 141 monotonic = false;
@@ -136,6 +144,7 @@ HwmonCounter::HwmonCounter(HwmonCounter *next, const sensors_chip_name *chip, co
136 title = "Humidity"; 144 title = "Humidity";
137 input = SENSORS_SUBFEATURE_HUMIDITY_INPUT; 145 input = SENSORS_SUBFEATURE_HUMIDITY_INPUT;
138 display = "average"; 146 display = "average";
147 counter_class = "absolute";
139 unit = "%"; 148 unit = "%";
140 modifier = 1000; 149 modifier = 1000;
141 monotonic = false; 150 monotonic = false;
@@ -311,6 +320,7 @@ void Hwmon::writeEvents(mxml_node_t *root) const {
311 mxmlElementSetAttr(node, "name", counter->getLabel()); 320 mxmlElementSetAttr(node, "name", counter->getLabel());
312 } 321 }
313 mxmlElementSetAttr(node, "display", counter->getDisplay()); 322 mxmlElementSetAttr(node, "display", counter->getDisplay());
323 mxmlElementSetAttr(node, "class", counter->getCounterClass());
314 mxmlElementSetAttr(node, "units", counter->getUnit()); 324 mxmlElementSetAttr(node, "units", counter->getUnit());
315 if (counter->getModifier() != 1) { 325 if (counter->getModifier() != 1) {
316 mxmlElementSetAttrf(node, "modifier", "%d", counter->getModifier()); 326 mxmlElementSetAttrf(node, "modifier", "%d", counter->getModifier());
diff --git a/daemon/KMod.cpp b/daemon/KMod.cpp
index 9300002..73e123d 100644
--- a/daemon/KMod.cpp
+++ b/daemon/KMod.cpp
@@ -58,10 +58,15 @@ void KMod::setupCounter(Counter &counter) {
58 return; 58 return;
59 } 59 }
60 60
61 int value = 0;
61 snprintf(text, sizeof(text), "%s/key", base); 62 snprintf(text, sizeof(text), "%s/key", base);
62 int key = 0; 63 DriverSource::readIntDriver(text, &value);
63 DriverSource::readIntDriver(text, &key); 64 counter.setKey(value);
64 counter.setKey(key); 65
66 snprintf(text, sizeof(text), "%s/cores", base);
67 if (DriverSource::readIntDriver(text, &value) == 0) {
68 counter.setCores(value);
69 }
65 70
66 snprintf(text, sizeof(text), "%s/event", base); 71 snprintf(text, sizeof(text), "%s/event", base);
67 DriverSource::writeDriver(text, counter.getEvent()); 72 DriverSource::writeDriver(text, counter.getEvent());
diff --git a/daemon/LocalCapture.h b/daemon/LocalCapture.h
index aadecce..b1e7219 100644
--- a/daemon/LocalCapture.h
+++ b/daemon/LocalCapture.h
@@ -23,4 +23,4 @@ private:
23 int removeDirAndAllContents(char* path); 23 int removeDirAndAllContents(char* path);
24}; 24};
25 25
26#endif //__LOCAL_CAPTURE_H__ 26#endif //__LOCAL_CAPTURE_H__
diff --git a/daemon/Logging.h b/daemon/Logging.h
index 6ae3280..4934bb0 100644
--- a/daemon/Logging.h
+++ b/daemon/Logging.h
@@ -33,4 +33,4 @@ extern Logging* logg;
33 33
34extern void handleException() __attribute__ ((noreturn)); 34extern void handleException() __attribute__ ((noreturn));
35 35
36#endif //__LOGGING_H__ 36#endif //__LOGGING_H__
diff --git a/daemon/Makefile b/daemon/Makefile
index 24ee940..2ed49fd 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -8,14 +8,14 @@
8# targets run 'make SOFTFLOAT=1 SYSROOT=/path/to/sysroot', see 8# targets run 'make SOFTFLOAT=1 SYSROOT=/path/to/sysroot', see
9# README_Streamline.txt for more details 9# README_Streamline.txt for more details
10 10
11CPP = $(CROSS_COMPILE)g++ 11CC = $(CROSS_COMPILE)gcc
12GCC = $(CROSS_COMPILE)gcc 12CXX = $(CROSS_COMPILE)g++
13 13
14# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc 14# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc
15CFLAGS += -mthumb-interwork 15CPPFLAGS += -mthumb-interwork
16 16
17ifeq ($(SOFTFLOAT),1) 17ifeq ($(SOFTFLOAT),1)
18 CFLAGS += -marm -march=armv4t -mfloat-abi=soft 18 CPPFLAGS += -marm -march=armv4t -mfloat-abi=soft
19 LDFLAGS += -marm -march=armv4t -mfloat-abi=soft 19 LDFLAGS += -marm -march=armv4t -mfloat-abi=soft
20endif 20endif
21ifneq ($(SYSROOT),) 21ifneq ($(SYSROOT),)
diff --git a/daemon/Makefile_aarch64 b/daemon/Makefile_aarch64
index 10b4b4a..efd1fa0 100644
--- a/daemon/Makefile_aarch64
+++ b/daemon/Makefile_aarch64
@@ -4,12 +4,9 @@
4# 4#
5 5
6# Uncomment and define CROSS_COMPILE if it is not already defined 6# Uncomment and define CROSS_COMPILE if it is not already defined
7# CROSS_COMPILE=/path/to/cross-compiler/arm-linux-gnueabihf- 7# CROSS_COMPILE=/path/to/cross-compiler/aarch64-linux-gnu-
8# NOTE: This toolchain uses the hardfloat abi by default. For non-hardfloat
9# targets it is necessary to add options
10# '-marm -march=armv4t -mfloat-abi=soft'.
11 8
12CPP = $(CROSS_COMPILE)g++ 9CC = $(CROSS_COMPILE)gcc
13GCC = $(CROSS_COMPILE)gcc 10CXX = $(CROSS_COMPILE)g++
14 11
15include common.mk 12include common.mk
diff --git a/daemon/MaliVideoDriver.cpp b/daemon/MaliVideoDriver.cpp
new file mode 100644
index 0000000..18b413b
--- /dev/null
+++ b/daemon/MaliVideoDriver.cpp
@@ -0,0 +1,253 @@
1/**
2 * Copyright (C) ARM Limited 2014. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include "MaliVideoDriver.h"
10
11#include <unistd.h>
12
13#include "Buffer.h"
14#include "Counter.h"
15#include "Logging.h"
16#include "SessionData.h"
17
18// From instr/src/mve_instr_comm_protocol.h
19typedef enum mve_instr_configuration_type {
20 MVE_INSTR_RAW = 1 << 0,
21 MVE_INSTR_COUNTERS = 1 << 1,
22 MVE_INSTR_EVENTS = 1 << 2,
23 MVE_INSTR_ACTIVITIES = 1 << 3,
24
25 // Raw always pushed regardless
26 MVE_INSTR_PULL = 1 << 12,
27 // Raw always unpacked regardless
28 MVE_INSTR_PACKED_COMM = 1 << 13,
29 // Don’t send ACKt response
30 MVE_INSTR_NO_AUTO_ACK = 1 << 14,
31} mve_instr_configuration_type_t;
32
33static const char COUNTER[] = "ARM_Mali-V500_cnt";
34static const char EVENT[] = "ARM_Mali-V500_evn";
35static const char ACTIVITY[] = "ARM_Mali-V500_act";
36
37class MaliVideoCounter {
38public:
39 MaliVideoCounter(MaliVideoCounter *next, const char *name, const MaliVideoCounterType type, const int id) : mNext(next), mName(name), mType(type), mId(id), mKey(getEventKey()), mEnabled(false) {
40 }
41
42 ~MaliVideoCounter() {
43 delete mName;
44 }
45
46 MaliVideoCounter *getNext() const { return mNext; }
47 const char *getName() const { return mName; }
48 MaliVideoCounterType getType() const { return mType; }
49 int getId() const { return mId; }
50 int getKey() const { return mKey; }
51 bool isEnabled() const { return mEnabled; }
52 void setEnabled(const bool enabled) { mEnabled = enabled; }
53
54private:
55 MaliVideoCounter *const mNext;
56 const char *const mName;
57 const MaliVideoCounterType mType;
58 // Mali Video id
59 const int mId;
60 // Streamline key
61 const int mKey;
62 bool mEnabled;
63};
64
65MaliVideoDriver::MaliVideoDriver() : mCounters(NULL), mActivityCount(0) {
66}
67
68MaliVideoDriver::~MaliVideoDriver() {
69 while (mCounters != NULL) {
70 MaliVideoCounter *counter = mCounters;
71 mCounters = counter->getNext();
72 delete counter;
73 }
74}
75
76void MaliVideoDriver::setup(mxml_node_t *const xml) {
77 // hwmon does not currently work with perf
78 if (gSessionData->perf.isSetup()) {
79 return;
80 }
81
82 mxml_node_t *node = xml;
83 while (true) {
84 node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
85 if (node == NULL) {
86 break;
87 }
88 const char *counter = mxmlElementGetAttr(node, "counter");
89 if (counter == NULL) {
90 // Ignore
91 } else if (strncmp(counter, COUNTER, sizeof(COUNTER) - 1) == 0) {
92 const int i = strtol(counter + sizeof(COUNTER) - 1, NULL, 10);
93 mCounters = new MaliVideoCounter(mCounters, strdup(counter), MVCT_COUNTER, i);
94 } else if (strncmp(counter, EVENT, sizeof(EVENT) - 1) == 0) {
95 const int i = strtol(counter + sizeof(EVENT) - 1, NULL, 10);
96 mCounters = new MaliVideoCounter(mCounters, strdup(counter), MVCT_EVENT, i);
97 } else if (strcmp(counter, ACTIVITY) == 0) {
98 mCounters = new MaliVideoCounter(mCounters, strdup(ACTIVITY), MVCT_ACTIVITY, 0);
99 mActivityCount = 0;
100 while (true) {
101 char buf[32];
102 snprintf(buf, sizeof(buf), "activity%i", mActivityCount + 1);
103 if (mxmlElementGetAttr(node, buf) == NULL) {
104 break;
105 }
106 ++mActivityCount;
107 }
108 }
109 }
110}
111
112MaliVideoCounter *MaliVideoDriver::findCounter(const Counter &counter) const {
113 for (MaliVideoCounter *maliVideoCounter = mCounters; maliVideoCounter != NULL; maliVideoCounter = maliVideoCounter->getNext()) {
114 if (strcmp(maliVideoCounter->getName(), counter.getType()) == 0) {
115 return maliVideoCounter;
116 }
117 }
118
119 return NULL;
120}
121
122bool MaliVideoDriver::claimCounter(const Counter &counter) const {
123 return findCounter(counter) != NULL;
124}
125
126bool MaliVideoDriver::countersEnabled() const {
127 for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
128 if (counter->isEnabled()) {
129 return true;
130 }
131 }
132 return false;
133}
134
135void MaliVideoDriver::resetCounters() {
136 for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
137 counter->setEnabled(false);
138 }
139}
140
141void MaliVideoDriver::setupCounter(Counter &counter) {
142 MaliVideoCounter *const maliVideoCounter = findCounter(counter);
143 if (maliVideoCounter == NULL) {
144 counter.setEnabled(false);
145 return;
146 }
147 maliVideoCounter->setEnabled(true);
148 counter.setKey(maliVideoCounter->getKey());
149}
150
151int MaliVideoDriver::writeCounters(mxml_node_t *root) const {
152 if (access("/dev/mv500", F_OK) != 0) {
153 return 0;
154 }
155
156 int count = 0;
157 for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
158 mxml_node_t *node = mxmlNewElement(root, "counter");
159 mxmlElementSetAttr(node, "name", counter->getName());
160 ++count;
161 }
162
163 return count;
164}
165
166void MaliVideoDriver::marshalEnable(const MaliVideoCounterType type, char *const buf, const size_t bufsize, int &pos) {
167 // size
168 int numEnabled = 0;
169 for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
170 if (counter->isEnabled() && (counter->getType() == type)) {
171 ++numEnabled;
172 }
173 }
174 Buffer::packInt(buf, bufsize, pos, numEnabled*sizeof(uint32_t));
175 for (MaliVideoCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
176 if (counter->isEnabled() && (counter->getType() == type)) {
177 Buffer::packInt(buf, bufsize, pos, counter->getId());
178 }
179 }
180}
181
182bool MaliVideoDriver::start(const int mveUds) {
183 char buf[256];
184 int pos = 0;
185
186 // code - MVE_INSTR_STARTUP
187 buf[pos++] = 'C';
188 buf[pos++] = 'L';
189 buf[pos++] = 'N';
190 buf[pos++] = 'T';
191 // size
192 Buffer::packInt(buf, sizeof(buf), pos, sizeof(uint32_t));
193 // client_version_number
194 Buffer::packInt(buf, sizeof(buf), pos, 1);
195
196 // code - MVE_INSTR_CONFIGURE
197 buf[pos++] = 'C';
198 buf[pos++] = 'N';
199 buf[pos++] = 'F';
200 buf[pos++] = 'G';
201 // size
202 Buffer::packInt(buf, sizeof(buf), pos, 5*sizeof(uint32_t));
203 // configuration
204 Buffer::packInt(buf, sizeof(buf), pos, MVE_INSTR_COUNTERS | MVE_INSTR_EVENTS | MVE_INSTR_ACTIVITIES | MVE_INSTR_PACKED_COMM);
205 // communication_protocol_version
206 Buffer::packInt(buf, sizeof(buf), pos, 1);
207 // data_protocol_version
208 Buffer::packInt(buf, sizeof(buf), pos, 1);
209 // sample_rate - convert samples/second to ms/sample
210 Buffer::packInt(buf, sizeof(buf), pos, 1000/gSessionData->mSampleRate);
211 // live_rate - convert ns/flush to ms/flush
212 Buffer::packInt(buf, sizeof(buf), pos, gSessionData->mLiveRate/1000000);
213
214 // code - MVE_INSTR_ENABLE_COUNTERS
215 buf[pos++] = 'C';
216 buf[pos++] = 'F';
217 buf[pos++] = 'G';
218 buf[pos++] = 'c';
219 marshalEnable(MVCT_COUNTER, buf, sizeof(buf), pos);
220
221 // code - MVE_INSTR_ENABLE_EVENTS
222 buf[pos++] = 'C';
223 buf[pos++] = 'F';
224 buf[pos++] = 'G';
225 buf[pos++] = 'e';
226 marshalEnable(MVCT_EVENT, buf, sizeof(buf), pos);
227
228 /*
229 // code - MVE_INSTR_ENABLE_ACTIVITIES
230 buf[pos++] = 'C';
231 buf[pos++] = 'F';
232 buf[pos++] = 'G';
233 buf[pos++] = 'a';
234 // size
235 Buffer::packInt(buf, sizeof(buf), pos, mActivityCount*sizeof(uint32_t));
236 for (int i = 0; i < mActivityCount; ++i) {
237 // activity_id
238 Buffer::packInt(buf, sizeof(buf), pos, i);
239 }
240 */
241
242 int written = 0;
243 while (written < pos) {
244 size_t bytes = ::write(mveUds, buf + written, pos - written);
245 if (bytes <= 0) {
246 logg->logMessage("%s(%s:%i): write failed", __FUNCTION__, __FILE__, __LINE__);
247 return false;
248 }
249 written += bytes;
250 }
251
252 return true;
253}
diff --git a/daemon/MaliVideoDriver.h b/daemon/MaliVideoDriver.h
new file mode 100644
index 0000000..00cb808
--- /dev/null
+++ b/daemon/MaliVideoDriver.h
@@ -0,0 +1,50 @@
1/**
2 * Copyright (C) ARM Limited 2014. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef MALIVIDEODRIVER_H
10#define MALIVIDEODRIVER_H
11
12#include "Driver.h"
13
14class MaliVideoCounter;
15
16enum MaliVideoCounterType {
17 MVCT_COUNTER,
18 MVCT_EVENT,
19 MVCT_ACTIVITY,
20};
21
22class MaliVideoDriver : public Driver {
23public:
24 MaliVideoDriver();
25 ~MaliVideoDriver();
26
27 void setup(mxml_node_t *const xml);
28
29 bool claimCounter(const Counter &counter) const;
30 bool countersEnabled() const;
31 void resetCounters();
32 void setupCounter(Counter &counter);
33
34 int writeCounters(mxml_node_t *root) const;
35
36 bool start(const int mveUds);
37
38private:
39 MaliVideoCounter *findCounter(const Counter &counter) const;
40 void marshalEnable(const MaliVideoCounterType type, char *const buf, const size_t bufsize, int &pos);
41
42 MaliVideoCounter *mCounters;
43 int mActivityCount;
44
45 // Intentionally unimplemented
46 MaliVideoDriver(const MaliVideoDriver &);
47 MaliVideoDriver &operator=(const MaliVideoDriver &);
48};
49
50#endif // MALIVIDEODRIVER_H
diff --git a/daemon/Monitor.cpp b/daemon/Monitor.cpp
index 90d5c47..b34a15f 100644
--- a/daemon/Monitor.cpp
+++ b/daemon/Monitor.cpp
@@ -18,8 +18,15 @@ Monitor::Monitor() : mFd(-1) {
18} 18}
19 19
20Monitor::~Monitor() { 20Monitor::~Monitor() {
21 if (mFd >= -1) { 21 if (mFd >= 0) {
22 close(mFd); 22 ::close(mFd);
23 }
24}
25
26void Monitor::close() {
27 if (mFd >= 0) {
28 ::close(mFd);
29 mFd = -1;
23 } 30 }
24} 31}
25 32
diff --git a/daemon/Monitor.h b/daemon/Monitor.h
index 6e268b6..7194e0e 100644
--- a/daemon/Monitor.h
+++ b/daemon/Monitor.h
@@ -16,6 +16,7 @@ public:
16 Monitor(); 16 Monitor();
17 ~Monitor(); 17 ~Monitor();
18 18
19 void close();
19 bool init(); 20 bool init();
20 bool add(const int fd); 21 bool add(const int fd);
21 int wait(struct epoll_event *const events, int maxevents, int timeout); 22 int wait(struct epoll_event *const events, int maxevents, int timeout);
diff --git a/daemon/OlySocket.cpp b/daemon/OlySocket.cpp
index 26e4768..28774e3 100644
--- a/daemon/OlySocket.cpp
+++ b/daemon/OlySocket.cpp
@@ -9,6 +9,7 @@
9#include "OlySocket.h" 9#include "OlySocket.h"
10 10
11#include <stdio.h> 11#include <stdio.h>
12#include <string.h>
12#ifdef WIN32 13#ifdef WIN32
13#include <Winsock2.h> 14#include <Winsock2.h>
14#include <ws2tcpip.h> 15#include <ws2tcpip.h>
@@ -43,16 +44,18 @@ OlyServerSocket::OlyServerSocket(int port) {
43 createServerSocket(port); 44 createServerSocket(port);
44} 45}
45 46
46OlySocket::OlySocket(int port, const char* host) {
47 createClientSocket(host, port);
48}
49
50OlySocket::OlySocket(int socketID) : mSocketID(socketID) { 47OlySocket::OlySocket(int socketID) : mSocketID(socketID) {
51} 48}
52 49
53#ifndef WIN32 50#ifndef WIN32
54 51
55OlyServerSocket::OlyServerSocket(const char* path) { 52#define MIN(A, B) ({ \
53 const __typeof__(A) __a = A; \
54 const __typeof__(B) __b = B; \
55 __a > __b ? __b : __a; \
56})
57
58OlyServerSocket::OlyServerSocket(const char* path, const size_t pathSize) {
56 // Create socket 59 // Create socket
57 mFDServer = socket(PF_UNIX, SOCK_STREAM, 0); 60 mFDServer = socket(PF_UNIX, SOCK_STREAM, 0);
58 if (mFDServer < 0) { 61 if (mFDServer < 0) {
@@ -60,13 +63,11 @@ OlyServerSocket::OlyServerSocket(const char* path) {
60 handleException(); 63 handleException();
61 } 64 }
62 65
63 unlink(path);
64
65 // Create sockaddr_in structure, ensuring non-populated fields are zero 66 // Create sockaddr_in structure, ensuring non-populated fields are zero
66 struct sockaddr_un sockaddr; 67 struct sockaddr_un sockaddr;
67 memset((void*)&sockaddr, 0, sizeof(sockaddr)); 68 memset((void*)&sockaddr, 0, sizeof(sockaddr));
68 sockaddr.sun_family = AF_UNIX; 69 sockaddr.sun_family = AF_UNIX;
69 strncpy(sockaddr.sun_path, path, sizeof(sockaddr.sun_path) - 1); 70 memcpy(sockaddr.sun_path, path, MIN(pathSize, sizeof(sockaddr.sun_path)));
70 sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0'; 71 sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0';
71 72
72 // Bind the socket to an address 73 // Bind the socket to an address
@@ -82,24 +83,25 @@ OlyServerSocket::OlyServerSocket(const char* path) {
82 } 83 }
83} 84}
84 85
85OlySocket::OlySocket(const char* path) { 86int OlySocket::connect(const char* path, const size_t pathSize) {
86 mSocketID = socket(PF_UNIX, SOCK_STREAM, 0); 87 int fd = socket(PF_UNIX, SOCK_STREAM, 0);
87 if (mSocketID < 0) { 88 if (fd < 0) {
88 return; 89 return -1;
89 } 90 }
90 91
91 // Create sockaddr_in structure, ensuring non-populated fields are zero 92 // Create sockaddr_in structure, ensuring non-populated fields are zero
92 struct sockaddr_un sockaddr; 93 struct sockaddr_un sockaddr;
93 memset((void*)&sockaddr, 0, sizeof(sockaddr)); 94 memset((void*)&sockaddr, 0, sizeof(sockaddr));
94 sockaddr.sun_family = AF_UNIX; 95 sockaddr.sun_family = AF_UNIX;
95 strncpy(sockaddr.sun_path, path, sizeof(sockaddr.sun_path) - 1); 96 memcpy(sockaddr.sun_path, path, MIN(pathSize, sizeof(sockaddr.sun_path)));
96 sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0'; 97 sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0';
97 98
98 if (connect(mSocketID, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) { 99 if (::connect(fd, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
99 close(mSocketID); 100 close(fd);
100 mSocketID = -1; 101 return -1;
101 return;
102 } 102 }
103
104 return fd;
103} 105}
104 106
105#endif 107#endif
@@ -137,47 +139,6 @@ void OlyServerSocket::closeServerSocket() {
137 mFDServer = 0; 139 mFDServer = 0;
138} 140}
139 141
140void OlySocket::createClientSocket(const char* hostname, int portno) {
141#ifdef WIN32
142 // TODO: Implement for Windows
143#else
144 char buf[32];
145 struct addrinfo hints, *res, *res0;
146
147 snprintf(buf, sizeof(buf), "%d", portno);
148 mSocketID = -1;
149 memset((void*)&hints, 0, sizeof(hints));
150 hints.ai_family = PF_UNSPEC;
151 hints.ai_socktype = SOCK_STREAM;
152
153 if (getaddrinfo(hostname, buf, &hints, &res0)) {
154 logg->logError(__FILE__, __LINE__, "Client socket failed to get address info for %s", hostname);
155 handleException();
156 }
157 for (res=res0; res!=NULL; res = res->ai_next) {
158 if ( res->ai_family != PF_INET || res->ai_socktype != SOCK_STREAM ) {
159 continue;
160 }
161 mSocketID = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
162 if (mSocketID < 0) {
163 continue;
164 }
165 if (connect(mSocketID, res->ai_addr, res->ai_addrlen) < 0) {
166 close(mSocketID);
167 mSocketID = -1;
168 }
169 if (mSocketID > 0) {
170 break;
171 }
172 }
173 freeaddrinfo(res0);
174 if (mSocketID <= 0) {
175 logg->logError(__FILE__, __LINE__, "Could not connect to client socket. Ensure ARM Streamline is running.");
176 handleException();
177 }
178#endif
179}
180
181void OlyServerSocket::createServerSocket(int port) { 142void OlyServerSocket::createServerSocket(int port) {
182 int family = AF_INET6; 143 int family = AF_INET6;
183 144
diff --git a/daemon/OlySocket.h b/daemon/OlySocket.h
index eab786b..20c67cc 100644
--- a/daemon/OlySocket.h
+++ b/daemon/OlySocket.h
@@ -9,13 +9,15 @@
9#ifndef __OLY_SOCKET_H__ 9#ifndef __OLY_SOCKET_H__
10#define __OLY_SOCKET_H__ 10#define __OLY_SOCKET_H__
11 11
12#include <stddef.h>
13
12class OlySocket { 14class OlySocket {
13public: 15public:
14 OlySocket(int port, const char* hostname);
15 OlySocket(int socketID);
16#ifndef WIN32 16#ifndef WIN32
17 OlySocket(const char* path); 17 static int connect(const char* path, const size_t pathSize);
18#endif 18#endif
19
20 OlySocket(int socketID);
19 ~OlySocket(); 21 ~OlySocket();
20 22
21 void closeSocket(); 23 void closeSocket();
@@ -29,21 +31,21 @@ public:
29 31
30private: 32private:
31 int mSocketID; 33 int mSocketID;
32
33 void createClientSocket(const char* hostname, int port);
34}; 34};
35 35
36class OlyServerSocket { 36class OlyServerSocket {
37public: 37public:
38 OlyServerSocket(int port); 38 OlyServerSocket(int port);
39#ifndef WIN32 39#ifndef WIN32
40 OlyServerSocket(const char* path); 40 OlyServerSocket(const char* path, const size_t pathSize);
41#endif 41#endif
42 ~OlyServerSocket(); 42 ~OlyServerSocket();
43 43
44 int acceptConnection(); 44 int acceptConnection();
45 void closeServerSocket(); 45 void closeServerSocket();
46 46
47 int getFd() { return mFDServer; }
48
47private: 49private:
48 int mFDServer; 50 int mFDServer;
49 51
diff --git a/daemon/PerfDriver.cpp b/daemon/PerfDriver.cpp
index 8e25c22..ac97a07 100644
--- a/daemon/PerfDriver.cpp
+++ b/daemon/PerfDriver.cpp
@@ -11,6 +11,7 @@
11#include <dirent.h> 11#include <dirent.h>
12#include <sys/utsname.h> 12#include <sys/utsname.h>
13#include <time.h> 13#include <time.h>
14#include <unistd.h>
14 15
15#include "Buffer.h" 16#include "Buffer.h"
16#include "Config.h" 17#include "Config.h"
@@ -30,7 +31,7 @@
30struct gator_cpu { 31struct gator_cpu {
31 const int cpuid; 32 const int cpuid;
32 // Human readable name 33 // Human readable name
33 const char core_name[32]; 34 const char *const core_name;
34 // gatorfs event and Perf PMU name 35 // gatorfs event and Perf PMU name
35 const char *const pmnc_name; 36 const char *const pmnc_name;
36 const int pmnc_counters; 37 const int pmnc_counters;
@@ -62,9 +63,20 @@ static const struct gator_cpu gator_cpus[] = {
62static const char OLD_PMU_PREFIX[] = "ARMv7 Cortex-"; 63static const char OLD_PMU_PREFIX[] = "ARMv7 Cortex-";
63static const char NEW_PMU_PREFIX[] = "ARMv7_Cortex_"; 64static const char NEW_PMU_PREFIX[] = "ARMv7_Cortex_";
64 65
66struct uncore_counter {
67 // gatorfs event and Perf PMU name
68 const char *const name;
69 const int count;
70};
71
72static const struct uncore_counter uncore_counters[] = {
73 { "CCI_400", 4 },
74 { "CCI_400-r1", 4 },
75};
76
65class PerfCounter { 77class PerfCounter {
66public: 78public:
67 PerfCounter(PerfCounter *next, const char *name, uint32_t type, uint64_t config) : mNext(next), mName(name), mType(type), mCount(0), mKey(getEventKey()), mConfig(config), mEnabled(false) {} 79 PerfCounter(PerfCounter *next, const char *name, uint32_t type, uint64_t config, bool perCpu) : mNext(next), mName(name), mType(type), mCount(0), mKey(getEventKey()), mConfig(config), mEnabled(false), mPerCpu(perCpu) {}
68 ~PerfCounter() { 80 ~PerfCounter() {
69 delete [] mName; 81 delete [] mName;
70 } 82 }
@@ -79,6 +91,7 @@ public:
79 void setConfig(const uint64_t config) { mConfig = config; } 91 void setConfig(const uint64_t config) { mConfig = config; }
80 bool isEnabled() const { return mEnabled; } 92 bool isEnabled() const { return mEnabled; }
81 void setEnabled(const bool enabled) { mEnabled = enabled; } 93 void setEnabled(const bool enabled) { mEnabled = enabled; }
94 bool isPerCpu() const { return mPerCpu; }
82 95
83private: 96private:
84 PerfCounter *const mNext; 97 PerfCounter *const mNext;
@@ -87,10 +100,11 @@ private:
87 int mCount; 100 int mCount;
88 const int mKey; 101 const int mKey;
89 uint64_t mConfig; 102 uint64_t mConfig;
90 bool mEnabled; 103 int mEnabled : 1,
104 mPerCpu : 1;
91}; 105};
92 106
93PerfDriver::PerfDriver() : mCounters(NULL), mIsSetup(false) { 107PerfDriver::PerfDriver() : mCounters(NULL), mIsSetup(false), mLegacySupport(false) {
94} 108}
95 109
96PerfDriver::~PerfDriver() { 110PerfDriver::~PerfDriver() {
@@ -105,13 +119,27 @@ void PerfDriver::addCpuCounters(const char *const counterName, const int type, c
105 int len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1; 119 int len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1;
106 char *name = new char[len]; 120 char *name = new char[len];
107 snprintf(name, len, "%s_ccnt", counterName); 121 snprintf(name, len, "%s_ccnt", counterName);
108 mCounters = new PerfCounter(mCounters, name, type, -1); 122 mCounters = new PerfCounter(mCounters, name, type, -1, true);
109 123
110 for (int j = 0; j < numCounters; ++j) { 124 for (int j = 0; j < numCounters; ++j) {
111 len = snprintf(NULL, 0, "%s_cnt%d", counterName, j) + 1; 125 len = snprintf(NULL, 0, "%s_cnt%d", counterName, j) + 1;
112 name = new char[len]; 126 name = new char[len];
113 snprintf(name, len, "%s_cnt%d", counterName, j); 127 snprintf(name, len, "%s_cnt%d", counterName, j);
114 mCounters = new PerfCounter(mCounters, name, type, -1); 128 mCounters = new PerfCounter(mCounters, name, type, -1, true);
129 }
130}
131
132void PerfDriver::addUncoreCounters(const char *const counterName, const int type, const int numCounters) {
133 int len = snprintf(NULL, 0, "%s_ccnt", counterName) + 1;
134 char *name = new char[len];
135 snprintf(name, len, "%s_ccnt", counterName);
136 mCounters = new PerfCounter(mCounters, name, type, -1, false);
137
138 for (int j = 0; j < numCounters; ++j) {
139 len = snprintf(NULL, 0, "%s_cnt%d", counterName, j) + 1;
140 name = new char[len];
141 snprintf(name, len, "%s_cnt%d", counterName, j);
142 mCounters = new PerfCounter(mCounters, name, type, -1, false);
115 } 143 }
116} 144}
117 145
@@ -139,10 +167,16 @@ bool PerfDriver::setup() {
139 } 167 }
140 } 168 }
141 169
142 if (KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 12, 0)) { 170 if (KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 4, 0)) {
143 logg->logMessage("%s(%s:%i): Unsupported kernel version", __FUNCTION__, __FILE__, __LINE__); 171 logg->logMessage("%s(%s:%i): Unsupported kernel version", __FUNCTION__, __FILE__, __LINE__);
144 return false; 172 return false;
145 } 173 }
174 mLegacySupport = KERNEL_VERSION(release[0], release[1], release[2]) < KERNEL_VERSION(3, 12, 0);
175
176 if (access(EVENTS_PATH, R_OK) != 0) {
177 logg->logMessage("%s(%s:%i): " EVENTS_PATH " does not exist, is CONFIG_TRACING enabled?", __FUNCTION__, __FILE__, __LINE__);
178 return false;
179 }
146 180
147 // Add supported PMUs 181 // Add supported PMUs
148 bool foundCpu = false; 182 bool foundCpu = false;
@@ -174,6 +208,21 @@ bool PerfDriver::setup() {
174 foundCpu = true; 208 foundCpu = true;
175 addCpuCounters(gator_cpus[i].pmnc_name, type, gator_cpus[i].pmnc_counters); 209 addCpuCounters(gator_cpus[i].pmnc_name, type, gator_cpus[i].pmnc_counters);
176 } 210 }
211
212 for (int i = 0; i < ARRAY_LENGTH(uncore_counters); ++i) {
213 if (strcmp(dirent->d_name, uncore_counters[i].name) != 0) {
214 continue;
215 }
216
217 int type;
218 char buf[256];
219 snprintf(buf, sizeof(buf), PERF_DEVICES "/%s/type", dirent->d_name);
220 if (DriverSource::readIntDriver(buf, &type) != 0) {
221 continue;
222 }
223
224 addUncoreCounters(uncore_counters[i].name, type, uncore_counters[i].count);
225 }
177 } 226 }
178 closedir(dir); 227 closedir(dir);
179 228
@@ -203,12 +252,12 @@ bool PerfDriver::setup() {
203 252
204 id = getTracepointId("irq/softirq_exit", &printb); 253 id = getTracepointId("irq/softirq_exit", &printb);
205 if (id >= 0) { 254 if (id >= 0) {
206 mCounters = new PerfCounter(mCounters, "Linux_irq_softirq", PERF_TYPE_TRACEPOINT, id); 255 mCounters = new PerfCounter(mCounters, "Linux_irq_softirq", PERF_TYPE_TRACEPOINT, id, true);
207 } 256 }
208 257
209 id = getTracepointId("irq/irq_handler_exit", &printb); 258 id = getTracepointId("irq/irq_handler_exit", &printb);
210 if (id >= 0) { 259 if (id >= 0) {
211 mCounters = new PerfCounter(mCounters, "Linux_irq_irq", PERF_TYPE_TRACEPOINT, id); 260 mCounters = new PerfCounter(mCounters, "Linux_irq_irq", PERF_TYPE_TRACEPOINT, id, true);
212 } 261 }
213 262
214 //Linux_block_rq_wr 263 //Linux_block_rq_wr
@@ -218,7 +267,7 @@ bool PerfDriver::setup() {
218 267
219 id = getTracepointId(SCHED_SWITCH, &printb); 268 id = getTracepointId(SCHED_SWITCH, &printb);
220 if (id >= 0) { 269 if (id >= 0) {
221 mCounters = new PerfCounter(mCounters, "Linux_sched_switch", PERF_TYPE_TRACEPOINT, id); 270 mCounters = new PerfCounter(mCounters, "Linux_sched_switch", PERF_TYPE_TRACEPOINT, id, true);
222 } 271 }
223 272
224 //Linux_meminfo_memused 273 //Linux_meminfo_memused
@@ -227,7 +276,7 @@ bool PerfDriver::setup() {
227 //Linux_power_cpu_freq 276 //Linux_power_cpu_freq
228 //Linux_power_cpu_idle 277 //Linux_power_cpu_idle
229 278
230 mCounters = new PerfCounter(mCounters, "Linux_cpu_wait_contention", TYPE_DERIVED, -1); 279 mCounters = new PerfCounter(mCounters, "Linux_cpu_wait_contention", TYPE_DERIVED, -1, false);
231 280
232 //Linux_cpu_wait_io 281 //Linux_cpu_wait_io
233 282
@@ -252,15 +301,16 @@ bool PerfDriver::summary(Buffer *const buffer) {
252 } 301 }
253 const int64_t timestamp = (int64_t)ts.tv_sec * 1000000000L + ts.tv_nsec; 302 const int64_t timestamp = (int64_t)ts.tv_sec * 1000000000L + ts.tv_nsec;
254 303
255 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { 304 const int64_t uptime = getTime();
256 logg->logMessage("%s(%s:%i): clock_gettime failed", __FUNCTION__, __FILE__, __LINE__);
257 return false;
258 }
259 const int64_t uptime = (int64_t)ts.tv_sec * 1000000000L + ts.tv_nsec;
260 305
261 buffer->summary(timestamp, uptime, 0, buf); 306 buffer->summary(timestamp, uptime, 0, buf);
262 307
263 for (int i = 0; i < gSessionData->mCores; ++i) { 308 for (int i = 0; i < gSessionData->mCores; ++i) {
309 // Don't send information on a cpu we know nothing about
310 if (gSessionData->mCpuIds[i] == -1) {
311 continue;
312 }
313
264 int j; 314 int j;
265 for (j = 0; j < ARRAY_LENGTH(gator_cpus); ++j) { 315 for (j = 0; j < ARRAY_LENGTH(gator_cpus); ++j) {
266 if (gator_cpus[j].cpuid == gSessionData->mCpuIds[i]) { 316 if (gator_cpus[j].cpuid == gSessionData->mCpuIds[i]) {
@@ -270,7 +320,11 @@ bool PerfDriver::summary(Buffer *const buffer) {
270 if (gator_cpus[j].cpuid == gSessionData->mCpuIds[i]) { 320 if (gator_cpus[j].cpuid == gSessionData->mCpuIds[i]) {
271 buffer->coreName(i, gSessionData->mCpuIds[i], gator_cpus[j].core_name); 321 buffer->coreName(i, gSessionData->mCpuIds[i], gator_cpus[j].core_name);
272 } else { 322 } else {
273 snprintf(buf, sizeof(buf), "Unknown (0x%.3x)", gSessionData->mCpuIds[i]); 323 if (gSessionData->mCpuIds[i] == -1) {
324 snprintf(buf, sizeof(buf), "Unknown");
325 } else {
326 snprintf(buf, sizeof(buf), "Unknown (0x%.3x)", gSessionData->mCpuIds[i]);
327 }
274 buffer->coreName(i, gSessionData->mCpuIds[i], buf); 328 buffer->coreName(i, gSessionData->mCpuIds[i], buf);
275 } 329 }
276 } 330 }
@@ -326,10 +380,10 @@ int PerfDriver::writeCounters(mxml_node_t *root) const {
326 return count; 380 return count;
327} 381}
328 382
329bool PerfDriver::enable(PerfGroup *group, Buffer *const buffer) const { 383bool PerfDriver::enable(PerfGroup *const group, Buffer *const buffer) const {
330 for (PerfCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) { 384 for (PerfCounter * counter = mCounters; counter != NULL; counter = counter->getNext()) {
331 if (counter->isEnabled() && (counter->getType() != TYPE_DERIVED)) { 385 if (counter->isEnabled() && (counter->getType() != TYPE_DERIVED)) {
332 if (!group->add(buffer, counter->getKey(), counter->getType(), counter->getConfig(), counter->getCount(), 0, 0)) { 386 if (!group->add(buffer, counter->getKey(), counter->getType(), counter->getConfig(), counter->getCount(), counter->getCount() > 0 ? PERF_SAMPLE_TID | PERF_SAMPLE_IP : 0, counter->isPerCpu() ? PERF_GROUP_PER_CPU : 0)) {
333 logg->logMessage("%s(%s:%i): PerfGroup::add failed", __FUNCTION__, __FILE__, __LINE__); 387 logg->logMessage("%s(%s:%i): PerfGroup::add failed", __FUNCTION__, __FILE__, __LINE__);
334 return false; 388 return false;
335 } 389 }
diff --git a/daemon/PerfDriver.h b/daemon/PerfDriver.h
index 3181b74..2cae575 100644
--- a/daemon/PerfDriver.h
+++ b/daemon/PerfDriver.h
@@ -27,6 +27,8 @@ public:
27 PerfDriver(); 27 PerfDriver();
28 ~PerfDriver(); 28 ~PerfDriver();
29 29
30 bool getLegacySupport() const { return mLegacySupport; }
31
30 bool setup(); 32 bool setup();
31 bool summary(Buffer *const buffer); 33 bool summary(Buffer *const buffer);
32 bool isSetup() const { return mIsSetup; } 34 bool isSetup() const { return mIsSetup; }
@@ -37,16 +39,18 @@ public:
37 39
38 int writeCounters(mxml_node_t *root) const; 40 int writeCounters(mxml_node_t *root) const;
39 41
40 bool enable(PerfGroup *group, Buffer *const buffer) const; 42 bool enable(PerfGroup *const group, Buffer *const buffer) const;
41 43
42 static long long getTracepointId(const char *const name, DynBuf *const printb); 44 static long long getTracepointId(const char *const name, DynBuf *const printb);
43 45
44private: 46private:
45 PerfCounter *findCounter(const Counter &counter) const; 47 PerfCounter *findCounter(const Counter &counter) const;
46 void addCpuCounters(const char *const counterName, const int type, const int numCounters); 48 void addCpuCounters(const char *const counterName, const int type, const int numCounters);
49 void addUncoreCounters(const char *const counterName, const int type, const int numCounters);
47 50
48 PerfCounter *mCounters; 51 PerfCounter *mCounters;
49 bool mIsSetup; 52 bool mIsSetup;
53 bool mLegacySupport;
50 54
51 // Intentionally undefined 55 // Intentionally undefined
52 PerfDriver(const PerfDriver &); 56 PerfDriver(const PerfDriver &);
diff --git a/daemon/PerfGroup.cpp b/daemon/PerfGroup.cpp
index faf5fca..2a0239f 100644
--- a/daemon/PerfGroup.cpp
+++ b/daemon/PerfGroup.cpp
@@ -23,7 +23,9 @@
23#define DEFAULT_PEA_ARGS(pea, additionalSampleType) \ 23#define DEFAULT_PEA_ARGS(pea, additionalSampleType) \
24 pea.size = sizeof(pea); \ 24 pea.size = sizeof(pea); \
25 /* Emit time, read_format below, group leader id, and raw tracepoint info */ \ 25 /* Emit time, read_format below, group leader id, and raw tracepoint info */ \
26 pea.sample_type = PERF_SAMPLE_TIME | PERF_SAMPLE_READ | PERF_SAMPLE_IDENTIFIER | additionalSampleType; \ 26 pea.sample_type = (gSessionData->perf.getLegacySupport() \
27 ? PERF_SAMPLE_TID | PERF_SAMPLE_IP | PERF_SAMPLE_TIME | PERF_SAMPLE_READ | PERF_SAMPLE_ID \
28 : PERF_SAMPLE_TIME | PERF_SAMPLE_READ | PERF_SAMPLE_IDENTIFIER ) | additionalSampleType; \
27 /* Emit emit value in group format */ \ 29 /* Emit emit value in group format */ \
28 pea.read_format = PERF_FORMAT_ID | PERF_FORMAT_GROUP; \ 30 pea.read_format = PERF_FORMAT_ID | PERF_FORMAT_GROUP; \
29 /* start out disabled */ \ 31 /* start out disabled */ \
@@ -39,6 +41,7 @@ static int sys_perf_event_open(struct perf_event_attr *const attr, const pid_t p
39 41
40PerfGroup::PerfGroup(PerfBuffer *const pb) : mPb(pb) { 42PerfGroup::PerfGroup(PerfBuffer *const pb) : mPb(pb) {
41 memset(&mAttrs, 0, sizeof(mAttrs)); 43 memset(&mAttrs, 0, sizeof(mAttrs));
44 memset(&mPerCpu, 0, sizeof(mPerCpu));
42 memset(&mKeys, -1, sizeof(mKeys)); 45 memset(&mKeys, -1, sizeof(mKeys));
43 memset(&mFds, -1, sizeof(mFds)); 46 memset(&mFds, -1, sizeof(mFds));
44} 47}
@@ -75,6 +78,7 @@ bool PerfGroup::add(Buffer *const buffer, const int key, const __u32 type, const
75 mAttrs[i].freq = (flags & PERF_GROUP_FREQ ? 1 : 0); 78 mAttrs[i].freq = (flags & PERF_GROUP_FREQ ? 1 : 0);
76 mAttrs[i].task = (flags & PERF_GROUP_TASK ? 1 : 0); 79 mAttrs[i].task = (flags & PERF_GROUP_TASK ? 1 : 0);
77 mAttrs[i].sample_id_all = (flags & PERF_GROUP_SAMPLE_ID_ALL ? 1 : 0); 80 mAttrs[i].sample_id_all = (flags & PERF_GROUP_SAMPLE_ID_ALL ? 1 : 0);
81 mPerCpu[i] = (flags & PERF_GROUP_PER_CPU);
78 82
79 mKeys[i] = key; 83 mKeys[i] = key;
80 84
@@ -91,13 +95,17 @@ bool PerfGroup::prepareCPU(const int cpu) {
91 continue; 95 continue;
92 } 96 }
93 97
98 if ((cpu != 0) && !mPerCpu[i]) {
99 continue;
100 }
101
94 const int offset = i * gSessionData->mCores; 102 const int offset = i * gSessionData->mCores;
95 if (mFds[cpu + offset] >= 0) { 103 if (mFds[cpu + offset] >= 0) {
96 logg->logMessage("%s(%s:%i): cpu already online or not correctly cleaned up", __FUNCTION__, __FILE__, __LINE__); 104 logg->logMessage("%s(%s:%i): cpu already online or not correctly cleaned up", __FUNCTION__, __FILE__, __LINE__);
97 return false; 105 return false;
98 } 106 }
99 107
100 logg->logMessage("%s(%s:%i): perf_event_open cpu: %i type: %lli config: %lli sample: %lli sample_type: %lli", __FUNCTION__, __FILE__, __LINE__, cpu, (long long)mAttrs[i].type, (long long)mAttrs[i].config, (long long)mAttrs[i].sample_period, (long long)mAttrs[i].sample_type); 108 logg->logMessage("%s(%s:%i): perf_event_open cpu: %i type: %lli config: %lli sample: %lli sample_type: 0x%llx pinned: %i mmap: %i comm: %i freq: %i task: %i sample_id_all: %i", __FUNCTION__, __FILE__, __LINE__, cpu, (long long)mAttrs[i].type, (long long)mAttrs[i].config, (long long)mAttrs[i].sample_period, (long long)mAttrs[i].sample_type, mAttrs[i].pinned, mAttrs[i].mmap, mAttrs[i].comm, mAttrs[i].freq, mAttrs[i].task, mAttrs[i].sample_id_all);
101 mFds[cpu + offset] = sys_perf_event_open(&mAttrs[i], -1, cpu, i == 0 ? -1 : mFds[cpu], i == 0 ? 0 : PERF_FLAG_FD_OUTPUT); 109 mFds[cpu + offset] = sys_perf_event_open(&mAttrs[i], -1, cpu, i == 0 ? -1 : mFds[cpu], i == 0 ? 0 : PERF_FLAG_FD_OUTPUT);
102 if (mFds[cpu + offset] < 0) { 110 if (mFds[cpu + offset] < 0) {
103 logg->logMessage("%s(%s:%i): failed %s", __FUNCTION__, __FILE__, __LINE__, strerror(errno)); 111 logg->logMessage("%s(%s:%i): failed %s", __FUNCTION__, __FILE__, __LINE__, strerror(errno));
@@ -125,7 +133,9 @@ int PerfGroup::onlineCPU(const int cpu, const bool start, Buffer *const buffer,
125 } 133 }
126 134
127 coreKeys[idCount] = mKeys[i]; 135 coreKeys[idCount] = mKeys[i];
128 if (ioctl(fd, PERF_EVENT_IOC_ID, &ids[idCount]) != 0) { 136 if (!gSessionData->perf.getLegacySupport() && ioctl(fd, PERF_EVENT_IOC_ID, &ids[idCount]) != 0 &&
137 // Workaround for running 32-bit gatord on 64-bit systems, kernel patch in the works
138 ioctl(fd, (PERF_EVENT_IOC_ID & ~IOCSIZE_MASK) | (8 << _IOC_SIZESHIFT), &ids[idCount]) != 0) {
129 logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__); 139 logg->logMessage("%s(%s:%i): ioctl failed", __FUNCTION__, __FILE__, __LINE__);
130 return false; 140 return false;
131 } 141 }
@@ -137,7 +147,17 @@ int PerfGroup::onlineCPU(const int cpu, const bool start, Buffer *const buffer,
137 return false; 147 return false;
138 } 148 }
139 149
140 buffer->keys(idCount, ids, coreKeys); 150 if (!gSessionData->perf.getLegacySupport()) {
151 buffer->keys(idCount, ids, coreKeys);
152 } else {
153 char buf[1024];
154 ssize_t bytes = read(mFds[cpu], buf, sizeof(buf));
155 if (bytes < 0) {
156 logg->logMessage("read failed");
157 return false;
158 }
159 buffer->keysOld(idCount, coreKeys, bytes, buf);
160 }
141 161
142 if (start) { 162 if (start) {
143 for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) { 163 for (int i = 0; i < ARRAY_LENGTH(mKeys); ++i) {
diff --git a/daemon/PerfGroup.h b/daemon/PerfGroup.h
index af496d4..3f1e2bb 100644
--- a/daemon/PerfGroup.h
+++ b/daemon/PerfGroup.h
@@ -24,6 +24,7 @@ enum PerfGroupFlags {
24 PERF_GROUP_FREQ = 1 << 2, 24 PERF_GROUP_FREQ = 1 << 2,
25 PERF_GROUP_TASK = 1 << 3, 25 PERF_GROUP_TASK = 1 << 3,
26 PERF_GROUP_SAMPLE_ID_ALL = 1 << 4, 26 PERF_GROUP_SAMPLE_ID_ALL = 1 << 4,
27 PERF_GROUP_PER_CPU = 1 << 5,
27}; 28};
28 29
29class PerfGroup { 30class PerfGroup {
@@ -43,6 +44,7 @@ public:
43private: 44private:
44 // +1 for the group leader 45 // +1 for the group leader
45 struct perf_event_attr mAttrs[MAX_PERFORMANCE_COUNTERS + 1]; 46 struct perf_event_attr mAttrs[MAX_PERFORMANCE_COUNTERS + 1];
47 bool mPerCpu[MAX_PERFORMANCE_COUNTERS + 1];
46 int mKeys[MAX_PERFORMANCE_COUNTERS + 1]; 48 int mKeys[MAX_PERFORMANCE_COUNTERS + 1];
47 int mFds[NR_CPUS * (MAX_PERFORMANCE_COUNTERS + 1)]; 49 int mFds[NR_CPUS * (MAX_PERFORMANCE_COUNTERS + 1)];
48 PerfBuffer *const mPb; 50 PerfBuffer *const mPb;
diff --git a/daemon/PerfSource.cpp b/daemon/PerfSource.cpp
index 1f1cb19..ecfaa66 100644
--- a/daemon/PerfSource.cpp
+++ b/daemon/PerfSource.cpp
@@ -37,7 +37,7 @@ static bool sendTracepointFormat(Buffer *const buffer, const char *const name, D
37 return true; 37 return true;
38} 38}
39 39
40PerfSource::PerfSource(sem_t *senderSem, sem_t *startProfile) : mSummary(0, FRAME_SUMMARY, 1024, senderSem), mBuffer(0, FRAME_PERF_ATTRS, 1024*1024, senderSem), mCountersBuf(), mCountersGroup(&mCountersBuf), mMonitor(), mUEvent(), mSenderSem(senderSem), mStartProfile(startProfile), mInterruptFd(-1), mIsDone(false) { 40PerfSource::PerfSource(sem_t *senderSem, sem_t *startProfile) : mSummary(0, FRAME_SUMMARY, 1024, senderSem), mBuffer(0, FRAME_PERF_ATTRS, 4*1024*1024, senderSem), mCountersBuf(), mCountersGroup(&mCountersBuf), mMonitor(), mUEvent(), mSenderSem(senderSem), mStartProfile(startProfile), mInterruptFd(-1), mIsDone(false) {
41 long l = sysconf(_SC_PAGE_SIZE); 41 long l = sysconf(_SC_PAGE_SIZE);
42 if (l < 0) { 42 if (l < 0) {
43 logg->logError(__FILE__, __LINE__, "Unable to obtain the page size"); 43 logg->logError(__FILE__, __LINE__, "Unable to obtain the page size");
@@ -74,6 +74,9 @@ bool PerfSource::prepare() {
74 DynBuf b3; 74 DynBuf b3;
75 long long schedSwitchId; 75 long long schedSwitchId;
76 76
77 // Reread cpuinfo since cores may have changed since startup
78 gSessionData->readCpuInfo();
79
77 if (0 80 if (0
78 || !mMonitor.init() 81 || !mMonitor.init()
79 || !mUEvent.init() 82 || !mUEvent.init()
@@ -83,14 +86,14 @@ bool PerfSource::prepare() {
83 || !sendTracepointFormat(&mBuffer, SCHED_SWITCH, &printb, &b1) 86 || !sendTracepointFormat(&mBuffer, SCHED_SWITCH, &printb, &b1)
84 87
85 // Only want RAW but not IP on sched_switch and don't want TID on SAMPLE_ID 88 // Only want RAW but not IP on sched_switch and don't want TID on SAMPLE_ID
86 || !mCountersGroup.add(&mBuffer, 100/**/, PERF_TYPE_TRACEPOINT, schedSwitchId, 1, PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL) 89 || !mCountersGroup.add(&mBuffer, 100/**/, PERF_TYPE_TRACEPOINT, schedSwitchId, 1, PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL | PERF_GROUP_PER_CPU)
87 90
88 // Only want TID and IP but not RAW on timer 91 // Only want TID and IP but not RAW on timer
89 || (gSessionData->mSampleRate > 0 && !gSessionData->mIsEBS && !mCountersGroup.add(&mBuffer, 99/**/, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData->mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP, 0)) 92 || (gSessionData->mSampleRate > 0 && !gSessionData->mIsEBS && !mCountersGroup.add(&mBuffer, 99/**/, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData->mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP, PERF_GROUP_PER_CPU))
90 93
91 || !gSessionData->perf.enable(&mCountersGroup, &mBuffer) 94 || !gSessionData->perf.enable(&mCountersGroup, &mBuffer)
92 || 0) { 95 || 0) {
93 logg->logMessage("%s(%s:%i): perf setup failed, are you running Linux 3.12 or later?", __FUNCTION__, __FILE__, __LINE__); 96 logg->logMessage("%s(%s:%i): perf setup failed, are you running Linux 3.4 or later?", __FUNCTION__, __FILE__, __LINE__);
94 return false; 97 return false;
95 } 98 }
96 99
@@ -134,7 +137,7 @@ bool PerfSource::prepare() {
134 return false; 137 return false;
135 } 138 }
136 139
137 if (!readProc(&mBuffer, &printb, &b1, &b2, &b3)) { 140 if (!readProc(&mBuffer, true, &printb, &b1, &b2, &b3)) {
138 logg->logMessage("%s(%s:%i): readProc failed", __FUNCTION__, __FILE__, __LINE__); 141 logg->logMessage("%s(%s:%i): readProc failed", __FUNCTION__, __FILE__, __LINE__);
139 return false; 142 return false;
140 } 143 }
@@ -260,6 +263,7 @@ bool PerfSource::isDone () {
260void PerfSource::write (Sender *sender) { 263void PerfSource::write (Sender *sender) {
261 if (!mSummary.isDone()) { 264 if (!mSummary.isDone()) {
262 mSummary.write(sender); 265 mSummary.write(sender);
266 gSessionData->mSentSummary = true;
263 } 267 }
264 if (!mBuffer.isDone()) { 268 if (!mBuffer.isDone()) {
265 mBuffer.write(sender); 269 mBuffer.write(sender);
diff --git a/daemon/Proc.cpp b/daemon/Proc.cpp
index e0b9e22..9f01770 100644
--- a/daemon/Proc.cpp
+++ b/daemon/Proc.cpp
@@ -57,14 +57,57 @@ static bool readProcStat(ProcStat *const ps, const char *const pathname, DynBuf
57 return true; 57 return true;
58} 58}
59 59
60static bool readProcTask(Buffer *const buffer, const int pid, const char *const image, DynBuf *const printb, DynBuf *const b) { 60static const char *readProcExe(DynBuf *const printb, const int pid, const int tid, DynBuf *const b) {
61 if (tid == -1 ? !printb->printf("/proc/%i/exe", pid)
62 : !printb->printf("/proc/%i/task/%i/exe", pid, tid)) {
63 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
64 return NULL;
65 }
66
67 const int err = b->readlink(printb->getBuf());
68 const char *image;
69 if (err == 0) {
70 image = strrchr(b->getBuf(), '/');
71 if (image == NULL) {
72 image = b->getBuf();
73 } else {
74 ++image;
75 }
76 } else if (err == -ENOENT) {
77 // readlink /proc/[pid]/exe returns ENOENT for kernel threads
78 image = "\0";
79 } else {
80 logg->logMessage("%s(%s:%i): DynBuf::readlink failed", __FUNCTION__, __FILE__, __LINE__);
81 return NULL;
82 }
83
84 // Android apps are run by app_process but the cmdline is changed to reference the actual app name
85 if (strcmp(image, "app_process") != 0) {
86 return image;
87 }
88
89 if (tid == -1 ? !printb->printf("/proc/%i/cmdline", pid)
90 : !printb->printf("/proc/%i/task/%i/cmdline", pid, tid)) {
91 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
92 return NULL;
93 }
94
95 if (!b->read(printb->getBuf())) {
96 logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the thread exited", __FUNCTION__, __FILE__, __LINE__);
97 return NULL;
98 }
99
100 return b->getBuf();
101}
102
103static bool readProcTask(Buffer *const buffer, const int pid, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2) {
61 bool result = false; 104 bool result = false;
62 105
63 if (!b->printf("/proc/%i/task", pid)) { 106 if (!b1->printf("/proc/%i/task", pid)) {
64 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); 107 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
65 return result; 108 return result;
66 } 109 }
67 DIR *task = opendir(b->getBuf()); 110 DIR *task = opendir(b1->getBuf());
68 if (task == NULL) { 111 if (task == NULL) {
69 logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__); 112 logg->logMessage("%s(%s:%i): opendir failed", __FUNCTION__, __FILE__, __LINE__);
70 return result; 113 return result;
@@ -84,11 +127,17 @@ static bool readProcTask(Buffer *const buffer, const int pid, const char *const
84 goto fail; 127 goto fail;
85 } 128 }
86 ProcStat ps; 129 ProcStat ps;
87 if (!readProcStat(&ps, printb->getBuf(), b)) { 130 if (!readProcStat(&ps, printb->getBuf(), b1)) {
88 logg->logMessage("%s(%s:%i): readProcStat failed", __FUNCTION__, __FILE__, __LINE__); 131 logg->logMessage("%s(%s:%i): readProcStat failed", __FUNCTION__, __FILE__, __LINE__);
89 goto fail; 132 goto fail;
90 } 133 }
91 134
135 const char *const image = readProcExe(printb, pid, tid, b2);
136 if (image == NULL) {
137 logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__);
138 goto fail;
139 }
140
92 buffer->comm(pid, tid, image, ps.comm); 141 buffer->comm(pid, tid, image, ps.comm);
93 } 142 }
94 143
@@ -100,7 +149,7 @@ static bool readProcTask(Buffer *const buffer, const int pid, const char *const
100 return result; 149 return result;
101} 150}
102 151
103bool readProc(Buffer *const buffer, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3) { 152bool readProc(Buffer *const buffer, bool sendMaps, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3) {
104 bool result = false; 153 bool result = false;
105 154
106 DIR *proc = opendir("/proc"); 155 DIR *proc = opendir("/proc");
@@ -128,42 +177,29 @@ bool readProc(Buffer *const buffer, DynBuf *const printb, DynBuf *const b1, DynB
128 goto fail; 177 goto fail;
129 } 178 }
130 179
131 if (!printb->printf("/proc/%i/exe", pid)) { 180 if (sendMaps) {
132 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__); 181 if (!printb->printf("/proc/%i/maps", pid)) {
133 goto fail; 182 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
134 } 183 goto fail;
135 const int err = b1->readlink(printb->getBuf()); 184 }
136 const char *image; 185 if (!b2->read(printb->getBuf())) {
137 if (err == 0) { 186 logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the process exited", __FUNCTION__, __FILE__, __LINE__);
138 image = strrchr(b1->getBuf(), '/'); 187 // This is not a fatal error - the process just doesn't exist any more
139 if (image == NULL) { 188 continue;
140 image = b1->getBuf();
141 } else {
142 ++image;
143 } 189 }
144 } else if (err == -ENOENT) {
145 // readlink /proc/[pid]/exe returns ENOENT for kernel threads
146 image = "\0";
147 } else {
148 logg->logMessage("%s(%s:%i): DynBuf::readlink failed", __FUNCTION__, __FILE__, __LINE__);
149 goto fail;
150 }
151 190
152 if (!printb->printf("/proc/%i/maps", pid)) { 191 buffer->maps(pid, pid, b2->getBuf());
153 logg->logMessage("%s(%s:%i): DynBuf::printf failed", __FUNCTION__, __FILE__, __LINE__);
154 goto fail;
155 } 192 }
156 if (!b2->read(printb->getBuf())) {
157 logg->logMessage("%s(%s:%i): DynBuf::read failed, likely because the process exited", __FUNCTION__, __FILE__, __LINE__);
158 // This is not a fatal error - the process just doesn't exist any more
159 continue;
160 }
161
162 buffer->maps(pid, pid, b2->getBuf());
163 if (ps.numThreads <= 1) { 193 if (ps.numThreads <= 1) {
194 const char *const image = readProcExe(printb, pid, -1, b1);
195 if (image == NULL) {
196 logg->logMessage("%s(%s:%i): readImage failed", __FUNCTION__, __FILE__, __LINE__);
197 goto fail;
198 }
199
164 buffer->comm(pid, pid, image, ps.comm); 200 buffer->comm(pid, pid, image, ps.comm);
165 } else { 201 } else {
166 if (!readProcTask(buffer, pid, image, printb, b3)) { 202 if (!readProcTask(buffer, pid, printb, b1, b3)) {
167 logg->logMessage("%s(%s:%i): readProcTask failed", __FUNCTION__, __FILE__, __LINE__); 203 logg->logMessage("%s(%s:%i): readProcTask failed", __FUNCTION__, __FILE__, __LINE__);
168 goto fail; 204 goto fail;
169 } 205 }
diff --git a/daemon/Proc.h b/daemon/Proc.h
index 057b610..31c2eec 100644
--- a/daemon/Proc.h
+++ b/daemon/Proc.h
@@ -12,6 +12,6 @@
12class Buffer; 12class Buffer;
13class DynBuf; 13class DynBuf;
14 14
15bool readProc(Buffer *const buffer, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3); 15bool readProc(Buffer *const buffer, bool sendMaps, DynBuf *const printb, DynBuf *const b1, DynBuf *const b2, DynBuf *const b3);
16 16
17#endif // PROC_H 17#endif // PROC_H
diff --git a/daemon/Sender.h b/daemon/Sender.h
index 4c359db..33b6cc3 100644
--- a/daemon/Sender.h
+++ b/daemon/Sender.h
@@ -39,4 +39,4 @@ private:
39 Sender &operator=(const Sender &); 39 Sender &operator=(const Sender &);
40}; 40};
41 41
42#endif //__SENDER_H__ 42#endif //__SENDER_H__
diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp
index c169299..14d995f 100644
--- a/daemon/SessionData.cpp
+++ b/daemon/SessionData.cpp
@@ -9,6 +9,7 @@
9#include "SessionData.h" 9#include "SessionData.h"
10 10
11#include <string.h> 11#include <string.h>
12#include <sys/mman.h>
12 13
13#include "SessionXML.h" 14#include "SessionXML.h"
14#include "Logging.h" 15#include "Logging.h"
@@ -27,6 +28,15 @@ void SessionData::initialize() {
27 mSessionIsActive = false; 28 mSessionIsActive = false;
28 mLocalCapture = false; 29 mLocalCapture = false;
29 mOneShot = false; 30 mOneShot = false;
31 mSentSummary = false;
32 const size_t cpuIdSize = sizeof(int)*NR_CPUS;
33 // Share mCpuIds across all instances of gatord
34 mCpuIds = (int *)mmap(NULL, cpuIdSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
35 if (mCpuIds == MAP_FAILED) {
36 logg->logError(__FILE__, __LINE__, "Unable to mmap shared memory for cpuids");
37 handleException();
38 }
39 memset(mCpuIds, -1, cpuIdSize);
30 readCpuInfo(); 40 readCpuInfo();
31 mConfigurationXMLPath = NULL; 41 mConfigurationXMLPath = NULL;
32 mSessionXMLPath = NULL; 42 mSessionXMLPath = NULL;
@@ -91,10 +101,9 @@ void SessionData::parseSessionXML(char* xmlString) {
91void SessionData::readCpuInfo() { 101void SessionData::readCpuInfo() {
92 char temp[256]; // arbitrarily large amount 102 char temp[256]; // arbitrarily large amount
93 strcpy(mCoreName, "unknown"); 103 strcpy(mCoreName, "unknown");
94 memset(&mCpuIds, -1, sizeof(mCpuIds));
95 mMaxCpuId = -1; 104 mMaxCpuId = -1;
96 105
97 FILE* f = fopen("/proc/cpuinfo", "r"); 106 FILE* f = fopen("/proc/cpuinfo", "r");
98 if (f == NULL) { 107 if (f == NULL) {
99 logg->logMessage("Error opening /proc/cpuinfo\n" 108 logg->logMessage("Error opening /proc/cpuinfo\n"
100 "The core name in the captured xml file will be 'unknown'."); 109 "The core name in the captured xml file will be 'unknown'.");
@@ -102,10 +111,18 @@ void SessionData::readCpuInfo() {
102 } 111 }
103 112
104 bool foundCoreName = false; 113 bool foundCoreName = false;
105 int processor = 0; 114 int processor = -1;
106 while (fgets(temp, sizeof(temp), f)) { 115 while (fgets(temp, sizeof(temp), f)) {
107 if (strlen(temp) > 0) { 116 const size_t len = strlen(temp);
108 temp[strlen(temp) - 1] = 0; // Replace the line feed with a null 117
118 if (len == 1) {
119 // New section, clear the processor. Streamline will not know the cpus if the pre Linux 3.8 format of cpuinfo is encountered but also that no incorrect information will be transmitted.
120 processor = -1;
121 continue;
122 }
123
124 if (len > 0) {
125 temp[len - 1] = '\0'; // Replace the line feed with a null
109 } 126 }
110 127
111 const bool foundHardware = strstr(temp, "Hardware") != 0; 128 const bool foundHardware = strstr(temp, "Hardware") != 0;
@@ -127,10 +144,15 @@ void SessionData::readCpuInfo() {
127 } 144 }
128 145
129 if (foundCPUPart) { 146 if (foundCPUPart) {
130 mCpuIds[processor] = strtol(position, NULL, 0); 147 const int cpuId = strtol(position, NULL, 0);
131 // If this does not have the full topology in /proc/cpuinfo, mCpuIds[0] may not have the 1 CPU part emitted - this guarantees it's in mMaxCpuId 148 // If this does not have the full topology in /proc/cpuinfo, mCpuIds[0] may not have the 1 CPU part emitted - this guarantees it's in mMaxCpuId
132 if (mCpuIds[processor] > mMaxCpuId) { 149 if (cpuId > mMaxCpuId) {
133 mMaxCpuId = mCpuIds[processor]; 150 mMaxCpuId = cpuId;
151 }
152 if (processor >= NR_CPUS) {
153 logg->logMessage("Too many processors, please increase NR_CPUS");
154 } else if (processor >= 0) {
155 mCpuIds[processor] = cpuId;
134 } 156 }
135 } 157 }
136 158
@@ -142,10 +164,23 @@ void SessionData::readCpuInfo() {
142 164
143 if (!foundCoreName) { 165 if (!foundCoreName) {
144 logg->logMessage("Could not determine core name from /proc/cpuinfo\n" 166 logg->logMessage("Could not determine core name from /proc/cpuinfo\n"
145 "The core name in the captured xml file will be 'unknown'."); 167 "The core name in the captured xml file will be 'unknown'.");
146 } 168 }
147 fclose(f); 169 fclose(f);
148 } 170}
171
172uint64_t getTime() {
173 struct timespec ts;
174#ifndef CLOCK_MONOTONIC_RAW
175 // Android doesn't have this defined but it was added in Linux 2.6.28
176#define CLOCK_MONOTONIC_RAW 4
177#endif
178 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
179 logg->logError(__FILE__, __LINE__, "Failed to get uptime");
180 handleException();
181 }
182 return (NS_PER_S*ts.tv_sec + ts.tv_nsec);
183}
149 184
150int getEventKey() { 185int getEventKey() {
151 // key 0 is reserved as a timestamp 186 // key 0 is reserved as a timestamp
diff --git a/daemon/SessionData.h b/daemon/SessionData.h
index ea34240..835082d 100644
--- a/daemon/SessionData.h
+++ b/daemon/SessionData.h
@@ -13,12 +13,16 @@
13 13
14#include "Config.h" 14#include "Config.h"
15#include "Counter.h" 15#include "Counter.h"
16#include "FSDriver.h"
16#include "Hwmon.h" 17#include "Hwmon.h"
18#include "MaliVideoDriver.h"
17#include "PerfDriver.h" 19#include "PerfDriver.h"
18 20
19#define PROTOCOL_VERSION 18 21#define PROTOCOL_VERSION 19
20#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions 22#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions
21 23
24#define NS_PER_S ((uint64_t)1000000000)
25
22struct ImageLinkList { 26struct ImageLinkList {
23 char* path; 27 char* path;
24 struct ImageLinkList *next; 28 struct ImageLinkList *next;
@@ -32,9 +36,12 @@ public:
32 ~SessionData(); 36 ~SessionData();
33 void initialize(); 37 void initialize();
34 void parseSessionXML(char* xmlString); 38 void parseSessionXML(char* xmlString);
39 void readCpuInfo();
35 40
36 Hwmon hwmon; 41 Hwmon hwmon;
42 FSDriver fsDriver;
37 PerfDriver perf; 43 PerfDriver perf;
44 MaliVideoDriver maliVideo;
38 45
39 char mCoreName[MAX_STRING_LEN]; 46 char mCoreName[MAX_STRING_LEN];
40 struct ImageLinkList *mImages; 47 struct ImageLinkList *mImages;
@@ -49,7 +56,8 @@ public:
49 bool mLocalCapture; 56 bool mLocalCapture;
50 bool mOneShot; // halt processing of the driver data until profiling is complete or the buffer is filled 57 bool mOneShot; // halt processing of the driver data until profiling is complete or the buffer is filled
51 bool mIsEBS; 58 bool mIsEBS;
52 59 bool mSentSummary;
60
53 int mBacktraceDepth; 61 int mBacktraceDepth;
54 int mTotalBufferSize; // number of MB to use for the entire collection buffer 62 int mTotalBufferSize; // number of MB to use for the entire collection buffer
55 int mSampleRate; 63 int mSampleRate;
@@ -57,7 +65,7 @@ public:
57 int mDuration; 65 int mDuration;
58 int mCores; 66 int mCores;
59 int mPageSize; 67 int mPageSize;
60 int mCpuIds[NR_CPUS]; 68 int *mCpuIds;
61 int mMaxCpuId; 69 int mMaxCpuId;
62 70
63 // PMU Counters 71 // PMU Counters
@@ -65,8 +73,6 @@ public:
65 Counter mCounters[MAX_PERFORMANCE_COUNTERS]; 73 Counter mCounters[MAX_PERFORMANCE_COUNTERS];
66 74
67private: 75private:
68 void readCpuInfo();
69
70 // Intentionally unimplemented 76 // Intentionally unimplemented
71 SessionData(const SessionData &); 77 SessionData(const SessionData &);
72 SessionData &operator=(const SessionData &); 78 SessionData &operator=(const SessionData &);
@@ -74,6 +80,7 @@ private:
74 80
75extern SessionData* gSessionData; 81extern SessionData* gSessionData;
76 82
83uint64_t getTime();
77int getEventKey(); 84int getEventKey();
78 85
79#endif // SESSION_DATA_H 86#endif // SESSION_DATA_H
diff --git a/daemon/SessionXML.cpp b/daemon/SessionXML.cpp
index 55b2f92..8cdc940 100644
--- a/daemon/SessionXML.cpp
+++ b/daemon/SessionXML.cpp
@@ -17,15 +17,15 @@
17#include "SessionData.h" 17#include "SessionData.h"
18 18
19static const char* TAG_SESSION = "session"; 19static const char* TAG_SESSION = "session";
20static const char* TAG_IMAGE = "image"; 20static const char* TAG_IMAGE = "image";
21 21
22static const char* ATTR_VERSION = "version"; 22static const char* ATTR_VERSION = "version";
23static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding"; 23static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding";
24static const char* ATTR_BUFFER_MODE = "buffer_mode"; 24static const char* ATTR_BUFFER_MODE = "buffer_mode";
25static const char* ATTR_SAMPLE_RATE = "sample_rate"; 25static const char* ATTR_SAMPLE_RATE = "sample_rate";
26static const char* ATTR_DURATION = "duration"; 26static const char* ATTR_DURATION = "duration";
27static const char* ATTR_PATH = "path"; 27static const char* ATTR_PATH = "path";
28static const char* ATTR_LIVE_RATE = "live_rate"; 28static const char* ATTR_LIVE_RATE = "live_rate";
29 29
30SessionXML::SessionXML(const char *str) { 30SessionXML::SessionXML(const char *str) {
31 parameters.buffer_mode[0] = 0; 31 parameters.buffer_mode[0] = 0;
diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp
index caa665e..2b61eae 100644
--- a/daemon/StreamlineSetup.cpp
+++ b/daemon/StreamlineSetup.cpp
@@ -266,7 +266,7 @@ void StreamlineSetup::writeConfiguration(char* xml) {
266 { ConfigurationXML configuration; } 266 { ConfigurationXML configuration; }
267 267
268 if (gSessionData->mCounterOverflow > 0) { 268 if (gSessionData->mCounterOverflow > 0) {
269 logg->logError(__FILE__, __LINE__, "Only %i performance counters counters are permitted, %i are selected", MAX_PERFORMANCE_COUNTERS, gSessionData->mCounterOverflow); 269 logg->logError(__FILE__, __LINE__, "Only %i performance counters are permitted, %i are selected", MAX_PERFORMANCE_COUNTERS, gSessionData->mCounterOverflow);
270 handleException(); 270 handleException();
271 } 271 }
272} 272}
diff --git a/daemon/StreamlineSetup.h b/daemon/StreamlineSetup.h
index 74bb197..b380f46 100644
--- a/daemon/StreamlineSetup.h
+++ b/daemon/StreamlineSetup.h
@@ -21,7 +21,7 @@ enum {
21 COMMAND_APC_START = 2, 21 COMMAND_APC_START = 2,
22 COMMAND_APC_STOP = 3, 22 COMMAND_APC_STOP = 3,
23 COMMAND_DISCONNECT = 4, 23 COMMAND_DISCONNECT = 4,
24 COMMAND_PING = 5 24 COMMAND_PING = 5
25}; 25};
26 26
27class StreamlineSetup { 27class StreamlineSetup {
@@ -47,4 +47,4 @@ private:
47 StreamlineSetup &operator=(const StreamlineSetup &); 47 StreamlineSetup &operator=(const StreamlineSetup &);
48}; 48};
49 49
50#endif //__STREAMLINE_SETUP_H__ 50#endif //__STREAMLINE_SETUP_H__
diff --git a/daemon/UEvent.cpp b/daemon/UEvent.cpp
index d977cd0..54d4575 100644
--- a/daemon/UEvent.cpp
+++ b/daemon/UEvent.cpp
@@ -8,12 +8,12 @@
8 8
9#include "UEvent.h" 9#include "UEvent.h"
10 10
11#include <sys/socket.h>
12#include <linux/netlink.h>
13#include <string.h> 11#include <string.h>
14 12#include <sys/socket.h>
15#include <unistd.h> 13#include <unistd.h>
16 14
15#include <linux/netlink.h>
16
17#include "Logging.h" 17#include "Logging.h"
18 18
19static const char EMPTY[] = ""; 19static const char EMPTY[] = "";
diff --git a/daemon/UserSpaceSource.cpp b/daemon/UserSpaceSource.cpp
index debe696..8c328e0 100644
--- a/daemon/UserSpaceSource.cpp
+++ b/daemon/UserSpaceSource.cpp
@@ -16,7 +16,6 @@
16#include "Logging.h" 16#include "Logging.h"
17#include "SessionData.h" 17#include "SessionData.h"
18 18
19#define NS_PER_S ((uint64_t)1000000000)
20#define NS_PER_US 1000 19#define NS_PER_US 1000
21 20
22extern Child *child; 21extern Child *child;
@@ -35,6 +34,7 @@ void UserSpaceSource::run() {
35 prctl(PR_SET_NAME, (unsigned long)&"gatord-counters", 0, 0, 0); 34 prctl(PR_SET_NAME, (unsigned long)&"gatord-counters", 0, 0, 0);
36 35
37 gSessionData->hwmon.start(); 36 gSessionData->hwmon.start();
37 gSessionData->fsDriver.start();
38 38
39 int64_t monotonic_started = 0; 39 int64_t monotonic_started = 0;
40 while (monotonic_started <= 0) { 40 while (monotonic_started <= 0) {
@@ -48,16 +48,7 @@ void UserSpaceSource::run() {
48 48
49 uint64_t next_time = 0; 49 uint64_t next_time = 0;
50 while (gSessionData->mSessionIsActive) { 50 while (gSessionData->mSessionIsActive) {
51 struct timespec ts; 51 const uint64_t curr_time = getTime() - monotonic_started;
52#ifndef CLOCK_MONOTONIC_RAW
53 // Android doesn't have this defined but it was added in Linux 2.6.28
54#define CLOCK_MONOTONIC_RAW 4
55#endif
56 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
57 logg->logError(__FILE__, __LINE__, "Failed to get uptime");
58 handleException();
59 }
60 const uint64_t curr_time = (NS_PER_S*ts.tv_sec + ts.tv_nsec) - monotonic_started;
61 // Sample ten times a second ignoring gSessionData->mSampleRate 52 // Sample ten times a second ignoring gSessionData->mSampleRate
62 next_time += NS_PER_S/10;//gSessionData->mSampleRate; 53 next_time += NS_PER_S/10;//gSessionData->mSampleRate;
63 if (next_time < curr_time) { 54 if (next_time < curr_time) {
@@ -67,6 +58,7 @@ void UserSpaceSource::run() {
67 58
68 if (mBuffer.eventHeader(curr_time)) { 59 if (mBuffer.eventHeader(curr_time)) {
69 gSessionData->hwmon.read(&mBuffer); 60 gSessionData->hwmon.read(&mBuffer);
61 gSessionData->fsDriver.read(&mBuffer);
70 // Only check after writing all counters so that time and corresponding counters appear in the same frame 62 // Only check after writing all counters so that time and corresponding counters appear in the same frame
71 mBuffer.check(curr_time); 63 mBuffer.check(curr_time);
72 } 64 }
diff --git a/daemon/UserSpaceSource.h b/daemon/UserSpaceSource.h
index fb5889d..9b36660 100644
--- a/daemon/UserSpaceSource.h
+++ b/daemon/UserSpaceSource.h
@@ -14,7 +14,7 @@
14#include "Buffer.h" 14#include "Buffer.h"
15#include "Source.h" 15#include "Source.h"
16 16
17// User space counters - currently just hwmon 17// User space counters
18class UserSpaceSource : public Source { 18class UserSpaceSource : public Source {
19public: 19public:
20 UserSpaceSource(sem_t *senderSem); 20 UserSpaceSource(sem_t *senderSem);
diff --git a/daemon/c++.cpp b/daemon/c++.cpp
new file mode 100644
index 0000000..6041e5e
--- /dev/null
+++ b/daemon/c++.cpp
@@ -0,0 +1,40 @@
1/**
2 * Minimal set of C++ functions so that libstdc++ is not required
3 *
4 * Copyright (C) ARM Limited 2010-2014. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <stdio.h>
12#include <stdlib.h>
13
14void operator delete(void *ptr) {
15 if (ptr != NULL) {
16 free(ptr);
17 }
18}
19
20void operator delete[](void *ptr) {
21 operator delete(ptr);
22}
23
24void *operator new(size_t size) {
25 void *ptr = malloc(size == 0 ? 1 : size);
26 if (ptr == NULL) {
27 abort();
28 }
29 return ptr;
30}
31
32void *operator new[](size_t size) {
33 return operator new(size);
34}
35
36extern "C"
37void __cxa_pure_virtual() {
38 printf("pure virtual method called\n");
39 abort();
40}
diff --git a/daemon/common.mk b/daemon/common.mk
index d9dc146..769a92e 100644
--- a/daemon/common.mk
+++ b/daemon/common.mk
@@ -5,16 +5,17 @@
5# -Werror treats warnings as errors 5# -Werror treats warnings as errors
6# -std=c++0x is the planned new c++ standard 6# -std=c++0x is the planned new c++ standard
7# -std=c++98 is the 1998 c++ standard 7# -std=c++98 is the 1998 c++ standard
8CFLAGS += -O3 -Wall -fno-exceptions -pthread -MMD -DETCDIR=\"/etc\" -Ilibsensors 8CPPFLAGS += -O3 -Wall -fno-exceptions -pthread -MMD -DETCDIR=\"/etc\" -Ilibsensors
9CXXFLAGS += -fno-rtti -Wextra # -Weffc++ 9CXXFLAGS += -fno-rtti -Wextra # -Weffc++
10ifeq ($(WERROR),1) 10ifeq ($(WERROR),1)
11 CFLAGS += -Werror 11 CPPFLAGS += -Werror
12endif 12endif
13# -s strips the binary of debug info 13# -s strips the binary of debug info
14LDFLAGS += -s 14LDFLAGS += -s
15LDLIBS += -lrt -lm -pthread
15TARGET = gatord 16TARGET = gatord
16C_SRC = $(wildcard mxml/*.c) $(wildcard libsensors/*.c) 17C_SRC = $(wildcard mxml/*.c) $(wildcard libsensors/*.c)
17CPP_SRC = $(wildcard *.cpp) 18CXX_SRC = $(wildcard *.cpp)
18 19
19all: $(TARGET) 20all: $(TARGET)
20 21
@@ -35,14 +36,15 @@ libsensors/conf-parse.c: ;
35 ./escape $< > $@ 36 ./escape $< > $@
36 37
37%.o: %.c 38%.o: %.c
38 $(GCC) -c $(CFLAGS) -o $@ $< 39 $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
39 40
40%.o: %.cpp 41%.o: %.cpp
41 $(CPP) -c $(CFLAGS) $(CXXFLAGS) -o $@ $< 42 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
42 43
43$(TARGET): $(CPP_SRC:%.cpp=%.o) $(C_SRC:%.c=%.o) 44$(TARGET): $(CXX_SRC:%.cpp=%.o) $(C_SRC:%.c=%.o)
44 $(CPP) $(LDFLAGS) -o $@ $^ -lrt -pthread 45 $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
45 46
47# Intentionally ignore CC as a native binary is required
46escape: escape.c 48escape: escape.c
47 gcc $^ -o $@ 49 gcc $^ -o $@
48 50
diff --git a/daemon/defaults.xml b/daemon/defaults.xml
index 5bf096c..39a0f65 100644
--- a/daemon/defaults.xml
+++ b/daemon/defaults.xml
@@ -58,5 +58,10 @@
58 <configuration counter="Linux_meminfo_memused"/> 58 <configuration counter="Linux_meminfo_memused"/>
59 <configuration counter="Linux_meminfo_memfree"/> 59 <configuration counter="Linux_meminfo_memfree"/>
60 <configuration counter="Linux_power_cpu_freq"/> 60 <configuration counter="Linux_power_cpu_freq"/>
61 <configuration counter="ARM_Mali-4xx_fragment"/>
62 <configuration counter="ARM_Mali-4xx_vertex"/>
63 <configuration counter="ARM_Mali-T6xx_fragment" cores="1"/>
64 <configuration counter="ARM_Mali-T6xx_vertex" cores="1"/>
65 <configuration counter="ARM_Mali-T6xx_opencl" cores="1"/>
61 <configuration counter="L2C-310_cnt0" event="0x1"/> 66 <configuration counter="L2C-310_cnt0" event="0x1"/>
62</configurations> 67</configurations>
diff --git a/daemon/escape.c b/daemon/escape.c
index c54aa1c..2b0863a 100644
--- a/daemon/escape.c
+++ b/daemon/escape.c
@@ -6,7 +6,7 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9/* 9/*
10 * The Makefile in the daemon folder builds and executes 'escape' 10 * The Makefile in the daemon folder builds and executes 'escape'
11 * 'escape' creates configuration_xml.h from configuration.xml and events_xml.h from events-*.xml 11 * 'escape' creates configuration_xml.h from configuration.xml and events_xml.h from events-*.xml
12 * these genereated xml files are then #included and built as part of the gatord binary 12 * these genereated xml files are then #included and built as part of the gatord binary
diff --git a/daemon/events-CCI-400.xml b/daemon/events-CCI-400.xml
index 4fa7711..20002ef 100644
--- a/daemon/events-CCI-400.xml
+++ b/daemon/events-CCI-400.xml
@@ -1,7 +1,6 @@
1 <counter_set name="cci-400_cnt" count="4"/> 1 <counter_set name="CCI_400_cnt" count="4"/>
2 <category name="CCI-400" counter_set="cci-400_cnt" per_cpu="no" supports_event_based_sampling="yes"> 2 <category name="CCI-400" counter_set="CCI_400_cnt" per_cpu="no" supports_event_based_sampling="yes">
3 <event counter="cci-400_ccnt" event="0xff" title="CCI-400 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="CCI_400_ccnt" event="0xff" title="CCI-400 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
4
5 <option_set name="Slave"> 4 <option_set name="Slave">
6 <option event_delta="0x00" name="S0" description="Slave interface 0"/> 5 <option event_delta="0x00" name="S0" description="Slave interface 0"/>
7 <option event_delta="0x20" name="S1" description="Slave interface 1"/> 6 <option event_delta="0x20" name="S1" description="Slave interface 1"/>
@@ -9,7 +8,6 @@
9 <option event_delta="0x60" name="S3" description="Slave interface 3"/> 8 <option event_delta="0x60" name="S3" description="Slave interface 3"/>
10 <option event_delta="0x80" name="S4" description="Slave interface 4"/> 9 <option event_delta="0x80" name="S4" description="Slave interface 4"/>
11 </option_set> 10 </option_set>
12
13 <event event="0x00" option_set="Slave" title="CCI-400" name="Read: any" description="Read request handshake: any"/> 11 <event event="0x00" option_set="Slave" title="CCI-400" name="Read: any" description="Read request handshake: any"/>
14 <event event="0x01" option_set="Slave" title="CCI-400" name="Read: transaction" description="Read request handshake: device transaction"/> 12 <event event="0x01" option_set="Slave" title="CCI-400" name="Read: transaction" description="Read request handshake: device transaction"/>
15 <event event="0x02" option_set="Slave" title="CCI-400" name="Read: normal" description="Read request handshake: normal, non-shareable or system-shareable, but not barrier or cache maintenance operation"/> 13 <event event="0x02" option_set="Slave" title="CCI-400" name="Read: normal" description="Read request handshake: normal, non-shareable or system-shareable, but not barrier or cache maintenance operation"/>
@@ -30,13 +28,11 @@
30 <event event="0x11" option_set="Slave" title="CCI-400" name="Write: WriteLineUnique" description="Write request handshake: WriteLineUnique"/> 28 <event event="0x11" option_set="Slave" title="CCI-400" name="Write: WriteLineUnique" description="Write request handshake: WriteLineUnique"/>
31 <event event="0x12" option_set="Slave" title="CCI-400" name="Write: Evict" description="Write request handshake: Evict"/> 29 <event event="0x12" option_set="Slave" title="CCI-400" name="Write: Evict" description="Write request handshake: Evict"/>
32 <event event="0x13" option_set="Slave" title="CCI-400" name="Write stall: tracker full" description="Write request stall cycle because the transaction tracker is full. Increase SIx_W_MAX to avoid this stall"/> 30 <event event="0x13" option_set="Slave" title="CCI-400" name="Write stall: tracker full" description="Write request stall cycle because the transaction tracker is full. Increase SIx_W_MAX to avoid this stall"/>
33
34 <option_set name="Master"> 31 <option_set name="Master">
35 <option event_delta="0xa0" name="M0" description="Master interface 0"/> 32 <option event_delta="0xa0" name="M0" description="Master interface 0"/>
36 <option event_delta="0xc0" name="M1" description="Master interface 1"/> 33 <option event_delta="0xc0" name="M1" description="Master interface 1"/>
37 <option event_delta="0xe0" name="M2" description="Master interface 2"/> 34 <option event_delta="0xe0" name="M2" description="Master interface 2"/>
38 </option_set> 35 </option_set>
39
40 <event event="0x14" option_set="Master" title="CCI-400" name="Retry fetch" description="RETRY of speculative fetch transaction"/> 36 <event event="0x14" option_set="Master" title="CCI-400" name="Retry fetch" description="RETRY of speculative fetch transaction"/>
41 <event event="0x15" option_set="Master" title="CCI-400" name="Read stall: address hazard" description="Read request stall cycle because of an address hazard"/> 37 <event event="0x15" option_set="Master" title="CCI-400" name="Read stall: address hazard" description="Read request stall cycle because of an address hazard"/>
42 <event event="0x16" option_set="Master" title="CCI-400" name="Read stall: ID hazard" description="Read request stall cycle because of an ID hazard"/> 38 <event event="0x16" option_set="Master" title="CCI-400" name="Read stall: ID hazard" description="Read request stall cycle because of an ID hazard"/>
@@ -45,11 +41,9 @@
45 <event event="0x19" option_set="Master" title="CCI-400" name="Write stall: barrier hazard" description="Write request stall cycle because of a barrier hazard"/> 41 <event event="0x19" option_set="Master" title="CCI-400" name="Write stall: barrier hazard" description="Write request stall cycle because of a barrier hazard"/>
46 <event event="0x1a" option_set="Master" title="CCI-400" name="Write stall: tracker full" description="Write request stall cycle because the transaction tracker is full. Increase MIx_W_MAX to avoid this stall. See the CoreLink CCI-400 Cache Coherent Interconnect Integration Manual"/> 42 <event event="0x1a" option_set="Master" title="CCI-400" name="Write stall: tracker full" description="Write request stall cycle because the transaction tracker is full. Increase MIx_W_MAX to avoid this stall. See the CoreLink CCI-400 Cache Coherent Interconnect Integration Manual"/>
47 </category> 43 </category>
48 44 <counter_set name="CCI_400-r1_cnt" count="4"/>
49 <counter_set name="cci-400-r1_cnt" count="4"/> 45 <category name="CCI-400" counter_set="CCI_400-r1_cnt" per_cpu="no" supports_event_based_sampling="yes">
50 <category name="CCI-400" counter_set="cci-400-r1_cnt" per_cpu="no" supports_event_based_sampling="yes"> 46 <event counter="CCI_400-r1_ccnt" event="0xff" title="CCI-400 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
51 <event counter="cci-400-r1_ccnt" event="0xff" title="CCI-400 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
52
53 <option_set name="Slave"> 47 <option_set name="Slave">
54 <option event_delta="0x00" name="S0" description="Slave interface 0"/> 48 <option event_delta="0x00" name="S0" description="Slave interface 0"/>
55 <option event_delta="0x20" name="S1" description="Slave interface 1"/> 49 <option event_delta="0x20" name="S1" description="Slave interface 1"/>
@@ -57,7 +51,6 @@
57 <option event_delta="0x60" name="S3" description="Slave interface 3"/> 51 <option event_delta="0x60" name="S3" description="Slave interface 3"/>
58 <option event_delta="0x80" name="S4" description="Slave interface 4"/> 52 <option event_delta="0x80" name="S4" description="Slave interface 4"/>
59 </option_set> 53 </option_set>
60
61 <event event="0x00" option_set="Slave" title="CCI-400" name="Read: any" description="Read request handshake: any"/> 54 <event event="0x00" option_set="Slave" title="CCI-400" name="Read: any" description="Read request handshake: any"/>
62 <event event="0x01" option_set="Slave" title="CCI-400" name="Read: transaction" description="Read request handshake: device transaction"/> 55 <event event="0x01" option_set="Slave" title="CCI-400" name="Read: transaction" description="Read request handshake: device transaction"/>
63 <event event="0x02" option_set="Slave" title="CCI-400" name="Read: normal" description="Read request handshake: normal, non-shareable or system-shareable, but not barrier or cache maintenance operation"/> 56 <event event="0x02" option_set="Slave" title="CCI-400" name="Read: normal" description="Read request handshake: normal, non-shareable or system-shareable, but not barrier or cache maintenance operation"/>
@@ -79,13 +72,11 @@
79 <event event="0x12" option_set="Slave" title="CCI-400" name="Write: Evict" description="Write request handshake: Evict"/> 72 <event event="0x12" option_set="Slave" title="CCI-400" name="Write: Evict" description="Write request handshake: Evict"/>
80 <event event="0x13" option_set="Slave" title="CCI-400" name="Write stall: tracker full" description="Write request stall cycle because the transaction tracker is full. Increase SIx_W_MAX to avoid this stall"/> 73 <event event="0x13" option_set="Slave" title="CCI-400" name="Write stall: tracker full" description="Write request stall cycle because the transaction tracker is full. Increase SIx_W_MAX to avoid this stall"/>
81 <event event="0x14" option_set="Slave" title="CCI-400" name="Read stall: slave hazard" description="Read request stall cycle because of a slave interface ID hazard"/> 74 <event event="0x14" option_set="Slave" title="CCI-400" name="Read stall: slave hazard" description="Read request stall cycle because of a slave interface ID hazard"/>
82
83 <option_set name="Master"> 75 <option_set name="Master">
84 <option event_delta="0xa0" name="M0" description="Master interface 0"/> 76 <option event_delta="0xa0" name="M0" description="Master interface 0"/>
85 <option event_delta="0xc0" name="M1" description="Master interface 1"/> 77 <option event_delta="0xc0" name="M1" description="Master interface 1"/>
86 <option event_delta="0xe0" name="M2" description="Master interface 2"/> 78 <option event_delta="0xe0" name="M2" description="Master interface 2"/>
87 </option_set> 79 </option_set>
88
89 <event event="0x00" option_set="Master" title="CCI-400" name="Retry fetch" description="RETRY of speculative fetch transaction"/> 80 <event event="0x00" option_set="Master" title="CCI-400" name="Retry fetch" description="RETRY of speculative fetch transaction"/>
90 <event event="0x01" option_set="Master" title="CCI-400" name="Read stall: address hazard" description="Stall cycle because of an address hazard. A read or write invalidation is stalled because of an outstanding transaction to an overlapping address"/> 81 <event event="0x01" option_set="Master" title="CCI-400" name="Read stall: address hazard" description="Stall cycle because of an address hazard. A read or write invalidation is stalled because of an outstanding transaction to an overlapping address"/>
91 <event event="0x02" option_set="Master" title="CCI-400" name="Read stall: ID hazard" description="Read request stall cycle because of a master interface ID hazard"/> 82 <event event="0x02" option_set="Master" title="CCI-400" name="Read stall: ID hazard" description="Read request stall cycle because of a master interface ID hazard"/>
diff --git a/daemon/events-CCN-504.xml b/daemon/events-CCN-504.xml
index cfabf65..6ef3e64 100644
--- a/daemon/events-CCN-504.xml
+++ b/daemon/events-CCN-504.xml
@@ -1,7 +1,6 @@
1 <counter_set name="CCN-504_cnt" count="4"/> 1 <counter_set name="CCN-504_cnt" count="4"/>
2 <category name="CCN-504" counter_set="CCN-504_cnt"> 2 <category name="CCN-504" counter_set="CCN-504_cnt">
3 <event counter="CCN-504_ccnt" title="CCN-504 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="CCN-504_ccnt" title="CCN-504 Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
4
5 <option_set name="XP_Region"> 4 <option_set name="XP_Region">
6 <option event_delta="0x400000" name="XP 0" description="Crosspoint 0"/> 5 <option event_delta="0x400000" name="XP 0" description="Crosspoint 0"/>
7 <option event_delta="0x410000" name="XP 1" description="Crosspoint 1"/> 6 <option event_delta="0x410000" name="XP 1" description="Crosspoint 1"/>
@@ -15,7 +14,6 @@
15 <option event_delta="0x490000" name="XP 9" description="Crosspoint 9"/> 14 <option event_delta="0x490000" name="XP 9" description="Crosspoint 9"/>
16 <option event_delta="0x4A0000" name="XP 10" description="Crosspoint 10"/> 15 <option event_delta="0x4A0000" name="XP 10" description="Crosspoint 10"/>
17 </option_set> 16 </option_set>
18
19 <event event="0x0801" option_set="XP_Region" title="CCN-504" name="Bus 0: REQ: H-bit" description="Bus 0: REQ: Set H-bit, signaled when this XP sets the H-bit."/> 17 <event event="0x0801" option_set="XP_Region" title="CCN-504" name="Bus 0: REQ: H-bit" description="Bus 0: REQ: Set H-bit, signaled when this XP sets the H-bit."/>
20 <event event="0x0802" option_set="XP_Region" title="CCN-504" name="Bus 0: REQ: S-bit" description="Bus 0: REQ: Set S-bit, signaled when this XP sets the S-bit."/> 18 <event event="0x0802" option_set="XP_Region" title="CCN-504" name="Bus 0: REQ: S-bit" description="Bus 0: REQ: Set S-bit, signaled when this XP sets the S-bit."/>
21 <event event="0x0803" option_set="XP_Region" title="CCN-504" name="Bus 0: REQ: P-Cnt" description="Bus 0: REQ: Set P-Cnt, signaled when this XP sets the P-Cnt. This is not applicable for the SNP VC."/> 19 <event event="0x0803" option_set="XP_Region" title="CCN-504" name="Bus 0: REQ: P-Cnt" description="Bus 0: REQ: Set P-Cnt, signaled when this XP sets the P-Cnt. This is not applicable for the SNP VC."/>
@@ -56,7 +54,6 @@
56 <event event="0x087A" option_set="XP_Region" title="CCN-504" name="Bus 1: DATB: S-bit" description="Bus 1: DATB: Set S-bit, signaled when this XP sets the S-bit."/> 54 <event event="0x087A" option_set="XP_Region" title="CCN-504" name="Bus 1: DATB: S-bit" description="Bus 1: DATB: Set S-bit, signaled when this XP sets the S-bit."/>
57 <event event="0x087B" option_set="XP_Region" title="CCN-504" name="Bus 1: DATB: P-Cnt" description="Bus 1: DATB: Set P-Cnt, signaled when this XP sets the P-Cnt. This is not applicable for the SNP VC."/> 55 <event event="0x087B" option_set="XP_Region" title="CCN-504" name="Bus 1: DATB: P-Cnt" description="Bus 1: DATB: Set P-Cnt, signaled when this XP sets the P-Cnt. This is not applicable for the SNP VC."/>
58 <event event="0x087C" option_set="XP_Region" title="CCN-504" name="Bus 1: DATB: TknV" description="Bus 1: DATB: No TknV, signaled when this XP transmits a valid packet."/> 56 <event event="0x087C" option_set="XP_Region" title="CCN-504" name="Bus 1: DATB: TknV" description="Bus 1: DATB: No TknV, signaled when this XP transmits a valid packet."/>
59
60 <option_set name="HN-F_Region"> 57 <option_set name="HN-F_Region">
61 <option event_delta="0x200000" name="HN-F 3" description="Fully-coherent Home Node 3"/> 58 <option event_delta="0x200000" name="HN-F 3" description="Fully-coherent Home Node 3"/>
62 <option event_delta="0x210000" name="HN-F 5" description="Fully-coherent Home Node 5"/> 59 <option event_delta="0x210000" name="HN-F 5" description="Fully-coherent Home Node 5"/>
@@ -67,7 +64,6 @@
67 <option event_delta="0x260000" name="HN-F 17" description="Fully-coherent Home Node 17"/> 64 <option event_delta="0x260000" name="HN-F 17" description="Fully-coherent Home Node 17"/>
68 <option event_delta="0x270000" name="HN-F 18" description="Fully-coherent Home Node 18"/> 65 <option event_delta="0x270000" name="HN-F 18" description="Fully-coherent Home Node 18"/>
69 </option_set> 66 </option_set>
70
71 <event event="0x0401" option_set="HN-F_Region" title="CCN-504" name="Cache Miss" description="Counts the total cache misses. This is the first time lookup result, and is high priority."/> 67 <event event="0x0401" option_set="HN-F_Region" title="CCN-504" name="Cache Miss" description="Counts the total cache misses. This is the first time lookup result, and is high priority."/>
72 <event event="0x0402" option_set="HN-F_Region" title="CCN-504" name="L3 SF Cache Access" description="Counts the number of cache accesses. This is the first time access, and is high priority."/> 68 <event event="0x0402" option_set="HN-F_Region" title="CCN-504" name="L3 SF Cache Access" description="Counts the number of cache accesses. This is the first time access, and is high priority."/>
73 <event event="0x0403" option_set="HN-F_Region" title="CCN-504" name="Cache Fill" description="Counts the total allocations in the HN L3 cache, and all cache line allocations to the L3 cache."/> 69 <event event="0x0403" option_set="HN-F_Region" title="CCN-504" name="Cache Fill" description="Counts the total allocations in the HN L3 cache, and all cache line allocations to the L3 cache."/>
@@ -82,7 +78,6 @@
82 <event event="0x040C" option_set="HN-F_Region" title="CCN-504" name="MC Retries" description="Counts the number of transactions retried by the memory controller."/> 78 <event event="0x040C" option_set="HN-F_Region" title="CCN-504" name="MC Retries" description="Counts the number of transactions retried by the memory controller."/>
83 <event event="0x040D" option_set="HN-F_Region" title="CCN-504" name="MC Reqs" description="Counts the number of requests to the memory controller."/> 79 <event event="0x040D" option_set="HN-F_Region" title="CCN-504" name="MC Reqs" description="Counts the number of requests to the memory controller."/>
84 <event event="0x040E" option_set="HN-F_Region" title="CCN-504" name="QOS HH Retry" description="Counts the number of times a highest-priority QoS class was retried at the HN-F."/> 80 <event event="0x040E" option_set="HN-F_Region" title="CCN-504" name="QOS HH Retry" description="Counts the number of times a highest-priority QoS class was retried at the HN-F."/>
85
86 <option_set name="RN-I_Region"> 81 <option_set name="RN-I_Region">
87 <option event_delta="0x800000" name="RN-I 0" description="I/O-coherent Requesting Node 0"/> 82 <option event_delta="0x800000" name="RN-I 0" description="I/O-coherent Requesting Node 0"/>
88 <option event_delta="0x820000" name="RN-I 2" description="I/O-coherent Requesting Node 2"/> 83 <option event_delta="0x820000" name="RN-I 2" description="I/O-coherent Requesting Node 2"/>
@@ -91,7 +86,6 @@
91 <option event_delta="0x900000" name="RN-I 16" description="I/O-coherent Requesting Node 16"/> 86 <option event_delta="0x900000" name="RN-I 16" description="I/O-coherent Requesting Node 16"/>
92 <option event_delta="0x940000" name="RN-I 20" description="I/O-coherent Requesting Node 20"/> 87 <option event_delta="0x940000" name="RN-I 20" description="I/O-coherent Requesting Node 20"/>
93 </option_set> 88 </option_set>
94
95 <event event="0x1601" option_set="RN-I_Region" title="CCN-504" name="S0 RDataBeats" description="S0 RDataBeats."/> 89 <event event="0x1601" option_set="RN-I_Region" title="CCN-504" name="S0 RDataBeats" description="S0 RDataBeats."/>
96 <event event="0x1602" option_set="RN-I_Region" title="CCN-504" name="S1 RDataBeats" description="S1 RDataBeats."/> 90 <event event="0x1602" option_set="RN-I_Region" title="CCN-504" name="S1 RDataBeats" description="S1 RDataBeats."/>
97 <event event="0x1603" option_set="RN-I_Region" title="CCN-504" name="S2 RDataBeats" description="S2 RDataBeats."/> 91 <event event="0x1603" option_set="RN-I_Region" title="CCN-504" name="S2 RDataBeats" description="S2 RDataBeats."/>
@@ -102,14 +96,12 @@
102 <event event="0x1608" option_set="RN-I_Region" title="CCN-504" name="RRT full" description="RRT full."/> 96 <event event="0x1608" option_set="RN-I_Region" title="CCN-504" name="RRT full" description="RRT full."/>
103 <event event="0x1609" option_set="RN-I_Region" title="CCN-504" name="WRT full" description="WRT full."/> 97 <event event="0x1609" option_set="RN-I_Region" title="CCN-504" name="WRT full" description="WRT full."/>
104 <event event="0x160A" option_set="RN-I_Region" title="CCN-504" name="Replayed TXREQ Flits" description="Replayed TXREQ Flits."/> 98 <event event="0x160A" option_set="RN-I_Region" title="CCN-504" name="Replayed TXREQ Flits" description="Replayed TXREQ Flits."/>
105
106 <option_set name="SBAS_Region"> 99 <option_set name="SBAS_Region">
107 <option event_delta="0x810000" name="SBAS 1" description="ACE master to CHI protocol bridge 1"/> 100 <option event_delta="0x810000" name="SBAS 1" description="ACE master to CHI protocol bridge 1"/>
108 <option event_delta="0x890000" name="SBAS 9" description="ACE master to CHI protocol bridge 9"/> 101 <option event_delta="0x890000" name="SBAS 9" description="ACE master to CHI protocol bridge 9"/>
109 <option event_delta="0x8B0000" name="SBAS 11" description="ACE master to CHI protocol bridge 11"/> 102 <option event_delta="0x8B0000" name="SBAS 11" description="ACE master to CHI protocol bridge 11"/>
110 <option event_delta="0x930000" name="SBAS 19" description="ACE master to CHI protocol bridge 19"/> 103 <option event_delta="0x930000" name="SBAS 19" description="ACE master to CHI protocol bridge 19"/>
111 </option_set> 104 </option_set>
112
113 <event event="0x1001" option_set="SBAS_Region" title="CCN-504" name="S0 RDataBeats" description="S0 RDataBeats."/> 105 <event event="0x1001" option_set="SBAS_Region" title="CCN-504" name="S0 RDataBeats" description="S0 RDataBeats."/>
114 <event event="0x1004" option_set="SBAS_Region" title="CCN-504" name="RXDAT Flits received" description="RXDAT Flits received."/> 106 <event event="0x1004" option_set="SBAS_Region" title="CCN-504" name="RXDAT Flits received" description="RXDAT Flits received."/>
115 <event event="0x1005" option_set="SBAS_Region" title="CCN-504" name="TXDAT Flits sent" description="TXDAT Flits sent."/> 107 <event event="0x1005" option_set="SBAS_Region" title="CCN-504" name="TXDAT Flits sent" description="TXDAT Flits sent."/>
@@ -118,5 +110,4 @@
118 <event event="0x1008" option_set="SBAS_Region" title="CCN-504" name="RRT full" description="RRT full."/> 110 <event event="0x1008" option_set="SBAS_Region" title="CCN-504" name="RRT full" description="RRT full."/>
119 <event event="0x1009" option_set="SBAS_Region" title="CCN-504" name="WRT full" description="WRT full."/> 111 <event event="0x1009" option_set="SBAS_Region" title="CCN-504" name="WRT full" description="WRT full."/>
120 <event event="0x100A" option_set="SBAS_Region" title="CCN-504" name="Replayed TXREQ Flits" description="Replayed TXREQ Flits."/> 112 <event event="0x100A" option_set="SBAS_Region" title="CCN-504" name="Replayed TXREQ Flits" description="Replayed TXREQ Flits."/>
121
122 </category> 113 </category>
diff --git a/daemon/events-Cortex-A53.xml b/daemon/events-Cortex-A53.xml
index 577dcd9..5ba1790 100644
--- a/daemon/events-Cortex-A53.xml
+++ b/daemon/events-Cortex-A53.xml
@@ -1,171 +1,87 @@
1 <counter_set name="ARM_Cortex-A53_cnt" count="6"/> 1 <counter_set name="ARM_Cortex-A53_cnt" count="6"/>
2 <category name="Cortex-A53" counter_set="ARM_Cortex-A53_cnt" per_cpu="yes" supports_event_based_sampling="yes"> 2 <category name="Cortex-A53" counter_set="ARM_Cortex-A53_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <!-- 0x11 CPU_CYCLES - Cycle -->
4 <event counter="ARM_Cortex-A53_ccnt" event="0x11" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_Cortex-A53_ccnt" event="0x11" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
5 <!-- 0x00 SW_INCR - Instruction architecturally executed (condition check pass) - Software increment -->
6 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
7 <!-- 0x01 L1I_CACHE_REFILL - Level 1 instruction cache refill -->
8 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
9 <!-- 0x02 L1I_TLB_REFILL - Level 1 instruction TLB refill -->
10 <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/> 6 <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
11 <!-- 0x03 L1D_CACHE_REFILL - Level 1 data cache refill -->
12 <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/> 7 <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
13 <!-- 0x04 L1D_CACHE - Level 1 data cache access -->
14 <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/> 8 <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
15 <!-- 0x05 L1D_TLB_REFILL - Level 1 data TLB refill -->
16 <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/> 9 <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
17 <!-- 0x08 INST_RETIRED - Instruction architecturally executed -->
18 <event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/> 10 <event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
19 <!-- 0x09 EXC_TAKEN - Exception taken -->
20 <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/> 11 <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
21 <!-- 0x0A EXC_RETURN - Instruction architecturally executed (condition check pass) - Exception return -->
22 <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/> 12 <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
23 <!-- 0x0B CID_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to CONTEXTIDR -->
24 <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/> 13 <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
25 <!-- 0x10 BR_MIS_PRED - Mispredicted or not predicted branch speculatively executed -->
26 <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/> 14 <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
27 <!-- 0x12 BR_PRED - Predictable branch speculatively executed -->
28 <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/> 15 <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
29 <!-- 0x13 MEM_ACCESS - Data memory access -->
30 <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/> 16 <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
31 <!-- 0x14 L1I_CACHE - Level 1 instruction cache access -->
32 <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/> 17 <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/>
33 <!-- 0x15 L1D_CACHE_WB - Level 1 data cache Write-Back -->
34 <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache Write-Back"/> 18 <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache Write-Back"/>
35 <!-- 0x16 L2D_CACHE - Level 2 data cache access -->
36 <event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/> 19 <event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/>
37 <!-- 0x17 L2D_CACHE_REFILL - Level 2 data cache refill -->
38 <event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/> 20 <event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
39 <!-- 0x18 L2D_CACHE_WB - Level 2 data cache Write-Back -->
40 <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/> 21 <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/>
41 <!-- 0x19 BUS_ACCESS - Bus access -->
42 <event event="0x19" title="Bus" name="Access" description="Bus access"/> 22 <event event="0x19" title="Bus" name="Access" description="Bus access"/>
43 <!-- 0x1A MEMORY_ERROR - Local memory error -->
44 <event event="0x1A" title="Memory" name="Error" description="Local memory error"/> 23 <event event="0x1A" title="Memory" name="Error" description="Local memory error"/>
45 <!-- 0x1B INST_SPEC - Operation speculatively executed -->
46 <event event="0x1B" title="Instruction" name="Speculative" description="Operation speculatively executed"/> 24 <event event="0x1B" title="Instruction" name="Speculative" description="Operation speculatively executed"/>
47 <!-- 0x1C TTBR_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to translation table base -->
48 <event event="0x1C" title="Memory" name="Translation table" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/> 25 <event event="0x1C" title="Memory" name="Translation table" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
49 <!-- 0x1D BUS_CYCLES - Bus cycle -->
50 <event event="0x1D" title="Bus" name="Cycle" description="Bus cycle"/> 26 <event event="0x1D" title="Bus" name="Cycle" description="Bus cycle"/>
51 <!-- 0x1E CHAIN - Odd performance counter chain mode -->
52 <event event="0x1E" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/> 27 <event event="0x1E" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/>
53 <!-- 0x40 L1D_CACHE_LD - Level 1 data cache access - Read -->
54 <event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/> 28 <event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/>
55 <!-- 0x41 L1D_CACHE_ST - Level 1 data cache access - Write -->
56 <event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/> 29 <event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/>
57 <!-- 0x42 L1D_CACHE_REFILL_LD - Level 1 data cache refill - Read -->
58 <event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill - Read"/> 30 <event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill - Read"/>
59 <!-- 0x43 L1D_CACHE_REFILL_ST - Level 1 data cache refill - Write -->
60 <event event="0x43" title="Cache" name="L1 data refill write" description="Level 1 data cache refill - Write"/> 31 <event event="0x43" title="Cache" name="L1 data refill write" description="Level 1 data cache refill - Write"/>
61 <!-- 0x46 L1D_CACHE_WB_VICTIM - Level 1 data cache Write-back - Victim -->
62 <event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-back - Victim"/> 32 <event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-back - Victim"/>
63 <!-- 0x47 L1D_CACHE_WB_CLEAN - Level 1 data cache Write-back - Cleaning and coherency -->
64 <event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-back - Cleaning and coherency"/> 33 <event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-back - Cleaning and coherency"/>
65 <!-- 0x48 L1D_CACHE_INVAL - Level 1 data cache invalidate -->
66 <event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/> 34 <event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/>
67 <!-- 0x4C L1D_TLB_REFILL_LD - Level 1 data TLB refill - Read -->
68 <event event="0x4C" title="Cache" name="L1 data refill read" description="Level 1 data TLB refill - Read"/> 35 <event event="0x4C" title="Cache" name="L1 data refill read" description="Level 1 data TLB refill - Read"/>
69 <!-- 0x4D L1D_TLB_REFILL_ST - Level 1 data TLB refill - Write -->
70 <event event="0x4D" title="Cache" name="L1 data refill write" description="Level 1 data TLB refill - Write"/> 36 <event event="0x4D" title="Cache" name="L1 data refill write" description="Level 1 data TLB refill - Write"/>
71 <!-- 0x50 L2D_CACHE_LD - Level 2 data cache access - Read -->
72 <event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/> 37 <event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/>
73 <!-- 0x51 L2D_CACHE_ST - Level 2 data cache access - Write -->
74 <event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/> 38 <event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/>
75 <!-- 0x52 L2D_CACHE_REFILL_LD - Level 2 data cache refill - Read -->
76 <event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/> 39 <event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/>
77 <!-- 0x53 L2D_CACHE_REFILL_ST - Level 2 data cache refill - Write -->
78 <event event="0x53" title="Cache" name="L2 data refill write" description="Level 2 data cache refill - Write"/> 40 <event event="0x53" title="Cache" name="L2 data refill write" description="Level 2 data cache refill - Write"/>
79 <!-- 0x56 L2D_CACHE_WB_VICTIM - Level 2 data cache Write-back - Victim -->
80 <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache Write-back - Victim"/> 41 <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache Write-back - Victim"/>
81 <!-- 0x57 L2D_CACHE_WB_CLEAN - Level 2 data cache Write-back - Cleaning and coherency -->
82 <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache Write-back - Cleaning and coherency"/> 42 <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache Write-back - Cleaning and coherency"/>
83 <!-- 0x58 L2D_CACHE_INVAL - Level 2 data cache invalidate -->
84 <event event="0x58" title="Cache" name="L2 data invalidate" description="Level 2 data cache invalidate"/> 43 <event event="0x58" title="Cache" name="L2 data invalidate" description="Level 2 data cache invalidate"/>
85 <!-- 0x60 BUS_ACCESS_LD - Bus access - Read -->
86 <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/> 44 <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/>
87 <!-- 0x61 BUS_ACCESS_ST - Bus access - Write -->
88 <event event="0x61" title="Bus" name="Write" description="Bus access - Write"/> 45 <event event="0x61" title="Bus" name="Write" description="Bus access - Write"/>
89 <!-- 0x62 BUS_ACCESS_SHARED - Bus access - Normal -->
90 <event event="0x62" title="Bus" name="Access shared" description="Bus access - Normal"/> 46 <event event="0x62" title="Bus" name="Access shared" description="Bus access - Normal"/>
91 <!-- 0x63 BUS_ACCESS_NOT_SHARED - Bus access - Not normal -->
92 <event event="0x63" title="Bus" name="Access not shared" description="Bus access - Not normal"/> 47 <event event="0x63" title="Bus" name="Access not shared" description="Bus access - Not normal"/>
93 <!-- 0x64 BUS_ACCESS_NORMAL - Bus access - Normal -->
94 <event event="0x64" title="Bus" name="Access normal" description="Bus access - Normal"/> 48 <event event="0x64" title="Bus" name="Access normal" description="Bus access - Normal"/>
95 <!-- 0x65 BUS_ACCESS_PERIPH - Bus access - Peripheral -->
96 <event event="0x65" title="Bus" name="Peripheral" description="Bus access - Peripheral"/> 49 <event event="0x65" title="Bus" name="Peripheral" description="Bus access - Peripheral"/>
97 <!-- 0x66 MEM_ACCESS_LD - Data memory access - Read -->
98 <event event="0x66" title="Memory" name="Read" description="Data memory access - Read"/> 50 <event event="0x66" title="Memory" name="Read" description="Data memory access - Read"/>
99 <!-- 0x67 MEM_ACCESS_ST - Data memory access - Write -->
100 <event event="0x67" title="Memory" name="Write" description="Data memory access - Write"/> 51 <event event="0x67" title="Memory" name="Write" description="Data memory access - Write"/>
101 <!-- 0x68 UNALIGNED_LD_SPEC - Unaligned access - Read -->
102 <event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access - Read"/> 52 <event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access - Read"/>
103 <!-- 0x69 UNALIGNED_ST_SPEC - Unaligned access - Write -->
104 <event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access - Write"/> 53 <event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access - Write"/>
105 <!-- 0x6A UNALIGNED_LDST_SPEC - Unaligned access -->
106 <event event="0x6A" title="Memory" name="Unaligned" description="Unaligned access"/> 54 <event event="0x6A" title="Memory" name="Unaligned" description="Unaligned access"/>
107 <!-- 0x6C LDREX_SPEC - Exclusive operation speculatively executed - LDREX -->
108 <event event="0x6C" title="Intrinsic" name="LDREX" description="Exclusive operation speculatively executed - LDREX"/> 55 <event event="0x6C" title="Intrinsic" name="LDREX" description="Exclusive operation speculatively executed - LDREX"/>
109 <!-- 0x6D STREX_PASS_SPEC - Exclusive instruction speculatively executed - STREX pass -->
110 <event event="0x6D" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/> 56 <event event="0x6D" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/>
111 <!-- 0x6E STREX_FAIL_SPEC - Exclusive operation speculatively executed - STREX fail -->
112 <event event="0x6E" title="Intrinsic" name="STREX fail" description="Exclusive operation speculatively executed - STREX fail"/> 57 <event event="0x6E" title="Intrinsic" name="STREX fail" description="Exclusive operation speculatively executed - STREX fail"/>
113 <!-- 0x70 LD_SPEC - Operation speculatively executed - Load -->
114 <event event="0x70" title="Instruction" name="Load" description="Operation speculatively executed - Load"/> 58 <event event="0x70" title="Instruction" name="Load" description="Operation speculatively executed - Load"/>
115 <!-- 0x71 ST_SPEC - Operation speculatively executed - Store -->
116 <event event="0x71" title="Instruction" name="Store" description="Operation speculatively executed - Store"/> 59 <event event="0x71" title="Instruction" name="Store" description="Operation speculatively executed - Store"/>
117 <!-- 0x72 LDST_SPEC - Operation speculatively executed - Load or store -->
118 <event event="0x72" title="Instruction" name="Load/Store" description="Operation speculatively executed - Load or store"/> 60 <event event="0x72" title="Instruction" name="Load/Store" description="Operation speculatively executed - Load or store"/>
119 <!-- 0x73 DP_SPEC - Operation speculatively executed - Integer data processing -->
120 <event event="0x73" title="Instruction" name="Integer" description="Operation speculatively executed - Integer data processing"/> 61 <event event="0x73" title="Instruction" name="Integer" description="Operation speculatively executed - Integer data processing"/>
121 <!-- 0x74 ASE_SPEC - Operation speculatively executed - Advanced SIMD -->
122 <event event="0x74" title="Instruction" name="Advanced SIMD" description="Operation speculatively executed - Advanced SIMD"/> 62 <event event="0x74" title="Instruction" name="Advanced SIMD" description="Operation speculatively executed - Advanced SIMD"/>
123 <!-- 0x75 VFP_SPEC - Operation speculatively executed - VFP -->
124 <event event="0x75" title="Instruction" name="VFP" description="Operation speculatively executed - VFP"/> 63 <event event="0x75" title="Instruction" name="VFP" description="Operation speculatively executed - VFP"/>
125 <!-- 0x76 PC_WRITE_SPEC - Operation speculatively executed - Software change of the PC -->
126 <event event="0x76" title="Instruction" name="Software change" description="Operation speculatively executed - Software change of the PC"/> 64 <event event="0x76" title="Instruction" name="Software change" description="Operation speculatively executed - Software change of the PC"/>
127 <!-- 0x77 CRYPTO_SPEC - Operation speculatively executed, crypto data processing -->
128 <event event="0x77" title="Instruction" name="Crypto" description="Operation speculatively executed, crypto data processing"/> 65 <event event="0x77" title="Instruction" name="Crypto" description="Operation speculatively executed, crypto data processing"/>
129 <!-- 0x78 BR_IMMED_SPEC - Branch speculatively executed - Immediate branch -->
130 <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/> 66 <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/>
131 <!-- 0x79 BR_RETURN_SPEC - Branch speculatively executed - Procedure return -->
132 <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/> 67 <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/>
133 <!-- 0x7A BR_INDIRECT_SPEC - Branch speculatively executed - Indirect branch -->
134 <event event="0x7A" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/> 68 <event event="0x7A" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/>
135 <!-- 0x7C ISB_SPEC - Barrier speculatively executed - ISB -->
136 <event event="0x7C" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/> 69 <event event="0x7C" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
137 <!-- 0x7D DSB_SPEC - Barrier speculatively executed - DSB -->
138 <event event="0x7D" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/> 70 <event event="0x7D" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
139 <!-- 0x7E DMB_SPEC - Barrier speculatively executed - DMB -->
140 <event event="0x7E" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/> 71 <event event="0x7E" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
141 <!-- 0x81 EXC_UNDEF - Exception taken, other synchronous -->
142 <event event="0x81" title="Exception" name="Undefined" description="Exception taken, other synchronous"/> 72 <event event="0x81" title="Exception" name="Undefined" description="Exception taken, other synchronous"/>
143 <!-- 0x82 EXC_SVC - Exception taken, Supervisor Call -->
144 <event event="0x82" title="Exception" name="Supervisor" description="Exception taken, Supervisor Call"/> 73 <event event="0x82" title="Exception" name="Supervisor" description="Exception taken, Supervisor Call"/>
145 <!-- 0x83 EXC_PABORT - Exception taken, Instruction Abort -->
146 <event event="0x83" title="Exception" name="Instruction abort" description="Exception taken, Instruction Abort"/> 74 <event event="0x83" title="Exception" name="Instruction abort" description="Exception taken, Instruction Abort"/>
147 <!-- 0x84 EXC_DABORT - Exception taken, Data Abort or SError -->
148 <event event="0x84" title="Exception" name="Data abort" description="Exception taken, Data Abort or SError"/> 75 <event event="0x84" title="Exception" name="Data abort" description="Exception taken, Data Abort or SError"/>
149 <!-- 0x86 EXC_IRQ - Exception taken, IRQ -->
150 <event event="0x86" title="Interrupts" name="IRQ" description="Exception taken, IRQ"/> 76 <event event="0x86" title="Interrupts" name="IRQ" description="Exception taken, IRQ"/>
151 <!-- 0x87 EXC_FIQ - Exception taken, FIQ -->
152 <event event="0x87" title="Interrupts" name="FIQ" description="Exception taken, FIQ"/> 77 <event event="0x87" title="Interrupts" name="FIQ" description="Exception taken, FIQ"/>
153 <!-- 0x88 EXC_SMC - Exception taken, Secure Monitor Call -->
154 <event event="0x88" title="Exception" name="Secure monitor call" description="Exception taken, Secure Monitor Call"/> 78 <event event="0x88" title="Exception" name="Secure monitor call" description="Exception taken, Secure Monitor Call"/>
155 <!-- 0x8A EXC_HVC - Exception taken, Hypervisor Call -->
156 <event event="0x8A" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/> 79 <event event="0x8A" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/>
157 <!-- 0x8B EXC_TRAP_PABORT - Exception taken, Instruction Abort not taken locally -->
158 <event event="0x8B" title="Exception" name="Instruction abort non-local" description="Exception taken, Instruction Abort not taken locally"/> 80 <event event="0x8B" title="Exception" name="Instruction abort non-local" description="Exception taken, Instruction Abort not taken locally"/>
159 <!-- 0x8C EXC_TRAP_DABORT - Exception taken, Data Abort or SError not taken locally -->
160 <event event="0x8C" title="Exception" name="Data abort non-local" description="Exception taken, Data Abort or SError not taken locally"/> 81 <event event="0x8C" title="Exception" name="Data abort non-local" description="Exception taken, Data Abort or SError not taken locally"/>
161 <!-- 0x8D EXC_TRAP_OTHER - Exception taken - Other traps not taken locally -->
162 <event event="0x8D" title="Exception" name="Other non-local" description="Exception taken - Other traps not taken locally"/> 82 <event event="0x8D" title="Exception" name="Other non-local" description="Exception taken - Other traps not taken locally"/>
163 <!-- 0x8E EXC_TRAP_IRQ - Exception taken, IRQ not taken locally -->
164 <event event="0x8E" title="Exception" name="IRQ non-local" description="Exception taken, IRQ not taken locally"/> 83 <event event="0x8E" title="Exception" name="IRQ non-local" description="Exception taken, IRQ not taken locally"/>
165 <!-- 0x8F EXC_TRAP_FIQ - Exception taken, FIQ not taken locally -->
166 <event event="0x8F" title="Exception" name="FIQ non-local" description="Exception taken, FIQ not taken locally"/> 84 <event event="0x8F" title="Exception" name="FIQ non-local" description="Exception taken, FIQ not taken locally"/>
167 <!-- 0x90 RC_LD_SPEC - Release consistency instruction speculatively executed - Load Acquire -->
168 <event event="0x90" title="Release Consistency" name="Load" description="Release consistency instruction speculatively executed - Load Acquire"/> 85 <event event="0x90" title="Release Consistency" name="Load" description="Release consistency instruction speculatively executed - Load Acquire"/>
169 <!-- 0x91 RC_ST_SPEC - Release consistency instruction speculatively executed - Store Release -->
170 <event event="0x91" title="Release Consistency" name="Store" description="Release consistency instruction speculatively executed - Store Release"/> 86 <event event="0x91" title="Release Consistency" name="Store" description="Release consistency instruction speculatively executed - Store Release"/>
171 </category> 87 </category>
diff --git a/daemon/events-Cortex-A57.xml b/daemon/events-Cortex-A57.xml
index b7178c0..fbe96c2 100644
--- a/daemon/events-Cortex-A57.xml
+++ b/daemon/events-Cortex-A57.xml
@@ -1,171 +1,87 @@
1 <counter_set name="ARM_Cortex-A57_cnt" count="6"/> 1 <counter_set name="ARM_Cortex-A57_cnt" count="6"/>
2 <category name="Cortex-A57" counter_set="ARM_Cortex-A57_cnt" per_cpu="yes" supports_event_based_sampling="yes"> 2 <category name="Cortex-A57" counter_set="ARM_Cortex-A57_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <!-- 0x11 CPU_CYCLES - Cycle -->
4 <event counter="ARM_Cortex-A57_ccnt" event="0x11" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_Cortex-A57_ccnt" event="0x11" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" average_cores="yes" description="The number of core clock cycles"/>
5 <!-- 0x00 SW_INCR - Instruction architecturally executed (condition check pass) - Software increment -->
6 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
7 <!-- 0x01 L1I_CACHE_REFILL - Level 1 instruction cache refill -->
8 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
9 <!-- 0x02 L1I_TLB_REFILL - Level 1 instruction TLB refill -->
10 <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/> 6 <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
11 <!-- 0x03 L1D_CACHE_REFILL - Level 1 data cache refill -->
12 <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/> 7 <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
13 <!-- 0x04 L1D_CACHE - Level 1 data cache access -->
14 <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/> 8 <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
15 <!-- 0x05 L1D_TLB_REFILL - Level 1 data TLB refill -->
16 <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/> 9 <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
17 <!-- 0x08 INST_RETIRED - Instruction architecturally executed -->
18 <event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/> 10 <event event="0x08" title="Instruction" name="Executed" description="Instruction architecturally executed"/>
19 <!-- 0x09 EXC_TAKEN - Exception taken -->
20 <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/> 11 <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
21 <!-- 0x0A EXC_RETURN - Instruction architecturally executed (condition check pass) - Exception return -->
22 <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/> 12 <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
23 <!-- 0x0B CID_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to CONTEXTIDR -->
24 <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/> 13 <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
25 <!-- 0x10 BR_MIS_PRED - Mispredicted or not predicted branch speculatively executed -->
26 <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/> 14 <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
27 <!-- 0x12 BR_PRED - Predictable branch speculatively executed -->
28 <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/> 15 <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
29 <!-- 0x13 MEM_ACCESS - Data memory access -->
30 <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/> 16 <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
31 <!-- 0x14 L1I_CACHE - Level 1 instruction cache access -->
32 <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/> 17 <event event="0x14" title="Cache" name="L1 inst access" description="Level 1 instruction cache access"/>
33 <!-- 0x15 L1D_CACHE_WB - Level 1 data cache Write-Back -->
34 <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache Write-Back"/> 18 <event event="0x15" title="Cache" name="L1 data write" description="Level 1 data cache Write-Back"/>
35 <!-- 0x16 L2D_CACHE - Level 2 data cache access -->
36 <event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/> 19 <event event="0x16" title="Cache" name="L2 data access" description="Level 2 data cache access"/>
37 <!-- 0x17 L2D_CACHE_REFILL - Level 2 data cache refill -->
38 <event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/> 20 <event event="0x17" title="Cache" name="L2 data refill" description="Level 2 data cache refill"/>
39 <!-- 0x18 L2D_CACHE_WB - Level 2 data cache Write-Back -->
40 <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/> 21 <event event="0x18" title="Cache" name="L2 data write" description="Level 2 data cache Write-Back"/>
41 <!-- 0x19 BUS_ACCESS - Bus access -->
42 <event event="0x19" title="Bus" name="Access" description="Bus access"/> 22 <event event="0x19" title="Bus" name="Access" description="Bus access"/>
43 <!-- 0x1A MEMORY_ERROR - Local memory error -->
44 <event event="0x1A" title="Memory" name="Error" description="Local memory error"/> 23 <event event="0x1A" title="Memory" name="Error" description="Local memory error"/>
45 <!-- 0x1B INST_SPEC - Operation speculatively executed -->
46 <event event="0x1B" title="Instruction" name="Speculative" description="Operation speculatively executed"/> 24 <event event="0x1B" title="Instruction" name="Speculative" description="Operation speculatively executed"/>
47 <!-- 0x1C TTBR_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to translation table base -->
48 <event event="0x1C" title="Memory" name="Translation table" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/> 25 <event event="0x1C" title="Memory" name="Translation table" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
49 <!-- 0x1D BUS_CYCLES - Bus cycle -->
50 <event event="0x1D" title="Bus" name="Cycle" description="Bus cycle"/> 26 <event event="0x1D" title="Bus" name="Cycle" description="Bus cycle"/>
51 <!-- 0x1E CHAIN - Odd performance counter chain mode -->
52 <event event="0x1E" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/> 27 <event event="0x1E" title="Counter chain" name="Odd Performance" description="Odd performance counter chain mode"/>
53 <!-- 0x40 L1D_CACHE_LD - Level 1 data cache access - Read -->
54 <event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/> 28 <event event="0x40" title="Cache" name="L1 data read" description="Level 1 data cache access - Read"/>
55 <!-- 0x41 L1D_CACHE_ST - Level 1 data cache access - Write -->
56 <event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/> 29 <event event="0x41" title="Cache" name="L1 data access write" description="Level 1 data cache access - Write"/>
57 <!-- 0x42 L1D_CACHE_REFILL_LD - Level 1 data cache refill - Read -->
58 <event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill - Read"/> 30 <event event="0x42" title="Cache" name="L1 data refill read" description="Level 1 data cache refill - Read"/>
59 <!-- 0x43 L1D_CACHE_REFILL_ST - Level 1 data cache refill - Write -->
60 <event event="0x43" title="Cache" name="L1 data refill write" description="Level 1 data cache refill - Write"/> 31 <event event="0x43" title="Cache" name="L1 data refill write" description="Level 1 data cache refill - Write"/>
61 <!-- 0x46 L1D_CACHE_WB_VICTIM - Level 1 data cache Write-back - Victim -->
62 <event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-back - Victim"/> 32 <event event="0x46" title="Cache" name="L1 data victim" description="Level 1 data cache Write-back - Victim"/>
63 <!-- 0x47 L1D_CACHE_WB_CLEAN - Level 1 data cache Write-back - Cleaning and coherency -->
64 <event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-back - Cleaning and coherency"/> 33 <event event="0x47" title="Cache" name="L1 data clean" description="Level 1 data cache Write-back - Cleaning and coherency"/>
65 <!-- 0x48 L1D_CACHE_INVAL - Level 1 data cache invalidate -->
66 <event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/> 34 <event event="0x48" title="Cache" name="L1 data invalidate" description="Level 1 data cache invalidate"/>
67 <!-- 0x4C L1D_TLB_REFILL_LD - Level 1 data TLB refill - Read -->
68 <event event="0x4C" title="Cache" name="L1 data refill read" description="Level 1 data TLB refill - Read"/> 35 <event event="0x4C" title="Cache" name="L1 data refill read" description="Level 1 data TLB refill - Read"/>
69 <!-- 0x4D L1D_TLB_REFILL_ST - Level 1 data TLB refill - Write -->
70 <event event="0x4D" title="Cache" name="L1 data refill write" description="Level 1 data TLB refill - Write"/> 36 <event event="0x4D" title="Cache" name="L1 data refill write" description="Level 1 data TLB refill - Write"/>
71 <!-- 0x50 L2D_CACHE_LD - Level 2 data cache access - Read -->
72 <event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/> 37 <event event="0x50" title="Cache" name="L2 data read" description="Level 2 data cache access - Read"/>
73 <!-- 0x51 L2D_CACHE_ST - Level 2 data cache access - Write -->
74 <event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/> 38 <event event="0x51" title="Cache" name="L2 data access write" description="Level 2 data cache access - Write"/>
75 <!-- 0x52 L2D_CACHE_REFILL_LD - Level 2 data cache refill - Read -->
76 <event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/> 39 <event event="0x52" title="Cache" name="L2 data refill read" description="Level 2 data cache refill - Read"/>
77 <!-- 0x53 L2D_CACHE_REFILL_ST - Level 2 data cache refill - Write -->
78 <event event="0x53" title="Cache" name="L2 data refill write" description="Level 2 data cache refill - Write"/> 40 <event event="0x53" title="Cache" name="L2 data refill write" description="Level 2 data cache refill - Write"/>
79 <!-- 0x56 L2D_CACHE_WB_VICTIM - Level 2 data cache Write-back - Victim -->
80 <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache Write-back - Victim"/> 41 <event event="0x56" title="Cache" name="L2 data victim" description="Level 2 data cache Write-back - Victim"/>
81 <!-- 0x57 L2D_CACHE_WB_CLEAN - Level 2 data cache Write-back - Cleaning and coherency -->
82 <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache Write-back - Cleaning and coherency"/> 42 <event event="0x57" title="Cache" name="L2 data clean" description="Level 2 data cache Write-back - Cleaning and coherency"/>
83 <!-- 0x58 L2D_CACHE_INVAL - Level 2 data cache invalidate -->
84 <event event="0x58" title="Cache" name="L2 data invalidate" description="Level 2 data cache invalidate"/> 43 <event event="0x58" title="Cache" name="L2 data invalidate" description="Level 2 data cache invalidate"/>
85 <!-- 0x60 BUS_ACCESS_LD - Bus access - Read -->
86 <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/> 44 <event event="0x60" title="Bus" name="Read" description="Bus access - Read"/>
87 <!-- 0x61 BUS_ACCESS_ST - Bus access - Write -->
88 <event event="0x61" title="Bus" name="Write" description="Bus access - Write"/> 45 <event event="0x61" title="Bus" name="Write" description="Bus access - Write"/>
89 <!-- 0x62 BUS_ACCESS_SHARED - Bus access - Normal -->
90 <event event="0x62" title="Bus" name="Access shared" description="Bus access - Normal"/> 46 <event event="0x62" title="Bus" name="Access shared" description="Bus access - Normal"/>
91 <!-- 0x63 BUS_ACCESS_NOT_SHARED - Bus access - Not normal -->
92 <event event="0x63" title="Bus" name="Access not shared" description="Bus access - Not normal"/> 47 <event event="0x63" title="Bus" name="Access not shared" description="Bus access - Not normal"/>
93 <!-- 0x64 BUS_ACCESS_NORMAL - Bus access - Normal -->
94 <event event="0x64" title="Bus" name="Access normal" description="Bus access - Normal"/> 48 <event event="0x64" title="Bus" name="Access normal" description="Bus access - Normal"/>
95 <!-- 0x65 BUS_ACCESS_PERIPH - Bus access - Peripheral -->
96 <event event="0x65" title="Bus" name="Peripheral" description="Bus access - Peripheral"/> 49 <event event="0x65" title="Bus" name="Peripheral" description="Bus access - Peripheral"/>
97 <!-- 0x66 MEM_ACCESS_LD - Data memory access - Read -->
98 <event event="0x66" title="Memory" name="Read" description="Data memory access - Read"/> 50 <event event="0x66" title="Memory" name="Read" description="Data memory access - Read"/>
99 <!-- 0x67 MEM_ACCESS_ST - Data memory access - Write -->
100 <event event="0x67" title="Memory" name="Write" description="Data memory access - Write"/> 51 <event event="0x67" title="Memory" name="Write" description="Data memory access - Write"/>
101 <!-- 0x68 UNALIGNED_LD_SPEC - Unaligned access - Read -->
102 <event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access - Read"/> 52 <event event="0x68" title="Memory" name="Unaligned Read" description="Unaligned access - Read"/>
103 <!-- 0x69 UNALIGNED_ST_SPEC - Unaligned access - Write -->
104 <event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access - Write"/> 53 <event event="0x69" title="Memory" name="Unaligned Write" description="Unaligned access - Write"/>
105 <!-- 0x6A UNALIGNED_LDST_SPEC - Unaligned access -->
106 <event event="0x6A" title="Memory" name="Unaligned" description="Unaligned access"/> 54 <event event="0x6A" title="Memory" name="Unaligned" description="Unaligned access"/>
107 <!-- 0x6C LDREX_SPEC - Exclusive operation speculatively executed - LDREX -->
108 <event event="0x6C" title="Intrinsic" name="LDREX" description="Exclusive operation speculatively executed - LDREX"/> 55 <event event="0x6C" title="Intrinsic" name="LDREX" description="Exclusive operation speculatively executed - LDREX"/>
109 <!-- 0x6D STREX_PASS_SPEC - Exclusive instruction speculatively executed - STREX pass -->
110 <event event="0x6D" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/> 56 <event event="0x6D" title="Intrinsic" name="STREX pass" description="Exclusive instruction speculatively executed - STREX pass"/>
111 <!-- 0x6E STREX_FAIL_SPEC - Exclusive operation speculatively executed - STREX fail -->
112 <event event="0x6E" title="Intrinsic" name="STREX fail" description="Exclusive operation speculatively executed - STREX fail"/> 57 <event event="0x6E" title="Intrinsic" name="STREX fail" description="Exclusive operation speculatively executed - STREX fail"/>
113 <!-- 0x70 LD_SPEC - Operation speculatively executed - Load -->
114 <event event="0x70" title="Instruction" name="Load" description="Operation speculatively executed - Load"/> 58 <event event="0x70" title="Instruction" name="Load" description="Operation speculatively executed - Load"/>
115 <!-- 0x71 ST_SPEC - Operation speculatively executed - Store -->
116 <event event="0x71" title="Instruction" name="Store" description="Operation speculatively executed - Store"/> 59 <event event="0x71" title="Instruction" name="Store" description="Operation speculatively executed - Store"/>
117 <!-- 0x72 LDST_SPEC - Operation speculatively executed - Load or store -->
118 <event event="0x72" title="Instruction" name="Load/Store" description="Operation speculatively executed - Load or store"/> 60 <event event="0x72" title="Instruction" name="Load/Store" description="Operation speculatively executed - Load or store"/>
119 <!-- 0x73 DP_SPEC - Operation speculatively executed - Integer data processing -->
120 <event event="0x73" title="Instruction" name="Integer" description="Operation speculatively executed - Integer data processing"/> 61 <event event="0x73" title="Instruction" name="Integer" description="Operation speculatively executed - Integer data processing"/>
121 <!-- 0x74 ASE_SPEC - Operation speculatively executed - Advanced SIMD -->
122 <event event="0x74" title="Instruction" name="Advanced SIMD" description="Operation speculatively executed - Advanced SIMD"/> 62 <event event="0x74" title="Instruction" name="Advanced SIMD" description="Operation speculatively executed - Advanced SIMD"/>
123 <!-- 0x75 VFP_SPEC - Operation speculatively executed - VFP -->
124 <event event="0x75" title="Instruction" name="VFP" description="Operation speculatively executed - VFP"/> 63 <event event="0x75" title="Instruction" name="VFP" description="Operation speculatively executed - VFP"/>
125 <!-- 0x76 PC_WRITE_SPEC - Operation speculatively executed - Software change of the PC -->
126 <event event="0x76" title="Instruction" name="Software change" description="Operation speculatively executed - Software change of the PC"/> 64 <event event="0x76" title="Instruction" name="Software change" description="Operation speculatively executed - Software change of the PC"/>
127 <!-- 0x77 CRYPTO_SPEC - Operation speculatively executed, crypto data processing -->
128 <event event="0x77" title="Instruction" name="Crypto" description="Operation speculatively executed, crypto data processing"/> 65 <event event="0x77" title="Instruction" name="Crypto" description="Operation speculatively executed, crypto data processing"/>
129 <!-- 0x78 BR_IMMED_SPEC - Branch speculatively executed - Immediate branch -->
130 <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/> 66 <event event="0x78" title="Instruction" name="Immediate branch" description="Branch speculatively executed - Immediate branch"/>
131 <!-- 0x79 BR_RETURN_SPEC - Branch speculatively executed - Procedure return -->
132 <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/> 67 <event event="0x79" title="Instruction" name="Procedure return" description="Branch speculatively executed - Procedure return"/>
133 <!-- 0x7A BR_INDIRECT_SPEC - Branch speculatively executed - Indirect branch -->
134 <event event="0x7A" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/> 68 <event event="0x7A" title="Instruction" name="Indirect branch" description="Branch speculatively executed - Indirect branch"/>
135 <!-- 0x7C ISB_SPEC - Barrier speculatively executed - ISB -->
136 <event event="0x7C" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/> 69 <event event="0x7C" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
137 <!-- 0x7D DSB_SPEC - Barrier speculatively executed - DSB -->
138 <event event="0x7D" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/> 70 <event event="0x7D" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
139 <!-- 0x7E DMB_SPEC - Barrier speculatively executed - DMB -->
140 <event event="0x7E" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/> 71 <event event="0x7E" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
141 <!-- 0x81 EXC_UNDEF - Exception taken, other synchronous -->
142 <event event="0x81" title="Exception" name="Undefined" description="Exception taken, other synchronous"/> 72 <event event="0x81" title="Exception" name="Undefined" description="Exception taken, other synchronous"/>
143 <!-- 0x82 EXC_SVC - Exception taken, Supervisor Call -->
144 <event event="0x82" title="Exception" name="Supervisor" description="Exception taken, Supervisor Call"/> 73 <event event="0x82" title="Exception" name="Supervisor" description="Exception taken, Supervisor Call"/>
145 <!-- 0x83 EXC_PABORT - Exception taken, Instruction Abort -->
146 <event event="0x83" title="Exception" name="Instruction abort" description="Exception taken, Instruction Abort"/> 74 <event event="0x83" title="Exception" name="Instruction abort" description="Exception taken, Instruction Abort"/>
147 <!-- 0x84 EXC_DABORT - Exception taken, Data Abort or SError -->
148 <event event="0x84" title="Exception" name="Data abort" description="Exception taken, Data Abort or SError"/> 75 <event event="0x84" title="Exception" name="Data abort" description="Exception taken, Data Abort or SError"/>
149 <!-- 0x86 EXC_IRQ - Exception taken, IRQ -->
150 <event event="0x86" title="Interrupts" name="IRQ" description="Exception taken, IRQ"/> 76 <event event="0x86" title="Interrupts" name="IRQ" description="Exception taken, IRQ"/>
151 <!-- 0x87 EXC_FIQ - Exception taken, FIQ -->
152 <event event="0x87" title="Interrupts" name="FIQ" description="Exception taken, FIQ"/> 77 <event event="0x87" title="Interrupts" name="FIQ" description="Exception taken, FIQ"/>
153 <!-- 0x88 EXC_SMC - Exception taken, Secure Monitor Call -->
154 <event event="0x88" title="Exception" name="Secure monitor call" description="Exception taken, Secure Monitor Call"/> 78 <event event="0x88" title="Exception" name="Secure monitor call" description="Exception taken, Secure Monitor Call"/>
155 <!-- 0x8A EXC_HVC - Exception taken, Hypervisor Call -->
156 <event event="0x8A" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/> 79 <event event="0x8A" title="Exception" name="Hypervisor call" description="Exception taken, Hypervisor Call"/>
157 <!-- 0x8B EXC_TRAP_PABORT - Exception taken, Instruction Abort not taken locally -->
158 <event event="0x8B" title="Exception" name="Instruction abort non-local" description="Exception taken, Instruction Abort not taken locally"/> 80 <event event="0x8B" title="Exception" name="Instruction abort non-local" description="Exception taken, Instruction Abort not taken locally"/>
159 <!-- 0x8C EXC_TRAP_DABORT - Exception taken, Data Abort or SError not taken locally -->
160 <event event="0x8C" title="Exception" name="Data abort non-local" description="Exception taken, Data Abort or SError not taken locally"/> 81 <event event="0x8C" title="Exception" name="Data abort non-local" description="Exception taken, Data Abort or SError not taken locally"/>
161 <!-- 0x8D EXC_TRAP_OTHER - Exception taken - Other traps not taken locally -->
162 <event event="0x8D" title="Exception" name="Other non-local" description="Exception taken - Other traps not taken locally"/> 82 <event event="0x8D" title="Exception" name="Other non-local" description="Exception taken - Other traps not taken locally"/>
163 <!-- 0x8E EXC_TRAP_IRQ - Exception taken, IRQ not taken locally -->
164 <event event="0x8E" title="Exception" name="IRQ non-local" description="Exception taken, IRQ not taken locally"/> 83 <event event="0x8E" title="Exception" name="IRQ non-local" description="Exception taken, IRQ not taken locally"/>
165 <!-- 0x8F EXC_TRAP_FIQ - Exception taken, FIQ not taken locally -->
166 <event event="0x8F" title="Exception" name="FIQ non-local" description="Exception taken, FIQ not taken locally"/> 84 <event event="0x8F" title="Exception" name="FIQ non-local" description="Exception taken, FIQ not taken locally"/>
167 <!-- 0x90 RC_LD_SPEC - Release consistency instruction speculatively executed - Load Acquire -->
168 <event event="0x90" title="Release Consistency" name="Load" description="Release consistency instruction speculatively executed - Load Acquire"/> 85 <event event="0x90" title="Release Consistency" name="Load" description="Release consistency instruction speculatively executed - Load Acquire"/>
169 <!-- 0x91 RC_ST_SPEC - Release consistency instruction speculatively executed - Store Release -->
170 <event event="0x91" title="Release Consistency" name="Store" description="Release consistency instruction speculatively executed - Store Release"/> 86 <event event="0x91" title="Release Consistency" name="Store" description="Release consistency instruction speculatively executed - Store Release"/>
171 </category> 87 </category>
diff --git a/daemon/events-Filesystem.xml b/daemon/events-Filesystem.xml
new file mode 100644
index 0000000..5feeb90
--- /dev/null
+++ b/daemon/events-Filesystem.xml
@@ -0,0 +1,11 @@
1 <category name="Filesystem">
2 <!-- counter attributes must be unique -->
3 <!-- regex item in () is the value shown -->
4 <!-- these counters are not compatible with userspace gator, i.e. gator.ko must be loaded -->
5 <!--
6 <event counter="/sys/devices/system/cpu/cpu1/online" title="online" name="cpu 1" class="absolute" description="If cpu 1 is online"/>
7 <event counter="/proc/self/loginuid" title="loginuid" name="loginuid" class="absolute" description="loginuid"/>
8 <event counter="/proc/self/stat" title="stat" name="rss" class="absolute" regex="-?[0-9]+ \(.*\) . -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ -?[0-9]+ (-?[0-9]+)" units="pages" description="resident set size"/>
9 <event counter="/proc/stat" title="proc-stat" name="processes" class="absolute" regex="processes ([0-9]+)" description="Number of processes and threads created"/>
10 -->
11 </category>
diff --git a/daemon/events-L2C-310.xml b/daemon/events-L2C-310.xml
index 4da4d1d..923fb90 100644
--- a/daemon/events-L2C-310.xml
+++ b/daemon/events-L2C-310.xml
@@ -1,18 +1,18 @@
1 <counter_set name="L2C-310_cnt" count="2"/> 1 <counter_set name="L2C-310_cnt" count="2"/>
2 <category name="L2C-310" counter_set="L2C-310_cnt" per_cpu="no"> 2 <category name="L2C-310" counter_set="L2C-310_cnt" per_cpu="no">
3 <event event="0x1" title="L2 Cache" name="CO" description="Eviction, CastOUT, of a line from the L2 cache"/> 3 <event event="0x1" title="L2 Cache" name="CastOUT" description="Eviction, CastOUT, of a line from the L2 cache"/>
4 <event event="0x2" title="L2 Cache" name="DRH" description="Data read hit"/> 4 <event event="0x2" title="L2 Cache" name="Data Read Hit" description="Data read hit in the L2 cache"/>
5 <event event="0x3" title="L2 Cache" name="DRREQ" description="Data read request"/> 5 <event event="0x3" title="L2 Cache" name="Data Read Request" description="Data read lookup to the L2 cache. Subsequently results in a hit or miss"/>
6 <event event="0x4" title="L2 Cache" name="DWHIT" description="Data write hit"/> 6 <event event="0x4" title="L2 Cache" name="Data Write Hit" description="Data write hit in the L2 cache"/>
7 <event event="0x5" title="L2 Cache" name="DWREQ" description="Data write request"/> 7 <event event="0x5" title="L2 Cache" name="Data Write Request" description="Data write lookup to the L2 cache. Subsequently results in a hit or miss"/>
8 <event event="0x6" title="L2 Cache" name="DWTREQ" description="Data write request with write-through attribute"/> 8 <event event="0x6" title="L2 Cache" name="Data Write-Through Request" description="Data write lookup to the L2 cache with Write-Through attribute. Subsequently results in a hit or miss"/>
9 <event event="0x7" title="L2 Cache" name="IRHIT" description="Instruction read hit"/> 9 <event event="0x7" title="L2 Cache" name="Instruction Read Hit" description="Instruction read hit in the L2 cache"/>
10 <event event="0x8" title="L2 Cache" name="IRREQ" description="Instruction read request"/> 10 <event event="0x8" title="L2 Cache" name="Instruction Read Request" description="Instruction read lookup to the L2 cache. Subsequently results in a hit or miss"/>
11 <event event="0x9" title="L2 Cache" name="WA" description="Write allocate"/> 11 <event event="0x9" title="L2 Cache" name="Write Allocate Miss" description="Allocation into the L2 cache caused by a write, with Write-Allocate attribute, miss"/>
12 <event event="0xa" title="L2 Cache" name="IPFALLOC" description="Allocation of a prefetch generated by L2C-310 into the L2 cache"/> 12 <event event="0xa" title="L2 Cache" name="Internal Prefetch Allocate" description="Allocation of a prefetch generated by L2C-310 into the L2 cache"/>
13 <event event="0xb" title="L2 Cache" name="EPFHIT" description="Prefetch hint hits in the L2 cache"/> 13 <event event="0xb" title="L2 Cache" name="Prefitch Hit" description="Prefetch hint hits in the L2 cache"/>
14 <event event="0xc" title="L2 Cache" name="EPFALLOC" description="Prefetch hint allocated into the L2 cache"/> 14 <event event="0xc" title="L2 Cache" name="Prefitch Allocate" description="Prefetch hint allocated into the L2 cache"/>
15 <event event="0xd" title="L2 Cache" name="SRRCVD" description="Speculative read received"/> 15 <event event="0xd" title="L2 Cache" name="Speculative Read Received" description="Speculative read received"/>
16 <event event="0xe" title="L2 Cache" name="SRCONF" description="Speculative read confirmed"/> 16 <event event="0xe" title="L2 Cache" name="Speculative Read Confirmed" description="Speculative read confirmed"/>
17 <event event="0xf" title="L2 Cache" name="EPFRCVD" description="Prefetch hint received"/> 17 <event event="0xf" title="L2 Cache" name="Prefetch Hint Received" description="Prefetch hint received"/>
18 </category> 18 </category>
diff --git a/daemon/events-Linux.xml b/daemon/events-Linux.xml
index 4d677e1..c306dd6 100644
--- a/daemon/events-Linux.xml
+++ b/daemon/events-Linux.xml
@@ -11,7 +11,6 @@
11 <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" class="absolute" units="B" description="Memory used by OS disk buffers"/> 11 <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" class="absolute" units="B" description="Memory used by OS disk buffers"/>
12 <event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" class="absolute" units="Hz" series_composition="overlay" average_cores="yes" description="Frequency setting of the CPU"/> 12 <event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" class="absolute" units="Hz" series_composition="overlay" average_cores="yes" description="Frequency setting of the CPU"/>
13 <event counter="Linux_power_cpu_idle" title="Idle" name="State" per_cpu="yes" class="absolute" description="CPU Idle State + 1, set the Sample Rate to None to prevent the hrtimer from interrupting the system"/> 13 <event counter="Linux_power_cpu_idle" title="Idle" name="State" per_cpu="yes" class="absolute" description="CPU Idle State + 1, set the Sample Rate to None to prevent the hrtimer from interrupting the system"/>
14 <event counter="Linux_cpu_wait_contention" title="CPU Contention" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" modifier="10000" description="Thread waiting on contended resource"/> 14 <event counter="Linux_cpu_wait_contention" title="CPU Contention" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" modifier="10000" color="0x003c96fb" description="Thread waiting on contended resource"/>
15 <event counter="Linux_cpu_wait_io" title="CPU I/O" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" modifier="10000" description="Thread waiting on I/O resource"/> 15 <event counter="Linux_cpu_wait_io" title="CPU I/O" name="Wait" per_cpu="no" class="activity" derived="yes" rendering_type="bar" average_selection="yes" percentage="yes" modifier="10000" color="0x00b30000" description="Thread waiting on I/O resource"/>
16 </category> 16 </category>
17
diff --git a/daemon/events-Mali-4xx.xml b/daemon/events-Mali-4xx.xml
index 5a71386..0a95dfe 100644
--- a/daemon/events-Mali-4xx.xml
+++ b/daemon/events-Mali-4xx.xml
@@ -1,34 +1,33 @@
1 <counter_set name="ARM_Mali-4xx_VP_0_cnt" count="2"/> 1 <counter_set name="ARM_Mali-4xx_VP_0_cnt" count="2"/>
2 <counter_set name="ARM_Mali-4xx_SW_cnt" count="0"/> 2 <counter_set name="ARM_Mali-4xx_SW_cnt" count="0"/>
3 <counter_set name="ARM_Mali-4xx_Filmstrip_cnt" count="1"/> 3 <category name="Mali Vertex Processor" counter_set="ARM_Mali-4xx_VP_0_cnt" per_cpu="no">
4 <category name="Mali-4xx-VP" counter_set="ARM_Mali-4xx_VP_0_cnt" per_cpu="no"> 4 <event event="0x01" title="Mali-4xx VP" name="Active cycles" description="Number of cycles per frame the MaliGP2 was active."/>
5 <event event="0x01" title="Mali GPU Vertex Processor" name="Active cycles" description="Number of cycles per frame the MaliGP2 was active."/> 5 <event event="0x02" title="Mali-4xx VP" name="Active cycles, vertex shader" description="Number of cycles per frame the vertex shader unit was active."/>
6 <event event="0x02" title="Mali GPU Vertex Processor" name="Active cycles, vertex shader" description="Number of cycles per frame the vertex shader unit was active."/> 6 <event event="0x03" title="Mali-4xx VP" name="Active cycles, vertex storer" description="Number of cycles per frame the vertex storer unit was active."/>
7 <event event="0x03" title="Mali GPU Vertex Processor" name="Active cycles, vertex storer" description="Number of cycles per frame the vertex storer unit was active."/> 7 <event event="0x04" title="Mali-4xx VP" name="Active cycles, vertex loader" description="Number of cycles per frame the vertex loader unit was active."/>
8 <event event="0x04" title="Mali GPU Vertex Processor" name="Active cycles, vertex loader" description="Number of cycles per frame the vertex loader unit was active."/> 8 <event event="0x05" title="Mali-4xx VP" name="Cycles vertex loader waiting for vertex shader" description="Number of cycles per frame the vertex loader was idle while waiting on the vertex shader."/>
9 <event event="0x05" title="Mali GPU Vertex Processor" name="Cycles vertex loader waiting for vertex shader" description="Number of cycles per frame the vertex loader was idle while waiting on the vertex shader."/> 9 <event event="0x06" title="Mali-4xx VP" name="Words read, system bus" description="Total number of 64 bit words read by the GP2 from the system bus per frame."/>
10 <event event="0x06" title="Mali GPU Vertex Processor" name="Words read, system bus" description="Total number of 64 bit words read by the GP2 from the system bus per frame."/> 10 <event event="0x07" title="Mali-4xx VP" name="Words written, system bus" description="Total number of 64 bit words written by the GP2 to the system bus per frame."/>
11 <event event="0x07" title="Mali GPU Vertex Processor" name="Words written, system bus" description="Total number of 64 bit words written by the GP2 to the system bus per frame."/> 11 <event event="0x08" title="Mali-4xx VP" name="Read bursts, system bus" description="Number of read bursts by the GP2 from the system bus per frame."/>
12 <event event="0x08" title="Mali GPU Vertex Processor" name="Read bursts, system bus" description="Number of read bursts by the GP2 from the system bus per frame."/> 12 <event event="0x09" title="Mali-4xx VP" name="Write bursts, system bus" description="Number of write bursts from the MaliGP2 to the system bus per frame."/>
13 <event event="0x09" title="Mali GPU Vertex Processor" name="Write bursts, system bus" description="Number of write bursts from the MaliGP2 to the system bus per frame."/> 13 <event event="0x0a" title="Mali-4xx VP" name="Vertices processed" description="Number of vertices processed by the MaliGP2 per frame."/>
14 <event event="0x0a" title="Mali GPU Vertex Processor" name="Vertices processed" description="Number of vertices processed by the MaliGP2 per frame."/> 14 <event event="0x0b" title="Mali-4xx VP" name="Vertices fetched" description="Number of vertices fetched by the MaliGP2 per frame."/>
15 <event event="0x0b" title="Mali GPU Vertex Processor" name="Vertices fetched" description="Number of vertices fetched by the MaliGP2 per frame."/> 15 <event event="0x0c" title="Mali-4xx VP" name="Primitives fetched" description="Number of graphics primitives fetched by the MaliGP2 per frame."/>
16 <event event="0x0c" title="Mali GPU Vertex Processor" name="Primitives fetched" description="Number of graphics primitives fetched by the MaliGP2 per frame."/> 16 <event event="0x0e" title="Mali-4xx VP" name="Primitives culled" description="Number of graphics primitives discarded per frame, because they were seen from the back or were offscreen."/>
17 <event event="0x0e" title="Mali GPU Vertex Processor" name="Primitives culled" description="Number of graphics primitives discarded per frame, because they were seen from the back or were offscreen."/> 17 <event event="0x0f" title="Mali-4xx VP" name="Commands written to tiles" description="Number of commands (8 Bytes, mainly primitives) written by GP2 to the PP input data structure per frame."/>
18 <event event="0x0f" title="Mali GPU Vertex Processor" name="Commands written to tiles" description="Number of commands (8 Bytes, mainly primitives) written by GP2 to the PP input data structure per frame."/> 18 <event event="0x10" title="Mali-4xx VP" name="Memory blocks allocated" description="Number of overflow data blocks needed for outputting the PP input data structure per frame ."/>
19 <event event="0x10" title="Mali GPU Vertex Processor" name="Memory blocks allocated" description="Number of overflow data blocks needed for outputting the PP input data structure per frame ."/> 19 <event event="0x13" title="Mali-4xx VP" name="Vertex loader cache misses" description="Number of cache misses for the vertex shader's vertex input unit per frame."/>
20 <event event="0x13" title="Mali GPU Vertex Processor" name="Vertex loader cache misses" description="Number of cache misses for the vertex shader's vertex input unit per frame."/> 20 <event event="0x16" title="Mali-4xx VP" name="Active cycles, vertex shader command processor" description="Number of cycles per frame the GP2 vertex shader command processor was active. This includes time waiting for semaphores."/>
21 <event event="0x16" title="Mali GPU Vertex Processor" name="Active cycles, vertex shader command processor" description="Number of cycles per frame the GP2 vertex shader command processor was active. This includes time waiting for semaphores."/> 21 <event event="0x17" title="Mali-4xx VP" name="Active cycles, PLBU command processor" description="Number of cycles per frame the MaliGP2 PLBU command processor was active. This includes time waiting for semaphores."/>
22 <event event="0x17" title="Mali GPU Vertex Processor" name="Active cycles, PLBU command processor" description="Number of cycles per frame the MaliGP2 PLBU command processor was active. This includes time waiting for semaphores."/> 22 <event event="0x18" title="Mali-4xx VP" name="Active Cycles, PLBU list writer" description="Number of cycles per frame the MaliGP2 PLBU output unit was active. This includes time spent waiting on the bus."/>
23 <event event="0x18" title="Mali GPU Vertex Processor" name="MaliGP2 PLBU cycles per frame" description="Number of cycles per frame the MaliGP2 PLBU output unit was active. This includes time spent waiting on the bus."/> 23 <event event="0x19" title="Mali-4xx VP" name="Active cycles, PLBU geometry processing" description="Number of cycles per frame the MaliGP2 PLBU was active, excepting final data output. In other words: active cycles through the prepare list commands. This includes time spent waiting on the bus."/>
24 <event event="0x19" title="Mali GPU Vertex Processor" name="Active cycles, PLBU geometry processing" description="Number of cycles per frame the MaliGP2 PLBU was active, excepting final data output. In other words: active cycles through the prepare list commands. This includes time spent waiting on the bus."/> 24 <event event="0x1b" title="Mali-4xx VP" name="Active cycles, PLBU primitive assembly" description="Number of active cycles per frame spent by the MaliGP2 PLBU doing primitive assembly. This does not include scissoring or final output. This includes time spent waiting on the bus."/>
25 <event event="0x1b" title="Mali GPU Vertex Processor" name="Active cycles, PLBU primitive assembly" description="Number of active cycles per frame spent by the MaliGP2 PLBU doing primitive assembly. This does not include scissoring or final output. This includes time spent waiting on the bus."/> 25 <event event="0x1c" title="Mali-4xx VP" name="Active cycles, PLBU vertex fetcher" description="Number of active cycles per frame spent by the MaliGP2 PLBU fetching vertex data. This includes time spent waiting on the bus."/>
26 <event event="0x1c" title="Mali GPU Vertex Processor" name="Active cycles, PLBU vertex fetcher" description="Number of active cycles per frame spent by the MaliGP2 PLBU fetching vertex data. This includes time spent waiting on the bus."/> 26 <event event="0x1e" title="Mali-4xx VP" name="Active cycles, Bounding-box and command generator" description="Number of active cycles per frame spent by the MaliGP2 PLBU setting up bounding boxes and commands (mainly graphics primitives). This includes time spent waiting on the bus."/>
27 <event event="0x1e" title="Mali GPU Vertex Processor" name="Active cycles, Bounding-box and command generator" description="Number of active cycles per frame spent by the MaliGP2 PLBU setting up bounding boxes and commands (mainly graphics primitives). This includes time spent waiting on the bus."/> 27 <event event="0x20" title="Mali-4xx VP" name="Active cycles, Scissor tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over tiles to perform scissoring. This includes time spent waiting on the bus."/>
28 <event event="0x20" title="Mali GPU Vertex Processor" name="Active cycles, Scissor tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over tiles to perform scissoring. This includes time spent waiting on the bus."/> 28 <event event="0x21" title="Mali-4xx VP" name="Active cycles, PLBU tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over the tiles in the bounding box generating commands (mainly graphics primitives). This includes time spent waiting on the bus."/>
29 <event event="0x21" title="Mali GPU Vertex Processor" name="Active cycles, PLBU tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over the tiles in the bounding box generating commands (mainly graphics primitives). This includes time spent waiting on the bus."/>
30 </category> 29 </category>
31 <category name="Mali GPU Fragment Processor" per_cpu="no"> 30 <category name="Mali Fragment Processor" per_cpu="no">
32 <counter_set name="ARM_Mali-4xx_FP_0_cnt" title="Mali-4xx FP0" description="Mali GPU Fragment Processor 0" count="2"/> 31 <counter_set name="ARM_Mali-4xx_FP_0_cnt" title="Mali-4xx FP0" description="Mali GPU Fragment Processor 0" count="2"/>
33 <counter_set name="ARM_Mali-4xx_FP_1_cnt" title="Mali-4xx FP1" description="Mali GPU Fragment Processor 1" count="2"/> 32 <counter_set name="ARM_Mali-4xx_FP_1_cnt" title="Mali-4xx FP1" description="Mali GPU Fragment Processor 1" count="2"/>
34 <counter_set name="ARM_Mali-4xx_FP_2_cnt" title="Mali-4xx FP2" description="Mali GPU Fragment Processor 2" count="2"/> 33 <counter_set name="ARM_Mali-4xx_FP_2_cnt" title="Mali-4xx FP2" description="Mali GPU Fragment Processor 2" count="2"/>
@@ -37,7 +36,6 @@
37 <counter_set name="ARM_Mali-4xx_FP_5_cnt" title="Mali-4xx FP5" description="Mali GPU Fragment Processor 5" count="2"/> 36 <counter_set name="ARM_Mali-4xx_FP_5_cnt" title="Mali-4xx FP5" description="Mali GPU Fragment Processor 5" count="2"/>
38 <counter_set name="ARM_Mali-4xx_FP_6_cnt" title="Mali-4xx FP6" description="Mali GPU Fragment Processor 6" count="2"/> 37 <counter_set name="ARM_Mali-4xx_FP_6_cnt" title="Mali-4xx FP6" description="Mali GPU Fragment Processor 6" count="2"/>
39 <counter_set name="ARM_Mali-4xx_FP_7_cnt" title="Mali-4xx FP7" description="Mali GPU Fragment Processor 7" count="2"/> 38 <counter_set name="ARM_Mali-4xx_FP_7_cnt" title="Mali-4xx FP7" description="Mali GPU Fragment Processor 7" count="2"/>
40
41 <event event="0x00" title="Mali-4xx FP" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> 39 <event event="0x00" title="Mali-4xx FP" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
42 <event event="0x02" title="Mali-4xx FP" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> 40 <event event="0x02" title="Mali-4xx FP" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
43 <event event="0x03" title="Mali-4xx FP" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> 41 <event event="0x03" title="Mali-4xx FP" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -96,11 +94,10 @@
96 <event event="0x3c" title="Mali-4xx FP" name="Program cache hit count" description="Number of hits in the program cache."/> 94 <event event="0x3c" title="Mali-4xx FP" name="Program cache hit count" description="Number of hits in the program cache."/>
97 <event event="0x3d" title="Mali-4xx FP" name="Program cache miss count" description="Number of misses in the program cache."/> 95 <event event="0x3d" title="Mali-4xx FP" name="Program cache miss count" description="Number of misses in the program cache."/>
98 </category> 96 </category>
99 <counter_set name="ARM_Mali-4xx_L2_0_cnt" title="Mali-4xx L2 0" description="Mali GPU L2 Cache Core 0" count="2"/> 97 <counter_set name="ARM_Mali-4xx_L2_0_cnt" title="Mali-4xx L2" description="Mali GPU L2 Cache Core 0" count="2"/>
100 <category name="Mali-4xx-L2_0" counter_set="ARM_Mali-4xx_L2_0_cnt" per_cpu="no"> 98 <category name="Mali-4xx L2" counter_set="ARM_Mali-4xx_L2_0_cnt" per_cpu="no">
101 <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles"/> 99 <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles"/>
102 <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles"/> 100 <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles"/>
103
104 <option_set name="All"> 101 <option_set name="All">
105 <option event_delta="0x08" name="Master" description="Master"/> 102 <option event_delta="0x08" name="Master" description="Master"/>
106 <option event_delta="0x10" name="All slaves" description="All slaves"/> 103 <option event_delta="0x10" name="All slaves" description="All slaves"/>
@@ -110,7 +107,6 @@
110 <option event_delta="0x50" name="Slave 3" description="Slave 3"/> 107 <option event_delta="0x50" name="Slave 3" description="Slave 3"/>
111 <option event_delta="0x60" name="Slave 4" description="Slave 4"/> 108 <option event_delta="0x60" name="Slave 4" description="Slave 4"/>
112 </option_set> 109 </option_set>
113
114 <option_set name="Slaves"> 110 <option_set name="Slaves">
115 <option event_delta="0x10" name="All slaves" description="All slaves"/> 111 <option event_delta="0x10" name="All slaves" description="All slaves"/>
116 <option event_delta="0x20" name="Slave 0" description="Slave 0"/> 112 <option event_delta="0x20" name="Slave 0" description="Slave 0"/>
@@ -119,7 +115,6 @@
119 <option event_delta="0x50" name="Slave 3" description="Slave 3"/> 115 <option event_delta="0x50" name="Slave 3" description="Slave 3"/>
120 <option event_delta="0x60" name="Slave 4" description="Slave 4"/> 116 <option event_delta="0x60" name="Slave 4" description="Slave 4"/>
121 </option_set> 117 </option_set>
122
123 <event event="0x00" option_set="All" title="Mali L2 Cache" name="Read transactions" description="Read transactions"/> 118 <event event="0x00" option_set="All" title="Mali L2 Cache" name="Read transactions" description="Read transactions"/>
124 <event event="0x01" option_set="All" title="Mali L2 Cache" name="Write transactions" description="Write transactions"/> 119 <event event="0x01" option_set="All" title="Mali L2 Cache" name="Write transactions" description="Write transactions"/>
125 <event event="0x02" option_set="All" title="Mali L2 Cache" name="Words read" description="Words read"/> 120 <event event="0x02" option_set="All" title="Mali L2 Cache" name="Words read" description="Words read"/>
@@ -131,10 +126,9 @@
131 <event event="0x08" option_set="Slaves" title="Mali L2 Cache" name="Cacheable read transactions" description="Cacheable read transactions"/> 126 <event event="0x08" option_set="Slaves" title="Mali L2 Cache" name="Cacheable read transactions" description="Cacheable read transactions"/>
132 </category> 127 </category>
133 <counter_set name="ARM_Mali-4xx_L2_1_cnt" title="Mali-4xx L2 1" description="Mali GPU L2 Cache Core 1" count="2"/> 128 <counter_set name="ARM_Mali-4xx_L2_1_cnt" title="Mali-4xx L2 1" description="Mali GPU L2 Cache Core 1" count="2"/>
134 <category name="Mali-4xx-L2_1" counter_set="ARM_Mali-4xx_L2_1_cnt" per_cpu="no"> 129 <category name="Mali-4xx L2_1" counter_set="ARM_Mali-4xx_L2_1_cnt" per_cpu="no">
135 <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles"/> 130 <event event="0x01" title="Mali L2 Cache 1" name="Total clock cycles" description="Total clock cycles"/>
136 <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles"/> 131 <event event="0x02" title="Mali L2 Cache 1" name="Active clock cycles" description="Active clock cycles"/>
137
138 <option_set name="All"> 132 <option_set name="All">
139 <option event_delta="0x08" name="Master" description="Master"/> 133 <option event_delta="0x08" name="Master" description="Master"/>
140 <option event_delta="0x10" name="All slaves" description="All slaves"/> 134 <option event_delta="0x10" name="All slaves" description="All slaves"/>
@@ -144,7 +138,6 @@
144 <option event_delta="0x50" name="Slave 3" description="Slave 3"/> 138 <option event_delta="0x50" name="Slave 3" description="Slave 3"/>
145 <option event_delta="0x60" name="Slave 4" description="Slave 4"/> 139 <option event_delta="0x60" name="Slave 4" description="Slave 4"/>
146 </option_set> 140 </option_set>
147
148 <option_set name="Slaves"> 141 <option_set name="Slaves">
149 <option event_delta="0x10" name="All slaves" description="All slaves"/> 142 <option event_delta="0x10" name="All slaves" description="All slaves"/>
150 <option event_delta="0x20" name="Slave 0" description="Slave 0"/> 143 <option event_delta="0x20" name="Slave 0" description="Slave 0"/>
@@ -153,22 +146,20 @@
153 <option event_delta="0x50" name="Slave 3" description="Slave 3"/> 146 <option event_delta="0x50" name="Slave 3" description="Slave 3"/>
154 <option event_delta="0x60" name="Slave 4" description="Slave 4"/> 147 <option event_delta="0x60" name="Slave 4" description="Slave 4"/>
155 </option_set> 148 </option_set>
156 149 <event event="0x00" option_set="All" title="Mali L2 Cache 1" name="Read transactions" description="Read transactions"/>
157 <event event="0x00" option_set="All" title="Mali L2 Cache" name="Read transactions" description="Read transactions"/> 150 <event event="0x01" option_set="All" title="Mali L2 Cache 1" name="Write transactions" description="Write transactions"/>
158 <event event="0x01" option_set="All" title="Mali L2 Cache" name="Write transactions" description="Write transactions"/> 151 <event event="0x02" option_set="All" title="Mali L2 Cache 1" name="Words read" description="Words read"/>
159 <event event="0x02" option_set="All" title="Mali L2 Cache" name="Words read" description="Words read"/> 152 <event event="0x03" option_set="All" title="Mali L2 Cache 1" name="Words written" description="Words written"/>
160 <event event="0x03" option_set="All" title="Mali L2 Cache" name="Words written" description="Words written"/> 153 <event event="0x04" option_set="Slaves" title="Mali L2 Cache 1" name="Read hits" description="Read hits"/>
161 <event event="0x04" option_set="Slaves" title="Mali L2 Cache" name="Read hits" description="Read hits"/> 154 <event event="0x05" option_set="Slaves" title="Mali L2 Cache 1" name="Read misses" description="Read misses"/>
162 <event event="0x05" option_set="Slaves" title="Mali L2 Cache" name="Read misses" description="Read misses"/> 155 <event event="0x06" option_set="Slaves" title="Mali L2 Cache 1" name="Write invalidates" description="Write invalidates"/>
163 <event event="0x06" option_set="Slaves" title="Mali L2 Cache" name="Write invalidates" description="Write invalidates"/> 156 <event event="0x07" option_set="Slaves" title="Mali L2 Cache 1" name="Read invalidates" description="Read invalidates"/>
164 <event event="0x07" option_set="Slaves" title="Mali L2 Cache" name="Read invalidates" description="Read invalidates"/> 157 <event event="0x08" option_set="Slaves" title="Mali L2 Cache 1" name="Cacheable read transactions" description="Cacheable read transactions"/>
165 <event event="0x08" option_set="Slaves" title="Mali L2 Cache" name="Cacheable read transactions" description="Cacheable read transactions"/>
166 </category> 158 </category>
167 <counter_set name="ARM_Mali-4xx_L2_2_cnt" title="Mali-4xx L2 2" description="Mali GPU L2 Cache Core 2" count="2"/> 159 <counter_set name="ARM_Mali-4xx_L2_2_cnt" title="Mali-4xx L2 2" description="Mali GPU L2 Cache Core 2" count="2"/>
168 <category name="Mali-4xx-L2_2" counter_set="ARM_Mali-4xx_L2_2_cnt" per_cpu="no"> 160 <category name="Mali-4xx L2_2" counter_set="ARM_Mali-4xx_L2_2_cnt" per_cpu="no">
169 <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles"/> 161 <event event="0x01" title="Mali L2 Cache 2" name="Total clock cycles" description="Total clock cycles"/>
170 <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles"/> 162 <event event="0x02" title="Mali L2 Cache 2" name="Active clock cycles" description="Active clock cycles"/>
171
172 <option_set name="All"> 163 <option_set name="All">
173 <option event_delta="0x08" name="Master" description="Master"/> 164 <option event_delta="0x08" name="Master" description="Master"/>
174 <option event_delta="0x10" name="All slaves" description="All slaves"/> 165 <option event_delta="0x10" name="All slaves" description="All slaves"/>
@@ -178,7 +169,6 @@
178 <option event_delta="0x50" name="Slave 3" description="Slave 3"/> 169 <option event_delta="0x50" name="Slave 3" description="Slave 3"/>
179 <option event_delta="0x60" name="Slave 4" description="Slave 4"/> 170 <option event_delta="0x60" name="Slave 4" description="Slave 4"/>
180 </option_set> 171 </option_set>
181
182 <option_set name="Slaves"> 172 <option_set name="Slaves">
183 <option event_delta="0x10" name="All slaves" description="All slaves"/> 173 <option event_delta="0x10" name="All slaves" description="All slaves"/>
184 <option event_delta="0x20" name="Slave 0" description="Slave 0"/> 174 <option event_delta="0x20" name="Slave 0" description="Slave 0"/>
@@ -187,18 +177,18 @@
187 <option event_delta="0x50" name="Slave 3" description="Slave 3"/> 177 <option event_delta="0x50" name="Slave 3" description="Slave 3"/>
188 <option event_delta="0x60" name="Slave 4" description="Slave 4"/> 178 <option event_delta="0x60" name="Slave 4" description="Slave 4"/>
189 </option_set> 179 </option_set>
190 180 <event event="0x00" option_set="All" title="Mali L2 Cache 2" name="Read transactions" description="Read transactions"/>
191 <event event="0x00" option_set="All" title="Mali L2 Cache" name="Read transactions" description="Read transactions"/> 181 <event event="0x01" option_set="All" title="Mali L2 Cache 2" name="Write transactions" description="Write transactions"/>
192 <event event="0x01" option_set="All" title="Mali L2 Cache" name="Write transactions" description="Write transactions"/> 182 <event event="0x02" option_set="All" title="Mali L2 Cache 2" name="Words read" description="Words read"/>
193 <event event="0x02" option_set="All" title="Mali L2 Cache" name="Words read" description="Words read"/> 183 <event event="0x03" option_set="All" title="Mali L2 Cache 2" name="Words written" description="Words written"/>
194 <event event="0x03" option_set="All" title="Mali L2 Cache" name="Words written" description="Words written"/> 184 <event event="0x04" option_set="Slaves" title="Mali L2 Cache 2" name="Read hits" description="Read hits"/>
195 <event event="0x04" option_set="Slaves" title="Mali L2 Cache" name="Read hits" description="Read hits"/> 185 <event event="0x05" option_set="Slaves" title="Mali L2 Cache 2" name="Read misses" description="Read misses"/>
196 <event event="0x05" option_set="Slaves" title="Mali L2 Cache" name="Read misses" description="Read misses"/> 186 <event event="0x06" option_set="Slaves" title="Mali L2 Cache 2" name="Write invalidates" description="Write invalidates"/>
197 <event event="0x06" option_set="Slaves" title="Mali L2 Cache" name="Write invalidates" description="Write invalidates"/> 187 <event event="0x07" option_set="Slaves" title="Mali L2 Cache 2" name="Read invalidates" description="Read invalidates"/>
198 <event event="0x07" option_set="Slaves" title="Mali L2 Cache" name="Read invalidates" description="Read invalidates"/> 188 <event event="0x08" option_set="Slaves" title="Mali L2 Cache 2" name="Cacheable read transactions" description="Cacheable read transactions"/>
199 <event event="0x08" option_set="Slaves" title="Mali L2 Cache" name="Cacheable read transactions" description="Cacheable read transactions"/>
200 </category> 189 </category>
201 <category name="ARM Mali-4xx Filmstrip" counter_set="ARM_Mali-4xx_Filmstrip_cnt" per_cpu="no"> 190 <counter_set name="ARM_Mali-4xx_Filmstrip_cnt" count="1"/>
191 <category name="Mali-4xx Filmstrip" counter_set="ARM_Mali-4xx_Filmstrip_cnt" per_cpu="no">
202 <option_set name="fs"> 192 <option_set name="fs">
203 <option event_delta="0x3c" name="1:60" description="captures every 60th frame"/> 193 <option event_delta="0x3c" name="1:60" description="captures every 60th frame"/>
204 <option event_delta="0x1e" name="1:30" description="captures every 30th frame"/> 194 <option event_delta="0x1e" name="1:30" description="captures every 30th frame"/>
@@ -212,7 +202,11 @@
212 <category name="ARM_Mali-4xx_Frequency" per_cpu="no"> 202 <category name="ARM_Mali-4xx_Frequency" per_cpu="no">
213 <event counter="ARM_Mali-4xx_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/> 203 <event counter="ARM_Mali-4xx_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/>
214 </category> 204 </category>
215 <category name="Mali-4xx-SW" counter_set="ARM_Mali-4xx_SW_cnt" per_cpu="no"> 205 <category name="Mali-4xx Activity" counter_set="ARM_Mali-4xx_Activity_cnt">
206 <event counter="ARM_Mali-4xx_fragment" title="GPU Fragment" name="Activity" class="activity" activity1="Activity" activity_color1="0x00006fcc" rendering_type="bar" average_selection="yes" average_cores="yes" percentage="yes" description="GPU Fragment Activity"/>
207 <event counter="ARM_Mali-4xx_vertex" title="GPU Vertex" name="Activity" class="activity" activity1="Activity" activity_color1="0x00eda000" rendering_type="bar" average_selection="yes" percentage="yes" description="GPU Vertex Activity"/>
208 </category>
209 <category name="Mali-4xx Software Counters" counter_set="ARM_Mali-4xx_SW_cnt" per_cpu="no">
216 <!-- EGL Counters --> 210 <!-- EGL Counters -->
217 <event counter="ARM_Mali-4xx_SW_0" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the framebuffer from video memory to framebuffer."/> 211 <event counter="ARM_Mali-4xx_SW_0" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the framebuffer from video memory to framebuffer."/>
218 <!-- glDrawElements Counters --> 212 <!-- glDrawElements Counters -->
diff --git a/daemon/events-Mali-T6xx.xml b/daemon/events-Mali-T6xx.xml
index ec9ca00..5e89797 100644
--- a/daemon/events-Mali-T6xx.xml
+++ b/daemon/events-Mali-T6xx.xml
@@ -1,9 +1,7 @@
1 1 <category name="Mali-T6xx Software Counters" per_cpu="no">
2 <category name="Mali-T6xx-SW-counters" per_cpu="no">
3 <event counter="ARM_Mali-T6xx_TOTAL_ALLOC_PAGES" title="Mali Total Alloc Pages" name="Total number of allocated pages" description="Mali total number of allocated pages."/> 2 <event counter="ARM_Mali-T6xx_TOTAL_ALLOC_PAGES" title="Mali Total Alloc Pages" name="Total number of allocated pages" description="Mali total number of allocated pages."/>
4 </category> 3 </category>
5 4 <category name="Mali-T6xx PM Shader" per_cpu="no">
6 <category name="Mali-T6xx-PMShader" per_cpu="no">
7 <event counter="ARM_Mali-T6xx_PM_SHADER_0" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 0" description="Mali PM Shader: PM Shader Core 0."/> 5 <event counter="ARM_Mali-T6xx_PM_SHADER_0" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 0" description="Mali PM Shader: PM Shader Core 0."/>
8 <event counter="ARM_Mali-T6xx_PM_SHADER_1" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 1" description="Mali PM Shader: PM Shader Core 1."/> 6 <event counter="ARM_Mali-T6xx_PM_SHADER_1" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 1" description="Mali PM Shader: PM Shader Core 1."/>
9 <event counter="ARM_Mali-T6xx_PM_SHADER_2" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 2" description="Mali PM Shader: PM Shader Core 2."/> 7 <event counter="ARM_Mali-T6xx_PM_SHADER_2" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 2" description="Mali PM Shader: PM Shader Core 2."/>
@@ -13,32 +11,27 @@
13 <event counter="ARM_Mali-T6xx_PM_SHADER_6" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 6" description="Mali PM Shader: PM Shader Core 6."/> 11 <event counter="ARM_Mali-T6xx_PM_SHADER_6" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 6" description="Mali PM Shader: PM Shader Core 6."/>
14 <event counter="ARM_Mali-T6xx_PM_SHADER_7" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 7" description="Mali PM Shader: PM Shader Core 7."/> 12 <event counter="ARM_Mali-T6xx_PM_SHADER_7" class="absolute" display="average" average_selection="yes" percentage="yes" title="Mali PM Shader" name="PM Shader Core 7" description="Mali PM Shader: PM Shader Core 7."/>
15 </category> 13 </category>
16 14 <category name="Mali-T6xx PM Tiler" per_cpu="no">
17 <category name="Mali-T6xx-PMTiler" per_cpu="no">
18 <event counter="ARM_Mali-T6xx_PM_TILER_0" display="average" average_selection="yes" percentage="yes" title="Mali PM Tiler" name="PM Tiler Core 0" description="Mali PM Tiler: PM Tiler Core 0."/> 15 <event counter="ARM_Mali-T6xx_PM_TILER_0" display="average" average_selection="yes" percentage="yes" title="Mali PM Tiler" name="PM Tiler Core 0" description="Mali PM Tiler: PM Tiler Core 0."/>
19 </category> 16 </category>
20 17 <category name="Mali-T6xx PM L2" per_cpu="no">
21 <category name="Mali-T6xx-PML2" per_cpu="no">
22 <event counter="ARM_Mali-T6xx_PM_L2_0" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 0" description="Mali PM L2: PM L2 Core 0."/> 18 <event counter="ARM_Mali-T6xx_PM_L2_0" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 0" description="Mali PM L2: PM L2 Core 0."/>
23 <event counter="ARM_Mali-T6xx_PM_L2_1" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 1" description="Mali PM L2: PM L2 Core 1."/> 19 <event counter="ARM_Mali-T6xx_PM_L2_1" display="average" average_selection="yes" percentage="yes" title="Mali PM L2" name="PM L2 Core 1" description="Mali PM L2: PM L2 Core 1."/>
24 </category> 20 </category>
25 21 <category name="Mali-T6xx MMU Address Space" per_cpu="no">
26 <category name="Mali-T6xx-MMU_AS" per_cpu="no">
27 <event counter="ARM_Mali-T6xx_MMU_AS_0" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/> 22 <event counter="ARM_Mali-T6xx_MMU_AS_0" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/>
28 <event counter="ARM_Mali-T6xx_MMU_AS_1" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/> 23 <event counter="ARM_Mali-T6xx_MMU_AS_1" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/>
29 <event counter="ARM_Mali-T6xx_MMU_AS_2" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/> 24 <event counter="ARM_Mali-T6xx_MMU_AS_2" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/>
30 <event counter="ARM_Mali-T6xx_MMU_AS_3" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/> 25 <event counter="ARM_Mali-T6xx_MMU_AS_3" display="average" average_selection="yes" percentage="yes" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/>
31 </category> 26 </category>
32 27 <category name="Mali-T6xx MMU Page Fault" per_cpu="no">
33 <category name="Mali-T6xx-MMU_page_fault" per_cpu="no">
34 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_0" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 0" description="Reports the number of newly allocated pages after a MMU page fault in address space 0."/> 28 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_0" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 0" description="Reports the number of newly allocated pages after a MMU page fault in address space 0."/>
35 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_1" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 1" description="Reports the number of newly allocated pages after a MMU page fault in address space 1."/> 29 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_1" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 1" description="Reports the number of newly allocated pages after a MMU page fault in address space 1."/>
36 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_2" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 2" description="Reports the number of newly allocated pages after a MMU page fault in address space 2."/> 30 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_2" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 2" description="Reports the number of newly allocated pages after a MMU page fault in address space 2."/>
37 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_3" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 3" description="Reports the number of newly allocated pages after a MMU page fault in address space 3."/> 31 <event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_3" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 3" description="Reports the number of newly allocated pages after a MMU page fault in address space 3."/>
38 </category> 32 </category>
39
40 <counter_set name="ARM_Mali-T6xx_Filmstrip_cnt" count="1"/> 33 <counter_set name="ARM_Mali-T6xx_Filmstrip_cnt" count="1"/>
41 <category name="ARM Mali-T6xx Filmstrip" counter_set="ARM_Mali-T6xx_Filmstrip_cnt" per_cpu="no"> 34 <category name="Mali-T6xx Filmstrip" counter_set="ARM_Mali-T6xx_Filmstrip_cnt" per_cpu="no">
42 <option_set name="fs"> 35 <option_set name="fs">
43 <option event_delta="0x3c" name="1:60" description="captures every 60th frame"/> 36 <option event_delta="0x3c" name="1:60" description="captures every 60th frame"/>
44 <option event_delta="0x1e" name="1:30" description="captures every 30th frame"/> 37 <option event_delta="0x1e" name="1:30" description="captures every 30th frame"/>
@@ -46,3 +39,8 @@
46 </option_set> 39 </option_set>
47 <event event="0x0400" option_set="fs" title="ARM Mali-T6xx" name="Filmstrip" description="Scaled framebuffer"/> 40 <event event="0x0400" option_set="fs" title="ARM Mali-T6xx" name="Filmstrip" description="Scaled framebuffer"/>
48 </category> 41 </category>
42 <category name="Mali-T6xx Activity" per_cpu="no">
43 <event counter="ARM_Mali-T6xx_fragment" title="GPU Fragment" name="Activity" class="activity" activity1="Activity" activity_color1="0x00006fcc" rendering_type="bar" average_selection="yes" percentage="yes" cores="1" description="GPU Job Slot 0 Activity"/>
44 <event counter="ARM_Mali-T6xx_vertex" title="GPU Vertex-Tiling-Compute" name="Activity" class="activity" activity1="Activity" activity_color1="0x00eda000" rendering_type="bar" average_selection="yes" percentage="yes" cores="1" description="GPU Job Slot 1 Activity"/>
45 <event counter="ARM_Mali-T6xx_opencl" title="GPU Vertex-Compute" name="Activity" class="activity" activity1="Activity" activity_color1="0x00ef022f" rendering_type="bar" average_selection="yes" percentage="yes" cores="1" description="GPU Job Slot 2 Activity"/>
46 </category>
diff --git a/daemon/events-Mali-T6xx_hw.xml b/daemon/events-Mali-T6xx_hw.xml
index 03566cb..df27962 100644
--- a/daemon/events-Mali-T6xx_hw.xml
+++ b/daemon/events-Mali-T6xx_hw.xml
@@ -1,35 +1,27 @@
1 1 <category name="Mali-T6xx Job Manager" per_cpu="no">
2 <category name="Mali-T6xx-JobManager" per_cpu="no">
3
4 <event counter="ARM_Mali-T6xx_GPU_ACTIVE" title="Mali Job Manager Cycles" name="GPU cycles" description="Number of cycles the GPU was active"/> 2 <event counter="ARM_Mali-T6xx_GPU_ACTIVE" title="Mali Job Manager Cycles" name="GPU cycles" description="Number of cycles the GPU was active"/>
5 <event counter="ARM_Mali-T6xx_IRQ_ACTIVE" title="Mali Job Manager Cycles" name="IRQ cycles" description="Number of cycles the GPU had a pending interrupt"/> 3 <event counter="ARM_Mali-T6xx_IRQ_ACTIVE" title="Mali Job Manager Cycles" name="IRQ cycles" description="Number of cycles the GPU had a pending interrupt"/>
6 <event counter="ARM_Mali-T6xx_JS0_ACTIVE" title="Mali Job Manager Cycles" name="JS0 cycles" description="Number of cycles JS0 (fragment) was active"/> 4 <event counter="ARM_Mali-T6xx_JS0_ACTIVE" title="Mali Job Manager Cycles" name="JS0 cycles" description="Number of cycles JS0 (fragment) was active"/>
7 <event counter="ARM_Mali-T6xx_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) was active"/> 5 <event counter="ARM_Mali-T6xx_JS1_ACTIVE" title="Mali Job Manager Cycles" name="JS1 cycles" description="Number of cycles JS1 (vertex/tiler/compute) was active"/>
8 <event counter="ARM_Mali-T6xx_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) was active"/> 6 <event counter="ARM_Mali-T6xx_JS2_ACTIVE" title="Mali Job Manager Cycles" name="JS2 cycles" description="Number of cycles JS2 (vertex/compute) was active"/>
9
10 <event counter="ARM_Mali-T6xx_JS0_JOBS" title="Mali Job Manager Work" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/> 7 <event counter="ARM_Mali-T6xx_JS0_JOBS" title="Mali Job Manager Work" name="JS0 jobs" description="Number of Jobs (fragment) completed in JS0"/>
11 <event counter="ARM_Mali-T6xx_JS0_TASKS" title="Mali Job Manager Work" name="JS0 tasks" description="Number of Tasks completed in JS0"/> 8 <event counter="ARM_Mali-T6xx_JS0_TASKS" title="Mali Job Manager Work" name="JS0 tasks" description="Number of Tasks completed in JS0"/>
12 <event counter="ARM_Mali-T6xx_JS1_JOBS" title="Mali Job Manager Work" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/> 9 <event counter="ARM_Mali-T6xx_JS1_JOBS" title="Mali Job Manager Work" name="JS1 jobs" description="Number of Jobs (vertex/tiler/compute) completed in JS1"/>
13 <event counter="ARM_Mali-T6xx_JS1_TASKS" title="Mali Job Manager Work" name="JS1 tasks" description="Number of Tasks completed in JS1"/> 10 <event counter="ARM_Mali-T6xx_JS1_TASKS" title="Mali Job Manager Work" name="JS1 tasks" description="Number of Tasks completed in JS1"/>
14 <event counter="ARM_Mali-T6xx_JS2_TASKS" title="Mali Job Manager Work" name="JS2 tasks" description="Number of Tasks completed in JS2"/> 11 <event counter="ARM_Mali-T6xx_JS2_TASKS" title="Mali Job Manager Work" name="JS2 tasks" description="Number of Tasks completed in JS2"/>
15 <event counter="ARM_Mali-T6xx_JS2_JOBS" title="Mali Job Manager Work" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/> 12 <event counter="ARM_Mali-T6xx_JS2_JOBS" title="Mali Job Manager Work" name="JS2 jobs" description="Number of Jobs (vertex/compute) completed in JS2"/>
16
17 </category> 13 </category>
18 14 <category name="Mali-T6xx Tiler" per_cpu="no">
19 <category name="Mali-T6xx-Tiler" per_cpu="no">
20
21 <event counter="ARM_Mali-T6xx_POLYGONS" title="Mali Tiler Primitives" name="Polygons" description="Number of polygons processed"/> 15 <event counter="ARM_Mali-T6xx_POLYGONS" title="Mali Tiler Primitives" name="Polygons" description="Number of polygons processed"/>
22 <event counter="ARM_Mali-T6xx_QUADS" title="Mali Tiler Primitives" name="Quads" description="Number of quads processed"/> 16 <event counter="ARM_Mali-T6xx_QUADS" title="Mali Tiler Primitives" name="Quads" description="Number of quads processed"/>
23 <event counter="ARM_Mali-T6xx_TRIANGLES" title="Mali Tiler Primitives" name="Triangles" description="Number of triangles processed"/> 17 <event counter="ARM_Mali-T6xx_TRIANGLES" title="Mali Tiler Primitives" name="Triangles" description="Number of triangles processed"/>
24 <event counter="ARM_Mali-T6xx_LINES" title="Mali Tiler Primitives" name="Lines" description="Number of lines processed"/> 18 <event counter="ARM_Mali-T6xx_LINES" title="Mali Tiler Primitives" name="Lines" description="Number of lines processed"/>
25 <event counter="ARM_Mali-T6xx_POINTS" title="Mali Tiler Primitives" name="Points" description="Number of points processed"/> 19 <event counter="ARM_Mali-T6xx_POINTS" title="Mali Tiler Primitives" name="Points" description="Number of points processed"/>
26
27 <event counter="ARM_Mali-T6xx_FRONT_FACING" title="Mali Tiler Culling" name="Front facing prims" description="Number of front facing primitives"/> 20 <event counter="ARM_Mali-T6xx_FRONT_FACING" title="Mali Tiler Culling" name="Front facing prims" description="Number of front facing primitives"/>
28 <event counter="ARM_Mali-T6xx_BACK_FACING" title="Mali Tiler Culling" name="Back facing prims" description="Number of back facing primitives"/> 21 <event counter="ARM_Mali-T6xx_BACK_FACING" title="Mali Tiler Culling" name="Back facing prims" description="Number of back facing primitives"/>
29 <event counter="ARM_Mali-T6xx_PRIM_VISIBLE" title="Mali Tiler Culling" name="Visible prims" description="Number of visible primitives"/> 22 <event counter="ARM_Mali-T6xx_PRIM_VISIBLE" title="Mali Tiler Culling" name="Visible prims" description="Number of visible primitives"/>
30 <event counter="ARM_Mali-T6xx_PRIM_CULLED" title="Mali Tiler Culling" name="Culled prims" description="Number of culled primitives"/> 23 <event counter="ARM_Mali-T6xx_PRIM_CULLED" title="Mali Tiler Culling" name="Culled prims" description="Number of culled primitives"/>
31 <event counter="ARM_Mali-T6xx_PRIM_CLIPPED" title="Mali Tiler Culling" name="Clipped prims" description="Number of clipped primitives"/> 24 <event counter="ARM_Mali-T6xx_PRIM_CLIPPED" title="Mali Tiler Culling" name="Clipped prims" description="Number of clipped primitives"/>
32
33 <event counter="ARM_Mali-T6xx_LEVEL0" title="Mali Tiler Hierarchy" name="L0 prims" description="Number of primitives in hierarchy level 0"/> 25 <event counter="ARM_Mali-T6xx_LEVEL0" title="Mali Tiler Hierarchy" name="L0 prims" description="Number of primitives in hierarchy level 0"/>
34 <event counter="ARM_Mali-T6xx_LEVEL1" title="Mali Tiler Hierarchy" name="L1 prims" description="Number of primitives in hierarchy level 1"/> 26 <event counter="ARM_Mali-T6xx_LEVEL1" title="Mali Tiler Hierarchy" name="L1 prims" description="Number of primitives in hierarchy level 1"/>
35 <event counter="ARM_Mali-T6xx_LEVEL2" title="Mali Tiler Hierarchy" name="L2 prims" description="Number of primitives in hierarchy level 2"/> 27 <event counter="ARM_Mali-T6xx_LEVEL2" title="Mali Tiler Hierarchy" name="L2 prims" description="Number of primitives in hierarchy level 2"/>
@@ -38,7 +30,6 @@
38 <event counter="ARM_Mali-T6xx_LEVEL5" title="Mali Tiler Hierarchy" name="L5 prims" description="Number of primitives in hierarchy level 5"/> 30 <event counter="ARM_Mali-T6xx_LEVEL5" title="Mali Tiler Hierarchy" name="L5 prims" description="Number of primitives in hierarchy level 5"/>
39 <event counter="ARM_Mali-T6xx_LEVEL6" title="Mali Tiler Hierarchy" name="L6 prims" description="Number of primitives in hierarchy level 6"/> 31 <event counter="ARM_Mali-T6xx_LEVEL6" title="Mali Tiler Hierarchy" name="L6 prims" description="Number of primitives in hierarchy level 6"/>
40 <event counter="ARM_Mali-T6xx_LEVEL7" title="Mali Tiler Hierarchy" name="L7 prims" description="Number of primitives in hierarchy level 7"/> 32 <event counter="ARM_Mali-T6xx_LEVEL7" title="Mali Tiler Hierarchy" name="L7 prims" description="Number of primitives in hierarchy level 7"/>
41
42 <event counter="ARM_Mali-T6xx_COMMAND_1" title="Mali Tiler Commands" name="Prims in 1 command" description="Number of primitives producing 1 command"/> 33 <event counter="ARM_Mali-T6xx_COMMAND_1" title="Mali Tiler Commands" name="Prims in 1 command" description="Number of primitives producing 1 command"/>
43 <event counter="ARM_Mali-T6xx_COMMAND_2" title="Mali Tiler Commands" name="Prims in 2 command" description="Number of primitives producing 2 commands"/> 34 <event counter="ARM_Mali-T6xx_COMMAND_2" title="Mali Tiler Commands" name="Prims in 2 command" description="Number of primitives producing 2 commands"/>
44 <event counter="ARM_Mali-T6xx_COMMAND_3" title="Mali Tiler Commands" name="Prims in 3 command" description="Number of primitives producing 3 commands"/> 35 <event counter="ARM_Mali-T6xx_COMMAND_3" title="Mali Tiler Commands" name="Prims in 3 command" description="Number of primitives producing 3 commands"/>
@@ -48,48 +39,36 @@
48 <event counter="ARM_Mali-T6xx_COMMAND_8_15" title="Mali Tiler Commands" name="Prims in 8-15 commands" description="Number of primitives producing 8-15 commands"/> 39 <event counter="ARM_Mali-T6xx_COMMAND_8_15" title="Mali Tiler Commands" name="Prims in 8-15 commands" description="Number of primitives producing 8-15 commands"/>
49 <event counter="ARM_Mali-T6xx_COMMAND_16_63" title="Mali Tiler Commands" name="Prims in 16-63 commands" description="Number of primitives producing 16-63 commands"/> 40 <event counter="ARM_Mali-T6xx_COMMAND_16_63" title="Mali Tiler Commands" name="Prims in 16-63 commands" description="Number of primitives producing 16-63 commands"/>
50 <event counter="ARM_Mali-T6xx_COMMAND_64" title="Mali Tiler Commands" name="Prims in &gt;= 64 commands" description="Number of primitives producing &gt;= 64 commands"/> 41 <event counter="ARM_Mali-T6xx_COMMAND_64" title="Mali Tiler Commands" name="Prims in &gt;= 64 commands" description="Number of primitives producing &gt;= 64 commands"/>
51
52 </category> 42 </category>
53 43 <category name="Mali-T6xx Shader Core" per_cpu="no">
54 <category name="Mali-T6xx-ShaderCore" per_cpu="no">
55
56 <event counter="ARM_Mali-T6xx_TRIPIPE_ACTIVE" title="Mali Core Cycles" name="Tripipe cycles" description="Number of cycles the Tripipe was active"/> 44 <event counter="ARM_Mali-T6xx_TRIPIPE_ACTIVE" title="Mali Core Cycles" name="Tripipe cycles" description="Number of cycles the Tripipe was active"/>
57 <event counter="ARM_Mali-T6xx_FRAG_ACTIVE" title="Mali Core Cycles" name="Fragment cycles" description="Number of cycles fragment processing was active"/> 45 <event counter="ARM_Mali-T6xx_FRAG_ACTIVE" title="Mali Core Cycles" name="Fragment cycles" description="Number of cycles fragment processing was active"/>
58 <event counter="ARM_Mali-T6xx_COMPUTE_ACTIVE" title="Mali Core Cycles" name="Compute cycles" description="Number of cycles vertex\compute processing was active"/> 46 <event counter="ARM_Mali-T6xx_COMPUTE_ACTIVE" title="Mali Core Cycles" name="Compute cycles" description="Number of cycles vertex\compute processing was active"/>
59 <event counter="ARM_Mali-T6xx_FRAG_CYCLE_NO_TILE" title="Mali Core Cycles" name="Fragment cycles waiting for tile" description="Number of cycles spent waiting for a physical tile buffer"/> 47 <event counter="ARM_Mali-T6xx_FRAG_CYCLE_NO_TILE" title="Mali Core Cycles" name="Fragment cycles waiting for tile" description="Number of cycles spent waiting for a physical tile buffer"/>
60
61 <event counter="ARM_Mali-T6xx_FRAG_THREADS" title="Mali Core Threads" name="Fragment threads" description="Number of fragment threads started"/> 48 <event counter="ARM_Mali-T6xx_FRAG_THREADS" title="Mali Core Threads" name="Fragment threads" description="Number of fragment threads started"/>
62 <event counter="ARM_Mali-T6xx_FRAG_DUMMY_THREADS" title="Mali Core Threads" name="Dummy fragment threads" description="Number of dummy fragment threads started"/> 49 <event counter="ARM_Mali-T6xx_FRAG_DUMMY_THREADS" title="Mali Core Threads" name="Dummy fragment threads" description="Number of dummy fragment threads started"/>
63 <event counter="ARM_Mali-T6xx_FRAG_QUADS_LZS_TEST" title="Mali Core Threads" name="Frag threads doing late ZS" description="Number of threads doing late ZS test"/> 50 <event counter="ARM_Mali-T6xx_FRAG_QUADS_LZS_TEST" title="Mali Core Threads" name="Frag threads doing late ZS" description="Number of threads doing late ZS test"/>
64 <event counter="ARM_Mali-T6xx_FRAG_QUADS_LZS_KILLED" title="Mali Core Threads" name="Frag threads killed late ZS" description="Number of threads killed by late ZS test"/> 51 <event counter="ARM_Mali-T6xx_FRAG_QUADS_LZS_KILLED" title="Mali Core Threads" name="Frag threads killed late ZS" description="Number of threads killed by late ZS test"/>
65 <event counter="ARM_Mali-T6xx_FRAG_THREADS_LZS_TEST" title="Mali Core Threads" name="Frag threads doing late ZS" description="Number of threads doing late ZS test"/> 52 <event counter="ARM_Mali-T6xx_FRAG_THREADS_LZS_TEST" title="Mali Core Threads" name="Frag threads doing late ZS" description="Number of threads doing late ZS test"/>
66 <event counter="ARM_Mali-T6xx_FRAG_THREADS_LZS_KILLED" title="Mali Core Threads" name="Frag threads killed late ZS" description="Number of threads killed by late ZS test"/> 53 <event counter="ARM_Mali-T6xx_FRAG_THREADS_LZS_KILLED" title="Mali Core Threads" name="Frag threads killed late ZS" description="Number of threads killed by late ZS test"/>
67
68 <event counter="ARM_Mali-T6xx_COMPUTE_TASKS" title="Mali Compute Threads" name="Compute tasks" description="Number of compute tasks"/> 54 <event counter="ARM_Mali-T6xx_COMPUTE_TASKS" title="Mali Compute Threads" name="Compute tasks" description="Number of compute tasks"/>
69 <event counter="ARM_Mali-T6xx_COMPUTE_THREADS" title="Mali Compute Threads" name="Compute threads started" description="Number of compute threads started"/> 55 <event counter="ARM_Mali-T6xx_COMPUTE_THREADS" title="Mali Compute Threads" name="Compute threads started" description="Number of compute threads started"/>
70 <event counter="ARM_Mali-T6xx_COMPUTE_CYCLES_DESC" title="Mali Compute Threads" name="Compute cycles awaiting descriptors" description="Number of compute cycles spent waiting for descriptors"/> 56 <event counter="ARM_Mali-T6xx_COMPUTE_CYCLES_DESC" title="Mali Compute Threads" name="Compute cycles awaiting descriptors" description="Number of compute cycles spent waiting for descriptors"/>
71
72 <event counter="ARM_Mali-T6xx_FRAG_PRIMATIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/> 57 <event counter="ARM_Mali-T6xx_FRAG_PRIMATIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
73 <event counter="ARM_Mali-T6xx_FRAG_PRIMATIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/> 58 <event counter="ARM_Mali-T6xx_FRAG_PRIMATIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
74 <event counter="ARM_Mali-T6xx_FRAG_PRIMITIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/> 59 <event counter="ARM_Mali-T6xx_FRAG_PRIMITIVES" title="Mali Fragment Primitives" name="Primitives loaded" description="Number of primitives loaded from tiler"/>
75 <event counter="ARM_Mali-T6xx_FRAG_PRIMITIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/> 60 <event counter="ARM_Mali-T6xx_FRAG_PRIMITIVES_DROPPED" title="Mali Fragment Primitives" name="Primitives dropped" description="Number of primitives dropped because out of tile"/>
76
77 <event counter="ARM_Mali-T6xx_FRAG_QUADS_RAST" title="Mali Fragment Quads" name="Quads rasterized" description="Number of quads rasterized"/> 61 <event counter="ARM_Mali-T6xx_FRAG_QUADS_RAST" title="Mali Fragment Quads" name="Quads rasterized" description="Number of quads rasterized"/>
78 <event counter="ARM_Mali-T6xx_FRAG_QUADS_EZS_TEST" title="Mali Fragment Quads" name="Quads doing early ZS" description="Number of quads doing early ZS test"/> 62 <event counter="ARM_Mali-T6xx_FRAG_QUADS_EZS_TEST" title="Mali Fragment Quads" name="Quads doing early ZS" description="Number of quads doing early ZS test"/>
79 <event counter="ARM_Mali-T6xx_FRAG_QUADS_EZS_KILLED" title="Mali Fragment Quads" name="Quads killed early Z" description="Number of quads killed by early ZS test"/> 63 <event counter="ARM_Mali-T6xx_FRAG_QUADS_EZS_KILLED" title="Mali Fragment Quads" name="Quads killed early Z" description="Number of quads killed by early ZS test"/>
80
81 <event counter="ARM_Mali-T6xx_FRAG_NUM_TILES" title="Mali Fragment Tasks" name="Tiles rendered" description="Number of tiles rendered"/> 64 <event counter="ARM_Mali-T6xx_FRAG_NUM_TILES" title="Mali Fragment Tasks" name="Tiles rendered" description="Number of tiles rendered"/>
82 <event counter="ARM_Mali-T6xx_FRAG_TRANS_ELIM" title="Mali Fragment Tasks" name="Tile writes killed by TE" description="Number of tile writes skipped by transaction elimination"/> 65 <event counter="ARM_Mali-T6xx_FRAG_TRANS_ELIM" title="Mali Fragment Tasks" name="Tile writes killed by TE" description="Number of tile writes skipped by transaction elimination"/>
83
84 <event counter="ARM_Mali-T6xx_ARITH_WORDS" title="Mali Arithmetic Pipe" name="A instructions" description="Number of instructions completed by the the A-pipe (normalized per pipeline)"/> 66 <event counter="ARM_Mali-T6xx_ARITH_WORDS" title="Mali Arithmetic Pipe" name="A instructions" description="Number of instructions completed by the the A-pipe (normalized per pipeline)"/>
85
86 <event counter="ARM_Mali-T6xx_LS_WORDS" title="Mali Load/Store Pipe" name="LS instructions" description="Number of instructions completed by the LS-pipe"/> 67 <event counter="ARM_Mali-T6xx_LS_WORDS" title="Mali Load/Store Pipe" name="LS instructions" description="Number of instructions completed by the LS-pipe"/>
87 <event counter="ARM_Mali-T6xx_LS_ISSUES" title="Mali Load/Store Pipe" name="LS instruction issues" description="Number of instructions issued to the LS-pipe, including restarts"/> 68 <event counter="ARM_Mali-T6xx_LS_ISSUES" title="Mali Load/Store Pipe" name="LS instruction issues" description="Number of instructions issued to the LS-pipe, including restarts"/>
88
89 <event counter="ARM_Mali-T6xx_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/> 69 <event counter="ARM_Mali-T6xx_TEX_WORDS" title="Mali Texture Pipe" name="T instructions" description="Number of instructions completed by the T-pipe"/>
90 <event counter="ARM_Mali-T6xx_TEX_THREADS" title="Mali Texture Pipe" name="T instruction issues" description="Number of instructions issused to the T-pipe, including restarts"/> 70 <event counter="ARM_Mali-T6xx_TEX_THREADS" title="Mali Texture Pipe" name="T instruction issues" description="Number of instructions issused to the T-pipe, including restarts"/>
91 <event counter="ARM_Mali-T6xx_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/> 71 <event counter="ARM_Mali-T6xx_TEX_RECIRC_FMISS" title="Mali Texture Pipe" name="Cache misses" description="Number of instructions in the T-pipe, recirculated due to cache miss"/>
92
93 <event counter="ARM_Mali-T6xx_LSC_READ_HITS" title="Mali Load/Store Cache" name="Read hits" description="Number of read hits in the Load/Store cache"/> 72 <event counter="ARM_Mali-T6xx_LSC_READ_HITS" title="Mali Load/Store Cache" name="Read hits" description="Number of read hits in the Load/Store cache"/>
94 <event counter="ARM_Mali-T6xx_LSC_READ_MISSES" title="Mali Load/Store Cache" name="Read misses" description="Number of read misses in the Load/Store cache"/> 73 <event counter="ARM_Mali-T6xx_LSC_READ_MISSES" title="Mali Load/Store Cache" name="Read misses" description="Number of read misses in the Load/Store cache"/>
95 <event counter="ARM_Mali-T6xx_LSC_WRITE_HITS" title="Mali Load/Store Cache" name="Write hits" description="Number of write hits in the Load/Store cache"/> 74 <event counter="ARM_Mali-T6xx_LSC_WRITE_HITS" title="Mali Load/Store Cache" name="Write hits" description="Number of write hits in the Load/Store cache"/>
@@ -99,11 +78,8 @@
99 <event counter="ARM_Mali-T6xx_LSC_LINE_FETCHES" title="Mali Load/Store Cache" name="Line fetches" description="Number of line fetches in the Load/Store cache"/> 78 <event counter="ARM_Mali-T6xx_LSC_LINE_FETCHES" title="Mali Load/Store Cache" name="Line fetches" description="Number of line fetches in the Load/Store cache"/>
100 <event counter="ARM_Mali-T6xx_LSC_DIRTY_LINE" title="Mali Load/Store Cache" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/> 79 <event counter="ARM_Mali-T6xx_LSC_DIRTY_LINE" title="Mali Load/Store Cache" name="Dirty line evictions" description="Number of dirty line evictions in the Load/Store cache"/>
101 <event counter="ARM_Mali-T6xx_LSC_SNOOPS" title="Mali Load/Store Cache" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/> 80 <event counter="ARM_Mali-T6xx_LSC_SNOOPS" title="Mali Load/Store Cache" name="Snoops in to LSC" description="Number of coherent memory snoops in to the Load/Store cache"/>
102
103 </category> 81 </category>
104 82 <category name="Mali-T6xx L2 and MMU" per_cpu="no">
105 <category name="Mali-T6xx-L2AndMMU" per_cpu="no">
106
107 <event counter="ARM_Mali-T6xx_L2_WRITE_BEATS" title="Mali L2 Cache" name="External write beats" description="Number of external bus write beats"/> 83 <event counter="ARM_Mali-T6xx_L2_WRITE_BEATS" title="Mali L2 Cache" name="External write beats" description="Number of external bus write beats"/>
108 <event counter="ARM_Mali-T6xx_L2_READ_BEATS" title="Mali L2 Cache" name="External read beats" description="Number of external bus read beats"/> 84 <event counter="ARM_Mali-T6xx_L2_READ_BEATS" title="Mali L2 Cache" name="External read beats" description="Number of external bus read beats"/>
109 <event counter="ARM_Mali-T6xx_L2_READ_SNOOP" title="Mali L2 Cache" name="Read snoops" description="Number of read transaction snoops"/> 85 <event counter="ARM_Mali-T6xx_L2_READ_SNOOP" title="Mali L2 Cache" name="Read snoops" description="Number of read transaction snoops"/>
@@ -112,5 +88,4 @@
112 <event counter="ARM_Mali-T6xx_L2_WRITE_HIT" title="Mali L2 Cache" name="L2 write hits" description="Number of writes hitting in the L2 cache"/> 88 <event counter="ARM_Mali-T6xx_L2_WRITE_HIT" title="Mali L2 Cache" name="L2 write hits" description="Number of writes hitting in the L2 cache"/>
113 <event counter="ARM_Mali-T6xx_L2_EXT_AR_STALL" title="Mali L2 Cache" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/> 89 <event counter="ARM_Mali-T6xx_L2_EXT_AR_STALL" title="Mali L2 Cache" name="External bus stalls (AR)" description="Number of cycles a valid read address (AR) is stalled by the external interconnect"/>
114 <event counter="ARM_Mali-T6xx_L2_EXT_W_STALL" title="Mali L2 Cache" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/> 90 <event counter="ARM_Mali-T6xx_L2_EXT_W_STALL" title="Mali L2 Cache" name="External bus stalls (W)" description="Number of cycles a valid write data (W channel) is stalled by the external interconnect"/>
115
116 </category> 91 </category>
diff --git a/daemon/events-Mali-V500.xml b/daemon/events-Mali-V500.xml
new file mode 100644
index 0000000..d2751e7
--- /dev/null
+++ b/daemon/events-Mali-V500.xml
@@ -0,0 +1,29 @@
1 <category name="Mali-V500">
2 <event counter="ARM_Mali-V500_cnt0" title="Mali Video Engine" name="Samples" class="absolute" description="The number of times we have taken a sample"/>
3 <event counter="ARM_Mali-V500_cnt1" title="Mali Video Engine" name="Queued input-buffers" class="absolute" description="The number of input-buffers that has been queued for consumption by the MVE"/>
4 <event counter="ARM_Mali-V500_cnt2" title="Mali Video Engine" name="Consumed input-buffers" class="absolute" description="The number of input-buffers that has been consumed by the MVE and returned to the application"/>
5 <event counter="ARM_Mali-V500_cnt3" title="Mali Video Engine" name="Queued output-buffers" class="absolute" description="The number of output-buffers that has been queued for usage by the MVE"/>
6 <event counter="ARM_Mali-V500_cnt4" title="Mali Video Engine" name="Consumed output-buffers" class="absolute" description="The number of output-buffers that has been consumed by the MVE and returned to the application"/>
7 <event counter="ARM_Mali-V500_cnt5" title="Mali Video Engine" name="Created Sessions" class="absolute" description="The number of created sessions throughout the lifetime of the process"/>
8 <event counter="ARM_Mali-V500_cnt6" title="Mali Video Engine" name="Active Sessions" description="The number of currently existing sessions"/>
9 <event counter="ARM_Mali-V500_cnt7" title="Mali Video Engine" name="Processed Frames" class="absolute" description="The number of processed frames. A processed frame is one where the encode or decode is complete for that particular frame. Frames can be processed out of order so this is not the same as the number of output-buffers returned"/>
10 <event counter="ARM_Mali-V500_cnt8" title="Mali Video Engine" name="Input Flushes Requested" class="absolute" description="The number of requested flushes of the input queue"/>
11 <event counter="ARM_Mali-V500_cnt9" title="Mali Video Engine" name="Input Flushes Complete" class="absolute" description="The number of completed flushes of the input queue"/>
12 <event counter="ARM_Mali-V500_cnt10" title="Mali Video Engine" name="Output Flushes Requested" class="absolute" description="The number of requested flushes of the output queue"/>
13 <event counter="ARM_Mali-V500_cnt11" title="Mali Video Engine" name="Output Flushes Complete" class="absolute" description="The number of completed flushes of the output queue"/>
14 <event counter="ARM_Mali-V500_cnt12" title="Mali Video Engine" name="Queued Output Buffers (current)" description="The number of output-buffers that are currently queued for usage by the MVE"/>
15 <event counter="ARM_Mali-V500_cnt13" title="Mali Video Engine" name="Queued Input Buffers (current)" description="The number of input-buffers that are currently queued for consumption by the MVE"/>
16 <event counter="ARM_Mali-V500_cnt14" title="Mali Video Engine" name="Output Queue Flushes" description="The number of pending flushes for the MVE output-queue"/>
17 <event counter="ARM_Mali-V500_cnt15" title="Mali Video Engine" name="Input Queue Flushes" description="The number of pending flushes for the MVE input-queue"/>
18 <event counter="ARM_Mali-V500_cnt16" title="Mali Video Engine" name="Errors encountered" class="absolute" description="The number of errors encountered"/>
19 <event counter="ARM_Mali-V500_cnt17" title="Mali Video Engine" name="Bits consumed" class="absolute" description="The number of bits consumed during decode"/>
20 <event counter="ARM_Mali-V500_cnt18" title="Mali Video Engine" name="AFBC bandwidth" class="absolute" description="The amount of AFBC-encoded bytes read or written"/>
21 <event counter="ARM_Mali-V500_cnt19" title="Mali Video Engine" name="Bandwidth (read)" class="absolute" description="The amount of bytes read over the AXI bus"/>
22 <event counter="ARM_Mali-V500_cnt20" title="Mali Video Engine" name="Bandwidth (write)" class="absolute" description="The amount of bytes written over the AXI bus"/>
23 <event counter="ARM_Mali-V500_evn0" title="Mali Video Engine" name="Session created" description="Generated when a session has been created"/>
24 <event counter="ARM_Mali-V500_evn1" title="Mali Video Engine" name="Session destroyed" description="Generated when a session has been destroyed"/>
25 <event counter="ARM_Mali-V500_evn2" title="Mali Video Engine" name="Frame Processed" description="Generated when the MVE has finished processing a frame"/>
26 <event counter="ARM_Mali-V500_evn3" title="Mali Video Engine" name="Output buffer received" description="Generated when an an output buffer is returned to us from the MVE"/>
27 <event counter="ARM_Mali-V500_evn4" title="Mali Video Engine" name="Input buffer received" description="Generated when we an input buffer is returned to us from the MVE"/>
28 <!--event counter="ARM_Mali-V500_act" title="VPU" name="Activity" class="activity" activity1="Parsed" activity_color1="0x000000ff" activity2="Piped" activity_color2="0x0000ff00" rendering_type="bar" average_selection="yes" average_cores="yes" percentage="yes" cores="8" description="Mali-V500 Activity"/-->
29 </category>
diff --git a/daemon/main.cpp b/daemon/main.cpp
index 1275aef..2998c70 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -20,8 +20,10 @@
20#include <unistd.h> 20#include <unistd.h>
21 21
22#include "Child.h" 22#include "Child.h"
23#include "EventsXML.h"
23#include "KMod.h" 24#include "KMod.h"
24#include "Logging.h" 25#include "Logging.h"
26#include "Monitor.h"
25#include "OlySocket.h" 27#include "OlySocket.h"
26#include "OlyUtility.h" 28#include "OlyUtility.h"
27#include "SessionData.h" 29#include "SessionData.h"
@@ -31,8 +33,9 @@
31extern Child* child; 33extern Child* child;
32static int shutdownFilesystem(); 34static int shutdownFilesystem();
33static pthread_mutex_t numSessions_mutex; 35static pthread_mutex_t numSessions_mutex;
34static int numSessions = 0;
35static OlyServerSocket* sock = NULL; 36static OlyServerSocket* sock = NULL;
37static Monitor monitor;
38static int numSessions = 0;
36static bool driverRunningAtStart = false; 39static bool driverRunningAtStart = false;
37static bool driverMountedAtStart = false; 40static bool driverMountedAtStart = false;
38 41
@@ -102,42 +105,8 @@ static void child_exit(int) {
102 } 105 }
103} 106}
104 107
105static int udpPort(int port) { 108static const int UDP_ANS_PORT = 30000;
106 int s; 109static const int UDP_REQ_PORT = 30001;
107 struct sockaddr_in6 sockaddr;
108 int on;
109 int family = AF_INET6;
110
111 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
112 if (s == -1) {
113 family = AF_INET;
114 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
115 if (s == -1) {
116 logg->logError(__FILE__, __LINE__, "socket failed");
117 handleException();
118 }
119 }
120
121 on = 1;
122 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
123 logg->logError(__FILE__, __LINE__, "setsockopt failed");
124 handleException();
125 }
126
127 memset((void*)&sockaddr, 0, sizeof(sockaddr));
128 sockaddr.sin6_family = family;
129 sockaddr.sin6_port = htons(port);
130 sockaddr.sin6_addr = in6addr_any;
131 if (bind(s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
132 logg->logError(__FILE__, __LINE__, "socket failed");
133 handleException();
134 }
135
136 return s;
137}
138
139#define UDP_ANS_PORT 30000
140#define UDP_REQ_PORT 30001
141 110
142typedef struct { 111typedef struct {
143 char rviHeader[8]; 112 char rviHeader[8];
@@ -149,50 +118,102 @@ typedef struct {
149 uint32_t ipAddress; 118 uint32_t ipAddress;
150 uint32_t defaultGateway; 119 uint32_t defaultGateway;
151 uint32_t subnetMask; 120 uint32_t subnetMask;
152 uint32_t activeConnections; 121 uint32_t activeConnections;
153} RVIConfigureInfo; 122} RVIConfigureInfo;
154 123
155static const char DST_REQ[] = { 'D', 'S', 'T', '_', 'R', 'E', 'Q', ' ', 0, 0, 0, 0x64 }; 124static const char DST_REQ[] = { 'D', 'S', 'T', '_', 'R', 'E', 'Q', ' ', 0, 0, 0, 0x64 };
156 125
157static void* answerThread(void* pVoid) { 126class UdpListener {
158 prctl(PR_SET_NAME, (unsigned long)&"gatord-discover", 0, 0, 0); 127public:
159 const struct cmdline_t * const cmdline = (struct cmdline_t *)pVoid; 128 UdpListener() : mDstAns(), mReq(-1), mAns(-1) {}
160 RVIConfigureInfo dstAns; 129
161 int req = udpPort(UDP_REQ_PORT); 130 void setup(int port) {
162 int ans = udpPort(UDP_ANS_PORT); 131 mReq = udpPort(UDP_REQ_PORT);
163 132 mAns = udpPort(UDP_ANS_PORT);
164 // Format the answer buffer 133
165 memset(&dstAns, 0, sizeof(dstAns)); 134 // Format the answer buffer
166 memcpy(dstAns.rviHeader, "STR_ANS ", sizeof(dstAns.rviHeader)); 135 memset(&mDstAns, 0, sizeof(mDstAns));
167 if (gethostname(dstAns.dhcpName, sizeof(dstAns.dhcpName) - 1) != 0) { 136 memcpy(mDstAns.rviHeader, "STR_ANS ", sizeof(mDstAns.rviHeader));
168 logg->logError(__FILE__, __LINE__, "gethostname failed"); 137 if (gethostname(mDstAns.dhcpName, sizeof(mDstAns.dhcpName) - 1) != 0) {
169 handleException(); 138 logg->logError(__FILE__, __LINE__, "gethostname failed");
139 handleException();
140 }
141 // Subvert the defaultGateway field for the port number
142 if (port != DEFAULT_PORT) {
143 mDstAns.defaultGateway = port;
144 }
145 // Subvert the subnetMask field for the protocol version
146 mDstAns.subnetMask = PROTOCOL_VERSION;
170 } 147 }
171 // Subvert the defaultGateway field for the port number 148
172 if (cmdline->port != DEFAULT_PORT) { 149 int getReq() const {
173 dstAns.defaultGateway = cmdline->port; 150 return mReq;
174 } 151 }
175 // Subvert the subnetMask field for the protocol version
176 dstAns.subnetMask = PROTOCOL_VERSION;
177 152
178 for (;;) { 153 void handle() {
179 char buf[128]; 154 char buf[128];
180 struct sockaddr_in6 sockaddr; 155 struct sockaddr_in6 sockaddr;
181 socklen_t addrlen; 156 socklen_t addrlen;
182 int read; 157 int read;
183 addrlen = sizeof(sockaddr); 158 addrlen = sizeof(sockaddr);
184 read = recvfrom(req, &buf, sizeof(buf), 0, (struct sockaddr *)&sockaddr, &addrlen); 159 read = recvfrom(mReq, &buf, sizeof(buf), 0, (struct sockaddr *)&sockaddr, &addrlen);
185 if (read < 0) { 160 if (read < 0) {
186 logg->logError(__FILE__, __LINE__, "recvfrom failed"); 161 logg->logError(__FILE__, __LINE__, "recvfrom failed");
187 handleException(); 162 handleException();
188 } else if ((read == 12) && (memcmp(buf, DST_REQ, sizeof(DST_REQ)) == 0)) { 163 } else if ((read == 12) && (memcmp(buf, DST_REQ, sizeof(DST_REQ)) == 0)) {
189 if (sendto(ans, &dstAns, sizeof(dstAns), 0, (struct sockaddr *)&sockaddr, addrlen) != sizeof(dstAns)) { 164 if (sendto(mAns, &mDstAns, sizeof(mDstAns), 0, (struct sockaddr *)&sockaddr, addrlen) != sizeof(mDstAns)) {
190 logg->logError(__FILE__, __LINE__, "sendto failed"); 165 logg->logError(__FILE__, __LINE__, "sendto failed");
191 handleException(); 166 handleException();
192 } 167 }
193 } 168 }
194 } 169 }
195} 170
171 void close() {
172 ::close(mReq);
173 ::close(mAns);
174 }
175
176private:
177 int udpPort(int port) {
178 int s;
179 struct sockaddr_in6 sockaddr;
180 int on;
181 int family = AF_INET6;
182
183 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
184 if (s == -1) {
185 family = AF_INET;
186 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
187 if (s == -1) {
188 logg->logError(__FILE__, __LINE__, "socket failed");
189 handleException();
190 }
191 }
192
193 on = 1;
194 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
195 logg->logError(__FILE__, __LINE__, "setsockopt failed");
196 handleException();
197 }
198
199 memset((void*)&sockaddr, 0, sizeof(sockaddr));
200 sockaddr.sin6_family = family;
201 sockaddr.sin6_port = htons(port);
202 sockaddr.sin6_addr = in6addr_any;
203 if (bind(s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
204 logg->logError(__FILE__, __LINE__, "socket failed");
205 handleException();
206 }
207
208 return s;
209 }
210
211 RVIConfigureInfo mDstAns;
212 int mReq;
213 int mAns;
214};
215
216static UdpListener udpListener;
196 217
197// retval: -1 = failure; 0 = was already mounted; 1 = successfully mounted 218// retval: -1 = failure; 0 = was already mounted; 1 = successfully mounted
198static int mountGatorFS() { 219static int mountGatorFS() {
@@ -218,7 +239,7 @@ static bool init_module (const char * const location) {
218 if (fstat(fd, &st) == 0) { 239 if (fstat(fd, &st) == 0) {
219 void * const p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 240 void * const p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
220 if (p != MAP_FAILED) { 241 if (p != MAP_FAILED) {
221 if (syscall(__NR_init_module, p, st.st_size, "") == 0) { 242 if (syscall(__NR_init_module, p, (unsigned long)st.st_size, "") == 0) {
222 ret = true; 243 ret = true;
223 } 244 }
224 munmap(p, st.st_size); 245 munmap(p, st.st_size);
@@ -264,8 +285,14 @@ static bool setupFilesystem(char* module) {
264 } 285 }
265 286
266 if (access(location, F_OK) == -1) { 287 if (access(location, F_OK) == -1) {
267 // The gator kernel is not already loaded and unable to locate gator.ko 288 if (module == NULL) {
268 return false; 289 // The gator kernel is not already loaded and unable to locate gator.ko in the default location
290 return false;
291 } else {
292 // gator location specified on the command line but it was not found
293 logg->logError(__FILE__, __LINE__, "gator module not found at %s", location);
294 handleException();
295 }
269 } 296 }
270 297
271 // Load driver 298 // Load driver
@@ -380,6 +407,45 @@ static struct cmdline_t parseCommandLine(int argc, char** argv) {
380 return cmdline; 407 return cmdline;
381} 408}
382 409
410void handleClient() {
411 OlySocket client(sock->acceptConnection());
412
413 int pid = fork();
414 if (pid < 0) {
415 // Error
416 logg->logError(__FILE__, __LINE__, "Fork process failed. Please power cycle the target device if this error persists.");
417 } else if (pid == 0) {
418 // Child
419 sock->closeServerSocket();
420 udpListener.close();
421 monitor.close();
422 child = new Child(&client, numSessions + 1);
423 child->run();
424 delete child;
425 exit(0);
426 } else {
427 // Parent
428 client.closeSocket();
429
430 pthread_mutex_lock(&numSessions_mutex);
431 numSessions++;
432 pthread_mutex_unlock(&numSessions_mutex);
433
434 // Maximum number of connections is 2
435 int wait = 0;
436 while (numSessions > 1) {
437 // Throttle until one of the children exits before continuing to accept another socket connection
438 logg->logMessage("%d sessions active!", numSessions);
439 if (wait++ >= 10) { // Wait no more than 10 seconds
440 // Kill last created child
441 kill(pid, SIGALRM);
442 break;
443 }
444 sleep(1);
445 }
446 }
447}
448
383// Gator data flow: collector -> collector fifo -> sender 449// Gator data flow: collector -> collector fifo -> sender
384int main(int argc, char** argv) { 450int main(int argc, char** argv) {
385 // Ensure proper signal handling by making gatord the process group leader 451 // Ensure proper signal handling by making gatord the process group leader
@@ -420,16 +486,23 @@ int main(int argc, char** argv) {
420 logg->logMessage("Unable to setup gatorfs, trying perf"); 486 logg->logMessage("Unable to setup gatorfs, trying perf");
421 if (!gSessionData->perf.setup()) { 487 if (!gSessionData->perf.setup()) {
422 logg->logError(__FILE__, __LINE__, 488 logg->logError(__FILE__, __LINE__,
423 "Unable to locate gator.ko driver:\n" 489 "Unable to locate gator.ko driver:\n"
424 " >>> gator.ko should be co-located with gatord in the same directory\n" 490 " >>> gator.ko should be co-located with gatord in the same directory\n"
425 " >>> OR insmod gator.ko prior to launching gatord\n" 491 " >>> OR insmod gator.ko prior to launching gatord\n"
426 " >>> OR specify the location of gator.ko on the command line\n" 492 " >>> OR specify the location of gator.ko on the command line\n"
427 " >>> OR run Linux 3.12 or later with perf support to collect data via userspace only"); 493 " >>> OR run Linux 3.4 or later with perf (CONFIG_PERF_EVENTS and CONFIG_HW_PERF_EVENTS) and tracing (CONFIG_TRACING) support to collect data via userspace only");
428 handleException(); 494 handleException();
429 } 495 }
430 } 496 }
431 497
432 gSessionData->hwmon.setup(); 498 gSessionData->hwmon.setup();
499 {
500 EventsXML eventsXML;
501 mxml_node_t *xml = eventsXML.getTree();
502 gSessionData->fsDriver.setup(xml);
503 gSessionData->maliVideo.setup(xml);
504 mxmlDelete(xml);
505 }
433 506
434 // Handle child exit codes 507 // Handle child exit codes
435 signal(SIGCHLD, child_exit); 508 signal(SIGCHLD, child_exit);
@@ -444,47 +517,26 @@ int main(int argc, char** argv) {
444 child->run(); 517 child->run();
445 delete child; 518 delete child;
446 } else { 519 } else {
447 pthread_t answerThreadID; 520 sock = new OlyServerSocket(cmdline.port);
448 if (pthread_create(&answerThreadID, NULL, answerThread, &cmdline)) { 521 udpListener.setup(cmdline.port);
449 logg->logError(__FILE__, __LINE__, "Failed to create answer thread"); 522 if (!monitor.init() || !monitor.add(sock->getFd()) || !monitor.add(udpListener.getReq())) {
523 logg->logError(__FILE__, __LINE__, "Monitor setup failed");
450 handleException(); 524 handleException();
451 } 525 }
452 sock = new OlyServerSocket(cmdline.port);
453 // Forever loop, can be exited via a signal or exception 526 // Forever loop, can be exited via a signal or exception
454 while (1) { 527 while (1) {
528 struct epoll_event events[2];
455 logg->logMessage("Waiting on connection..."); 529 logg->logMessage("Waiting on connection...");
456 OlySocket client(sock->acceptConnection()); 530 int ready = monitor.wait(events, ARRAY_LENGTH(events), -1);
457 531 if (ready < 0) {
458 int pid = fork(); 532 logg->logError(__FILE__, __LINE__, "Monitor::wait failed");
459 if (pid < 0) { 533 handleException();
460 // Error 534 }
461 logg->logError(__FILE__, __LINE__, "Fork process failed. Please power cycle the target device if this error persists."); 535 for (int i = 0; i < ready; ++i) {
462 } else if (pid == 0) { 536 if (events[i].data.fd == sock->getFd()) {
463 // Child 537 handleClient();
464 sock->closeServerSocket(); 538 } else if (events[i].data.fd == udpListener.getReq()) {
465 child = new Child(&client, numSessions + 1); 539 udpListener.handle();
466 child->run();
467 delete child;
468 exit(0);
469 } else {
470 // Parent
471 client.closeSocket();
472
473 pthread_mutex_lock(&numSessions_mutex);
474 numSessions++;
475 pthread_mutex_unlock(&numSessions_mutex);
476
477 // Maximum number of connections is 2
478 int wait = 0;
479 while (numSessions > 1) {
480 // Throttle until one of the children exits before continuing to accept another socket connection
481 logg->logMessage("%d sessions active!", numSessions);
482 if (wait++ >= 10) { // Wait no more than 10 seconds
483 // Kill last created child
484 kill(pid, SIGALRM);
485 break;
486 }
487 sleep(1);
488 } 540 }
489 } 541 }
490 } 542 }
diff --git a/driver/Makefile b/driver/Makefile
index 3dc9d05..2f86823 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -7,13 +7,14 @@ CONFIG_GATOR ?= m
7obj-$(CONFIG_GATOR) := gator.o 7obj-$(CONFIG_GATOR) := gator.o
8 8
9gator-y := gator_main.o \ 9gator-y := gator_main.o \
10 gator_events_irq.o \
11 gator_events_sched.o \
12 gator_events_net.o \
13 gator_events_block.o \ 10 gator_events_block.o \
11 gator_events_irq.o \
14 gator_events_meminfo.o \ 12 gator_events_meminfo.o \
15 gator_events_perf_pmu.o \
16 gator_events_mmapped.o \ 13 gator_events_mmapped.o \
14 gator_events_net.o \
15 gator_events_perf_pmu.o \
16 gator_events_sched.o \
17 gator_events_threads.o \
17 18
18# Convert the old GATOR_WITH_MALI_SUPPORT to the new kernel flags 19# Convert the old GATOR_WITH_MALI_SUPPORT to the new kernel flags
19ifneq ($(GATOR_WITH_MALI_SUPPORT),) 20ifneq ($(GATOR_WITH_MALI_SUPPORT),)
@@ -48,10 +49,14 @@ ifeq ($(CONFIG_GATOR_WITH_MALI_SUPPORT),y)
48 ccflags-$(CONFIG_GATOR_MALI_T6XX) += -DMALI_SUPPORT=MALI_T6xx 49 ccflags-$(CONFIG_GATOR_MALI_T6XX) += -DMALI_SUPPORT=MALI_T6xx
49endif 50endif
50 51
51# GATOR_TEST controls whether to include (=1) or exclude (=0) test code. 52# GATOR_TEST controls whether to include (=1) or exclude (=0) test code.
52GATOR_TEST ?= 0 53GATOR_TEST ?= 0
53EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST) 54EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST)
54 55
56# Should the original or new block_rq_complete API be used?
57OLD_BLOCK_RQ_COMPLETE := $(shell grep -A3 block_rq_complete include/trace/events/block.h | grep nr_bytes > /dev/null; echo $$?)
58EXTRA_CFLAGS += -DOLD_BLOCK_RQ_COMPLETE=$(OLD_BLOCK_RQ_COMPLETE)
59
55gator-$(CONFIG_ARM) += gator_events_armv6.o \ 60gator-$(CONFIG_ARM) += gator_events_armv6.o \
56 gator_events_armv7.o \ 61 gator_events_armv7.o \
57 gator_events_ccn-504.o \ 62 gator_events_ccn-504.o \
diff --git a/driver/gator.h b/driver/gator.h
index 58cb0a2..5ad0254 100644
--- a/driver/gator.h
+++ b/driver/gator.h
@@ -42,6 +42,10 @@
42#define AARCH64 0xd0f 42#define AARCH64 0xd0f
43#define OTHER 0xfff 43#define OTHER 0xfff
44 44
45// gpu enums
46#define MALI_4xx 1
47#define MALI_T6xx 2
48
45#define MAXSIZE_CORE_NAME 32 49#define MAXSIZE_CORE_NAME 32
46 50
47struct gator_cpu { 51struct gator_cpu {
@@ -123,6 +127,8 @@ u32 gator_cpuid(void);
123 127
124void gator_backtrace_handler(struct pt_regs *const regs); 128void gator_backtrace_handler(struct pt_regs *const regs);
125 129
130void gator_marshal_activity_switch(int core, int key, int activity, int pid);
131
126#if !GATOR_IKS_SUPPORT 132#if !GATOR_IKS_SUPPORT
127 133
128#define get_physical_cpu() smp_processor_id() 134#define get_physical_cpu() smp_processor_id()
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index 9f305cf..e03c165 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -178,7 +178,7 @@ static void kernel_backtrace(int cpu, struct pt_regs *const regs)
178 marshal_backtrace(PC_REG & ~1, NO_COOKIE, 1); 178 marshal_backtrace(PC_REG & ~1, NO_COOKIE, 1);
179#endif 179#endif
180} 180}
181 181
182static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time) 182static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time)
183{ 183{
184 bool in_kernel; 184 bool in_kernel;
diff --git a/driver/gator_buffer.c b/driver/gator_buffer.c
index eba22df..dfbc97d 100644
--- a/driver/gator_buffer.c
+++ b/driver/gator_buffer.c
@@ -37,12 +37,12 @@ static void marshal_frame(int cpu, int buftype)
37 case SCHED_TRACE_BUF: 37 case SCHED_TRACE_BUF:
38 frame = FRAME_SCHED_TRACE; 38 frame = FRAME_SCHED_TRACE;
39 break; 39 break;
40 case GPU_TRACE_BUF:
41 frame = FRAME_GPU_TRACE;
42 break;
43 case IDLE_BUF: 40 case IDLE_BUF:
44 frame = FRAME_IDLE; 41 frame = FRAME_IDLE;
45 break; 42 break;
43 case ACTIVITY_BUF:
44 frame = FRAME_ACTIVITY;
45 break;
46 default: 46 default:
47 frame = -1; 47 frame = -1;
48 break; 48 break;
diff --git a/driver/gator_events_armv7.c b/driver/gator_events_armv7.c
index 153119b..bd8a9ba 100644
--- a/driver/gator_events_armv7.c
+++ b/driver/gator_events_armv7.c
@@ -27,9 +27,9 @@
27// ccnt reg 27// ccnt reg
28#define CCNT_REG (1 << 31) 28#define CCNT_REG (1 << 31)
29 29
30#define CCNT 0 30#define CCNT 0
31#define CNT0 1 31#define CNT0 1
32#define CNTMAX (6+1) 32#define CNTMAX (6+1)
33 33
34static const char *pmnc_name; 34static const char *pmnc_name;
35static int pmnc_counters; 35static int pmnc_counters;
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c
index b2bc414..03eed4f 100644
--- a/driver/gator_events_block.c
+++ b/driver/gator_events_block.c
@@ -28,15 +28,25 @@ static ulong block_rq_rd_key;
28static atomic_t blockCnt[BLOCK_TOTAL]; 28static atomic_t blockCnt[BLOCK_TOTAL];
29static int blockGet[BLOCK_TOTAL * 4]; 29static int blockGet[BLOCK_TOTAL * 4];
30 30
31// Tracepoint changed in 3.15 backported to older kernels. The Makefile tries to autodetect the correct value, but if it fails change the #if below
32#if OLD_BLOCK_RQ_COMPLETE
31GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq)) 33GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq))
34#else
35GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq, unsigned int nr_bytes))
36#endif
32{ 37{
33 int write, size; 38 int write;
39 unsigned int size;
34 40
35 if (!rq) 41 if (!rq)
36 return; 42 return;
37 43
38 write = rq->cmd_flags & EVENTWRITE; 44 write = rq->cmd_flags & EVENTWRITE;
45#if OLD_BLOCK_RQ_COMPLETE
39 size = rq->resid_len; 46 size = rq->resid_len;
47#else
48 size = nr_bytes;
49#endif
40 50
41 if (!size) 51 if (!size)
42 return; 52 return;
diff --git a/driver/gator_events_mali_4xx.c b/driver/gator_events_mali_4xx.c
index 85d4764..9e1c706 100644
--- a/driver/gator_events_mali_4xx.c
+++ b/driver/gator_events_mali_4xx.c
@@ -18,17 +18,27 @@
18#include "gator_events_mali_4xx.h" 18#include "gator_events_mali_4xx.h"
19 19
20/* 20/*
21 * There are (currently) four different variants of the comms between gator and Mali: 21* There have been four different variants of the comms between gator and Mali depending on driver version:
22 * 1 (deprecated): No software counter support 22* # | DDK vsn range | Support | Notes
23 * 2 (deprecated): Tracepoint called for each separate s/w counter value as it appears 23*
24 * 3 (default): Single tracepoint for all s/w counters in a bundle. 24* 1 | (obsolete) | No software counter support | Obsolete patches
25 * Interface style 3 is the default if no other is specified. 1 and 2 will be eliminated when 25* 2 | (obsolete) | Tracepoint called for each separate s/w counter value as it appears | Obsolete patches
26 * existing Mali DDKs are upgraded. 26* 3 | r3p0-04rel0 - r3p2-01rel2 | Single tracepoint for all s/w counters in a bundle. |
27 * 4. As above, but for the Utgard (Mali-450) driver. 27* 4 | r3p2-01rel3 - date | As above but with extensions for MP devices (Mali-450) | At least r4p0-00rel1
28 */ 28*/
29 29
30#if !defined(GATOR_MALI_INTERFACE_STYLE) 30#if !defined(GATOR_MALI_INTERFACE_STYLE)
31#define GATOR_MALI_INTERFACE_STYLE (3) 31#define GATOR_MALI_INTERFACE_STYLE (4)
32#endif
33
34#if GATOR_MALI_INTERFACE_STYLE == 1
35#error GATOR_MALI_INTERFACE_STYLE 1 is obsolete
36#elif GATOR_MALI_INTERFACE_STYLE == 2
37#error GATOR_MALI_INTERFACE_STYLE 2 is obsolete
38#elif GATOR_MALI_INTERFACE_STYLE >= 3
39// Valid GATOR_MALI_INTERFACE_STYLE
40#else
41#error Unknown GATOR_MALI_INTERFACE_STYLE option.
32#endif 42#endif
33 43
34#if GATOR_MALI_INTERFACE_STYLE < 4 44#if GATOR_MALI_INTERFACE_STYLE < 4
@@ -44,6 +54,8 @@
44#error MALI_SUPPORT set to an invalid device code: expecting MALI_4xx 54#error MALI_SUPPORT set to an invalid device code: expecting MALI_4xx
45#endif 55#endif
46 56
57static const char mali_name[] = "Mali-4xx";
58
47/* gatorfs variables for counter enable state, 59/* gatorfs variables for counter enable state,
48 * the event the counter should count and the 60 * the event the counter should count and the
49 * 'key' (a unique id set by gatord and returned 61 * 'key' (a unique id set by gatord and returned
@@ -63,6 +75,7 @@ static u32 *counter_address[NUMBER_OF_EVENTS];
63 */ 75 */
64static unsigned long counter_dump[NUMBER_OF_EVENTS * 2]; 76static unsigned long counter_dump[NUMBER_OF_EVENTS * 2];
65static unsigned long counter_prev[NUMBER_OF_EVENTS]; 77static unsigned long counter_prev[NUMBER_OF_EVENTS];
78static bool prev_set[NUMBER_OF_EVENTS];
66 79
67/* Note whether tracepoints have been registered */ 80/* Note whether tracepoints have been registered */
68static int trace_registered; 81static int trace_registered;
@@ -76,18 +89,11 @@ static unsigned int n_vp_cores = MAX_NUM_VP_CORES;
76static unsigned int n_l2_cores = MAX_NUM_L2_CACHE_CORES; 89static unsigned int n_l2_cores = MAX_NUM_L2_CACHE_CORES;
77static unsigned int n_fp_cores = MAX_NUM_FP_CORES; 90static unsigned int n_fp_cores = MAX_NUM_FP_CORES;
78 91
79/** 92extern mali_counter mali_activity[2];
80 * Calculate the difference and handle the overflow. 93static const char* const mali_activity_names[] = {
81 */ 94 "fragment",
82static u32 get_difference(u32 start, u32 end) 95 "vertex",
83{ 96};
84 if (start - end >= 0) {
85 return start - end;
86 }
87
88 // Mali counters are unsigned 32 bit values that wrap.
89 return (4294967295u - end) + start;
90}
91 97
92/** 98/**
93 * Returns non-zero if the given counter ID is an activity counter. 99 * Returns non-zero if the given counter ID is an activity counter.
@@ -112,40 +118,6 @@ static inline int is_hw_counter(unsigned int event_id)
112typedef void _mali_profiling_get_mali_version_type(struct _mali_profiling_mali_version *values); 118typedef void _mali_profiling_get_mali_version_type(struct _mali_profiling_mali_version *values);
113typedef u32 _mali_profiling_get_l2_counters_type(_mali_profiling_l2_counter_values *values); 119typedef u32 _mali_profiling_get_l2_counters_type(_mali_profiling_l2_counter_values *values);
114 120
115#if GATOR_MALI_INTERFACE_STYLE == 2
116/**
117 * Returns non-zero if the given counter ID is a software counter.
118 */
119static inline int is_sw_counter(unsigned int event_id)
120{
121 return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
122}
123#endif
124
125#if GATOR_MALI_INTERFACE_STYLE == 2
126/*
127 * The Mali DDK uses s64 types to contain software counter values, but gator
128 * can only use a maximum of 32 bits. This function scales a software counter
129 * to an appropriate range.
130 */
131static u32 scale_sw_counter_value(unsigned int event_id, signed long long value)
132{
133 u32 scaled_value;
134
135 switch (event_id) {
136 case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
137 case COUNTER_GLES_UPLOAD_VBO_TIME:
138 scaled_value = (u32)div_s64(value, 1000000);
139 break;
140 default:
141 scaled_value = (u32)value;
142 break;
143 }
144
145 return scaled_value;
146}
147#endif
148
149/* Probe for continuously sampled counter */ 121/* Probe for continuously sampled counter */
150#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING 122#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
151GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32 *addr)) 123GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32 *addr))
@@ -172,16 +144,6 @@ GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int
172 } 144 }
173} 145}
174 146
175#if GATOR_MALI_INTERFACE_STYLE == 2
176GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value))
177{
178 if (is_sw_counter(event_id)) {
179 counter_data[event_id] = scale_sw_counter_value(event_id, value);
180 }
181}
182#endif /* GATOR_MALI_INTERFACE_STYLE == 2 */
183
184#if GATOR_MALI_INTERFACE_STYLE >= 3
185GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters)) 147GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters))
186{ 148{
187 u32 i; 149 u32 i;
@@ -193,7 +155,6 @@ GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surfac
193 } 155 }
194 } 156 }
195} 157}
196#endif /* GATOR_MALI_INTERFACE_STYLE >= 3 */
197 158
198/** 159/**
199 * Create a single filesystem entry for a specified event. 160 * Create a single filesystem entry for a specified event.
@@ -254,6 +215,7 @@ static void initialise_version_info(void)
254 symbol_put(_mali_profiling_get_mali_version); 215 symbol_put(_mali_profiling_get_mali_version);
255 } else { 216 } else {
256 printk("gator: mali online _mali_profiling_get_mali_version symbol not found\n"); 217 printk("gator: mali online _mali_profiling_get_mali_version symbol not found\n");
218 printk("gator: check your Mali DDK version versus the GATOR_MALI_INTERFACE_STYLE setting\n");
257 } 219 }
258} 220}
259#endif 221#endif
@@ -261,7 +223,6 @@ static void initialise_version_info(void)
261static int create_files(struct super_block *sb, struct dentry *root) 223static int create_files(struct super_block *sb, struct dentry *root)
262{ 224{
263 int event; 225 int event;
264 const char *mali_name = gator_mali_get_mali_name();
265 226
266 char buf[40]; 227 char buf[40];
267 int core_id; 228 int core_id;
@@ -278,6 +239,14 @@ static int create_files(struct super_block *sb, struct dentry *root)
278 initialise_version_info(); 239 initialise_version_info();
279#endif 240#endif
280 241
242 mali_activity[0].cores = n_fp_cores;
243 mali_activity[1].cores = n_vp_cores;
244 for (event = 0; event < ARRAY_SIZE(mali_activity); event++) {
245 if (gator_mali_create_file_system(mali_name, mali_activity_names[event], sb, root, &mali_activity[event], NULL) != 0) {
246 return -1;
247 }
248 }
249
281 /* Vertex processor counters */ 250 /* Vertex processor counters */
282 for (core_id = 0; core_id < n_vp_cores; core_id++) { 251 for (core_id = 0; core_id < n_vp_cores; core_id++) {
283 int activity_counter_id = ACTIVITY_VP_0; 252 int activity_counter_id = ACTIVITY_VP_0;
@@ -413,7 +382,6 @@ static void init_counters(unsigned int from_counter, unsigned int to_counter)
413static void mali_counter_initialize(void) 382static void mali_counter_initialize(void)
414{ 383{
415 int i; 384 int i;
416 int core_id;
417 385
418 mali_profiling_control_type *mali_control; 386 mali_profiling_control_type *mali_control;
419 387
@@ -463,15 +431,10 @@ static void mali_counter_initialize(void)
463 n_l2_cores = 0; 431 n_l2_cores = 0;
464 } 432 }
465 433
466 for (core_id = 0; core_id < n_l2_cores; core_id++) {
467 int counter_id = COUNTER_L2_0_C0 + (2 * core_id);
468 counter_prev[counter_id] = 0;
469 counter_prev[counter_id + 1] = 0;
470 }
471
472 /* Clear counters in the start */ 434 /* Clear counters in the start */
473 for (i = 0; i < NUMBER_OF_EVENTS; i++) { 435 for (i = 0; i < NUMBER_OF_EVENTS; i++) {
474 counter_data[i] = 0; 436 counter_data[i] = 0;
437 prev_set[i] = false;
475 } 438 }
476} 439}
477 440
@@ -528,23 +491,11 @@ static int start(void)
528 return -1; 491 return -1;
529 } 492 }
530 493
531#if GATOR_MALI_INTERFACE_STYLE == 1
532 /* None. */
533#elif GATOR_MALI_INTERFACE_STYLE == 2
534 /* For patched Mali driver. */
535 if (GATOR_REGISTER_TRACE(mali_sw_counter)) {
536 printk("gator: mali_sw_counter tracepoint failed to activate\n");
537 return -1;
538 }
539#elif GATOR_MALI_INTERFACE_STYLE >= 3
540 /* For Mali drivers with built-in support. */ 494 /* For Mali drivers with built-in support. */
541 if (GATOR_REGISTER_TRACE(mali_sw_counters)) { 495 if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
542 printk("gator: mali_sw_counters tracepoint failed to activate\n"); 496 printk("gator: mali_sw_counters tracepoint failed to activate\n");
543 return -1; 497 return -1;
544 } 498 }
545#else
546#error Unknown GATOR_MALI_INTERFACE_STYLE option.
547#endif
548 499
549 trace_registered = 1; 500 trace_registered = 1;
550 501
@@ -561,17 +512,8 @@ static void stop(void)
561 if (trace_registered) { 512 if (trace_registered) {
562 GATOR_UNREGISTER_TRACE(mali_hw_counter); 513 GATOR_UNREGISTER_TRACE(mali_hw_counter);
563 514
564#if GATOR_MALI_INTERFACE_STYLE == 1
565 /* None. */
566#elif GATOR_MALI_INTERFACE_STYLE == 2
567 /* For patched Mali driver. */
568 GATOR_UNREGISTER_TRACE(mali_sw_counter);
569#elif GATOR_MALI_INTERFACE_STYLE >= 3
570 /* For Mali drivers with built-in support. */ 515 /* For Mali drivers with built-in support. */
571 GATOR_UNREGISTER_TRACE(mali_sw_counters); 516 GATOR_UNREGISTER_TRACE(mali_sw_counters);
572#else
573#error Unknown GATOR_MALI_INTERFACE_STYLE option.
574#endif
575 517
576 pr_debug("gator: mali timeline tracepoint deactivated\n"); 518 pr_debug("gator: mali timeline tracepoint deactivated\n");
577 519
@@ -636,21 +578,23 @@ static int read(int **buffer)
636 578
637 per_core = &cache_values.cores[cache_id]; 579 per_core = &cache_values.cores[cache_id];
638 580
639 if (counter_enabled[counter_id_0]) { 581 if (counter_enabled[counter_id_0] && prev_set[counter_id_0]) {
640 // Calculate and save src0's counter val0 582 // Calculate and save src0's counter val0
641 counter_dump[len++] = counter_key[counter_id_0]; 583 counter_dump[len++] = counter_key[counter_id_0];
642 counter_dump[len++] = get_difference(per_core->value0, counter_prev[counter_id_0]); 584 counter_dump[len++] = per_core->value0 - counter_prev[counter_id_0];
643 } 585 }
644 586
645 if (counter_enabled[counter_id_1]) { 587 if (counter_enabled[counter_id_1] && prev_set[counter_id_1]) {
646 // Calculate and save src1's counter val1 588 // Calculate and save src1's counter val1
647 counter_dump[len++] = counter_key[counter_id_1]; 589 counter_dump[len++] = counter_key[counter_id_1];
648 counter_dump[len++] = get_difference(per_core->value1, counter_prev[counter_id_1]); 590 counter_dump[len++] = per_core->value1 - counter_prev[counter_id_1];
649 } 591 }
650 592
651 // Save the previous values for the counters. 593 // Save the previous values for the counters.
652 counter_prev[counter_id_0] = per_core->value0; 594 counter_prev[counter_id_0] = per_core->value0;
595 prev_set[counter_id_0] = true;
653 counter_prev[counter_id_1] = per_core->value1; 596 counter_prev[counter_id_1] = per_core->value1;
597 prev_set[counter_id_1] = true;
654 } 598 }
655 } 599 }
656 600
@@ -709,6 +653,8 @@ int gator_events_mali_init(void)
709 653
710 pr_debug("gator: mali init\n"); 654 pr_debug("gator: mali init\n");
711 655
656 gator_mali_initialise_counters(mali_activity, ARRAY_SIZE(mali_activity));
657
712 for (cnt = 0; cnt < NUMBER_OF_EVENTS; cnt++) { 658 for (cnt = 0; cnt < NUMBER_OF_EVENTS; cnt++) {
713 counter_enabled[cnt] = 0; 659 counter_enabled[cnt] = 0;
714 counter_event[cnt] = 0; 660 counter_event[cnt] = 0;
diff --git a/driver/gator_events_mali_common.c b/driver/gator_events_mali_common.c
index dc58dcf..4f2cce4 100644
--- a/driver/gator_events_mali_common.c
+++ b/driver/gator_events_mali_common.c
@@ -8,26 +8,6 @@
8 */ 8 */
9#include "gator_events_mali_common.h" 9#include "gator_events_mali_common.h"
10 10
11static u32 gator_mali_get_id(void)
12{
13 return MALI_SUPPORT;
14}
15
16extern const char *gator_mali_get_mali_name(void)
17{
18 u32 id = gator_mali_get_id();
19
20 switch (id) {
21 case MALI_T6xx:
22 return "Mali-T6xx";
23 case MALI_4xx:
24 return "Mali-4xx";
25 default:
26 pr_debug("gator: Mali-T6xx: unknown Mali ID (%d)\n", id);
27 return "Mali-Unknown";
28 }
29}
30
31extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter, unsigned long *event) 11extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter, unsigned long *event)
32{ 12{
33 int err; 13 int err;
@@ -42,24 +22,31 @@ extern int gator_mali_create_file_system(const char *mali_name, const char *even
42 dir = gatorfs_mkdir(sb, root, buf); 22 dir = gatorfs_mkdir(sb, root, buf);
43 23
44 if (dir == NULL) { 24 if (dir == NULL) {
45 pr_debug("gator: Mali-T6xx: error creating file system for: %s (%s)", event_name, buf); 25 pr_debug("gator: %s: error creating file system for: %s (%s)", mali_name, event_name, buf);
46 return -1; 26 return -1;
47 } 27 }
48 28
49 err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled); 29 err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled);
50 if (err != 0) { 30 if (err != 0) {
51 pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ulong for: %s (%s)", event_name, buf); 31 pr_debug("gator: %s: error calling gatorfs_create_ulong for: %s (%s)", mali_name, event_name, buf);
52 return -1; 32 return -1;
53 } 33 }
54 err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key); 34 err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key);
55 if (err != 0) { 35 if (err != 0) {
56 pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf); 36 pr_debug("gator: %s: error calling gatorfs_create_ro_ulong for: %s (%s)", mali_name, event_name, buf);
57 return -1; 37 return -1;
58 } 38 }
39 if (counter->cores != -1) {
40 err = gatorfs_create_ro_ulong(sb, dir, "cores", &counter->cores);
41 if (err != 0) {
42 pr_debug("gator: %s: error calling gatorfs_create_ro_ulong for: %s (%s)", mali_name, event_name, buf);
43 return -1;
44 }
45 }
59 if (event != NULL) { 46 if (event != NULL) {
60 err = gatorfs_create_ulong(sb, dir, "event", event); 47 err = gatorfs_create_ulong(sb, dir, "event", event);
61 if (err != 0) { 48 if (err != 0) {
62 pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf); 49 pr_debug("gator: %s: error calling gatorfs_create_ro_ulong for: %s (%s)", mali_name, event_name, buf);
63 return -1; 50 return -1;
64 } 51 }
65 } 52 }
@@ -77,5 +64,6 @@ extern void gator_mali_initialise_counters(mali_counter counters[], unsigned int
77 64
78 counter->key = gator_events_get_key(); 65 counter->key = gator_events_get_key();
79 counter->enabled = 0; 66 counter->enabled = 0;
67 counter->cores = -1;
80 } 68 }
81} 69}
diff --git a/driver/gator_events_mali_common.h b/driver/gator_events_mali_common.h
index 41c2a3c..91d871b 100644
--- a/driver/gator_events_mali_common.h
+++ b/driver/gator_events_mali_common.h
@@ -18,10 +18,6 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <asm/io.h> 19#include <asm/io.h>
20 20
21/* Device codes for each known GPU */
22#define MALI_4xx (0x0b07)
23#define MALI_T6xx (0x0056)
24
25/* Ensure that MALI_SUPPORT has been defined to something. */ 21/* Ensure that MALI_SUPPORT has been defined to something. */
26#ifndef MALI_SUPPORT 22#ifndef MALI_SUPPORT
27#error MALI_SUPPORT not defined! 23#error MALI_SUPPORT not defined!
@@ -35,8 +31,12 @@
35 * Runtime state information for a counter. 31 * Runtime state information for a counter.
36 */ 32 */
37typedef struct { 33typedef struct {
38 unsigned long key; /* 'key' (a unique id set by gatord and returned by gator.ko) */ 34 // 'key' (a unique id set by gatord and returned by gator.ko)
39 unsigned long enabled; /* counter enable state */ 35 unsigned long key;
36 // counter enable state
37 unsigned long enabled;
38 // for activity counters, the number of cores, otherwise -1
39 unsigned long cores;
40} mali_counter; 40} mali_counter;
41 41
42/* 42/*
@@ -54,17 +54,9 @@ extern void _mali_profiling_control(unsigned int, unsigned int);
54extern void _mali_profiling_get_counters(unsigned int *, unsigned int *, unsigned int *, unsigned int *); 54extern void _mali_profiling_get_counters(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
55 55
56/** 56/**
57 * Returns a name which identifies the GPU type (eg Mali-4xx, Mali-T6xx).
58 *
59 * @return The name as a constant string.
60 */
61extern const char *gator_mali_get_mali_name(void);
62
63/**
64 * Creates a filesystem entry under /dev/gator relating to the specified event name and key, and 57 * Creates a filesystem entry under /dev/gator relating to the specified event name and key, and
65 * associate the key/enable values with this entry point. 58 * associate the key/enable values with this entry point.
66 * 59 *
67 * @param mali_name A name related to the type of GPU, obtained from a call to gator_mali_get_mali_name()
68 * @param event_name The name of the event. 60 * @param event_name The name of the event.
69 * @param sb Linux super block 61 * @param sb Linux super block
70 * @param root Directory under which the entry will be created. 62 * @param root Directory under which the entry will be created.
diff --git a/driver/gator_events_mali_t6xx.c b/driver/gator_events_mali_t6xx.c
index 76f14ee..e56ba84 100644
--- a/driver/gator_events_mali_t6xx.c
+++ b/driver/gator_events_mali_t6xx.c
@@ -32,6 +32,8 @@
32#error MALI_SUPPORT set to an invalid device code: expecting MALI_T6xx 32#error MALI_SUPPORT set to an invalid device code: expecting MALI_T6xx
33#endif 33#endif
34 34
35static const char mali_name[] = "Mali-T6xx";
36
35/* Counters for Mali-T6xx: 37/* Counters for Mali-T6xx:
36 * 38 *
37 * - Timeline events 39 * - Timeline events
@@ -292,7 +294,6 @@ static int create_files(struct super_block *sb, struct dentry *root)
292 * Create the filesystem for all events 294 * Create the filesystem for all events
293 */ 295 */
294 int counter_index = 0; 296 int counter_index = 0;
295 const char *mali_name = gator_mali_get_mali_name();
296 mali_profiling_control_type *mali_control; 297 mali_profiling_control_type *mali_control;
297 298
298 for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++) { 299 for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++) {
@@ -317,7 +318,7 @@ static int create_files(struct super_block *sb, struct dentry *root)
317 } 318 }
318 319
319 mali_control = symbol_get(_mali_profiling_control); 320 mali_control = symbol_get(_mali_profiling_control);
320 if (mali_control) { 321 if (mali_control) {
321 if (gator_mali_create_file_system(mali_name, "Filmstrip_cnt0", sb, root, &counters[FILMSTRIP], &filmstrip_event) != 0) { 322 if (gator_mali_create_file_system(mali_name, "Filmstrip_cnt0", sb, root, &counters[FILMSTRIP], &filmstrip_event) != 0) {
322 return -1; 323 return -1;
323 } 324 }
diff --git a/driver/gator_events_mali_t6xx_hw.c b/driver/gator_events_mali_t6xx_hw.c
index dfbc91f..3a072bb 100644
--- a/driver/gator_events_mali_t6xx_hw.c
+++ b/driver/gator_events_mali_t6xx_hw.c
@@ -16,7 +16,10 @@
16#include <asm/io.h> 16#include <asm/io.h>
17 17
18/* Mali T6xx DDK includes */ 18/* Mali T6xx DDK includes */
19#ifdef MALI_DIR_MIDGARD 19#if defined(MALI_SIMPLE_API)
20/* Header with wrapper functions to kbase structures and functions */
21#include "mali/mali_dd_gator_api.h"
22#elif defined(MALI_DIR_MIDGARD)
20/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/ 23/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/
21#include "mali_linux_trace.h" 24#include "mali_linux_trace.h"
22#include "mali_kbase.h" 25#include "mali_kbase.h"
@@ -28,37 +31,49 @@
28#include "kbase/src/linux/mali_kbase_mem_linux.h" 31#include "kbase/src/linux/mali_kbase_mem_linux.h"
29#endif 32#endif
30 33
31#include "gator_events_mali_common.h"
32
33/* If API version is not specified then assume API version 1. */ 34/* If API version is not specified then assume API version 1. */
34#ifndef MALI_DDK_GATOR_API_VERSION 35#ifndef MALI_DDK_GATOR_API_VERSION
35#define MALI_DDK_GATOR_API_VERSION 1 36#define MALI_DDK_GATOR_API_VERSION 1
36#endif 37#endif
37 38
38#if (MALI_DDK_GATOR_API_VERSION != 1) && (MALI_DDK_GATOR_API_VERSION != 2) 39#if (MALI_DDK_GATOR_API_VERSION != 1) && (MALI_DDK_GATOR_API_VERSION != 2) && (MALI_DDK_GATOR_API_VERSION != 3)
39#error MALI_DDK_GATOR_API_VERSION is invalid (must be 1 for r1/r2 DDK, or 2 for r3 DDK). 40#error MALI_DDK_GATOR_API_VERSION is invalid (must be 1 for r1/r2 DDK, or 2 for r3 DDK, or 3 for r? DDK).
40#endif 41#endif
41 42
43#include "gator_events_mali_common.h"
44
42/* 45/*
43 * Mali-T6xx 46 * Mali-T6xx
44 */ 47 */
48#if MALI_DDK_GATOR_API_VERSION == 3
49typedef uint32_t kbase_dd_instr_hwcnt_dump_irq_type(struct mali_dd_hwcnt_handles *);
50typedef uint32_t kbase_dd_instr_hwcnt_dump_complete_type(struct mali_dd_hwcnt_handles *, uint32_t *);
51typedef struct mali_dd_hwcnt_handles* mali_dd_hwcnt_init_type(struct mali_dd_hwcnt_info *);
52typedef void mali_dd_hwcnt_clear_type(struct mali_dd_hwcnt_info *, struct mali_dd_hwcnt_handles *);
53
54static kbase_dd_instr_hwcnt_dump_irq_type *kbase_dd_instr_hwcnt_dump_irq_symbol;
55static kbase_dd_instr_hwcnt_dump_complete_type *kbase_dd_instr_hwcnt_dump_complete_symbol;
56static mali_dd_hwcnt_init_type *mali_dd_hwcnt_init_symbol;
57static mali_dd_hwcnt_clear_type *mali_dd_hwcnt_clear_symbol;
58
59#else
45typedef struct kbase_device *kbase_find_device_type(int); 60typedef struct kbase_device *kbase_find_device_type(int);
46typedef kbase_context *kbase_create_context_type(kbase_device *); 61typedef struct kbase_context *kbase_create_context_type(struct kbase_device *);
47typedef void kbase_destroy_context_type(kbase_context *); 62typedef void kbase_destroy_context_type(struct kbase_context *);
48 63
49#if MALI_DDK_GATOR_API_VERSION == 1 64#if MALI_DDK_GATOR_API_VERSION == 1
50typedef void *kbase_va_alloc_type(kbase_context *, u32); 65typedef void *kbase_va_alloc_type(struct kbase_context *, u32);
51typedef void kbase_va_free_type(kbase_context *, void *); 66typedef void kbase_va_free_type(struct kbase_context *, void *);
52#elif MALI_DDK_GATOR_API_VERSION == 2 67#elif MALI_DDK_GATOR_API_VERSION == 2
53typedef void *kbase_va_alloc_type(kbase_context *, u32, kbase_hwc_dma_mapping * handle); 68typedef void *kbase_va_alloc_type(struct kbase_context *, u32, kbase_hwc_dma_mapping * handle);
54typedef void kbase_va_free_type(kbase_context *, kbase_hwc_dma_mapping * handle); 69typedef void kbase_va_free_type(struct kbase_context *, kbase_hwc_dma_mapping * handle);
55#endif 70#endif
56 71
57typedef mali_error kbase_instr_hwcnt_enable_type(kbase_context *, kbase_uk_hwcnt_setup *); 72typedef mali_error kbase_instr_hwcnt_enable_type(struct kbase_context *, struct kbase_uk_hwcnt_setup *);
58typedef mali_error kbase_instr_hwcnt_disable_type(kbase_context *); 73typedef mali_error kbase_instr_hwcnt_disable_type(struct kbase_context *);
59typedef mali_error kbase_instr_hwcnt_clear_type(kbase_context *); 74typedef mali_error kbase_instr_hwcnt_clear_type(struct kbase_context *);
60typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *); 75typedef mali_error kbase_instr_hwcnt_dump_irq_type(struct kbase_context *);
61typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *); 76typedef mali_bool kbase_instr_hwcnt_dump_complete_type(struct kbase_context *, mali_bool *);
62 77
63static kbase_find_device_type *kbase_find_device_symbol; 78static kbase_find_device_type *kbase_find_device_symbol;
64static kbase_create_context_type *kbase_create_context_symbol; 79static kbase_create_context_type *kbase_create_context_symbol;
@@ -70,6 +85,7 @@ static kbase_instr_hwcnt_dump_complete_type *kbase_instr_hwcnt_dump_complete_sym
70static kbase_instr_hwcnt_disable_type *kbase_instr_hwcnt_disable_symbol; 85static kbase_instr_hwcnt_disable_type *kbase_instr_hwcnt_disable_symbol;
71static kbase_va_free_type *kbase_va_free_symbol; 86static kbase_va_free_type *kbase_va_free_symbol;
72static kbase_destroy_context_type *kbase_destroy_context_symbol; 87static kbase_destroy_context_type *kbase_destroy_context_symbol;
88#endif
73 89
74static long shader_present_low = 0; 90static long shader_present_low = 0;
75 91
@@ -99,6 +115,8 @@ enum {
99 MMU_BLOCK 115 MMU_BLOCK
100}; 116};
101 117
118static const char mali_name[] = "Mali-T6xx";
119
102/* Counters for Mali-T6xx: 120/* Counters for Mali-T6xx:
103 * 121 *
104 * - HW counters, 4 blocks 122 * - HW counters, 4 blocks
@@ -381,6 +399,14 @@ static const char *const hardware_counter_names[] = {
381#define GET_HW_BLOCK(c) (((c) >> 6) & 0x3) 399#define GET_HW_BLOCK(c) (((c) >> 6) & 0x3)
382#define GET_COUNTER_OFFSET(c) ((c) & 0x3f) 400#define GET_COUNTER_OFFSET(c) ((c) & 0x3f)
383 401
402#if MALI_DDK_GATOR_API_VERSION == 3
403/* Opaque handles for kbase_context and kbase_hwc_dma_mapping */
404static struct mali_dd_hwcnt_handles *handles;
405
406/* Information about hardware counters */
407static struct mali_dd_hwcnt_info *in_out_info;
408
409#else
384/* Memory to dump hardware counters into */ 410/* Memory to dump hardware counters into */
385static void *kernel_dump_buffer; 411static void *kernel_dump_buffer;
386 412
@@ -390,14 +416,9 @@ kbase_hwc_dma_mapping kernel_dump_buffer_handle;
390#endif 416#endif
391 417
392/* kbase context and device */ 418/* kbase context and device */
393static kbase_context *kbcontext = NULL; 419static struct kbase_context *kbcontext = NULL;
394static struct kbase_device *kbdevice = NULL; 420static struct kbase_device *kbdevice = NULL;
395 421#endif
396/*
397 * The following function has no external prototype in older DDK revisions. When the DDK
398 * is updated then this should be removed.
399 */
400struct kbase_device *kbase_find_device(int minor);
401 422
402static volatile bool kbase_device_busy = false; 423static volatile bool kbase_device_busy = false;
403static unsigned int num_hardware_counters_enabled; 424static unsigned int num_hardware_counters_enabled;
@@ -412,6 +433,13 @@ static mali_counter counters[NUMBER_OF_HARDWARE_COUNTERS];
412 */ 433 */
413static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2]; 434static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2];
414 435
436extern mali_counter mali_activity[3];
437static const char* const mali_activity_names[] = {
438 "fragment",
439 "vertex",
440 "opencl",
441};
442
415#define SYMBOL_GET(FUNCTION, ERROR_COUNT) \ 443#define SYMBOL_GET(FUNCTION, ERROR_COUNT) \
416 if(FUNCTION ## _symbol) \ 444 if(FUNCTION ## _symbol) \
417 { \ 445 { \
@@ -431,8 +459,8 @@ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2];
431#define SYMBOL_CLEANUP(FUNCTION) \ 459#define SYMBOL_CLEANUP(FUNCTION) \
432 if(FUNCTION ## _symbol) \ 460 if(FUNCTION ## _symbol) \
433 { \ 461 { \
434 symbol_put(FUNCTION); \ 462 symbol_put(FUNCTION); \
435 FUNCTION ## _symbol = NULL; \ 463 FUNCTION ## _symbol = NULL; \
436 } 464 }
437 465
438/** 466/**
@@ -442,6 +470,12 @@ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2];
442static int init_symbols(void) 470static int init_symbols(void)
443{ 471{
444 int error_count = 0; 472 int error_count = 0;
473#if MALI_DDK_GATOR_API_VERSION == 3
474 SYMBOL_GET(kbase_dd_instr_hwcnt_dump_irq, error_count);
475 SYMBOL_GET(kbase_dd_instr_hwcnt_dump_complete, error_count);
476 SYMBOL_GET(mali_dd_hwcnt_init, error_count);
477 SYMBOL_GET(mali_dd_hwcnt_clear, error_count);
478#else
445 SYMBOL_GET(kbase_find_device, error_count); 479 SYMBOL_GET(kbase_find_device, error_count);
446 SYMBOL_GET(kbase_create_context, error_count); 480 SYMBOL_GET(kbase_create_context, error_count);
447 SYMBOL_GET(kbase_va_alloc, error_count); 481 SYMBOL_GET(kbase_va_alloc, error_count);
@@ -452,6 +486,7 @@ static int init_symbols(void)
452 SYMBOL_GET(kbase_instr_hwcnt_disable, error_count); 486 SYMBOL_GET(kbase_instr_hwcnt_disable, error_count);
453 SYMBOL_GET(kbase_va_free, error_count); 487 SYMBOL_GET(kbase_va_free, error_count);
454 SYMBOL_GET(kbase_destroy_context, error_count); 488 SYMBOL_GET(kbase_destroy_context, error_count);
489#endif
455 490
456 return error_count; 491 return error_count;
457} 492}
@@ -461,6 +496,12 @@ static int init_symbols(void)
461 */ 496 */
462static void clean_symbols(void) 497static void clean_symbols(void)
463{ 498{
499#if MALI_DDK_GATOR_API_VERSION == 3
500 SYMBOL_CLEANUP(kbase_dd_instr_hwcnt_dump_irq);
501 SYMBOL_CLEANUP(kbase_dd_instr_hwcnt_dump_complete);
502 SYMBOL_CLEANUP(mali_dd_hwcnt_init);
503 SYMBOL_CLEANUP(mali_dd_hwcnt_clear);
504#else
464 SYMBOL_CLEANUP(kbase_find_device); 505 SYMBOL_CLEANUP(kbase_find_device);
465 SYMBOL_CLEANUP(kbase_create_context); 506 SYMBOL_CLEANUP(kbase_create_context);
466 SYMBOL_CLEANUP(kbase_va_alloc); 507 SYMBOL_CLEANUP(kbase_va_alloc);
@@ -471,6 +512,7 @@ static void clean_symbols(void)
471 SYMBOL_CLEANUP(kbase_instr_hwcnt_disable); 512 SYMBOL_CLEANUP(kbase_instr_hwcnt_disable);
472 SYMBOL_CLEANUP(kbase_va_free); 513 SYMBOL_CLEANUP(kbase_va_free);
473 SYMBOL_CLEANUP(kbase_destroy_context); 514 SYMBOL_CLEANUP(kbase_destroy_context);
515#endif
474} 516}
475 517
476/** 518/**
@@ -502,11 +544,13 @@ static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time
502 544
503static int start(void) 545static int start(void)
504{ 546{
505 kbase_uk_hwcnt_setup setup; 547#if MALI_DDK_GATOR_API_VERSION < 3
548 struct kbase_uk_hwcnt_setup setup;
549 unsigned long long shadersPresent = 0;
550 u16 bitmask[] = { 0, 0, 0, 0 };
506 mali_error err; 551 mali_error err;
552#endif
507 int cnt; 553 int cnt;
508 u16 bitmask[] = { 0, 0, 0, 0 };
509 unsigned long long shadersPresent = 0;
510 554
511 /* Setup HW counters */ 555 /* Setup HW counters */
512 num_hardware_counters_enabled = 0; 556 num_hardware_counters_enabled = 0;
@@ -515,18 +559,52 @@ static int start(void)
515 pr_debug("Unexpected number of hardware counters defined: expecting 256, got %d\n", NUMBER_OF_HARDWARE_COUNTERS); 559 pr_debug("Unexpected number of hardware counters defined: expecting 256, got %d\n", NUMBER_OF_HARDWARE_COUNTERS);
516 } 560 }
517 561
562#if MALI_DDK_GATOR_API_VERSION == 3
563 /* Declare and initialise mali_dd_hwcnt_info structure */
564 in_out_info = kmalloc(sizeof(struct mali_dd_hwcnt_info), GFP_KERNEL);
565 for (cnt = 0; cnt < 4; cnt++){
566 in_out_info->bitmask[cnt] = 0;
567 }
568#endif
518 /* Calculate enable bitmasks based on counters_enabled array */ 569 /* Calculate enable bitmasks based on counters_enabled array */
519 for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) { 570 for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
520 const mali_counter *counter = &counters[cnt]; 571 const mali_counter *counter = &counters[cnt];
521 if (counter->enabled) { 572 if (counter->enabled) {
522 int block = GET_HW_BLOCK(cnt); 573 int block = GET_HW_BLOCK(cnt);
523 int enable_bit = GET_COUNTER_OFFSET(cnt) / 4; 574 int enable_bit = GET_COUNTER_OFFSET(cnt) / 4;
575#if MALI_DDK_GATOR_API_VERSION == 3
576 in_out_info->bitmask[block] |= (1 << enable_bit);
577#else
524 bitmask[block] |= (1 << enable_bit); 578 bitmask[block] |= (1 << enable_bit);
579#endif
525 pr_debug("gator: Mali-T6xx: hardware counter %s selected [%d]\n", hardware_counter_names[cnt], cnt); 580 pr_debug("gator: Mali-T6xx: hardware counter %s selected [%d]\n", hardware_counter_names[cnt], cnt);
526 num_hardware_counters_enabled++; 581 num_hardware_counters_enabled++;
527 } 582 }
528 } 583 }
529 584
585#if MALI_DDK_GATOR_API_VERSION == 3
586 /* Create a kbase context for HW counters */
587 if (num_hardware_counters_enabled > 0) {
588 if (init_symbols() > 0) {
589 clean_symbols();
590 /* No Mali driver code entrypoints found - not a fault. */
591 return 0;
592 }
593
594 handles = mali_dd_hwcnt_init_symbol(in_out_info);
595
596 if(handles == NULL) {
597 goto out;
598 }
599
600 /* See if we can get the number of shader cores */
601 shader_present_low = (unsigned long)in_out_info->shader_present_bitmap;
602
603 kbase_device_busy = false;
604 }
605
606 return 0;
607#else
530 /* Create a kbase context for HW counters */ 608 /* Create a kbase context for HW counters */
531 if (num_hardware_counters_enabled > 0) { 609 if (num_hardware_counters_enabled > 0) {
532 if (init_symbols() > 0) { 610 if (init_symbols() > 0) {
@@ -606,6 +684,7 @@ free_buffer:
606 684
607destroy_context: 685destroy_context:
608 kbase_destroy_context_symbol(kbcontext); 686 kbase_destroy_context_symbol(kbcontext);
687#endif
609 688
610out: 689out:
611 clean_symbols(); 690 clean_symbols();
@@ -615,7 +694,11 @@ out:
615static void stop(void) 694static void stop(void)
616{ 695{
617 unsigned int cnt; 696 unsigned int cnt;
618 kbase_context *temp_kbcontext; 697#if MALI_DDK_GATOR_API_VERSION == 3
698 struct mali_dd_hwcnt_handles *temp_hand;
699#else
700 struct kbase_context *temp_kbcontext;
701#endif
619 702
620 pr_debug("gator: Mali-T6xx: stop\n"); 703 pr_debug("gator: Mali-T6xx: stop\n");
621 704
@@ -625,6 +708,20 @@ static void stop(void)
625 } 708 }
626 709
627 /* Destroy the context for HW counters */ 710 /* Destroy the context for HW counters */
711#if MALI_DDK_GATOR_API_VERSION == 3
712 if (num_hardware_counters_enabled > 0 && handles != NULL) {
713 /*
714 * Set the global variable to NULL before destroying it, because
715 * other function will check this before using it.
716 */
717 temp_hand = handles;
718 handles = NULL;
719
720 mali_dd_hwcnt_clear_symbol(in_out_info, temp_hand);
721
722 kfree(in_out_info);
723
724#else
628 if (num_hardware_counters_enabled > 0 && kbcontext != NULL) { 725 if (num_hardware_counters_enabled > 0 && kbcontext != NULL) {
629 /* 726 /*
630 * Set the global variable to NULL before destroying it, because 727 * Set the global variable to NULL before destroying it, because
@@ -642,6 +739,7 @@ static void stop(void)
642#endif 739#endif
643 740
644 kbase_destroy_context_symbol(temp_kbcontext); 741 kbase_destroy_context_symbol(temp_kbcontext);
742#endif
645 743
646 pr_debug("gator: Mali-T6xx: hardware counters stopped\n"); 744 pr_debug("gator: Mali-T6xx: hardware counters stopped\n");
647 745
@@ -654,7 +752,7 @@ static int read(int **buffer)
654 int cnt; 752 int cnt;
655 int len = 0; 753 int len = 0;
656 u32 value = 0; 754 u32 value = 0;
657 mali_bool success; 755 uint32_t success;
658 756
659 struct timespec current_time; 757 struct timespec current_time;
660 static u32 prev_time_s = 0; 758 static u32 prev_time_s = 0;
@@ -686,12 +784,21 @@ static int read(int **buffer)
686 0x500 /* VITHAR_MEMORY_SYSTEM, Block 3 */ 784 0x500 /* VITHAR_MEMORY_SYSTEM, Block 3 */
687 }; 785 };
688 786
787#if MALI_DDK_GATOR_API_VERSION == 3
788 if (!handles) {
789 return -1;
790 }
791
792 /* Mali symbols can be called safely since a kbcontext is valid */
793 if (kbase_dd_instr_hwcnt_dump_complete_symbol(handles, &success) == MALI_TRUE) {
794#else
689 if (!kbcontext) { 795 if (!kbcontext) {
690 return -1; 796 return -1;
691 } 797 }
692 798
693 /* Mali symbols can be called safely since a kbcontext is valid */ 799 /* Mali symbols can be called safely since a kbcontext is valid */
694 if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE) { 800 if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE) {
801#endif
695 kbase_device_busy = false; 802 kbase_device_busy = false;
696 803
697 if (success == MALI_TRUE) { 804 if (success == MALI_TRUE) {
@@ -702,7 +809,11 @@ static int read(int **buffer)
702 const int block = GET_HW_BLOCK(cnt); 809 const int block = GET_HW_BLOCK(cnt);
703 const int counter_offset = GET_COUNTER_OFFSET(cnt); 810 const int counter_offset = GET_COUNTER_OFFSET(cnt);
704 811
812#if MALI_DDK_GATOR_API_VERSION == 3
813 const char* block_base_address = (char*)in_out_info->kernel_dump_buffer + vithar_blocks[block];
814#else
705 const char* block_base_address = (char*)kernel_dump_buffer + vithar_blocks[block]; 815 const char* block_base_address = (char*)kernel_dump_buffer + vithar_blocks[block];
816#endif
706 817
707 /* If counter belongs to shader block need to take into account all cores */ 818 /* If counter belongs to shader block need to take into account all cores */
708 if (block == SHADER_BLOCK) { 819 if (block == SHADER_BLOCK) {
@@ -741,7 +852,11 @@ static int read(int **buffer)
741 852
742 if (!kbase_device_busy) { 853 if (!kbase_device_busy) {
743 kbase_device_busy = true; 854 kbase_device_busy = true;
855#if MALI_DDK_GATOR_API_VERSION == 3
856 kbase_dd_instr_hwcnt_dump_irq_symbol(handles);
857#else
744 kbase_instr_hwcnt_dump_irq_symbol(kbcontext); 858 kbase_instr_hwcnt_dump_irq_symbol(kbcontext);
859#endif
745 } 860 }
746 } 861 }
747 862
@@ -760,7 +875,12 @@ static int create_files(struct super_block *sb, struct dentry *root)
760 * Create the filesystem for all events 875 * Create the filesystem for all events
761 */ 876 */
762 int counter_index = 0; 877 int counter_index = 0;
763 const char *mali_name = gator_mali_get_mali_name(); 878
879 for (event = 0; event < ARRAY_SIZE(mali_activity); event++) {
880 if (gator_mali_create_file_system(mali_name, mali_activity_names[event], sb, root, &mali_activity[event], NULL) != 0) {
881 return -1;
882 }
883 }
764 884
765 for (event = 0; event < NUMBER_OF_HARDWARE_COUNTERS; event++) { 885 for (event = 0; event < NUMBER_OF_HARDWARE_COUNTERS; event++) {
766 if (gator_mali_create_file_system(mali_name, hardware_counter_names[counter_index], sb, root, &counters[event], NULL) != 0) 886 if (gator_mali_create_file_system(mali_name, hardware_counter_names[counter_index], sb, root, &counters[event], NULL) != 0)
@@ -786,6 +906,7 @@ int gator_events_mali_t6xx_hw_init(void)
786 test_all_is_read_scheduled(); 906 test_all_is_read_scheduled();
787#endif 907#endif
788 908
909 gator_mali_initialise_counters(mali_activity, ARRAY_SIZE(mali_activity));
789 gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS); 910 gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS);
790 911
791 return gator_events_install(&gator_events_mali_t6xx_interface); 912 return gator_events_install(&gator_events_mali_t6xx_interface);
diff --git a/driver/gator_events_mmapped.c b/driver/gator_events_mmapped.c
index 3b248ec..5bc01c4 100644
--- a/driver/gator_events_mmapped.c
+++ b/driver/gator_events_mmapped.c
@@ -8,21 +8,25 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * Similar entries to those below must be present in the events.xml file. 10 * Similar entries to those below must be present in the events.xml file.
11 * To add them to the events.xml, create an events-mmap.xml with the 11 * To add them to the events.xml, create an events-mmap.xml with the
12 * following contents and rebuild gatord: 12 * following contents and rebuild gatord:
13 * 13 *
14 * <counter_set name="mmapped_cnt" count="3"/> 14 * <category name="mmapped">
15 * <category name="mmapped" counter_set="mmapped_cnt" per_cpu="no"> 15 * <event counter="mmapped_cnt0" title="Simulated1" name="Sine" display="maximum" class="absolute" description="Sort-of-sine"/>
16 * <event event="0x0" title="Simulated1" name="Sine" display="maximum" average_selection="yes" description="Sort-of-sine"/> 16 * <event counter="mmapped_cnt1" title="Simulated2" name="Triangle" display="maximum" class="absolute" description="Triangular wave"/>
17 * <event event="0x1" title="Simulated2" name="Triangle" display="maximum" average_selection="yes" description="Triangular wave"/> 17 * <event counter="mmapped_cnt2" title="Simulated3" name="PWM" display="maximum" class="absolute" description="PWM Signal"/>
18 * <event event="0x2" title="Simulated3" name="PWM" display="maximum" average_selection="yes" description="PWM Signal"/>
19 * </category> 18 * </category>
20 * 19 *
21 * When adding custom events, be sure do the following 20 * When adding custom events, be sure to do the following:
22 * - add any needed .c files to the gator driver Makefile 21 * - add any needed .c files to the gator driver Makefile
23 * - call gator_events_install in the events init function 22 * - call gator_events_install in the events init function
24 * - add the init function to GATOR_EVENTS_LIST in gator_main.c 23 * - add the init function to GATOR_EVENTS_LIST in gator_main.c
25 * - add a new events-*.xml file to the gator daemon and rebuild 24 * - add a new events-*.xml file to the gator daemon and rebuild
25 *
26 * Troubleshooting:
27 * - verify the new events are part of events.xml, which is created when building the daemon
28 * - verify the new events exist at /dev/gator/events/ once gatord is launched
29 * - verify the counter name in the XML matches the name at /dev/gator/events
26 */ 30 */
27 31
28#include <linux/init.h> 32#include <linux/init.h>
@@ -37,7 +41,6 @@ static int mmapped_global_enabled;
37 41
38static struct { 42static struct {
39 unsigned long enabled; 43 unsigned long enabled;
40 unsigned long event;
41 unsigned long key; 44 unsigned long key;
42} mmapped_counters[MMAPPED_COUNTERS_NUM]; 45} mmapped_counters[MMAPPED_COUNTERS_NUM];
43 46
@@ -47,7 +50,7 @@ static s64 prev_time;
47 50
48/* Adds mmapped_cntX directories and enabled, event, and key files to /dev/gator/events */ 51/* Adds mmapped_cntX directories and enabled, event, and key files to /dev/gator/events */
49static int gator_events_mmapped_create_files(struct super_block *sb, 52static int gator_events_mmapped_create_files(struct super_block *sb,
50 struct dentry *root) 53 struct dentry *root)
51{ 54{
52 int i; 55 int i;
53 56
@@ -61,8 +64,6 @@ static int gator_events_mmapped_create_files(struct super_block *sb,
61 return -1; 64 return -1;
62 gatorfs_create_ulong(sb, dir, "enabled", 65 gatorfs_create_ulong(sb, dir, "enabled",
63 &mmapped_counters[i].enabled); 66 &mmapped_counters[i].enabled);
64 gatorfs_create_ulong(sb, dir, "event",
65 &mmapped_counters[i].event);
66 gatorfs_create_ro_ulong(sb, dir, "key", 67 gatorfs_create_ro_ulong(sb, dir, "key",
67 &mmapped_counters[i].key); 68 &mmapped_counters[i].key);
68 } 69 }
@@ -177,8 +178,7 @@ static int gator_events_mmapped_read(int **buffer)
177 if (mmapped_counters[i].enabled) { 178 if (mmapped_counters[i].enabled) {
178 mmapped_buffer[len++] = mmapped_counters[i].key; 179 mmapped_buffer[len++] = mmapped_counters[i].key;
179 mmapped_buffer[len++] = 180 mmapped_buffer[len++] =
180 mmapped_simulate(mmapped_counters[i].event, 181 mmapped_simulate(i, delta_in_us);
181 delta_in_us);
182 } 182 }
183 } 183 }
184 184
diff --git a/driver/gator_events_perf_pmu.c b/driver/gator_events_perf_pmu.c
index 8b2d67a..06bbad5 100644
--- a/driver/gator_events_perf_pmu.c
+++ b/driver/gator_events_perf_pmu.c
@@ -470,10 +470,10 @@ static void gator_events_perf_pmu_cci_init(const int type)
470 470
471 switch (probe_cci_revision()) { 471 switch (probe_cci_revision()) {
472 case 0: 472 case 0:
473 cci_name = "cci-400"; 473 cci_name = "CCI_400";
474 break; 474 break;
475 case 1: 475 case 1:
476 cci_name = "cci-400-r1"; 476 cci_name = "CCI_400-r1";
477 break; 477 break;
478 default: 478 default:
479 pr_debug("gator: unrecognized cci-400 revision\n"); 479 pr_debug("gator: unrecognized cci-400 revision\n");
@@ -549,7 +549,7 @@ int gator_events_perf_pmu_init(void)
549 } 549 }
550 550
551 if (pe->pmu != NULL && type == pe->pmu->type) { 551 if (pe->pmu != NULL && type == pe->pmu->type) {
552 if (strcmp("CCI", pe->pmu->name) == 0 || strcmp("CCI_400", pe->pmu->name) == 0) { 552 if (strcmp("CCI", pe->pmu->name) == 0 || strcmp("CCI_400", pe->pmu->name) == 0 || strcmp("CCI_400-r1", pe->pmu->name) == 0) {
553 gator_events_perf_pmu_cci_init(type); 553 gator_events_perf_pmu_cci_init(type);
554 } else if ((gator_cpu = gator_find_cpu_by_pmu_name(pe->pmu->name)) != NULL) { 554 } else if ((gator_cpu = gator_find_cpu_by_pmu_name(pe->pmu->name)) != NULL) {
555 found_cpu = true; 555 found_cpu = true;
diff --git a/driver/gator_events_scorpion.c b/driver/gator_events_scorpion.c
index 8ca251a..2e5be8d 100644
--- a/driver/gator_events_scorpion.c
+++ b/driver/gator_events_scorpion.c
@@ -26,9 +26,9 @@ static int pmnc_counters;
26// ccnt reg 26// ccnt reg
27#define CCNT_REG (1 << 31) 27#define CCNT_REG (1 << 31)
28 28
29#define CCNT 0 29#define CCNT 0
30#define CNT0 1 30#define CNT0 1
31#define CNTMAX (4+1) 31#define CNTMAX (4+1)
32 32
33static unsigned long pmnc_enabled[CNTMAX]; 33static unsigned long pmnc_enabled[CNTMAX];
34static unsigned long pmnc_event[CNTMAX]; 34static unsigned long pmnc_event[CNTMAX];
diff --git a/driver/gator_events_threads.c b/driver/gator_events_threads.c
new file mode 100644
index 0000000..9de8586
--- /dev/null
+++ b/driver/gator_events_threads.c
@@ -0,0 +1,115 @@
1/*
2 * Sample activity provider
3 *
4 * Copyright (C) ARM Limited 2014. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * See gator_events_mmapped.c for additional directions and
11 * troubleshooting.
12 *
13 * For this sample to work these entries must be present in the
14 * events.xml file. So create an events-threads.xml in the gator
15 * daemon source directory with the following contents and rebuild
16 * gatord:
17 *
18 * <category name="threads">
19 * <event counter="Linux_threads" title="Linux" name="Threads" class="activity" activity1="odd" activity_color1="0x000000ff" rendering_type="bar" average_selection="yes" average_cores="yes" percentage="yes" description="Linux syscall activity"/>
20 * </category>
21 */
22
23#include <trace/events/sched.h>
24
25#include "gator.h"
26
27static ulong threads_enabled;
28static ulong threads_key;
29static ulong threads_cores;
30
31#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
32GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next))
33#else
34GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next))
35#endif
36{
37 int cpu = get_physical_cpu();
38 int pid = next->pid;
39 if (pid == 0) {
40 // idle
41 gator_marshal_activity_switch(cpu, threads_key, 0, 0);
42 } else if (pid & 1) {
43 // odd
44 gator_marshal_activity_switch(cpu, threads_key, 1, pid);
45 } else {
46 // even
47 //gator_marshal_activity_switch(cpu, threads_key, 2, current->pid);
48 // Multiple activities are not yet supported so emit idle
49 gator_marshal_activity_switch(cpu, threads_key, 0, 0);
50 }
51}
52
53// Adds Linux_threads directory and enabled, key, and cores files to /dev/gator/events
54static int gator_events_threads_create_files(struct super_block *sb, struct dentry *root)
55{
56 struct dentry *dir;
57
58 dir = gatorfs_mkdir(sb, root, "Linux_threads");
59 if (!dir) {
60 return -1;
61 }
62 gatorfs_create_ulong(sb, dir, "enabled", &threads_enabled);
63 gatorfs_create_ro_ulong(sb, dir, "key", &threads_key);
64 // Number of cores associated with this activity
65 gatorfs_create_ro_ulong(sb, dir, "cores", &threads_cores);
66
67 return 0;
68}
69
70static int gator_events_threads_start(void)
71{
72 int cpu;
73
74 if (threads_enabled) {
75 preempt_disable();
76 for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
77 gator_marshal_activity_switch(cpu, threads_key, 0, 0);
78 }
79 preempt_enable();
80
81 if (GATOR_REGISTER_TRACE(sched_switch)) {
82 goto fail_sched_switch;
83 }
84 }
85
86 return 0;
87
88fail_sched_switch:
89 return -1;
90}
91
92static void gator_events_threads_stop(void)
93{
94 if (threads_enabled) {
95 GATOR_UNREGISTER_TRACE(sched_switch);
96 }
97
98 threads_enabled = 0;
99}
100
101static struct gator_interface gator_events_threads_interface = {
102 .create_files = gator_events_threads_create_files,
103 .start = gator_events_threads_start,
104 .stop = gator_events_threads_stop,
105};
106
107// Must not be static. Ensure that this init function is added to GATOR_EVENTS_LIST in gator_main.c
108int __init gator_events_threads_init(void)
109{
110 threads_enabled = 0;
111 threads_key = gator_events_get_key();
112 threads_cores = nr_cpu_ids;
113
114 return gator_events_install(&gator_events_threads_interface);
115}
diff --git a/driver/gator_iks.c b/driver/gator_iks.c
index e90dfcc..9180b87 100644
--- a/driver/gator_iks.c
+++ b/driver/gator_iks.c
@@ -150,7 +150,7 @@ static void gator_send_iks_core_names(void)
150 preempt_disable(); 150 preempt_disable();
151 for (cpu = 0; cpu < nr_cpu_ids; ++cpu) { 151 for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
152 if (mpidr_cpus[cpu] != NULL) { 152 if (mpidr_cpus[cpu] != NULL) {
153 gator_send_core_name(cpu, mpidr_cpus[cpu]->cpuid, mpidr_cpus[cpu]); 153 gator_send_core_name(cpu, mpidr_cpus[cpu]->cpuid);
154 } 154 }
155 } 155 }
156 preempt_enable(); 156 preempt_enable();
diff --git a/driver/gator_main.c b/driver/gator_main.c
index 55772ef..0d867f2 100644
--- a/driver/gator_main.c
+++ b/driver/gator_main.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10// This version must match the gator daemon version 10// This version must match the gator daemon version
11#define PROTOCOL_VERSION 18 11#define PROTOCOL_VERSION 19
12static unsigned long gator_protocol_version = PROTOCOL_VERSION; 12static unsigned long gator_protocol_version = PROTOCOL_VERSION;
13 13
14#include <linux/slab.h> 14#include <linux/slab.h>
@@ -55,9 +55,9 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
55 55
56#if (GATOR_PERF_SUPPORT) && (!(GATOR_PERF_PMU_SUPPORT)) 56#if (GATOR_PERF_SUPPORT) && (!(GATOR_PERF_PMU_SUPPORT))
57#ifndef CONFIG_PERF_EVENTS 57#ifndef CONFIG_PERF_EVENTS
58#warning gator requires the kernel to have CONFIG_PERF_EVENTS defined to support pmu hardware counters 58#error gator requires the kernel to have CONFIG_PERF_EVENTS defined to support pmu hardware counters
59#elif !defined CONFIG_HW_PERF_EVENTS 59#elif !defined CONFIG_HW_PERF_EVENTS
60#warning gator requires the kernel to have CONFIG_HW_PERF_EVENTS defined to support pmu hardware counters 60#error gator requires the kernel to have CONFIG_HW_PERF_EVENTS defined to support pmu hardware counters
61#endif 61#endif
62#endif 62#endif
63 63
@@ -71,8 +71,8 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
71#define BLOCK_COUNTER_BUFFER_SIZE (128*1024) 71#define BLOCK_COUNTER_BUFFER_SIZE (128*1024)
72#define ANNOTATE_BUFFER_SIZE (128*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded 72#define ANNOTATE_BUFFER_SIZE (128*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded
73#define SCHED_TRACE_BUFFER_SIZE (128*1024) 73#define SCHED_TRACE_BUFFER_SIZE (128*1024)
74#define GPU_TRACE_BUFFER_SIZE (64*1024) // gpu trace counters have the core as part of the data and the core value in the frame header may be discarded
75#define IDLE_BUFFER_SIZE (32*1024) // idle counters have the core as part of the data and the core value in the frame header may be discarded 74#define IDLE_BUFFER_SIZE (32*1024) // idle counters have the core as part of the data and the core value in the frame header may be discarded
75#define ACTIVITY_BUFFER_SIZE (128*1024)
76 76
77#define NO_COOKIE 0U 77#define NO_COOKIE 0U
78#define UNRESOLVED_COOKIE ~0U 78#define UNRESOLVED_COOKIE ~0U
@@ -84,8 +84,8 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
84#define FRAME_BLOCK_COUNTER 5 84#define FRAME_BLOCK_COUNTER 5
85#define FRAME_ANNOTATE 6 85#define FRAME_ANNOTATE 6
86#define FRAME_SCHED_TRACE 7 86#define FRAME_SCHED_TRACE 7
87#define FRAME_GPU_TRACE 8
88#define FRAME_IDLE 9 87#define FRAME_IDLE 9
88#define FRAME_ACTIVITY 13
89 89
90#define MESSAGE_END_BACKTRACE 1 90#define MESSAGE_END_BACKTRACE 1
91 91
@@ -94,14 +94,9 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
94#define MESSAGE_THREAD_NAME 2 94#define MESSAGE_THREAD_NAME 2
95#define MESSAGE_LINK 4 95#define MESSAGE_LINK 4
96 96
97// GPU Trace Frame Messages
98#define MESSAGE_GPU_START 1
99#define MESSAGE_GPU_STOP 2
100
101// Scheduler Trace Frame Messages 97// Scheduler Trace Frame Messages
102#define MESSAGE_SCHED_SWITCH 1 98#define MESSAGE_SCHED_SWITCH 1
103#define MESSAGE_SCHED_EXIT 2 99#define MESSAGE_SCHED_EXIT 2
104#define MESSAGE_SCHED_START 3
105 100
106// Idle Frame Messages 101// Idle Frame Messages
107#define MESSAGE_IDLE_ENTER 1 102#define MESSAGE_IDLE_ENTER 1
@@ -111,6 +106,10 @@ static unsigned long gator_protocol_version = PROTOCOL_VERSION;
111#define MESSAGE_SUMMARY 1 106#define MESSAGE_SUMMARY 1
112#define MESSAGE_CORE_NAME 3 107#define MESSAGE_CORE_NAME 3
113 108
109// Activity Frame Messages
110#define MESSAGE_SWITCH 2
111#define MESSAGE_EXIT 3
112
114#define MAXSIZE_PACK32 5 113#define MAXSIZE_PACK32 5
115#define MAXSIZE_PACK64 10 114#define MAXSIZE_PACK64 10
116 115
@@ -132,8 +131,8 @@ enum {
132 BLOCK_COUNTER_BUF, 131 BLOCK_COUNTER_BUF,
133 ANNOTATE_BUF, 132 ANNOTATE_BUF,
134 SCHED_TRACE_BUF, 133 SCHED_TRACE_BUF,
135 GPU_TRACE_BUF,
136 IDLE_BUF, 134 IDLE_BUF,
135 ACTIVITY_BUF,
137 NUM_GATOR_BUFS 136 NUM_GATOR_BUFS
138}; 137};
139 138
@@ -175,6 +174,7 @@ static DEFINE_PER_CPU(u64, last_timestamp);
175 174
176static bool printed_monotonic_warning; 175static bool printed_monotonic_warning;
177 176
177static u32 gator_cpuids[NR_CPUS];
178static bool sent_core_name[NR_CPUS]; 178static bool sent_core_name[NR_CPUS];
179 179
180static DEFINE_PER_CPU(bool, in_scheduler_context); 180static DEFINE_PER_CPU(bool, in_scheduler_context);
@@ -226,6 +226,7 @@ static DEFINE_PER_CPU(u64, gator_buffer_commit_time);
226 GATOR_EVENT(gator_events_perf_pmu_init) \ 226 GATOR_EVENT(gator_events_perf_pmu_init) \
227 GATOR_EVENT(gator_events_sched_init) \ 227 GATOR_EVENT(gator_events_sched_init) \
228 GATOR_EVENT(gator_events_scorpion_init) \ 228 GATOR_EVENT(gator_events_scorpion_init) \
229 GATOR_EVENT(gator_events_threads_init) \
229 230
230#define GATOR_EVENT(EVENT_INIT) __weak int EVENT_INIT(void); 231#define GATOR_EVENT(EVENT_INIT) __weak int EVENT_INIT(void);
231GATOR_EVENTS_LIST 232GATOR_EVENTS_LIST
@@ -570,25 +571,37 @@ static void gator_timer_stop(void)
570 } 571 }
571} 572}
572 573
573#if defined(__arm__) || defined(__aarch64__) 574static void gator_send_core_name(const int cpu, const u32 cpuid)
574static void gator_send_core_name(int cpu, const u32 cpuid, const struct gator_cpu *const gator_cpu)
575{ 575{
576 const char *core_name = NULL; 576#if defined(__arm__) || defined(__aarch64__)
577 char core_name_buf[32]; 577 if (!sent_core_name[cpu] || (cpuid != gator_cpuids[cpu])) {
578 const struct gator_cpu *const gator_cpu = gator_find_cpu_by_cpuid(cpuid);
579 const char *core_name = NULL;
580 char core_name_buf[32];
578 581
579 if (!sent_core_name[cpu]) { 582 // Save off this cpuid
583 gator_cpuids[cpu] = cpuid;
580 if (gator_cpu != NULL) { 584 if (gator_cpu != NULL) {
581 core_name = gator_cpu->core_name; 585 core_name = gator_cpu->core_name;
582 } else { 586 } else {
583 snprintf(core_name_buf, sizeof(core_name_buf), "Unknown (0x%.3x)", cpuid); 587 if (cpuid == -1) {
588 snprintf(core_name_buf, sizeof(core_name_buf), "Unknown");
589 } else {
590 snprintf(core_name_buf, sizeof(core_name_buf), "Unknown (0x%.3x)", cpuid);
591 }
584 core_name = core_name_buf; 592 core_name = core_name_buf;
585 } 593 }
586 594
587 marshal_core_name(cpu, cpuid, core_name); 595 marshal_core_name(cpu, cpuid, core_name);
588 sent_core_name[cpu] = true; 596 sent_core_name[cpu] = true;
589 } 597 }
590}
591#endif 598#endif
599}
600
601static void gator_read_cpuid(void * arg)
602{
603 gator_cpuids[get_physical_cpu()] = gator_cpuid();
604}
592 605
593// This function runs in interrupt context and on the appropriate core 606// This function runs in interrupt context and on the appropriate core
594static void gator_timer_online(void *migrate) 607static void gator_timer_online(void *migrate)
@@ -598,6 +611,9 @@ static void gator_timer_online(void *migrate)
598 int *buffer; 611 int *buffer;
599 u64 time; 612 u64 time;
600 613
614 // Send what is currently running on this core
615 marshal_sched_trace_switch(current->pid, 0);
616
601 gator_trace_power_online(); 617 gator_trace_power_online();
602 618
603 // online any events and output counters 619 // online any events and output counters
@@ -617,12 +633,7 @@ static void gator_timer_online(void *migrate)
617 gator_hrtimer_online(); 633 gator_hrtimer_online();
618 } 634 }
619 635
620#if defined(__arm__) || defined(__aarch64__) 636 gator_send_core_name(cpu, gator_cpuid());
621 if (!sent_core_name[cpu]) {
622 const u32 cpuid = gator_cpuid();
623 gator_send_core_name(cpu, cpuid, gator_find_cpu_by_cpuid(cpuid));
624 }
625#endif
626} 637}
627 638
628// This function runs in interrupt context and may be running on a core other than core 'cpu' 639// This function runs in interrupt context and may be running on a core other than core 'cpu'
@@ -658,6 +669,13 @@ static int gator_timer_start(unsigned long sample_rate)
658 if (gator_hrtimer_init(sample_rate, gator_timer_interrupt) == -1) 669 if (gator_hrtimer_init(sample_rate, gator_timer_interrupt) == -1)
659 return -1; 670 return -1;
660 671
672 // Send off the previously saved cpuids
673 for_each_present_cpu(cpu) {
674 preempt_disable();
675 gator_send_core_name(cpu, gator_cpuids[cpu]);
676 preempt_enable();
677 }
678
661 gator_send_iks_core_names(); 679 gator_send_iks_core_names();
662 for_each_online_cpu(cpu) { 680 for_each_online_cpu(cpu) {
663 gator_timer_online_dispatch(lcpu_to_pcpu(cpu), false); 681 gator_timer_online_dispatch(lcpu_to_pcpu(cpu), false);
@@ -1009,12 +1027,12 @@ static int gator_op_setup(void)
1009 gator_buffer_size[SCHED_TRACE_BUF] = SCHED_TRACE_BUFFER_SIZE; 1027 gator_buffer_size[SCHED_TRACE_BUF] = SCHED_TRACE_BUFFER_SIZE;
1010 gator_buffer_mask[SCHED_TRACE_BUF] = SCHED_TRACE_BUFFER_SIZE - 1; 1028 gator_buffer_mask[SCHED_TRACE_BUF] = SCHED_TRACE_BUFFER_SIZE - 1;
1011 1029
1012 gator_buffer_size[GPU_TRACE_BUF] = GPU_TRACE_BUFFER_SIZE;
1013 gator_buffer_mask[GPU_TRACE_BUF] = GPU_TRACE_BUFFER_SIZE - 1;
1014
1015 gator_buffer_size[IDLE_BUF] = IDLE_BUFFER_SIZE; 1030 gator_buffer_size[IDLE_BUF] = IDLE_BUFFER_SIZE;
1016 gator_buffer_mask[IDLE_BUF] = IDLE_BUFFER_SIZE - 1; 1031 gator_buffer_mask[IDLE_BUF] = IDLE_BUFFER_SIZE - 1;
1017 1032
1033 gator_buffer_size[ACTIVITY_BUF] = ACTIVITY_BUFFER_SIZE;
1034 gator_buffer_mask[ACTIVITY_BUF] = ACTIVITY_BUFFER_SIZE - 1;
1035
1018 // Initialize percpu per buffer variables 1036 // Initialize percpu per buffer variables
1019 for (i = 0; i < NUM_GATOR_BUFS; i++) { 1037 for (i = 0; i < NUM_GATOR_BUFS; i++) {
1020 // Verify buffers are a power of 2 1038 // Verify buffers are a power of 2
@@ -1373,6 +1391,7 @@ static void gator_op_create_files(struct super_block *sb, struct dentry *root)
1373 GATOR_HANDLE_TRACEPOINT(mm_page_alloc); \ 1391 GATOR_HANDLE_TRACEPOINT(mm_page_alloc); \
1374 GATOR_HANDLE_TRACEPOINT(mm_page_free); \ 1392 GATOR_HANDLE_TRACEPOINT(mm_page_free); \
1375 GATOR_HANDLE_TRACEPOINT(mm_page_free_batched); \ 1393 GATOR_HANDLE_TRACEPOINT(mm_page_free_batched); \
1394 GATOR_HANDLE_TRACEPOINT(sched_process_exec); \
1376 GATOR_HANDLE_TRACEPOINT(sched_process_fork); \ 1395 GATOR_HANDLE_TRACEPOINT(sched_process_fork); \
1377 GATOR_HANDLE_TRACEPOINT(sched_process_free); \ 1396 GATOR_HANDLE_TRACEPOINT(sched_process_free); \
1378 GATOR_HANDLE_TRACEPOINT(sched_switch); \ 1397 GATOR_HANDLE_TRACEPOINT(sched_switch); \
@@ -1415,6 +1434,10 @@ static int __init gator_module_init(void)
1415 1434
1416 setup_timer(&gator_buffer_wake_up_timer, gator_buffer_wake_up, 0); 1435 setup_timer(&gator_buffer_wake_up_timer, gator_buffer_wake_up, 0);
1417 1436
1437 // Initialize the list of cpuids
1438 memset(gator_cpuids, -1, sizeof(gator_cpuids));
1439 on_each_cpu(gator_read_cpuid, NULL, 1);
1440
1418 return 0; 1441 return 0;
1419} 1442}
1420 1443
diff --git a/driver/gator_marshaling.c b/driver/gator_marshaling.c
index 18c890d..97b4ae6 100644
--- a/driver/gator_marshaling.c
+++ b/driver/gator_marshaling.c
@@ -231,77 +231,28 @@ static void marshal_event_single(int core, int key, int value)
231 // Check and commit; commit is set to occur once buffer is 3/4 full 231 // Check and commit; commit is set to occur once buffer is 3/4 full
232 buffer_check(cpu, COUNTER_BUF, time); 232 buffer_check(cpu, COUNTER_BUF, time);
233} 233}
234#endif
235 234
236#if defined(MALI_SUPPORT) 235static void marshal_event_single64(int core, int key, long long value)
237static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
238{ 236{
239 unsigned long cpu = get_physical_cpu(), flags; 237 unsigned long flags, cpu;
240 u64 time;
241
242 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
243 return;
244
245 local_irq_save(flags);
246 time = gator_get_time();
247 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
248 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
249 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time);
250 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
251 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
252 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
253 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
254 }
255 local_irq_restore(flags);
256 // Check and commit; commit is set to occur once buffer is 3/4 full
257 buffer_check(cpu, GPU_TRACE_BUF, time);
258}
259
260static void marshal_sched_gpu_stop(int unit, int core)
261{
262 unsigned long cpu = get_physical_cpu(), flags;
263 u64 time; 238 u64 time;
264 239
265 if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
266 return;
267
268 local_irq_save(flags); 240 local_irq_save(flags);
241 cpu = get_physical_cpu();
269 time = gator_get_time(); 242 time = gator_get_time();
270 if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) { 243 if (buffer_check_space(cpu, COUNTER_BUF, 2 * MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
271 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP); 244 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, time);
272 gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, time); 245 gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
273 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit); 246 gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
274 gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core); 247 gator_buffer_write_packed_int64(cpu, COUNTER_BUF, value);
275 } 248 }
276 local_irq_restore(flags); 249 local_irq_restore(flags);
277 // Check and commit; commit is set to occur once buffer is 3/4 full 250 // Check and commit; commit is set to occur once buffer is 3/4 full
278 buffer_check(cpu, GPU_TRACE_BUF, time); 251 buffer_check(cpu, COUNTER_BUF, time);
279} 252}
280#endif 253#endif
281 254
282static void marshal_sched_trace_start(int tgid, int pid, int cookie) 255static void marshal_sched_trace_switch(int pid, int state)
283{
284 unsigned long cpu = get_physical_cpu(), flags;
285 u64 time;
286
287 if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
288 return;
289
290 local_irq_save(flags);
291 time = gator_get_time();
292 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
293 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_START);
294 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
295 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
296 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
297 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
298 }
299 local_irq_restore(flags);
300 // Check and commit; commit is set to occur once buffer is 3/4 full
301 buffer_check(cpu, SCHED_TRACE_BUF, time);
302}
303
304static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
305{ 256{
306 unsigned long cpu = get_physical_cpu(), flags; 257 unsigned long cpu = get_physical_cpu(), flags;
307 u64 time; 258 u64 time;
@@ -314,9 +265,7 @@ static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
314 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) { 265 if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
315 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH); 266 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
316 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time); 267 gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
317 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
318 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid); 268 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
319 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
320 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state); 269 gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
321 } 270 }
322 local_irq_restore(flags); 271 local_irq_restore(flags);
@@ -381,3 +330,33 @@ static void marshal_core_name(const int core, const int cpuid, const char *name)
381 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time()); 330 gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
382} 331}
383#endif 332#endif
333
334static void marshal_activity_switch(int core, int key, int activity, int pid, int state)
335{
336 unsigned long cpu = get_physical_cpu(), flags;
337 u64 time;
338
339 if (!per_cpu(gator_buffer, cpu)[ACTIVITY_BUF])
340 return;
341
342 local_irq_save(flags);
343 time = gator_get_time();
344 if (buffer_check_space(cpu, ACTIVITY_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
345 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, MESSAGE_SWITCH);
346 gator_buffer_write_packed_int64(cpu, ACTIVITY_BUF, time);
347 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, core);
348 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, key);
349 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, activity);
350 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, pid);
351 gator_buffer_write_packed_int(cpu, ACTIVITY_BUF, state);
352 }
353 local_irq_restore(flags);
354 // Check and commit; commit is set to occur once buffer is 3/4 full
355 buffer_check(cpu, ACTIVITY_BUF, time);
356}
357
358void gator_marshal_activity_switch(int core, int key, int activity, int pid)
359{
360 // state is reserved for cpu use only
361 marshal_activity_switch(core, key, activity, pid, 0);
362}
diff --git a/driver/gator_trace_gpu.c b/driver/gator_trace_gpu.c
index 6afa548..a8b9e7d 100644
--- a/driver/gator_trace_gpu.c
+++ b/driver/gator_trace_gpu.c
@@ -44,21 +44,19 @@ enum {
44 NUMBER_OF_GPU_UNITS 44 NUMBER_OF_GPU_UNITS
45}; 45};
46 46
47#define MALI_4xx (0x0b07)
48#define MALI_T6xx (0x0056)
49
50#if defined(MALI_SUPPORT) 47#if defined(MALI_SUPPORT)
51 48
52struct mali_gpu_job { 49struct mali_activity {
50 int core;
51 int key;
53 int count; 52 int count;
54 int last_tgid; 53 int last_activity;
55 int last_pid; 54 int last_pid;
56 int last_job_id;
57}; 55};
58 56
59#define NUMBER_OF_GPU_CORES 16 57#define NUMBER_OF_GPU_CORES 16
60static struct mali_gpu_job mali_gpu_jobs[NUMBER_OF_GPU_UNITS][NUMBER_OF_GPU_CORES]; 58static struct mali_activity mali_activities[NUMBER_OF_GPU_UNITS*NUMBER_OF_GPU_CORES];
61static DEFINE_SPINLOCK(mali_gpu_jobs_lock); 59static DEFINE_SPINLOCK(mali_activities_lock);
62 60
63/* Only one event should be running on a unit and core at a time (ie, a start 61/* Only one event should be running on a unit and core at a time (ie, a start
64 * event can only be followed by a stop and vice versa), but because the kernel 62 * event can only be followed by a stop and vice versa), but because the kernel
@@ -66,52 +64,95 @@ static DEFINE_SPINLOCK(mali_gpu_jobs_lock);
66 * start1, start2, stop1, stop2. Change it back into start1, stop1, start2, 64 * start1, start2, stop1, stop2. Change it back into start1, stop1, start2,
67 * stop2 by queueing up start2 and releasing it when stop1 is received. 65 * stop2 by queueing up start2 and releasing it when stop1 is received.
68 */ 66 */
69static void mali_gpu_enqueue(int unit, int core, int tgid, int pid, int job_id) 67
68static int mali_activity_index(int core, int key)
69{
70 int i;
71
72 for (i = 0; i < ARRAY_SIZE(mali_activities); ++i) {
73 if ((mali_activities[i].core == core) && (mali_activities[i].key == key)) {
74 break;
75 }
76 if ((mali_activities[i].core == 0) && (mali_activities[i].key == 0)) {
77 mali_activities[i].core = core;
78 mali_activities[i].key = key;
79 break;
80 }
81 }
82 BUG_ON(i >= ARRAY_SIZE(mali_activities));
83
84 return i;
85}
86
87static void mali_activity_enqueue(int core, int key, int activity, int pid)
70{ 88{
89 int i;
71 int count; 90 int count;
72 91
73 spin_lock(&mali_gpu_jobs_lock); 92 spin_lock(&mali_activities_lock);
74 count = mali_gpu_jobs[unit][core].count; 93 i = mali_activity_index(core, key);
94
95 count = mali_activities[i].count;
75 BUG_ON(count < 0); 96 BUG_ON(count < 0);
76 ++mali_gpu_jobs[unit][core].count; 97 ++mali_activities[i].count;
77 if (count) { 98 if (count) {
78 mali_gpu_jobs[unit][core].last_tgid = tgid; 99 mali_activities[i].last_activity = activity;
79 mali_gpu_jobs[unit][core].last_pid = pid; 100 mali_activities[i].last_pid = pid;
80 mali_gpu_jobs[unit][core].last_job_id = job_id;
81 } 101 }
82 spin_unlock(&mali_gpu_jobs_lock); 102 spin_unlock(&mali_activities_lock);
83 103
84 if (!count) { 104 if (!count) {
85 marshal_sched_gpu_start(unit, core, tgid, pid/*, job_id*/); 105 gator_marshal_activity_switch(core, key, activity, pid);
86 } 106 }
87} 107}
88 108
89static void mali_gpu_stop(int unit, int core) 109static void mali_activity_stop(int core, int key)
90{ 110{
111 int i;
91 int count; 112 int count;
92 int last_tgid = 0; 113 int last_activity = 0;
93 int last_pid = 0; 114 int last_pid = 0;
94 //int last_job_id = 0;
95 115
96 spin_lock(&mali_gpu_jobs_lock); 116 spin_lock(&mali_activities_lock);
97 if (mali_gpu_jobs[unit][core].count == 0) { 117 i = mali_activity_index(core, key);
98 spin_unlock(&mali_gpu_jobs_lock); 118
119 if (mali_activities[i].count == 0) {
120 spin_unlock(&mali_activities_lock);
99 return; 121 return;
100 } 122 }
101 --mali_gpu_jobs[unit][core].count; 123 --mali_activities[i].count;
102 count = mali_gpu_jobs[unit][core].count; 124 count = mali_activities[i].count;
103 if (count) { 125 if (count) {
104 last_tgid = mali_gpu_jobs[unit][core].last_tgid; 126 last_activity = mali_activities[i].last_activity;
105 last_pid = mali_gpu_jobs[unit][core].last_pid; 127 last_pid = mali_activities[i].last_pid;
106 //last_job_id = mali_gpu_jobs[unit][core].last_job_id;
107 } 128 }
108 spin_unlock(&mali_gpu_jobs_lock); 129 spin_unlock(&mali_activities_lock);
109 130
110 marshal_sched_gpu_stop(unit, core); 131 gator_marshal_activity_switch(core, key, 0, 0);
111 if (count) { 132 if (count) {
112 marshal_sched_gpu_start(unit, core, last_tgid, last_pid/*, last_job_id*/); 133 gator_marshal_activity_switch(core, key, last_activity, last_pid);
113 } 134 }
114} 135}
136
137void mali_activity_clear(mali_counter mali_activity[], size_t mali_activity_size)
138{
139 int activity;
140 int cores;
141 int core;
142
143 for (activity = 0; activity < mali_activity_size; ++activity) {
144 cores = mali_activity[activity].cores;
145 if (cores < 0) {
146 cores = 1;
147 }
148 for (core = 0; core < cores; ++core) {
149 if (mali_activity[activity].enabled) {
150 gator_marshal_activity_switch(core, mali_activity[activity].key, 0, 0);
151 }
152 }
153 }
154}
155
115#endif 156#endif
116 157
117#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx) 158#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
@@ -142,6 +183,8 @@ enum {
142 EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1, 183 EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
143}; 184};
144 185
186mali_counter mali_activity[2];
187
145GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned int d2, unsigned int d3, unsigned int d4)) 188GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned int d2, unsigned int d3, unsigned int d4))
146{ 189{
147 unsigned int component, state; 190 unsigned int component, state;
@@ -154,18 +197,26 @@ GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned
154 case EVENT_TYPE_START: 197 case EVENT_TYPE_START:
155 if (component == EVENT_CHANNEL_VP0) { 198 if (component == EVENT_CHANNEL_VP0) {
156 /* tgid = d0; pid = d1; */ 199 /* tgid = d0; pid = d1; */
157 mali_gpu_enqueue(GPU_UNIT_VP, 0, d0, d1, 0); 200 if (mali_activity[1].enabled) {
201 mali_activity_enqueue(0, mali_activity[1].key, 1, d1);
202 }
158 } else if (component >= EVENT_CHANNEL_FP0 && component <= EVENT_CHANNEL_FP7) { 203 } else if (component >= EVENT_CHANNEL_FP0 && component <= EVENT_CHANNEL_FP7) {
159 /* tgid = d0; pid = d1; */ 204 /* tgid = d0; pid = d1; */
160 mali_gpu_enqueue(GPU_UNIT_FP, component - EVENT_CHANNEL_FP0, d0, d1, 0); 205 if (mali_activity[0].enabled) {
206 mali_activity_enqueue(component - EVENT_CHANNEL_FP0, mali_activity[0].key, 1, d1);
207 }
161 } 208 }
162 break; 209 break;
163 210
164 case EVENT_TYPE_STOP: 211 case EVENT_TYPE_STOP:
165 if (component == EVENT_CHANNEL_VP0) { 212 if (component == EVENT_CHANNEL_VP0) {
166 mali_gpu_stop(GPU_UNIT_VP, 0); 213 if (mali_activity[1].enabled) {
214 mali_activity_stop(0, mali_activity[1].key);
215 }
167 } else if (component >= EVENT_CHANNEL_FP0 && component <= EVENT_CHANNEL_FP7) { 216 } else if (component >= EVENT_CHANNEL_FP0 && component <= EVENT_CHANNEL_FP7) {
168 mali_gpu_stop(GPU_UNIT_FP, component - EVENT_CHANNEL_FP0); 217 if (mali_activity[0].enabled) {
218 mali_activity_stop(component - EVENT_CHANNEL_FP0, mali_activity[0].key);
219 }
169 } 220 }
170 break; 221 break;
171 222
@@ -186,6 +237,9 @@ GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned
186#endif 237#endif
187 238
188#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx) 239#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx)
240
241mali_counter mali_activity[3];
242
189#if defined(MALI_JOB_SLOTS_EVENT_CHANGED) 243#if defined(MALI_JOB_SLOTS_EVENT_CHANGED)
190GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigned int tgid, unsigned int pid, unsigned char job_id)) 244GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigned int tgid, unsigned int pid, unsigned char job_id))
191#else 245#else
@@ -217,16 +271,16 @@ GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigne
217 if (unit != GPU_UNIT_NONE) { 271 if (unit != GPU_UNIT_NONE) {
218 switch (state) { 272 switch (state) {
219 case EVENT_TYPE_START: 273 case EVENT_TYPE_START:
220 mali_gpu_enqueue(unit, 0, tgid, (pid != 0 ? pid : tgid), job_id); 274 if (mali_activity[component].enabled) {
275 mali_activity_enqueue(0, mali_activity[component].key, 1, (pid != 0 ? pid : tgid));
276 }
221 break; 277 break;
222 case EVENT_TYPE_STOP: 278 case EVENT_TYPE_STOP:
223 mali_gpu_stop(unit, 0); 279 default: // Some jobs can be soft-stopped, so ensure that this terminates the activity trace.
280 if (mali_activity[component].enabled) {
281 mali_activity_stop(0, mali_activity[component].key);
282 }
224 break; 283 break;
225 default:
226 /*
227 * Some jobs can be soft-stopped, so ensure that this terminates the activity trace.
228 */
229 mali_gpu_stop(unit, 0);
230 } 284 }
231 } 285 }
232} 286}
@@ -240,17 +294,19 @@ static int gator_trace_gpu_start(void)
240 */ 294 */
241 295
242#if defined(MALI_SUPPORT) 296#if defined(MALI_SUPPORT)
243 memset(&mali_gpu_jobs, 0, sizeof(mali_gpu_jobs)); 297 memset(&mali_activities, 0, sizeof(mali_activities));
244#endif 298#endif
245 mali_timeline_trace_registered = mali_job_slots_trace_registered = 0; 299 mali_timeline_trace_registered = mali_job_slots_trace_registered = 0;
246 300
247#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx) 301#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
302 mali_activity_clear(mali_activity, ARRAY_SIZE(mali_activity));
248 if (!GATOR_REGISTER_TRACE(mali_timeline_event)) { 303 if (!GATOR_REGISTER_TRACE(mali_timeline_event)) {
249 mali_timeline_trace_registered = 1; 304 mali_timeline_trace_registered = 1;
250 } 305 }
251#endif 306#endif
252 307
253#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx) 308#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx)
309 mali_activity_clear(mali_activity, ARRAY_SIZE(mali_activity));
254 if (!GATOR_REGISTER_TRACE(mali_job_slots_event)) { 310 if (!GATOR_REGISTER_TRACE(mali_job_slots_event)) {
255 mali_job_slots_trace_registered = 1; 311 mali_job_slots_trace_registered = 1;
256 } 312 }
diff --git a/driver/gator_trace_power.c b/driver/gator_trace_power.c
index 1895bb9..f2754b1 100644
--- a/driver/gator_trace_power.c
+++ b/driver/gator_trace_power.c
@@ -75,7 +75,7 @@ static int gator_trace_power_create_files(struct super_block *sb, struct dentry
75GATOR_DEFINE_PROBE(cpu_frequency, TP_PROTO(unsigned int frequency, unsigned int cpu)) 75GATOR_DEFINE_PROBE(cpu_frequency, TP_PROTO(unsigned int frequency, unsigned int cpu))
76{ 76{
77 cpu = lcpu_to_pcpu(cpu); 77 cpu = lcpu_to_pcpu(cpu);
78 marshal_event_single(cpu, power_cpu_key[POWER_CPU_FREQ], frequency * 1000); 78 marshal_event_single64(cpu, power_cpu_key[POWER_CPU_FREQ], frequency * 1000L);
79} 79}
80 80
81GATOR_DEFINE_PROBE(cpu_idle, TP_PROTO(unsigned int state, unsigned int cpu)) 81GATOR_DEFINE_PROBE(cpu_idle, TP_PROTO(unsigned int state, unsigned int cpu))
@@ -109,7 +109,7 @@ static void gator_trace_power_online(void)
109 int pcpu = get_physical_cpu(); 109 int pcpu = get_physical_cpu();
110 int lcpu = get_logical_cpu(); 110 int lcpu = get_logical_cpu();
111 if (power_cpu_enabled[POWER_CPU_FREQ]) { 111 if (power_cpu_enabled[POWER_CPU_FREQ]) {
112 marshal_event_single(pcpu, power_cpu_key[POWER_CPU_FREQ], cpufreq_quick_get(lcpu) * 1000); 112 marshal_event_single64(pcpu, power_cpu_key[POWER_CPU_FREQ], cpufreq_quick_get(lcpu) * 1000L);
113 } 113 }
114} 114}
115 115
diff --git a/driver/gator_trace_sched.c b/driver/gator_trace_sched.c
index 52990e9..6550086 100644
--- a/driver/gator_trace_sched.c
+++ b/driver/gator_trace_sched.c
@@ -114,7 +114,7 @@ static void collect_counters(u64 time, struct task_struct *task)
114 114
115 // Commit buffers on timeout 115 // Commit buffers on timeout
116 if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) { 116 if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) {
117 static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF }; 117 static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF, ACTIVITY_BUF };
118 int i; 118 int i;
119 119
120 for (i = 0; i < ARRAY_SIZE(buftypes); ++i) { 120 for (i = 0; i < ARRAY_SIZE(buftypes); ++i) {
@@ -137,35 +137,44 @@ static void collect_counters(u64 time, struct task_struct *task)
137// special case used during a suspend of the system 137// special case used during a suspend of the system
138static void trace_sched_insert_idle(void) 138static void trace_sched_insert_idle(void)
139{ 139{
140 marshal_sched_trace_switch(0, 0, 0, 0); 140 marshal_sched_trace_switch(0, 0);
141} 141}
142 142
143GATOR_DEFINE_PROBE(sched_process_fork, TP_PROTO(struct task_struct *parent, struct task_struct *child)) 143static void gator_trace_emit_link(struct task_struct *p)
144{ 144{
145 int cookie; 145 int cookie;
146 int cpu = get_physical_cpu(); 146 int cpu = get_physical_cpu();
147 147
148 cookie = get_exec_cookie(cpu, child); 148 cookie = get_exec_cookie(cpu, p);
149 emit_pid_name(child); 149 emit_pid_name(p);
150 150
151 marshal_sched_trace_start(child->tgid, child->pid, cookie); 151 marshal_link(cookie, p->tgid, p->pid);
152} 152}
153 153
154GATOR_DEFINE_PROBE(sched_process_fork, TP_PROTO(struct task_struct *parent, struct task_struct *child))
155{
156 gator_trace_emit_link(child);
157}
158
159#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
160GATOR_DEFINE_PROBE(sched_process_exec, TP_PROTO(struct task_struct *p, pid_t old_pid, struct linux_binprm *bprm))
161{
162 gator_trace_emit_link(p);
163}
164#endif
165
154#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) 166#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
155GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next)) 167GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next))
156#else 168#else
157GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next)) 169GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next))
158#endif 170#endif
159{ 171{
160 int cookie;
161 int state; 172 int state;
162 int cpu = get_physical_cpu(); 173 int cpu = get_physical_cpu();
163 174
164 per_cpu(in_scheduler_context, cpu) = true; 175 per_cpu(in_scheduler_context, cpu) = true;
165 176
166 // do as much work as possible before disabling interrupts 177 // do as much work as possible before disabling interrupts
167 cookie = get_exec_cookie(cpu, next);
168 emit_pid_name(next);
169 if (prev->state == TASK_RUNNING) { 178 if (prev->state == TASK_RUNNING) {
170 state = STATE_CONTENTION; 179 state = STATE_CONTENTION;
171 } else if (prev->in_iowait) { 180 } else if (prev->in_iowait) {
@@ -178,7 +187,10 @@ GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_
178 collect_counters(gator_get_time(), prev); 187 collect_counters(gator_get_time(), prev);
179 per_cpu(collecting, cpu) = 0; 188 per_cpu(collecting, cpu) = 0;
180 189
181 marshal_sched_trace_switch(next->tgid, next->pid, cookie, state); 190#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
191 gator_trace_emit_link(next);
192#endif
193 marshal_sched_trace_switch(next->pid, state);
182 194
183 per_cpu(in_scheduler_context, cpu) = false; 195 per_cpu(in_scheduler_context, cpu) = false;
184} 196}
@@ -199,6 +211,10 @@ static int register_scheduler_tracepoints(void)
199 // register tracepoints 211 // register tracepoints
200 if (GATOR_REGISTER_TRACE(sched_process_fork)) 212 if (GATOR_REGISTER_TRACE(sched_process_fork))
201 goto fail_sched_process_fork; 213 goto fail_sched_process_fork;
214#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
215 if (GATOR_REGISTER_TRACE(sched_process_exec))
216 goto fail_sched_process_exec;
217#endif
202 if (GATOR_REGISTER_TRACE(sched_switch)) 218 if (GATOR_REGISTER_TRACE(sched_switch))
203 goto fail_sched_switch; 219 goto fail_sched_switch;
204 if (GATOR_REGISTER_TRACE(sched_process_free)) 220 if (GATOR_REGISTER_TRACE(sched_process_free))
@@ -216,15 +232,42 @@ fail_sched_process_free:
216 GATOR_UNREGISTER_TRACE(sched_switch); 232 GATOR_UNREGISTER_TRACE(sched_switch);
217fail_sched_switch: 233fail_sched_switch:
218 GATOR_UNREGISTER_TRACE(sched_process_fork); 234 GATOR_UNREGISTER_TRACE(sched_process_fork);
235#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
236fail_sched_process_exec:
237 GATOR_UNREGISTER_TRACE(sched_process_exec);
238#endif
219fail_sched_process_fork: 239fail_sched_process_fork:
220 pr_err("gator: tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); 240 pr_err("gator: tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n");
221 241
222 return -1; 242 return -1;
223} 243}
224 244
245static void unregister_scheduler_tracepoints(void)
246{
247 GATOR_UNREGISTER_TRACE(sched_process_fork);
248#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
249 GATOR_UNREGISTER_TRACE(sched_process_exec);
250#endif
251 GATOR_UNREGISTER_TRACE(sched_switch);
252 GATOR_UNREGISTER_TRACE(sched_process_free);
253 pr_debug("gator: unregistered tracepoints\n");
254}
255
256static void gator_trace_sched_stop(void)
257{
258 int cpu;
259
260 unregister_scheduler_tracepoints();
261
262 for_each_present_cpu(cpu) {
263 kfree(per_cpu(taskname_keys, cpu));
264 }
265}
266
225static int gator_trace_sched_start(void) 267static int gator_trace_sched_start(void)
226{ 268{
227 int cpu, size; 269 int cpu, size;
270 int ret;
228 271
229 for_each_present_cpu(cpu) { 272 for_each_present_cpu(cpu) {
230 size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t); 273 size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t);
@@ -234,7 +277,9 @@ static int gator_trace_sched_start(void)
234 memset(per_cpu(taskname_keys, cpu), 0, size); 277 memset(per_cpu(taskname_keys, cpu), 0, size);
235 } 278 }
236 279
237 return register_scheduler_tracepoints(); 280 ret = register_scheduler_tracepoints();
281
282 return ret;
238} 283}
239 284
240static void gator_trace_sched_offline(void) 285static void gator_trace_sched_offline(void)
@@ -242,24 +287,6 @@ static void gator_trace_sched_offline(void)
242 trace_sched_insert_idle(); 287 trace_sched_insert_idle();
243} 288}
244 289
245static void unregister_scheduler_tracepoints(void)
246{
247 GATOR_UNREGISTER_TRACE(sched_process_fork);
248 GATOR_UNREGISTER_TRACE(sched_switch);
249 GATOR_UNREGISTER_TRACE(sched_process_free);
250 pr_debug("gator: unregistered tracepoints\n");
251}
252
253static void gator_trace_sched_stop(void)
254{
255 int cpu;
256 unregister_scheduler_tracepoints();
257
258 for_each_present_cpu(cpu) {
259 kfree(per_cpu(taskname_keys, cpu));
260 }
261}
262
263static void gator_trace_sched_init(void) 290static void gator_trace_sched_init(void)
264{ 291{
265 int i; 292 int i;
diff --git a/driver/mali/mali_dd_gator_api.h b/driver/mali/mali_dd_gator_api.h
new file mode 100644
index 0000000..104b34f
--- /dev/null
+++ b/driver/mali/mali_dd_gator_api.h
@@ -0,0 +1,40 @@
1#if !defined(MALI_DDK_GATOR_API_VERSION)
2 #define MALI_DDK_GATOR_API_VERSION 3
3#endif
4#if !defined(MALI_TRUE)
5 #define MALI_TRUE ((unsigned int)1)
6#endif
7
8#if !defined(MALI_FALSE)
9 #define MALI_FALSE ((unsigned int)0)
10#endif
11
12struct mali_dd_hwcnt_info {
13
14 /* Passed from Gator to kbase */
15 //u32 in_mali_dd_hwcnt_version;
16 unsigned short int bitmask[4];
17
18 /* Passed from kbase to Gator */
19
20 /* ptr to counter dump memory */
21 void *kernel_dump_buffer;
22
23 /* size of counter dump memory */
24 unsigned int size;
25
26 unsigned int gpu_id;
27
28 unsigned int nr_cores;
29
30 unsigned int nr_core_groups;
31
32 /* The cached present bitmaps - these are the same as the corresponding hardware registers*/
33 unsigned long int shader_present_bitmap;
34};
35
36struct mali_dd_hwcnt_handles;
37extern struct mali_dd_hwcnt_handles* mali_dd_hwcnt_init(struct mali_dd_hwcnt_info *in_out_info);
38extern void mali_dd_hwcnt_clear(struct mali_dd_hwcnt_info *in_out_info, struct mali_dd_hwcnt_handles *opaque_handles);
39extern unsigned int kbase_dd_instr_hwcnt_dump_complete(struct mali_dd_hwcnt_handles *opaque_handles, unsigned int * const success);
40extern unsigned int kbase_dd_instr_hwcnt_dump_irq(struct mali_dd_hwcnt_handles *opaque_handles);
diff --git a/driver/mali_t6xx.mk b/driver/mali_t6xx.mk
index 059d47a..fa7571d 100644
--- a/driver/mali_t6xx.mk
+++ b/driver/mali_t6xx.mk
@@ -21,6 +21,10 @@ OSK_DIR = $(DDK_DIR)/drivers/gpu/arm/midgard/osk
21EXTRA_CFLAGS += -DMALI_DIR_MIDGARD=1 21EXTRA_CFLAGS += -DMALI_DIR_MIDGARD=1
22endif 22endif
23 23
24ifneq ($(wildcard $(DDK_DIR)/drivers/gpu/arm/midgard/mali_dd_gator_api.h),)
25EXTRA_CFLAGS += -DMALI_SIMPLE_API=1
26endif
27
24UMP_DIR = $(DDK_DIR)/include/linux 28UMP_DIR = $(DDK_DIR)/include/linux
25 29
26# Include directories in the DDK 30# Include directories in the DDK