diff options
author | Jon Medhurst | 2013-01-14 11:16:24 -0600 |
---|---|---|
committer | Jon Medhurst | 2013-01-14 11:16:24 -0600 |
commit | 3c295d4955ed76ce1fee385305153c1334a9b890 (patch) | |
tree | 18ae79e6c43406e15fecda3e1c49775c2dc64cce | |
parent | 197f43d9c9c94dec5f05cb93047d9d10f7915265 (diff) | |
parent | bceca61860ed3cde4adc5c9231b7099d9b6f5786 (diff) | |
download | arm-ds5-gator-3c295d4955ed76ce1fee385305153c1334a9b890.tar.gz arm-ds5-gator-3c295d4955ed76ce1fee385305153c1334a9b890.tar.xz arm-ds5-gator-3c295d4955ed76ce1fee385305153c1334a9b890.zip |
Merge branch 'master' into android
59 files changed, 2867 insertions, 2727 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 @@ | |||
1 | LOCAL_PATH:= $(call my-dir) | 1 | LOCAL_PATH := $(call my-dir) |
2 | include $(CLEAR_VARS) | 2 | include $(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) | 4 | XML_H := $(shell cd $(LOCAL_PATH) && make events_xml.h configuration_xml.h) |
5 | 5 | ||
6 | LOCAL_CFLAGS += -Wall -O3 -ftree-vectorize -Wno-error=sequence-point | 6 | LOCAL_CFLAGS += -Wall -O3 -mthumb-interwork -fno-exceptions |
7 | 7 | ||
8 | LOCAL_SRC_FILES:= \ | 8 | LOCAL_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 | ||
34 | LOCAL_C_INCLUDES := $(LOCAL_PATH) | 34 | LOCAL_C_INCLUDES := $(LOCAL_PATH) |
35 | 35 | ||
36 | LOCAL_MODULE:= gatord | 36 | LOCAL_MODULE := gatord |
37 | LOCAL_MODULE_TAGS:= optional | 37 | LOCAL_MODULE_TAGS := optional |
38 | 38 | ||
39 | LOCAL_LDLIBS := -lz -llog | 39 | include $(BUILD_EXECUTABLE) |
40 | |||
41 | include $(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 | ||
17 | extern void handleException(); | ||
18 | |||
19 | CapturedXML::CapturedXML() { | 17 | CapturedXML::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 | ||
114 | const 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 | ||
25 | const 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 | ||
21 | extern void handleException(); | ||
22 | |||
23 | // Driver initialization independent of session settings | 21 | // Driver initialization independent of session settings |
24 | Collector::Collector() { | 22 | Collector::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 | ||
17 | extern void handleException(); | ||
18 | |||
19 | static const char* ATTR_COUNTER = "counter"; | 17 | static const char* ATTR_COUNTER = "counter"; |
20 | static const char* ATTR_REVISION = "revision"; | 18 | static const char* ATTR_REVISION = "revision"; |
21 | static const char* ATTR_TITLE = "title"; | 19 | static 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 | ||
186 | void ConfigurationXML::getDefaultConfigurationXml(const char * & xml, unsigned int & len) { | 184 | void 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 | ||
15 | extern 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 | ||
38 | Fifo::~Fifo() { | 36 | Fifo::~Fifo() { |
39 | free(mBuffer); | 37 | free(mBuffer); |
38 | sem_destroy(&mWaitForSpaceSem); | ||
39 | sem_destroy(&mWaitForDataSem); | ||
40 | } | 40 | } |
41 | 41 | ||
42 | int Fifo::numBytesFilled() { | 42 | int Fifo::numBytesFilled() const { |
43 | return mWrite - mRead + mRaggedEnd; | 43 | return mWrite - mRead + mRaggedEnd; |
44 | } | 44 | } |
45 | 45 | ||
46 | char* Fifo::start() { | 46 | char* Fifo::start() const { |
47 | return mBuffer; | 47 | return mBuffer; |
48 | } | 48 | } |
49 | 49 | ||
50 | bool Fifo::isEmpty() { | 50 | bool Fifo::isEmpty() const { |
51 | return mRead == mWrite && mRaggedEnd == 0; | 51 | return mRead == mWrite && mRaggedEnd == 0; |
52 | } | 52 | } |
53 | 53 | ||
54 | bool Fifo::isFull() { | 54 | bool 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 |
60 | bool Fifo::willFill(int additional) { | 60 | bool 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 |
101 | char* Fifo::read(int* length) { | 101 | char* 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 { | |||
15 | public: | 15 | public: |
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 | ||
26 | private: | 26 | private: |
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 | ||
20 | extern void handleException(); | ||
21 | |||
22 | LocalCapture::LocalCapture() {} | 20 | LocalCapture::LocalCapture() {} |
23 | 21 | ||
24 | LocalCapture::~LocalCapture() {} | 22 | LocalCapture::~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 | ||
43 | extern Logging* logg; | 43 | extern Logging* logg; |
44 | 44 | ||
45 | extern 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 | ||
11 | ARCH=arm | 11 | CPP = $(CROSS_COMPILE)g++ |
12 | 12 | GCC = $(CROSS_COMPILE)gcc | |
13 | CPP=$(CROSS_COMPILE)g++ | ||
14 | GCC=$(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 |
24 | CFLAGS=-O3 -Wall -mthumb-interwork | 22 | CFLAGS = -O3 -Wall -mthumb-interwork -fno-exceptions |
23 | CXXFLAGS = -fno-rtti | ||
25 | ifeq ($(WERROR),1) | 24 | ifeq ($(WERROR),1) |
26 | CFLAGS += -Werror | 25 | CFLAGS += -Werror |
27 | endif | 26 | endif |
28 | # -s strips the binary of debug info | 27 | # -s strips the binary of debug info |
29 | LDFLAGS=-s | 28 | LDFLAGS = -s |
30 | TARGET=gatord | 29 | TARGET = gatord |
31 | C_SRC = $(wildcard mxml/*.c) | 30 | C_SRC = $(wildcard mxml/*.c) |
32 | CPP_SRC = $(wildcard *.cpp) | 31 | CPP_SRC = $(wildcard *.cpp) |
33 | TGT_OBJS = $(CPP_SRC:%.cpp=%.o) \ | ||
34 | $(C_SRC:%.c=%.o) | ||
35 | 32 | ||
36 | all: $(TARGET) | 33 | all: $(TARGET) |
37 | 34 | ||
35 | events.xml: events_header.xml $(wildcard events-*.xml) events_footer.xml | ||
36 | cat $^ > $@ | ||
37 | |||
38 | StreamlineSetup.cpp: events_xml.h | ||
39 | ConfigurationXML.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 | ||
48 | convert: | 54 | escape: 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 | ||
53 | clean: | 57 | clean: |
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 | ||
30 | extern void handleException(); | ||
31 | |||
32 | OlySocket::OlySocket(int port, bool multiple) { | 30 | OlySocket::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 | ||
48 | OlySocket::OlySocket(int port, char* host) { | 46 | OlySocket::OlySocket(int port, char* host) { |
49 | mFDServer = 0; | 47 | mFDServer = 0; |
50 | createClientSocket(host, port); | 48 | createClientSocket(host, port); |
51 | } | 49 | } |
52 | 50 | ||
53 | OlySocket::~OlySocket() { | 51 | OlySocket::~OlySocket() { |
54 | if (mSocketID > 0) { | 52 | if (mSocketID > 0) { |
55 | CLOSE_SOCKET(mSocketID); | 53 | CLOSE_SOCKET(mSocketID); |
56 | } | 54 | } |
57 | } | 55 | } |
58 | 56 | ||
59 | void OlySocket::shutdownConnection() { | 57 | void 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 | ||
64 | void OlySocket::closeSocket() { | 62 | void 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 | ||
72 | void OlySocket::closeServerSocket() { | 70 | void 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 | ||
80 | void OlySocket::createClientSocket(char* hostname, int portno) { | 78 | void 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 | ||
121 | void OlySocket::createSingleServerConnection(int port) { | 119 | void 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 | ||
128 | void OlySocket::createServerSocket(int port) { | 126 | void 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 |
165 | int OlySocket::acceptConnection() { | 163 | int 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 | ||
180 | void OlySocket::send(char* buffer, int size) { | 178 | void 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 |
197 | int OlySocket::receive(char* buffer, int size) { | 195 | int 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 |
214 | int OlySocket::receiveNBytes(char* buffer, int size) { | 212 | int 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 |
232 | int OlySocket::receiveString(char* buffer, int size) { | 230 | int 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 | ||
14 | class OlySocket { | 14 | class OlySocket { |
15 | public: | 15 | public: |
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;} |
29 | private: | 29 | private: |
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 @@ | |||
22 | OlyUtility* util = NULL; | 24 | OlyUtility* util = NULL; |
23 | 25 | ||
24 | bool OlyUtility::stringToBool(const char* string, bool defValue) { | 26 | bool 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 | ||
53 | void OlyUtility::stringToLower(char* string) { | 55 | void 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 |
65 | int OlyUtility::getApplicationFullPath(char* fullpath, int sizeOfPath) { | 67 | int 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 | ||
83 | char* OlyUtility::readFromDisk(const char* file, unsigned int *size, bool appendNull) { | 91 | char* 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 | ||
123 | int OlyUtility::writeToDisk(const char* path, const char* data) { | 131 | int 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 | ||
141 | int OlyUtility::appendToDisk(const char* path, const char* data) { | 149 | int 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 |
165 | int OlyUtility::copyFile(const char* srcFile, const char* dstFile) { | 173 | int 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 | ||
196 | const char* OlyUtility::getFilePart(const char* path) { | 204 | const 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 |
209 | char* OlyUtility::getPathPart(char* path) { | 217 | char* 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 | ||
223 | const 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 | ||
18 | class OlyUtility { | 22 | class OlyUtility { |
19 | public: | 23 | public: |
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); |
31 | private: | 35 | private: |
32 | }; | 36 | }; |
33 | 37 | ||
34 | #include "mxml/mxml.h" | ||
35 | const char * mxmlWhitespaceCB(mxml_node_t *node, int where); | ||
36 | extern OlyUtility* util; | 38 | extern 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 | ||
20 | extern void handleException(); | ||
21 | |||
22 | Sender::Sender(OlySocket* socket) { | 20 | Sender::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" |
13 | extern void handleException(); | ||
14 | 13 | ||
15 | SessionData* gSessionData = NULL; | 14 | SessionData* 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 | ||
19 | struct ImageLinkList { | 19 | struct 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 | ||
16 | extern void handleException(); | ||
17 | |||
18 | static const char* TAG_SESSION = "session"; | 16 | static const char* TAG_SESSION = "session"; |
19 | static const char* TAG_IMAGE = "image"; | 17 | static 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 | ||
25 | extern void handleException(); | ||
26 | |||
27 | static const char* TAG_SESSION = "session"; | 25 | static const char* TAG_SESSION = "session"; |
28 | static const char* TAG_REQUEST = "request"; | 26 | static const char* TAG_REQUEST = "request"; |
29 | static const char* TAG_CONFIGURATIONS = "configurations"; | 27 | static const char* TAG_CONFIGURATIONS = "configurations"; |
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-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 | ||
30 | extern Child* child; | 32 | extern Child* child; |
31 | extern void handleException(); | ||
32 | int shutdownFilesystem(); | 33 | int shutdownFilesystem(); |
33 | static pthread_mutex_t numSessions_mutex; | 34 | static pthread_mutex_t numSessions_mutex; |
34 | static int numSessions = 0; | 35 | static 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 |
299 | int main(int argc, char** argv, char* envp[]) { | 300 | int 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 | |||
27 | EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) | 27 | EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) |
28 | endif | 28 | endif |
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. |
31 | GATOR_TEST ?= 0 | 31 | GATOR_TEST ?= 0 |
32 | EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST) | 32 | EXTRA_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 | |||
44 | struct 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 | |||
52 | extern struct gator_cpu gator_cpus[]; | ||
37 | 53 | ||
38 | /****************************************************************************** | 54 | /****************************************************************************** |
39 | * Filesystem | 55 | * Filesystem |
40 | ******************************************************************************/ | 56 | ******************************************************************************/ |
41 | int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root, | 57 | int 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 | ||
44 | struct dentry *gatorfs_mkdir(struct super_block *sb, | 61 | struct dentry *gatorfs_mkdir(struct super_block *sb, struct dentry *root, |
45 | struct dentry *root, char const *name); | 62 | char const *name); |
46 | 63 | ||
47 | int gatorfs_create_ulong(struct super_block *sb, struct dentry *root, | 64 | int 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 | ||
50 | int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root, | 67 | int 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 | ||
53 | void gator_op_create_files(struct super_block *sb, struct dentry *root); | 70 | void 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 | ******************************************************************************/ |
79 | struct gator_interface { | 96 | struct 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 | ||
97 | int gator_events_install(struct gator_interface *interface); | 115 | int gator_events_install(struct gator_interface *interface); |
98 | int gator_events_get_key(void); | 116 | int gator_events_get_key(void); |
99 | extern u32 gator_cpuid(void); | 117 | u32 gator_cpuid(void); |
100 | 118 | ||
101 | void gator_backtrace_handler(struct pt_regs * const regs); | 119 | void 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 | ||
141 | static const struct file_operations annotate_fops = { | 146 | static 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 | ||
146 | static int gator_annotate_create_files(struct super_block *sb, struct dentry *root) | 151 | static 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 | ||
15 | static void kannotate_write(const char* ptr, unsigned int size) | 17 | static 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 | ||
30 | static void gator_annotate_code(char code) | 32 | void 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 | ||
36 | static void gator_annotate_code_str(char code, const char* string) | 40 | EXPORT_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 | ||
44 | static void gator_annotate_code_color(char code, int color) | 42 | void 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 | ||
50 | static void gator_annotate_code_color_str(char code, int color, const char* string) | 47 | EXPORT_SYMBOL(gator_annotate); |
48 | |||
49 | void 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 | 62 | EXPORT_SYMBOL(gator_annotate_channel_color); |
59 | void gator_annotate(const char* string) | 63 | |
64 | void 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 | } |
63 | EXPORT_SYMBOL(gator_annotate); | ||
64 | 68 | ||
65 | // String annotation with color | 69 | EXPORT_SYMBOL(gator_annotate_color); |
66 | void gator_annotate_color(int color, const char* string) | 70 | |
71 | void 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 | } |
70 | EXPORT_SYMBOL(gator_annotate_color); | ||
71 | 76 | ||
72 | // Terminate an annotation | 77 | EXPORT_SYMBOL(gator_annotate_channel_end); |
78 | |||
73 | void gator_annotate_end(void) | 79 | void gator_annotate_end(void) |
74 | { | 80 | { |
75 | gator_annotate_code(STRING_ANNOTATION); | 81 | gator_annotate_channel_end(0); |
76 | } | 82 | } |
83 | |||
77 | EXPORT_SYMBOL(gator_annotate_end); | 84 | EXPORT_SYMBOL(gator_annotate_end); |
78 | 85 | ||
79 | // Image annotation with optional string | 86 | void gator_annotate_name_channel(int channel, int group, const char* str) |
80 | void 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 | |||
99 | EXPORT_SYMBOL(gator_annotate_name_channel); | ||
100 | |||
101 | void 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 | |||
109 | EXPORT_SYMBOL(gator_annotate_name_group); | ||
110 | |||
111 | void 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 | |||
89 | EXPORT_SYMBOL(gator_annotate_visual); | 121 | EXPORT_SYMBOL(gator_annotate_visual); |
90 | 122 | ||
91 | // Marker annotation | ||
92 | void gator_annotate_marker(void) | 123 | void 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 | |||
96 | EXPORT_SYMBOL(gator_annotate_marker); | 129 | EXPORT_SYMBOL(gator_annotate_marker); |
97 | 130 | ||
98 | // Marker annotation with a string | 131 | void gator_annotate_marker_str(const char *str) |
99 | void 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 | |||
103 | EXPORT_SYMBOL(gator_annotate_marker_str); | 139 | EXPORT_SYMBOL(gator_annotate_marker_str); |
104 | 140 | ||
105 | // Marker annotation with a color | ||
106 | void gator_annotate_marker_color(int color) | 141 | void 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 | |||
110 | EXPORT_SYMBOL(gator_annotate_marker_color); | 147 | EXPORT_SYMBOL(gator_annotate_marker_color); |
111 | 148 | ||
112 | // Marker annotation with a string and color | 149 | void gator_annotate_marker_color_str(int color, const char *str) |
113 | void 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 | |||
117 | EXPORT_SYMBOL(gator_annotate_marker_color_str); | 157 | EXPORT_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 | */ |
13 | struct frame_tail_eabi { | 13 | struct 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 | ||
18 | static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth) | 18 | static 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__) |
72 | static int report_trace(struct stackframe *frame, void *d) | 80 | static 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 |
94 | static void kernel_backtrace(int cpu, struct pt_regs * const regs) | 102 | static 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); | |||
20 | static DEFINE_PER_CPU(uint32_t *, cookie_values); | 20 | static DEFINE_PER_CPU(uint32_t *, cookie_values); |
21 | static DEFINE_PER_CPU(int, translate_buffer_read); | 21 | static DEFINE_PER_CPU(int, translate_buffer_read); |
22 | static DEFINE_PER_CPU(int, translate_buffer_write); | 22 | static DEFINE_PER_CPU(int, translate_buffer_write); |
23 | static DEFINE_PER_CPU(void * *, translate_buffer); | 23 | static DEFINE_PER_CPU(void **, translate_buffer); |
24 | 24 | ||
25 | static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt); | 25 | static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq); |
26 | static void wq_cookie_handler(struct work_struct *unused); | 26 | static void wq_cookie_handler(struct work_struct *unused); |
27 | DECLARE_WORK(cookie_work, wq_cookie_handler); | 27 | DECLARE_WORK(cookie_work, wq_cookie_handler); |
28 | static struct timer_list app_process_wake_up_timer; | 28 | static struct timer_list app_process_wake_up_timer; |
29 | static void app_process_wake_up_handler(unsigned long unused_data); | 29 | static void app_process_wake_up_handler(unsigned long unused_data); |
30 | 30 | ||
31 | static uint32_t cookiemap_code(uint64_t value64) { | 31 | static 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 | ||
41 | static uint32_t gator_chksum_crc32(char *data) | 42 | static 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 | */ |
60 | static uint32_t cookiemap_exists(uint64_t key) { | 61 | static 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 | */ |
92 | static void cookiemap_add(uint64_t key, uint32_t value) { | 94 | static 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 | ||
107 | static void translate_buffer_write_ptr(int cpu, void * x) | 110 | static 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 | ||
113 | static void * translate_buffer_read_ptr(int cpu) | 116 | static 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) | |||
120 | static void wq_cookie_handler(struct work_struct *unused) | 123 | static 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 |
148 | static int translate_app_process(char** text, int cpu, struct task_struct * task, struct vm_area_struct *vma, bool in_interrupt) | 151 | static 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 | ||
225 | static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt) | 228 | static 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 | ||
277 | static int get_exec_cookie(int cpu, struct task_struct *task) | 261 | static 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 | ||
291 | static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset) | 278 | static 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 | ||
96 | static int gator_events_armv6_online(int** buffer) | 96 | static 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 | ||
144 | static int gator_events_armv6_offline(int** buffer) | 144 | static 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 | ||
162 | static int gator_events_armv7_online(int** buffer) | 162 | static 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 | ||
217 | static int gator_events_armv7_offline(int** buffer) | 217 | static 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 | |||
159 | gator_events_init(gator_events_block_init); | 160 | gator_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; | |||
21 | static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt); | 21 | static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt); |
22 | static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); | 22 | static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); |
23 | 23 | ||
24 | GATOR_DEFINE_PROBE(irq_handler_exit, TP_PROTO(int irq, | 24 | GATOR_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 | ||
74 | static int gator_events_irq_online(int** buffer) | 74 | static 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 | ||
137 | static int gator_events_irq_read(int **buffer) | 137 | static 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 | |||
188 | gator_events_init(gator_events_irq_init); | 189 | gator_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 | ||
27 | static void __iomem *l2c310_base; | 27 | static void __iomem *l2c310_base; |
28 | 28 | ||
29 | |||
30 | |||
31 | static void gator_events_l2c310_reset_counters(void) | 29 | static 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 | |||
41 | static int gator_events_l2c310_create_files(struct super_block *sb, | 38 | static 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 | |||
179 | gator_events_init(gator_events_l2c310_init); | 177 | gator_events_init(gator_events_l2c310_init); |
diff --git a/driver/gator_events_mali_400.c b/driver/gator_events_mali_400.c index a44cd8e..4888b54 100644 --- a/driver/gator_events_mali_400.c +++ b/driver/gator_events_mali_400.c | |||
@@ -60,81 +60,81 @@ | |||
60 | #define NUM_FP_UNITS (4) | 60 | #define NUM_FP_UNITS (4) |
61 | 61 | ||
62 | enum counters { | 62 | enum counters { |
63 | /* Timeline activity */ | 63 | /* Timeline activity */ |
64 | ACTIVITY_VP = 0, | 64 | ACTIVITY_VP = 0, |
65 | ACTIVITY_FP0, | 65 | ACTIVITY_FP0, |
66 | ACTIVITY_FP1, | 66 | ACTIVITY_FP1, |
67 | ACTIVITY_FP2, | 67 | ACTIVITY_FP2, |
68 | ACTIVITY_FP3, | 68 | ACTIVITY_FP3, |
69 | 69 | ||
70 | /* L2 cache counters */ | 70 | /* L2 cache counters */ |
71 | COUNTER_L2_C0, | 71 | COUNTER_L2_C0, |
72 | COUNTER_L2_C1, | 72 | COUNTER_L2_C1, |
73 | 73 | ||
74 | /* Vertex processor counters */ | 74 | /* Vertex processor counters */ |
75 | COUNTER_VP_C0, | 75 | COUNTER_VP_C0, |
76 | COUNTER_VP_C1, | 76 | COUNTER_VP_C1, |
77 | 77 | ||
78 | /* Fragment processor counters */ | 78 | /* Fragment processor counters */ |
79 | COUNTER_FP0_C0, | 79 | COUNTER_FP0_C0, |
80 | COUNTER_FP0_C1, | 80 | COUNTER_FP0_C1, |
81 | COUNTER_FP1_C0, | 81 | COUNTER_FP1_C0, |
82 | COUNTER_FP1_C1, | 82 | COUNTER_FP1_C1, |
83 | COUNTER_FP2_C0, | 83 | COUNTER_FP2_C0, |
84 | COUNTER_FP2_C1, | 84 | COUNTER_FP2_C1, |
85 | COUNTER_FP3_C0, | 85 | COUNTER_FP3_C0, |
86 | COUNTER_FP3_C1, | 86 | COUNTER_FP3_C1, |
87 | 87 | ||
88 | /* EGL Software Counters */ | 88 | /* EGL Software Counters */ |
89 | COUNTER_EGL_BLIT_TIME, | 89 | COUNTER_EGL_BLIT_TIME, |
90 | 90 | ||
91 | /* GLES Software Counters */ | 91 | /* GLES Software Counters */ |
92 | COUNTER_GLES_DRAW_ELEMENTS_CALLS, | 92 | COUNTER_GLES_DRAW_ELEMENTS_CALLS, |
93 | COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, | 93 | COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, |
94 | COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, | 94 | COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, |
95 | COUNTER_GLES_DRAW_ARRAYS_CALLS, | 95 | COUNTER_GLES_DRAW_ARRAYS_CALLS, |
96 | COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, | 96 | COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, |
97 | COUNTER_GLES_DRAW_POINTS, | 97 | COUNTER_GLES_DRAW_POINTS, |
98 | COUNTER_GLES_DRAW_LINES, | 98 | COUNTER_GLES_DRAW_LINES, |
99 | COUNTER_GLES_DRAW_LINE_LOOP, | 99 | COUNTER_GLES_DRAW_LINE_LOOP, |
100 | COUNTER_GLES_DRAW_LINE_STRIP, | 100 | COUNTER_GLES_DRAW_LINE_STRIP, |
101 | COUNTER_GLES_DRAW_TRIANGLES, | 101 | COUNTER_GLES_DRAW_TRIANGLES, |
102 | COUNTER_GLES_DRAW_TRIANGLE_STRIP, | 102 | COUNTER_GLES_DRAW_TRIANGLE_STRIP, |
103 | COUNTER_GLES_DRAW_TRIANGLE_FAN, | 103 | COUNTER_GLES_DRAW_TRIANGLE_FAN, |
104 | COUNTER_GLES_NON_VBO_DATA_COPY_TIME, | 104 | COUNTER_GLES_NON_VBO_DATA_COPY_TIME, |
105 | COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, | 105 | COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, |
106 | COUNTER_GLES_UPLOAD_TEXTURE_TIME, | 106 | COUNTER_GLES_UPLOAD_TEXTURE_TIME, |
107 | COUNTER_GLES_UPLOAD_VBO_TIME, | 107 | COUNTER_GLES_UPLOAD_VBO_TIME, |
108 | COUNTER_GLES_NUM_FLUSHES, | 108 | COUNTER_GLES_NUM_FLUSHES, |
109 | COUNTER_GLES_NUM_VSHADERS_GENERATED, | 109 | COUNTER_GLES_NUM_VSHADERS_GENERATED, |
110 | COUNTER_GLES_NUM_FSHADERS_GENERATED, | 110 | COUNTER_GLES_NUM_FSHADERS_GENERATED, |
111 | COUNTER_GLES_VSHADER_GEN_TIME, | 111 | COUNTER_GLES_VSHADER_GEN_TIME, |
112 | COUNTER_GLES_FSHADER_GEN_TIME, | 112 | COUNTER_GLES_FSHADER_GEN_TIME, |
113 | COUNTER_GLES_INPUT_TRIANGLES, | 113 | COUNTER_GLES_INPUT_TRIANGLES, |
114 | COUNTER_GLES_VXCACHE_HIT, | 114 | COUNTER_GLES_VXCACHE_HIT, |
115 | COUNTER_GLES_VXCACHE_MISS, | 115 | COUNTER_GLES_VXCACHE_MISS, |
116 | COUNTER_GLES_VXCACHE_COLLISION, | 116 | COUNTER_GLES_VXCACHE_COLLISION, |
117 | COUNTER_GLES_CULLED_TRIANGLES, | 117 | COUNTER_GLES_CULLED_TRIANGLES, |
118 | COUNTER_GLES_CULLED_LINES, | 118 | COUNTER_GLES_CULLED_LINES, |
119 | COUNTER_GLES_BACKFACE_TRIANGLES, | 119 | COUNTER_GLES_BACKFACE_TRIANGLES, |
120 | COUNTER_GLES_GBCLIP_TRIANGLES, | 120 | COUNTER_GLES_GBCLIP_TRIANGLES, |
121 | COUNTER_GLES_GBCLIP_LINES, | 121 | COUNTER_GLES_GBCLIP_LINES, |
122 | COUNTER_GLES_TRIANGLES_DRAWN, | 122 | COUNTER_GLES_TRIANGLES_DRAWN, |
123 | COUNTER_GLES_DRAWCALL_TIME, | 123 | COUNTER_GLES_DRAWCALL_TIME, |
124 | COUNTER_GLES_TRIANGLES_COUNT, | 124 | COUNTER_GLES_TRIANGLES_COUNT, |
125 | COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, | 125 | COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, |
126 | COUNTER_GLES_STRIP_TRIANGLES_COUNT, | 126 | COUNTER_GLES_STRIP_TRIANGLES_COUNT, |
127 | COUNTER_GLES_FAN_TRIANGLES_COUNT, | 127 | COUNTER_GLES_FAN_TRIANGLES_COUNT, |
128 | COUNTER_GLES_LINES_COUNT, | 128 | COUNTER_GLES_LINES_COUNT, |
129 | COUNTER_GLES_INDEPENDENT_LINES_COUNT, | 129 | COUNTER_GLES_INDEPENDENT_LINES_COUNT, |
130 | COUNTER_GLES_STRIP_LINES_COUNT, | 130 | COUNTER_GLES_STRIP_LINES_COUNT, |
131 | COUNTER_GLES_LOOP_LINES_COUNT, | 131 | COUNTER_GLES_LOOP_LINES_COUNT, |
132 | 132 | ||
133 | COUNTER_FILMSTRIP, | 133 | COUNTER_FILMSTRIP, |
134 | COUNTER_FREQUENCY, | 134 | COUNTER_FREQUENCY, |
135 | COUNTER_VOLTAGE, | 135 | COUNTER_VOLTAGE, |
136 | 136 | ||
137 | NUMBER_OF_EVENTS | 137 | NUMBER_OF_EVENTS |
138 | }; | 138 | }; |
139 | 139 | ||
140 | #define FIRST_ACTIVITY_EVENT ACTIVITY_VP | 140 | #define FIRST_ACTIVITY_EVENT ACTIVITY_VP |
@@ -161,7 +161,7 @@ static unsigned long counter_key[NUMBER_OF_EVENTS]; | |||
161 | /* The data we have recorded */ | 161 | /* The data we have recorded */ |
162 | static u32 counter_data[NUMBER_OF_EVENTS]; | 162 | static u32 counter_data[NUMBER_OF_EVENTS]; |
163 | /* The address to sample (or 0 if samples are sent to us) */ | 163 | /* The address to sample (or 0 if samples are sent to us) */ |
164 | static u32* counter_address[NUMBER_OF_EVENTS]; | 164 | static u32 *counter_address[NUMBER_OF_EVENTS]; |
165 | 165 | ||
166 | /* An array used to return the data we recorded | 166 | /* An array used to return the data we recorded |
167 | * as key,value pairs hence the *2 | 167 | * as key,value pairs hence the *2 |
@@ -177,13 +177,12 @@ static int trace_registered; | |||
177 | */ | 177 | */ |
178 | static u32 get_difference(u32 start, u32 end) | 178 | static u32 get_difference(u32 start, u32 end) |
179 | { | 179 | { |
180 | if (start - end >= 0) | 180 | if (start - end >= 0) { |
181 | { | 181 | return start - end; |
182 | return start - end; | 182 | } |
183 | } | ||
184 | 183 | ||
185 | // Mali counters are unsigned 32 bit values that wrap. | 184 | // Mali counters are unsigned 32 bit values that wrap. |
186 | return (4294967295u - end) + start; | 185 | return (4294967295u - end) + start; |
187 | } | 186 | } |
188 | 187 | ||
189 | /** | 188 | /** |
@@ -191,8 +190,8 @@ static u32 get_difference(u32 start, u32 end) | |||
191 | */ | 190 | */ |
192 | static inline int is_activity_counter(unsigned int event_id) | 191 | static inline int is_activity_counter(unsigned int event_id) |
193 | { | 192 | { |
194 | return (event_id >= FIRST_ACTIVITY_EVENT && | 193 | return (event_id >= FIRST_ACTIVITY_EVENT && |
195 | event_id <= LAST_ACTIVITY_EVENT); | 194 | event_id <= LAST_ACTIVITY_EVENT); |
196 | } | 195 | } |
197 | 196 | ||
198 | /** | 197 | /** |
@@ -200,7 +199,7 @@ static inline int is_activity_counter(unsigned int event_id) | |||
200 | */ | 199 | */ |
201 | static inline int is_hw_counter(unsigned int event_id) | 200 | static inline int is_hw_counter(unsigned int event_id) |
202 | { | 201 | { |
203 | return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER); | 202 | return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER); |
204 | } | 203 | } |
205 | 204 | ||
206 | #if GATOR_MALI_INTERFACE_STYLE == 2 | 205 | #if GATOR_MALI_INTERFACE_STYLE == 2 |
@@ -209,7 +208,7 @@ static inline int is_hw_counter(unsigned int event_id) | |||
209 | */ | 208 | */ |
210 | static inline int is_sw_counter(unsigned int event_id) | 209 | static inline int is_sw_counter(unsigned int event_id) |
211 | { | 210 | { |
212 | return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER); | 211 | return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER); |
213 | } | 212 | } |
214 | #endif | 213 | #endif |
215 | 214 | ||
@@ -217,209 +216,204 @@ static inline int is_sw_counter(unsigned int event_id) | |||
217 | /* | 216 | /* |
218 | * The Mali DDK uses s64 types to contain software counter values, but gator | 217 | * 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 | 218 | * can only use a maximum of 32 bits. This function scales a software counter |
220 | * to an appopriate range. | 219 | * to an appropriate range. |
221 | */ | 220 | */ |
222 | static u32 scale_sw_counter_value(unsigned int event_id, signed long long value) | 221 | static u32 scale_sw_counter_value(unsigned int event_id, signed long long value) |
223 | { | 222 | { |
224 | u32 scaled_value; | 223 | u32 scaled_value; |
225 | 224 | ||
226 | switch (event_id) { | 225 | switch (event_id) { |
227 | case COUNTER_GLES_UPLOAD_TEXTURE_TIME: | 226 | case COUNTER_GLES_UPLOAD_TEXTURE_TIME: |
228 | case COUNTER_GLES_UPLOAD_VBO_TIME: | 227 | case COUNTER_GLES_UPLOAD_VBO_TIME: |
229 | scaled_value = (u32)div_s64(value, 1000000); | 228 | scaled_value = (u32)div_s64(value, 1000000); |
230 | break; | 229 | break; |
231 | default: | 230 | default: |
232 | scaled_value = (u32)value; | 231 | scaled_value = (u32)value; |
233 | break; | 232 | break; |
234 | } | 233 | } |
235 | 234 | ||
236 | return scaled_value; | 235 | return scaled_value; |
237 | } | 236 | } |
238 | #endif | 237 | #endif |
239 | 238 | ||
240 | /* Probe for continuously sampled counter */ | 239 | /* Probe for continuously sampled counter */ |
241 | #if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING | 240 | #if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING |
242 | GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32* addr)) | 241 | GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32 *addr)) |
243 | { | 242 | { |
244 | /* Turning on too many pr_debug statements in frequently called functions | 243 | /* Turning on too many pr_debug statements in frequently called functions |
245 | * can cause stability and/or performance problems | 244 | * can cause stability and/or performance problems |
246 | */ | 245 | */ |
247 | //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr); | 246 | //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr); |
248 | if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) { | 247 | if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) { |
249 | counter_address[event_id] = addr; | 248 | counter_address[event_id] = addr; |
250 | } | 249 | } |
251 | } | 250 | } |
252 | #endif | 251 | #endif |
253 | 252 | ||
254 | /* Probe for hardware counter events */ | 253 | /* Probe for hardware counter events */ |
255 | GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value)) | 254 | GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value)) |
256 | { | 255 | { |
257 | /* Turning on too many pr_debug statements in frequently called functions | 256 | /* Turning on too many pr_debug statements in frequently called functions |
258 | * can cause stability and/or performance problems | 257 | * can cause stability and/or performance problems |
259 | */ | 258 | */ |
260 | //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value); | 259 | //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value); |
261 | if (is_hw_counter(event_id)) { | 260 | if (is_hw_counter(event_id)) { |
262 | counter_data[event_id] = value; | 261 | counter_data[event_id] = value; |
263 | } | 262 | } |
264 | } | 263 | } |
265 | 264 | ||
266 | #if GATOR_MALI_INTERFACE_STYLE == 2 | 265 | #if GATOR_MALI_INTERFACE_STYLE == 2 |
267 | GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value)) | 266 | GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value)) |
268 | { | 267 | { |
269 | if (is_sw_counter(event_id)) { | 268 | if (is_sw_counter(event_id)) { |
270 | counter_data[event_id] = scale_sw_counter_value(event_id, value); | 269 | counter_data[event_id] = scale_sw_counter_value(event_id, value); |
271 | } | 270 | } |
272 | } | 271 | } |
273 | #endif /* GATOR_MALI_INTERFACE_STYLE == 2 */ | 272 | #endif /* GATOR_MALI_INTERFACE_STYLE == 2 */ |
274 | 273 | ||
275 | |||
276 | #if GATOR_MALI_INTERFACE_STYLE == 3 | 274 | #if GATOR_MALI_INTERFACE_STYLE == 3 |
277 | GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters)) | 275 | GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters)) |
278 | { | 276 | { |
279 | u32 i; | 277 | u32 i; |
280 | 278 | ||
281 | /* Copy over the values for those counters which are enabled. */ | 279 | /* Copy over the values for those counters which are enabled. */ |
282 | for(i=FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) | 280 | for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) { |
283 | { | 281 | if (counter_enabled[i]) { |
284 | if(counter_enabled[i]) | 282 | counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]); |
285 | { | 283 | } |
286 | counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]); | 284 | } |
287 | } | ||
288 | } | ||
289 | } | 285 | } |
290 | #endif /* GATOR_MALI_INTERFACE_STYLE == 3 */ | 286 | #endif /* GATOR_MALI_INTERFACE_STYLE == 3 */ |
291 | 287 | ||
292 | static int create_files(struct super_block *sb, struct dentry *root) { | 288 | static int create_files(struct super_block *sb, struct dentry *root) |
293 | struct dentry *dir; | 289 | { |
294 | int event; | 290 | struct dentry *dir; |
295 | int n_fp = NUM_FP_UNITS; | 291 | int event; |
296 | 292 | int n_fp = NUM_FP_UNITS; | |
297 | const char* mali_name = gator_mali_get_mali_name(); | 293 | |
298 | 294 | const char *mali_name = gator_mali_get_mali_name(); | |
299 | /* | 295 | |
300 | * Create the filesystem entries for vertex processor, fragement processor | 296 | /* |
301 | * and L2 cache timeline and hardware counters. Software counters get | 297 | * Create the filesystem entries for vertex processor, fragment processor |
302 | * special handling after this block. | 298 | * and L2 cache timeline and hardware counters. Software counters get |
303 | */ | 299 | * special handling after this block. |
304 | for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) | 300 | */ |
305 | { | 301 | for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) { |
306 | char buf[40]; | 302 | char buf[40]; |
307 | 303 | ||
308 | /* | 304 | /* |
309 | * We can skip this event if it's for a non-existent fragment | 305 | * We can skip this event if it's for a non-existent fragment |
310 | * processor. | 306 | * processor. |
311 | */ | 307 | */ |
312 | if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0)) || | 308 | if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0)) |
313 | (((event - COUNTER_FP0_C0)/2 >= n_fp))) | 309 | || (((event - COUNTER_FP0_C0) / 2 >= n_fp))) { |
314 | { | 310 | continue; |
315 | continue; | 311 | } |
316 | } | 312 | |
317 | 313 | /* Otherwise, set up the filesystem entry for this event. */ | |
318 | /* Otherwise, set up the filesystem entry for this event. */ | 314 | switch (event) { |
319 | switch (event) { | 315 | case ACTIVITY_VP: |
320 | case ACTIVITY_VP: | 316 | snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name); |
321 | snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name); | 317 | break; |
322 | break; | 318 | case ACTIVITY_FP0: |
323 | case ACTIVITY_FP0: | 319 | case ACTIVITY_FP1: |
324 | case ACTIVITY_FP1: | 320 | case ACTIVITY_FP2: |
325 | case ACTIVITY_FP2: | 321 | case ACTIVITY_FP3: |
326 | case ACTIVITY_FP3: | 322 | snprintf(buf, sizeof buf, "ARM_%s_FP%d_active", |
327 | snprintf(buf, sizeof buf, "ARM_%s_FP%d_active", | 323 | mali_name, event - ACTIVITY_FP0); |
328 | mali_name, event - ACTIVITY_FP0); | 324 | break; |
329 | break; | 325 | case COUNTER_L2_C0: |
330 | case COUNTER_L2_C0: | 326 | case COUNTER_L2_C1: |
331 | case COUNTER_L2_C1: | 327 | snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d", |
332 | snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d", | 328 | mali_name, event - COUNTER_L2_C0); |
333 | mali_name, event - COUNTER_L2_C0); | 329 | break; |
334 | break; | 330 | case COUNTER_VP_C0: |
335 | case COUNTER_VP_C0: | 331 | case COUNTER_VP_C1: |
336 | case COUNTER_VP_C1: | 332 | snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d", |
337 | snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d", | 333 | mali_name, event - COUNTER_VP_C0); |
338 | mali_name, event - COUNTER_VP_C0); | 334 | break; |
339 | break; | 335 | case COUNTER_FP0_C0: |
340 | case COUNTER_FP0_C0: | 336 | case COUNTER_FP0_C1: |
341 | case COUNTER_FP0_C1: | 337 | case COUNTER_FP1_C0: |
342 | case COUNTER_FP1_C0: | 338 | case COUNTER_FP1_C1: |
343 | case COUNTER_FP1_C1: | 339 | case COUNTER_FP2_C0: |
344 | case COUNTER_FP2_C0: | 340 | case COUNTER_FP2_C1: |
345 | case COUNTER_FP2_C1: | 341 | case COUNTER_FP3_C0: |
346 | case COUNTER_FP3_C0: | 342 | case COUNTER_FP3_C1: |
347 | case COUNTER_FP3_C1: | 343 | snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d", |
348 | snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d", mali_name, | 344 | mali_name, (event - COUNTER_FP0_C0) / 2, |
349 | (event - COUNTER_FP0_C0) / 2, (event - COUNTER_FP0_C0) % 2); | 345 | (event - COUNTER_FP0_C0) % 2); |
350 | break; | 346 | break; |
351 | default: | 347 | default: |
352 | printk("gator: trying to create file for non-existent counter (%d)\n", event); | 348 | printk("gator: trying to create file for non-existent counter (%d)\n", event); |
353 | continue; | 349 | continue; |
354 | } | 350 | } |
355 | 351 | ||
356 | dir = gatorfs_mkdir(sb, root, buf); | 352 | dir = gatorfs_mkdir(sb, root, buf); |
357 | 353 | ||
358 | if (!dir) { | 354 | if (!dir) { |
359 | return -1; | 355 | return -1; |
360 | } | 356 | } |
361 | 357 | ||
362 | gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); | 358 | gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); |
363 | 359 | ||
364 | /* Only create an event node for counters that can change what they count */ | 360 | /* Only create an event node for counters that can change what they count */ |
365 | if (event >= COUNTER_L2_C0) { | 361 | if (event >= COUNTER_L2_C0) { |
366 | gatorfs_create_ulong(sb, dir, "event", &counter_event[event]); | 362 | gatorfs_create_ulong(sb, dir, "event", &counter_event[event]); |
367 | } | 363 | } |
368 | 364 | ||
369 | gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); | 365 | gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); |
370 | } | 366 | } |
371 | 367 | ||
372 | /* Now set up the software counter entries */ | 368 | /* Now set up the software counter entries */ |
373 | for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++) | 369 | for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++) { |
374 | { | 370 | char buf[40]; |
375 | char buf[40]; | 371 | |
376 | 372 | snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event); | |
377 | snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event); | 373 | |
378 | 374 | dir = gatorfs_mkdir(sb, root, buf); | |
379 | dir = gatorfs_mkdir(sb, root, buf); | 375 | |
380 | 376 | if (!dir) { | |
381 | if (!dir) { | 377 | return -1; |
382 | return -1; | 378 | } |
383 | } | 379 | |
384 | 380 | gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); | |
385 | gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); | 381 | gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); |
386 | gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); | 382 | } |
387 | } | 383 | |
388 | 384 | /* Now set up the special counter entries */ | |
389 | /* Now set up the special counter entries */ | 385 | for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++) { |
390 | for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++) | 386 | char buf[40]; |
391 | { | 387 | |
392 | char buf[40]; | 388 | switch (event) { |
393 | 389 | case COUNTER_FILMSTRIP: | |
394 | switch(event) { | 390 | snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name); |
395 | case COUNTER_FILMSTRIP: | 391 | break; |
396 | snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name); | 392 | |
397 | break; | 393 | case COUNTER_FREQUENCY: |
398 | 394 | snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name); | |
399 | case COUNTER_FREQUENCY: | 395 | break; |
400 | snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name); | 396 | |
401 | break; | 397 | case COUNTER_VOLTAGE: |
402 | 398 | snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name); | |
403 | case COUNTER_VOLTAGE: | 399 | break; |
404 | snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name); | 400 | |
405 | break; | 401 | default: |
406 | 402 | break; | |
407 | default: | 403 | } |
408 | break; | 404 | |
409 | } | 405 | dir = gatorfs_mkdir(sb, root, buf); |
410 | 406 | ||
411 | dir = gatorfs_mkdir(sb, root, buf); | 407 | if (!dir) { |
412 | 408 | return -1; | |
413 | if (!dir) { | 409 | } |
414 | return -1; | 410 | |
415 | } | 411 | gatorfs_create_ulong(sb, dir, "event", &counter_event[event]); |
416 | 412 | gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); | |
417 | gatorfs_create_ulong(sb, dir, "event", &counter_event[event]); | 413 | gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); |
418 | gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]); | 414 | } |
419 | gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]); | 415 | |
420 | } | 416 | return 0; |
421 | |||
422 | return 0; | ||
423 | } | 417 | } |
424 | 418 | ||
425 | /* | 419 | /* |
@@ -434,312 +428,311 @@ static mali_profiling_get_counters_type *mali_get_counters = NULL; | |||
434 | */ | 428 | */ |
435 | static int is_any_sw_counter_enabled(void) | 429 | static int is_any_sw_counter_enabled(void) |
436 | { | 430 | { |
437 | unsigned int i; | 431 | unsigned int i; |
438 | 432 | ||
439 | for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) | 433 | for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) { |
440 | { | 434 | if (counter_enabled[i]) { |
441 | if (counter_enabled[i]) | 435 | return 1; /* At least one counter is enabled */ |
442 | { | 436 | } |
443 | return 1; /* At least one counter is enabled */ | 437 | } |
444 | } | ||
445 | } | ||
446 | 438 | ||
447 | return 0; /* No s/w counters enabled */ | 439 | return 0; /* No s/w counters enabled */ |
448 | } | 440 | } |
449 | 441 | ||
450 | static void mali_counter_initialize(void) | 442 | static void mali_counter_initialize(void) |
451 | { | 443 | { |
452 | /* If a Mali driver is present and exporting the appropriate symbol | 444 | /* If a Mali driver is present and exporting the appropriate symbol |
453 | * then we can request the HW counters (of which there are only 2) | 445 | * then we can request the HW counters (of which there are only 2) |
454 | * be configured to count the desired events | 446 | * be configured to count the desired events |
455 | */ | 447 | */ |
456 | mali_profiling_set_event_type *mali_set_hw_event; | 448 | mali_profiling_set_event_type *mali_set_hw_event; |
457 | mali_osk_fb_control_set_type *mali_set_fb_event; | 449 | mali_osk_fb_control_set_type *mali_set_fb_event; |
458 | mali_profiling_control_type *mali_control; | 450 | mali_profiling_control_type *mali_control; |
459 | 451 | ||
460 | mali_set_hw_event = symbol_get(_mali_profiling_set_event); | 452 | mali_set_hw_event = symbol_get(_mali_profiling_set_event); |
461 | 453 | ||
462 | if (mali_set_hw_event) { | 454 | if (mali_set_hw_event) { |
463 | int i; | 455 | int i; |
464 | 456 | ||
465 | pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event); | 457 | pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event); |
466 | 458 | ||
467 | for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) { | 459 | for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) { |
468 | if (counter_enabled[i]) { | 460 | if (counter_enabled[i]) { |
469 | mali_set_hw_event(i, counter_event[i]); | 461 | mali_set_hw_event(i, counter_event[i]); |
470 | } else { | 462 | } else { |
471 | mali_set_hw_event(i, 0xFFFFFFFF); | 463 | mali_set_hw_event(i, 0xFFFFFFFF); |
472 | } | 464 | } |
473 | } | 465 | } |
474 | 466 | ||
475 | symbol_put(_mali_profiling_set_event); | 467 | symbol_put(_mali_profiling_set_event); |
476 | } else { | 468 | } else { |
477 | printk("gator: mali online _mali_profiling_set_event symbol not found\n"); | 469 | printk("gator: mali online _mali_profiling_set_event symbol not found\n"); |
478 | } | 470 | } |
479 | 471 | ||
480 | mali_set_fb_event = symbol_get(_mali_osk_fb_control_set); | 472 | mali_set_fb_event = symbol_get(_mali_osk_fb_control_set); |
481 | 473 | ||
482 | if (mali_set_fb_event) { | 474 | if (mali_set_fb_event) { |
483 | pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event); | 475 | pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event); |
484 | 476 | ||
485 | mali_set_fb_event(0,(counter_enabled[COUNTER_FILMSTRIP]?1:0)); | 477 | mali_set_fb_event(0, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0)); |
486 | 478 | ||
487 | symbol_put(_mali_osk_fb_control_set); | 479 | symbol_put(_mali_osk_fb_control_set); |
488 | } else { | 480 | } else { |
489 | printk("gator: mali online _mali_osk_fb_control_set symbol not found\n"); | 481 | printk("gator: mali online _mali_osk_fb_control_set symbol not found\n"); |
490 | } | 482 | } |
491 | 483 | ||
492 | /* Generic control interface for Mali DDK. */ | 484 | /* Generic control interface for Mali DDK. */ |
493 | mali_control = symbol_get(_mali_profiling_control); | 485 | mali_control = symbol_get(_mali_profiling_control); |
494 | if (mali_control) { | 486 | if (mali_control) { |
495 | /* The event attribute in the XML file keeps the actual frame rate. */ | 487 | /* The event attribute in the XML file keeps the actual frame rate. */ |
496 | unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff; | 488 | unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff; |
497 | unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff; | 489 | unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff; |
498 | 490 | ||
499 | pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control); | 491 | pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control); |
500 | 492 | ||
501 | mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled()?1:0)); | 493 | mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled() ? 1 : 0)); |
502 | mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP]?1:0)); | 494 | mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0)); |
503 | mali_control(FBDUMP_CONTROL_RATE, rate); | 495 | mali_control(FBDUMP_CONTROL_RATE, rate); |
504 | mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor); | 496 | mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor); |
505 | 497 | ||
506 | pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP]?1:0), rate); | 498 | pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0), rate); |
507 | 499 | ||
508 | symbol_put(_mali_profiling_control); | 500 | symbol_put(_mali_profiling_control); |
509 | } else { | 501 | } else { |
510 | printk("gator: mali online _mali_profiling_control symbol not found\n"); | 502 | printk("gator: mali online _mali_profiling_control symbol not found\n"); |
511 | } | 503 | } |
512 | 504 | ||
513 | mali_get_counters = symbol_get(_mali_profiling_get_counters); | 505 | mali_get_counters = symbol_get(_mali_profiling_get_counters); |
514 | if (mali_get_counters){ | 506 | if (mali_get_counters) { |
515 | pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters); | 507 | pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters); |
516 | counter_prev[COUNTER_L2_C0] = 0; | 508 | counter_prev[COUNTER_L2_C0] = 0; |
517 | counter_prev[COUNTER_L2_C1] = 0; | 509 | counter_prev[COUNTER_L2_C1] = 0; |
518 | } | 510 | } else { |
519 | else{ | 511 | pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined"); |
520 | pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined"); | 512 | } |
521 | } | ||
522 | } | 513 | } |
523 | 514 | ||
524 | static void mali_counter_deinitialize(void) | 515 | static void mali_counter_deinitialize(void) |
525 | { | 516 | { |
526 | mali_profiling_set_event_type *mali_set_hw_event; | 517 | mali_profiling_set_event_type *mali_set_hw_event; |
527 | mali_osk_fb_control_set_type *mali_set_fb_event; | 518 | mali_osk_fb_control_set_type *mali_set_fb_event; |
528 | mali_profiling_control_type *mali_control; | 519 | mali_profiling_control_type *mali_control; |
520 | |||
521 | mali_set_hw_event = symbol_get(_mali_profiling_set_event); | ||
529 | 522 | ||
530 | mali_set_hw_event = symbol_get(_mali_profiling_set_event); | 523 | if (mali_set_hw_event) { |
524 | int i; | ||
531 | 525 | ||
532 | if (mali_set_hw_event) { | 526 | pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event); |
533 | int i; | 527 | for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) { |
534 | 528 | mali_set_hw_event(i, 0xFFFFFFFF); | |
535 | pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event); | 529 | } |
536 | for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) { | ||
537 | mali_set_hw_event(i, 0xFFFFFFFF); | ||
538 | } | ||
539 | |||
540 | symbol_put(_mali_profiling_set_event); | ||
541 | } else { | ||
542 | printk("gator: mali offline _mali_profiling_set_event symbol not found\n"); | ||
543 | } | ||
544 | 530 | ||
545 | mali_set_fb_event = symbol_get(_mali_osk_fb_control_set); | 531 | symbol_put(_mali_profiling_set_event); |
532 | } else { | ||
533 | printk("gator: mali offline _mali_profiling_set_event symbol not found\n"); | ||
534 | } | ||
546 | 535 | ||
547 | if (mali_set_fb_event) { | 536 | mali_set_fb_event = symbol_get(_mali_osk_fb_control_set); |
548 | pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event); | ||
549 | 537 | ||
550 | mali_set_fb_event(0,0); | 538 | if (mali_set_fb_event) { |
539 | pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event); | ||
551 | 540 | ||
552 | symbol_put(_mali_osk_fb_control_set); | 541 | mali_set_fb_event(0, 0); |
553 | } else { | ||
554 | printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n"); | ||
555 | } | ||
556 | 542 | ||
557 | /* Generic control interface for Mali DDK. */ | 543 | symbol_put(_mali_osk_fb_control_set); |
558 | mali_control = symbol_get(_mali_profiling_control); | 544 | } else { |
545 | printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n"); | ||
546 | } | ||
559 | 547 | ||
560 | if (mali_control) { | 548 | /* Generic control interface for Mali DDK. */ |
561 | pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event); | 549 | mali_control = symbol_get(_mali_profiling_control); |
562 | 550 | ||
563 | /* Reset the DDK state - disable counter collection */ | 551 | if (mali_control) { |
564 | mali_control(SW_EVENTS_ENABLE, 0); | 552 | pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event); |
565 | 553 | ||
566 | mali_control(FBDUMP_CONTROL_ENABLE, 0); | 554 | /* Reset the DDK state - disable counter collection */ |
555 | mali_control(SW_EVENTS_ENABLE, 0); | ||
567 | 556 | ||
568 | symbol_put(_mali_profiling_control); | 557 | mali_control(FBDUMP_CONTROL_ENABLE, 0); |
569 | } else { | ||
570 | printk("gator: mali offline _mali_profiling_control symbol not found\n"); | ||
571 | } | ||
572 | 558 | ||
573 | if (mali_get_counters){ | 559 | symbol_put(_mali_profiling_control); |
574 | symbol_put(_mali_profiling_get_counters); | 560 | } else { |
575 | } | 561 | printk("gator: mali offline _mali_profiling_control symbol not found\n"); |
562 | } | ||
563 | |||
564 | if (mali_get_counters) { | ||
565 | symbol_put(_mali_profiling_get_counters); | ||
566 | } | ||
576 | 567 | ||
577 | } | 568 | } |
578 | 569 | ||
579 | static int start(void) { | 570 | static int start(void) |
580 | // register tracepoints | 571 | { |
581 | if (GATOR_REGISTER_TRACE(mali_hw_counter)) { | 572 | // register tracepoints |
582 | printk("gator: mali_hw_counter tracepoint failed to activate\n"); | 573 | if (GATOR_REGISTER_TRACE(mali_hw_counter)) { |
583 | return -1; | 574 | printk("gator: mali_hw_counter tracepoint failed to activate\n"); |
584 | } | 575 | return -1; |
576 | } | ||
585 | 577 | ||
586 | #if GATOR_MALI_INTERFACE_STYLE == 1 | 578 | #if GATOR_MALI_INTERFACE_STYLE == 1 |
587 | /* None. */ | 579 | /* None. */ |
588 | #elif GATOR_MALI_INTERFACE_STYLE == 2 | 580 | #elif GATOR_MALI_INTERFACE_STYLE == 2 |
589 | /* For patched Mali driver. */ | 581 | /* For patched Mali driver. */ |
590 | if (GATOR_REGISTER_TRACE(mali_sw_counter)) { | 582 | if (GATOR_REGISTER_TRACE(mali_sw_counter)) { |
591 | printk("gator: mali_sw_counter tracepoint failed to activate\n"); | 583 | printk("gator: mali_sw_counter tracepoint failed to activate\n"); |
592 | return -1; | 584 | return -1; |
593 | } | 585 | } |
594 | #elif GATOR_MALI_INTERFACE_STYLE == 3 | 586 | #elif GATOR_MALI_INTERFACE_STYLE == 3 |
595 | /* For Mali drivers with built-in support. */ | 587 | /* For Mali drivers with built-in support. */ |
596 | if (GATOR_REGISTER_TRACE(mali_sw_counters)) { | 588 | if (GATOR_REGISTER_TRACE(mali_sw_counters)) { |
597 | printk("gator: mali_sw_counters tracepoint failed to activate\n"); | 589 | printk("gator: mali_sw_counters tracepoint failed to activate\n"); |
598 | return -1; | 590 | return -1; |
599 | } | 591 | } |
600 | #else | 592 | #else |
601 | #error Unknown GATOR_MALI_INTERFACE_STYLE option. | 593 | #error Unknown GATOR_MALI_INTERFACE_STYLE option. |
602 | #endif | 594 | #endif |
603 | 595 | ||
604 | trace_registered = 1; | 596 | trace_registered = 1; |
605 | 597 | ||
606 | mali_counter_initialize(); | 598 | mali_counter_initialize(); |
607 | return 0; | 599 | return 0; |
608 | } | 600 | } |
609 | 601 | ||
610 | static void stop(void) { | 602 | static void stop(void) |
611 | unsigned int cnt; | 603 | { |
604 | unsigned int cnt; | ||
612 | 605 | ||
613 | pr_debug("gator: mali stop\n"); | 606 | pr_debug("gator: mali stop\n"); |
614 | 607 | ||
615 | if (trace_registered) { | 608 | if (trace_registered) { |
616 | GATOR_UNREGISTER_TRACE(mali_hw_counter); | 609 | GATOR_UNREGISTER_TRACE(mali_hw_counter); |
617 | 610 | ||
618 | #if GATOR_MALI_INTERFACE_STYLE == 1 | 611 | #if GATOR_MALI_INTERFACE_STYLE == 1 |
619 | /* None. */ | 612 | /* None. */ |
620 | #elif GATOR_MALI_INTERFACE_STYLE == 2 | 613 | #elif GATOR_MALI_INTERFACE_STYLE == 2 |
621 | /* For patched Mali driver. */ | 614 | /* For patched Mali driver. */ |
622 | GATOR_UNREGISTER_TRACE(mali_sw_counter); | 615 | GATOR_UNREGISTER_TRACE(mali_sw_counter); |
623 | #elif GATOR_MALI_INTERFACE_STYLE == 3 | 616 | #elif GATOR_MALI_INTERFACE_STYLE == 3 |
624 | /* For Mali drivers with built-in support. */ | 617 | /* For Mali drivers with built-in support. */ |
625 | GATOR_UNREGISTER_TRACE(mali_sw_counters); | 618 | GATOR_UNREGISTER_TRACE(mali_sw_counters); |
626 | #else | 619 | #else |
627 | #error Unknown GATOR_MALI_INTERFACE_STYLE option. | 620 | #error Unknown GATOR_MALI_INTERFACE_STYLE option. |
628 | #endif | 621 | #endif |
629 | 622 | ||
630 | pr_debug("gator: mali timeline tracepoint deactivated\n"); | 623 | pr_debug("gator: mali timeline tracepoint deactivated\n"); |
631 | 624 | ||
632 | trace_registered = 0; | 625 | trace_registered = 0; |
633 | } | 626 | } |
634 | 627 | ||
635 | for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) { | 628 | for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) { |
636 | counter_enabled[cnt] = 0; | 629 | counter_enabled[cnt] = 0; |
637 | counter_event[cnt] = 0; | 630 | counter_event[cnt] = 0; |
638 | counter_address[cnt] = NULL; | 631 | counter_address[cnt] = NULL; |
639 | } | 632 |