summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Medhurst2013-01-14 02:34:37 -0600
committerJon Medhurst2013-01-15 05:01:37 -0600
commit10443d8e335e2ae4bb73d62f2e60484122fc6769 (patch)
tree8cc885bc69817dac112793467af0e37d7af5298c
parentee4f56e0d75f42583505dd338d1b91e67ff0ab53 (diff)
downloadarm-ds5-gator-10443d8e335e2ae4bb73d62f2e60484122fc6769.tar.gz
arm-ds5-gator-10443d8e335e2ae4bb73d62f2e60484122fc6769.tar.xz
arm-ds5-gator-10443d8e335e2ae4bb73d62f2e60484122fc6769.zip
gator: Version 5.13
Signed-off-by: Jon Medhurst <tixy@linaro.org>
-rw-r--r--daemon/Android.mk80
-rw-r--r--daemon/CapturedXML.cpp41
-rw-r--r--daemon/CapturedXML.h2
-rw-r--r--daemon/Collector.cpp2
-rw-r--r--daemon/ConfigurationXML.cpp8
-rw-r--r--daemon/Fifo.cpp16
-rw-r--r--daemon/Fifo.h12
-rw-r--r--daemon/LocalCapture.cpp4
-rw-r--r--daemon/Logging.h2
-rw-r--r--daemon/Makefile42
-rw-r--r--daemon/OlySocket.cpp362
-rw-r--r--daemon/OlySocket.h40
-rw-r--r--daemon/OlyUtility.cpp361
-rw-r--r--daemon/OlyUtility.h28
-rw-r--r--daemon/Sender.cpp4
-rw-r--r--daemon/SessionData.cpp1
-rw-r--r--daemon/SessionData.h2
-rw-r--r--daemon/SessionXML.cpp2
-rw-r--r--daemon/StreamlineSetup.cpp2
-rw-r--r--daemon/escape.c63
-rw-r--r--daemon/events-Cortex-A15.xml2
-rw-r--r--daemon/events-Cortex-A53.xml171
-rw-r--r--daemon/events-Cortex-A57.xml171
-rw-r--r--daemon/events-Cortex-A7.xml2
-rw-r--r--daemon/events-Cortex-A9.xml12
-rw-r--r--daemon/events-Linux.xml4
-rw-r--r--daemon/events-Mali-400.xml8
-rw-r--r--daemon/events-Mali-T6xx.xml12
-rw-r--r--daemon/events-Mali-T6xx_hw.xml8
-rw-r--r--daemon/events-ScorpionMP.xml2
-rw-r--r--daemon/main.cpp9
-rw-r--r--driver/Makefile2
-rw-r--r--driver/gator.h52
-rw-r--r--driver/gator_annotate.c17
-rw-r--r--driver/gator_annotate_kernel.c132
-rw-r--r--driver/gator_backtrace.c36
-rw-r--r--driver/gator_cookies.c105
-rw-r--r--driver/gator_events_armv6.c6
-rw-r--r--driver/gator_events_armv7.c18
-rw-r--r--driver/gator_events_block.c5
-rw-r--r--driver/gator_events_irq.c11
-rw-r--r--driver/gator_events_l2c-310.c18
-rw-r--r--driver/gator_events_mali_400.c1009
-rw-r--r--driver/gator_events_mali_common.c90
-rw-r--r--driver/gator_events_mali_common.h14
-rw-r--r--driver/gator_events_mali_t6xx.c716
-rw-r--r--driver/gator_events_mali_t6xx_hw.c1007
-rw-r--r--driver/gator_events_mali_t6xx_hw_test.c20
-rw-r--r--driver/gator_events_meminfo.c14
-rw-r--r--driver/gator_events_mmaped.c34
-rw-r--r--driver/gator_events_net.c9
-rw-r--r--driver/gator_events_perf_pmu.c77
-rw-r--r--driver/gator_events_sched.c1
-rw-r--r--driver/gator_events_scorpion.c218
-rw-r--r--driver/gator_fs.c58
-rw-r--r--driver/gator_main.c372
-rw-r--r--driver/gator_marshaling.c179
-rw-r--r--driver/gator_pack.c110
-rw-r--r--driver/gator_trace_gpu.c76
-rw-r--r--driver/gator_trace_gpu.h60
-rw-r--r--driver/gator_trace_power.c46
-rw-r--r--driver/gator_trace_sched.c24
62 files changed, 3274 insertions, 2737 deletions
diff --git a/daemon/Android.mk b/daemon/Android.mk
index cbaf42d..b8cc7ff 100644
--- a/daemon/Android.mk
+++ b/daemon/Android.mk
@@ -1,41 +1,39 @@
1LOCAL_PATH:= $(call my-dir) 1LOCAL_PATH := $(call my-dir)
2include $(CLEAR_VARS) 2include $(CLEAR_VARS)
3 3
4$(shell cd $(LOCAL_PATH);cat events_header.xml events-*\.xml events_footer.xml > events.xml;xxd -i events.xml > events_xml.h;xxd -i configuration.xml > configuration_xml.h) 4XML_H := $(shell cd $(LOCAL_PATH) && make events_xml.h configuration_xml.h)
5 5
6LOCAL_CFLAGS += -Wall -O3 -ftree-vectorize -Wno-error=sequence-point 6LOCAL_CFLAGS += -Wall -O3 -mthumb-interwork -fno-exceptions
7 7
8LOCAL_SRC_FILES:= \ 8LOCAL_SRC_FILES := \
9 CapturedXML.cpp \ 9 CapturedXML.cpp \
10 Child.cpp \ 10 Child.cpp \
11 Collector.cpp \ 11 Collector.cpp \
12 ConfigurationXML.cpp \ 12 ConfigurationXML.cpp \
13 Fifo.cpp \ 13 Fifo.cpp \
14 LocalCapture.cpp \ 14 LocalCapture.cpp \
15 Logging.cpp \ 15 Logging.cpp \
16 main.cpp \ 16 main.cpp \
17 OlySocket.cpp \ 17 OlySocket.cpp \
18 OlyUtility.cpp \ 18 OlyUtility.cpp \
19 Sender.cpp \ 19 Sender.cpp \
20 SessionData.cpp \ 20 SessionData.cpp \
21 SessionXML.cpp \ 21 SessionXML.cpp \
22 StreamlineSetup.cpp \ 22 StreamlineSetup.cpp \
23 mxml/mxml-attr.c \ 23 mxml/mxml-attr.c \
24 mxml/mxml-entity.c \ 24 mxml/mxml-entity.c \
25 mxml/mxml-file.c \ 25 mxml/mxml-file.c \
26 mxml/mxml-get.c \ 26 mxml/mxml-get.c \
27 mxml/mxml-index.c \ 27 mxml/mxml-index.c \
28 mxml/mxml-node.c \ 28 mxml/mxml-node.c \
29 mxml/mxml-private.c \ 29 mxml/mxml-private.c \
30 mxml/mxml-search.c \ 30 mxml/mxml-search.c \
31 mxml/mxml-set.c \ 31 mxml/mxml-set.c \
32 mxml/mxml-string.c 32 mxml/mxml-string.c
33 33
34LOCAL_C_INCLUDES := $(LOCAL_PATH) 34LOCAL_C_INCLUDES := $(LOCAL_PATH)
35 35
36LOCAL_MODULE:= gatord 36LOCAL_MODULE := gatord
37LOCAL_MODULE_TAGS:= optional 37LOCAL_MODULE_TAGS := optional
38 38
39LOCAL_LDLIBS := -lz -llog 39include $(BUILD_EXECUTABLE)
40
41include $(BUILD_EXECUTABLE)
diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp
index 30d984f..cc218d7 100644
--- a/daemon/CapturedXML.cpp
+++ b/daemon/CapturedXML.cpp
@@ -14,8 +14,6 @@
14#include "Logging.h" 14#include "Logging.h"
15#include "OlyUtility.h" 15#include "OlyUtility.h"
16 16
17extern void handleException();
18
19CapturedXML::CapturedXML() { 17CapturedXML::CapturedXML() {
20} 18}
21 19
@@ -111,3 +109,42 @@ void CapturedXML::write(char* path) {
111 free(xml); 109 free(xml);
112 free(file); 110 free(file);
113} 111}
112
113// whitespace callback utility function used with mini-xml
114const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
115 const char *name;
116
117 name = mxmlGetElement(node);
118
119 if (loc == MXML_WS_BEFORE_OPEN) {
120 // Single indentation
121 if (!strcmp(name, "target") || !strcmp(name, "counters"))
122 return("\n ");
123
124 // Double indentation
125 if (!strcmp(name, "counter"))
126 return("\n ");
127
128 // Avoid a carriage return on the first line of the xml file
129 if (!strncmp(name, "?xml", 4))
130 return(NULL);
131
132 // Default - no indentation
133 return("\n");
134 }
135
136 if (loc == MXML_WS_BEFORE_CLOSE) {
137 // No indentation
138 if (!strcmp(name, "captured"))
139 return("\n");
140
141 // Single indentation
142 if (!strcmp(name, "counters"))
143 return("\n ");
144
145 // Default - no carriage return
146 return(NULL);
147 }
148
149 return(NULL);
150}
diff --git a/daemon/CapturedXML.h b/daemon/CapturedXML.h
index 3f6a4de..3cac576 100644
--- a/daemon/CapturedXML.h
+++ b/daemon/CapturedXML.h
@@ -22,4 +22,6 @@ private:
22 mxml_node_t* getTree(bool includeTime); 22 mxml_node_t* getTree(bool includeTime);
23}; 23};
24 24
25const char * mxmlWhitespaceCB(mxml_node_t *node, int where);
26
25#endif //__CAPTURED_XML_H__ 27#endif //__CAPTURED_XML_H__
diff --git a/daemon/Collector.cpp b/daemon/Collector.cpp
index 25bb934..2e4af0c 100644
--- a/daemon/Collector.cpp
+++ b/daemon/Collector.cpp
@@ -18,8 +18,6 @@
18#include "Logging.h" 18#include "Logging.h"
19#include "Sender.h" 19#include "Sender.h"
20 20
21extern void handleException();
22
23// Driver initialization independent of session settings 21// Driver initialization independent of session settings
24Collector::Collector() { 22Collector::Collector() {
25 char text[sizeof(gSessionData->mPerfCounterType[0]) + 30]; // sufficiently large to hold all /dev/gator/events/<types>/<file> 23 char text[sizeof(gSessionData->mPerfCounterType[0]) + 30]; // sufficiently large to hold all /dev/gator/events/<types>/<file>
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp
index a213cbb..14c2809 100644
--- a/daemon/ConfigurationXML.cpp
+++ b/daemon/ConfigurationXML.cpp
@@ -14,8 +14,6 @@
14#include "OlyUtility.h" 14#include "OlyUtility.h"
15#include "SessionData.h" 15#include "SessionData.h"
16 16
17extern void handleException();
18
19static const char* ATTR_COUNTER = "counter"; 17static const char* ATTR_COUNTER = "counter";
20static const char* ATTR_REVISION = "revision"; 18static const char* ATTR_REVISION = "revision";
21static const char* ATTR_TITLE = "title"; 19static const char* ATTR_TITLE = "title";
@@ -33,7 +31,7 @@ ConfigurationXML::ConfigurationXML() {
33 const char * configuration_xml; 31 const char * configuration_xml;
34 unsigned int configuration_xml_len; 32 unsigned int configuration_xml_len;
35 getDefaultConfigurationXml(configuration_xml, configuration_xml_len); 33 getDefaultConfigurationXml(configuration_xml, configuration_xml_len);
36 34
37 mIndex = 0; 35 mIndex = 0;
38 char* path = (char*)malloc(PATH_MAX); 36 char* path = (char*)malloc(PATH_MAX);
39 37
@@ -171,7 +169,7 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
171 if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false); 169 if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false);
172 gSessionData->mPerfCounterEnabled[mIndex] = true; 170 gSessionData->mPerfCounterEnabled[mIndex] = true;
173 171
174 // strncpy does not guarantee a null-termianted string 172 // strncpy does not guarantee a null-terminated string
175 gSessionData->mPerfCounterType[mIndex][sizeof(gSessionData->mPerfCounterType[mIndex]) - 1] = 0; 173 gSessionData->mPerfCounterType[mIndex][sizeof(gSessionData->mPerfCounterType[mIndex]) - 1] = 0;
176 gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0; 174 gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0;
177 gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0; 175 gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0;
@@ -184,8 +182,6 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
184} 182}
185 183
186void ConfigurationXML::getDefaultConfigurationXml(const char * & xml, unsigned int & len) { 184void ConfigurationXML::getDefaultConfigurationXml(const char * & xml, unsigned int & len) {
187 // the first line of configuration_xml.h is "unsigned char configuration_xml", but configuration_xml needs to be const static as well
188 const static
189#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len 185#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len
190 xml = (const char *)configuration_xml; 186 xml = (const char *)configuration_xml;
191 len = configuration_xml_len; 187 len = configuration_xml_len;
diff --git a/daemon/Fifo.cpp b/daemon/Fifo.cpp
index 191536f..4a27452 100644
--- a/daemon/Fifo.cpp
+++ b/daemon/Fifo.cpp
@@ -12,8 +12,6 @@
12#include "Fifo.h" 12#include "Fifo.h"
13#include "Logging.h" 13#include "Logging.h"
14 14
15extern void handleException();
16
17// bufferSize is the amount of data to be filled 15// bufferSize is the amount of data to be filled
18// singleBufferSize is the maximum size that may be filled during a single write 16// singleBufferSize is the maximum size that may be filled during a single write
19// (bufferSize + singleBufferSize) will be allocated 17// (bufferSize + singleBufferSize) will be allocated
@@ -37,27 +35,29 @@ Fifo::Fifo(int singleBufferSize, int bufferSize) {
37 35
38Fifo::~Fifo() { 36Fifo::~Fifo() {
39 free(mBuffer); 37 free(mBuffer);
38 sem_destroy(&mWaitForSpaceSem);
39 sem_destroy(&mWaitForDataSem);
40} 40}
41 41
42int Fifo::numBytesFilled() { 42int Fifo::numBytesFilled() const {
43 return mWrite - mRead + mRaggedEnd; 43 return mWrite - mRead + mRaggedEnd;
44} 44}
45 45
46char* Fifo::start() { 46char* Fifo::start() const {
47 return mBuffer; 47 return mBuffer;
48} 48}
49 49
50bool Fifo::isEmpty() { 50bool Fifo::isEmpty() const {
51 return mRead == mWrite && mRaggedEnd == 0; 51 return mRead == mWrite && mRaggedEnd == 0;
52} 52}
53 53
54bool Fifo::isFull() { 54bool Fifo::isFull() const {
55 return willFill(0); 55 return willFill(0);
56} 56}
57 57
58// Determines if the buffer will fill assuming 'additional' bytes will be added to the buffer 58// Determines if the buffer will fill assuming 'additional' bytes will be added to the buffer
59// 'full' means there is less than singleBufferSize bytes available contiguously; it does not mean there are zero bytes available 59// 'full' means there is less than singleBufferSize bytes available contiguously; it does not mean there are zero bytes available
60bool Fifo::willFill(int additional) { 60bool Fifo::willFill(int additional) const {
61 if (mWrite > mRead) { 61 if (mWrite > mRead) {
62 if (numBytesFilled() + additional < mWrapThreshold) { 62 if (numBytesFilled() + additional < mWrapThreshold) {
63 return false; 63 return false;
@@ -98,7 +98,7 @@ char* Fifo::write(int length) {
98} 98}
99 99
100// This function will stall until data is available 100// This function will stall until data is available
101char* Fifo::read(int* length) { 101char* Fifo::read(int *const length) {
102 // update the read pointer now that the data has been handled 102 // update the read pointer now that the data has been handled
103 mRead = mReadCommit; 103 mRead = mReadCommit;
104 104
diff --git a/daemon/Fifo.h b/daemon/Fifo.h
index b460549..e2a5d94 100644
--- a/daemon/Fifo.h
+++ b/daemon/Fifo.h
@@ -15,13 +15,13 @@ class Fifo {
15public: 15public:
16 Fifo(int singleBufferSize, int totalBufferSize); 16 Fifo(int singleBufferSize, int totalBufferSize);
17 ~Fifo(); 17 ~Fifo();
18 int numBytesFilled(); 18 int numBytesFilled() const;
19 bool isEmpty(); 19 bool isEmpty() const;
20 bool isFull(); 20 bool isFull() const;
21 bool willFill(int additional); 21 bool willFill(int additional) const;
22 char* start(); 22 char* start() const;
23 char* write(int length); 23 char* write(int length);
24 char* read(int* length); 24 char* read(int *const length);
25 25
26private: 26private:
27 int mSingleBufferSize, mWrite, mRead, mReadCommit, mRaggedEnd, mWrapThreshold; 27 int mSingleBufferSize, mWrite, mRead, mReadCommit, mRaggedEnd, mWrapThreshold;
diff --git a/daemon/LocalCapture.cpp b/daemon/LocalCapture.cpp
index f8cd17f..2dd3aff 100644
--- a/daemon/LocalCapture.cpp
+++ b/daemon/LocalCapture.cpp
@@ -17,8 +17,6 @@
17#include "Logging.h" 17#include "Logging.h"
18#include "OlyUtility.h" 18#include "OlyUtility.h"
19 19
20extern void handleException();
21
22LocalCapture::LocalCapture() {} 20LocalCapture::LocalCapture() {}
23 21
24LocalCapture::~LocalCapture() {} 22LocalCapture::~LocalCapture() {}
@@ -56,7 +54,7 @@ char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* e
56 handleException(); 54 handleException();
57 } else if (initialPath[0] != '/') { 55 } else if (initialPath[0] != '/') {
58 if (getcwd(path, PATH_MAX) == 0) { 56 if (getcwd(path, PATH_MAX) == 0) {
59 logg->logMessage("Unable to retrive the current working directory"); 57 logg->logMessage("Unable to retrieve the current working directory");
60 } 58 }
61 strncat(path, "/", PATH_MAX - strlen(path) - 1); 59 strncat(path, "/", PATH_MAX - strlen(path) - 1);
62 strncat(path, initialPath, PATH_MAX - strlen(path) - 1); 60 strncat(path, initialPath, PATH_MAX - strlen(path) - 1);
diff --git a/daemon/Logging.h b/daemon/Logging.h
index 4247966..37f7dd3 100644
--- a/daemon/Logging.h
+++ b/daemon/Logging.h
@@ -42,4 +42,6 @@ private:
42 42
43extern Logging* logg; 43extern Logging* logg;
44 44
45extern void handleException();
46
45#endif //__LOGGING_H__ 47#endif //__LOGGING_H__
diff --git a/daemon/Makefile b/daemon/Makefile
index 5562db7..95d1809 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -8,10 +8,8 @@
8# targets it is necessary to add options 8# targets it is necessary to add options
9# '-marm -march=armv4t -mfloat-abi=soft'. 9# '-marm -march=armv4t -mfloat-abi=soft'.
10 10
11ARCH=arm 11CPP = $(CROSS_COMPILE)g++
12 12GCC = $(CROSS_COMPILE)gcc
13CPP=$(CROSS_COMPILE)g++
14GCC=$(CROSS_COMPILE)gcc
15 13
16# -g produces debugging information 14# -g produces debugging information
17# -O3 maximum optimization 15# -O3 maximum optimization
@@ -21,34 +19,40 @@ GCC=$(CROSS_COMPILE)gcc
21# -std=c++0x is the planned new c++ standard 19# -std=c++0x is the planned new c++ standard
22# -std=c++98 is the 1998 c++ standard 20# -std=c++98 is the 1998 c++ standard
23# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc 21# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc
24CFLAGS=-O3 -Wall -mthumb-interwork 22CFLAGS = -O3 -Wall -mthumb-interwork -fno-exceptions
23CXXFLAGS = -fno-rtti
25ifeq ($(WERROR),1) 24ifeq ($(WERROR),1)
26 CFLAGS += -Werror 25 CFLAGS += -Werror
27endif 26endif
28# -s strips the binary of debug info 27# -s strips the binary of debug info
29LDFLAGS=-s 28LDFLAGS = -s
30TARGET=gatord 29TARGET = gatord
31C_SRC = $(wildcard mxml/*.c) 30C_SRC = $(wildcard mxml/*.c)
32CPP_SRC = $(wildcard *.cpp) 31CPP_SRC = $(wildcard *.cpp)
33TGT_OBJS = $(CPP_SRC:%.cpp=%.o) \
34 $(C_SRC:%.c=%.o)
35 32
36all: $(TARGET) 33all: $(TARGET)
37 34
35events.xml: events_header.xml $(wildcard events-*.xml) events_footer.xml
36 cat $^ > $@
37
38StreamlineSetup.cpp: events_xml.h
39ConfigurationXML.cpp: configuration_xml.h
40
41%_xml.h: %.xml escape
42 ./escape $< > $@
43
38%.o: %.c *.h 44%.o: %.c *.h
39 $(GCC) -c $(CFLAGS) -o $@ $< 45 $(GCC) -c $(CFLAGS) -o $@ $<
40 46
41%.o: %.cpp *.h 47%.o: %.cpp *.h
42 $(CPP) -c $(CFLAGS) -o $@ $< 48 $(CPP) -c $(CFLAGS) $(CXXFLAGS) -o $@ $<
43 49
44$(TARGET): convert $(TGT_OBJS) 50$(TARGET): $(CPP_SRC:%.cpp=%.o) $(C_SRC:%.c=%.o)
45 $(CPP) $(LDFLAGS) -o $@ $(TGT_OBJS) -lc -lrt -lpthread 51 $(CPP) $(LDFLAGS) -o $@ $^ -lc -lrt -lpthread
46 rm events_xml.h configuration_xml.h 52 rm -f events_xml.h configuration_xml.h
47 53
48convert: 54escape: escape.c
49 cat events_header.xml events-*\.xml events_footer.xml > events.xml 55 gcc $^ -o $@
50 xxd -i events.xml > events_xml.h
51 xxd -i configuration.xml > configuration_xml.h
52 56
53clean: 57clean:
54 rm -f *.o mxml/*.o $(TARGET) events.xml events_xml.h configuration_xml.h 58 rm -f *.o mxml/*.o $(TARGET) escape events.xml events_xml.h configuration_xml.h
diff --git a/daemon/OlySocket.cpp b/daemon/OlySocket.cpp
index a3bf746..6128dc0 100644
--- a/daemon/OlySocket.cpp
+++ b/daemon/OlySocket.cpp
@@ -20,242 +20,240 @@
20 20
21#ifdef WIN32 21#ifdef WIN32
22#define CLOSE_SOCKET(x) closesocket(x) 22#define CLOSE_SOCKET(x) closesocket(x)
23#define SHUTDOWN_RX_TX SD_BOTH 23#define SHUTDOWN_RX_TX SD_BOTH
24#define snprintf _snprintf 24#define snprintf _snprintf
25#else 25#else
26#define CLOSE_SOCKET(x) close(x) 26#define CLOSE_SOCKET(x) close(x)
27#define SHUTDOWN_RX_TX SHUT_RDWR 27#define SHUTDOWN_RX_TX SHUT_RDWR
28#endif 28#endif
29 29
30extern void handleException();
31
32OlySocket::OlySocket(int port, bool multiple) { 30OlySocket::OlySocket(int port, bool multiple) {
33#ifdef WIN32 31#ifdef WIN32
34 WSADATA wsaData; 32 WSADATA wsaData;
35 if (WSAStartup(0x0202, &wsaData) != 0) { 33 if (WSAStartup(0x0202, &wsaData) != 0) {
36 logg->logError(__FILE__, __LINE__, "Windows socket initialization failed"); 34 logg->logError(__FILE__, __LINE__, "Windows socket initialization failed");
37 handleException(); 35 handleException();
38 } 36 }
39#endif 37#endif
40 38
41 if (multiple) { 39 if (multiple) {
42 createServerSocket(port); 40 createServerSocket(port);
43 } else { 41 } else {
44 createSingleServerConnection(port); 42 createSingleServerConnection(port);
45 } 43 }
46} 44}
47 45
48OlySocket::OlySocket(int port, char* host) { 46OlySocket::OlySocket(int port, char* host) {
49 mFDServer = 0; 47 mFDServer = 0;
50 createClientSocket(host, port); 48 createClientSocket(host, port);
51} 49}
52 50
53OlySocket::~OlySocket() { 51OlySocket::~OlySocket() {
54 if (mSocketID > 0) { 52 if (mSocketID > 0) {
55 CLOSE_SOCKET(mSocketID); 53 CLOSE_SOCKET(mSocketID);
56 } 54 }
57} 55}
58 56
59void OlySocket::shutdownConnection() { 57void OlySocket::shutdownConnection() {
60 // Shutdown is primarily used to unblock other threads that are blocking on send/receive functions 58 // Shutdown is primarily used to unblock other threads that are blocking on send/receive functions
61 shutdown(mSocketID, SHUTDOWN_RX_TX); 59 shutdown(mSocketID, SHUTDOWN_RX_TX);
62} 60}
63 61
64void OlySocket::closeSocket() { 62void OlySocket::closeSocket() {
65 // Used for closing an accepted socket but keeping the server socket active 63 // Used for closing an accepted socket but keeping the server socket active
66 if (mSocketID > 0) { 64 if (mSocketID > 0) {
67 CLOSE_SOCKET(mSocketID); 65 CLOSE_SOCKET(mSocketID);
68 mSocketID = -1; 66 mSocketID = -1;
69 } 67 }
70} 68}
71 69
72void OlySocket::closeServerSocket() { 70void OlySocket::closeServerSocket() {
73 if (CLOSE_SOCKET(mFDServer) != 0) { 71 if (CLOSE_SOCKET(mFDServer) != 0) {
74 logg->logError(__FILE__, __LINE__, "Failed to close server socket."); 72 logg->logError(__FILE__, __LINE__, "Failed to close server socket.");
75 handleException(); 73 handleException();
76 } 74 }
77 mFDServer = 0; 75 mFDServer = 0;
78} 76}
79 77
80void OlySocket::createClientSocket(char* hostname, int portno) { 78void OlySocket::createClientSocket(char* hostname, int portno) {
81#ifdef WIN32 79#ifdef WIN32
82 // TODO: Implement for Windows 80 // TODO: Implement for Windows
83#else 81#else
84 char buf[32]; 82 char buf[32];
85 struct addrinfo hints, *res, *res0; 83 struct addrinfo hints, *res, *res0;
86 84
87 snprintf(buf, sizeof(buf), "%d", portno); 85 snprintf(buf, sizeof(buf), "%d", portno);
88 mSocketID = -1; 86 mSocketID = -1;
89 memset((void*)&hints, 0, sizeof(hints)); 87 memset((void*)&hints, 0, sizeof(hints));
90 hints.ai_family = PF_UNSPEC; 88 hints.ai_family = PF_UNSPEC;
91 hints.ai_socktype = SOCK_STREAM; 89 hints.ai_socktype = SOCK_STREAM;
92 90
93 if (getaddrinfo(hostname, buf, &hints, &res0)) { 91 if (getaddrinfo(hostname, buf, &hints, &res0)) {
94 logg->logError(__FILE__, __LINE__, "Client socket failed to get address info for %s", hostname); 92 logg->logError(__FILE__, __LINE__, "Client socket failed to get address info for %s", hostname);
95 handleException(); 93 handleException();
96 } 94 }
97 for (res=res0; res!=NULL; res = res->ai_next) { 95 for (res=res0; res!=NULL; res = res->ai_next) {
98 if ( res->ai_family != PF_INET || res->ai_socktype != SOCK_STREAM ) { 96 if ( res->ai_family != PF_INET || res->ai_socktype != SOCK_STREAM ) {
99 continue; 97 continue;
100 } 98 }
101 mSocketID = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 99 mSocketID = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
102 if (mSocketID < 0) { 100 if (mSocketID < 0) {
103 continue; 101 continue;
104 } 102 }
105 if (connect(mSocketID, res->ai_addr, res->ai_addrlen) < 0) { 103 if (connect(mSocketID, res->ai_addr, res->ai_addrlen) < 0) {
106 close(mSocketID); 104 close(mSocketID);
107 mSocketID = -1; 105 mSocketID = -1;
108 } 106 }
109 if (mSocketID > 0) { 107 if (mSocketID > 0) {
110 break; 108 break;
111 } 109 }
112 } 110 }
113 freeaddrinfo(res0); 111 freeaddrinfo(res0);
114 if (mSocketID <= 0) { 112 if (mSocketID <= 0) {
115 logg->logError(__FILE__, __LINE__, "Could not connect to client socket. Ensure ARM Streamline is running."); 113 logg->logError(__FILE__, __LINE__, "Could not connect to client socket. Ensure ARM Streamline is running.");
116 handleException(); 114 handleException();
117 } 115 }
118#endif 116#endif
119} 117}
120 118
121void OlySocket::createSingleServerConnection(int port) { 119void OlySocket::createSingleServerConnection(int port) {
122 createServerSocket(port); 120 createServerSocket(port);
123 121
124 mSocketID = acceptConnection(); 122 mSocketID = acceptConnection();
125 closeServerSocket(); 123 closeServerSocket();
126} 124}
127 125
128void OlySocket::createServerSocket(int port) { 126void OlySocket::createServerSocket(int port) {
129 // Create socket 127 // Create socket
130 mFDServer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 128 mFDServer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
131 if (mFDServer < 0) { 129 if (mFDServer < 0) {
132 logg->logError(__FILE__, __LINE__, "Error creating server socket"); 130 logg->logError(__FILE__, __LINE__, "Error creating server socket");
133 handleException(); 131 handleException();
134 } 132 }
135 133
136 // Enable address reuse, another solution would be to create the server socket once and only close it when the object exits 134 // Enable address reuse, another solution would be to create the server socket once and only close it when the object exits
137 int on = 1; 135 int on = 1;
138 if (setsockopt(mFDServer, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) { 136 if (setsockopt(mFDServer, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
139 logg->logError(__FILE__, __LINE__, "Setting server socket options failed"); 137 logg->logError(__FILE__, __LINE__, "Setting server socket options failed");
140 handleException(); 138 handleException();
141 } 139 }
142 140
143 // Create sockaddr_in structure, ensuring non-populated fields are zero 141 // Create sockaddr_in structure, ensuring non-populated fields are zero
144 struct sockaddr_in sockaddr; 142 struct sockaddr_in sockaddr;
145 memset((void*)&sockaddr, 0, sizeof(struct sockaddr_in)); 143 memset((void*)&sockaddr, 0, sizeof(struct sockaddr_in));
146 sockaddr.sin_family = AF_INET; 144 sockaddr.sin_family = AF_INET;
147 sockaddr.sin_port = htons(port); 145 sockaddr.sin_port = htons(port);
148 sockaddr.sin_addr.s_addr = INADDR_ANY; 146 sockaddr.sin_addr.s_addr = INADDR_ANY;
149 147
150 // Bind the socket to an address 148 // Bind the socket to an address
151 if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) { 149 if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
152 logg->logError(__FILE__, __LINE__, "Binding of server socket failed.\nIs an instance already running?"); 150 logg->logError(__FILE__, __LINE__, "Binding of server socket failed.\nIs an instance already running?");
153 handleException(); 151 handleException();
154 } 152 }
155 153
156 // Listen for connections on this socket 154 // Listen for connections on this socket
157 if (listen(mFDServer, 1) < 0) { 155 if (listen(mFDServer, 1) < 0) {
158 logg->logError(__FILE__, __LINE__, "Listening of server socket failed"); 156 logg->logError(__FILE__, __LINE__, "Listening of server socket failed");
159 handleException(); 157 handleException();
160 } 158 }
161} 159}
162 160
163// mSocketID is always set to the most recently accepted connection 161// mSocketID is always set to the most recently accepted connection
164// The user of this class should maintain the different socket connections, e.g. by forking the process 162// The user of this class should maintain the different socket connections, e.g. by forking the process
165int OlySocket::acceptConnection() { 163int OlySocket::acceptConnection() {
166 if (mFDServer <= 0) { 164 if (mFDServer <= 0) {
167 logg->logError(__FILE__, __LINE__, "Attempting multiple connections on a single connection server socket or attempting to accept on a client socket"); 165 logg->logError(__FILE__, __LINE__, "Attempting multiple connections on a single connection server socket or attempting to accept on a client socket");
168 handleException(); 166 handleException();
169 } 167 }
170 168
171 // Accept a connection, note that this call blocks until a client connects 169 // Accept a connection, note that this call blocks until a client connects
172 mSocketID = accept(mFDServer, NULL, NULL); 170 mSocketID = accept(mFDServer, NULL, NULL);
173 if (mSocketID < 0) { 171 if (mSocketID < 0) {
174 logg->logError(__FILE__, __LINE__, "Socket acceptance failed"); 172 logg->logError(__FILE__, __LINE__, "Socket acceptance failed");
175 handleException(); 173 handleException();
176 } 174 }
177 return mSocketID; 175 return mSocketID;
178} 176}
179 177
180void OlySocket::send(char* buffer, int size) { 178void OlySocket::send(char* buffer, int size) {
181 if (size <= 0 || buffer == NULL) { 179 if (size <= 0 || buffer == NULL) {
182 return; 180 return;
183 } 181 }
184 182
185 while (size > 0) { 183 while (size > 0) {
186 int n = ::send(mSocketID, buffer, size, 0); 184 int n = ::send(mSocketID, buffer, size, 0);
187 if (n < 0) { 185 if (n < 0) {
188 logg->logError(__FILE__, __LINE__, "Socket send error"); 186 logg->logError(__FILE__, __LINE__, "Socket send error");
189 handleException(); 187 handleException();
190 } 188 }
191 size -= n; 189 size -= n;
192 buffer += n; 190 buffer += n;
193 } 191 }
194} 192}
195 193
196// Returns the number of bytes received 194// Returns the number of bytes received
197int OlySocket::receive(char* buffer, int size) { 195int OlySocket::receive(char* buffer, int size) {
198 if (size <= 0 || buffer == NULL) { 196 if (size <= 0 || buffer == NULL) {
199 return 0; 197 return 0;
200 } 198 }
201 199
202 int bytes = recv(mSocketID, buffer, size, 0); 200 int bytes = recv(mSocketID, buffer, size, 0);
203 if (bytes < 0) { 201 if (bytes < 0) {
204 logg->logError(__FILE__, __LINE__, "Socket receive error"); 202 logg->logError(__FILE__, __LINE__, "Socket receive error");
205 handleException(); 203 handleException();
206 } else if (bytes == 0) { 204 } else if (bytes == 0) {
207 logg->logMessage("Socket disconnected"); 205 logg->logMessage("Socket disconnected");
208 return -1; 206 return -1;
209 } 207 }
210 return bytes; 208 return bytes;
211} 209}
212 210
213// Receive exactly size bytes of data. Note, this function will block until all bytes are received 211// Receive exactly size bytes of data. Note, this function will block until all bytes are received
214int OlySocket::receiveNBytes(char* buffer, int size) { 212int OlySocket::receiveNBytes(char* buffer, int size) {
215 int bytes = 0; 213 int bytes = 0;
216 while (size > 0 && buffer != NULL) { 214 while (size > 0 && buffer != NULL) {
217 bytes = recv(mSocketID, buffer, size, 0); 215 bytes = recv(mSocketID, buffer, size, 0);
218 if (bytes < 0) { 216 if (bytes < 0) {
219 logg->logError(__FILE__, __LINE__, "Socket receive error"); 217 logg->logError(__FILE__, __LINE__, "Socket receive error");
220 handleException(); 218 handleException();
221 } else if (bytes == 0) { 219 } else if (bytes == 0) {
222 logg->logMessage("Socket disconnected"); 220 logg->logMessage("Socket disconnected");
223 return -1; 221 return -1;
224 } 222 }
225 buffer += bytes; 223 buffer += bytes;
226 size -= bytes; 224 size -= bytes;
227 } 225 }
228 return bytes; 226 return bytes;
229} 227}
230 228
231// Receive data until a carriage return, line feed, or null is encountered, or the buffer fills 229// Receive data until a carriage return, line feed, or null is encountered, or the buffer fills
232int OlySocket::receiveString(char* buffer, int size) { 230int OlySocket::receiveString(char* buffer, int size) {
233 int bytes_received = 0; 231 int bytes_received = 0;
234 bool found = false; 232 bool found = false;
235 233
236 if (buffer == 0) { 234 if (buffer == 0) {
237 return 0; 235 return 0;
238 } 236 }
239 237
240 while (!found && bytes_received < size) { 238 while (!found && bytes_received < size) {
241 // Receive a single character 239 // Receive a single character
242 int bytes = recv(mSocketID, &buffer[bytes_received], 1, 0); 240 int bytes = recv(mSocketID, &buffer[bytes_received], 1, 0);
243 if (bytes < 0) { 241 if (bytes < 0) {
244 logg->logError(__FILE__, __LINE__, "Socket receive error"); 242 logg->logError(__FILE__, __LINE__, "Socket receive error");
245 handleException(); 243 handleException();
246 } else if (bytes == 0) { 244 } else if (bytes == 0) {
247 logg->logMessage("Socket disconnected"); 245 logg->logMessage("Socket disconnected");
248 return -1; 246 return -1;
249 } 247 }
250 248
251 // Replace carriage returns and line feeds with zero 249 // Replace carriage returns and line feeds with zero
252 if (buffer[bytes_received] == '\n' || buffer[bytes_received] == '\r' || buffer[bytes_received] == '\0') { 250 if (buffer[bytes_received] == '\n' || buffer[bytes_received] == '\r' || buffer[bytes_received] == '\0') {
253 buffer[bytes_received] = '\0'; 251 buffer[bytes_received] = '\0';
254 found = true; 252 found = true;
255 } 253 }
256 254
257 bytes_received++; 255 bytes_received++;
258 } 256 }
259 257
260 return bytes_received; 258 return bytes_received;
261} 259}
diff --git a/daemon/OlySocket.h b/daemon/OlySocket.h
index 266a831..b306908 100644
--- a/daemon/OlySocket.h
+++ b/daemon/OlySocket.h
@@ -6,31 +6,31 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#ifndef __OLY_SOCKET_H__ 9#ifndef __OLY_SOCKET_H__
10#define __OLY_SOCKET_H__ 10#define __OLY_SOCKET_H__
11 11
12#include <string.h> 12#include <string.h>
13 13
14class OlySocket { 14class OlySocket {
15public: 15public:
16 OlySocket(int port, bool multipleConnections = false); 16 OlySocket(int port, bool multipleConnections = false);
17 OlySocket(int port, char* hostname); 17 OlySocket(int port, char* hostname);
18 ~OlySocket(); 18 ~OlySocket();
19 int acceptConnection(); 19 int acceptConnection();
20 void closeSocket(); 20 void closeSocket();
21 void closeServerSocket(); 21 void closeServerSocket();
22 void shutdownConnection(); 22 void shutdownConnection();
23 void send(char* buffer, int size); 23 void send(char* buffer, int size);
24 void sendString(const char* string) {send((char*)string, strlen(string));} 24 void sendString(const char* string) {send((char*)string, strlen(string));}
25 int receive(char* buffer, int size); 25 int receive(char* buffer, int size);
26 int receiveNBytes(char* buffer, int size); 26 int receiveNBytes(char* buffer, int size);
27 int receiveString(char* buffer, int size); 27 int receiveString(char* buffer, int size);
28 int getSocketID() {return mSocketID;} 28 int getSocketID() {return mSocketID;}
29private: 29private:
30 int mSocketID, mFDServer; 30 int mSocketID, mFDServer;
31 void createClientSocket(char* hostname, int port); 31 void createClientSocket(char* hostname, int port);
32 void createSingleServerConnection(int port); 32 void createSingleServerConnection(int port);
33 void createServerSocket(int port); 33 void createServerSocket(int port);
34}; 34};
35 35
36#endif //__OLY_SOCKET_H__ 36#endif //__OLY_SOCKET_H__
diff --git a/daemon/OlyUtility.cpp b/daemon/OlyUtility.cpp
index adc7aba..df4fe22 100644
--- a/daemon/OlyUtility.cpp
+++ b/daemon/OlyUtility.cpp
@@ -11,10 +11,12 @@
11#include <string.h> 11#include <string.h>
12#include <ctype.h> 12#include <ctype.h>
13 13
14#ifndef WIN32 14#if defined(WIN32)
15#include <windows.h>
16#elif defined(__linux__)
15#include <unistd.h> 17#include <unistd.h>
16#else 18#elif defined(DARWIN)
17#include <Windows.h> 19#include <mach-o/dyld.h>
18#endif 20#endif
19 21
20#include "OlyUtility.h" 22#include "OlyUtility.h"
@@ -22,138 +24,144 @@
22OlyUtility* util = NULL; 24OlyUtility* util = NULL;
23 25
24bool OlyUtility::stringToBool(const char* string, bool defValue) { 26bool OlyUtility::stringToBool(const char* string, bool defValue) {
25 char value[32]; 27 char value[32];
26 28
27 if (string == NULL) { 29 if (string == NULL) {
28 return defValue; 30 return defValue;
29 } 31 }
30 32
31 strncpy(value, string, sizeof(value)); 33 strncpy(value, string, sizeof(value));
32 if (value[0] == 0) { 34 if (value[0] == 0) {
33 return defValue; 35 return defValue;
34 } 36 }
35 value[sizeof(value) - 1] = 0; // strncpy does not guarantee a null-terminated string 37 value[sizeof(value) - 1] = 0; // strncpy does not guarantee a null-terminated string
36 38
37 // Convert to lowercase 39 // Convert to lowercase
38 int i = 0; 40 int i = 0;
39 while (value[i]) { 41 while (value[i]) {
40 value[i] = tolower(value[i]); 42 value[i] = tolower(value[i]);
41 i++; 43 i++;
42 } 44 }
43 45
44 if (strcmp(value, "true") == 0 || strcmp(value, "yes") == 0 || strcmp(value, "1") == 0 || strcmp(value, "on") == 0) { 46 if (strcmp(value, "true") == 0 || strcmp(value, "yes") == 0 || strcmp(value, "1") == 0 || strcmp(value, "on") == 0) {
45 return true; 47 return true;
46 } else if (strcmp(value, "false") == 0 || strcmp(value, "no") == 0 || strcmp(value, "0") == 0 || strcmp(value, "off") == 0) { 48 } else if (strcmp(value, "false") == 0 || strcmp(value, "no") == 0 || strcmp(value, "0") == 0 || strcmp(value, "off") == 0) {
47 return false; 49 return false;
48 } else { 50 } else {
49 return defValue; 51 return defValue;
50 } 52 }
51} 53}
52 54
53void OlyUtility::stringToLower(char* string) { 55void OlyUtility::stringToLower(char* string) {
54 if (string == NULL) { 56 if (string == NULL) {
55 return; 57 return;
56 } 58 }
57 59
58 while (*string) { 60 while (*string) {
59 *string = tolower(*string); 61 *string = tolower(*string);
60 string++; 62 string++;
61 } 63 }
62} 64}
63 65
64// Modifies fullpath with the path part including the trailing path separator 66// Modifies fullpath with the path part including the trailing path separator
65int OlyUtility::getApplicationFullPath(char* fullpath, int sizeOfPath) { 67int OlyUtility::getApplicationFullPath(char* fullpath, int sizeOfPath) {
66 memset(fullpath, 0, sizeOfPath); 68 memset(fullpath, 0, sizeOfPath);
67#ifdef WIN32 69#if defined(WIN32)
68 int length = GetModuleFileName(NULL, fullpath, sizeOfPath); 70 int length = GetModuleFileName(NULL, fullpath, sizeOfPath);
69#else 71#elif defined(__linux__)
70 int length = readlink("/proc/self/exe", fullpath, sizeOfPath); 72 int length = readlink("/proc/self/exe", fullpath, sizeOfPath);
73#elif defined(DARWIN)
74 uint32_t length_u = (uint32_t)sizeOfPath;
75 int length = sizeOfPath;
76 if (_NSGetExecutablePath(fullpath, &length_u) == 0) {
77 length = strlen(fullpath);
78 }
71#endif 79#endif
72 80
73 if (length == sizeOfPath) { 81 if (length == sizeOfPath) {
74 return -1; 82 return -1;
75 } 83 }
76 84
77 fullpath[length] = 0; 85 fullpath[length] = 0;
78 fullpath = getPathPart(fullpath); 86 fullpath = getPathPart(fullpath);
79 87
80 return 0; 88 return 0;
81} 89}
82 90
83char* OlyUtility::readFromDisk(const char* file, unsigned int *size, bool appendNull) { 91char* OlyUtility::readFromDisk(const char* file, unsigned int *size, bool appendNull) {
84 // Open the file 92 // Open the file
85 FILE* pFile = fopen(file, "rb"); 93 FILE* pFile = fopen(file, "rb");
86 if (pFile==NULL) { 94 if (pFile==NULL) {
87 return NULL; 95 return NULL;
88 } 96 }
89 97
90 // Obtain file size 98 // Obtain file size
91 fseek(pFile , 0 , SEEK_END); 99 fseek(pFile , 0 , SEEK_END);
92 unsigned int lSize = ftell(pFile); 100 unsigned int lSize = ftell(pFile);
93 rewind(pFile); 101 rewind(pFile);
94 102
95 // Allocate memory to contain the whole file 103 // Allocate memory to contain the whole file
96 char* buffer = (char*)malloc(lSize + (int)appendNull); 104 char* buffer = (char*)malloc(lSize + (int)appendNull);
97 if (buffer == NULL) { 105 if (buffer == NULL) {
98 fclose(pFile); 106 fclose(pFile);
99 return NULL; 107 return NULL;
100 } 108 }
101 109
102 // Copy the file into the buffer 110 // Copy the file into the buffer
103 if (fread(buffer, 1, lSize, pFile) != lSize) { 111 if (fread(buffer, 1, lSize, pFile) != lSize) {
104 free(buffer); 112 free(buffer);
105 fclose(pFile); 113 fclose(pFile);
106 return NULL; 114 return NULL;
107 } 115 }
108 116
109 // Terminate 117 // Terminate
110 fclose(pFile); 118 fclose(pFile);
111 119
112 if (appendNull) { 120 if (appendNull) {
113 buffer[lSize] = 0; 121 buffer[lSize] = 0;
114 } 122 }
115 123
116 if (size) { 124 if (size) {
117 *size = lSize; 125 *size = lSize;
118 } 126 }
119 127
120 return buffer; 128 return buffer;
121} 129}
122 130
123int OlyUtility::writeToDisk(const char* path, const char* data) { 131int OlyUtility::writeToDisk(const char* path, const char* data) {
124 // Open the file 132 // Open the file
125 FILE* pFile = fopen(path, "wb"); 133 FILE* pFile = fopen(path, "wb");
126 if (pFile == NULL) { 134 if (pFile == NULL) {
127 return -1; 135 return -1;
128 } 136 }
129 137
130 // Write the data to disk 138 // Write the data to disk
131 if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) { 139 if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) {
132 fclose(pFile); 140 fclose(pFile);
133 return -1; 141 return -1;
134 } 142 }
135 143
136 // Terminate 144 // Terminate
137 fclose(pFile); 145 fclose(pFile);
138 return 0; 146 return 0;
139} 147}
140 148
141int OlyUtility::appendToDisk(const char* path, const char* data) { 149int OlyUtility::appendToDisk(const char* path, const char* data) {
142 // Open the file 150 // Open the file
143 FILE* pFile = fopen(path, "a"); 151 FILE* pFile = fopen(path, "a");
144 if (pFile == NULL) { 152 if (pFile == NULL) {
145 return -1; 153 return -1;
146 } 154 }
147 155
148 // Write the data to disk 156 // Write the data to disk
149 if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) { 157 if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) {
150 fclose(pFile); 158 fclose(pFile);
151 return -1; 159 return -1;
152 } 160 }
153 161
154 // Terminate 162 // Terminate
155 fclose(pFile); 163 fclose(pFile);
156 return 0; 164 return 0;
157} 165}
158 166
159/** 167/**
@@ -163,97 +171,58 @@ int OlyUtility::appendToDisk(const char* path, const char* data) {
163 */ 171 */
164#define TRANSFER_SIZE 1024 172#define TRANSFER_SIZE 1024
165int OlyUtility::copyFile(const char* srcFile, const char* dstFile) { 173int OlyUtility::copyFile(const char* srcFile, const char* dstFile) {
166 char* buffer = (char*)malloc(TRANSFER_SIZE); 174 char* buffer = (char*)malloc(TRANSFER_SIZE);
167 FILE * f_src = fopen(srcFile,"rb"); 175 FILE * f_src = fopen(srcFile,"rb");
168 if (!f_src) { 176 if (!f_src) {
169 return 0; 177 return 0;
170 } 178 }
171 FILE * f_dst = fopen(dstFile,"wb"); 179 FILE * f_dst = fopen(dstFile,"wb");
172 if (!f_dst) { 180 if (!f_dst) {
173 fclose(f_src); 181 fclose(f_src);
174 return 0; 182 return 0;
175 } 183 }
176 while (!feof(f_src)) { 184 while (!feof(f_src)) {
177 int num_bytes_read = fread(buffer, 1, TRANSFER_SIZE, f_src); 185 int num_bytes_read = fread(buffer, 1, TRANSFER_SIZE, f_src);
178 if (num_bytes_read < TRANSFER_SIZE && !feof(f_src)) { 186 if (num_bytes_read < TRANSFER_SIZE && !feof(f_src)) {
179 fclose(f_src); 187 fclose(f_src);
180 fclose(f_dst); 188 fclose(f_dst);
181 return 0; 189 return 0;
182 } 190 }
183 int num_bytes_written = fwrite(buffer, 1, num_bytes_read, f_dst); 191 int num_bytes_written = fwrite(buffer, 1, num_bytes_read, f_dst);
184 if (num_bytes_written != num_bytes_read) { 192 if (num_bytes_written != num_bytes_read) {
185 fclose(f_src); 193 fclose(f_src);
186 fclose(f_dst); 194 fclose(f_dst);
187 return 0; 195 return 0;
188 } 196 }
189 } 197 }
190 fclose(f_src); 198 fclose(f_src);
191 fclose(f_dst); 199 fclose(f_dst);
192 free(buffer); 200 free(buffer);
193 return 1; 201 return 1;
194} 202}
195 203
196const char* OlyUtility::getFilePart(const char* path) { 204const char* OlyUtility::getFilePart(const char* path) {
197 const char* last_sep = strrchr(path, PATH_SEPARATOR); 205 const char* last_sep = strrchr(path, PATH_SEPARATOR);
198 206
199 // in case path is not a full path 207 // in case path is not a full path
200 if (last_sep == NULL) { 208 if (last_sep == NULL) {
201 return path; 209 return path;
202 } 210 }
203 211
204 return last_sep++; 212 return last_sep++;
205} 213}
206 214
207// getPathPart may modify the contents of path 215// getPathPart may modify the contents of path
208// returns the path including the trailing path separator 216// returns the path including the trailing path separator
209char* OlyUtility::getPathPart(char* path) { 217char* OlyUtility::getPathPart(char* path) {
210 char* last_sep = strrchr(path, PATH_SEPARATOR); 218 char* last_sep = strrchr(path, PATH_SEPARATOR);
211 219
212 // in case path is not a full path 220 // in case path is not a full path
213 if (last_sep == NULL) { 221 if (last_sep == NULL) {
214 return 0; 222 return 0;
215 } 223 }
216 last_sep++; 224 last_sep++;
217 *last_sep = 0; 225 *last_sep = 0;
218 226
219 return (path); 227 return (path);
220}
221
222// whitespace callback utility function used with mini-xml
223const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
224 const char *name;
225
226 name = mxmlGetElement(node);
227
228 if (loc == MXML_WS_BEFORE_OPEN) {
229 // Single indentation
230 if (!strcmp(name, "target") || !strcmp(name, "counters"))
231 return("\n ");
232
233 // Double indentation
234 if (!strcmp(name, "counter"))
235 return("\n ");
236
237 // Avoid a carriage return on the first line of the xml file
238 if (!strncmp(name, "?xml", 4))
239 return(NULL);
240
241 // Default - no indentation
242 return("\n");
243 }
244
245 if (loc == MXML_WS_BEFORE_CLOSE) {
246 // No indentation
247 if (!strcmp(name, "captured"))
248 return("\n");
249
250 // Single indentation
251 if (!strcmp(name, "counters"))
252 return("\n ");
253
254 // Default - no carriage return
255 return(NULL);
256 }
257
258 return(NULL);
259} 228}
diff --git a/daemon/OlyUtility.h b/daemon/OlyUtility.h
index 793a733..424c583 100644
--- a/daemon/OlyUtility.h
+++ b/daemon/OlyUtility.h
@@ -11,28 +11,30 @@
11 11
12#ifdef WIN32 12#ifdef WIN32
13#define PATH_SEPARATOR '\\' 13#define PATH_SEPARATOR '\\'
14#define CAIMAN_PATH_MAX MAX_PATH
15#define snprintf _snprintf
14#else 16#else
17#include <limits.h>
15#define PATH_SEPARATOR '/' 18#define PATH_SEPARATOR '/'
19#define CAIMAN_PATH_MAX PATH_MAX
16#endif 20#endif
17 21
18class OlyUtility { 22class OlyUtility {
19public: 23public:
20 OlyUtility() {}; 24 OlyUtility() {};
21 ~OlyUtility() {}; 25 ~OlyUtility() {};
22 bool stringToBool(const char* string, bool defValue); 26 bool stringToBool(const char* string, bool defValue);
23 void stringToLower(char* string); 27 void stringToLower(char* string);
24 int getApplicationFullPath(char* path, int sizeOfPath); 28 int getApplicationFullPath(char* path, int sizeOfPath);
25 char* readFromDisk(const char* file, unsigned int *size = NULL, bool appendNull = true); 29 char* readFromDisk(const char* file, unsigned int *size = NULL, bool appendNull = true);
26 int writeToDisk(const char* path, const char* file); 30 int writeToDisk(const char* path, const char* file);
27 int appendToDisk(const char* path, const char* file); 31 int appendToDisk(const char* path, const char* file);
28 int copyFile(const char* srcFile, const char* dstFile); 32 int copyFile(const char* srcFile, const char* dstFile);
29 const char* getFilePart(const char* path); 33 const char* getFilePart(const char* path);
30 char* getPathPart(char* path); 34 char* getPathPart(char* path);
31private: 35private:
32}; 36};
33 37
34#include "mxml/mxml.h"
35const char * mxmlWhitespaceCB(mxml_node_t *node, int where);
36extern OlyUtility* util; 38extern OlyUtility* util;
37 39
38#endif // OLY_UTILITY_H 40#endif // OLY_UTILITY_H
diff --git a/daemon/Sender.cpp b/daemon/Sender.cpp
index eba8343..54f2207 100644
--- a/daemon/Sender.cpp
+++ b/daemon/Sender.cpp
@@ -17,8 +17,6 @@
17#include "Logging.h" 17#include "Logging.h"
18#include "SessionData.h" 18#include "SessionData.h"
19 19
20extern void handleException();
21
22Sender::Sender(OlySocket* socket) { 20Sender::Sender(OlySocket* socket) {
23 mDataFile = NULL; 21 mDataFile = NULL;
24 mDataSocket = NULL; 22 mDataSocket = NULL;
@@ -37,7 +35,7 @@ Sender::Sender(OlySocket* socket) {
37 } 35 }
38 } 36 }
39 37
40 // Send magic sequence - must be done first, afterwhich error messages can be sent 38 // Send magic sequence - must be done first, after which error messages can be sent
41 char magic[32]; 39 char magic[32];
42 snprintf(magic, 32, "GATOR %i\n", PROTOCOL_VERSION); 40 snprintf(magic, 32, "GATOR %i\n", PROTOCOL_VERSION);
43 mDataSocket->send(magic, strlen(magic)); 41 mDataSocket->send(magic, strlen(magic));
diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp
index 5aa3f11..53a3ea6 100644
--- a/daemon/SessionData.cpp
+++ b/daemon/SessionData.cpp
@@ -10,7 +10,6 @@
10#include "SessionData.h" 10#include "SessionData.h"
11#include "SessionXML.h" 11#include "SessionXML.h"
12#include "Logging.h" 12#include "Logging.h"
13extern void handleException();
14 13
15SessionData* gSessionData = NULL; 14SessionData* gSessionData = NULL;
16 15
diff --git a/daemon/SessionData.h b/daemon/SessionData.h
index 00a71b1..e0e0b7a 100644
--- a/daemon/SessionData.h
+++ b/daemon/SessionData.h
@@ -13,7 +13,7 @@
13#define MAX_STRING_LEN 80 13#define MAX_STRING_LEN 80
14#define MAX_DESCRIPTION_LEN 400 14#define MAX_DESCRIPTION_LEN 400
15 15
16#define PROTOCOL_VERSION 11 16#define PROTOCOL_VERSION 12
17#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions 17#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions
18 18
19struct ImageLinkList { 19struct ImageLinkList {
diff --git a/daemon/SessionXML.cpp b/daemon/SessionXML.cpp
index 4c373d8..b2b6c30 100644
--- a/daemon/SessionXML.cpp
+++ b/daemon/SessionXML.cpp
@@ -13,8 +13,6 @@
13#include "Logging.h" 13#include "Logging.h"
14#include "OlyUtility.h" 14#include "OlyUtility.h"
15 15
16extern void handleException();
17
18static const char* TAG_SESSION = "session"; 16static const char* TAG_SESSION = "session";
19static const char* TAG_IMAGE = "image"; 17static const char* TAG_IMAGE = "image";
20 18
diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp
index 3f59eab..d13cf1d 100644
--- a/daemon/StreamlineSetup.cpp
+++ b/daemon/StreamlineSetup.cpp
@@ -22,8 +22,6 @@
22#include "StreamlineSetup.h" 22#include "StreamlineSetup.h"
23#include "ConfigurationXML.h" 23#include "ConfigurationXML.h"
24 24
25extern void handleException();
26
27static const char* TAG_SESSION = "session"; 25static const char* TAG_SESSION = "session";
28static const char* TAG_REQUEST = "request"; 26static const char* TAG_REQUEST = "request";
29static const char* TAG_CONFIGURATIONS = "configurations"; 27static const char* TAG_CONFIGURATIONS = "configurations";
diff --git a/daemon/escape.c b/daemon/escape.c
new file mode 100644
index 0000000..c0f47f1
--- /dev/null
+++ b/daemon/escape.c
@@ -0,0 +1,63 @@
1/**
2 * Copyright (C) ARM Limited 2010-2012. 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 <errno.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <ctype.h>
14
15static void print_escaped_path(char *path) {
16 if (isdigit(*path)) {
17 printf("__");
18 }
19 for (; *path != '\0'; ++path) {
20 printf("%c", isalnum(*path) ? *path : '_');
21 }
22}
23
24int main(int argc, char *argv[]) {
25 int i;
26 char *path;
27 FILE *in = NULL;
28 int ch;
29 unsigned int len = 0;
30
31 for (i = 1; i < argc && argv[i][0] == '-'; ++i) ;
32 if (i == argc) {
33 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
34 return EXIT_FAILURE;
35 }
36 path = argv[i];
37
38 errno = 0;
39 if ((in = fopen(path, "r")) == NULL) {
40 fprintf(stderr, "Unable to open '%s': %s\n", path, strerror(errno));
41 return EXIT_FAILURE;
42 }
43
44 printf("static const unsigned char ");
45 print_escaped_path(path);
46 printf("[] = {");
47 for (; (ch = fgetc(in)) != EOF; ++len) {
48 if (len != 0) {
49 printf(",");
50 }
51 if (len % 12 == 0) {
52 printf("\n ");
53 }
54 printf(" 0x%.2x", ch);
55 }
56 printf("\n};\nstatic const unsigned int ");
57 print_escaped_path(path);
58 printf("_len = %i;\n", len);
59
60 fclose(in);
61
62 return EXIT_SUCCESS;
63}
diff --git a/daemon/events-Cortex-A15.xml b/daemon/events-Cortex-A15.xml
index 0ec196f..e0bd201 100644
--- a/daemon/events-Cortex-A15.xml
+++ b/daemon/events-Cortex-A15.xml
@@ -65,4 +65,4 @@
65 <event event="0x7c" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/> 65 <event event="0x7c" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
66 <event event="0x7d" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/> 66 <event event="0x7d" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
67 <event event="0x7e" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/> 67 <event event="0x7e" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
68 </category> 68 </category>
diff --git a/daemon/events-Cortex-A53.xml b/daemon/events-Cortex-A53.xml
new file mode 100644
index 0000000..3fa9c66
--- /dev/null
+++ b/daemon/events-Cortex-A53.xml
@@ -0,0 +1,171 @@
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">
3 <!-- 0x11 CPU_CYCLES - Cycle -->
4 <event counter="ARM_Cortex-A53_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="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"/>
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"/>
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"/>
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"/>
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"/>
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"/>
17 <!-- 0x08 INST_RETIRED - Instruction architecturally executed -->
18 <event event="0x08" title="-" name="INST_RETIRED" description="Instruction architecturally executed"/>
19 <!-- 0x09 EXC_TAKEN - Exception taken -->
20 <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"/>
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"/>
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"/>
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"/>
29 <!-- 0x13 MEM_ACCESS - Data memory access -->
30 <event event="0x13" title="-" name="MEM_ACCESS" description="Data memory access"/>
31 <!-- 0x14 L1I_CACHE - Level 1 instruction cache access -->
32 <event event="0x14" title="-" name="L1I_CACHE" description="Level 1 instruction cache access"/>
33 <!-- 0x15 L1D_CACHE_WB - Level 1 data cache Write-Back -->
34 <event event="0x15" title="-" name="L1D_CACHE_WB" description="Level 1 data cache Write-Back"/>
35 <!-- 0x16 L2D_CACHE - Level 2 data cache access -->
36 <event event="0x16" title="-" name="L2D_CACHE" description="Level 2 data cache access"/>
37 <!-- 0x17 L2D_CACHE_REFILL - Level 2 data cache refill -->
38 <event event="0x17" title="-" name="L2D_CACHE_REFILL" description="Level 2 data cache refill"/>
39 <!-- 0x18 L2D_CACHE_WB - Level 2 data cache Write-Back -->
40 <event event="0x18" title="-" name="L2D_CACHE_WB" description="Level 2 data cache Write-Back"/>
41 <!-- 0x19 BUS_ACCESS - Bus access -->
42 <event event="0x19" title="-" name="BUS_ACCESS" description="Bus access"/>
43 <!-- 0x1A MEMORY_ERROR - Local memory error -->
44 <event event="0x1A" title="-" name="MEMORY_ERROR" description="Local memory error"/>
45 <!-- 0x1B INST_SPEC - Operation speculatively executed -->
46 <event event="0x1B" title="-" name="INST_SPEC" 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="-" name="TTBR_WRITE_RETIRED" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
49 <!-- 0x1D BUS_CYCLES - Bus cycle -->
50 <event event="0x1D" title="-" name="BUS_CYCLES" description="Bus cycle"/>
51 <!-- 0x1E CHAIN - Odd performance counter chain mode -->
52 <event event="0x1E" title="-" name="CHAIN" description="Odd performance counter chain mode"/>
53 <!-- 0x40 L1D_CACHE_LD - Level 1 data cache access - Read -->
54 <event event="0x40" title="-" name="L1D_CACHE_LD" description="Level 1 data cache access - Read"/>
55 <!-- 0x41 L1D_CACHE_ST - Level 1 data cache access - Write -->
56 <event event="0x41" title="-" name="L1D_CACHE_ST" description="Level 1 data cache access - Write"/>
57 <!-- 0x42 L1D_CACHE_REFILL_LD - Level 1 data cache refill - Read -->
58 <event event="0x42" title="-" name="L1D_CACHE_REFILL_LD" description="Level 1 data cache refill - Read"/>
59 <!-- 0x43 L1D_CACHE_REFILL_ST - Level 1 data cache refill - Write -->
60 <event event="0x43" title="-" name="L1D_CACHE_REFILL_ST" 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="-" name="L1D_CACHE_WB_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="-" name="L1D_CACHE_WB_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="-" name="L1D_CACHE_INVAL" description="Level 1 data cache invalidate"/>
67 <!-- 0x4C L1D_TLB_REFILL_LD - Level 1 data TLB refill - Read -->
68 <event event="0x4C" title="-" name="L1D_TLB_REFILL_LD" description="Level 1 data TLB refill - Read"/>
69 <!-- 0x4D L1D_TLB_REFILL_ST - Level 1 data TLB refill - Write -->
70 <event event="0x4D" title="-" name="L1D_TLB_REFILL_ST" description="Level 1 data TLB refill - Write"/>
71 <!-- 0x50 L2D_CACHE_LD - Level 2 data cache access - Read -->
72 <event event="0x50" title="-" name="L2D_CACHE_LD" description="Level 2 data cache access - Read"/>
73 <!-- 0x51 L2D_CACHE_ST - Level 2 data cache access - Write -->
74 <event event="0x51" title="-" name="L2D_CACHE_ST" description="Level 2 data cache access - Write"/>
75 <!-- 0x52 L2D_CACHE_REFILL_LD - Level 2 data cache refill - Read -->
76 <event event="0x52" title="-" name="L2D_CACHE_REFILL_LD" description="Level 2 data cache refill - Read"/>
77 <!-- 0x53 L2D_CACHE_REFILL_ST - Level 2 data cache refill - Write -->
78 <event event="0x53" title="-" name="L2D_CACHE_REFILL_ST" 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="-" name="L2D_CACHE_WB_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="-" name="L2D_CACHE_WB_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="-" name="L2D_CACHE_INVAL" description="Level 2 data cache invalidate"/>
85 <!-- 0x60 BUS_ACCESS_LD - Bus access - Read -->
86 <event event="0x60" title="-" name="BUS_ACCESS_LD" description="Bus access - Read"/>
87 <!-- 0x61 BUS_ACCESS_ST - Bus access - Write -->
88 <event event="0x61" title="-" name="BUS_ACCESS_ST" description="Bus access - Write"/>
89 <!-- 0x62 BUS_ACCESS_SHARED - Bus access - Normal -->
90 <event event="0x62" title="-" name="BUS_ACCESS_SHARED" description="Bus access - Normal"/>
91 <!-- 0x63 BUS_ACCESS_NOT_SHARED - Bus access - Not normal -->
92 <event event="0x63" title="-" name="BUS_ACCESS_NOT_SHARED" description="Bus access - Not normal"/>
93 <!-- 0x64 BUS_ACCESS_NORMAL - Bus access - Normal -->
94 <event event="0x64" title="-" name="BUS_ACCESS_NORMAL" description="Bus access - Normal"/>
95 <!-- 0x65 BUS_ACCESS_PERIPH - Bus access - Peripheral -->
96 <event event="0x65" title="-" name="BUS_ACCESS_PERIPH" description="Bus access - Peripheral"/>
97 <!-- 0x66 MEM_ACCESS_LD - Data memory access - Read -->
98 <event event="0x66" title="-" name="MEM_ACCESS_LD" description="Data memory access - Read"/>
99 <!-- 0x67 MEM_ACCESS_ST - Data memory access - Write -->
100 <event event="0x67" title="-" name="MEM_ACCESS_ST" description="Data memory access - Write"/>
101 <!-- 0x68 UNALIGNED_LD_SPEC - Unaligned access - Read -->
102 <event event="0x68" title="-" name="UNALIGNED_LD_SPEC" description="Unaligned access - Read"/>
103 <!-- 0x69 UNALIGNED_ST_SPEC - Unaligned access - Write -->
104 <event event="0x69" title="-" name="UNALIGNED_ST_SPEC" description="Unaligned access - Write"/>
105 <!-- 0x6A UNALIGNED_LDST_SPEC - Unaligned access -->
106 <event event="0x6A" title="-" name="UNALIGNED_LDST_SPEC" description="Unaligned access"/>
107 <!-- 0x6C LDREX_SPEC - Exclusive operation speculatively executed - LDREX -->
108 <event event="0x6C" title="-" name="LDREX_SPEC" description="Exclusive operation speculatively executed - LDREX"/>
109 <!-- 0x6D STREX_PASS_SPEC - Exclusive instruction speculatively executed - STREX pass -->
110 <event event="0x6D" title="-" name="STREX_PASS_SPEC" description="Exclusive instruction speculatively executed - STREX pass"/>
111 <!-- 0x6E STREX_FAIL_SPEC - Exclusive operation speculatively executed - STREX fail -->
112 <event event="0x6E" title="-" name="STREX_FAIL_SPEC" description="Exclusive operation speculatively executed - STREX fail"/>
113 <!-- 0x70 LD_SPEC - Operation speculatively executed - Load -->
114 <event event="0x70" title="-" name="LD_SPEC" description="Operation speculatively executed - Load"/>
115 <!-- 0x71 ST_SPEC - Operation speculatively executed - Store -->
116 <event event="0x71" title="-" name="ST_SPEC" description="Operation speculatively executed - Store"/>
117 <!-- 0x72 LDST_SPEC - Operation speculatively executed - Load or store -->
118 <event event="0x72" title="-" name="LDST_SPEC" description="Operation speculatively executed - Load or store"/>
119 <!-- 0x73 DP_SPEC - Operation speculatively executed - Integer data processing -->
120 <event event="0x73" title="-" name="DP_SPEC" description="Operation speculatively executed - Integer data processing"/>
121 <!-- 0x74 ASE_SPEC - Operation speculatively executed - Advanced SIMD -->
122 <event event="0x74" title="-" name="ASE_SPEC" description="Operation speculatively executed - Advanced SIMD"/>
123 <!-- 0x75 VFP_SPEC - Operation speculatively executed - VFP -->
124 <event event="0x75" title="-" name="VFP_SPEC" description="Operation speculatively executed - VFP"/>
125 <!-- 0x76 PC_WRITE_SPEC - Operation speculatively executed - Software change of the PC -->
126 <event event="0x76" title="-" name="PC_WRITE_SPEC" description="Operation speculatively executed - Software change of the PC"/>
127 <!-- 0x77 CRYPTO_SPEC - Operation speculatively executed, crypto data processing -->
128 <event event="0x77" title="-" name="CRYPTO_SPEC" description="Operation speculatively executed, crypto data processing"/>
129 <!-- 0x78 BR_IMMED_SPEC - Branch speculatively executed - Immediate branch -->
130 <event event="0x78" title="-" name="BR_IMMED_SPEC" description="Branch speculatively executed - Immediate branch"/>
131 <!-- 0x79 BR_RETURN_SPEC - Branch speculatively executed - Procedure return -->
132 <event event="0x79" title="-" name="BR_RETURN_SPEC" description="Branch speculatively executed - Procedure return"/>
133 <!-- 0x7A BR_INDIRECT_SPEC - Branch speculatively executed - Indirect branch -->
134 <event event="0x7A" title="-" name="BR_INDIRECT_SPEC" description="Branch speculatively executed - Indirect branch"/>
135 <!-- 0x7C ISB_SPEC - Barrier speculatively executed - ISB -->
136 <event event="0x7C" title="-" name="ISB_SPEC" description="Barrier speculatively executed - ISB"/>
137 <!-- 0x7D DSB_SPEC - Barrier speculatively executed - DSB -->
138 <event event="0x7D" title="-" name="DSB_SPEC" description="Barrier speculatively executed - DSB"/>
139 <!-- 0x7E DMB_SPEC - Barrier speculatively executed - DMB -->
140 <event event="0x7E" title="-" name="DMB_SPEC" description="Barrier speculatively executed - DMB"/>
141 <!-- 0x81 EXC_UNDEF - Exception taken, other synchronous -->
142 <event event="0x81" title="-" name="EXC_UNDEF" description="Exception taken, other synchronous"/>
143 <!-- 0x82 EXC_SVC - Exception taken, Supervisor Call -->
144 <event event="0x82" title="-" name="EXC_SVC" description="Exception taken, Supervisor Call"/>
145 <!-- 0x83 EXC_PABORT - Exception taken, Instruction Abort -->
146 <event event="0x83" title="-" name="EXC_PABORT" description="Exception taken, Instruction Abort"/>
147 <!-- 0x84 EXC_DABORT - Exception taken, Data Abort or SError -->
148 <event event="0x84" title="-" name="EXC_DABORT" description="Exception taken, Data Abort or SError"/>
149 <!-- 0x86 EXC_IRQ - Exception taken, IRQ -->
150 <event event="0x86" title="-" name="EXC_IRQ" description="Exception taken, IRQ"/>
151 <!-- 0x87 EXC_FIQ - Exception taken, FIQ -->
152 <event event="0x87" title="-" name="EXC_FIQ" description="Exception taken, FIQ"/>
153 <!-- 0x88 EXC_SMC - Exception taken, Secure Monitor Call -->
154 <event event="0x88" title="-" name="EXC_SMC" description="Exception taken, Secure Monitor Call"/>
155 <!-- 0x8A EXC_HVC - Exception taken, Hypervisor Call -->
156 <event event="0x8A" title="-" name="EXC_HVC" description="Exception taken, Hypervisor Call"/>
157 <!-- 0x8B EXC_TRAP_PABORT - Exception taken, Instruction Abort not taken locally -->
158 <event event="0x8B" title="-" name="EXC_TRAP_PABORT" 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="-" name="EXC_TRAP_DABORT" 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="-" name="EXC_TRAP_OTHER" description="Exception taken – Other traps not taken locally"/>
163 <!-- 0x8E EXC_TRAP_IRQ - Exception taken, IRQ not taken locally -->
164 <event event="0x8E" title="-" name="EXC_TRAP_IRQ" description="Exception taken, IRQ not taken locally"/>
165 <!-- 0x8F EXC_TRAP_FIQ - Exception taken, FIQ not taken locally -->
166 <event event="0x8F" title="-" name="EXC_TRAP_FIQ" description="Exception taken, FIQ not taken locally"/>
167 <!-- 0x90 RC_LD_SPEC - Release consistency instruction speculatively executed – Load Acquire -->
168 <event event="0x90" title="-" name="RC_LD_SPEC" 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="-" name="RC_ST_SPEC" description="Release consistency instruction speculatively executed – Store Release"/>
171 </category>
diff --git a/daemon/events-Cortex-A57.xml b/daemon/events-Cortex-A57.xml
new file mode 100644
index 0000000..5db6dc2
--- /dev/null
+++ b/daemon/events-Cortex-A57.xml
@@ -0,0 +1,171 @@
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">
3 <!-- 0x11 CPU_CYCLES - Cycle -->
4 <event counter="ARM_Cortex-A57_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
5 <!-- 0x00 SW_INCR - Instruction architecturally executed number (condition check pass) - Software increment -->
6 <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"/>
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"/>
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"/>
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"/>
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"/>
17 <!-- 0x08 INST_RETIRED - Instruction architecturally executed -->
18 <event event="0x08" title="-" name="INST_RETIRED" description="Instruction architecturally executed"/>
19 <!-- 0x09 EXC_TAKEN - Exception taken -->
20 <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"/>
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"/>
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"/>
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"/>
29 <!-- 0x13 MEM_ACCESS - Data memory access -->
30 <event event="0x13" title="-" name="MEM_ACCESS" description="Data memory access"/>
31 <!-- 0x14 L1I_CACHE - Level 1 instruction cache access -->
32 <event event="0x14" title="-" name="L1I_CACHE" description="Level 1 instruction cache access"/>
33 <!-- 0x15 L1D_CACHE_WB - Level 1 data cache Write-Back -->
34 <event event="0x15" title="-" name="L1D_CACHE_WB" description="Level 1 data cache Write-Back"/>
35 <!-- 0x16 L2D_CACHE - Level 2 data cache access -->
36 <event event="0x16" title="-" name="L2D_CACHE" description="Level 2 data cache access"/>
37 <!-- 0x17 L2D_CACHE_REFILL - Level 2 data cache refill -->
38 <event event="0x17" title="-" name="L2D_CACHE_REFILL" description="Level 2 data cache refill"/>
39 <!-- 0x18 L2D_CACHE_WB - Level 2 data cache Write-Back -->
40 <event event="0x18" title="-" name="L2D_CACHE_WB" description="Level 2 data cache Write-Back"/>
41 <!-- 0x19 BUS_ACCESS - Bus access -->
42 <event event="0x19" title="-" name="BUS_ACCESS" description="Bus access"/>
43 <!-- 0x1A MEMORY_ERROR - Local memory error -->
44 <event event="0x1A" title="-" name="MEMORY_ERROR" description="Local memory error"/>
45 <!-- 0x1B INST_SPEC - Operation speculatively executed -->
46 <event event="0x1B" title="-" name="INST_SPEC" 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="-" name="TTBR_WRITE_RETIRED" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
49 <!-- 0x1D BUS_CYCLES - Bus cycle -->
50 <event event="0x1D" title="-" name="BUS_CYCLES" description="Bus cycle"/>
51 <!-- 0x1E CHAIN - Odd performance counter chain mode -->
52 <event event="0x1E" title="-" name="CHAIN" description="Odd performance counter chain mode"/>
53 <!-- 0x40 L1D_CACHE_LD - Level 1 data cache access - Read -->
54 <event event="0x40" title="-" name="L1D_CACHE_LD" description="Level 1 data cache access - Read"/>
55 <!-- 0x41 L1D_CACHE_ST - Level 1 data cache access - Write -->
56 <event event="0x41" title="-" name="L1D_CACHE_ST" description="Level 1 data cache access - Write"/>
57 <!-- 0x42 L1D_CACHE_REFILL_LD - Level 1 data cache refill - Read -->
58 <event event="0x42" title="-" name="L1D_CACHE_REFILL_LD" description="Level 1 data cache refill - Read"/>
59 <!-- 0x43 L1D_CACHE_REFILL_ST - Level 1 data cache refill - Write -->
60 <event event="0x43" title="-" name="L1D_CACHE_REFILL_ST" 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="-" name="L1D_CACHE_WB_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="-" name="L1D_CACHE_WB_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="-" name="L1D_CACHE_INVAL" description="Level 1 data cache invalidate"/>
67 <!-- 0x4C L1D_TLB_REFILL_LD - Level 1 data TLB refill - Read -->
68 <event event="0x4C" title="-" name="L1D_TLB_REFILL_LD" description="Level 1 data TLB refill - Read"/>
69 <!-- 0x4D L1D_TLB_REFILL_ST - Level 1 data TLB refill - Write -->
70 <event event="0x4D" title="-" name="L1D_TLB_REFILL_ST" description="Level 1 data TLB refill - Write"/>
71 <!-- 0x50 L2D_CACHE_LD - Level 2 data cache access - Read -->
72 <event event="0x50" title="-" name="L2D_CACHE_LD" description="Level 2 data cache access - Read"/>
73 <!-- 0x51 L2D_CACHE_ST - Level 2 data cache access - Write -->
74 <event event="0x51" title="-" name="L2D_CACHE_ST" description="Level 2 data cache access - Write"/>
75 <!-- 0x52 L2D_CACHE_REFILL_LD - Level 2 data cache refill - Read -->
76 <event event="0x52" title="-" name="L2D_CACHE_REFILL_LD" description="Level 2 data cache refill - Read"/>
77 <!-- 0x53 L2D_CACHE_REFILL_ST - Level 2 data cache refill - Write -->
78 <event event="0x53" title="-" name="L2D_CACHE_REFILL_ST" 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="-" name="L2D_CACHE_WB_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="-" name="L2D_CACHE_WB_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="-" name="L2D_CACHE_INVAL" description="Level 2 data cache invalidate"/>
85 <!-- 0x60 BUS_ACCESS_LD - Bus access - Read -->
86 <event event="0x60" title="-" name="BUS_ACCESS_LD" description="Bus access - Read"/>
87 <!-- 0x61 BUS_ACCESS_ST - Bus access - Write -->
88 <event event="0x61" title="-" name="BUS_ACCESS_ST" description="Bus access - Write"/>
89 <!-- 0x62 BUS_ACCESS_SHARED - Bus access - Normal -->
90 <event event="0x62" title="-" name="BUS_ACCESS_SHARED" description="Bus access - Normal"/>
91 <!-- 0x63 BUS_ACCESS_NOT_SHARED - Bus access - Not normal -->
92 <event event="0x63" title="-" name="BUS_ACCESS_NOT_SHARED" description="Bus access - Not normal"/>
93 <!-- 0x64 BUS_ACCESS_NORMAL - Bus access - Normal -->
94 <event event="0x64" title="-" name="BUS_ACCESS_NORMAL" description="Bus access - Normal"/>
95 <!-- 0x65 BUS_ACCESS_PERIPH - Bus access - Peripheral -->
96 <event event="0x65" title="-" name="BUS_ACCESS_PERIPH" description="Bus access - Peripheral"/>
97 <!-- 0x66 MEM_ACCESS_LD - Data memory access - Read -->
98 <event event="0x66" title="-" name="MEM_ACCESS_LD" description="Data memory access - Read"/>
99 <!-- 0x67 MEM_ACCESS_ST - Data memory access - Write -->
100 <event event="0x67" title="-" name="MEM_ACCESS_ST" description="Data memory access - Write"/>
101 <!-- 0x68 UNALIGNED_LD_SPEC - Unaligned access - Read -->
102 <event event="0x68" title="-" name="UNALIGNED_LD_SPEC" description="Unaligned access - Read"/>
103 <!-- 0x69 UNALIGNED_ST_SPEC - Unaligned access - Write -->
104 <event event="0x69" title="-" name="UNALIGNED_ST_SPEC" description="Unaligned access - Write"/>
105 <!-- 0x6A UNALIGNED_LDST_SPEC - Unaligned access -->
106 <event event="0x6A" title="-" name="UNALIGNED_LDST_SPEC" description="Unaligned access"/>
107 <!-- 0x6C LDREX_SPEC - Exclusive operation speculatively executed - LDREX -->
108 <event event="0x6C" title="-" name="LDREX_SPEC" description="Exclusive operation speculatively executed - LDREX"/>
109 <!-- 0x6D STREX_PASS_SPEC - Exclusive instruction speculatively executed - STREX pass -->
110 <event event="0x6D" title="-" name="STREX_PASS_SPEC" description="Exclusive instruction speculatively executed - STREX pass"/>
111 <!-- 0x6E STREX_FAIL_SPEC - Exclusive operation speculatively executed - STREX fail -->
112 <event event="0x6E" title="-" name="STREX_FAIL_SPEC" description="Exclusive operation speculatively executed - STREX fail"/>
113 <!-- 0x70 LD_SPEC - Operation speculatively executed - Load -->
114 <event event="0x70" title="-" name="LD_SPEC" description="Operation speculatively executed - Load"/>
115 <!-- 0x71 ST_SPEC - Operation speculatively executed - Store -->
116 <event event="0x71" title="-" name="ST_SPEC" description="Operation speculatively executed - Store"/>
117 <!-- 0x72 LDST_SPEC - Operation speculatively executed - Load or store -->
118 <event event="0x72" title="-" name="LDST_SPEC" description="Operation speculatively executed - Load or store"/>
119 <!-- 0x73 DP_SPEC - Operation speculatively executed - Integer data processing -->
120 <event event="0x73" title="-" name="DP_SPEC" description="Operation speculatively executed - Integer data processing"/>
121 <!-- 0x74 ASE_SPEC - Operation speculatively executed - Advanced SIMD -->
122 <event event="0x74" title="-" name="ASE_SPEC" description="Operation speculatively executed - Advanced SIMD"/>
123 <!-- 0x75 VFP_SPEC - Operation speculatively executed - VFP -->
124 <event event="0x75" title="-" name="VFP_SPEC" description="Operation speculatively executed - VFP"/>
125 <!-- 0x76 PC_WRITE_SPEC - Operation speculatively executed - Software change of the PC -->
126 <event event="0x76" title="-" name="PC_WRITE_SPEC" description="Operation speculatively executed - Software change of the PC"/>
127 <!-- 0x77 CRYPTO_SPEC - Operation speculatively executed, crypto data processing -->
128 <event event="0x77" title="-" name="CRYPTO_SPEC" description="Operation speculatively executed, crypto data processing"/>
129 <!-- 0x78 BR_IMMED_SPEC - Branch speculatively executed - Immediate branch -->
130 <event event="0x78" title="-" name="BR_IMMED_SPEC" description="Branch speculatively executed - Immediate branch"/>
131 <!-- 0x79 BR_RETURN_SPEC - Branch speculatively executed - Procedure return -->
132 <event event="0x79" title="-" name="BR_RETURN_SPEC" description="Branch speculatively executed - Procedure return"/>
133 <!-- 0x7A BR_INDIRECT_SPEC - Branch speculatively executed - Indirect branch -->
134 <event event="0x7A" title="-" name="BR_INDIRECT_SPEC" description="Branch speculatively executed - Indirect branch"/>
135 <!-- 0x7C ISB_SPEC - Barrier speculatively executed - ISB -->
136 <event event="0x7C" title="-" name="ISB_SPEC" description="Barrier speculatively executed - ISB"/>
137 <!-- 0x7D DSB_SPEC - Barrier speculatively executed - DSB -->
138 <event event="0x7D" title="-" name="DSB_SPEC" description="Barrier speculatively executed - DSB"/>
139 <!-- 0x7E DMB_SPEC - Barrier speculatively executed - DMB -->
140 <event event="0x7E" title="-" name="DMB_SPEC" description="Barrier speculatively executed - DMB"/>
141 <!-- 0x81 EXC_UNDEF - Exception taken, other synchronous -->
142 <event event="0x81" title="-" name="EXC_UNDEF" description="Exception taken, other synchronous"/>
143 <!-- 0x82 EXC_SVC - Exception taken, Supervisor Call -->
144 <event event="0x82" title="-" name="EXC_SVC" description="Exception taken, Supervisor Call"/>
145 <!-- 0x83 EXC_PABORT - Exception taken, Instruction Abort -->
146 <event event="0x83" title="-" name="EXC_PABORT" description="Exception taken, Instruction Abort"/>
147 <!-- 0x84 EXC_DABORT - Exception taken, Data Abort or SError -->
148 <event event="0x84" title="-" name="EXC_DABORT" description="Exception taken, Data Abort or SError"/>
149 <!-- 0x86 EXC_IRQ - Exception taken, IRQ -->
150 <event event="0x86" title="-" name="EXC_IRQ" description="Exception taken, IRQ"/>
151 <!-- 0x87 EXC_FIQ - Exception taken, FIQ -->
152 <event event="0x87" title="-" name="EXC_FIQ" description="Exception taken, FIQ"/>
153 <!-- 0x88 EXC_SMC - Exception taken, Secure Monitor Call -->
154 <event event="0x88" title="-" name="EXC_SMC" description="Exception taken, Secure Monitor Call"/>
155 <!-- 0x8A EXC_HVC - Exception taken, Hypervisor Call -->
156 <event event="0x8A" title="-" name="EXC_HVC" description="Exception taken, Hypervisor Call"/>
157 <!-- 0x8B EXC_TRAP_PABORT - Exception taken, Instruction Abort not taken locally -->
158 <event event="0x8B" title="-" name="EXC_TRAP_PABORT" 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="-" name="EXC_TRAP_DABORT" 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="-" name="EXC_TRAP_OTHER" description="Exception taken – Other traps not taken locally"/>
163 <!-- 0x8E EXC_TRAP_IRQ - Exception taken, IRQ not taken locally -->
164 <event event="0x8E" title="-" name="EXC_TRAP_IRQ" description="Exception taken, IRQ not taken locally"/>
165 <!-- 0x8F EXC_TRAP_FIQ - Exception taken, FIQ not taken locally -->
166 <event event="0x8F" title="-" name="EXC_TRAP_FIQ" description="Exception taken, FIQ not taken locally"/>
167 <!-- 0x90 RC_LD_SPEC - Release consistency instruction speculatively executed – Load Acquire -->
168 <event event="0x90" title="-" name="RC_LD_SPEC" 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="-" name="RC_ST_SPEC" description="Release consistency instruction speculatively executed – Store Release"/>
171 </category>
diff --git a/daemon/events-Cortex-A7.xml b/daemon/events-Cortex-A7.xml
index 2bd4797..50bba7f 100644
--- a/daemon/events-Cortex-A7.xml
+++ b/daemon/events-Cortex-A7.xml
@@ -41,4 +41,4 @@
41 <event event="0xC8" title="ETM" name="ETM Ext Out[1]" description=""/> 41 <event event="0xC8" title="ETM" name="ETM Ext Out[1]" description=""/>
42 <event event="0xC9" title="Instruction" name="Pipeline stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/> 42 <event event="0xC9" title="Instruction" name="Pipeline stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
43 <event event="0xCA" title="Memory" name="Snoop" description="Data snooped from other processor. This event counts memory-read operations that read data from another processor within the local cluster, rather than accessing the L2 cache or issuing an external read."/> 43 <event event="0xCA" title="Memory" name="Snoop" description="Data snooped from other processor. This event counts memory-read operations that read data from another processor within the local cluster, rather than accessing the L2 cache or issuing an external read."/>
44 </category> 44 </category>
diff --git a/daemon/events-Cortex-A9.xml b/daemon/events-Cortex-A9.xml
index 7597f78..89d6a19 100644
--- a/daemon/events-Cortex-A9.xml
+++ b/daemon/events-Cortex-A9.xml
@@ -31,9 +31,9 @@
31 <event event="0x66" title="Pipeline" name="Issue stage no dispatch" description="Counts the number of cycles where the issue stage does not dispatch any instruction because it is empty or cannot dispatch any instructions"/> 31 <event event="0x66" title="Pipeline" name="Issue stage no dispatch" description="Counts the number of cycles where the issue stage does not dispatch any instruction because it is empty or cannot dispatch any instructions"/>
32 <event event="0x67" title="Pipeline" name="Issue stage empty" description="Counts the number of cycles where the issue stage is empty"/> 32 <event event="0x67" title="Pipeline" name="Issue stage empty" description="Counts the number of cycles where the issue stage is empty"/>
33 <event event="0x68" title="Instruction" name="Executed" description="Counts the number of instructions going through the Register Renaming stage. This number is an approximate number of the total number of instructions speculatively executed, and even more approximate of the total number of instructions architecturally executed"/> 33 <event event="0x68" title="Instruction" name="Executed" description="Counts the number of instructions going through the Register Renaming stage. This number is an approximate number of the total number of instructions speculatively executed, and even more approximate of the total number of instructions architecturally executed"/>
34 <event event="0x69" title="Cache" name="Data linefills" description="Counts the number of linefills performed on the external AXI bus"/> 34 <event event="0x69" title="Cache" name="Data linefills" description="Counts the number of linefills performed on the external AXI bus"/>
35 <event event="0x6A" title="Cache" name="Prefetch linefills" description="Counts the number of data linefills caused by prefetcher requests"/> 35 <event event="0x6A" title="Cache" name="Prefetch linefills" description="Counts the number of data linefills caused by prefetcher requests"/>
36 <event event="0x6B" title="Cache" name="Prefetch hits" description="Counts the number of cache hits in a line that belongs to a stream followed by the prefetcher"/> 36 <event event="0x6B" title="Cache" name="Prefetch hits" description="Counts the number of cache hits in a line that belongs to a stream followed by the prefetcher"/>
37 <event event="0x6E" title="Core" name="Functions" description="Counts the number of procedure returns whose condition codes do not fail, excluding all returns from exception"/> 37 <event event="0x6E" title="Core" name="Functions" description="Counts the number of procedure returns whose condition codes do not fail, excluding all returns from exception"/>
38 <event event="0x70" title="Instruction" name="Main execution unit" description="Counts the number of instructions being executed in the main execution pipeline of the processor, the multiply pipeline and arithmetic logic unit pipeline"/> 38 <event event="0x70" title="Instruction" name="Main execution unit" description="Counts the number of instructions being executed in the main execution pipeline of the processor, the multiply pipeline and arithmetic logic unit pipeline"/>
39 <event event="0x71" title="Instruction" name="Second execution unit" description="Counts the number of instructions being executed in the processor second execution pipeline (ALU)"/> 39 <event event="0x71" title="Instruction" name="Second execution unit" description="Counts the number of instructions being executed in the processor second execution pipeline (ALU)"/>
@@ -49,9 +49,9 @@
49 <event event="0x86" title="Stalls" name="DMB" description="Counts the number of stall cycles because of the execution of a DMB memory barrier"/> 49 <event event="0x86" title="Stalls" name="DMB" description="Counts the number of stall cycles because of the execution of a DMB memory barrier"/>
50 <event event="0x8A" title="Clock" name="Integer core" description="Counts the number of cycles during which the integer core clock is enabled"/> 50 <event event="0x8A" title="Clock" name="Integer core" description="Counts the number of cycles during which the integer core clock is enabled"/>
51 <event event="0x8B" title="Clock" name="Data engine" description="Counts the number of cycles during which the Data Engine clock is enabled"/> 51 <event event="0x8B" title="Clock" name="Data engine" description="Counts the number of cycles during which the Data Engine clock is enabled"/>
52 <event event="0x8C" title="Clock" name="NEON" description="Counts the number of cycles when the NEON SIMD clock is enabled"/> 52 <event event="0x8C" title="Clock" name="NEON" description="Counts the number of cycles when the NEON SIMD clock is enabled"/>
53 <event event="0x8D" title="Memory" name="TLB inst allocations" description="Counts the number of TLB allocations because of Instruction requests"/> 53 <event event="0x8D" title="Memory" name="TLB inst allocations" description="Counts the number of TLB allocations because of Instruction requests"/>
54 <event event="0x8E" title="Memory" name="TLB data allocations" description="Counts the number of TLB allocations because of Data requests"/> 54 <event event="0x8E" title="Memory" name="TLB data allocations" description="Counts the number of TLB allocations because of Data requests"/>
55 <event event="0x90" title="Instruction" name="ISB" description="Counts the number of ISB instructions architecturally executed"/> 55 <event event="0x90" title="Instruction" name="ISB" description="Counts the number of ISB instructions architecturally executed"/>
56 <event event="0x91" title="Instruction" name="DSB" description="Counts the number of DSB instructions architecturally executed"/> 56 <event event="0x91" title="Instruction" name="DSB" description="Counts the number of DSB instructions architecturally executed"/>
57 <event event="0x92" title="Instruction" name="DMB" description="Counts the number of DMB instructions speculatively executed"/> 57 <event event="0x92" title="Instruction" name="DMB" description="Counts the number of DMB instructions speculatively executed"/>
diff --git a/daemon/events-Linux.xml b/daemon/events-Linux.xml
index b45a122..42baf14 100644
--- a/daemon/events-Linux.xml
+++ b/daemon/events-Linux.xml
@@ -8,8 +8,8 @@
8 <event counter="Linux_sched_switch" title="Scheduler" name="Switch" per_cpu="yes" description="Context switch events"/> 8 <event counter="Linux_sched_switch" title="Scheduler" name="Switch" per_cpu="yes" description="Context switch events"/>
9 <event counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/> 9 <event counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/>
10 <event counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/> 10 <event counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/>
11 <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" display="maximum" units="B" average_selection="yes" description="Memory used by buffers"/> 11 <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" display="maximum" units="B" average_selection="yes" description="Memory used by OS disk buffers"/>
12 <event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/> 12 <event counter="Linux_power_cpu_freq" title="Clock" name="Frequency" per_cpu="yes" display="maximum" units="Hz" average_selection="yes" description="Frequency setting of the CPU"/>
13 <event counter="Linux_power_cpu_idle" title="Power" name="Idle" per_cpu="yes" display="maximum" average_selection="yes" 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="Power" name="Idle" per_cpu="yes" display="maximum" average_selection="yes" description="CPU Idle State + 1, set the Sample Rate to None to prevent the hrtimer from interrupting the system"/>
14 </category> 14 </category>
15 15
diff --git a/daemon/events-Mali-400.xml b/daemon/events-Mali-400.xml
index 6830d46..cb0b9d5 100644
--- a/daemon/events-Mali-400.xml
+++ b/daemon/events-Mali-400.xml
@@ -30,7 +30,7 @@
30 <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."/> 30 <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."/>
31 <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."/> 31 <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."/>
32 <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."/> 32 <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."/>
33 <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 scissoringi. This includes time spent waiting on the bus."/> 33 <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."/>
34 <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."/> 34 <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."/>
35 </category> 35 </category>
36 <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cnt" per_cpu="no"> 36 <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cnt" per_cpu="no">
@@ -344,10 +344,10 @@
344 </category> 344 </category>
345 <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cnt" per_cpu="no"> 345 <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cnt" per_cpu="no">
346 <!-- EGL Counters --> 346 <!-- EGL Counters -->
347 <event counter="ARM_Mali-400_SW_17" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the the framebuffer from video memory to framebuffer."/> 347 <event counter="ARM_Mali-400_SW_17" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the framebuffer from video memory to framebuffer."/>
348 <!-- glDrawElements Counters --> 348 <!-- glDrawElements Counters -->
349 <event counter="ARM_Mali-400_SW_18" title="glDrawElements Statistics" name="Calls to glDrawElements" description="Number of calls to glDrawElements."/> 349 <event counter="ARM_Mali-400_SW_18" title="glDrawElements Statistics" name="Calls to glDrawElements" description="Number of calls to glDrawElements."/>
350 <event counter="ARM_Mali-400_SW_19" title="glDrawElements Statistics" name="Indices to glDrawElements" description="Number of indicies to glDrawElements."/> 350 <event counter="ARM_Mali-400_SW_19" title="glDrawElements Statistics" name="Indices to glDrawElements" description="Number of indices to glDrawElements."/>
351 <event counter="ARM_Mali-400_SW_20" title="glDrawElements Statistics" name="Transformed by glDrawElements" description="Number of vertices transformed by glDrawElements."/> 351 <event counter="ARM_Mali-400_SW_20" title="glDrawElements Statistics" name="Transformed by glDrawElements" description="Number of vertices transformed by glDrawElements."/>
352 <!-- glDrawArrays Counters --> 352 <!-- glDrawArrays Counters -->
353 <event counter="ARM_Mali-400_SW_21" title="glDrawArrays Statistics" name="Calls to glDrawArrays" description="Number of calls to glDrawArrays."/> 353 <event counter="ARM_Mali-400_SW_21" title="glDrawArrays Statistics" name="Calls to glDrawArrays" description="Number of calls to glDrawArrays."/>
@@ -365,7 +365,7 @@
365 <!-- Buffer Profiling Counters --> 365 <!-- Buffer Profiling Counters -->
366 <event counter="ARM_Mali-400_SW_32" title="Buffer Profiling" name="Texture Upload Time (ms)" description="Time spent uploading textures."/> 366 <event counter="ARM_Mali-400_SW_32" title="Buffer Profiling" name="Texture Upload Time (ms)" description="Time spent uploading textures."/>
367 <event counter="ARM_Mali-400_SW_33" title="Buffer Profiling" name="VBO Upload Time (ms)" description="Time spent uploading vertex buffer objects."/> 367 <event counter="ARM_Mali-400_SW_33" title="Buffer Profiling" name="VBO Upload Time (ms)" description="Time spent uploading vertex buffer objects."/>
368 <event counter="ARM_Mali-400_SW_34" title="Buffer Profiling" name="FBO Flushes" description="Number of flushed on framebuffer attachement."/> 368 <event counter="ARM_Mali-400_SW_34" title="Buffer Profiling" name="FBO Flushes" description="Number of flushed on framebuffer attachment."/>
369 <!-- OpenGL ES 1.1 Emulation --> 369 <!-- OpenGL ES 1.1 Emulation -->
370 <event counter="ARM_Mali-400_SW_35" title="Fixed-function Emulation" name="# Vertex Shaders Generated" description="Number of vertex shaders generated."/> 370 <event counter="ARM_Mali-400_SW_35" title="Fixed-function Emulation" name="# Vertex Shaders Generated" description="Number of vertex shaders generated."/>
371 <event counter="ARM_Mali-400_SW_36" title="Fixed-function Emulation" name="# Fragment Shaders Generated" description="Number of fragment shaders generated."/> 371 <event counter="ARM_Mali-400_SW_36" title="Fixed-function Emulation" name="# Fragment Shaders Generated" description="Number of fragment shaders generated."/>
diff --git a/daemon/events-Mali-T6xx.xml b/daemon/events-Mali-T6xx.xml
index 5237e30..3d795de 100644
--- a/daemon/events-Mali-T6xx.xml
+++ b/daemon/events-Mali-T6xx.xml
@@ -1,8 +1,8 @@
1 1
2 <category name="Mali-T6xx-SW-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."/> 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."/>
4 </category> 4 </category>
5 5
6 <category name="Mali-T6xx-PMShader" per_cpu="no"> 6 <category name="Mali-T6xx-PMShader" per_cpu="no">
7 <event counter="ARM_Mali-T6xx_PM_SHADER_0" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 0" description="Mali PM Shader: PM Shader Core 0."/> 7 <event counter="ARM_Mali-T6xx_PM_SHADER_0" display="average" average_selection="yes" units="%" 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" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 1" description="Mali PM Shader: PM Shader Core 1."/> 8 <event counter="ARM_Mali-T6xx_PM_SHADER_1" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 1" description="Mali PM Shader: PM Shader Core 1."/>
@@ -13,23 +13,23 @@
13 <event counter="ARM_Mali-T6xx_PM_SHADER_6" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 6" description="Mali PM Shader: PM Shader Core 6."/> 13 <event counter="ARM_Mali-T6xx_PM_SHADER_6" display="average" average_selection="yes" units="%" 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" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 7" description="Mali PM Shader: PM Shader Core 7."/> 14 <event counter="ARM_Mali-T6xx_PM_SHADER_7" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 7" description="Mali PM Shader: PM Shader Core 7."/>
15 </category> 15 </category>
16 16
17 <category name="Mali-T6xx-PMTiler" 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" units="%" title="Mali PM Tiler" name="PM Tiler Core 0" description="Mali PM Tiler: PM Tiler Core 0."/> 18 <event counter="ARM_Mali-T6xx_PM_TILER_0" display="average" average_selection="yes" units="%" title="Mali PM Tiler" name="PM Tiler Core 0" description="Mali PM Tiler: PM Tiler Core 0."/>
19 </category> 19 </category>
20 20
21 <category name="Mali-T6xx-PML2" 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" units="%" title="Mali PM L2" name="PM L2 Core 0" description="Mali PM L2: PM L2 Core 0."/> 22 <event counter="ARM_Mali-T6xx_PM_L2_0" display="average" average_selection="yes" units="%" 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" units="%" title="Mali PM L2" name="PM L2 Core 1" description="Mali PM L2: PM L2 Core 1."/> 23 <event counter="ARM_Mali-T6xx_PM_L2_1" display="average" average_selection="yes" units="%" title="Mali PM L2" name="PM L2 Core 1" description="Mali PM L2: PM L2 Core 1."/>
24 </category> 24 </category>
25 25
26 <category name="Mali-T6xx-MMU_AS" 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" units="%" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/> 27 <event counter="ARM_Mali-T6xx_MMU_AS_0" display="average" average_selection="yes" units="%" 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" units="%" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/> 28 <event counter="ARM_Mali-T6xx_MMU_AS_1" display="average" average_selection="yes" units="%" 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" units="%" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/> 29 <event counter="ARM_Mali-T6xx_MMU_AS_2" display="average" average_selection="yes" units="%" 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" units="%" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/> 30 <event counter="ARM_Mali-T6xx_MMU_AS_3" display="average" average_selection="yes" units="%" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/>
31 </category> 31 </category>
32 32
33 <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."/> 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."/>
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."/> 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."/>
diff --git a/daemon/events-Mali-T6xx_hw.xml b/daemon/events-Mali-T6xx_hw.xml
index 77f7aec..825b668 100644
--- a/daemon/events-Mali-T6xx_hw.xml
+++ b/daemon/events-Mali-T6xx_hw.xml
@@ -1,5 +1,5 @@
1 1
2 <category name="Mali-T6xx-JobManager" per_cpu="no"> 2 <category name="Mali-T6xx-JobManager" per_cpu="no">
3 <event counter="ARM_Mali-T6xx_MESSAGES_SENT" title="Mali GPU Job Manager" name="Job Manager messages sent" description="Number of JCB messages sent by the Job Manager."/> 3 <event counter="ARM_Mali-T6xx_MESSAGES_SENT" title="Mali GPU Job Manager" name="Job Manager messages sent" description="Number of JCB messages sent by the Job Manager."/>
4 <event counter="ARM_Mali-T6xx_MESSAGES_RECEIVED" title="Mali GPU Job Manager" name="Job Manager messages received " description="Number of JCB messages received by the Job Manager."/> 4 <event counter="ARM_Mali-T6xx_MESSAGES_RECEIVED" title="Mali GPU Job Manager" name="Job Manager messages received " description="Number of JCB messages received by the Job Manager."/>
5 <event counter="ARM_Mali-T6xx_GPU_ACTIVE" title="Mali GPU Job Manager" name="GPU active cycles" description="Number of cycles the GPU was active."/> 5 <event counter="ARM_Mali-T6xx_GPU_ACTIVE" title="Mali GPU Job Manager" name="GPU active cycles" description="Number of cycles the GPU was active."/>
@@ -63,7 +63,7 @@
63--> 63-->
64 </category> 64 </category>
65 65
66 <category name="Mali-T6xx-Tiler" per_cpu="no"> 66 <category name="Mali-T6xx-Tiler" per_cpu="no">
67<!-- 67<!--
68 <event counter="ARM_Mali-T6xx_JOBS_PROCESSED" title="Mali GPU Tiler" name="Jobs processed" description="Number of jobs processed."/> 68 <event counter="ARM_Mali-T6xx_JOBS_PROCESSED" title="Mali GPU Tiler" name="Jobs processed" description="Number of jobs processed."/>
69--> 69-->
@@ -119,7 +119,7 @@
119 119
120 <event counter="ARM_Mali-T6xx_WRBUF_STALL" title="Mali GPU Tiler" name="Write-buffer stalls" description="Number of write-buffer stalls."/> 120 <event counter="ARM_Mali-T6xx_WRBUF_STALL" title="Mali GPU Tiler" name="Write-buffer stalls" description="Number of write-buffer stalls."/>
121 <event counter="ARM_Mali-T6xx_ACTIVE" title="Mali GPU Tiler" name="Tiler active cycles" description="Number of cycles the tiler is active."/> 121 <event counter="ARM_Mali-T6xx_ACTIVE" title="Mali GPU Tiler" name="Tiler active cycles" description="Number of cycles the tiler is active."/>
122 <event counter="ARM_Mali-T6xx_LOADING_DESC" title="Mali GPU Tiler" name="Cycles loading descriptors" description="Number of cycle spent loading descriptors while the tiler frontend is otherwise idle."/> 122 <event counter="ARM_Mali-T6xx_LOADING_DESC" title="Mali GPU Tiler" name="Cycles loading descriptors" description="Number of cycle spent loading descriptors while the tiler frontend is otherwise idle."/>
123 <event counter="ARM_Mali-T6xx_INDEX_WAIT" title="Mali GPU Tiler" name="Cycles index fetch miss" description="Number of cycles the vertex cache could accept an index, but due to a miss, the index fetcher could not provide one."/> 123 <event counter="ARM_Mali-T6xx_INDEX_WAIT" title="Mali GPU Tiler" name="Cycles index fetch miss" description="Number of cycles the vertex cache could accept an index, but due to a miss, the index fetcher could not provide one."/>
124 124
125 <event counter="ARM_Mali-T6xx_INDEX_RANGE_WAIT" title="Mali GPU Tiler" name="Cycles index out of range" description="Number of cycles the index fetcher provides an index, but the index is outside the range of currently shaded vertices. Only relevant for fused jobs."/> 125 <event counter="ARM_Mali-T6xx_INDEX_RANGE_WAIT" title="Mali GPU Tiler" name="Cycles index out of range" description="Number of cycles the index fetcher provides an index, but the index is outside the range of currently shaded vertices. Only relevant for fused jobs."/>
@@ -132,7 +132,7 @@
132 132
133 <event counter="ARM_Mali-T6xx_UTLB_STALL" title="Mali GPU Tiler" name="uTLB cycles stall" description="uTLB: Cycles with stall on input AXI address channel."/> 133 <event counter="ARM_Mali-T6xx_UTLB_STALL" title="Mali GPU Tiler" name="uTLB cycles stall" description="uTLB: Cycles with stall on input AXI address channel."/>
134 134
135 <event counter="ARM_Mali-T6xx_UTLB_REPLAY_MISS" title="Mali GPU Tiler" name="uTLB replay buffer cache misses" description="uTLB: Number of cache misses on accesses from replay buffer."/> 135 <event counter="ARM_Mali-T6xx_UTLB_REPLAY_MISS" title="Mali GPU Tiler" name="uTLB replay buffer cache misses" description="uTLB: Number of cache misses on accesses from replay buffer."/>
136 <event counter="ARM_Mali-T6xx_UTLB_REPLAY_FULL" title="Mali GPU Tiler" name="uTLB cycle reply buffer full" description="uTLB: Number of cycles replay buffer is full."/> 136 <event counter="ARM_Mali-T6xx_UTLB_REPLAY_FULL" title="Mali GPU Tiler" name="uTLB cycle reply buffer full" description="uTLB: Number of cycles replay buffer is full."/>
137 <event counter="ARM_Mali-T6xx_UTLB_NEW_MISS" title="Mali GPU Tiler" name="uTLB cache misses on new request" description="uTLB: Number of cache misses on new requests."/> 137 <event counter="ARM_Mali-T6xx_UTLB_NEW_MISS" title="Mali GPU Tiler" name="uTLB cache misses on new request" description="uTLB: Number of cache misses on new requests."/>
138 <event counter="ARM_Mali-T6xx_UTLB_HIT" title="Mali GPU Tiler" name="uTLB cache hits" description="uTLB: Number of cache hits."/> 138 <event counter="ARM_Mali-T6xx_UTLB_HIT" title="Mali GPU Tiler" name="uTLB cache hits" description="uTLB: Number of cache hits."/>
diff --git a/daemon/events-ScorpionMP.xml b/daemon/events-ScorpionMP.xml
index 42acc64..309f103 100644
--- a/daemon/events-ScorpionMP.xml
+++ b/daemon/events-ScorpionMP.xml
@@ -87,4 +87,4 @@
87 <event event="0x8d" title="Scorpion" name="EXCEPTIONS_DENORM" description="Scorpion denorm exceptions"/> 87 <event event="0x8d" title="Scorpion" name="EXCEPTIONS_DENORM" description="Scorpion denorm exceptions"/>
88 <event event="0x8e" title="ScorpionMP" name="NUM_BARRIERS" description="Barriers"/> 88 <event event="0x8e" title="ScorpionMP" name="NUM_BARRIERS" description="Barriers"/>
89 <event event="0x8f" title="ScorpionMP" name="BARRIER_CYCLES" description="Barrier cycles"/> 89 <event event="0x8f" title="ScorpionMP" name="BARRIER_CYCLES" description="Barrier cycles"/>
90 </category> 90 </category>
diff --git a/daemon/main.cpp b/daemon/main.cpp
index 5bc75ef..894bad7 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -19,6 +19,8 @@
19#include <sys/mount.h> 19#include <sys/mount.h>
20#include <fcntl.h> 20#include <fcntl.h>
21#include <sys/mman.h> 21#include <sys/mman.h>
22#include <sys/time.h>
23#include <sys/resource.h>
22#include "Child.h" 24#include "Child.h"
23#include "SessionData.h" 25#include "SessionData.h"
24#include "OlySocket.h" 26#include "OlySocket.h"
@@ -28,7 +30,6 @@
28#define DEBUG false 30#define DEBUG false
29 31
30extern Child* child; 32extern Child* child;
31extern void handleException();
32int shutdownFilesystem(); 33int shutdownFilesystem();
33static pthread_mutex_t numSessions_mutex; 34static pthread_mutex_t numSessions_mutex;
34static int numSessions = 0; 35static int numSessions = 0;
@@ -297,7 +298,10 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
297 298
298// Gator data flow: collector -> collector fifo -> sender 299// Gator data flow: collector -> collector fifo -> sender
299int main(int argc, char** argv, char* envp[]) { 300int main(int argc, char** argv, char* envp[]) {
301 // Ensure proper signal handling by making gatord the process group leader
302 // e.g. it may not be the group leader when launched as 'sudo gatord'
300 setsid(); 303 setsid();
304
301 gSessionData = new SessionData(); // Global data class 305 gSessionData = new SessionData(); // Global data class
302 logg = new Logging(DEBUG); // Set up global thread-safe logging 306 logg = new Logging(DEBUG); // Set up global thread-safe logging
303 util = new OlyUtility(); // Set up global utility class 307 util = new OlyUtility(); // Set up global utility class
@@ -314,9 +318,6 @@ int main(int argc, char** argv, char* envp[]) {
314 logg->logMessage("setpriority() failed"); 318 logg->logMessage("setpriority() failed");
315 } 319 }
316 320
317 // Initialize session data
318 gSessionData->initialize();
319
320 // Parse the command line parameters 321 // Parse the command line parameters
321 struct cmdline_t cmdline = parseCommandLine(argc, argv); 322 struct cmdline_t cmdline = parseCommandLine(argc, argv);
322 323
diff --git a/driver/Makefile b/driver/Makefile
index 6cafecf..d22d29d 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -27,7 +27,7 @@ gator-y += gator_events_mali_common.o
27EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) 27EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT)
28endif 28endif
29 29
30# GATOR_TEST controls whether to include (=1) or exclude (=0) test code. 30# GATOR_TEST controls whether to include (=1) or exclude (=0) test code.
31GATOR_TEST ?= 0 31GATOR_TEST ?= 0
32EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST) 32EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST)
33 33
diff --git a/driver/gator.h b/driver/gator.h
index 5a40e17..9a4617b 100644
--- a/driver/gator.h
+++ b/driver/gator.h
@@ -15,7 +15,7 @@
15#include <linux/list.h> 15#include <linux/list.h>
16 16
17#define GATOR_PERF_SUPPORT LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) 17#define GATOR_PERF_SUPPORT LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
18#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && defined(CONFIG_HW_PERF_EVENTS) 18#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && (!(defined(__arm__) || defined(__aarch64__)) || defined(CONFIG_HW_PERF_EVENTS))
19#define GATOR_NO_PERF_SUPPORT (!(GATOR_PERF_SUPPORT)) 19#define GATOR_NO_PERF_SUPPORT (!(GATOR_PERF_SUPPORT))
20#define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ) 20#define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ)
21 21
@@ -33,22 +33,39 @@
33#define SCORPIONMP 0x02d 33#define SCORPIONMP 0x02d
34#define KRAITSIM 0x049 34#define KRAITSIM 0x049
35#define KRAIT 0x04d 35#define KRAIT 0x04d
36#define KRAIT_S4_PRO 0x06f
37#define CORTEX_A53 0xd03
38#define CORTEX_A57 0xd07
36#define AARCH64 0xd0f 39#define AARCH64 0xd0f
40#define OTHER 0xfff
41
42#define MAXSIZE_CORE_NAME 32
43
44struct gator_cpu {
45 const int cpuid;
46 const char core_name[MAXSIZE_CORE_NAME];
47 const char * const pmnc_name;
48 const int pmnc_counters;
49 const int ccnt;
50};
51
52extern struct gator_cpu gator_cpus[];
37 53
38/****************************************************************************** 54/******************************************************************************
39 * Filesystem 55 * Filesystem
40 ******************************************************************************/ 56 ******************************************************************************/
41int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, 57int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
42 char const *name, const struct file_operations *fops, int perm); 58 char const *name,
59 const struct file_operations *fops, int perm);
43 60
44struct dentry *gatorfs_mkdir(struct super_block *sb, 61struct dentry *gatorfs_mkdir(struct super_block *sb, struct dentry *root,
45 struct dentry *root, char const *name); 62 char const *name);
46 63
47int gatorfs_create_ulong(struct super_block *sb, struct dentry *root, 64int gatorfs_create_ulong(struct super_block *sb, struct dentry *root,
48 char const *name, unsigned long *val); 65 char const *name, unsigned long *val);
49 66
50int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root, 67int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root,
51 char const *name, unsigned long *val); 68 char const *name, unsigned long *val);
52 69
53void gator_op_create_files(struct super_block *sb, struct dentry *root); 70void gator_op_create_files(struct super_block *sb, struct dentry *root);
54 71
@@ -77,15 +94,16 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root);
77 * Events 94 * Events
78 ******************************************************************************/ 95 ******************************************************************************/
79struct gator_interface { 96struct gator_interface {
80 int (*create_files)(struct super_block *sb, struct dentry *root); 97 void (*shutdown)(void); // Complementary function to init
81 int (*start)(void); 98 int (*create_files)(struct super_block *sb, struct dentry *root);
82 void (*stop)(void); 99 int (*start)(void);
83 int (*online)(int** buffer); 100 void (*stop)(void); // Complementary function to start
84 int (*offline)(int** buffer); 101 int (*online)(int **buffer);
85 void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu' 102 int (*offline)(int **buffer);
86 void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu' 103 void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
87 int (*read)(int **buffer); 104 void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
88 int (*read64)(long long **buffer); 105 int (*read)(int **buffer);
106 int (*read64)(long long **buffer);
89 struct list_head list; 107 struct list_head list;
90}; 108};
91 109
@@ -96,8 +114,8 @@ struct gator_interface {
96 114
97int gator_events_install(struct gator_interface *interface); 115int gator_events_install(struct gator_interface *interface);
98int gator_events_get_key(void); 116int gator_events_get_key(void);
99extern u32 gator_cpuid(void); 117u32 gator_cpuid(void);
100 118
101void gator_backtrace_handler(struct pt_regs * const regs); 119void gator_backtrace_handler(struct pt_regs *const regs);
102 120
103#endif // GATOR_H_ 121#endif // GATOR_H_
diff --git a/driver/gator_annotate.c b/driver/gator_annotate.c
index 928e252..42f9951 100644
--- a/driver/gator_annotate.c
+++ b/driver/gator_annotate.c
@@ -44,8 +44,9 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
44 return -EINVAL; 44 return -EINVAL;
45 } 45 }
46 46
47 // Annotation is not supported in interrupt context 47 // Annotations are not supported in interrupt context
48 if (in_interrupt()) { 48 if (in_interrupt()) {
49 printk(KERN_WARNING "gator: Annotations are not supported in interrupt context\n");
49 return -EINVAL; 50 return -EINVAL;
50 } 51 }
51 52
@@ -58,7 +59,8 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
58 goto annotate_write_out; 59 goto annotate_write_out;
59 } 60 }
60 61
61 cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine 62 // Annotation only uses a single per-cpu buffer as the data must be in order to the engine
63 cpu = 0;
62 64
63 if (current == NULL) { 65 if (current == NULL) {
64 pid = 0; 66 pid = 0;
@@ -129,18 +131,21 @@ static int annotate_release(struct inode *inode, struct file *file)
129 uint32_t pid = current->pid; 131 uint32_t pid = current->pid;
130 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); 132 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id());
131 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid); 133 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
132 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time 134 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time
133 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size 135 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size
134 } 136 }
135 137
138 // Check and commit; commit is set to occur once buffer is 3/4 full
139 buffer_check(cpu, ANNOTATE_BUF);
140
136 spin_unlock(&annotate_lock); 141 spin_unlock(&annotate_lock);
137 142
138 return 0; 143 return 0;
139} 144}
140 145
141static const struct file_operations annotate_fops = { 146static const struct file_operations annotate_fops = {
142 .write = annotate_write, 147 .write = annotate_write,
143 .release = annotate_release 148 .release = annotate_release
144}; 149};
145 150
146static int gator_annotate_create_files(struct super_block *sb, struct dentry *root) 151static int gator_annotate_create_files(struct super_block *sb, struct dentry *root)
diff --git a/driver/gator_annotate_kernel.c b/driver/gator_annotate_kernel.c
index bc68fa8..67d2d6c 100644
--- a/driver/gator_annotate_kernel.c
+++ b/driver/gator_annotate_kernel.c
@@ -8,11 +8,13 @@
8 */ 8 */
9 9
10#define ESCAPE_CODE 0x1c 10#define ESCAPE_CODE 0x1c
11#define STRING_ANNOTATION 0x03 11#define STRING_ANNOTATION 0x06
12#define NAME_CHANNEL_ANNOTATION 0x07
13#define NAME_GROUP_ANNOTATION 0x08
12#define VISUAL_ANNOTATION 0x04 14#define VISUAL_ANNOTATION 0x04
13#define MARKER_ANNOTATION 0x05 15#define MARKER_ANNOTATION 0x05
14 16
15static void kannotate_write(const char* ptr, unsigned int size) 17static void kannotate_write(const char *ptr, unsigned int size)
16{ 18{
17 int retval; 19 int retval;
18 int pos = 0; 20 int pos = 0;
@@ -27,91 +29,129 @@ static void kannotate_write(const char* ptr, unsigned int size)
27 } 29 }
28} 30}
29 31
30static void gator_annotate_code(char code) 32void gator_annotate_channel(int channel, const char *str)
31{ 33{
32 int header = ESCAPE_CODE | (code << 8); 34 int str_size = strlen(str) & 0xffff;
33 kannotate_write((char*)&header, sizeof(header)); 35 long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16) | ((long long)str_size << 48);
36 kannotate_write((char *)&header, sizeof(header));
37 kannotate_write(str, str_size);
34} 38}
35 39
36static void gator_annotate_code_str(char code, const char* string) 40EXPORT_SYMBOL(gator_annotate_channel);
37{
38 int str_size = strlen(string) & 0xffff;
39 int header = ESCAPE_CODE | (code << 8) | (str_size << 16);
40 kannotate_write((char*)&header, sizeof(header));
41 kannotate_write(string, str_size);
42}
43 41
44static void gator_annotate_code_color(char code, int color) 42void gator_annotate(const char *str)
45{ 43{
46 long long header = (ESCAPE_CODE | (code << 8) | 0x00040000 | ((long long)color << 32)); 44 gator_annotate_channel(0, str);
47 kannotate_write((char*)&header, sizeof(header));
48} 45}
49 46
50static void gator_annotate_code_color_str(char code, int color, const char* string) 47EXPORT_SYMBOL(gator_annotate);
48
49void gator_annotate_channel_color(int channel, int color, const char *str)
51{ 50{
52 int str_size = (strlen(string) + 4) & 0xffff; 51 int str_size = (strlen(str) + 4) & 0xffff;
53 long long header = ESCAPE_CODE | (code << 8) | (str_size << 16) | ((long long)color << 32); 52 char header[12];
54 kannotate_write((char*)&header, sizeof(header)); 53 header[0] = ESCAPE_CODE;
55 kannotate_write(string, str_size - 4); 54 header[1] = STRING_ANNOTATION;
55 *(u32 *)(&header[2]) = channel;
56 *(u16 *)(&header[6]) = str_size;
57 *(u32 *)(&header[8]) = color;
58 kannotate_write((char *)&header, sizeof(header));
59 kannotate_write(str, str_size - 4);
56} 60}
57 61
58// String annotation 62EXPORT_SYMBOL(gator_annotate_channel_color);
59void gator_annotate(const char* string) 63
64void gator_annotate_color(int color, const char *str)
60{ 65{
61 gator_annotate_code_str(STRING_ANNOTATION, string); 66 gator_annotate_channel_color(0, color, str);
62} 67}
63EXPORT_SYMBOL(gator_annotate);
64 68
65// String annotation with color 69EXPORT_SYMBOL(gator_annotate_color);
66void gator_annotate_color(int color, const char* string) 70
71void gator_annotate_channel_end(int channel)
67{ 72{
68 gator_annotate_code_color_str(STRING_ANNOTATION, color, string); 73 long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16);
74 kannotate_write((char *)&header, sizeof(header));
69} 75}
70EXPORT_SYMBOL(gator_annotate_color);
71 76
72// Terminate an annotation 77EXPORT_SYMBOL(gator_annotate_channel_end);
78
73void gator_annotate_end(void) 79void gator_annotate_end(void)
74{ 80{
75 gator_annotate_code(STRING_ANNOTATION); 81 gator_annotate_channel_end(0);
76} 82}
83
77EXPORT_SYMBOL(gator_annotate_end); 84EXPORT_SYMBOL(gator_annotate_end);
78 85
79// Image annotation with optional string 86void gator_annotate_name_channel(int channel, int group, const char* str)
80void gator_annotate_visual(const char* data, unsigned int length, const char* string) 87{
88 int str_size = strlen(str) & 0xffff;
89 char header[12];
90 header[0] = ESCAPE_CODE;
91 header[1] = NAME_CHANNEL_ANNOTATION;
92 *(u32 *)(&header[2]) = channel;
93 *(u32 *)(&header[6]) = group;
94 *(u16 *)(&header[10]) = str_size;
95 kannotate_write((char *)&header, sizeof(header));
96 kannotate_write(str, str_size);
97}
98
99EXPORT_SYMBOL(gator_annotate_name_channel);
100
101void gator_annotate_name_group(int group, const char* str)
102{
103 int str_size = strlen(str) & 0xffff;
104 long long header = ESCAPE_CODE | (NAME_GROUP_ANNOTATION << 8) | (group << 16) | ((long long)str_size << 48);
105 kannotate_write((char *)&header, sizeof(header));
106 kannotate_write(str, str_size);
107}
108
109EXPORT_SYMBOL(gator_annotate_name_group);
110
111void gator_annotate_visual(const char *data, unsigned int length, const char *str)
81{ 112{
82 int str_size = strlen(string) & 0xffff; 113 int str_size = strlen(str) & 0xffff;
83 int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16); 114 int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16);
84 kannotate_write((char*)&visual_annotation, sizeof(visual_annotation)); 115 kannotate_write((char *)&visual_annotation, sizeof(visual_annotation));
85 kannotate_write(string, str_size); 116 kannotate_write(str, str_size);
86 kannotate_write((char*)&length, sizeof(length)); 117 kannotate_write((char *)&length, sizeof(length));
87 kannotate_write(data, length); 118 kannotate_write(data, length);
88} 119}
120
89EXPORT_SYMBOL(gator_annotate_visual); 121EXPORT_SYMBOL(gator_annotate_visual);
90 122
91// Marker annotation
92void gator_annotate_marker(void) 123void gator_annotate_marker(void)
93{ 124{
94 gator_annotate_code(MARKER_ANNOTATION); 125 int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8);
126 kannotate_write((char *)&header, sizeof(header));
95} 127}
128
96EXPORT_SYMBOL(gator_annotate_marker); 129EXPORT_SYMBOL(gator_annotate_marker);
97 130
98// Marker annotation with a string 131void gator_annotate_marker_str(const char *str)
99void gator_annotate_marker_str(const char* string)
100{ 132{
101 gator_annotate_code_str(MARKER_ANNOTATION, string); 133 int str_size = strlen(str) & 0xffff;
134 int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16);
135 kannotate_write((char *)&header, sizeof(header));
136 kannotate_write(str, str_size);
102} 137}
138
103EXPORT_SYMBOL(gator_annotate_marker_str); 139EXPORT_SYMBOL(gator_annotate_marker_str);
104 140
105// Marker annotation with a color
106void gator_annotate_marker_color(int color) 141void gator_annotate_marker_color(int color)
107{ 142{
108 gator_annotate_code_color(MARKER_ANNOTATION, color); 143 long long header = (ESCAPE_CODE | (MARKER_ANNOTATION << 8) | 0x00040000 | ((long long)color << 32));
144 kannotate_write((char *)&header, sizeof(header));
109} 145}
146
110EXPORT_SYMBOL(gator_annotate_marker_color); 147EXPORT_SYMBOL(gator_annotate_marker_color);
111 148
112// Marker annotation with a string and color 149void gator_annotate_marker_color_str(int color, const char *str)
113void gator_annotate_marker_color_str(int color, const char* string)
114{ 150{
115 gator_annotate_code_color_str(MARKER_ANNOTATION, color, string); 151 int str_size = (strlen(str) + 4) & 0xffff;
152 long long header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16) | ((long long)color << 32);
153 kannotate_write((char *)&header, sizeof(header));
154 kannotate_write(str, str_size - 4);
116} 155}
156
117EXPORT_SYMBOL(gator_annotate_marker_color_str); 157EXPORT_SYMBOL(gator_annotate_marker_color_str);
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index 2173d8a..e6125b3 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -11,20 +11,28 @@
11 * EABI backtrace stores {fp,lr} on the stack. 11 * EABI backtrace stores {fp,lr} on the stack.
12 */ 12 */
13struct frame_tail_eabi { 13struct frame_tail_eabi {
14 unsigned long fp; // points to prev_lr 14 unsigned long fp; // points to prev_lr
15 unsigned long lr; 15 unsigned long lr;
16}; 16};
17 17
18static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth) 18static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth)
19{ 19{
20#if defined(__arm__) 20#if defined(__arm__) || defined(__aarch64__)
21 struct frame_tail_eabi *tail; 21 struct frame_tail_eabi *tail;
22 struct frame_tail_eabi *next; 22 struct frame_tail_eabi *next;
23 struct frame_tail_eabi *ptrtail; 23 struct frame_tail_eabi *ptrtail;
24 struct frame_tail_eabi buftail; 24 struct frame_tail_eabi buftail;
25#if defined(__arm__)
25 unsigned long fp = regs->ARM_fp; 26 unsigned long fp = regs->ARM_fp;
26 unsigned long sp = regs->ARM_sp; 27 unsigned long sp = regs->ARM_sp;
27 unsigned long lr = regs->ARM_lr; 28 unsigned long lr = regs->ARM_lr;
29 const int frame_offset = 4;
30#else
31 unsigned long fp = regs->regs[29];
32 unsigned long sp = regs->sp;
33 unsigned long lr = regs->regs[30];
34 const int frame_offset = 0;
35#endif
28 int is_user_mode = user_mode(regs); 36 int is_user_mode = user_mode(regs);
29 37
30 if (!is_user_mode) { 38 if (!is_user_mode) {
@@ -39,9 +47,9 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
39 return; 47 return;
40 } 48 }
41 49
42 tail = (struct frame_tail_eabi *)(fp - 4); 50 tail = (struct frame_tail_eabi *)(fp - frame_offset);
43 51
44 while (depth-- && tail && !((unsigned long) tail & 3)) { 52 while (depth-- && tail && !((unsigned long)tail & 3)) {
45 /* Also check accessibility of one struct frame_tail beyond */ 53 /* Also check accessibility of one struct frame_tail beyond */
46 if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi))) 54 if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi)))
47 return; 55 return;
@@ -53,10 +61,10 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
53 gator_add_trace(cpu, lr); 61 gator_add_trace(cpu, lr);
54 62
55 /* frame pointers should progress back up the stack, towards higher addresses */ 63 /* frame pointers should progress back up the stack, towards higher addresses */
56 next = (struct frame_tail_eabi *)(lr - 4); 64 next = (struct frame_tail_eabi *)(lr - frame_offset);
57 if (tail >= next || lr == 0) { 65 if (tail >= next || lr == 0) {
58 fp = ptrtail[0].fp; 66 fp = ptrtail[0].fp;
59 next = (struct frame_tail_eabi *)(fp - 4); 67 next = (struct frame_tail_eabi *)(fp - frame_offset);
60 /* check tail is valid */ 68 /* check tail is valid */
61 if (tail >= next || fp == 0) { 69 if (tail >= next || fp == 0) {
62 return; 70 return;
@@ -68,7 +76,7 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
68#endif 76#endif
69} 77}
70 78
71#if defined(__arm__) 79#if defined(__arm__) || defined(__aarch64__)
72static int report_trace(struct stackframe *frame, void *d) 80static int report_trace(struct stackframe *frame, void *d)
73{ 81{
74 struct module *mod; 82 struct module *mod;
@@ -78,7 +86,7 @@ static int report_trace(struct stackframe *frame, void *d)
78 if (*depth) { 86 if (*depth) {
79 mod = __module_address(addr); 87 mod = __module_address(addr);
80 if (mod) { 88 if (mod) {
81 cookie = get_cookie(cpu, current, NULL, mod, true); 89 cookie = get_cookie(cpu, current, mod->name, false);
82 addr = addr - (unsigned long)mod->module_core; 90 addr = addr - (unsigned long)mod->module_core;
83 } 91 }
84 marshal_backtrace(addr & ~1, cookie); 92 marshal_backtrace(addr & ~1, cookie);
@@ -91,9 +99,9 @@ static int report_trace(struct stackframe *frame, void *d)
91 99
92// Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile 100// Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile
93// #define GATOR_KERNEL_STACK_UNWINDING 101// #define GATOR_KERNEL_STACK_UNWINDING
94static void kernel_backtrace(int cpu, struct pt_regs * const regs) 102static void kernel_backtrace(int cpu, struct pt_regs *const regs)
95{ 103{
96#if defined(__arm__) 104#if defined(__arm__) || defined(__aarch64__)
97#ifdef GATOR_KERNEL_STACK_UNWINDING 105#ifdef GATOR_KERNEL_STACK_UNWINDING
98 int depth = gator_backtrace_depth; 106 int depth = gator_backtrace_depth;
99#else 107#else
@@ -102,10 +110,16 @@ static void kernel_backtrace(int cpu, struct pt_regs * const regs)
102 struct stackframe frame; 110 struct stackframe frame;
103 if (depth == 0) 111 if (depth == 0)
104 depth = 1; 112 depth = 1;
113#if defined(__arm__)
105 frame.fp = regs->ARM_fp; 114 frame.fp = regs->ARM_fp;
106 frame.sp = regs->ARM_sp; 115 frame.sp = regs->ARM_sp;
107 frame.lr = regs->ARM_lr; 116 frame.lr = regs->ARM_lr;
108 frame.pc = regs->ARM_pc; 117 frame.pc = regs->ARM_pc;
118#else
119 frame.fp = regs->regs[29];
120 frame.sp = regs->sp;
121 frame.pc = regs->pc;
122#endif
109 walk_stackframe(&frame, report_trace, &depth); 123 walk_stackframe(&frame, report_trace, &depth);
110#else 124#else
111 marshal_backtrace(PC_REG & ~1, NO_COOKIE); 125 marshal_backtrace(PC_REG & ~1, NO_COOKIE);
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c
index 21dc4eb..bb401bb 100644
--- a/driver/gator_cookies.c
+++ b/driver/gator_cookies.c
@@ -7,7 +7,7 @@
7 * 7 *
8 */ 8 */
9 9
10#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */ 10#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */
11#define TRANSLATE_SIZE 256 11#define TRANSLATE_SIZE 256
12#define MAX_COLLISIONS 2 12#define MAX_COLLISIONS 2
13 13
@@ -20,28 +20,29 @@ static DEFINE_PER_CPU(uint64_t *, cookie_keys);
20static DEFINE_PER_CPU(uint32_t *, cookie_values); 20static DEFINE_PER_CPU(uint32_t *, cookie_values);
21static DEFINE_PER_CPU(int, translate_buffer_read); 21static DEFINE_PER_CPU(int, translate_buffer_read);
22static DEFINE_PER_CPU(int, translate_buffer_write); 22static DEFINE_PER_CPU(int, translate_buffer_write);
23static DEFINE_PER_CPU(void * *, translate_buffer); 23static DEFINE_PER_CPU(void **, translate_buffer);
24 24
25static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt); 25static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq);
26static void wq_cookie_handler(struct work_struct *unused); 26static void wq_cookie_handler(struct work_struct *unused);
27DECLARE_WORK(cookie_work, wq_cookie_handler); 27DECLARE_WORK(cookie_work, wq_cookie_handler);
28static struct timer_list app_process_wake_up_timer; 28static struct timer_list app_process_wake_up_timer;
29static void app_process_wake_up_handler(unsigned long unused_data); 29static void app_process_wake_up_handler(unsigned long unused_data);
30 30
31static uint32_t cookiemap_code(uint64_t value64) { 31static uint32_t cookiemap_code(uint64_t value64)
32{
32 uint32_t value = (uint32_t)((value64 >> 32) + value64); 33 uint32_t value = (uint32_t)((value64 >> 32) + value64);
33 uint32_t cookiecode = (value >> 24) & 0xff; 34 uint32_t cookiecode = (value >> 24) & 0xff;
34 cookiecode = cookiecode * 31 + ((value >> 16) & 0xff); 35 cookiecode = cookiecode * 31 + ((value >> 16) & 0xff);
35 cookiecode = cookiecode * 31 + ((value >> 8) & 0xff); 36 cookiecode = cookiecode * 31 + ((value >> 8) & 0xff);
36 cookiecode = cookiecode * 31 + ((value >> 0) & 0xff); 37 cookiecode = cookiecode * 31 + ((value >> 0) & 0xff);
37 cookiecode &= (COOKIEMAP_ENTRIES-1); 38 cookiecode &= (COOKIEMAP_ENTRIES - 1);
38 return cookiecode * MAX_COLLISIONS; 39 return cookiecode * MAX_COLLISIONS;
39} 40}
40 41
41static uint32_t gator_chksum_crc32(char *data) 42static uint32_t gator_chksum_crc32(const char *data)
42{ 43{
43 register unsigned long crc; 44 register unsigned long crc;
44 unsigned char *block = data; 45 const unsigned char *block = data;
45 int i, length = strlen(data); 46 int i, length = strlen(data);
46 47
47 crc = 0xFFFFFFFF; 48 crc = 0xFFFFFFFF;
@@ -57,7 +58,8 @@ static uint32_t gator_chksum_crc32(char *data)
57 * Pre: [0][1][v][3]..[n-1] 58 * Pre: [0][1][v][3]..[n-1]
58 * Post: [v][0][1][3]..[n-1] 59 * Post: [v][0][1][3]..[n-1]
59 */ 60 */
60static uint32_t cookiemap_exists(uint64_t key) { 61static uint32_t cookiemap_exists(uint64_t key)
62{
61 unsigned long x, flags, retval = 0; 63 unsigned long x, flags, retval = 0;
62 int cpu = smp_processor_id(); 64 int cpu = smp_processor_id();
63 uint32_t cookiecode = cookiemap_code(key); 65 uint32_t cookiecode = cookiemap_code(key);
@@ -70,8 +72,8 @@ static uint32_t cookiemap_exists(uint64_t key) {
70 if (keys[x] == key) { 72 if (keys[x] == key) {
71 uint32_t value = values[x]; 73 uint32_t value = values[x];
72 for (; x > 0; x--) { 74 for (; x > 0; x--) {
73 keys[x] = keys[x-1]; 75 keys[x] = keys[x - 1];
74 values[x] = values[x-1]; 76 values[x] = values[x - 1];
75 } 77 }
76 keys[0] = key; 78 keys[0] = key;
77 values[0] = value; 79 values[0] = value;
@@ -89,30 +91,31 @@ static uint32_t cookiemap_exists(uint64_t key) {
89 * Pre: [0][1][2][3]..[n-1] 91 * Pre: [0][1][2][3]..[n-1]
90 * Post: [v][0][1][2]..[n-2] 92 * Post: [v][0][1][2]..[n-2]
91 */ 93 */
92static void cookiemap_add(uint64_t key, uint32_t value) { 94static void cookiemap_add(uint64_t key, uint32_t value)
95{
93 int cpu = smp_processor_id(); 96 int cpu = smp_processor_id();
94 int cookiecode = cookiemap_code(key); 97 int cookiecode = cookiemap_code(key);
95 uint64_t *keys = &(per_cpu(cookie_keys, cpu)[cookiecode]); 98 uint64_t *keys = &(per_cpu(cookie_keys, cpu)[cookiecode]);
96 uint32_t *values = &(per_cpu(cookie_values, cpu)[cookiecode]); 99 uint32_t *values = &(per_cpu(cookie_values, cpu)[cookiecode]);
97 int x; 100 int x;
98 101
99 for (x = MAX_COLLISIONS-1; x > 0; x--) { 102 for (x = MAX_COLLISIONS - 1; x > 0; x--) {
100 keys[x] = keys[x-1]; 103 keys[x] = keys[x - 1];
101 values[x] = values[x-1]; 104 values[x] = values[x - 1];
102 } 105 }
103 keys[0] = key; 106 keys[0] = key;
104 values[0] = value; 107 values[0] = value;
105} 108}
106 109
107static void translate_buffer_write_ptr(int cpu, void * x) 110static void translate_buffer_write_ptr(int cpu, void *x)
108{ 111{
109 per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x; 112 per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
110 per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask; 113 per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
111} 114}
112 115
113static void * translate_buffer_read_ptr(int cpu) 116static void *translate_buffer_read_ptr(int cpu)
114{ 117{
115 void * value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++]; 118 void *value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
116 per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask; 119 per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask;
117 return value; 120 return value;
118} 121}
@@ -120,9 +123,9 @@ static void * translate_buffer_read_ptr(int cpu)
120static void wq_cookie_handler(struct work_struct *unused) 123static void wq_cookie_handler(struct work_struct *unused)
121{ 124{
122 struct task_struct *task; 125 struct task_struct *task;
123 struct vm_area_struct *vma; 126 char *text;
124 int cpu = smp_processor_id(); 127 int cpu = smp_processor_id();
125 unsigned int cookie, commit; 128 unsigned int commit;
126 129
127 mutex_lock(&start_mutex); 130 mutex_lock(&start_mutex);
128 131
@@ -130,8 +133,8 @@ static void wq_cookie_handler(struct work_struct *unused)
130 commit = per_cpu(translate_buffer_write, cpu); 133 commit = per_cpu(translate_buffer_write, cpu);
131 while (per_cpu(translate_buffer_read, cpu) != commit) { 134 while (per_cpu(translate_buffer_read, cpu) != commit) {
132 task = (struct task_struct *)translate_buffer_read_ptr(cpu); 135 task = (struct task_struct *)translate_buffer_read_ptr(cpu);
133 vma = (struct vm_area_struct *)translate_buffer_read_ptr(cpu); 136 text = (char *)translate_buffer_read_ptr(cpu);
134 cookie = get_cookie(cpu, task, vma, NULL, false); 137 get_cookie(cpu, task, text, true);
135 } 138 }
136 } 139 }
137 140
@@ -145,7 +148,7 @@ static void app_process_wake_up_handler(unsigned long unused_data)
145} 148}
146 149
147// Retrieve full name from proc/pid/cmdline for java processes on Android 150// Retrieve full name from proc/pid/cmdline for java processes on Android
148static int translate_app_process(char** text, int cpu, struct task_struct * task, struct vm_area_struct *vma, bool in_interrupt) 151static int translate_app_process(const char **text, int cpu, struct task_struct *task, bool from_wq)
149{ 152{
150 void *maddr; 153 void *maddr;
151 unsigned int len; 154 unsigned int len;
@@ -154,12 +157,12 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
154 struct page *page = NULL; 157 struct page *page = NULL;
155 struct vm_area_struct *page_vma; 158 struct vm_area_struct *page_vma;
156 int bytes, offset, retval = 0, ptr; 159 int bytes, offset, retval = 0, ptr;
157 char * buf = per_cpu(translate_text, cpu); 160 char *buf = per_cpu(translate_text, cpu);
158 161
159 // Push work into a work queue if in atomic context as the kernel functions below might sleep 162 // Push work into a work queue if in atomic context as the kernel functions below might sleep
160 // Rely on the in_interrupt variable rather than in_irq() or in_interrupt() kernel functions, as the value of these functions seems 163 // Rely on the in_interrupt variable rather than in_irq() or in_interrupt() kernel functions, as the value of these functions seems
161 // inconsistent during a context switch between android/linux versions 164 // inconsistent during a context switch between android/linux versions
162 if (in_interrupt) { 165 if (!from_wq) {
163 // Check if already in buffer 166 // Check if already in buffer
164 ptr = per_cpu(translate_buffer_read, cpu); 167 ptr = per_cpu(translate_buffer_read, cpu);
165 while (ptr != per_cpu(translate_buffer_write, cpu)) { 168 while (ptr != per_cpu(translate_buffer_write, cpu)) {
@@ -169,7 +172,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
169 } 172 }
170 173
171 translate_buffer_write_ptr(cpu, (void *)task); 174 translate_buffer_write_ptr(cpu, (void *)task);
172 translate_buffer_write_ptr(cpu, (void *)vma); 175 translate_buffer_write_ptr(cpu, (void *)*text);
173 176
174 mod_timer(&app_process_wake_up_timer, jiffies + 1); 177 mod_timer(&app_process_wake_up_timer, jiffies + 1);
175 goto out; 178 goto out;
@@ -192,7 +195,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
192 goto outsem; 195 goto outsem;
193 196
194 maddr = kmap(page); 197 maddr = kmap(page);
195 offset = addr & (PAGE_SIZE-1); 198 offset = addr & (PAGE_SIZE - 1);
196 bytes = len; 199 bytes = len;
197 if (bytes > PAGE_SIZE - offset) 200 if (bytes > PAGE_SIZE - offset)
198 bytes = PAGE_SIZE - offset; 201 bytes = PAGE_SIZE - offset;
@@ -222,29 +225,10 @@ out:
222 return retval; 225 return retval;
223} 226}
224 227
225static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt) 228static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq)
226{ 229{
227 unsigned long flags, cookie; 230 unsigned long flags, cookie;
228 struct path *path;
229 uint64_t key; 231 uint64_t key;
230 char *text;
231
232 if (mod) {
233 text = mod->name;
234 } else {
235 if (vma && vma->vm_file) {
236 path = &vma->vm_file->f_path;
237 } else if (task && task->mm && task->mm->exe_file) {
238 path = &task->mm->exe_file->f_path;
239 } else {
240 return INVALID_COOKIE;
241 }
242 if (!path || !path->dentry) {
243 return INVALID_COOKIE;
244 }
245
246 text = (char*)path->dentry->d_name.name;
247 }
248 232
249 key = gator_chksum_crc32(text); 233 key = gator_chksum_crc32(text);
250 key = (key << 32) | (uint32_t)task->tgid; 234 key = (key << 32) | (uint32_t)task->tgid;
@@ -254,8 +238,8 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
254 return cookie; 238 return cookie;
255 } 239 }
256 240
257 if (strcmp(text, "app_process") == 0 && !mod) { 241 if (strcmp(text, "app_process") == 0) {
258 if (!translate_app_process(&text, cpu, task, vma, in_interrupt)) 242 if (!translate_app_process(&text, cpu, task, from_wq))
259 return INVALID_COOKIE; 243 return INVALID_COOKIE;
260 } 244 }
261 245
@@ -276,16 +260,19 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
276 260
277static int get_exec_cookie(int cpu, struct task_struct *task) 261static int get_exec_cookie(int cpu, struct task_struct *task)
278{ 262{
279 unsigned long cookie = NO_COOKIE;
280 struct mm_struct *mm = task->mm; 263 struct mm_struct *mm = task->mm;
264 const char *text;
281 265
282 // kernel threads have no address space 266 // kernel threads have no address space
283 if (!mm) 267 if (!mm)
284 return cookie; 268 return NO_COOKIE;
285 269
286 cookie = get_cookie(cpu, task, NULL, NULL, true); 270 if (task && task->mm && task->mm->exe_file) {
271 text = task->mm->exe_file->f_path.dentry->d_name.name;
272 return get_cookie(cpu, task, text, false);
273 }
287 274
288 return cookie; 275 return INVALID_COOKIE;
289} 276}
290 277
291static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset) 278static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset)
@@ -293,6 +280,7 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
293 unsigned long cookie = NO_COOKIE; 280 unsigned long cookie = NO_COOKIE;
294 struct mm_struct *mm = task->mm; 281 struct mm_struct *mm = task->mm;
295 struct vm_area_struct *vma; 282 struct vm_area_struct *vma;
283 const char *text;
296 284
297 if (!mm) 285 if (!mm)
298 return cookie; 286 return cookie;
@@ -302,7 +290,8 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
302 continue; 290 continue;
303 291
304 if (vma->vm_file) { 292 if (vma->vm_file) {
305 cookie = get_cookie(cpu, task, vma, NULL, true); 293 text = vma->vm_file->f_path.dentry->d_name.name;
294 cookie = get_cookie(cpu, task, text, false);
306 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; 295 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start;
307 } else { 296 } else {
308 /* must be an anonymous map */ 297 /* must be an anonymous map */
@@ -323,14 +312,14 @@ static int cookies_initialize(void)
323 uint32_t crc, poly; 312 uint32_t crc, poly;
324 int i, j, cpu, size, err = 0; 313 int i, j, cpu, size, err = 0;
325 314
326 int translate_buffer_size = 512; // must be a power of 2 315 int translate_buffer_size = 512; // must be a power of 2
327 translate_buffer_mask = translate_buffer_size / sizeof(per_cpu(translate_buffer, 0)[0]) - 1; 316 translate_buffer_mask = translate_buffer_size / sizeof(per_cpu(translate_buffer, 0)[0]) - 1;
328 317
329 for_each_present_cpu(cpu) { 318 for_each_present_cpu(cpu) {
330 per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu; 319 per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu;
331 320
332 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint64_t); 321 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint64_t);
333 per_cpu(cookie_keys, cpu) = (uint64_t*)kmalloc(size, GFP_KERNEL); 322 per_cpu(cookie_keys, cpu) = (uint64_t *)kmalloc(size, GFP_KERNEL);
334 if (!per_cpu(cookie_keys, cpu)) { 323 if (!per_cpu(cookie_keys, cpu)) {
335 err = -ENOMEM; 324 err = -ENOMEM;
336 goto cookie_setup_error; 325 goto cookie_setup_error;
@@ -338,14 +327,14 @@ static int cookies_initialize(void)
338 memset(per_cpu(cookie_keys, cpu), 0, size); 327 memset(per_cpu(cookie_keys, cpu), 0, size);
339 328
340 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint32_t); 329 size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint32_t);
341 per_cpu(cookie_values, cpu) = (uint32_t*)kmalloc(size, GFP_KERNEL); 330 per_cpu(cookie_values, cpu) = (uint32_t *)kmalloc(size, GFP_KERNEL);
342 if (!per_cpu(cookie_values, cpu)) { 331 if (!per_cpu(cookie_values, cpu)) {
343 err = -ENOMEM; 332 err = -ENOMEM;
344 goto cookie_setup_error; 333 goto cookie_setup_error;
345 } 334 }
346 memset(per_cpu(cookie_values, cpu), 0, size); 335 memset(per_cpu(cookie_values, cpu), 0, size);
347 336
348 per_cpu(translate_buffer, cpu) = (void * *)kmalloc(translate_buffer_size, GFP_KERNEL); 337 per_cpu(translate_buffer, cpu) = (void **)kmalloc(translate_buffer_size, GFP_KERNEL);
349 if (!per_cpu(translate_buffer, cpu)) { 338 if (!per_cpu(translate_buffer, cpu)) {
350 err = -ENOMEM; 339 err = -ENOMEM;
351 goto cookie_setup_error; 340 goto cookie_setup_error;
@@ -363,7 +352,7 @@ static int cookies_initialize(void)
363 352
364 // build CRC32 table 353 // build CRC32 table
365 poly = 0x04c11db7; 354 poly = 0x04c11db7;
366 gator_crc32_table = (uint32_t*)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL); 355 gator_crc32_table = (uint32_t *)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL);
367 for (i = 0; i < 256; i++) { 356 for (i = 0; i < 256; i++) {
368 crc = i; 357 crc = i;
369 for (j = 8; j > 0; j--) { 358 for (j = 8; j > 0; j--) {
diff --git a/driver/gator_events_armv6.c b/driver/gator_events_armv6.c
index 5f989ba..ee36dd0 100644
--- a/driver/gator_events_armv6.c
+++ b/driver/gator_events_armv6.c
@@ -93,7 +93,7 @@ int gator_events_armv6_create_files(struct super_block *sb, struct dentry *root)
93 return 0; 93 return 0;
94} 94}
95 95
96static int gator_events_armv6_online(int** buffer) 96static int gator_events_armv6_online(int **buffer)
97{ 97{
98 unsigned int cnt, len = 0, cpu = smp_processor_id(); 98 unsigned int cnt, len = 0, cpu = smp_processor_id();
99 u32 pmnc; 99 u32 pmnc;
@@ -104,7 +104,7 @@ static int gator_events_armv6_online(int** buffer)
104 104
105 /* initialize PMNC, reset overflow, D bit, C bit and P bit. */ 105 /* initialize PMNC, reset overflow, D bit, C bit and P bit. */
106 armv6_pmnc_write(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT | 106 armv6_pmnc_write(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
107 PMCR_C | PMCR_P); 107 PMCR_C | PMCR_P);
108 108
109 /* configure control register */ 109 /* configure control register */
110 for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) { 110 for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
@@ -141,7 +141,7 @@ static int gator_events_armv6_online(int** buffer)
141 return len; 141 return len;
142} 142}
143 143
144static int gator_events_armv6_offline(int** buffer) 144static int gator_events_armv6_offline(int **buffer)
145{ 145{
146 unsigned int cnt; 146 unsigned int cnt;
147 147
diff --git a/driver/gator_events_armv7.c b/driver/gator_events_armv7.c
index 590421d..212b17b 100644
--- a/driver/gator_events_armv7.c
+++ b/driver/gator_events_armv7.c
@@ -22,7 +22,7 @@
22#define PMNC_E (1 << 0) /* Enable all counters */ 22#define PMNC_E (1 << 0) /* Enable all counters */
23#define PMNC_P (1 << 1) /* Reset all counters */ 23#define PMNC_P (1 << 1) /* Reset all counters */
24#define PMNC_C (1 << 2) /* Cycle counter reset */ 24#define PMNC_C (1 << 2) /* Cycle counter reset */
25#define PMNC_MASK 0x3f /* Mask for writable bits */ 25#define PMNC_MASK 0x3f /* Mask for writable bits */
26 26
27// ccnt reg 27// ccnt reg
28#define CCNT_REG (1 << 31) 28#define CCNT_REG (1 << 31)
@@ -63,7 +63,7 @@ inline u32 armv7_ccnt_read(u32 reset_value)
63 local_irq_save(flags); 63 local_irq_save(flags);
64 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable 64 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
65 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); // read 65 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); // read
66 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval));// new value 66 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval)); // new value
67 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable 67 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
68 local_irq_restore(flags); 68 local_irq_restore(flags);
69 69
@@ -82,7 +82,7 @@ inline u32 armv7_cntn_read(unsigned int cnt, u32 reset_value)
82 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable 82 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
83 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (sel)); // select 83 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (sel)); // select
84 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (oldval)); // read 84 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (oldval)); // read
85 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval));// new value 85 asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval)); // new value
86 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable 86 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
87 local_irq_restore(flags); 87 local_irq_restore(flags);
88 88
@@ -143,7 +143,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
143 if (i == 0) { 143 if (i == 0) {
144 snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name); 144 snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name);
145 } else { 145 } else {
146 snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i-1); 146 snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i - 1);
147 } 147 }
148 dir = gatorfs_mkdir(sb, root, buf); 148 dir = gatorfs_mkdir(sb, root, buf);
149 if (!dir) { 149 if (!dir) {
@@ -159,7 +159,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
159 return 0; 159 return 0;
160} 160}
161 161
162static int gator_events_armv7_online(int** buffer) 162static int gator_events_armv7_online(int **buffer)
163{ 163{
164 unsigned int cnt, len = 0, cpu = smp_processor_id(); 164 unsigned int cnt, len = 0, cpu = smp_processor_id();
165 165
@@ -214,11 +214,11 @@ static int gator_events_armv7_online(int** buffer)
214 return len; 214 return len;
215} 215}
216 216
217static int gator_events_armv7_offline(int** buffer) 217static int gator_events_armv7_offline(int **buffer)
218{ 218{
219 // disbale all counters, including PMCCNTR; overflow IRQs will not be signaled 219 // disable all counters, including PMCCNTR; overflow IRQs will not be signaled
220 armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E); 220 armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
221 221
222 return 0; 222 return 0;
223} 223}
224 224
@@ -298,7 +298,7 @@ int gator_events_armv7_init(void)
298 return -1; 298 return -1;
299 } 299 }
300 300
301 pmnc_counters++; // CNT[n] + CCNT 301 pmnc_counters++; // CNT[n] + CCNT
302 302
303 for (cnt = CCNT; cnt < CNTMAX; cnt++) { 303 for (cnt = CCNT; cnt < CNTMAX; cnt++) {
304 pmnc_enabled[cnt] = 0; 304 pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c
index b18c3ca..f512b13 100644
--- a/driver/gator_events_block.c
+++ b/driver/gator_events_block.c
@@ -119,7 +119,7 @@ static int gator_events_block_read(int **buffer)
119 if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) { 119 if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) {
120 atomic_sub(value, &blockCnt[BLOCK_RQ_WR]); 120 atomic_sub(value, &blockCnt[BLOCK_RQ_WR]);
121 blockGet[len++] = block_rq_wr_key; 121 blockGet[len++] = block_rq_wr_key;
122 blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message 122 blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
123 blockGet[len++] = block_rq_wr_key; 123 blockGet[len++] = block_rq_wr_key;
124 blockGet[len++] = value; 124 blockGet[len++] = value;
125 data += value; 125 data += value;
@@ -127,7 +127,7 @@ static int gator_events_block_read(int **buffer)
127 if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) { 127 if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) {
128 atomic_sub(value, &blockCnt[BLOCK_RQ_RD]); 128 atomic_sub(value, &blockCnt[BLOCK_RQ_RD]);
129 blockGet[len++] = block_rq_rd_key; 129 blockGet[len++] = block_rq_rd_key;
130 blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message 130 blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
131 blockGet[len++] = block_rq_rd_key; 131 blockGet[len++] = block_rq_rd_key;
132 blockGet[len++] = value; 132 blockGet[len++] = value;
133 data += value; 133 data += value;
@@ -156,4 +156,5 @@ int gator_events_block_init(void)
156 156
157 return gator_events_install(&gator_events_block_interface); 157 return gator_events_install(&gator_events_block_interface);
158} 158}
159
159gator_events_init(gator_events_block_init); 160gator_events_init(gator_events_block_init);
diff --git a/driver/gator_events_irq.c b/driver/gator_events_irq.c
index 435bc86..1221372 100644
--- a/driver/gator_events_irq.c
+++ b/driver/gator_events_irq.c
@@ -21,8 +21,8 @@ static ulong softirq_key;
21static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt); 21static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt);
22static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); 22static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet);
23 23
24GATOR_DEFINE_PROBE(irq_handler_exit, TP_PROTO(int irq, 24GATOR_DEFINE_PROBE(irq_handler_exit,
25 struct irqaction *action, int ret)) 25 TP_PROTO(int irq, struct irqaction *action, int ret))
26{ 26{
27 unsigned long flags; 27 unsigned long flags;
28 28
@@ -71,10 +71,10 @@ static int gator_events_irq_create_files(struct super_block *sb, struct dentry *
71 return 0; 71 return 0;
72} 72}
73 73
74static int gator_events_irq_online(int** buffer) 74static int gator_events_irq_online(int **buffer)
75{ 75{
76 int len = 0, cpu = smp_processor_id(); 76 int len = 0, cpu = smp_processor_id();
77 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt 77 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
78 78
79 // synchronization with the irq_exit functions is not necessary as the values are being reset 79 // synchronization with the irq_exit functions is not necessary as the values are being reset
80 if (hardirq_enabled) { 80 if (hardirq_enabled) {
@@ -136,7 +136,7 @@ static void gator_events_irq_stop(void)
136 136
137static int gator_events_irq_read(int **buffer) 137static int gator_events_irq_read(int **buffer)
138{ 138{
139 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt 139 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
140 int len, value; 140 int len, value;
141 int cpu = smp_processor_id(); 141 int cpu = smp_processor_id();
142 142
@@ -185,4 +185,5 @@ int gator_events_irq_init(void)
185 185
186 return gator_events_install(&gator_events_irq_interface); 186 return gator_events_install(&gator_events_irq_interface);
187} 187}
188
188gator_events_init(gator_events_irq_init); 189gator_events_init(gator_events_irq_init);
diff --git a/driver/gator_events_l2c-310.c b/driver/gator_events_l2c-310.c
index bd1c48a..197af04 100644
--- a/driver/gator_events_l2c-310.c
+++ b/driver/gator_events_l2c-310.c
@@ -26,8 +26,6 @@ static int l2c310_buffer[L2C310_COUNTERS_NUM * 2];
26 26
27static void __iomem *l2c310_base; 27static void __iomem *l2c310_base;
28 28
29
30
31static void gator_events_l2c310_reset_counters(void) 29static void gator_events_l2c310_reset_counters(void)
32{ 30{
33 u32 val = readl(l2c310_base + L2X0_EVENT_CNT_CTRL); 31 u32 val = readl(l2c310_base + L2X0_EVENT_CNT_CTRL);
@@ -37,9 +35,8 @@ static void gator_events_l2c310_reset_counters(void)
37 writel(val, l2c310_base + L2X0_EVENT_CNT_CTRL); 35 writel(val, l2c310_base + L2X0_EVENT_CNT_CTRL);
38} 36}
39 37
40
41static int gator_events_l2c310_create_files(struct super_block *sb, 38static int gator_events_l2c310_create_files(struct super_block *sb,
42 struct dentry *root) 39 struct dentry *root)
43{ 40{
44 int i; 41 int i;
45 42
@@ -52,11 +49,11 @@ static int gator_events_l2c310_create_files(struct super_block *sb,
52 if (WARN_ON(!dir)) 49 if (WARN_ON(!dir))
53 return -1; 50 return -1;
54 gatorfs_create_ulong(sb, dir, "enabled", 51 gatorfs_create_ulong(sb, dir, "enabled",
55 &l2c310_counters[i].enabled); 52 &l2c310_counters[i].enabled);
56 gatorfs_create_ulong(sb, dir, "event", 53 gatorfs_create_ulong(sb, dir, "event",
57 &l2c310_counters[i].event); 54 &l2c310_counters[i].event);
58 gatorfs_create_ro_ulong(sb, dir, "key", 55 gatorfs_create_ro_ulong(sb, dir, "key",
59 &l2c310_counters[i].key); 56 &l2c310_counters[i].key);
60 } 57 }
61 58
62 return 0; 59 return 0;
@@ -73,7 +70,7 @@ static int gator_events_l2c310_start(void)
73 /* Counter event sources */ 70 /* Counter event sources */
74 for (i = 0; i < L2C310_COUNTERS_NUM; i++) 71 for (i = 0; i < L2C310_COUNTERS_NUM; i++)
75 writel((l2c310_counters[i].event & 0xf) << 2, 72 writel((l2c310_counters[i].event & 0xf) << 2,
76 l2c310_base + l2x0_event_cntx_cfg[i]); 73 l2c310_base + l2x0_event_cntx_cfg[i]);
77 74
78 gator_events_l2c310_reset_counters(); 75 gator_events_l2c310_reset_counters();
79 76
@@ -105,10 +102,10 @@ static int gator_events_l2c310_read(int **buffer)
105 if (l2c310_counters[i].enabled) { 102 if (l2c310_counters[i].enabled) {
106 l2c310_buffer[len++] = l2c310_counters[i].key; 103 l2c310_buffer[len++] = l2c310_counters[i].key;
107 l2c310_buffer[len++] = readl(l2c310_base + 104 l2c310_buffer[len++] = readl(l2c310_base +
108 l2x0_event_cntx_val[i]); 105 l2x0_event_cntx_val[i]);
109 } 106 }
110 } 107 }
111 108
112 /* l2c310 counters are saturating, not wrapping in case of overflow */ 109 /* l2c310 counters are saturating, not wrapping in case of overflow */
113 gator_events_l2c310_reset_counters(); 110 gator_events_l2c310_reset_counters();
114 111
@@ -176,4 +173,5 @@ int gator_events_l2c310_init(void)
176 173
177 return gator_events_install(&gator_events_l2c310_interface); 174 return gator_events_install(&gator_events_l2c310_interface);
178} 175}
176
179gator_events_init(gator_events_l2c310_init); 177gator_events_init(gator_events_l2c310_init);
diff --git a/driver/gator_events_mali_400.c b/driver/gator_events_mali_400.c
index a44cd8e..34a73c8 100644
--- a/driver/gator_events_mali_400.c
+++ b/driver/gator_events_mali_400.c
@@ -17,14 +17,6 @@
17#include "gator_events_mali_common.h" 17#include "gator_events_mali_common.h"
18#include "gator_events_mali_400.h" 18#include "gator_events_mali_400.h"
19 19
20#if !defined(GATOR_MALI_INTERFACE_STYLE)
21/*
22 * At the moment, we only have users with the old style interface, so
23 * make our life easier by making it the default...
24 */
25#define GATOR_MALI_INTERFACE_STYLE (2)
26#endif
27
28/* 20/*
29 * There are (currently) three different variants of the comms between gator and Mali: 21 * There are (currently) three different variants of the comms between gator and Mali:
30 * 1 (deprecated): No software counter support 22 * 1 (deprecated): No software counter support
@@ -60,81 +52,81 @@
60#define NUM_FP_UNITS (4) 52#define NUM_FP_UNITS (4)
61 53
62enum counters { 54enum counters {
63 /* Timeline activity */ 55 /* Timeline activity */
64 ACTIVITY_VP = 0, 56 ACTIVITY_VP = 0,
65 ACTIVITY_FP0, 57 ACTIVITY_FP0,
66 ACTIVITY_FP1, 58 ACTIVITY_FP1,
67 ACTIVITY_FP2, 59 ACTIVITY_FP2,
68 ACTIVITY_FP3, 60 ACTIVITY_FP3,
69 61
70 /* L2 cache counters */ 62 /* L2 cache counters */
71 COUNTER_L2_C0, 63 COUNTER_L2_C0,
72 COUNTER_L2_C1, 64 COUNTER_L2_C1,
73 65
74 /* Vertex processor counters */ 66 /* Vertex processor counters */
75 COUNTER_VP_C0, 67 COUNTER_VP_C0,
76 COUNTER_VP_C1, 68 COUNTER_VP_C1,
77 69
78 /* Fragment processor counters */ 70 /* Fragment processor counters */
79 COUNTER_FP0_C0, 71 COUNTER_FP0_C0,
80 COUNTER_FP0_C1, 72 COUNTER_FP0_C1,
81 COUNTER_FP1_C0, 73 COUNTER_FP1_C0,
82 COUNTER_FP1_C1, 74 COUNTER_FP1_C1,
83 COUNTER_FP2_C0, 75 COUNTER_FP2_C0,
84 COUNTER_FP2_C1, 76 COUNTER_FP2_C1,
85 COUNTER_FP3_C0, 77 COUNTER_FP3_C0,
86 COUNTER_FP3_C1, 78 COUNTER_FP3_C1,
87 79
88 /* EGL Software Counters */ 80 /* EGL Software Counters */
89 COUNTER_EGL_BLIT_TIME, 81 COUNTER_EGL_BLIT_TIME,
90 82
91 /* GLES Software Counters */ 83 /* GLES Software Counters */
92 COUNTER_GLES_DRAW_ELEMENTS_CALLS, 84 COUNTER_GLES_DRAW_ELEMENTS_CALLS,
93 COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, 85 COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
94 COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, 86 COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
95 COUNTER_GLES_DRAW_ARRAYS_CALLS, 87 COUNTER_GLES_DRAW_ARRAYS_CALLS,
96 COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, 88 COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
97 COUNTER_GLES_DRAW_POINTS, 89 COUNTER_GLES_DRAW_POINTS,
98 COUNTER_GLES_DRAW_LINES, 90 COUNTER_GLES_DRAW_LINES,
99 COUNTER_GLES_DRAW_LINE_LOOP, 91 COUNTER_GLES_DRAW_LINE_LOOP,
100 COUNTER_GLES_DRAW_LINE_STRIP, 92 COUNTER_GLES_DRAW_LINE_STRIP,
101 COUNTER_GLES_DRAW_TRIANGLES, 93 COUNTER_GLES_DRAW_TRIANGLES,
102 COUNTER_GLES_DRAW_TRIANGLE_STRIP, 94 COUNTER_GLES_DRAW_TRIANGLE_STRIP,
103 COUNTER_GLES_DRAW_TRIANGLE_FAN, 95 COUNTER_GLES_DRAW_TRIANGLE_FAN,
104 COUNTER_GLES_NON_VBO_DATA_COPY_TIME, 96 COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
105 COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, 97 COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
106 COUNTER_GLES_UPLOAD_TEXTURE_TIME, 98 COUNTER_GLES_UPLOAD_TEXTURE_TIME,
107 COUNTER_GLES_UPLOAD_VBO_TIME, 99 COUNTER_GLES_UPLOAD_VBO_TIME,
108 COUNTER_GLES_NUM_FLUSHES, 100 COUNTER_GLES_NUM_FLUSHES,
109 COUNTER_GLES_NUM_VSHADERS_GENERATED, 101 COUNTER_GLES_NUM_VSHADERS_GENERATED,
110 COUNTER_GLES_NUM_FSHADERS_GENERATED, 102 COUNTER_GLES_NUM_FSHADERS_GENERATED,
111 COUNTER_GLES_VSHADER_GEN_TIME, 103 COUNTER_GLES_VSHADER_GEN_TIME,
112 COUNTER_GLES_FSHADER_GEN_TIME, 104 COUNTER_GLES_FSHADER_GEN_TIME,
113 COUNTER_GLES_INPUT_TRIANGLES, 105 COUNTER_GLES_INPUT_TRIANGLES,
114 COUNTER_GLES_VXCACHE_HIT, 106 COUNTER_GLES_VXCACHE_HIT,
115 COUNTER_GLES_VXCACHE_MISS, 107 COUNTER_GLES_VXCACHE_MISS,
116 COUNTER_GLES_VXCACHE_COLLISION, 108 COUNTER_GLES_VXCACHE_COLLISION,
117 COUNTER_GLES_CULLED_TRIANGLES, 109 COUNTER_GLES_CULLED_TRIANGLES,
118 COUNTER_GLES_CULLED_LINES, 110 COUNTER_GLES_CULLED_LINES,
119 COUNTER_GLES_BACKFACE_TRIANGLES, 111 COUNTER_GLES_BACKFACE_TRIANGLES,
120 COUNTER_GLES_GBCLIP_TRIANGLES, 112 COUNTER_GLES_GBCLIP_TRIANGLES,
121 COUNTER_GLES_GBCLIP_LINES, 113 COUNTER_GLES_GBCLIP_LINES,
122 COUNTER_GLES_TRIANGLES_DRAWN, 114 COUNTER_GLES_TRIANGLES_DRAWN,
123 COUNTER_GLES_DRAWCALL_TIME, 115 COUNTER_GLES_DRAWCALL_TIME,
124 COUNTER_GLES_TRIANGLES_COUNT, 116 COUNTER_GLES_TRIANGLES_COUNT,
125 COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, 117 COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
126 COUNTER_GLES_STRIP_TRIANGLES_COUNT, 118 COUNTER_GLES_STRIP_TRIANGLES_COUNT,
127 COUNTER_GLES_FAN_TRIANGLES_COUNT, 119 COUNTER_GLES_FAN_TRIANGLES_COUNT,
128 COUNTER_GLES_LINES_COUNT, 120 COUNTER_GLES_LINES_COUNT,
129 COUNTER_GLES_INDEPENDENT_LINES_COUNT, 121 COUNTER_GLES_INDEPENDENT_LINES_COUNT,
130 COUNTER_GLES_STRIP_LINES_COUNT, 122 COUNTER_GLES_STRIP_LINES_COUNT,
131 COUNTER_GLES_LOOP_LINES_COUNT, 123 COUNTER_GLES_LOOP_LINES_COUNT,
132 124
133 COUNTER_FILMSTRIP, 125 COUNTER_FILMSTRIP,
134 COUNTER_FREQUENCY, 126 COUNTER_FREQUENCY,
135 COUNTER_VOLTAGE, 127 COUNTER_VOLTAGE,
136 128
137 NUMBER_OF_EVENTS 129 NUMBER_OF_EVENTS
138}; 130};
139 131
140#define FIRST_ACTIVITY_EVENT ACTIVITY_VP 132#define FIRST_ACTIVITY_EVENT ACTIVITY_VP
@@ -161,7 +153,7 @@ static unsigned long counter_key[NUMBER_OF_EVENTS];
161/* The data we have recorded */ 153/* The data we have recorded */
162static u32 counter_data[NUMBER_OF_EVENTS]; 154static u32 counter_data[NUMBER_OF_EVENTS];
163/* The address to sample (or 0 if samples are sent to us) */ 155/* The address to sample (or 0 if samples are sent to us) */
164static u32* counter_address[NUMBER_OF_EVENTS]; 156static u32 *counter_address[NUMBER_OF_EVENTS];
165 157
166/* An array used to return the data we recorded 158/* An array used to return the data we recorded
167 * as key,value pairs hence the *2 159 * as key,value pairs hence the *2
@@ -177,13 +169,12 @@ static int trace_registered;
177 */ 169 */
178static u32 get_difference(u32 start, u32 end) 170static u32 get_difference(u32 start, u32 end)
179{ 171{
180 if (start - end >= 0) 172 if (start - end >= 0) {
181 { 173 return start - end;
182 return start - end; 174 }
183 }
184 175
185 // Mali counters are unsigned 32 bit values that wrap. 176 // Mali counters are unsigned 32 bit values that wrap.
186 return (4294967295u - end) + start; 177 return (4294967295u - end) + start;
187} 178}
188 179
189/** 180/**
@@ -191,8 +182,8 @@ static u32 get_difference(u32 start, u32 end)
191 */ 182 */
192static inline int is_activity_counter(unsigned int event_id) 183static inline int is_activity_counter(unsigned int event_id)
193{ 184{
194 return (event_id >= FIRST_ACTIVITY_EVENT && 185 return (event_id >= FIRST_ACTIVITY_EVENT &&
195 event_id <= LAST_ACTIVITY_EVENT); 186 event_id <= LAST_ACTIVITY_EVENT);
196} 187}
197 188
198/** 189/**
@@ -200,7 +191,7 @@ static inline int is_activity_counter(unsigned int event_id)
200 */ 191 */
201static inline int is_hw_counter(unsigned int event_id) 192static inline int is_hw_counter(unsigned int event_id)
202{ 193{
203 return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER); 194 return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
204} 195}
205 196
206#if GATOR_MALI_INTERFACE_STYLE == 2 197#if GATOR_MALI_INTERFACE_STYLE == 2
@@ -209,7 +200,7 @@ static inline int is_hw_counter(unsigned int event_id)
209 */ 200 */
210static inline int is_sw_counter(unsigned int event_id) 201static inline int is_sw_counter(unsigned int event_id)
211{ 202{
212 return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER); 203 return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
213} 204}
214#endif 205#endif
215 206
@@ -217,209 +208,204 @@ static inline int is_sw_counter(unsigned int event_id)
217/* 208/*
218 * The Mali DDK uses s64 types to contain software counter values, but gator 209 * The Mali DDK uses s64 types to contain software counter values, but gator
219 * can only use a maximum of 32 bits. This function scales a software counter 210 * can only use a maximum of 32 bits. This function scales a software counter
220 * to an appopriate range. 211 * to an appropriate range.
221 */ 212 */
222static u32 scale_sw_counter_value(unsigned int event_id, signed long long value) 213static u32 scale_sw_counter_value(unsigned int event_id, signed long long value)
223{ 214{
224 u32 scaled_value; 215 u32 scaled_value;
225 216
226 switch (event_id) { 217 switch (event_id) {
227 case COUNTER_GLES_UPLOAD_TEXTURE_TIME: 218 case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
228 case COUNTER_GLES_UPLOAD_VBO_TIME: 219 case COUNTER_GLES_UPLOAD_VBO_TIME:
229 scaled_value = (u32)div_s64(value, 1000000); 220 scaled_value = (u32)div_s64(value, 1000000);
230 break; 221 break;
231 default: 222 default:
232 scaled_value = (u32)value; 223 scaled_value = (u32)value;
233 break; 224 break;
234 } 225 }
235 226
236 return scaled_value; 227 return scaled_value;
237} 228}
238#endif 229#endif
239 230
240/* Probe for continuously sampled counter */ 231/* Probe for continuously sampled counter */
241#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING 232#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
242GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32* addr)) 233GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32 *addr))
243{ 234{
244 /* Turning on too many pr_debug statements in frequently called functions 235 /* Turning on too many pr_debug statements in frequently called functions
245 * can cause stability and/or performance problems 236 * can cause stability and/or performance problems
246 */ 237 */
247 //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr); 238 //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr);
248 if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) { 239 if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) {
249 counter_address[event_id] = addr; 240 counter_address[event_id] = addr;
250 } 241 }
251} 242}
252#endif 243#endif
253 244
254/* Probe for hardware counter events */ 245/* Probe for hardware counter events */
255GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value)) 246GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value))
256{ 247{
257 /* Turning on too many pr_debug statements in frequently called functions 248 /* Turning on too many pr_debug statements in frequently called functions
258 * can cause stability and/or performance problems 249 * can cause stability and/or performance problems
259 */ 250 */
260 //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value); 251 //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value);
261 if (is_hw_counter(event_id)) { 252 if (is_hw_counter(event_id)) {
262 counter_data[event_id] = value; 253 counter_data[event_id] = value;
263 } 254 }
264} 255}
265 256
266#if GATOR_MALI_INTERFACE_STYLE == 2 257#if GATOR_MALI_INTERFACE_STYLE == 2
267GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value)) 258GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value))
268{ 259{
269 if (is_sw_counter(event_id)) { 260 if (is_sw_counter(event_id)) {
270 counter_data[event_id] = scale_sw_counter_value(event_id, value); 261 counter_data[event_id] = scale_sw_counter_value(event_id, value);
271 } 262 }
272} 263}
273#endif /* GATOR_MALI_INTERFACE_STYLE == 2 */ 264#endif /* GATOR_MALI_INTERFACE_STYLE == 2 */
274 265
275
276#if GATOR_MALI_INTERFACE_STYLE == 3 266#if GATOR_MALI_INTERFACE_STYLE == 3
277GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters)) 267GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters))
278{ 268{
279 u32 i; 269 u32 i;
280 270
281 /* Copy over the values for those counters which are enabled. */ 271 /* Copy over the values for those counters which are enabled. */
282 for(i=FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) 272 for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
283 { 273 if (counter_enabled[i]) {
284 if(counter_enabled[i]) 274 counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]);
285 { 275 }
286 counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]); 276 }
287 }
288 }
289} 277}
290#endif /* GATOR_MALI_INTERFACE_STYLE == 3 */ 278#endif /* GATOR_MALI_INTERFACE_STYLE == 3 */
291 279
292static int create_files(struct super_block *sb, struct dentry *root) { 280static int create_files(struct super_block *sb, struct dentry *root)
293 struct dentry *dir; 281{
294 int event; 282 struct dentry *dir;
295 int n_fp = NUM_FP_UNITS; 283 int event;
296 284 int n_fp = NUM_FP_UNITS;
297 const char* mali_name = gator_mali_get_mali_name(); 285
298 286 const char *mali_name = gator_mali_get_mali_name();
299 /* 287
300 * Create the filesystem entries for vertex processor, fragement processor 288 /*
301 * and L2 cache timeline and hardware counters. Software counters get 289 * Create the filesystem entries for vertex processor, fragment processor
302 * special handling after this block. 290 * and L2 cache timeline and hardware counters. Software counters get
303 */ 291 * special handling after this block.
304 for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) 292 */
305 { 293 for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) {
306 char buf[40]; 294 char buf[40];
307 295
308 /* 296 /*
309 * We can skip this event if it's for a non-existent fragment 297 * We can skip this event if it's for a non-existent fragment
310 * processor. 298 * processor.
311 */ 299 */
312 if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0)) || 300 if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0))
313 (((event - COUNTER_FP0_C0)/2 >= n_fp))) 301 || (((event - COUNTER_FP0_C0) / 2 >= n_fp))) {
314 { 302 continue;
315 continue; 303 }
316 } 304
317 305 /* Otherwise, set up the filesystem entry for this event. */
318 /* Otherwise, set up the filesystem entry for this event. */ 306 switch (event) {
319 switch (event) { 307 case ACTIVITY_VP:
320 case ACTIVITY_VP: 308 snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name);
321 snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name); 309 break;
322 break; 310 case ACTIVITY_FP0:
323 case ACTIVITY_FP0: 311 case ACTIVITY_FP1:
324 case ACTIVITY_FP1: 312 case ACTIVITY_FP2:
325 case ACTIVITY_FP2: 313 case ACTIVITY_FP3:
326 case ACTIVITY_FP3: 314 snprintf(buf, sizeof buf, "ARM_%s_FP%d_active",
327 snprintf(buf, sizeof buf, "ARM_%s_FP%d_active", 315 mali_name, event - ACTIVITY_FP0);
328 mali_name, event - ACTIVITY_FP0);