summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Medhurst2012-10-26 11:05:14 -0500
committerJon Medhurst2012-10-26 11:05:14 -0500
commite17241f3e69b79e9470797e0dcc2a34094b542c7 (patch)
treeab36ba48e1bc766b691b26de3983b5c725bce72a
parent1963aa53d43ccd827335b28ba2c7e25300065e6c (diff)
downloadarm-ds5-gator-e17241f3e69b79e9470797e0dcc2a34094b542c7.tar.gz
arm-ds5-gator-e17241f3e69b79e9470797e0dcc2a34094b542c7.tar.xz
arm-ds5-gator-e17241f3e69b79e9470797e0dcc2a34094b542c7.zip
gator: Version 5.12
Signed-off-by: Jon Medhurst <tixy@linaro.org>
-rw-r--r--daemon/CapturedXML.cpp26
-rw-r--r--daemon/CapturedXML.h4
-rw-r--r--daemon/Child.cpp7
-rw-r--r--daemon/Collector.cpp5
-rw-r--r--daemon/ConfigurationXML.cpp32
-rw-r--r--daemon/ConfigurationXML.h3
-rw-r--r--daemon/LocalCapture.cpp96
-rw-r--r--daemon/LocalCapture.h5
-rw-r--r--daemon/Makefile11
-rw-r--r--daemon/OlyUtility.cpp4
-rw-r--r--daemon/Sender.cpp5
-rw-r--r--daemon/Sender.h1
-rw-r--r--daemon/SessionData.cpp21
-rw-r--r--daemon/SessionData.h8
-rw-r--r--daemon/SessionXML.cpp35
-rw-r--r--daemon/SessionXML.h4
-rw-r--r--daemon/StreamlineSetup.cpp69
-rw-r--r--daemon/StreamlineSetup.h1
-rw-r--r--daemon/configuration.xml70
-rw-r--r--daemon/events-ARM11.xml8
-rw-r--r--daemon/events-ARM11MPCore.xml8
-rw-r--r--daemon/events-Cortex-A15.xml12
-rw-r--r--daemon/events-Cortex-A5.xml7
-rw-r--r--daemon/events-Cortex-A7.xml9
-rw-r--r--daemon/events-Cortex-A8.xml9
-rw-r--r--daemon/events-Cortex-A9.xml11
-rw-r--r--daemon/events-Krait-architected.xml9
-rw-r--r--daemon/events-L2C-310.xml7
-rw-r--r--daemon/events-Linux.xml6
-rw-r--r--daemon/events-Mali-400.xml53
-rw-r--r--daemon/events-Scorpion.xml9
-rw-r--r--daemon/events-ScorpionMP.xml9
-rw-r--r--daemon/main.cpp55
-rw-r--r--driver/Makefile4
-rw-r--r--driver/gator.h25
-rw-r--r--driver/gator_annotate.c39
-rw-r--r--driver/gator_annotate_kernel.c89
-rw-r--r--driver/gator_backtrace.c15
-rw-r--r--driver/gator_cookies.c52
-rw-r--r--driver/gator_ebs.c156
-rw-r--r--driver/gator_events_block.c70
-rw-r--r--driver/gator_events_mali_400.c10
-rw-r--r--driver/gator_events_mali_400.h15
-rw-r--r--driver/gator_events_mali_common.c15
-rw-r--r--driver/gator_events_mali_common.h19
-rw-r--r--driver/gator_events_mali_t6xx.c15
-rw-r--r--driver/gator_events_mali_t6xx_hw.c216
-rw-r--r--driver/gator_events_mali_t6xx_hw_test.c57
-rw-r--r--driver/gator_events_mmaped.c8
-rw-r--r--driver/gator_events_net.c4
-rw-r--r--driver/gator_events_perf_pmu.c55
-rw-r--r--driver/gator_main.c258
-rw-r--r--driver/gator_marshaling.c152
-rw-r--r--driver/gator_pack.c25
-rw-r--r--driver/gator_trace_gpu.c37
-rw-r--r--driver/gator_trace_power.c26
-rw-r--r--driver/gator_trace_sched.c17
-rw-r--r--driver/mali_t6xx.mk3
58 files changed, 1045 insertions, 956 deletions
diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp
index f02ed2a..30d984f 100644
--- a/daemon/CapturedXML.cpp
+++ b/daemon/CapturedXML.cpp
@@ -22,12 +22,12 @@ CapturedXML::CapturedXML() {
22CapturedXML::~CapturedXML() { 22CapturedXML::~CapturedXML() {
23} 23}
24 24
25mxml_node_t* CapturedXML::getTree() { 25mxml_node_t* CapturedXML::getTree(bool includeTime) {
26 bool perfCounters = false; 26 bool perfCounters = false;
27 mxml_node_t *xml; 27 mxml_node_t *xml;
28 mxml_node_t *captured; 28 mxml_node_t *captured;
29 mxml_node_t *target; 29 mxml_node_t *target;
30 mxml_node_t *counters; 30 mxml_node_t *counters;
31 mxml_node_t *counter; 31 mxml_node_t *counter;
32 int x; 32 int x;
33 33
@@ -43,11 +43,10 @@ mxml_node_t* CapturedXML::getTree() {
43 captured = mxmlNewElement(xml, "captured"); 43 captured = mxmlNewElement(xml, "captured");
44 mxmlElementSetAttr(captured, "version", "1"); 44 mxmlElementSetAttr(captured, "version", "1");
45 mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION); 45 mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION);
46 if (gSessionData->mBytes > 0) { // Send the following only after the capture is complete 46 if (includeTime) { // Send the following only after the capture is complete
47 if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010) 47 if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010)
48 mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038 48 mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038
49 } 49 }
50 mxmlElementSetAttrf(captured, "bytes", "%d", gSessionData->mBytes);
51 } 50 }
52 51
53 target = mxmlNewElement(captured, "target"); 52 target = mxmlNewElement(captured, "target");
@@ -69,18 +68,9 @@ mxml_node_t* CapturedXML::getTree() {
69 if (gSessionData->mPerfCounterPerCPU[x]) { 68 if (gSessionData->mPerfCounterPerCPU[x]) {
70 mxmlElementSetAttr(counter, "per_cpu", "yes"); 69 mxmlElementSetAttr(counter, "per_cpu", "yes");
71 } 70 }
72 if (strlen(gSessionData->mPerfCounterOperation[x]) > 0) {
73 mxmlElementSetAttr(counter, "operation", gSessionData->mPerfCounterOperation[x]);
74 }
75 if (gSessionData->mPerfCounterCount[x] > 0) { 71 if (gSessionData->mPerfCounterCount[x] > 0) {
76 mxmlElementSetAttrf(counter, "count", "%d", gSessionData->mPerfCounterCount[x]); 72 mxmlElementSetAttrf(counter, "count", "%d", gSessionData->mPerfCounterCount[x]);
77 } 73 }
78 if (gSessionData->mPerfCounterLevel[x]) {
79 mxmlElementSetAttr(counter, "level", "yes");
80 }
81 if (strlen(gSessionData->mPerfCounterAlias[x]) > 0) {
82 mxmlElementSetAttr(counter, "alias", gSessionData->mPerfCounterAlias[x]);
83 }
84 if (strlen(gSessionData->mPerfCounterDisplay[x]) > 0) { 74 if (strlen(gSessionData->mPerfCounterDisplay[x]) > 0) {
85 mxmlElementSetAttr(counter, "display", gSessionData->mPerfCounterDisplay[x]); 75 mxmlElementSetAttr(counter, "display", gSessionData->mPerfCounterDisplay[x]);
86 } 76 }
@@ -98,9 +88,9 @@ mxml_node_t* CapturedXML::getTree() {
98 return xml; 88 return xml;
99} 89}
100 90
101char* CapturedXML::getXML() { 91char* CapturedXML::getXML(bool includeTime) {
102 char* xml_string; 92 char* xml_string;
103 mxml_node_t *xml = getTree(); 93 mxml_node_t *xml = getTree(includeTime);
104 xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB); 94 xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
105 mxmlDelete(xml); 95 mxmlDelete(xml);
106 return xml_string; 96 return xml_string;
@@ -112,7 +102,7 @@ void CapturedXML::write(char* path) {
112 // Set full path 102 // Set full path
113 snprintf(file, PATH_MAX, "%s/captured.xml", path); 103 snprintf(file, PATH_MAX, "%s/captured.xml", path);
114 104
115 char* xml = getXML(); 105 char* xml = getXML(true);
116 if (util->writeToDisk(file, xml) < 0) { 106 if (util->writeToDisk(file, xml) < 0) {
117 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file); 107 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
118 handleException(); 108 handleException();
diff --git a/daemon/CapturedXML.h b/daemon/CapturedXML.h
index 984d1f2..3f6a4de 100644
--- a/daemon/CapturedXML.h
+++ b/daemon/CapturedXML.h
@@ -16,10 +16,10 @@ class CapturedXML {
16public: 16public:
17 CapturedXML(); 17 CapturedXML();
18 ~CapturedXML(); 18 ~CapturedXML();
19 char* getXML(); // the string should be freed by the caller 19 char* getXML(bool includeTime); // the string should be freed by the caller
20 void write(char* path); 20 void write(char* path);
21private: 21private:
22 mxml_node_t* getTree(); 22 mxml_node_t* getTree(bool includeTime);
23}; 23};
24 24
25#endif //__CAPTURED_XML_H__ 25#endif //__CAPTURED_XML_H__
diff --git a/daemon/Child.cpp b/daemon/Child.cpp
index 2c7c292..b97e0db 100644
--- a/daemon/Child.cpp
+++ b/daemon/Child.cpp
@@ -102,7 +102,10 @@ void* stopThread(void* pVoid) {
102 prctl(PR_SET_NAME, (unsigned long)&"gatord-stopper", 0, 0, 0); 102 prctl(PR_SET_NAME, (unsigned long)&"gatord-stopper", 0, 0, 0);
103 while (gSessionData->mSessionIsActive) { 103 while (gSessionData->mSessionIsActive) {
104 // This thread will stall until the APC_STOP or PING command is received over the socket or the socket is disconnected 104 // This thread will stall until the APC_STOP or PING command is received over the socket or the socket is disconnected
105 if (socket->receiveNBytes(&type, sizeof(type)) > 0) { 105 const int result = socket->receiveNBytes(&type, sizeof(type));
106 if (result == -1) {
107 child->endSession();
108 } else if (result > 0) {
106 if ((type != COMMAND_APC_STOP) && (type != COMMAND_PING)) { 109 if ((type != COMMAND_APC_STOP) && (type != COMMAND_PING)) {
107 logg->logMessage("INVESTIGATE: Received unknown command type %d", type); 110 logg->logMessage("INVESTIGATE: Received unknown command type %d", type);
108 } else { 111 } else {
@@ -228,7 +231,7 @@ void Child::run() {
228 } 231 }
229 gSessionData->parseSessionXML(xmlString); 232 gSessionData->parseSessionXML(xmlString);
230 localCapture = new LocalCapture(); 233 localCapture = new LocalCapture();
231 localCapture->createAPCDirectory(gSessionData->mTargetPath, gSessionData->mTitle); 234 localCapture->createAPCDirectory(gSessionData->mTargetPath);
232 localCapture->copyImages(gSessionData->mImages); 235 localCapture->copyImages(gSessionData->mImages);
233 localCapture->write(xmlString); 236 localCapture->write(xmlString);
234 sender->createDataFile(gSessionData->mAPCDir); 237 sender->createDataFile(gSessionData->mAPCDir);
diff --git a/daemon/Collector.cpp b/daemon/Collector.cpp
index d29cd16..25bb934 100644
--- a/daemon/Collector.cpp
+++ b/daemon/Collector.cpp
@@ -202,7 +202,10 @@ void Collector::stop() {
202 202
203int Collector::collect(char* buffer) { 203int Collector::collect(char* buffer) {
204 // Calls event_buffer_read in the driver 204 // Calls event_buffer_read in the driver
205 int bytesRead = read(mBufferFD, buffer, mBufferSize); 205 int bytesRead;
206
207 errno = 0;
208 bytesRead = read(mBufferFD, buffer, mBufferSize);
206 209
207 // If read() returned due to an interrupt signal, re-read to obtain the last bit of collected data 210 // If read() returned due to an interrupt signal, re-read to obtain the last bit of collected data
208 if (bytesRead == -1 && errno == EINTR) { 211 if (bytesRead == -1 && errno == EINTR) {
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp
index 145ddbd..a213cbb 100644
--- a/daemon/ConfigurationXML.cpp
+++ b/daemon/ConfigurationXML.cpp
@@ -21,20 +21,19 @@ static const char* ATTR_REVISION = "revision";
21static const char* ATTR_TITLE = "title"; 21static const char* ATTR_TITLE = "title";
22static const char* ATTR_NAME = "name"; 22static const char* ATTR_NAME = "name";
23static const char* ATTR_EVENT = "event"; 23static const char* ATTR_EVENT = "event";
24static const char* ATTR_COLOR = "color";
25static const char* ATTR_COUNT = "count"; 24static const char* ATTR_COUNT = "count";
26static const char* ATTR_OPERATION = "operation";
27static const char* ATTR_PER_CPU = "per_cpu"; 25static const char* ATTR_PER_CPU = "per_cpu";
28static const char* ATTR_DESCRIPTION = "description"; 26static const char* ATTR_DESCRIPTION = "description";
29static const char* ATTR_EBS = "event_based_sampling"; 27static const char* ATTR_EBS = "supports_event_based_sampling";
30static const char* ATTR_LEVEL = "level";
31static const char* ATTR_ALIAS = "alias";
32static const char* ATTR_DISPLAY = "display"; 28static const char* ATTR_DISPLAY = "display";
33static const char* ATTR_UNITS = "units"; 29static const char* ATTR_UNITS = "units";
34static const char* ATTR_AVERAGE_SELECTION = "average_selection"; 30static const char* ATTR_AVERAGE_SELECTION = "average_selection";
35 31
36ConfigurationXML::ConfigurationXML() { 32ConfigurationXML::ConfigurationXML() {
37#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len 33 const char * configuration_xml;
34 unsigned int configuration_xml_len;
35 getDefaultConfigurationXml(configuration_xml, configuration_xml_len);
36
38 mIndex = 0; 37 mIndex = 0;
39 char* path = (char*)malloc(PATH_MAX); 38 char* path = (char*)malloc(PATH_MAX);
40 39
@@ -61,6 +60,9 @@ ConfigurationXML::ConfigurationXML() {
61 gSessionData->mPerfCounterEnabled[i] = 0; 60 gSessionData->mPerfCounterEnabled[i] = 0;
62 } 61 }
63 62
63 // clear counter overflow
64 gSessionData->mCounterOverflow = false;
65
64 int ret = parse(mConfigurationXML); 66 int ret = parse(mConfigurationXML);
65 if (ret == 1) { 67 if (ret == 1) {
66 // remove configuration.xml on disk to use the default 68 // remove configuration.xml on disk to use the default
@@ -151,8 +153,8 @@ int ConfigurationXML::configurationsTag(mxml_node_t *node) {
151void ConfigurationXML::configurationTag(mxml_node_t *node) { 153void ConfigurationXML::configurationTag(mxml_node_t *node) {
152 // handle all other performance counters 154 // handle all other performance counters
153 if (mIndex >= MAX_PERFORMANCE_COUNTERS) { 155 if (mIndex >= MAX_PERFORMANCE_COUNTERS) {
154 logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS); 156 gSessionData->mCounterOverflow = true;
155 handleException(); 157 return;
156 } 158 }
157 159
158 // read attributes 160 // read attributes
@@ -162,12 +164,8 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
162 if (mxmlElementGetAttr(node, ATTR_DESCRIPTION)) strncpy(gSessionData->mPerfCounterDescription[mIndex], mxmlElementGetAttr(node, ATTR_DESCRIPTION), sizeof(gSessionData->mPerfCounterDescription[mIndex])); 164 if (mxmlElementGetAttr(node, ATTR_DESCRIPTION)) strncpy(gSessionData->mPerfCounterDescription[mIndex], mxmlElementGetAttr(node, ATTR_DESCRIPTION), sizeof(gSessionData->mPerfCounterDescription[mIndex]));
163 if (mxmlElementGetAttr(node, ATTR_EVENT)) gSessionData->mPerfCounterEvent[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16); 165 if (mxmlElementGetAttr(node, ATTR_EVENT)) gSessionData->mPerfCounterEvent[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_EVENT), NULL, 16);
164 if (mxmlElementGetAttr(node, ATTR_COUNT)) gSessionData->mPerfCounterCount[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10); 166 if (mxmlElementGetAttr(node, ATTR_COUNT)) gSessionData->mPerfCounterCount[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COUNT), NULL, 10);
165 if (mxmlElementGetAttr(node, ATTR_COLOR)) gSessionData->mPerfCounterColor[mIndex] = strtol(mxmlElementGetAttr(node, ATTR_COLOR), NULL, 16);
166 if (mxmlElementGetAttr(node, ATTR_PER_CPU)) gSessionData->mPerfCounterPerCPU[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_PER_CPU), false); 167 if (mxmlElementGetAttr(node, ATTR_PER_CPU)) gSessionData->mPerfCounterPerCPU[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_PER_CPU), false);
167 if (mxmlElementGetAttr(node, ATTR_EBS)) gSessionData->mPerfCounterEBSCapable[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_EBS), false); 168 if (mxmlElementGetAttr(node, ATTR_EBS)) gSessionData->mPerfCounterEBSCapable[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_EBS), false);
168 if (mxmlElementGetAttr(node, ATTR_OPERATION)) strncpy(gSessionData->mPerfCounterOperation[mIndex], mxmlElementGetAttr(node, ATTR_OPERATION), sizeof(gSessionData->mPerfCounterOperation[mIndex]));
169 if (mxmlElementGetAttr(node, ATTR_LEVEL)) gSessionData->mPerfCounterLevel[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_LEVEL), false);
170 if (mxmlElementGetAttr(node, ATTR_ALIAS)) strncpy(gSessionData->mPerfCounterAlias[mIndex], mxmlElementGetAttr(node, ATTR_ALIAS), sizeof(gSessionData->mPerfCounterAlias[mIndex]));
171 if (mxmlElementGetAttr(node, ATTR_DISPLAY)) strncpy(gSessionData->mPerfCounterDisplay[mIndex], mxmlElementGetAttr(node, ATTR_DISPLAY), sizeof(gSessionData->mPerfCounterDisplay[mIndex])); 169 if (mxmlElementGetAttr(node, ATTR_DISPLAY)) strncpy(gSessionData->mPerfCounterDisplay[mIndex], mxmlElementGetAttr(node, ATTR_DISPLAY), sizeof(gSessionData->mPerfCounterDisplay[mIndex]));
172 if (mxmlElementGetAttr(node, ATTR_UNITS)) strncpy(gSessionData->mPerfCounterUnits[mIndex], mxmlElementGetAttr(node, ATTR_UNITS), sizeof(gSessionData->mPerfCounterUnits[mIndex])); 170 if (mxmlElementGetAttr(node, ATTR_UNITS)) strncpy(gSessionData->mPerfCounterUnits[mIndex], mxmlElementGetAttr(node, ATTR_UNITS), sizeof(gSessionData->mPerfCounterUnits[mIndex]));
173 if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false); 171 if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false);
@@ -178,11 +176,17 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
178 gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0; 176 gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0;
179 gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0; 177 gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0;
180 gSessionData->mPerfCounterDescription[mIndex][sizeof(gSessionData->mPerfCounterDescription[mIndex]) - 1] = 0; 178 gSessionData->mPerfCounterDescription[mIndex][sizeof(gSessionData->mPerfCounterDescription[mIndex]) - 1] = 0;
181 gSessionData->mPerfCounterOperation[mIndex][sizeof(gSessionData->mPerfCounterOperation[mIndex]) - 1] = 0;
182 gSessionData->mPerfCounterAlias[mIndex][sizeof(gSessionData->mPerfCounterAlias[mIndex]) - 1] = 0;
183 gSessionData->mPerfCounterDisplay[mIndex][sizeof(gSessionData->mPerfCounterDisplay[mIndex]) - 1] = 0; 179 gSessionData->mPerfCounterDisplay[mIndex][sizeof(gSessionData->mPerfCounterDisplay[mIndex]) - 1] = 0;
184 gSessionData->mPerfCounterUnits[mIndex][sizeof(gSessionData->mPerfCounterUnits[mIndex]) - 1] = 0; 180 gSessionData->mPerfCounterUnits[mIndex][sizeof(gSessionData->mPerfCounterUnits[mIndex]) - 1] = 0;
185 181
186 // update counter index 182 // update counter index
187 mIndex++; 183 mIndex++;
188} 184}
185
186void 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
190 xml = (const char *)configuration_xml;
191 len = configuration_xml_len;
192}
diff --git a/daemon/ConfigurationXML.h b/daemon/ConfigurationXML.h
index b48d32f..66ad587 100644
--- a/daemon/ConfigurationXML.h
+++ b/daemon/ConfigurationXML.h
@@ -13,10 +13,13 @@
13 13
14class ConfigurationXML { 14class ConfigurationXML {
15public: 15public:
16 static void getDefaultConfigurationXml(const char * & xml, unsigned int & len);
17
16 ConfigurationXML(); 18 ConfigurationXML();
17 ~ConfigurationXML(); 19 ~ConfigurationXML();
18 const char* getConfigurationXML() {return mConfigurationXML;} 20 const char* getConfigurationXML() {return mConfigurationXML;}
19 void validate(void); 21 void validate(void);
22
20private: 23private:
21 char* mConfigurationXML; 24 char* mConfigurationXML;
22 int mIndex; 25 int mIndex;
diff --git a/daemon/LocalCapture.cpp b/daemon/LocalCapture.cpp
index 6449d03..f8cd17f 100644
--- a/daemon/LocalCapture.cpp
+++ b/daemon/LocalCapture.cpp
@@ -23,8 +23,8 @@ LocalCapture::LocalCapture() {}
23 23
24LocalCapture::~LocalCapture() {} 24LocalCapture::~LocalCapture() {}
25 25
26void LocalCapture::createAPCDirectory(char* target_path, char* name) { 26void LocalCapture::createAPCDirectory(char* target_path) {
27 gSessionData->mAPCDir = createUniqueDirectory(target_path, ".apc", name); 27 gSessionData->mAPCDir = createUniqueDirectory(target_path, ".apc");
28 if ((removeDirAndAllContents(gSessionData->mAPCDir) != 0 || mkdir(gSessionData->mAPCDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)) { 28 if ((removeDirAndAllContents(gSessionData->mAPCDir) != 0 || mkdir(gSessionData->mAPCDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)) {
29 logg->logError(__FILE__, __LINE__, "Unable to create directory %s", gSessionData->mAPCDir); 29 logg->logError(__FILE__, __LINE__, "Unable to create directory %s", gSessionData->mAPCDir);
30 handleException(); 30 handleException();
@@ -46,17 +46,14 @@ void LocalCapture::write(char* string) {
46 free(file); 46 free(file);
47} 47}
48 48
49char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending, char* title) { 49char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* ending) {
50 int i;
51 char* output; 50 char* output;
52 char* path = (char*)malloc(PATH_MAX); 51 char* path = (char*)malloc(PATH_MAX);
53 52
54 // Ensure the path is an absolute path, i.e. starts with a slash 53 // Ensure the path is an absolute path, i.e. starts with a slash
55 if (initialPath == 0 || strlen(initialPath) == 0) { 54 if (initialPath == 0 || strlen(initialPath) == 0) {
56 if (getcwd(path, PATH_MAX) == 0) { 55 logg->logError(__FILE__, __LINE__, "Missing -o command line option required for a local capture.");
57 logg->logMessage("Unable to retrive the current working directory"); 56 handleException();
58 }
59 strncat(path, "/@F_@N", PATH_MAX - strlen(path) - 1);
60 } else if (initialPath[0] != '/') { 57 } else if (initialPath[0] != '/') {
61 if (getcwd(path, PATH_MAX) == 0) { 58 if (getcwd(path, PATH_MAX) == 0) {
62 logg->logMessage("Unable to retrive the current working directory"); 59 logg->logMessage("Unable to retrive the current working directory");
@@ -68,98 +65,17 @@ char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* e
68 path[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string 65 path[PATH_MAX - 1] = 0; // strncpy does not guarantee a null-terminated string
69 } 66 }
70 67
71 // Convert to uppercase
72 replaceAll(path, "@f", "@F", PATH_MAX);
73 replaceAll(path, "@n", "@N", PATH_MAX);
74
75 // Replace @F with the session xml title
76 replaceAll(path, "@F", title, PATH_MAX);
77
78 // Add ending if it is not already there 68 // Add ending if it is not already there
79 if (strcmp(&path[strlen(path) - strlen(ending)], ending) != 0) { 69 if (strcmp(&path[strlen(path) - strlen(ending)], ending) != 0) {
80 strncat(path, ending, PATH_MAX - strlen(path) - 1); 70 strncat(path, ending, PATH_MAX - strlen(path) - 1);
81 } 71 }
82 72
83 // Replace @N with a unique integer 73 output = strdup(path);
84 if (strstr(path, "@N")) {
85 char* tempPath = (char*)malloc(PATH_MAX);
86 for (i = 1; i < 1000; i++) {
87 char number[4];
88 snprintf(number, sizeof(number), "%03d", i);
89 strcpy(tempPath, path);
90 replaceAll(tempPath, "@N", number, PATH_MAX);
91 struct stat mFileInfo;
92 if (stat(tempPath, &mFileInfo) != 0) {
93 // if the direcotry does not exist, break
94 break;
95 }
96 }
97
98 if (i == 1000) {
99 logg->logError(__FILE__, __LINE__, "Unable to create .apc directory, please delete older directories.");
100 handleException();
101 }
102
103 output = strdup(tempPath);
104 free(tempPath);
105 } else {
106 output = strdup(path);
107 }
108 74
109 free(path); 75 free(path);
110 return output; 76 return output;
111} 77}
112 78
113//Replaces all occurrences of <find> in <target> with <replace> provided enough <size> is available
114void LocalCapture::replaceAll(char* target, const char* find, const char* replace, unsigned int size) {
115 char* nextOccurrence;
116 unsigned int count = 0;
117
118 // Duplicate the original string
119 char* original = strdup(target);
120 char* ptr = original;
121
122 // Determine number of <find>s
123 ptr = strstr(ptr, find);
124 while (ptr) {
125 count++;
126 ptr += strlen(find);
127 ptr = strstr(ptr, find);
128 }
129
130 // Is there enough space available
131 if (strlen(target) + (strlen(replace) - strlen(find)) * count > size - 1) {
132 free(original);
133 return;
134 }
135
136 // Reset
137 ptr = original;
138
139 nextOccurrence = strstr(ptr, find);
140 while (nextOccurrence) {
141 // Move pointers to location of replace
142 int length = nextOccurrence - ptr;
143 target += length;
144 ptr += length;
145
146 // Replace <find> with <replace>
147 memcpy(target, replace, strlen(replace));
148
149 // Increment over <replace>/<find>
150 target += strlen(replace);
151 ptr += strlen(find);
152
153 // Copy remainder of ptr
154 strcpy(target, ptr);
155
156 // Get next occurrence
157 nextOccurrence = strstr(ptr, find);
158 }
159
160 free(original);
161}
162
163int LocalCapture::removeDirAndAllContents(char* path) { 79int LocalCapture::removeDirAndAllContents(char* path) {
164 int error = 0; 80 int error = 0;
165 struct stat mFileInfo; 81 struct stat mFileInfo;
diff --git a/daemon/LocalCapture.h b/daemon/LocalCapture.h
index ca37f6e..40f7883 100644
--- a/daemon/LocalCapture.h
+++ b/daemon/LocalCapture.h
@@ -17,10 +17,9 @@ public:
17 ~LocalCapture(); 17 ~LocalCapture();
18 void write(char* string); 18 void write(char* string);
19 void copyImages(ImageLinkList* ptr); 19 void copyImages(ImageLinkList* ptr);
20 void createAPCDirectory(char* target_path, char* name); 20 void createAPCDirectory(char* target_path);
21private: 21private:
22 char* createUniqueDirectory(const char* path, const char* ending, char* title); 22 char* createUniqueDirectory(const char* path, const char* ending);
23 void replaceAll(char* target, const char* find, const char* replace, unsigned int size);
24 int removeDirAndAllContents(char* path); 23 int removeDirAndAllContents(char* path);
25}; 24};
26 25
diff --git a/daemon/Makefile b/daemon/Makefile
index b62a223..5562db7 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -3,7 +3,11 @@
3# 3#
4 4
5# Uncomment and define CROSS_COMPILE if it is not already defined 5# Uncomment and define CROSS_COMPILE if it is not already defined
6# CROSS_COMPILE=/path/to/cross-compiler/arm-none-linux-gnueabi- 6# CROSS_COMPILE=/path/to/cross-compiler/arm-linux-gnueabihf-
7# NOTE: This toolchain uses the hardfloat abi by default. For non-hardfloat
8# targets it is necessary to add options
9# '-marm -march=armv4t -mfloat-abi=soft'.
10
7ARCH=arm 11ARCH=arm
8 12
9CPP=$(CROSS_COMPILE)g++ 13CPP=$(CROSS_COMPILE)g++
@@ -17,7 +21,10 @@ GCC=$(CROSS_COMPILE)gcc
17# -std=c++0x is the planned new c++ standard 21# -std=c++0x is the planned new c++ standard
18# -std=c++98 is the 1998 c++ standard 22# -std=c++98 is the 1998 c++ standard
19# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc 23# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc
20CFLAGS=-O3 -Wall -Werror -Wno-error=sequence-point -mthumb-interwork 24CFLAGS=-O3 -Wall -mthumb-interwork
25ifeq ($(WERROR),1)
26 CFLAGS += -Werror
27endif
21# -s strips the binary of debug info 28# -s strips the binary of debug info
22LDFLAGS=-s 29LDFLAGS=-s
23TARGET=gatord 30TARGET=gatord
diff --git a/daemon/OlyUtility.cpp b/daemon/OlyUtility.cpp
index c72b0d1..adc7aba 100644
--- a/daemon/OlyUtility.cpp
+++ b/daemon/OlyUtility.cpp
@@ -24,6 +24,10 @@ OlyUtility* util = NULL;
24bool OlyUtility::stringToBool(const char* string, bool defValue) { 24bool OlyUtility::stringToBool(const char* string, bool defValue) {
25 char value[32]; 25 char value[32];
26 26
27 if (string == NULL) {
28 return defValue;
29 }
30
27 strncpy(value, string, sizeof(value)); 31 strncpy(value, string, sizeof(value));
28 if (value[0] == 0) { 32 if (value[0] == 0) {
29 return defValue; 33 return defValue;
diff --git a/daemon/Sender.cpp b/daemon/Sender.cpp
index efff753..eba8343 100644
--- a/daemon/Sender.cpp
+++ b/daemon/Sender.cpp
@@ -38,8 +38,9 @@ Sender::Sender(OlySocket* socket) {
38 } 38 }
39 39
40 // Send magic sequence - must be done first, afterwhich error messages can be sent 40 // Send magic sequence - must be done first, afterwhich error messages can be sent
41 char magic[] = {'G', 'A', 'T', 'O', 'R', '\n'}; 41 char magic[32];
42 mDataSocket->send(magic, sizeof(magic)); 42 snprintf(magic, 32, "GATOR %i\n", PROTOCOL_VERSION);
43 mDataSocket->send(magic, strlen(magic));
43 44
44 gSessionData->mWaitingOnCommand = true; 45 gSessionData->mWaitingOnCommand = true;
45 logg->logMessage("Completed magic sequence"); 46 logg->logMessage("Completed magic sequence");
diff --git a/daemon/Sender.h b/daemon/Sender.h
index 98467e0..ceab343 100644
--- a/daemon/Sender.h
+++ b/daemon/Sender.h
@@ -14,7 +14,6 @@
14#include "OlySocket.h" 14#include "OlySocket.h"
15 15
16enum { 16enum {
17 RESPONSE_END = 0, // unused
18 RESPONSE_XML = 1, 17 RESPONSE_XML = 1,
19 RESPONSE_APC_DATA = 3, 18 RESPONSE_APC_DATA = 3,
20 RESPONSE_ACK = 4, 19 RESPONSE_ACK = 4,
diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp
index a245369..5aa3f11 100644
--- a/daemon/SessionData.cpp
+++ b/daemon/SessionData.cpp
@@ -30,10 +30,10 @@ void SessionData::initialize() {
30 mConfigurationXMLPath = NULL; 30 mConfigurationXMLPath = NULL;
31 mSessionXMLPath = NULL; 31 mSessionXMLPath = NULL;
32 mEventsXMLPath = NULL; 32 mEventsXMLPath = NULL;
33 mTargetPath = NULL;
33 mAPCDir = NULL; 34 mAPCDir = NULL;
34 mSampleRate = 0; 35 mSampleRate = 0;
35 mDuration = 0; 36 mDuration = 0;
36 mBytes = 0;
37 mBacktraceDepth = 0; 37 mBacktraceDepth = 0;
38 mTotalBufferSize = 0; 38 mTotalBufferSize = 0;
39 mCores = 1; 39 mCores = 1;
@@ -48,8 +48,6 @@ void SessionData::initializeCounters() {
48 mPerfCounterTitle[i][0] = 0; 48 mPerfCounterTitle[i][0] = 0;
49 mPerfCounterName[i][0] = 0; 49 mPerfCounterName[i][0] = 0;
50 mPerfCounterDescription[i][0] = 0; 50 mPerfCounterDescription[i][0] = 0;
51 mPerfCounterOperation[i][0] = 0;
52 mPerfCounterAlias[i][0] = 0;
53 mPerfCounterDisplay[i][0] = 0; 51 mPerfCounterDisplay[i][0] = 0;
54 mPerfCounterUnits[i][0] = 0; 52 mPerfCounterUnits[i][0] = 0;
55 mPerfCounterEnabled[i] = 0; 53 mPerfCounterEnabled[i] = 0;
@@ -59,7 +57,6 @@ void SessionData::initializeCounters() {
59 mPerfCounterCount[i] = 0; 57 mPerfCounterCount[i] = 0;
60 mPerfCounterPerCPU[i] = false; 58 mPerfCounterPerCPU[i] = false;
61 mPerfCounterEBSCapable[i] = false; 59 mPerfCounterEBSCapable[i] = false;
62 mPerfCounterLevel[i] = false;
63 mPerfCounterAverageSelection[i] = false; 60 mPerfCounterAverageSelection[i] = false;
64 } 61 }
65} 62}
@@ -68,15 +65,6 @@ void SessionData::parseSessionXML(char* xmlString) {
68 SessionXML session(xmlString); 65 SessionXML session(xmlString);
69 session.parse(); 66 session.parse();
70 67
71 // Parameter error checking
72 if (session.parameters.output_path == 0 && session.parameters.target_path == 0) {
73 logg->logError(__FILE__, __LINE__, "No capture path (target or host) was provided.");
74 handleException();
75 } else if (gSessionData->mLocalCapture && session.parameters.target_path == 0) {
76 logg->logError(__FILE__, __LINE__, "Missing target_path tag in session xml required for a local capture.");
77 handleException();
78 }
79
80 // Set session data values 68 // Set session data values
81 if (strcmp(session.parameters.sample_rate, "high") == 0) { 69 if (strcmp(session.parameters.sample_rate, "high") == 0) {
82 gSessionData->mSampleRate = 10000; 70 gSessionData->mSampleRate = 10000;
@@ -84,8 +72,11 @@ void SessionData::parseSessionXML(char* xmlString) {
84 gSessionData->mSampleRate = 1000; 72 gSessionData->mSampleRate = 1000;
85 } else if (strcmp(session.parameters.sample_rate, "low") == 0) { 73 } else if (strcmp(session.parameters.sample_rate, "low") == 0) {
86 gSessionData->mSampleRate = 100; 74 gSessionData->mSampleRate = 100;
87 } else { 75 } else if (strcmp(session.parameters.sample_rate, "none") == 0) {
88 gSessionData->mSampleRate = 0; 76 gSessionData->mSampleRate = 0;
77 } else {
78 logg->logError(__FILE__, __LINE__, "Invalid sample rate (%s) in session xml.", session.parameters.sample_rate);
79 handleException();
89 } 80 }
90 gSessionData->mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0; 81 gSessionData->mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0;
91 gSessionData->mDuration = session.parameters.duration; 82 gSessionData->mDuration = session.parameters.duration;
@@ -107,6 +98,4 @@ void SessionData::parseSessionXML(char* xmlString) {
107 } 98 }
108 99
109 gSessionData->mImages = session.parameters.images; 100 gSessionData->mImages = session.parameters.images;
110 gSessionData->mTargetPath = session.parameters.target_path;
111 gSessionData->mTitle = session.parameters.title;
112} 101}
diff --git a/daemon/SessionData.h b/daemon/SessionData.h
index 6f42c07..00a71b1 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 10 16#define PROTOCOL_VERSION 11
17#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions 17#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions
18 18
19struct ImageLinkList { 19struct ImageLinkList {
@@ -36,7 +36,6 @@ public:
36 char* mEventsXMLPath; 36 char* mEventsXMLPath;
37 char* mTargetPath; 37 char* mTargetPath;
38 char* mAPCDir; 38 char* mAPCDir;
39 char* mTitle;
40 39
41 bool mWaitingOnCommand; 40 bool mWaitingOnCommand;
42 bool mSessionIsActive; 41 bool mSessionIsActive;
@@ -48,15 +47,13 @@ public:
48 int mSampleRate; 47 int mSampleRate;
49 int mDuration; 48 int mDuration;
50 int mCores; 49 int mCores;
51 int mBytes;
52 50
53 // PMU Counters 51 // PMU Counters
52 bool mCounterOverflow;
54 char mPerfCounterType[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; 53 char mPerfCounterType[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
55 char mPerfCounterTitle[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; 54 char mPerfCounterTitle[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
56 char mPerfCounterName[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; 55 char mPerfCounterName[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
57 char mPerfCounterDescription[MAX_PERFORMANCE_COUNTERS][MAX_DESCRIPTION_LEN]; 56 char mPerfCounterDescription[MAX_PERFORMANCE_COUNTERS][MAX_DESCRIPTION_LEN];
58 char mPerfCounterOperation[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
59 char mPerfCounterAlias[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
60 char mPerfCounterDisplay[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; 57 char mPerfCounterDisplay[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
61 char mPerfCounterUnits[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN]; 58 char mPerfCounterUnits[MAX_PERFORMANCE_COUNTERS][MAX_STRING_LEN];
62 int mPerfCounterEnabled[MAX_PERFORMANCE_COUNTERS]; 59 int mPerfCounterEnabled[MAX_PERFORMANCE_COUNTERS];
@@ -66,7 +63,6 @@ public:
66 int mPerfCounterKey[MAX_PERFORMANCE_COUNTERS]; 63 int mPerfCounterKey[MAX_PERFORMANCE_COUNTERS];
67 bool mPerfCounterPerCPU[MAX_PERFORMANCE_COUNTERS]; 64 bool mPerfCounterPerCPU[MAX_PERFORMANCE_COUNTERS];
68 bool mPerfCounterEBSCapable[MAX_PERFORMANCE_COUNTERS]; 65 bool mPerfCounterEBSCapable[MAX_PERFORMANCE_COUNTERS];
69 bool mPerfCounterLevel[MAX_PERFORMANCE_COUNTERS];
70 bool mPerfCounterAverageSelection[MAX_PERFORMANCE_COUNTERS]; 66 bool mPerfCounterAverageSelection[MAX_PERFORMANCE_COUNTERS];
71}; 67};
72 68
diff --git a/daemon/SessionXML.cpp b/daemon/SessionXML.cpp
index f1a8258..4c373d8 100644
--- a/daemon/SessionXML.cpp
+++ b/daemon/SessionXML.cpp
@@ -19,21 +19,13 @@ static const char* TAG_SESSION = "session";
19static const char* TAG_IMAGE = "image"; 19static const char* TAG_IMAGE = "image";
20 20
21static const char* ATTR_VERSION = "version"; 21static const char* ATTR_VERSION = "version";
22static const char* ATTR_TITLE = "title";
23static const char* ATTR_UUID = "uuid";
24static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding"; 22static const char* ATTR_CALL_STACK_UNWINDING = "call_stack_unwinding";
25static const char* ATTR_BUFFER_MODE = "buffer_mode"; 23static const char* ATTR_BUFFER_MODE = "buffer_mode";
26static const char* ATTR_SAMPLE_RATE = "sample_rate"; 24static const char* ATTR_SAMPLE_RATE = "sample_rate";
27static const char* ATTR_TARGET_PATH = "target_path";
28static const char* ATTR_OUTPUT_PATH = "output_path";
29static const char* ATTR_DURATION = "duration"; 25static const char* ATTR_DURATION = "duration";
30static const char* ATTR_PATH = "path"; 26static const char* ATTR_PATH = "path";
31 27
32SessionXML::SessionXML(const char* str) { 28SessionXML::SessionXML(const char* str) {
33 parameters.title = 0;
34 parameters.uuid[0] = 0;
35 parameters.target_path = 0;
36 parameters.output_path = 0;
37 parameters.buffer_mode[0] = 0; 29 parameters.buffer_mode[0] = 0;
38 parameters.sample_rate[0] = 0; 30 parameters.sample_rate[0] = 0;
39 parameters.duration = 0; 31 parameters.duration = 0;
@@ -75,34 +67,7 @@ void SessionXML::sessionTag(mxml_node_t *tree, mxml_node_t *node) {
75 handleException(); 67 handleException();
76 } 68 }
77 69
78 // allocate strings
79 if (mxmlElementGetAttr(node, ATTR_TITLE)) {
80 parameters.title = strdup(mxmlElementGetAttr(node, ATTR_TITLE)); // freed when the child process exits
81 if (parameters.title == NULL) {
82 logg->logError(__FILE__, __LINE__, "failed to allocate parameters.title");
83 handleException();
84 }
85 }
86 if (mxmlElementGetAttr(node, ATTR_TARGET_PATH)) {
87 parameters.target_path = strdup(mxmlElementGetAttr(node, ATTR_TARGET_PATH)); // freed when the child process exits
88 if (parameters.target_path == NULL) {
89 logg->logError(__FILE__, __LINE__, "failed to allocate parameters.target_path");
90 handleException();
91 }
92 }
93 if (mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)) {
94 parameters.output_path = strdup(mxmlElementGetAttr(node, ATTR_OUTPUT_PATH)); // freed when the child process exits
95 if (parameters.output_path == NULL) {
96 logg->logError(__FILE__, __LINE__, "failed to allocate parameters.output_path");
97 handleException();
98 }
99 }
100
101 // copy to pre-allocated strings 70 // copy to pre-allocated strings
102 if (mxmlElementGetAttr(node, ATTR_UUID)) {
103 strncpy(parameters.uuid, mxmlElementGetAttr(node, ATTR_UUID), sizeof(parameters.uuid));
104 parameters.uuid[sizeof(parameters.uuid) - 1] = 0; // strncpy does not guarantee a null-terminated string
105 }
106 if (mxmlElementGetAttr(node, ATTR_BUFFER_MODE)) { 71 if (mxmlElementGetAttr(node, ATTR_BUFFER_MODE)) {
107 strncpy(parameters.buffer_mode, mxmlElementGetAttr(node, ATTR_BUFFER_MODE), sizeof(parameters.buffer_mode)); 72 strncpy(parameters.buffer_mode, mxmlElementGetAttr(node, ATTR_BUFFER_MODE), sizeof(parameters.buffer_mode));
108 parameters.buffer_mode[sizeof(parameters.buffer_mode) - 1] = 0; // strncpy does not guarantee a null-terminated string 73 parameters.buffer_mode[sizeof(parameters.buffer_mode) - 1] = 0; // strncpy does not guarantee a null-terminated string
diff --git a/daemon/SessionXML.h b/daemon/SessionXML.h
index c2b5489..f7a5641 100644
--- a/daemon/SessionXML.h
+++ b/daemon/SessionXML.h
@@ -13,10 +13,6 @@
13#include "SessionData.h" 13#include "SessionData.h"
14 14
15struct ConfigParameters { 15struct ConfigParameters {
16 char* title; // status title
17 char uuid[64]; // universal unique identifier
18 char* target_path; // target path of where to write to disk
19 char* output_path; // host path of where to write to disk
20 char buffer_mode[64]; // buffer mode, "streaming", "low", "normal", "high" defines oneshot and buffer size 16 char buffer_mode[64]; // buffer mode, "streaming", "low", "normal", "high" defines oneshot and buffer size
21 char sample_rate[64]; // capture mode, "high", "normal", or "low" 17 char sample_rate[64]; // capture mode, "high", "normal", or "low"
22 int duration; // length of profile in seconds 18 int duration; // length of profile in seconds
diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp
index 53729ab..3f59eab 100644
--- a/daemon/StreamlineSetup.cpp
+++ b/daemon/StreamlineSetup.cpp
@@ -28,13 +28,13 @@ static const char* TAG_SESSION = "session";
28static const char* TAG_REQUEST = "request"; 28static const char* TAG_REQUEST = "request";
29static const char* TAG_CONFIGURATIONS = "configurations"; 29static const char* TAG_CONFIGURATIONS = "configurations";
30 30
31static const char* ATTR_PROTOCOL = "protocol"; 31static const char* ATTR_TYPE = "type";
32static const char* ATTR_EVENTS = "events"; 32static const char* VALUE_EVENTS = "events";
33static const char* ATTR_CONFIGURATION = "configuration"; 33static const char* VALUE_CONFIGURATION = "configuration";
34static const char* ATTR_COUNTERS = "counters"; 34static const char* VALUE_COUNTERS = "counters";
35static const char* ATTR_SESSION = "session"; 35static const char* VALUE_SESSION = "session";
36static const char* ATTR_CAPTURED = "captured"; 36static const char* VALUE_CAPTURED = "captured";
37static const char* ATTR_DEFAULTS = "defaults"; 37static const char* VALUE_DEFAULTS = "defaults";
38 38
39StreamlineSetup::StreamlineSetup(OlySocket* s) { 39StreamlineSetup::StreamlineSetup(OlySocket* s) {
40 bool ready = false; 40 bool ready = false;
@@ -81,6 +81,11 @@ StreamlineSetup::StreamlineSetup(OlySocket* s) {
81 81
82 free(data); 82 free(data);
83 } 83 }
84
85 if (gSessionData->mCounterOverflow) {
86 logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS);
87 handleException();
88 }
84} 89}
85 90
86StreamlineSetup::~StreamlineSetup() { 91StreamlineSetup::~StreamlineSetup() {
@@ -143,30 +148,32 @@ char* StreamlineSetup::readCommand(int* command) {
143 148
144void StreamlineSetup::handleRequest(char* xml) { 149void StreamlineSetup::handleRequest(char* xml) {
145 mxml_node_t *tree, *node; 150 mxml_node_t *tree, *node;
151 const char * attr = NULL;
146 152
147 tree = mxmlLoadString(NULL, xml, MXML_NO_CALLBACK); 153 tree = mxmlLoadString(NULL, xml, MXML_NO_CALLBACK);
148 if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_PROTOCOL, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_PROTOCOL), false)) { 154 node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_TYPE, NULL, MXML_DESCEND_FIRST);
149 sendProtocol(); 155 if (node) {
150 logg->logMessage("Sent protocol xml response"); 156 attr = mxmlElementGetAttr(node, ATTR_TYPE);
151 } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_EVENTS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_EVENTS), false)) { 157 }
158 if (attr && strcmp(attr, VALUE_EVENTS) == 0) {
152 sendEvents(); 159 sendEvents();
153 logg->logMessage("Sent events xml response"); 160 logg->logMessage("Sent events xml response");
154 } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_CONFIGURATION, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_CONFIGURATION), false)) { 161 } else if (attr && strcmp(attr, VALUE_CONFIGURATION) == 0) {
155 sendConfiguration(); 162 sendConfiguration();
156 logg->logMessage("Sent configuration xml response"); 163 logg->logMessage("Sent configuration xml response");
157 } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_COUNTERS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_COUNTERS), false)) { 164 } else if (attr && strcmp(attr, VALUE_COUNTERS) == 0) {
158 sendCounters(); 165 sendCounters();
159 logg->logMessage("Sent counters xml response"); 166 logg->logMessage("Sent counters xml response");
160 } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_SESSION, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_SESSION), false)) { 167 } else if (attr && strcmp(attr, VALUE_SESSION) == 0) {
161 sendData(mSessionXML, strlen(mSessionXML), RESPONSE_XML); 168 sendData(mSessionXML, strlen(mSessionXML), RESPONSE_XML);
162 logg->logMessage("Sent session xml response"); 169 logg->logMessage("Sent session xml response");
163 } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_CAPTURED, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_CAPTURED), false)) { 170 } else if (attr && strcmp(attr, VALUE_CAPTURED) == 0) {
164 CapturedXML capturedXML; 171 CapturedXML capturedXML;
165 char* capturedText = capturedXML.getXML(); 172 char* capturedText = capturedXML.getXML(false);
166 sendData(capturedText, strlen(capturedText), RESPONSE_XML); 173 sendData(capturedText, strlen(capturedText), RESPONSE_XML);
167 free(capturedText); 174 free(capturedText);
168 logg->logMessage("Sent captured xml response"); 175 logg->logMessage("Sent captured xml response");
169 } else if ((node = mxmlFindElement(tree, tree, TAG_REQUEST, ATTR_DEFAULTS, NULL, MXML_DESCEND_FIRST)) && util->stringToBool(mxmlElementGetAttr(node, ATTR_DEFAULTS), false)) { 176 } else if (attr && strcmp(attr, VALUE_DEFAULTS) == 0) {
170 sendDefaults(); 177 sendDefaults();
171 logg->logMessage("Sent default configuration xml response"); 178 logg->logMessage("Sent default configuration xml response");
172 } else { 179 } else {
@@ -215,21 +222,6 @@ void StreamlineSetup::sendData(const char* data, int length, int type) {
215 mSocket->send((char*)data, length); 222 mSocket->send((char*)data, length);
216} 223}
217 224
218void StreamlineSetup::sendProtocol() {
219 mxml_node_t *xml;
220 mxml_node_t *protocol;
221
222 xml = mxmlNewXML("1.0");
223 protocol = mxmlNewElement(xml, "protocol");
224 mxmlElementSetAttrf(protocol, "version", "%d", PROTOCOL_VERSION);
225
226 char* string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
227 sendString(string, RESPONSE_XML);
228
229 free(string);
230 mxmlDelete(xml);
231}
232
233void StreamlineSetup::sendEvents() { 225void StreamlineSetup::sendEvents() {
234#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len 226#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len
235 char* path = (char*)malloc(PATH_MAX);; 227 char* path = (char*)malloc(PATH_MAX);;
@@ -264,10 +256,10 @@ void StreamlineSetup::sendConfiguration() {
264} 256}
265 257
266void StreamlineSetup::sendDefaults() { 258void StreamlineSetup::sendDefaults() {
267#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len
268 // Send the config built into the binary 259 // Send the config built into the binary
269 char* xml = (char*)configuration_xml; 260 const char* xml;
270 unsigned int size = configuration_xml_len; 261 unsigned int size;
262 ConfigurationXML::getDefaultConfigurationXml(xml, size);
271 263
272 // Artificial size restriction 264 // Artificial size restriction
273 if (size > 1024*1024) { 265 if (size > 1024*1024) {
@@ -282,7 +274,7 @@ void StreamlineSetup::sendDefaults() {
282void StreamlineSetup::sendCounters() { 274void StreamlineSetup::sendCounters() {
283 struct dirent *ent; 275 struct dirent *ent;
284 mxml_node_t *xml; 276 mxml_node_t *xml;
285 mxml_node_t *counters; 277 mxml_node_t *counters;
286 mxml_node_t *counter; 278 mxml_node_t *counter;
287 279
288 // counters.xml is simply a file listing of /dev/gator/events 280 // counters.xml is simply a file listing of /dev/gator/events
@@ -328,4 +320,9 @@ void StreamlineSetup::writeConfiguration(char* xml) {
328 // Re-populate gSessionData with the configuration, as it has now changed 320 // Re-populate gSessionData with the configuration, as it has now changed
329 new ConfigurationXML(); 321 new ConfigurationXML();
330 free(path); 322 free(path);
323
324 if (gSessionData->mCounterOverflow) {
325 logg->logError(__FILE__, __LINE__, "Exceeded maximum number of %d performance counters", MAX_PERFORMANCE_COUNTERS);
326 handleException();
327 }
331} 328}
diff --git a/daemon/StreamlineSetup.h b/daemon/StreamlineSetup.h
index c46ae08..8086fe2 100644
--- a/daemon/StreamlineSetup.h
+++ b/daemon/StreamlineSetup.h
@@ -35,7 +35,6 @@ private:
35 void handleDeliver(char* xml); 35 void handleDeliver(char* xml);
36 void sendData(const char* data, int length, int type); 36 void sendData(const char* data, int length, int type);
37 void sendString(const char* string, int type) {sendData(string, strlen(string), type);} 37 void sendString(const char* string, int type) {sendData(string, strlen(string), type);}
38 void sendProtocol();
39 void sendEvents(); 38 void sendEvents();
40 void sendConfiguration(); 39 void sendConfiguration();
41 void sendDefaults(); 40 void sendDefaults();
diff --git a/daemon/configuration.xml b/daemon/configuration.xml
index 4875f1f..fbdef31 100644
--- a/daemon/configuration.xml
+++ b/daemon/configuration.xml
@@ -1,49 +1,45 @@
1<?xml version="1.0" encoding='UTF-8'?> 1<?xml version="1.0" encoding='UTF-8'?>
2<configurations version="1" revision="1"> 2<configurations revision="1">
3 <configuration counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <configuration counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
4 <configuration counter="ARM_ARM11_cnt0" event="0x7" title="Instruction" name="Executed" per_cpu="yes" description="Instructions executed"/> 4 <configuration counter="ARM_ARM11_cnt0" event="0x7" title="Instruction" name="Executed" per_cpu="yes" description="Instructions executed"/>
5 <configuration counter="ARM_ARM11_cnt1" event="0xb" title="Cache" name="Data miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/> 5 <configuration counter="ARM_ARM11_cnt1" event="0xb" title="Cache" name="Data miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/>
6 <configuration counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 6 <configuration counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" per_cpu="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
7 <configuration counter="ARM_ARM11MPCore_cnt0" event="0x08" title="Core" name="Instructions" per_cpu="yes" description="Instructions executed"/> 7 <configuration counter="ARM_ARM11MPCore_cnt0" event="0x08" title="Core" name="Instructions" per_cpu="yes" description="Instructions executed"/>
8 <configuration counter="ARM_ARM11MPCore_cnt1" event="0x0b" title="Cache" name="Data read miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/> 8 <configuration counter="ARM_ARM11MPCore_cnt1" event="0x0b" title="Cache" name="Data read miss" per_cpu="yes" description="Data cache miss, not including Cache Operations"/>
9 <configuration counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 9 <configuration counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
10 <configuration counter="ARM_Cortex-A5_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> 10 <configuration counter="ARM_Cortex-A5_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
11 <configuration counter="ARM_Cortex-A5_cnt1" event="0x1" title="Cache" name="Instruction refill" per_cpu="yes" event_based_sampling="yes" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 11 <configuration counter="ARM_Cortex-A5_cnt1" event="0x1" title="Cache" name="Instruction refill" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
12 <configuration counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 12 <configuration counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
13 <configuration counter="ARM_Cortex-A7_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> 13 <configuration counter="ARM_Cortex-A7_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
14 <configuration counter="ARM_Cortex-A7_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> 14 <configuration counter="ARM_Cortex-A7_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
15 <configuration counter="ARM_Cortex-A7_cnt2" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" event_based_sampling="yes" description="Level 2 data cache access"/> 15 <configuration counter="ARM_Cortex-A7_cnt2" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" supports_event_based_sampling="yes" description="Level 2 data cache access"/>
16 <configuration counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 16 <configuration counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
17 <configuration counter="ARM_Cortex-A8_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> 17 <configuration counter="ARM_Cortex-A8_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
18 <configuration counter="ARM_Cortex-A8_cnt1" event="0x44" title="Cache" name="L2 miss" per_cpu="yes" event_based_sampling="yes" description="Any cacheable miss in the L2 cache"/> 18 <configuration counter="ARM_Cortex-A8_cnt1" event="0x44" title="Cache" name="L2 miss" per_cpu="yes" supports_event_based_sampling="yes" description="Any cacheable miss in the L2 cache"/>
19 <configuration counter="ARM_Cortex-A8_cnt2" event="0x43" title="Cache" name="L1 miss" per_cpu="yes" event_based_sampling="yes" description="Any accesses to the L2 cache"/> 19 <configuration counter="ARM_Cortex-A8_cnt2" event="0x43" title="Cache" name="L1 miss" per_cpu="yes" supports_event_based_sampling="yes" description="Any accesses to the L2 cache"/>
20 <configuration counter="ARM_Cortex-A8_cnt3" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> 20 <configuration counter="ARM_Cortex-A8_cnt3" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
21 <configuration counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 21 <configuration counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
22 <configuration counter="ARM_Cortex-A9_cnt0" event="0x68" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" 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"/> 22 <configuration counter="ARM_Cortex-A9_cnt0" event="0x68" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" 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"/>
23 <configuration counter="ARM_Cortex-A9_cnt1" event="0x06" title="Instruction" name="Memory read" per_cpu="yes" event_based_sampling="yes" description="Memory-reading instruction architecturally executed"/> 23 <configuration counter="ARM_Cortex-A9_cnt1" event="0x06" title="Instruction" name="Memory read" per_cpu="yes" supports_event_based_sampling="yes" description="Memory-reading instruction architecturally executed"/>
24 <configuration counter="ARM_Cortex-A9_cnt2" event="0x07" title="Instruction" name="Memory write" per_cpu="yes" event_based_sampling="yes" description="Memory-writing instruction architecturally executed"/> 24 <configuration counter="ARM_Cortex-A9_cnt2" event="0x07" title="Instruction" name="Memory write" per_cpu="yes" supports_event_based_sampling="yes" description="Memory-writing instruction architecturally executed"/>
25 <configuration counter="ARM_Cortex-A9_cnt3" event="0x03" title="Cache" name="Data refill" per_cpu="yes" event_based_sampling="yes" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/> 25 <configuration counter="ARM_Cortex-A9_cnt3" event="0x03" title="Cache" name="Data refill" per_cpu="yes" supports_event_based_sampling="yes" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
26 <configuration counter="ARM_Cortex-A9_cnt4" event="0x04" title="Cache" name="Data access" per_cpu="yes" event_based_sampling="yes" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/> 26 <configuration counter="ARM_Cortex-A9_cnt4" event="0x04" title="Cache" name="Data access" per_cpu="yes" supports_event_based_sampling="yes" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
27 <configuration counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 27 <configuration counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
28 <configuration counter="ARM_Cortex-A15_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> 28 <configuration counter="ARM_Cortex-A15_cnt0" event="0x8" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
29 <configuration counter="ARM_Cortex-A15_cnt1" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" event_based_sampling="yes" description="Level 2 data cache access"/> 29 <configuration counter="ARM_Cortex-A15_cnt1" event="0x16" title="Cache" name="L2 data access" per_cpu="yes" supports_event_based_sampling="yes" description="Level 2 data cache access"/>
30 <configuration counter="ARM_Cortex-A15_cnt2" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> 30 <configuration counter="ARM_Cortex-A15_cnt2" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
31 <configuration counter="ARM_Cortex-A15_cnt3" event="0x19" title="Bus" name="Access" per_cpu="yes" event_based_sampling="yes" description=""/> 31 <configuration counter="ARM_Cortex-A15_cnt3" event="0x19" title="Bus" name="Access" per_cpu="yes" supports_event_based_sampling="yes" description=""/>
32 <configuration counter="Scorpion_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 32 <configuration counter="Scorpion_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
33 <configuration counter="Scorpion_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> 33 <configuration counter="Scorpion_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
34 <configuration counter="Scorpion_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> 34 <configuration counter="Scorpion_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
35 <configuration counter="ScorpionMP_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 35 <configuration counter="ScorpionMP_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
36 <configuration counter="ScorpionMP_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> 36 <configuration counter="ScorpionMP_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
37 <configuration counter="ScorpionMP_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> 37 <configuration counter="ScorpionMP_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
38 <configuration counter="Krait_ccnt" title="Clock" name="Cycles" per_cpu="yes" event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 38 <configuration counter="Krait_ccnt" title="Clock" name="Cycles" per_cpu="yes" supports_event_based_sampling="yes" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
39 <configuration counter="Krait_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" event_based_sampling="yes" description="Instruction architecturally executed"/> 39 <configuration counter="Krait_cnt0" event="0x08" title="Instruction" name="Executed" per_cpu="yes" supports_event_based_sampling="yes" description="Instruction architecturally executed"/>
40 <configuration counter="Krait_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" event_based_sampling="yes" description="Branch mispredicted or not predicted"/> 40 <configuration counter="Krait_cnt1" event="0x10" title="Branch" name="Mispredicted" per_cpu="yes" supports_event_based_sampling="yes" description="Branch mispredicted or not predicted"/>
41 <configuration counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/> 41 <configuration counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/>
42 <configuration counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/> 42 <configuration counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/>
43 <configuration counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/>
44 <configuration counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/>
45 <configuration counter="Linux_cpuload_system" title="CPU Load" name="System" description="Scheduler CPU Load of System Behavior"/>
46 <configuration counter="Linux_cpuload_user" title="CPU Load" name="User" description="Scheduler CPU Load of User Application"/>
47 <configuration counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/> 43 <configuration counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/>
48 <configuration counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/> 44 <configuration counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/>
49 <configuration 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"/> 45 <configuration 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"/>
diff --git a/daemon/events-ARM11.xml b/daemon/events-ARM11.xml
index d4a2914..0a5ee66 100644
--- a/daemon/events-ARM11.xml
+++ b/daemon/events-ARM11.xml
@@ -1,9 +1,5 @@
1 <counter_set name="ARM_ARM11_cntX"> 1 <counter_set name="ARM_ARM11_cnt" count="3"/>
2 <counter name="ARM_ARM11_cnt0"/> 2 <category name="ARM11" counter_set="ARM_ARM11_cnt" per_cpu="yes">
3 <counter name="ARM_ARM11_cnt1"/>
4 <counter name="ARM_ARM11_cnt2"/>
5 </counter_set>
6 <category name="ARM11" counter_set="ARM_ARM11_cntX" per_cpu="yes">
7 <event counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_ARM11_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
8 <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/> 4 <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/>
9 <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/> 5 <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/>
diff --git a/daemon/events-ARM11MPCore.xml b/daemon/events-ARM11MPCore.xml
index 7de51b0..1a9ca3f 100644
--- a/daemon/events-ARM11MPCore.xml
+++ b/daemon/events-ARM11MPCore.xml
@@ -1,9 +1,5 @@
1 <counter_set name="ARM_ARM11MPCore_cntX"> 1 <counter_set name="ARM_ARM11MPCore_cnt" count="3"/>
2 <counter name="ARM_ARM11MPCore_cnt0"/> 2 <category name="ARM11MPCore" counter_set="ARM_ARM11MPCore_cnt" per_cpu="yes">
3 <counter name="ARM_ARM11MPCore_cnt1"/>
4 <counter name="ARM_ARM11MPCore_cnt2"/>
5 </counter_set>
6 <category name="ARM11MPCore" counter_set="ARM_ARM11MPCore_cntX" per_cpu="yes">
7 <event counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_ARM11MPCore_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
8 <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/> 4 <event event="0x00" title="Cache" name="Inst miss" description="Instruction cache miss to a cacheable location, which requires a fetch from external memory"/>
9 <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/> 5 <event event="0x01" title="Pipeline" name="Instruction stall" description="Stall because instruction buffer cannot deliver an instruction"/>
diff --git a/daemon/events-Cortex-A15.xml b/daemon/events-Cortex-A15.xml
index d6222eb..0ec196f 100644
--- a/daemon/events-Cortex-A15.xml
+++ b/daemon/events-Cortex-A15.xml
@@ -1,12 +1,5 @@
1 <counter_set name="ARM_Cortex-A15_cntX"> 1 <counter_set name="ARM_Cortex-A15_cnt" count="6"/>
2 <counter name="ARM_Cortex-A15_cnt0"/> 2 <category name="Cortex-A15" counter_set="ARM_Cortex-A15_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="ARM_Cortex-A15_cnt1"/>
4 <counter name="ARM_Cortex-A15_cnt2"/>
5 <counter name="ARM_Cortex-A15_cnt3"/>
6 <counter name="ARM_Cortex-A15_cnt4"/>
7 <counter name="ARM_Cortex-A15_cnt5"/>
8 </counter_set>
9 <category name="Cortex-A15" counter_set="ARM_Cortex-A15_cntX" per_cpu="yes" event_based_sampling="yes">
10 <event counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_Cortex-A15_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
11 <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/> 4 <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/>
12 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
@@ -19,7 +12,6 @@
19 <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/> 12 <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
20 <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/> 13 <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
21 <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/> 14 <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
22 <event event="0x11" title="Cycle" name="Cycle" description=""/>
23 <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/> 15 <event event="0x12" title="Branch" name="Potential prediction" description="Branch or other change in program flow that could have been predicted by the branch prediction resources of the processor"/>
24 <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/> 16 <event event="0x13" title="Memory" name="Memory access" description="Data memory access"/>
25 <event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/> 17 <event event="0x14" title="Cache" name="L1 inst access" description="Instruction cache access"/>
diff --git a/daemon/events-Cortex-A5.xml b/daemon/events-Cortex-A5.xml
index e01492b..4a894d3 100644
--- a/daemon/events-Cortex-A5.xml
+++ b/daemon/events-Cortex-A5.xml
@@ -1,8 +1,5 @@
1 <counter_set name="ARM_Cortex-A5_cntX"> 1 <counter_set name="ARM_Cortex-A5_cnt" count="2"/>
2 <counter name="ARM_Cortex-A5_cnt0"/> 2 <category name="Cortex-A5" counter_set="ARM_Cortex-A5_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="ARM_Cortex-A5_cnt1"/>
4 </counter_set>
5 <category name="Cortex-A5" counter_set="ARM_Cortex-A5_cntX" per_cpu="yes" event_based_sampling="yes">
6 <event counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_Cortex-A5_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
7 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
8 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Cortex-A7.xml b/daemon/events-Cortex-A7.xml
index 9ee4580..2bd4797 100644
--- a/daemon/events-Cortex-A7.xml
+++ b/daemon/events-Cortex-A7.xml
@@ -1,10 +1,5 @@
1 <counter_set name="ARM_Cortex-A7_cntX"> 1 <counter_set name="ARM_Cortex-A7_cnt" count="4"/>
2 <counter name="ARM_Cortex-A7_cnt0"/> 2 <category name="Cortex-A7" counter_set="ARM_Cortex-A7_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="ARM_Cortex-A7_cnt1"/>
4 <counter name="ARM_Cortex-A7_cnt2"/>
5 <counter name="ARM_Cortex-A7_cnt3"/>
6 </counter_set>
7 <category name="Cortex-A7" counter_set="ARM_Cortex-A7_cntX" per_cpu="yes" event_based_sampling="yes">
8 <event counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_Cortex-A7_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
9 <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/> 4 <event event="0x00" title="Software" name="Increment" description="Software increment architecturally executed"/>
10 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Cortex-A8.xml b/daemon/events-Cortex-A8.xml
index 1981c36..fe4c69d 100644
--- a/daemon/events-Cortex-A8.xml
+++ b/daemon/events-Cortex-A8.xml
@@ -1,10 +1,5 @@
1 <counter_set name="ARM_Cortex-A8_cntX"> 1 <counter_set name="ARM_Cortex-A8_cnt" count="4"/>
2 <counter name="ARM_Cortex-A8_cnt0"/> 2 <category name="Cortex-A8" counter_set="ARM_Cortex-A8_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="ARM_Cortex-A8_cnt1"/>
4 <counter name="ARM_Cortex-A8_cnt2"/>
5 <counter name="ARM_Cortex-A8_cnt3"/>
6 </counter_set>
7 <category name="Cortex-A8" counter_set="ARM_Cortex-A8_cntX" per_cpu="yes" event_based_sampling="yes">
8 <event counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_Cortex-A8_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
9 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
10 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Cortex-A9.xml b/daemon/events-Cortex-A9.xml
index faccb2f..7597f78 100644
--- a/daemon/events-Cortex-A9.xml
+++ b/daemon/events-Cortex-A9.xml
@@ -1,12 +1,5 @@
1 <counter_set name="ARM_Cortex-A9_cntX"> 1 <counter_set name="ARM_Cortex-A9_cnt" count="6"/>
2 <counter name="ARM_Cortex-A9_cnt0"/> 2 <category name="Cortex-A9" counter_set="ARM_Cortex-A9_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="ARM_Cortex-A9_cnt1"/>
4 <counter name="ARM_Cortex-A9_cnt2"/>
5 <counter name="ARM_Cortex-A9_cnt3"/>
6 <counter name="ARM_Cortex-A9_cnt4"/>
7 <counter name="ARM_Cortex-A9_cnt5"/>
8 </counter_set>
9 <category name="Cortex-A9" counter_set="ARM_Cortex-A9_cntX" per_cpu="yes" event_based_sampling="yes">
10 <event counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ARM_Cortex-A9_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
11 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
12 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-Krait-architected.xml b/daemon/events-Krait-architected.xml
index 6f2982e..06c1901 100644
--- a/daemon/events-Krait-architected.xml
+++ b/daemon/events-Krait-architected.xml
@@ -1,10 +1,5 @@
1 <counter_set name="Krait_cntX"> 1 <counter_set name="Krait_cnt" count="4"/>
2 <counter name="Krait_cnt0"/> 2 <category name="Krait" counter_set="Krait_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="Krait_cnt1"/>
4 <counter name="Krait_cnt2"/>
5 <counter name="Krait_cnt3"/>
6 </counter_set>
7 <category name="Krait" counter_set="Krait_cntX" per_cpu="yes">
8 <event counter="Krait_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="Krait_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
9 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
10 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-L2C-310.xml b/daemon/events-L2C-310.xml
index 695b6b8..4da4d1d 100644
--- a/daemon/events-L2C-310.xml
+++ b/daemon/events-L2C-310.xml
@@ -1,8 +1,5 @@
1 <counter_set name="L2C-310_cntX"> 1 <counter_set name="L2C-310_cnt" count="2"/>
2 <counter name="L2C-310_cnt0"/> 2 <category name="L2C-310" counter_set="L2C-310_cnt" per_cpu="no">
3 <counter name="L2C-310_cnt1"/>
4 </counter_set>
5 <category name="L2C-310" counter_set="L2C-310_cntX" per_cpu="no">
6 <event event="0x1" title="L2 Cache" name="CO" description="Eviction, CastOUT, of a line from the L2 cache"/> 3 <event event="0x1" title="L2 Cache" name="CO" description="Eviction, CastOUT, of a line from the L2 cache"/>
7 <event event="0x2" title="L2 Cache" name="DRH" description="Data read hit"/> 4 <event event="0x2" title="L2 Cache" name="DRH" description="Data read hit"/>
8 <event event="0x3" title="L2 Cache" name="DRREQ" description="Data read request"/> 5 <event event="0x3" title="L2 Cache" name="DRREQ" description="Data read request"/>
diff --git a/daemon/events-Linux.xml b/daemon/events-Linux.xml
index 3f626b3..b45a122 100644
--- a/daemon/events-Linux.xml
+++ b/daemon/events-Linux.xml
@@ -1,17 +1,15 @@
1 <category name="Linux"> 1 <category name="Linux">
2 <event counter="Linux_cpuload_user" title="CPU Load" name="User" per_cpu="yes" description="Scheduler CPU Load of User Application"/>
3 <event counter="Linux_cpuload_system" title="CPU Load" name="System" per_cpu="yes" description="Scheduler CPU Load of System Behavior"/>
4 <event counter="Linux_irq_softirq" title="Interrupts" name="SoftIRQ" per_cpu="yes" description="Linux SoftIRQ taken"/> 2 <event counter="Linux_irq_softirq" title="Interrupts" name="SoftIRQ" per_cpu="yes" description="Linux SoftIRQ taken"/>
5 <event counter="Linux_irq_irq" title="Interrupts" name="IRQ" per_cpu="yes" description="Linux IRQ taken"/> 3 <event counter="Linux_irq_irq" title="Interrupts" name="IRQ" per_cpu="yes" description="Linux IRQ taken"/>
6 <event counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/> 4 <event counter="Linux_block_rq_wr" title="Disk IO" name="Write" units="B" description="Disk IO Bytes Written"/>
7 <event counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/> 5 <event counter="Linux_block_rq_rd" title="Disk IO" name="Read" units="B" description="Disk IO Bytes Read"/>
8 <event counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/> 6 <event counter="Linux_net_rx" title="Network" name="Receive" units="B" description="Receive network traffic, including effect from Streamline"/>
9 <event counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/> 7 <event counter="Linux_net_tx" title="Network" name="Transmit" units="B" description="Transmit network traffic, including effect from Streamline"/>
10 <event counter="Linux_sched_switch" title="Scheduler" name="Switch" description="Context switch events"/> 8 <event counter="Linux_sched_switch" title="Scheduler" name="Switch" per_cpu="yes" description="Context switch events"/>
11 <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"/>
12 <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"/>
13 <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 buffers"/>
14 <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"/>
15 <event counter="Linux_power_cpu_idle" title="Power" name="Idle" per_cpu="yes" display="maximum" average_selection="yes" description="CPU Idle State, 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"/>
16 </category> 14 </category>
17 15
diff --git a/daemon/events-Mali-400.xml b/daemon/events-Mali-400.xml
index cb1c6b4..6830d46 100644
--- a/daemon/events-Mali-400.xml
+++ b/daemon/events-Mali-400.xml
@@ -1,33 +1,12 @@
1 <counter_set name="ARM_Mali-400_VP_cntX"> 1 <counter_set name="ARM_Mali-400_VP_cnt" count="2"/>
2 <counter name="ARM_Mali-400_VP_cnt0"/> 2 <counter_set name="ARM_Mali-400_FP0_cnt" count="2"/>
3 <counter name="ARM_Mali-400_VP_cnt1"/> 3 <counter_set name="ARM_Mali-400_FP1_cnt" count="2"/>
4 </counter_set> 4 <counter_set name="ARM_Mali-400_FP2_cnt" count="2"/>
5 <counter_set name="ARM_Mali-400_FP0_cntX"> 5 <counter_set name="ARM_Mali-400_FP3_cnt" count="2"/>
6 <counter name="ARM_Mali-400_FP0_cnt0"/> 6 <counter_set name="ARM_Mali-400_L2_cnt" count="2"/>
7 <counter name="ARM_Mali-400_FP0_cnt1"/> 7 <counter_set name="ARM_Mali-400_SW_cnt" count="0"/>
8 </counter_set> 8 <counter_set name="ARM_Mali-400_Filmstrip_cnt" count="1"/>
9 <counter_set name="ARM_Mali-400_FP1_cntX"> 9 <category name="Mali-400-VP" counter_set="ARM_Mali-400_VP_cnt" per_cpu="no">
10 <counter name="ARM_Mali-400_FP1_cnt0"/>
11 <counter name="ARM_Mali-400_FP1_cnt1"/>
12 </counter_set>
13 <counter_set name="ARM_Mali-400_FP2_cntX">
14 <counter name="ARM_Mali-400_FP2_cnt0"/>
15 <counter name="ARM_Mali-400_FP2_cnt1"/>
16 </counter_set>
17 <counter_set name="ARM_Mali-400_FP3_cntX">
18 <counter name="ARM_Mali-400_FP3_cnt0"/>
19 <counter name="ARM_Mali-400_FP3_cnt1"/>
20 </counter_set>
21 <counter_set name="ARM_Mali-400_L2_cntX">
22 <counter name="ARM_Mali-400_L2_cnt0"/>
23 <counter name="ARM_Mali-400_L2_cnt1"/>
24 </counter_set>
25 <counter_set name="ARM_Mali-400_SW_cntX">
26 </counter_set>
27 <counter_set name="ARM_Mali-400_Filmstrip_cntX">
28 <counter name="ARM_Mali-400_Filmstrip"/>
29 </counter_set>
30 <category name="Mali-400-VP" counter_set="ARM_Mali-400_VP_cntX" per_cpu="no">
31 <event event="0x01" title="Mali GPU Vertex Processor" name="Active cycles" description="Number of cycles per frame the MaliGP2 was active."/> 10 <event event="0x01" title="Mali GPU Vertex Processor" name="Active cycles" description="Number of cycles per frame the MaliGP2 was active."/>
32 <event event="0x02" title="Mali GPU Vertex Processor" name="Active cycles, vertex shader" description="Number of cycles per frame the vertex shader unit was active."/> 11 <event event="0x02" title="Mali GPU Vertex Processor" name="Active cycles, vertex shader" description="Number of cycles per frame the vertex shader unit was active."/>
33 <event event="0x03" title="Mali GPU Vertex Processor" name="Active cycles, vertex storer" description="Number of cycles per frame the vertex storer unit was active."/> 12 <event event="0x03" title="Mali GPU Vertex Processor" name="Active cycles, vertex storer" description="Number of cycles per frame the vertex storer unit was active."/>
@@ -54,7 +33,7 @@
54 <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 scissoringi. This includes time spent waiting on the bus."/>
55 <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."/>
56 </category> 35 </category>
57 <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cntX" per_cpu="no"> 36 <category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cnt" per_cpu="no">
58 <event event="0x00" title="Mali GPU Fragment Processor 0" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> 37 <event event="0x00" title="Mali GPU Fragment Processor 0" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
59 <event event="0x02" title="Mali GPU Fragment Processor 0" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> 38 <event event="0x02" title="Mali GPU Fragment Processor 0" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
60 <event event="0x03" title="Mali GPU Fragment Processor 0" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> 39 <event event="0x03" title="Mali GPU Fragment Processor 0" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -113,7 +92,7 @@
113 <event event="0x3c" title="Mali GPU Fragment Processor 0" name="Program cache hit count" description="Number of hits in the program cache."/> 92 <event event="0x3c" title="Mali GPU Fragment Processor 0" name="Program cache hit count" description="Number of hits in the program cache."/>
114 <event event="0x3d" title="Mali GPU Fragment Processor 0" name="Program cache miss count" description="Number of misses in the program cache."/> 93 <event event="0x3d" title="Mali GPU Fragment Processor 0" name="Program cache miss count" description="Number of misses in the program cache."/>
115 </category> 94 </category>
116 <category name="Mali-400-FP1" counter_set="ARM_Mali-400_FP1_cntX" per_cpu="no"> 95 <category name="Mali-400-FP1" counter_set="ARM_Mali-400_FP1_cnt" per_cpu="no">
117 <event event="0x00" title="Mali GPU Fragment Processor 1" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> 96 <event event="0x00" title="Mali GPU Fragment Processor 1" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
118 <event event="0x02" title="Mali GPU Fragment Processor 1" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> 97 <event event="0x02" title="Mali GPU Fragment Processor 1" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
119 <event event="0x03" title="Mali GPU Fragment Processor 1" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> 98 <event event="0x03" title="Mali GPU Fragment Processor 1" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -172,7 +151,7 @@
172 <event event="0x3c" title="Mali GPU Fragment Processor 1" name="Program cache hit count" description="Number of hits in the program cache."/> 151 <event event="0x3c" title="Mali GPU Fragment Processor 1" name="Program cache hit count" description="Number of hits in the program cache."/>
173 <event event="0x3d" title="Mali GPU Fragment Processor 1" name="Program cache miss count" description="Number of misses in the program cache."/> 152 <event event="0x3d" title="Mali GPU Fragment Processor 1" name="Program cache miss count" description="Number of misses in the program cache."/>
174 </category> 153 </category>
175 <category name="Mali-400-FP2" counter_set="ARM_Mali-400_FP2_cntX" per_cpu="no"> 154 <category name="Mali-400-FP2" counter_set="ARM_Mali-400_FP2_cnt" per_cpu="no">
176 <event event="0x00" title="Mali GPU Fragment Processor 2" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> 155 <event event="0x00" title="Mali GPU Fragment Processor 2" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
177 <event event="0x02" title="Mali GPU Fragment Processor 2" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> 156 <event event="0x02" title="Mali GPU Fragment Processor 2" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
178 <event event="0x03" title="Mali GPU Fragment Processor 2" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> 157 <event event="0x03" title="Mali GPU Fragment Processor 2" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -231,7 +210,7 @@
231 <event event="0x3c" title="Mali GPU Fragment Processor 2" name="Program cache hit count" description="Number of hits in the program cache."/> 210 <event event="0x3c" title="Mali GPU Fragment Processor 2" name="Program cache hit count" description="Number of hits in the program cache."/>
232 <event event="0x3d" title="Mali GPU Fragment Processor 2" name="Program cache miss count" description="Number of misses in the program cache."/> 211 <event event="0x3d" title="Mali GPU Fragment Processor 2" name="Program cache miss count" description="Number of misses in the program cache."/>
233 </category> 212 </category>
234 <category name="Mali-400-FP3" counter_set="ARM_Mali-400_FP3_cntX" per_cpu="no"> 213 <category name="Mali-400-FP3" counter_set="ARM_Mali-400_FP3_cnt" per_cpu="no">
235 <event event="0x00" title="Mali GPU Fragment Processor 3" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/> 214 <event event="0x00" title="Mali GPU Fragment Processor 3" name="Active clock cycles" description="Active clock cycles, between polygon start and IRQ."/>
236 <event event="0x02" title="Mali GPU Fragment Processor 3" name="Total bus reads" description="Total number of 64-bit words read from the bus."/> 215 <event event="0x02" title="Mali GPU Fragment Processor 3" name="Total bus reads" description="Total number of 64-bit words read from the bus."/>
237 <event event="0x03" title="Mali GPU Fragment Processor 3" name="Total bus writes" description="Total number of 64-bit words written to the bus."/> 216 <event event="0x03" title="Mali GPU Fragment Processor 3" name="Total bus writes" description="Total number of 64-bit words written to the bus."/>
@@ -290,7 +269,7 @@
290 <event event="0x3c" title="Mali GPU Fragment Processor 3" name="Program cache hit count" description="Number of hits in the program cache."/> 269 <event event="0x3c" title="Mali GPU Fragment Processor 3" name="Program cache hit count" description="Number of hits in the program cache."/>
291 <event event="0x3d" title="Mali GPU Fragment Processor 3" name="Program cache miss count" description="Number of misses in the program cache."/> 270 <event event="0x3d" title="Mali GPU Fragment Processor 3" name="Program cache miss count" description="Number of misses in the program cache."/>
292 </category> 271 </category>
293 <category name="Mali-400-L2" counter_set="ARM_Mali-400_L2_cntX" per_cpu="no"> 272 <category name="Mali-400-L2" counter_set="ARM_Mali-400_L2_cnt" per_cpu="no">
294 <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles."/> 273 <event event="0x01" title="Mali L2 Cache" name="Total clock cycles" description="Total clock cycles."/>
295 <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles." /> 274 <event event="0x02" title="Mali L2 Cache" name="Active clock cycles" description="Active clock cycles." />
296 <event event="0x08" title="Mali L2 Cache" name="Read transactions, master" description="Read transactions, master." /> 275 <event event="0x08" title="Mali L2 Cache" name="Read transactions, master" description="Read transactions, master." />
@@ -352,7 +331,7 @@
352 <event event="0x67" title="Mali L2 Cache" name="Read invalidates, slave 4" description="Read invalidates, slave 4." /> 331 <event event="0x67" title="Mali L2 Cache" name="Read invalidates, slave 4" description="Read invalidates, slave 4." />
353 <event event="0x68" title="Mali L2 Cache" name="Cacheable read transactions, slave 4" description="Cacheable read transactions, slave 4." /> 332 <event event="0x68" title="Mali L2 Cache" name="Cacheable read transactions, slave 4" description="Cacheable read transactions, slave 4." />
354 </category> 333 </category>
355 <category name="ARM_Mali-400_Filmstrip" counter_set="ARM_Mali-400_Filmstrip_cntX" per_cpu="no"> 334 <category name="ARM_Mali-400_Filmstrip" counter_set="ARM_Mali-400_Filmstrip_cnt" per_cpu="no">
356 <event event="0x040a" title="ARM_Mali-400_Filmstrip" name="Freq 1:10" description="Scaled framebuffer captures every 10th frame." /> 335 <event event="0x040a" title="ARM_Mali-400_Filmstrip" name="Freq 1:10" description="Scaled framebuffer captures every 10th frame." />
357 <event event="0x041e" title="ARM_Mali-400_Filmstrip" name="Freq 1:30" description="Scaled framebuffer captures every 30th frame." /> 336 <event event="0x041e" title="ARM_Mali-400_Filmstrip" name="Freq 1:30" description="Scaled framebuffer captures every 30th frame." />
358 <event event="0x043c" title="ARM_Mali-400_Filmstrip" name="Freq 1:60" description="Scaled framebuffer captures every 60th frame." /> 337 <event event="0x043c" title="ARM_Mali-400_Filmstrip" name="Freq 1:60" description="Scaled framebuffer captures every 60th frame." />
@@ -363,7 +342,7 @@
363 <category name="ARM_Mali-400_Frequency" per_cpu="no"> 342 <category name="ARM_Mali-400_Frequency" per_cpu="no">
364 <event counter="ARM_Mali-400_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/> 343 <event counter="ARM_Mali-400_Frequency" title="Mali GPU Frequency" name="Frequency" display="average" average_selection="yes" units="MHz" description="GPU core frequency."/>
365 </category> 344 </category>
366 <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cntX" per_cpu="no"> 345 <category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cnt" per_cpu="no">
367 <!-- EGL Counters --> 346 <!-- EGL Counters -->
368 <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 the framebuffer from video memory to framebuffer."/>
369 <!-- glDrawElements Counters --> 348 <!-- glDrawElements Counters -->
diff --git a/daemon/events-Scorpion.xml b/daemon/events-Scorpion.xml
index 51ed937..1642e85 100644
--- a/daemon/events-Scorpion.xml
+++ b/daemon/events-Scorpion.xml
@@ -1,10 +1,5 @@
1 <counter_set name="Scorpion_cntX"> 1 <counter_set name="Scorpion_cnt" count="4"/>
2 <counter name="Scorpion_cnt0"/> 2 <category name="Scorpion" counter_set="Scorpion_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="Scorpion_cnt1"/>
4 <counter name="Scorpion_cnt2"/>
5 <counter name="Scorpion_cnt3"/>
6 </counter_set>
7 <category name="Scorpion" counter_set="Scorpion_cntX" per_cpu="yes">
8 <event counter="Scorpion_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="Scorpion_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
9 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
10 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/events-ScorpionMP.xml b/daemon/events-ScorpionMP.xml
index d3dd430..42acc64 100644
--- a/daemon/events-ScorpionMP.xml
+++ b/daemon/events-ScorpionMP.xml
@@ -1,10 +1,5 @@
1 <counter_set name="ScorpionMP_cntX"> 1 <counter_set name="ScorpionMP_cnt" count="4"/>
2 <counter name="ScorpionMP_cnt0"/> 2 <category name="ScorpionMP" counter_set="ScorpionMP_cnt" per_cpu="yes" supports_event_based_sampling="yes">
3 <counter name="ScorpionMP_cnt1"/>
4 <counter name="ScorpionMP_cnt2"/>
5 <counter name="ScorpionMP_cnt3"/>
6 </counter_set>
7 <category name="ScorpionMP" counter_set="ScorpionMP_cntX" per_cpu="yes">
8 <event counter="ScorpionMP_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/> 3 <event counter="ScorpionMP_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
9 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/> 4 <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
10 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/> 5 <event event="0x01" title="Cache" name="Instruction refill" description="Instruction fetch that causes a refill of at least the level of instruction or unified cache closest to the processor"/>
diff --git a/daemon/main.cpp b/daemon/main.cpp
index d972913..5bc75ef 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -17,6 +17,8 @@
17#include <sys/types.h> 17#include <sys/types.h>
18#include <sys/stat.h> 18#include <sys/stat.h>
19#include <sys/mount.h> 19#include <sys/mount.h>
20#include <fcntl.h>
21#include <sys/mman.h>
20#include "Child.h" 22#include "Child.h"
21#include "SessionData.h" 23#include "SessionData.h"
22#include "OlySocket.h" 24#include "OlySocket.h"
@@ -114,6 +116,26 @@ int mountGatorFS() {
114 } 116 }
115} 117}
116 118
119bool init_module (const char * const location) {
120 bool ret(false);
121 const int fd = open(location, O_RDONLY);
122 if (fd >= 0) {
123 struct stat st;
124 if (fstat(fd, &st) == 0) {
125 void * const p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
126 if (p != MAP_FAILED) {
127 if (syscall(__NR_init_module, p, st.st_size, "") == 0) {
128 ret = true;
129 }
130 munmap(p, st.st_size);
131 }
132 }
133 close(fd);
134 }
135
136 return ret;
137}
138
117int setupFilesystem(char* module) { 139int setupFilesystem(char* module) {
118 int retval; 140 int retval;
119 141
@@ -162,11 +184,15 @@ int setupFilesystem(char* module) {
162 } 184 }
163 185
164 // Load driver 186 // Load driver
165 snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location); 187 bool success = init_module(location);
166 if (system(command) != 0) { 188 if (!success) {
167 logg->logMessage("Unable to load gator.ko driver with command: %s", command); 189 logg->logMessage("init_module failed, trying insmod");
168 logg->logError(__FILE__, __LINE__, "Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details"); 190 snprintf(command, sizeof(command), "insmod %s >/dev/null 2>&1", location);
169 handleException(); 191 if (system(command) != 0) {
192 logg->logMessage("Unable to load gator.ko driver with command: %s", command);
193 logg->logError(__FILE__, __LINE__, "Unable to load (insmod) gator.ko driver:\n >>> gator.ko must be built against the current kernel version & configuration\n >>> See dmesg for more details");
194 handleException();
195 }
170 } 196 }
171 197
172 if (mountGatorFS() == -1) { 198 if (mountGatorFS() == -1) {
@@ -183,8 +209,11 @@ int shutdownFilesystem() {
183 umount("/dev/gator"); 209 umount("/dev/gator");
184 } 210 }
185 if (driverRunningAtStart == false) { 211 if (driverRunningAtStart == false) {
186 if (system("rmmod gator >/dev/null 2>&1") != 0) { 212 if (syscall(__NR_delete_module, "gator", O_NONBLOCK) != 0) {
187 return -1; 213 logg->logMessage("delete_module failed, trying rmmod");
214 if (system("rmmod gator >/dev/null 2>&1") != 0) {
215 return -1;
216 }
188 } 217 }
189 } 218 }
190 219
@@ -205,7 +234,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
205 snprintf(version_string, sizeof(version_string), "Streamline gatord development version %d", PROTOCOL_VERSION); 234 snprintf(version_string, sizeof(version_string), "Streamline gatord development version %d", PROTOCOL_VERSION);
206 } 235 }
207 236
208 while ((c = getopt(argc, argv, "hvp:s:c:e:m:")) != -1) { 237 while ((c = getopt(argc, argv, "hvp:s:c:e:m:o:")) != -1) {
209 switch(c) { 238 switch(c) {
210 case 'c': 239 case 'c':
211 gSessionData->mConfigurationXMLPath = optarg; 240 gSessionData->mConfigurationXMLPath = optarg;
@@ -222,6 +251,9 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
222 case 's': 251 case 's':
223 gSessionData->mSessionXMLPath = optarg; 252 gSessionData->mSessionXMLPath = optarg;
224 break; 253 break;
254 case 'o':
255 gSessionData->mTargetPath = optarg;
256 break;
225 case 'h': 257 case 'h':
226 case '?': 258 case '?':
227 logg->logError(__FILE__, __LINE__, 259 logg->logError(__FILE__, __LINE__,
@@ -232,6 +264,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
232 "-m module path and filename of gator.ko\n" 264 "-m module path and filename of gator.ko\n"
233 "-p port_number port upon which the server listens; default is 8080\n" 265 "-p port_number port upon which the server listens; default is 8080\n"
234 "-s session_xml path and filename of a session xml used for local capture\n" 266 "-s session_xml path and filename of a session xml used for local capture\n"
267 "-o apc_dir path and name of the output for a local capture\n"
235 "-v version information\n" 268 "-v version information\n"
236 , version_string); 269 , version_string);
237 handleException(); 270 handleException();
@@ -249,6 +282,11 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
249 handleException(); 282 handleException();
250 } 283 }
251 284
285 if (gSessionData->mTargetPath != NULL && gSessionData->mSessionXMLPath == NULL) {
286 logg->logError(__FILE__, __LINE__, "Missing -s command line option required for a local capture.");
287 handleException();
288 }
289
252 if (optind < argc) { 290 if (optind < argc) {
253 logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]); 291 logg->logError(__FILE__, __LINE__, "Unknown argument: %s. Use '-h' for help.", argv[optind]);
254 handleException(); 292 handleException();
@@ -259,6 +297,7 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
259 297
260// Gator data flow: collector -> collector fifo -> sender 298// Gator data flow: collector -> collector fifo -> sender
261int main(int argc, char** argv, char* envp[]) { 299int main(int argc, char** argv, char* envp[]) {
300 setsid();
262 gSessionData = new SessionData(); // Global data class 301 gSessionData = new SessionData(); // Global data class
263 logg = new Logging(DEBUG); // Set up global thread-safe logging 302 logg = new Logging(DEBUG); // Set up global thread-safe logging
264 util = new OlyUtility(); // Set up global utility class 303 util = new OlyUtility(); // Set up global utility class
diff --git a/driver/Makefile b/driver/Makefile
index 025dd9e..6cafecf 100644
--- a/driver/Makefile
+++ b/driver/Makefile
@@ -27,6 +27,10 @@ gator-y += gator_events_mali_common.o
27EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT) 27EXTRA_CFLAGS += -DMALI_SUPPORT=$(GATOR_WITH_MALI_SUPPORT)
28endif 28endif
29 29
30# GATOR_TEST controls whether to include (=1) or exclude (=0) test code.
31GATOR_TEST ?= 0
32EXTRA_CFLAGS += -DGATOR_TEST=$(GATOR_TEST)
33
30gator-$(CONFIG_ARM) += gator_events_armv6.o \ 34gator-$(CONFIG_ARM) += gator_events_armv6.o \
31 gator_events_armv7.o \ 35 gator_events_armv7.o \
32 gator_events_l2c-310.o \ 36 gator_events_l2c-310.o \
diff --git a/driver/gator.h b/driver/gator.h
index 6b96109..5a40e17 100644
--- a/driver/gator.h
+++ b/driver/gator.h
@@ -20,19 +20,20 @@
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
22// cpu ids 22// cpu ids
23#define ARM1136 0xb36 23#define ARM1136 0xb36
24#define ARM1156 0xb56 24#define ARM1156 0xb56
25#define ARM1176 0xb76 25#define ARM1176 0xb76
26#define ARM11MPCORE 0xb02 26#define ARM11MPCORE 0xb02
27#define CORTEX_A5 0xc05 27#define CORTEX_A5 0xc05
28#define CORTEX_A7 0xc07 28#define CORTEX_A7 0xc07
29#define CORTEX_A8 0xc08 29#define CORTEX_A8 0xc08
30#define CORTEX_A9 0xc09 30#define CORTEX_A9 0xc09
31#define CORTEX_A15 0xc0f 31#define CORTEX_A15 0xc0f
32#define SCORPION 0x00f 32#define SCORPION 0x00f
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 AARCH64 0xd0f
36 37
37/****************************************************************************** 38/******************************************************************************
38 * Filesystem 39 * Filesystem
@@ -97,4 +98,6 @@ int gator_events_install(struct gator_interface *interface);
97int gator_events_get_key(void); 98int gator_events_get_key(void);
98extern u32 gator_cpuid(void); 99extern u32 gator_cpuid(void);
99 100
101void gator_backtrace_handler(struct pt_regs * const regs);
102
100#endif // GATOR_H_ 103#endif // GATOR_H_
diff --git a/driver/gator_annotate.c b/driver/gator_annotate.c
index b444789..928e252 100644
--- a/driver/gator_annotate.c
+++ b/driver/gator_annotate.c
@@ -38,26 +38,34 @@ static int annotate_copy(struct file *file, char const __user *buf, size_t count
38 38
39static ssize_t annotate_write(struct file *file, char const __user *buf, size_t count_orig, loff_t *offset) 39static ssize_t annotate_write(struct file *file, char const __user *buf, size_t count_orig, loff_t *offset)
40{ 40{
41 int tid, cpu, header_size, available, contiguous, length1, length2, size, count = count_orig & 0x7fffffff; 41 int pid, cpu, header_size, available, contiguous, length1, length2, size, count = count_orig & 0x7fffffff;
42 42
43 if (*offset) 43 if (*offset) {
44 return -EINVAL; 44 return -EINVAL;
45 }
46
47 // Annotation is not supported in interrupt context
48 if (in_interrupt()) {
49 return -EINVAL;
50 }
45 51
46 if (!collect_annotations) 52 // synchronize between cores and with collect_annotations
53 spin_lock(&annotate_lock);
54
55 if (!collect_annotations) {
47 // Not collecting annotations, tell the caller everything was written 56 // Not collecting annotations, tell the caller everything was written
48 return count_orig; 57 size = count_orig;
58 goto annotate_write_out;
59 }
49 60
50 cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine 61 cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine
51 62
52 if (file == NULL) { 63 if (current == NULL) {
53 tid = -1; // set the thread id to the kernel thread 64 pid = 0;
54 } else { 65 } else {
55 tid = current->pid; 66 pid = current->pid;
56 } 67 }
57 68
58 // synchronize between cores
59 spin_lock(&annotate_lock);
60
61 // determine total size of the payload 69 // determine total size of the payload
62 header_size = MAXSIZE_PACK32 * 3 + MAXSIZE_PACK64; 70 header_size = MAXSIZE_PACK32 * 3 + MAXSIZE_PACK64;
63 available = buffer_bytes_available(cpu, ANNOTATE_BUF) - header_size; 71 available = buffer_bytes_available(cpu, ANNOTATE_BUF) - header_size;
@@ -71,9 +79,9 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
71 } 79 }
72 80
73 // synchronize shared variables annotateBuf and annotatePos 81 // synchronize shared variables annotateBuf and annotatePos
74 if (collect_annotations && per_cpu(gator_buffer, cpu)[ANNOTATE_BUF]) { 82 if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF]) {
75 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); 83 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id());
76 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, tid); 84 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
77 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, gator_get_time()); 85 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, gator_get_time());
78 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, size); 86 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, size);
79 87
@@ -118,9 +126,9 @@ static int annotate_release(struct inode *inode, struct file *file)
118 spin_lock(&annotate_lock); 126 spin_lock(&annotate_lock);
119 127
120 if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF] && buffer_check_space(cpu, ANNOTATE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) { 128 if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF] && buffer_check_space(cpu, ANNOTATE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
121 uint32_t tid = current->pid; 129 uint32_t pid = current->pid;
122 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id()); 130 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id());
123 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, tid); 131 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
124 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time 132 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time
125 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size 133 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size
126 } 134 }
@@ -148,5 +156,8 @@ static int gator_annotate_start(void)
148 156
149static void gator_annotate_stop(void) 157static void gator_annotate_stop(void)
150{ 158{
159 // the spinlock here will ensure that when this function exits, we are not in the middle of an annotation
160 spin_lock(&annotate_lock);
151 collect_annotations = false; 161 collect_annotations = false;
162 spin_unlock(&annotate_lock);
152} 163}
diff --git a/driver/gator_annotate_kernel.c b/driver/gator_annotate_kernel.c
index ffab087..bc68fa8 100644
--- a/driver/gator_annotate_kernel.c
+++ b/driver/gator_annotate_kernel.c
@@ -7,50 +7,83 @@
7 * 7 *
8 */ 8 */
9 9
10static void kannotate_write(char* ptr, unsigned int size) 10#define ESCAPE_CODE 0x1c
11#define STRING_ANNOTATION 0x03
12#define VISUAL_ANNOTATION 0x04
13#define MARKER_ANNOTATION 0x05
14
15static void kannotate_write(const char* ptr, unsigned int size)
11{ 16{
12 int retval; 17 int retval;
13 int pos = 0; 18 int pos = 0;
14 loff_t offset = 0; 19 loff_t offset = 0;
15 while (pos < size) { 20 while (pos < size) {
16 retval = annotate_write(NULL, &ptr[pos], size - pos, &offset); 21 retval = annotate_write(NULL, &ptr[pos], size - pos, &offset);
17 if (retval < 0) { 22 if (retval < 0) {
18 printk(KERN_WARNING "gator: kannotate_write failed with return value %d\n", retval); 23 printk(KERN_WARNING "gator: kannotate_write failed with return value %d\n", retval);
19 return; 24 return;
20 } 25 }
21 pos += retval; 26 pos += retval;
22 } 27 }
23} 28}
24 29
30static void gator_annotate_code(char code)
31{
32 int header = ESCAPE_CODE | (code << 8);
33 kannotate_write((char*)&header, sizeof(header));
34}
35
36static void gator_annotate_code_str(char code, const char* string)
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
44static void gator_annotate_code_color(char code, int color)
45{
46 long long header = (ESCAPE_CODE | (code << 8) | 0x00040000 | ((long long)color << 32));
47 kannotate_write((char*)&header, sizeof(header));
48}
49
50static void gator_annotate_code_color_str(char code, int color, const char* string)
51{
52 int str_size = (strlen(string) + 4) & 0xffff;
53 long long header = ESCAPE_CODE | (code << 8) | (str_size << 16) | ((long long)color << 32);
54 kannotate_write((char*)&header, sizeof(header));
55 kannotate_write(string, str_size - 4);
56}
57
25// String annotation 58// String annotation
26void gator_annotate(char* string) 59void gator_annotate(const char* string)
27{ 60{
28 kannotate_write(string, strlen(string) + 1); 61 gator_annotate_code_str(STRING_ANNOTATION, string);
29} 62}
30EXPORT_SYMBOL(gator_annotate); 63EXPORT_SYMBOL(gator_annotate);
31 64
32// String annotation with color 65// String annotation with color
33void gator_annotate_color(int color, char* string) 66void gator_annotate_color(int color, const char* string)
34{ 67{
35 kannotate_write((char*)&color, sizeof(color)); 68 gator_annotate_code_color_str(STRING_ANNOTATION, color, string);
36 kannotate_write(string, strlen(string) + 1);
37} 69}
38EXPORT_SYMBOL(gator_annotate_color); 70EXPORT_SYMBOL(gator_annotate_color);
39 71
40// Terminate an annotation 72// Terminate an annotation
41void gator_annotate_end(void) 73void gator_annotate_end(void)
42{ 74{
43 char nul = 0; 75 gator_annotate_code(STRING_ANNOTATION);
44 kannotate_write(&nul, sizeof(nul));
45} 76}
46EXPORT_SYMBOL(gator_annotate_end); 77EXPORT_SYMBOL(gator_annotate_end);
47 78
48// Image annotation with optional string 79// Image annotation with optional string
49void gator_annotate_visual(char* data, unsigned int length, char* string) 80void gator_annotate_visual(const char* data, unsigned int length, const char* string)
50{ 81{
51 long long visual_annotation = 0x011c | (strlen(string) << 16) | ((long long)length << 32); 82 int str_size = strlen(string) & 0xffff;
52 kannotate_write((char*)&visual_annotation, 8); 83 int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16);
53 kannotate_write(string, strlen(string)); 84 kannotate_write((char*)&visual_annotation, sizeof(visual_annotation));
85 kannotate_write(string, str_size);
86 kannotate_write((char*)&length, sizeof(length));
54 kannotate_write(data, length); 87 kannotate_write(data, length);
55} 88}
56EXPORT_SYMBOL(gator_annotate_visual); 89EXPORT_SYMBOL(gator_annotate_visual);
@@ -58,33 +91,27 @@ EXPORT_SYMBOL(gator_annotate_visual);
58// Marker annotation 91// Marker annotation
59void gator_annotate_marker(void) 92void gator_annotate_marker(void)
60{ 93{
61 int marker_annotation = 0x00021c; 94 gator_annotate_code(MARKER_ANNOTATION);
62 kannotate_write((char*)&marker_annotation, 3);
63} 95}
64EXPORT_SYMBOL(gator_annotate_marker); 96EXPORT_SYMBOL(gator_annotate_marker);
65 97
66// Marker annotation with a string 98// Marker annotation with a string
67void gator_annotate_marker_str(char* string) 99void gator_annotate_marker_str(const char* string)
68{ 100{
69 int marker_annotation = 0x021c; 101 gator_annotate_code_str(MARKER_ANNOTATION, string);
70 kannotate_write((char*)&marker_annotation, 2);
71 kannotate_write(string, strlen(string) + 1);
72} 102}
73EXPORT_SYMBOL(gator_annotate_marker_str); 103EXPORT_SYMBOL(gator_annotate_marker_str);
74 104
75// Marker annotation with a color 105// Marker annotation with a color
76void gator_annotate_marker_color(int color) 106void gator_annotate_marker_color(int color)
77{ 107{
78 long long marker_annotation = (0x021c | ((long long)color << 16)) & 0x0000ffffffffffffLL; 108 gator_annotate_code_color(MARKER_ANNOTATION, color);
79 kannotate_write((char*)&marker_annotation, 7);
80} 109}
81EXPORT_SYMBOL(gator_annotate_marker_color); 110EXPORT_SYMBOL(gator_annotate_marker_color);
82 111
83// Marker annotationw ith a string and color 112// Marker annotation with a string and color
84void gator_annotate_marker_color_str(int color, char* string) 113void gator_annotate_marker_color_str(int color, const char* string)
85{ 114{
86 long long marker_annotation = 0x021c | ((long long)color << 16); 115 gator_annotate_code_color_str(MARKER_ANNOTATION, color, string);
87 kannotate_write((char*)&marker_annotation, 6);
88 kannotate_write(string, strlen(string) + 1);
89} 116}
90EXPORT_SYMBOL(gator_annotate_marker_color_str); 117EXPORT_SYMBOL(gator_annotate_marker_color_str);
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index 50783d6..2173d8a 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -15,7 +15,7 @@ struct frame_tail_eabi {
15 unsigned long lr; 15 unsigned long lr;
16}; 16};
17 17
18static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs, unsigned int depth) 18static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth)
19{ 19{
20#if defined(__arm__) 20#if defined(__arm__)
21 struct frame_tail_eabi *tail; 21 struct frame_tail_eabi *tail;
@@ -32,7 +32,7 @@ static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs
32 } 32 }
33 33
34 /* entry preamble may not have executed */ 34 /* entry preamble may not have executed */
35 gator_add_trace(cpu, buftype, lr); 35 gator_add_trace(cpu, lr);
36 36
37 /* check tail is valid */ 37 /* check tail is valid */
38 if (fp == 0 || fp < sp) { 38 if (fp == 0 || fp < sp) {
@@ -50,7 +50,7 @@ static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs
50 ptrtail = &buftail; 50 ptrtail = &buftail;
51 51
52 lr = ptrtail[0].lr; 52 lr = ptrtail[0].lr;
53 gator_add_trace(cpu, buftype, lr); 53 gator_add_trace(cpu, lr);
54 54
55 /* frame pointers should progress back up the stack, towards higher addresses */ 55 /* frame pointers should progress back up the stack, towards higher addresses */
56 next = (struct frame_tail_eabi *)(lr - 4); 56 next = (struct frame_tail_eabi *)(lr - 4);
@@ -69,16 +69,16 @@ static void arm_backtrace_eabi(int cpu, int buftype, struct pt_regs * const regs
69} 69}
70 70
71#if defined(__arm__) 71#if defined(__arm__)
72static DEFINE_PER_CPU(int, backtrace_buffer);
73static int report_trace(struct stackframe *frame, void *d) 72static int report_trace(struct stackframe *frame, void *d)
74{ 73{
75 struct module *mod; 74 struct module *mod;
76 unsigned int *depth = d, addr = frame->pc, cookie = NO_COOKIE, cpu = smp_processor_id(); 75 unsigned int *depth = d, cookie = NO_COOKIE, cpu = smp_processor_id();
76 unsigned long addr = frame->pc;
77 77
78 if (*depth) { 78 if (*depth) {
79 mod = __module_address(addr); 79 mod = __module_address(addr);
80 if (mod) { 80 if (mod) {
81 cookie = get_cookie(cpu, per_cpu(backtrace_buffer, cpu), current, NULL, mod, true); 81 cookie = get_cookie(cpu, current, NULL, mod, true);
82 addr = addr - (unsigned long)mod->module_core; 82 addr = addr - (unsigned long)mod->module_core;
83 } 83 }
84 marshal_backtrace(addr & ~1, cookie); 84 marshal_backtrace(addr & ~1, cookie);
@@ -91,7 +91,7 @@ static int report_trace(struct stackframe *frame, void *d)
91 91
92// Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile 92// 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 93// #define GATOR_KERNEL_STACK_UNWINDING
94static void kernel_backtrace(int cpu, int buftype, struct pt_regs * const regs) 94static void kernel_backtrace(int cpu, struct pt_regs * const regs)
95{ 95{
96#if defined(__arm__) 96#if defined(__arm__)
97#ifdef GATOR_KERNEL_STACK_UNWINDING 97#ifdef GATOR_KERNEL_STACK_UNWINDING
@@ -106,7 +106,6 @@ static void kernel_backtrace(int cpu, int buftype, struct pt_regs * const regs)
106 frame.sp = regs->ARM_sp; 106 frame.sp = regs->ARM_sp;
107 frame.lr = regs->ARM_lr; 107 frame.lr = regs->ARM_lr;
108 frame.pc = regs->ARM_pc; 108 frame.pc = regs->ARM_pc;
109 per_cpu(backtrace_buffer, cpu) = buftype;
110 walk_stackframe(&frame, report_trace, &depth); 109 walk_stackframe(&frame, report_trace, &depth);
111#else 110#else
112 marshal_backtrace(PC_REG & ~1, NO_COOKIE); 111 marshal_backtrace(PC_REG & ~1, NO_COOKIE);
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c
index d7d8e84..b2ed686 100644
--- a/driver/gator_cookies.c
+++ b/driver/gator_cookies.c
@@ -12,7 +12,7 @@
12#define MAX_COLLISIONS 2 12#define MAX_COLLISIONS 2
13 13
14static uint32_t *gator_crc32_table; 14static uint32_t *gator_crc32_table;
15static uint32_t translate_buffer_mask; 15static unsigned int translate_buffer_mask;
16 16
17static DEFINE_PER_CPU(char *, translate_text); 17static DEFINE_PER_CPU(char *, translate_text);
18static DEFINE_PER_CPU(uint32_t, cookie_next_key); 18static DEFINE_PER_CPU(uint32_t, cookie_next_key);
@@ -20,9 +20,9 @@ static DEFINE_PER_CPU(uint64_t *, cookie_keys);
20static DEFINE_PER_CPU(uint32_t *, cookie_values); 20static DEFINE_PER_CPU(uint32_t *, cookie_values);
21static DEFINE_PER_CPU(int, translate_buffer_read); 21static DEFINE_PER_CPU(int, translate_buffer_read);
22static DEFINE_PER_CPU(int, translate_buffer_write); 22static DEFINE_PER_CPU(int, translate_buffer_write);
23static DEFINE_PER_CPU(unsigned int *, translate_buffer); 23static DEFINE_PER_CPU(void * *, translate_buffer);
24 24
25static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt); 25static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt);
26static void wq_cookie_handler(struct work_struct *unused); 26static void wq_cookie_handler(struct work_struct *unused);
27DECLARE_WORK(cookie_work, wq_cookie_handler); 27DECLARE_WORK(cookie_work, wq_cookie_handler);
28static struct timer_list app_process_wake_up_timer; 28static struct timer_list app_process_wake_up_timer;
@@ -40,16 +40,16 @@ static uint32_t cookiemap_code(uint64_t value64) {
40 40
41static uint32_t gator_chksum_crc32(char *data) 41static uint32_t gator_chksum_crc32(char *data)
42{ 42{
43 register unsigned long crc; 43 register unsigned long crc;
44 unsigned char *block = data; 44 unsigned char *block = data;
45 int i, length = strlen(data); 45 int i, length = strlen(data);
46 46
47 crc = 0xFFFFFFFF; 47 crc = 0xFFFFFFFF;
48 for (i = 0; i < length; i++) { 48 for (i = 0; i < length; i++) {
49 crc = ((crc >> 8) & 0x00FFFFFF) ^ gator_crc32_table[(crc ^ *block++) & 0xFF]; 49 crc = ((crc >> 8) & 0x00FFFFFF) ^ gator_crc32_table[(crc ^ *block++) & 0xFF];
50 } 50 }
51 51
52 return (crc ^ 0xFFFFFFFF); 52 return (crc ^ 0xFFFFFFFF);
53} 53}
54 54
55/* 55/*
@@ -104,15 +104,15 @@ static void cookiemap_add(uint64_t key, uint32_t value) {
104 values[0] = value; 104 values[0] = value;
105} 105}
106 106
107static void translate_buffer_write_int(int cpu, unsigned int x) 107static void translate_buffer_write_ptr(int cpu, void * x)
108{ 108{
109 per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x; 109 per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
110 per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask; 110 per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
111} 111}
112 112
113static unsigned int translate_buffer_read_int(int cpu) 113static void * translate_buffer_read_ptr(int cpu)
114{ 114{
115 unsigned int value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++]; 115 void * value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
116 per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask; 116 per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask;
117 return value; 117 return value;
118} 118}
@@ -129,9 +129,9 @@ static void wq_cookie_handler(struct work_struct *unused)
129 if (gator_started != 0) { 129 if (gator_started != 0) {
130 commit = per_cpu(translate_buffer_write, cpu); 130 commit = per_cpu(translate_buffer_write, cpu);
131 while (per_cpu(translate_buffer_read, cpu) != commit) { 131 while (per_cpu(translate_buffer_read, cpu) != commit) {
132 task = (struct task_struct *)translate_buffer_read_int(cpu); 132 task = (struct task_struct *)translate_buffer_read_ptr(cpu);
133 vma = (struct vm_area_struct *)translate_buffer_read_int(cpu); 133 vma = (struct vm_area_struct *)translate_buffer_read_ptr(cpu);
134 cookie = get_cookie(cpu, BACKTRACE_BUF, task, vma, NULL, false); 134 cookie = get_cookie(cpu, task, vma, NULL, false);
135 } 135 }
136 } 136 }
137 137
@@ -163,13 +163,13 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
163 // Check if already in buffer 163 // Check if already in buffer
164 ptr = per_cpu(translate_buffer_read, cpu); 164 ptr = per_cpu(translate_buffer_read, cpu);
165 while (ptr != per_cpu(translate_buffer_write, cpu)) { 165 while (ptr != per_cpu(translate_buffer_write, cpu)) {
166 if (per_cpu(translate_buffer, cpu)[ptr] == (int)task) 166 if (per_cpu(translate_buffer, cpu)[ptr] == (void *)task)
167 goto out; 167 goto out;
168 ptr = (ptr + 2) & translate_buffer_mask; 168 ptr = (ptr + 2) & translate_buffer_mask;
169 } 169 }
170 170
171 translate_buffer_write_int(cpu, (unsigned int)task); 171 translate_buffer_write_ptr(cpu, (void *)task);
172 translate_buffer_write_int(cpu, (unsigned int)vma); 172 translate_buffer_write_ptr(cpu, (void *)vma);
173 173
174 mod_timer(&app_process_wake_up_timer, jiffies + 1); 174 mod_timer(&app_process_wake_up_timer, jiffies + 1);
175 goto out; 175 goto out;
@@ -222,7 +222,7 @@ out:
222 return retval; 222 return retval;
223} 223}
224 224
225static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt) 225static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt)
226{ 226{
227 unsigned long flags, cookie; 227 unsigned long flags, cookie;
228 struct path *path; 228 struct path *path;
@@ -271,7 +271,7 @@ static inline uint32_t get_cookie(int cpu, int buftype, struct task_struct *task
271 return cookie; 271 return cookie;
272} 272}
273 273
274static int get_exec_cookie(int cpu, int buftype, struct task_struct *task) 274static int get_exec_cookie(int cpu, struct task_struct *task)
275{ 275{
276 unsigned long cookie = NO_COOKIE; 276 unsigned long cookie = NO_COOKIE;
277 struct mm_struct *mm = task->mm; 277 struct mm_struct *mm = task->mm;
@@ -286,14 +286,14 @@ static int get_exec_cookie(int cpu, int buftype, struct task_struct *task)
286 continue; 286 continue;
287 if (!(vma->vm_flags & VM_EXECUTABLE)) 287 if (!(vma->vm_flags & VM_EXECUTABLE))
288 continue; 288 continue;
289 cookie = get_cookie(cpu, buftype, task, vma, NULL, true); 289 cookie = get_cookie(cpu, task, vma, NULL, true);
290 break; 290 break;
291 } 291 }
292 292
293 return cookie; 293 return cookie;
294} 294}
295 295
296static unsigned long get_address_cookie(int cpu, int buftype, struct task_struct *task, unsigned long addr, off_t *offset) 296static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset)
297{ 297{
298 unsigned long cookie = NO_COOKIE; 298 unsigned long cookie = NO_COOKIE;
299 struct mm_struct *mm = task->mm; 299 struct mm_struct *mm = task->mm;
@@ -307,7 +307,7 @@ static unsigned long get_address_cookie(int cpu, int buftype, struct task_struct
307 continue; 307 continue;
308 308
309 if (vma->vm_file) { 309 if (vma->vm_file) {
310 cookie = get_cookie(cpu, buftype, task, vma, NULL, true); 310 cookie = get_cookie(cpu, task, vma, NULL, true);
311 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; 311 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start;
312 } else { 312 } else {
313 /* must be an anonymous map */ 313 /* must be an anonymous map */
@@ -350,7 +350,7 @@ static int cookies_initialize(void)
350 } 350 }
351 memset(per_cpu(cookie_values, cpu), 0, size); 351 memset(per_cpu(cookie_values, cpu), 0, size);
352 352
353 per_cpu(translate_buffer, cpu) = (unsigned int *)kmalloc(translate_buffer_size, GFP_KERNEL); 353 per_cpu(translate_buffer, cpu) = (void * *)kmalloc(translate_buffer_size, GFP_KERNEL);
354 if (!per_cpu(translate_buffer, cpu)) { 354 if (!per_cpu(translate_buffer, cpu)) {
355 err = -ENOMEM; 355 err = -ENOMEM;
356 goto cookie_setup_error; 356 goto cookie_setup_error;
diff --git a/driver/gator_ebs.c b/driver/gator_ebs.c
deleted file mode 100644
index 6abdfa4..0000000
--- a/driver/gator_ebs.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/**
2 * Copyright (C) ARM Limited 2012. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 */
9
10#if defined(__arm__) && (GATOR_PERF_PMU_SUPPORT)
11#include <linux/platform_device.h>
12#include <linux/interrupt.h>
13#include <linux/irq.h>
14
15#include <asm/pmu.h>
16
17static DEFINE_MUTEX(perf_mutex);
18
19extern int pmnc_counters;
20extern int ccnt;
21extern unsigned long pmnc_enabled[];
22extern unsigned long pmnc_event[];
23extern unsigned long pmnc_count[];
24extern unsigned long pmnc_key[];
25
26static DEFINE_PER_CPU(struct perf_event_attr *, pevent_attr);
27static DEFINE_PER_CPU(int, key);
28
29#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
30static void ebs_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs)
31#else
32static void ebs_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs)
33#endif
34{
35 int cpu = smp_processor_id();
36
37 if (event != per_cpu(pevent_ebs, cpu))
38 return;
39
40 // Output backtrace
41 gator_add_sample(cpu, BACKTRACE_BUF, regs);
42
43 // Collect counters
44 collect_counters();
45}
46
47static void gator_event_sampling_online_dispatch(int cpu)
48{
49 struct perf_event * ev;
50
51 if (!event_based_sampling)
52 return;
53
54#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
55 ev = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu), cpu, 0, ebs_overflow_handler);
56#else
57 ev = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu), cpu, 0, ebs_overflow_handler, 0);
58#endif
59
60 if (IS_ERR(ev)) {
61 pr_err("gator: unable to start event-based-sampling");
62 return;
63 }
64
65 if (ev->state != PERF_EVENT_STATE_ACTIVE) {
66 pr_err("gator: unable to start event-based-sampling");
67 perf_event_release_kernel(ev);
68 return;
69 }
70
71 ev->pmu->read(ev);
72 per_cpu(pevent_ebs, cpu) = ev;
73}
74
75static void gator_event_sampling_offline_dispatch(int cpu)
76{
77 struct perf_event * pe = NULL;
78
79 mutex_lock(&perf_mutex);
80 if (per_cpu(pevent_ebs, cpu)) {
81 pe = per_cpu(pevent_ebs, cpu);
82 per_cpu(pevent_ebs, cpu) = NULL;
83 }
84 mutex_unlock(&perf_mutex);
85
86 if (pe) {
87 perf_event_release_kernel(pe);
88 }
89}
90
91static int gator_event_sampling_start(void)
92{
93 int cnt, event = 0, count = 0, ebs_key = 0, cpu;
94
95 for_each_present_cpu(cpu) {
96 per_cpu(pevent_ebs, cpu) = NULL;
97 per_cpu(pevent_attr, cpu) = NULL;
98 }
99
100 event_based_sampling = false;
101 for (cnt = 0; cnt < pmnc_counters; cnt++) {
102 if (pmnc_count[cnt] > 0) {
103 event_based_sampling = true;
104 event = pmnc_event[cnt];
105 count = pmnc_count[cnt];
106 ebs_key = pmnc_key[cnt];
107 break;
108 }
109 }
110
111 if (!event_based_sampling)
112 return 0;
113
114 for_each_present_cpu(cpu) {
115 u32 size = sizeof(struct perf_event_attr);
116 per_cpu(pevent_attr, cpu) = kmalloc(size, GFP_KERNEL);
117 if (!per_cpu(pevent_attr, cpu))
118 return -1;
119
120 memset(per_cpu(pevent_attr, cpu), 0, size);
121 per_cpu(pevent_attr, cpu)->type = PERF_TYPE_RAW;
122 per_cpu(pevent_attr, cpu)->size = size;
123 per_cpu(pevent_attr, cpu)->config = event;
124 per_cpu(pevent_attr, cpu)->sample_period = count;
125 per_cpu(pevent_attr, cpu)->pinned = 1;
126
127 // handle special case for ccnt
128 if (cnt == ccnt) {
129 per_cpu(pevent_attr, cpu)->type = PERF_TYPE_HARDWARE;
130 per_cpu(pevent_attr, cpu)->config = PERF_COUNT_HW_CPU_CYCLES;
131 }
132
133 per_cpu(key, cpu) = ebs_key;
134 }
135
136 return 0;
137}
138
139static void gator_event_sampling_stop(void)
140{
141 int cpu;
142
143 for_each_present_cpu(cpu) {
144 if (per_cpu(pevent_attr, cpu)) {
145 kfree(per_cpu(pevent_attr, cpu));
146 per_cpu(pevent_attr, cpu) = NULL;
147 }
148 }
149}
150
151#else
152static void gator_event_sampling_online_dispatch(int cpu) {}
153static void gator_event_sampling_offline_dispatch(int cpu) {}
154static int gator_event_sampling_start(void) {return 0;}
155static void gator_event_sampling_stop(void) {}
156#endif
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c
index a8b8114..b18c3ca 100644
--- a/driver/gator_events_block.c
+++ b/driver/gator_events_block.c
@@ -25,15 +25,13 @@ static ulong block_rq_wr_enabled;
25static ulong block_rq_rd_enabled; 25static ulong block_rq_rd_enabled;
26static ulong block_rq_wr_key; 26static ulong block_rq_wr_key;
27static ulong block_rq_rd_key; 27static ulong block_rq_rd_key;
28static DEFINE_PER_CPU(int[BLOCK_TOTAL], blockCnt); 28static atomic_t blockCnt[BLOCK_TOTAL];
29static DEFINE_PER_CPU(int[BLOCK_TOTAL * 4], blockGet); 29static int blockGet[BLOCK_TOTAL * 4];
30static DEFINE_PER_CPU(bool, new_data_avail);
31 30
32GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq)) 31GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq))
33{ 32{
34 unsigned long flags; 33 unsigned long flags;
35 int write, size; 34 int write, size;
36 int cpu = smp_processor_id();
37 35
38 if (!rq) 36 if (!rq)
39 return; 37 return;
@@ -47,13 +45,16 @@ GATOR_DEFINE_PROBE(block_rq_complete, TP_PROTO(struct request_queue *q, struct r
47 // disable interrupts to synchronize with gator_events_block_read() 45 // disable interrupts to synchronize with gator_events_block_read()
48 // spinlocks not needed since percpu buffers are used 46 // spinlocks not needed since percpu buffers are used
49 local_irq_save(flags); 47 local_irq_save(flags);
50 if (write) 48 if (write) {
51 per_cpu(blockCnt, cpu)[BLOCK_RQ_WR] += size; 49 if (block_rq_wr_enabled) {
52 else 50 atomic_add(size, &blockCnt[BLOCK_RQ_WR]);
53 per_cpu(blockCnt, cpu)[BLOCK_RQ_RD] += size; 51 }
52 } else {
53 if (block_rq_rd_enabled) {
54 atomic_add(size, &blockCnt[BLOCK_RQ_RD]);
55 }
56 }
54 local_irq_restore(flags); 57 local_irq_restore(flags);
55
56 per_cpu(new_data_avail, cpu) = true;
57} 58}
58 59
59static int gator_events_block_create_files(struct super_block *sb, struct dentry *root) 60static int gator_events_block_create_files(struct super_block *sb, struct dentry *root)
@@ -81,11 +82,6 @@ static int gator_events_block_create_files(struct super_block *sb, struct dentry
81 82
82static int gator_events_block_start(void) 83static int gator_events_block_start(void)
83{ 84{
84 int cpu;
85
86 for_each_present_cpu(cpu)
87 per_cpu(new_data_avail, cpu) = true;
88
89 // register tracepoints 85 // register tracepoints
90 if (block_rq_wr_enabled || block_rq_rd_enabled) 86 if (block_rq_wr_enabled || block_rq_rd_enabled)
91 if (GATOR_REGISTER_TRACE(block_rq_complete)) 87 if (GATOR_REGISTER_TRACE(block_rq_complete))
@@ -113,44 +109,32 @@ static void gator_events_block_stop(void)
113 109
114static int gator_events_block_read(int **buffer) 110static int gator_events_block_read(int **buffer)
115{ 111{
116 unsigned long flags; 112 int len, value, data = 0;
117 int len, value, cpu, data = 0;
118 cpu = smp_processor_id();
119 113
120 if (per_cpu(new_data_avail, cpu) == false) 114 if (smp_processor_id() != 0) {
121 return 0; 115 return 0;
122 116 }
123 per_cpu(new_data_avail, cpu) = false;
124 117
125 len = 0; 118 len = 0;
126 if (block_rq_wr_enabled) { 119 if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) {
127 local_irq_save(flags); 120 atomic_sub(value, &blockCnt[BLOCK_RQ_WR]);
128 value = per_cpu(blockCnt, cpu)[BLOCK_RQ_WR]; 121 blockGet[len++] = block_rq_wr_key;
129 per_cpu(blockCnt, cpu)[BLOCK_RQ_WR] = 0; 122 blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
130 local_irq_restore(flags); 123 blockGet[len++] = block_rq_wr_key;
131 per_cpu(blockGet, cpu)[len++] = block_rq_wr_key; 124 blockGet[len++] = value;
132 per_cpu(blockGet, cpu)[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
133 per_cpu(blockGet, cpu)[len++] = block_rq_wr_key;
134 per_cpu(blockGet, cpu)[len++] = value;
135 data += value; 125 data += value;
136 } 126 }
137 if (block_rq_rd_enabled) { 127 if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) {
138 local_irq_save(flags); 128 atomic_sub(value, &blockCnt[BLOCK_RQ_RD]);
139 value = per_cpu(blockCnt, cpu)[BLOCK_RQ_RD]; 129 blockGet[len++] = block_rq_rd_key;
140 per_cpu(blockCnt, cpu)[BLOCK_RQ_RD] = 0; 130 blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
141 local_irq_restore(flags); 131 blockGet[len++] = block_rq_rd_key;
142 per_cpu(blockGet, cpu)[len++] = block_rq_rd_key; 132 blockGet[len++] = value;
143 per_cpu(blockGet, cpu)[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
144 per_cpu(blockGet, cpu)[len++] = block_rq_rd_key;
145 per_cpu(blockGet, cpu)[len++] = value;
146 data += value; 133 data += value;
147 } 134 }
148 135
149 if (data != 0)
150 per_cpu(new_data_avail, cpu) = true;
151
152 if (buffer) 136 if (buffer)
153 *buffer = per_cpu(blockGet, cpu); 137 *buffer = blockGet;
154 138
155 return len; 139 return len;
156} 140}
diff --git a/driver/gator_events_mali_400.c b/driver/gator_events_mali_400.c
index 38d5b3d..65eeb4f 100644
--- a/driver/gator_events_mali_400.c
+++ b/driver/gator_events_mali_400.c
@@ -17,14 +17,6 @@
17#include "gator_events_mali_common.h" 17#include "gator_events_mali_common.h"
18#include "gator_events_mali_400.h" 18#include "gator_events_mali_400.h"
19 19
20#if !defined(GATOR_MALI_INTERFACE_STYLE)
21/*
22 * At the moment, we only have users with the old style interface, so
23 * make our life easier by making it the default...
24 */
25#define GATOR_MALI_INTERFACE_STYLE (2)
26#endif
27
28/* 20/*
29 * There are (currently) three different variants of the comms between gator and Mali: 21 * There are (currently) three different variants of the comms between gator and Mali:
30 * 1 (deprecated): No software counter support 22 * 1 (deprecated): No software counter support
@@ -393,7 +385,7 @@ static int create_files(struct super_block *sb, struct dentry *root) {
393 385
394 switch(event) { 386 switch(event) {
395 case COUNTER_FILMSTRIP: 387 case COUNTER_FILMSTRIP:
396 snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip", mali_name); 388 snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name);
397 break; 389 break;
398 390
399 case COUNTER_FREQUENCY: 391 case COUNTER_FREQUENCY:
diff --git a/driver/gator_events_mali_400.h b/driver/gator_events_mali_400.h
index b784ae9..a09757e 100644
--- a/driver/gator_events_mali_400.h
+++ b/driver/gator_events_mali_400.h
@@ -1,11 +1,10 @@
1/* 1/**
2 * This confidential and proprietary software may be used only as 2 * Copyright (C) ARM Limited 2011-2012. All rights reserved.
3 * authorised by a licensing agreement from ARM Limited 3 *
4 * (C) COPYRIGHT 2011-2012 ARM Limited 4 * This program is free software; you can redistribute it and/or modify
5 * ALL RIGHTS RESERVED 5 * it under the terms of the GNU General Public License version 2 as
6 * The entire notice above must be reproduced on all authorised 6 * published by the Free Software Foundation.
7 * copies and copies may only be made to the extent permitted 7 *
8 * by a licensing agreement from ARM Limited.
9 */ 8 */
10 9
11/* 10/*
diff --git a/driver/gator_events_mali_common.c b/driver/gator_events_mali_common.c
index 2dd9ad6..62e441c 100644
--- a/driver/gator_events_mali_common.c
+++ b/driver/gator_events_mali_common.c
@@ -1,11 +1,10 @@
1/* 1/**
2 * This confidential and proprietary software may be used only as 2 * Copyright (C) ARM Limited 2012. All rights reserved.
3 * authorised by a licensing agreement from ARM Limited 3 *
4 * (C) COPYRIGHT 2011-2012 ARM Limited 4 * This program is free software; you can redistribute it and/or modify
5 * ALL RIGHTS RESERVED 5 * it under the terms of the GNU General Public License version 2 as
6 * The entire notice above must be reproduced on all authorised 6 * published by the Free Software Foundation.
7 * copies and copies may only be made to the extent permitted 7 *
8 * by a licensing agreement from ARM Limited.
9 */ 8 */
10#include "gator_events_mali_common.h" 9#include "gator_events_mali_common.h"
11 10
diff --git a/driver/gator_events_mali_common.h b/driver/gator_events_mali_common.h
index cb851d5..2c9457f 100644
--- a/driver/gator_events_mali_common.h
+++ b/driver/gator_events_mali_common.h
@@ -1,12 +1,12 @@
1/* 1/**
2 * This confidential and proprietary software may be used only as 2 * Copyright (C) ARM Limited 2012. All rights reserved.
3 * authorised by a licensing agreement from ARM Limited 3 *
4 * (C) COPYRIGHT 2011-2012 ARM Limited 4 * This program is free software; you can redistribute it and/or modify
5 * ALL RIGHTS RESERVED 5 * it under the terms of the GNU General Public License version 2 as
6 * The entire notice above must be reproduced on all authorised 6 * published by the Free Software Foundation.
7 * copies and copies may only be made to the extent permitted 7 *
8 * by a licensing agreement from ARM Limited.
9 */ 8 */
9
10#if !defined(GATOR_EVENTS_MALI_COMMON_H) 10#if !defined(GATOR_EVENTS_MALI_COMMON_H)
11#define GATOR_EVENTS_MALI_COMMON_H 11#define GATOR_EVENTS_MALI_COMMON_H
12 12
@@ -39,6 +39,9 @@ typedef struct {
39 unsigned long enabled; /* counter enable state */ 39 unsigned long enabled; /* counter enable state */
40} mali_counter; 40} mali_counter;
41 41
42/*
43 * Mali-400
44 */
42typedef void mali_profiling_set_event_type(unsigned int, unsigned int); 45typedef void mali_profiling_set_event_type(unsigned int, unsigned int);
43typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int); 46typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int);
44typedef void mali_profiling_control_type(unsigned int, unsigned int); 47typedef void mali_profiling_control_type(unsigned int, unsigned int);
diff --git a/driver/gator_events_mali_t6xx.c b/driver/gator_events_mali_t6xx.c
index 79af764..f8f868e 100644
--- a/driver/gator_events_mali_t6xx.c
+++ b/driver/gator_events_mali_t6xx.c
@@ -1,11 +1,10 @@
1/* 1/**
2 * This confidential and proprietary software may be used only as 2 * Copyright (C) ARM Limited 2011-2012. All rights reserved.
3 * authorised by a licensing agreement from ARM Limited 3 *
4 * (C) COPYRIGHT 2011 ARM Limited 4 * This program is free software; you can redistribute it and/or modify
5 * ALL RIGHTS RESERVED 5 * it under the terms of the GNU General Public License version 2 as
6 * The entire notice above must be reproduced on all authorised 6 * published by the Free Software Foundation.
7 * copies and copies may only be made to the extent permitted 7 *
8 * by a licensing agreement from ARM Limited.
9 */ 8 */
10 9
11#include "gator.h" 10#include "gator.h"
diff --git a/driver/gator_events_mali_t6xx_hw.c b/driver/gator_events_mali_t6xx_hw.c
index 12ffebc..854d02d 100644
--- a/driver/gator_events_mali_t6xx_hw.c
+++ b/driver/gator_events_mali_t6xx_hw.c
@@ -1,11 +1,10 @@
1/* 1/**
2 * This confidential and proprietary software may be used only as 2 * Copyright (C) ARM Limited 2012. All rights reserved.
3 * authorised by a licensing agreement from ARM Limited 3 *
4 * (C) COPYRIGHT 2011-2012 ARM Limited 4 * This program is free software; you can redistribute it and/or modify
5 * ALL RIGHTS RESERVED 5 * it under the terms of the GNU General Public License version 2 as
6 * The entire notice above must be reproduced on all authorised 6 * published by the Free Software Foundation.
7 * copies and copies may only be made to the extent permitted 7 *
8 * by a licensing agreement from ARM Limited.
9 */ 8 */
10 9
11#include "gator.h" 10#include "gator.h"
@@ -23,6 +22,39 @@
23 22
24#include "gator_events_mali_common.h" 23#include "gator_events_mali_common.h"
25 24
25/*
26 * Mali-T6xx
27 */
28typedef struct kbase_device *kbase_find_device_type(int);
29typedef kbase_context *kbase_create_context_type(kbase_device*);
30typedef void kbase_destroy_context_type(kbase_context *);
31typedef void *kbase_va_alloc_type(kbase_context *, u32);
32typedef void kbase_va_free_type(kbase_context *, void *);
33typedef mali_error kbase_instr_hwcnt_enable_type(kbase_context *, kbase_uk_hwcnt_setup *);
34typedef mali_error kbase_instr_hwcnt_disable_type(kbase_context *);
35typedef mali_error kbase_instr_hwcnt_clear_type(kbase_context *);
36typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *);
37typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *);
38
39static kbase_find_device_type * kbase_find_device_symbol;
40static kbase_create_context_type * kbase_create_context_symbol;
41static kbase_va_alloc_type * kbase_va_alloc_symbol;
42static kbase_instr_hwcnt_enable_type * kbase_instr_hwcnt_enable_symbol;
43static kbase_instr_hwcnt_clear_type * kbase_instr_hwcnt_clear_symbol;
44static kbase_instr_hwcnt_dump_irq_type * kbase_instr_hwcnt_dump_irq_symbol;
45static kbase_instr_hwcnt_dump_complete_type * kbase_instr_hwcnt_dump_complete_symbol;
46static kbase_instr_hwcnt_disable_type * kbase_instr_hwcnt_disable_symbol;
47static kbase_va_free_type * kbase_va_free_symbol;
48static kbase_destroy_context_type * kbase_destroy_context_symbol;
49
50/** The interval between reads, in ns. */
51static const int READ_INTERVAL_NSEC = 1000000;
52
53
54#if GATOR_TEST
55#include "gator_events_mali_t6xx_hw_test.c"
56#endif
57
26/* Blocks for HW counters */ 58/* Blocks for HW counters */
27enum 59enum
28{ 60{
@@ -322,7 +354,12 @@ static void *kernel_dump_buffer;
322static kbase_context *kbcontext = NULL; 354static kbase_context *kbcontext = NULL;
323static struct kbase_device *kbdevice = NULL; 355static struct kbase_device *kbdevice = NULL;
324 356
325extern struct kbase_device *kbase_find_device(int minor); 357/*
358 * The following function has no external prototype in older DDK revisions. When the DDK
359 * is updated then this should be removed.
360 */
361struct kbase_device *kbase_find_device(int minor);
362
326static volatile bool kbase_device_busy = false; 363static volatile bool kbase_device_busy = false;
327static unsigned int num_hardware_counters_enabled; 364static unsigned int num_hardware_counters_enabled;
328 365
@@ -336,6 +373,96 @@ static mali_counter counters[NUMBER_OF_HARDWARE_COUNTERS];
336 */ 373 */
337static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2]; 374static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2];
338 375
376#define SYMBOL_GET(FUNCTION, ERROR_COUNT) \
377 if(FUNCTION ## _symbol) \
378 { \
379 printk("gator: mali " #FUNCTION " symbol was already registered\n"); \
380 (ERROR_COUNT)++; \
381 } \
382 else \
383 { \
384 FUNCTION ## _symbol = symbol_get(FUNCTION); \
385 if(! FUNCTION ## _symbol) \
386 { \
387 printk("gator: mali online " #FUNCTION " symbol not found\n"); \
388 (ERROR_COUNT)++; \
389 } \
390 }
391
392#define SYMBOL_CLEANUP(FUNCTION) \
393 if(FUNCTION ## _symbol) \
394 { \
395 symbol_put(FUNCTION); \
396 FUNCTION ## _symbol = NULL; \
397 }
398
399/**
400 * Execute symbol_get for all the Mali symbols and check for success.
401 * @return the number of symbols not loaded.
402 */
403static int init_symbols(void)
404{
405 int error_count = 0;
406 SYMBOL_GET(kbase_find_device, error_count);
407 SYMBOL_GET(kbase_create_context, error_count);
408 SYMBOL_GET(kbase_va_alloc, error_count);
409 SYMBOL_GET(kbase_instr_hwcnt_enable, error_count);
410 SYMBOL_GET(kbase_instr_hwcnt_clear, error_count);
411 SYMBOL_GET(kbase_instr_hwcnt_dump_irq, error_count);
412 SYMBOL_GET(kbase_instr_hwcnt_dump_complete, error_count);
413 SYMBOL_GET(kbase_instr_hwcnt_disable, error_count);
414 SYMBOL_GET(kbase_va_free, error_count);
415 SYMBOL_GET(kbase_destroy_context, error_count);
416
417 return error_count;
418}
419
420/**
421 * Execute symbol_put for all the registered Mali symbols.
422 */
423static void clean_symbols(void)
424{
425 SYMBOL_CLEANUP(kbase_find_device);
426 SYMBOL_CLEANUP(kbase_create_context);
427 SYMBOL_CLEANUP(kbase_va_alloc);
428 SYMBOL_CLEANUP(kbase_instr_hwcnt_enable);
429 SYMBOL_CLEANUP(kbase_instr_hwcnt_clear);
430 SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_irq);
431 SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_complete);
432 SYMBOL_CLEANUP(kbase_instr_hwcnt_disable);
433 SYMBOL_CLEANUP(kbase_va_free);
434 SYMBOL_CLEANUP(kbase_destroy_context);
435}
436
437/**
438 * Determines whether a read should take place
439 * @param current_time The current time, obtained from getnstimeofday()
440 * @param prev_time_s The number of seconds at the previous read attempt.
441 * @param next_read_time_ns The time (in ns) when the next read should be allowed.
442 *
443 * Note that this function has been separated out here to allow it to be tested.
444 */
445static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns)
446{
447 /* If the current ns count rolls over a second, roll the next read time too. */
448 if(current_time->tv_sec != *prev_time_s)
449 {
450 *next_read_time_ns = *next_read_time_ns - NSEC_PER_SEC;
451 }
452
453 /* Abort the read if the next read time has not arrived. */
454 if(current_time->tv_nsec < *next_read_time_ns)
455 {
456 return 0;
457 }
458
459 /* Set the next read some fixed time after this one, and update the read timestamp. */
460 *next_read_time_ns = current_time->tv_nsec + READ_INTERVAL_NSEC;
461
462 *prev_time_s = current_time->tv_sec;
463 return 1;
464}
465
339static int start(void) 466static int start(void)
340{ 467{
341 kbase_uk_hwcnt_setup setup; 468 kbase_uk_hwcnt_setup setup;
@@ -368,12 +495,23 @@ static int start(void)
368 /* Create a kbase context for HW counters */ 495 /* Create a kbase context for HW counters */
369 if (num_hardware_counters_enabled > 0) 496 if (num_hardware_counters_enabled > 0)
370 { 497 {
371 kbdevice = kbase_find_device(-1); 498 if(init_symbols() > 0)
372 499 {
373 if (kbcontext) 500 clean_symbols();
374 return -1; 501 /* No Mali driver code entrypoints found - not a fault. */
375 502 return 0;
376 kbcontext = kbase_create_context(kbdevice); 503 }
504
505 kbdevice = kbase_find_device_symbol(-1);
506
507 /* If we already got a context, fail */
508 if (kbcontext) {
509 pr_debug("gator: Mali-T6xx: error context already present\n");
510 goto out;
511 }
512
513 /* kbcontext will only be valid after all the Mali symbols are loaded successfully */
514 kbcontext = kbase_create_context_symbol(kbdevice);
377 if (!kbcontext) 515 if (!kbcontext)
378 { 516 {
379 pr_debug("gator: Mali-T6xx: error creating kbase context\n"); 517 pr_debug("gator: Mali-T6xx: error creating kbase context\n");
@@ -388,7 +526,7 @@ static int start(void)
388 * * number of bytes per counter (always 4 in midgard) 526 * * number of bytes per counter (always 4 in midgard)
389 * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4 527 * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4
390 */ 528 */
391 kernel_dump_buffer = kbase_va_alloc(kbcontext, 2048); 529 kernel_dump_buffer = kbase_va_alloc_symbol(kbcontext, 2048);
392 if (!kernel_dump_buffer) 530 if (!kernel_dump_buffer)
393 { 531 {
394 pr_debug("gator: Mali-T6xx: error trying to allocate va\n"); 532 pr_debug("gator: Mali-T6xx: error trying to allocate va\n");
@@ -404,14 +542,14 @@ static int start(void)
404 setup.l3_cache_bm = 0; 542 setup.l3_cache_bm = 0;
405 543
406 /* Use kbase API to enable hardware counters and provide dump buffer */ 544 /* Use kbase API to enable hardware counters and provide dump buffer */
407 err = kbase_instr_hwcnt_enable(kbcontext, &setup); 545 err = kbase_instr_hwcnt_enable_symbol(kbcontext, &setup);
408 if (err != MALI_ERROR_NONE) 546 if (err != MALI_ERROR_NONE)
409 { 547 {
410 pr_debug("gator: Mali-T6xx: can't setup hardware counters\n"); 548 pr_debug("gator: Mali-T6xx: can't setup hardware counters\n");
411 goto free_buffer; 549 goto free_buffer;
412 } 550 }
413 pr_debug("gator: Mali-T6xx: hardware counters enabled\n"); 551 pr_debug("gator: Mali-T6xx: hardware counters enabled\n");
414 kbase_instr_hwcnt_clear(kbcontext); 552 kbase_instr_hwcnt_clear_symbol(kbcontext);
415 pr_debug("gator: Mali-T6xx: hardware counters cleared \n"); 553 pr_debug("gator: Mali-T6xx: hardware counters cleared \n");
416 554
417 kbase_device_busy = false; 555 kbase_device_busy = false;
@@ -420,10 +558,13 @@ static int start(void)
420 return 0; 558 return 0;
421 559
422 free_buffer: 560 free_buffer:
423 kbase_va_free(kbcontext, kernel_dump_buffer); 561 kbase_va_free_symbol(kbcontext, kernel_dump_buffer);
562
424 destroy_context: 563 destroy_context:
425 kbase_destroy_context(kbcontext); 564 kbase_destroy_context_symbol(kbcontext);
565
426 out: 566 out:
567 clean_symbols();
427 return -1; 568 return -1;
428} 569}
429 570
@@ -448,10 +589,13 @@ static void stop(void) {
448 temp_kbcontext = kbcontext; 589 temp_kbcontext = kbcontext;
449 kbcontext = NULL; 590 kbcontext = NULL;
450 591
451 kbase_instr_hwcnt_disable(temp_kbcontext); 592 kbase_instr_hwcnt_disable_symbol(temp_kbcontext);
452 kbase_va_free(temp_kbcontext, kernel_dump_buffer); 593 kbase_va_free_symbol(temp_kbcontext, kernel_dump_buffer);
453 kbase_destroy_context(temp_kbcontext); 594 kbase_destroy_context_symbol(temp_kbcontext);
595
454 pr_debug("gator: Mali-T6xx: hardware counters stopped\n"); 596 pr_debug("gator: Mali-T6xx: hardware counters stopped\n");
597
598 clean_symbols();
455 } 599 }
456} 600}
457 601
@@ -461,11 +605,26 @@ static int read(int **buffer) {
461 u32 value = 0; 605 u32 value = 0;
462 mali_bool success; 606 mali_bool success;
463 607
608 struct timespec current_time;
609 static u32 prev_time_s = 0;
610 static s32 next_read_time_ns = 0;
611
464 if (smp_processor_id()!=0) 612 if (smp_processor_id()!=0)
465 { 613 {
466 return 0; 614 return 0;
467 } 615 }
468 616
617 getnstimeofday(&current_time);
618
619 /*
620 * Discard reads unless a respectable time has passed. This reduces the load on the GPU without sacrificing
621 * accuracy on the Streamline display.
622 */
623 if(!is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns))
624 {
625 return 0;
626 }
627
469 /* 628 /*
470 * Report the HW counters 629 * Report the HW counters
471 * Only process hardware counters if at least one of the hardware counters is enabled. 630 * Only process hardware counters if at least one of the hardware counters is enabled.
@@ -484,8 +643,8 @@ static int read(int **buffer) {
484 return -1; 643 return -1;
485 } 644 }
486 645
487 // TODO: SYMBOL_GET (all kbase functions) 646 /* Mali symbols can be called safely since a kbcontext is valid */
488 if (kbase_instr_hwcnt_dump_complete(kbcontext, &success) == MALI_TRUE) 647 if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE)
489 { 648 {
490 kbase_device_busy = false; 649 kbase_device_busy = false;
491 650
@@ -520,7 +679,7 @@ static int read(int **buffer) {
520 if (! kbase_device_busy) 679 if (! kbase_device_busy)
521 { 680 {
522 kbase_device_busy = true; 681 kbase_device_busy = true;
523 kbase_instr_hwcnt_dump_irq(kbcontext); 682 kbase_instr_hwcnt_dump_irq_symbol(kbcontext);
524 } 683 }
525 } 684 }
526 685
@@ -551,7 +710,6 @@ static int create_files(struct super_block *sb, struct dentry *root)
551 return 0; 710 return 0;
552} 711}
553 712
554
555static struct gator_interface gator_events_mali_t6xx_interface = { 713static struct gator_interface gator_events_mali_t6xx_interface = {
556 .create_files = create_files, 714 .create_files = create_files,
557 .start = start, 715 .start = start,
@@ -563,6 +721,10 @@ int gator_events_mali_t6xx_hw_init(void)
563{ 721{
564 pr_debug("gator: Mali-T6xx: sw_counters init\n"); 722 pr_debug("gator: Mali-T6xx: sw_counters init\n");
565 723
724#if GATOR_TEST
725 test_all_is_read_scheduled();
726#endif
727
566 gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS); 728 gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS);
567 729
568 return gator_events_install(&gator_events_mali_t6xx_interface); 730 return gator_events_install(&gator_events_mali_t6xx_interface);
diff --git a/driver/gator_events_mali_t6xx_hw_test.c b/driver/gator_events_mali_t6xx_hw_test.c
new file mode 100644
index 0000000..2a35e77
--- /dev/null
+++ b/driver/gator_events_mali_t6xx_hw_test.c
@@ -0,0 +1,57 @@
1/**
2 * Copyright (C) ARM Limited 2012. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 */
9
10/**
11 * Test functions for mali_t600_hw code.
12 */
13
14static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns);
15
16static int test_is_read_scheduled(u32 s, u32 ns, u32 prev_s, s32 next_ns, int expected_result, s32 expected_next_ns)
17{
18 struct timespec current_time;
19 u32 prev_time_s = prev_s;
20 s32 next_read_time_ns = next_ns;
21
22 current_time.tv_sec = s;
23 current_time.tv_nsec = ns;
24
25 if(is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns) != expected_result)
26 {
27 printk("Failed do_read(%u, %u, %u, %d): expected %d\n", s, ns, prev_s, next_ns, expected_result);
28 return 0;
29 }
30
31 if(next_read_time_ns != expected_next_ns)
32 {
33 printk("Failed: next_read_ns expected=%d, actual=%d\n", expected_next_ns, next_read_time_ns);
34 return 0;
35 }
36
37 return 1;
38}
39
40static void test_all_is_read_scheduled(void)
41{
42 const int HIGHEST_NS = 999999999;
43 int n_tests_passed = 0;
44
45 printk("gator: running tests on %s\n", __FILE__);
46
47 n_tests_passed += test_is_read_scheduled(0,0,0,0, 1, READ_INTERVAL_NSEC); /* Null time */
48 n_tests_passed += test_is_read_scheduled(100,1000,0,0, 1, READ_INTERVAL_NSEC + 1000); /* Initial values */
49
50 n_tests_passed += test_is_read_scheduled(100, HIGHEST_NS, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500);
51 n_tests_passed += test_is_read_scheduled(101, 0001, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500 - NSEC_PER_SEC);
52 n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500 - NSEC_PER_SEC, 1, 600 + READ_INTERVAL_NSEC);
53
54 n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500, 1, 600 + READ_INTERVAL_NSEC);
55
56 printk("gator: %d tests passed\n", n_tests_passed);
57}
diff --git a/driver/gator_events_mmaped.c b/driver/gator_events_mmaped.c
index f81c402..1be6e66 100644
--- a/driver/gator_events_mmaped.c
+++ b/driver/gator_events_mmaped.c
@@ -11,12 +11,8 @@
11 * To add them to the events.xml, create an events-mmap.xml with the 11 * To add them to the events.xml, create an events-mmap.xml with the
12 * following contents and rebuild gatord: 12 * following contents and rebuild gatord:
13 * 13 *
14 * <counter_set name="mmaped_cntX"> 14 * <counter_set name="mmaped_cnt" count="3"/>
15 * <counter name="mmaped_cnt0"/> 15 * <category name="mmaped" counter_set="mmaped_cnt" per_cpu="no">
16 * <counter name="mmaped_cnt1"/>
17 * <counter name="mmaped_cnt2"/>
18 * </counter_set>
19 * <category name="mmaped" counter_set="mmaped_cntX" per_cpu="no">
20 * <event event="0x0" title="Simulated" name="Sine" display="maximum" average_selection="yes" description="Sort-of-sine"/> 16 * <event event="0x0" title="Simulated" name="Sine" display="maximum" average_selection="yes" description="Sort-of-sine"/>
21 * <event event="0x1" title="Simulated" name="Triangle" display="maximum" average_selection="yes" description="Triangular wave"/> 17 * <event event="0x1" title="Simulated" name="Triangle" display="maximum" average_selection="yes" description="Triangular wave"/>
22 * <event event="0x2" title="Simulated" name="PWM" display="maximum" average_selection="yes" description="PWM Signal"/> 18 * <event event="0x2" title="Simulated" name="PWM" display="maximum" average_selection="yes" description="PWM Signal"/>
diff --git a/driver/gator_events_net.c b/driver/gator_events_net.c
index 11282b5..31cc3ef 100644
--- a/driver/gator_events_net.c
+++ b/driver/gator_events_net.c
@@ -95,7 +95,11 @@ static int gator_events_net_start(void)
95 get_network_stats(0); 95 get_network_stats(0);
96 netPrev[NETRX] = rx_total; 96 netPrev[NETRX] = rx_total;
97 netPrev[NETTX] = tx_total; 97 netPrev[NETTX] = tx_total;
98#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
98 setup_timer(&net_wake_up_timer, net_wake_up_handler, 0); 99 setup_timer(&net_wake_up_timer, net_wake_up_handler, 0);
100#else
101 setup_deferrable_timer_on_stack(&net_wake_up_timer, net_wake_up_handler, 0);
102#endif
99 return 0; 103 return 0;
100} 104}
101 105
diff --git a/driver/gator_events_perf_pmu.c b/driver/gator_events_perf_pmu.c
index 9d78b46..e025155 100644
--- a/driver/gator_events_perf_pmu.c
+++ b/driver/gator_events_perf_pmu.c
@@ -32,7 +32,6 @@ static DEFINE_PER_CPU(int[CNTMAX], perfPrevDelta);
32static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt); 32static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt);
33static DEFINE_PER_CPU(struct perf_event *[CNTMAX], pevent); 33static DEFINE_PER_CPU(struct perf_event *[CNTMAX], pevent);
34static DEFINE_PER_CPU(struct perf_event_attr *[CNTMAX], pevent_attr); 34static DEFINE_PER_CPU(struct perf_event_attr *[CNTMAX], pevent_attr);
35extern DEFINE_PER_CPU(struct perf_event *, pevent_ebs);
36 35
37static void gator_events_perf_pmu_stop(void); 36static void gator_events_perf_pmu_stop(void);
38 37
@@ -64,6 +63,15 @@ static int gator_events_perf_pmu_create_files(struct super_block *sb, struct den
64} 63}
65 64
66#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) 65#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
66static void ebs_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs)
67#else
68static void ebs_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs)
69#endif
70{
71 gator_backtrace_handler(regs);
72}
73
74#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
67static void dummy_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs) 75static void dummy_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs)
68#else 76#else
69static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) 77static void dummy_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs)
@@ -75,15 +83,10 @@ static void dummy_handler(struct perf_event *event, struct perf_sample_data *dat
75static int gator_events_perf_pmu_online(int** buffer) 83static int gator_events_perf_pmu_online(int** buffer)
76{ 84{
77 int cnt, len = 0, cpu = smp_processor_id(); 85 int cnt, len = 0, cpu = smp_processor_id();
78 struct perf_event * ev;
79 86
80 // read the counters and toss the invalid data, return zero instead 87 // read the counters and toss the invalid data, return zero instead
81 for (cnt = 0; cnt < pmnc_counters; cnt++) { 88 for (cnt = 0; cnt < pmnc_counters; cnt++) {
82 if (pmnc_count[cnt] > 0) { 89 struct perf_event * ev = per_cpu(pevent, cpu)[cnt];
83 ev = per_cpu(pevent_ebs, cpu); // special case for EBS
84 } else {
85 ev = per_cpu(pevent, cpu)[cnt];
86 }
87 if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) { 90 if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
88 ev->pmu->read(ev); 91 ev->pmu->read(ev);
89 per_cpu(perfPrev, cpu)[cnt] = per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count); 92 per_cpu(perfPrev, cpu)[cnt] = per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count);
@@ -102,18 +105,22 @@ static int gator_events_perf_pmu_online(int** buffer)
102static void gator_events_perf_pmu_online_dispatch(int cpu) 105static void gator_events_perf_pmu_online_dispatch(int cpu)
103{ 106{
104 int cnt; 107 int cnt;
108 perf_overflow_handler_t handler;
105 109
106 for (cnt = 0; cnt < pmnc_counters; cnt++) { 110 for (cnt = 0; cnt < pmnc_counters; cnt++) {
107 if (per_cpu(pevent, cpu)[cnt] != NULL || per_cpu(pevent_attr, cpu)[cnt] == 0) 111 if (per_cpu(pevent, cpu)[cnt] != NULL || per_cpu(pevent_attr, cpu)[cnt] == 0)
108 continue; 112 continue;
109 113
110 if (pmnc_count[cnt] > 0) 114 if (pmnc_count[cnt] > 0) {
111 continue; // skip the EBS counter 115 handler = ebs_overflow_handler;
116 } else {
117 handler = dummy_handler;
118 }
112 119
113#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) 120#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
114 per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, dummy_handler); 121 per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, handler);
115#else 122#else
116 per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, dummy_handler, 0); 123 per_cpu(pevent, cpu)[cnt] = perf_event_create_kernel_counter(per_cpu(pevent_attr, cpu)[cnt], cpu, 0, handler, 0);
117#endif 124#endif
118 if (IS_ERR(per_cpu(pevent, cpu)[cnt])) { 125 if (IS_ERR(per_cpu(pevent, cpu)[cnt])) {
119 pr_debug("gator: unable to online a counter on cpu %d\n", cpu); 126 pr_debug("gator: unable to online a counter on cpu %d\n", cpu);
@@ -154,6 +161,18 @@ static int gator_events_perf_pmu_start(void)
154{ 161{
155 int cnt, cpu; 162 int cnt, cpu;
156 u32 size = sizeof(struct perf_event_attr); 163 u32 size = sizeof(struct perf_event_attr);
164 int found_ebs = false;
165
166 for (cnt = 0; cnt < pmnc_counters; cnt++) {
167 if (pmnc_count[cnt] > 0) {
168 if (!found_ebs) {
169 found_ebs = true;
170 } else {
171 // Only one ebs counter is allowed
172 return -1;
173 }
174 }
175 }
157 176
158 for_each_present_cpu(cpu) { 177 for_each_present_cpu(cpu) {
159 for (cnt = 0; cnt < pmnc_counters; cnt++) { 178 for (cnt = 0; cnt < pmnc_counters; cnt++) {
@@ -174,7 +193,7 @@ static int gator_events_perf_pmu_start(void)
174 per_cpu(pevent_attr, cpu)[cnt]->type = PERF_TYPE_RAW; 193 per_cpu(pevent_attr, cpu)[cnt]->type = PERF_TYPE_RAW;
175 per_cpu(pevent_attr, cpu)[cnt]->size = size; 194 per_cpu(pevent_attr, cpu)[cnt]->size = size;
176 per_cpu(pevent_attr, cpu)[cnt]->config = pmnc_event[cnt]; 195 per_cpu(pevent_attr, cpu)[cnt]->config = pmnc_event[cnt];
177 per_cpu(pevent_attr, cpu)[cnt]->sample_period = 0; 196 per_cpu(pevent_attr, cpu)[cnt]->sample_period = pmnc_count[cnt];
178 per_cpu(pevent_attr, cpu)[cnt]->pinned = 1; 197 per_cpu(pevent_attr, cpu)[cnt]->pinned = 1;
179 198
180 // handle special case for ccnt 199 // handle special case for ccnt
@@ -212,14 +231,9 @@ static int gator_events_perf_pmu_read(int **buffer)
212{ 231{
213 int cnt, delta, len = 0; 232 int cnt, delta, len = 0;
214 int cpu = smp_processor_id(); 233 int cpu = smp_processor_id();
215 struct perf_event * ev;
216 234
217 for (cnt = 0; cnt < pmnc_counters; cnt++) { 235 for (cnt = 0; cnt < pmnc_counters; cnt++) {
218 if (pmnc_count[cnt] > 0) { 236 struct perf_event * ev = per_cpu(pevent, cpu)[cnt];
219 ev = per_cpu(pevent_ebs, cpu); // special case for EBS
220 } else {
221 ev = per_cpu(pevent, cpu)[cnt];
222 }
223 if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) { 237 if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
224 ev->pmu->read(ev); 238 ev->pmu->read(ev);
225 per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count); 239 per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count);
@@ -300,6 +314,11 @@ int gator_events_perf_pmu_init(void)
300 pmnc_name = "Krait"; 314 pmnc_name = "Krait";
301 pmnc_counters = 4; 315 pmnc_counters = 4;
302 break; 316 break;
317 case AARCH64:
318 pmnc_name = "ARM_AArch64";
319 // Copied from A15, get the correct number
320 pmnc_counters = 6;
321 break;
303 default: 322 default:
304 return -1; 323 return -1;
305 } 324 }
diff --git a/driver/gator_main.c b/driver/gator_main.c
index f6c1135..309c6c2 100644
--- a/driver/gator_main.c
+++ b/driver/gator_main.c
@@ -7,7 +7,7 @@
7 * 7 *
8 */ 8 */
9 9
10static unsigned long gator_protocol_version = 10; 10static unsigned long gator_protocol_version = 11;
11 11
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/cpu.h> 13#include <linux/cpu.h>
@@ -48,50 +48,74 @@ static unsigned long gator_protocol_version = 10;
48 48
49#if (GATOR_PERF_SUPPORT) && (!(GATOR_PERF_PMU_SUPPORT)) 49#if (GATOR_PERF_SUPPORT) && (!(GATOR_PERF_PMU_SUPPORT))
50#ifndef CONFIG_PERF_EVENTS 50#ifndef CONFIG_PERF_EVENTS
51#warning gator requires the kernel to have CONFIG_PERF_EVENTS defined to support pmu hardware counters 51#error gator requires the kernel to have CONFIG_PERF_EVENTS defined to support pmu hardware counters
52#elif !defined CONFIG_HW_PERF_EVENTS 52#elif !defined CONFIG_HW_PERF_EVENTS
53#warning gator requires the kernel to have CONFIG_HW_PERF_EVENTS defined to support pmu hardware counters 53#error gator requires the kernel to have CONFIG_HW_PERF_EVENTS defined to support pmu hardware counters
54#endif 54#endif
55#endif 55#endif
56 56
57/****************************************************************************** 57/******************************************************************************
58 * DEFINES 58 * DEFINES
59 ******************************************************************************/ 59 ******************************************************************************/
60#define BACKTRACE_BUFFER_SIZE (128*1024) 60#define SUMMARY_BUFFER_SIZE (1*1024)
61#define COUNTER_BUFFER_SIZE (128*1024) 61#define BACKTRACE_BUFFER_SIZE (128*1024)
62#define ANNOTATE_BUFFER_SIZE (64*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded 62#define NAME_BUFFER_SIZE (64*1024)
63#define SCHED_TRACE_BUFFER_SIZE (128*1024) 63#define COUNTER_BUFFER_SIZE (64*1024) // counters have the core as part of the data and the core value in the frame header may be discarded
64#define GPU_TRACE_BUFFER_SIZE (64*1024) 64#define BLOCK_COUNTER_BUFFER_SIZE (128*1024)
65#define COUNTER2_BUFFER_SIZE (64*1024) // counters2 counters have the core as part of the data and the core value in the frame header may be discarded 65#define ANNOTATE_BUFFER_SIZE (64*1024) // annotate counters have the core as part of the data and the core value in the frame header may be discarded
66#define WFI_BUFFER_SIZE (32*1024) // wfi counters have the core as part of the data and the core value in the frame header may be discarded 66#define SCHED_TRACE_BUFFER_SIZE (128*1024)
67 67#define GPU_TRACE_BUFFER_SIZE (64*1024) // gpu trace counters have the core as part of the data and the core value in the frame header may be discarded
68#define NO_COOKIE 0UL 68#define IDLE_BUFFER_SIZE (32*1024) // idle counters have the core as part of the data and the core value in the frame header may be discarded
69#define INVALID_COOKIE ~0UL 69
70 70#define NO_COOKIE 0U
71#define FRAME_BACKTRACE 1 71#define INVALID_COOKIE ~0U
72#define FRAME_COUNTER 2 72
73#define FRAME_ANNOTATE 3 73#define FRAME_SUMMARY 1
74#define FRAME_SCHED_TRACE 4 74#define FRAME_BACKTRACE 2
75#define FRAME_GPU_TRACE 5 75#define FRAME_NAME 3
76#define FRAME_COUNTER2 6 76#define FRAME_COUNTER 4
77#define FRAME_WFI 7 77#define FRAME_BLOCK_COUNTER 5
78 78#define FRAME_ANNOTATE 6
79#define MESSAGE_COOKIE 1 79#define FRAME_SCHED_TRACE 7
80#define MESSAGE_START_BACKTRACE 5 80#define FRAME_GPU_TRACE 8
81#define MESSAGE_END_BACKTRACE 7 81#define FRAME_IDLE 9
82#define MESSAGE_SUMMARY 9 82
83#define MESSAGE_PID_NAME 11 83#define MESSAGE_END_BACKTRACE 1
84 84
85#define MAXSIZE_PACK32 5 85#define MESSAGE_COOKIE 1
86#define MAXSIZE_PACK64 9 86#define MESSAGE_THREAD_NAME 2
87#define HRTIMER_CORE_NAME 3
88
89#define MESSAGE_GPU_START 1
90#define MESSAGE_GPU_STOP 2
91
92#define MESSAGE_SCHED_SWITCH 1
93#define MESSAGE_SCHED_EXIT 2
94
95#define MAXSIZE_PACK32 5
96#define MAXSIZE_PACK64 10
97#define MAXSIZE_CORE_NAME 32
87 98
88#if defined(__arm__) 99#if defined(__arm__)
89#define PC_REG regs->ARM_pc 100#define PC_REG regs->ARM_pc
101#elif defined(__aarch64__)
102#define PC_REG regs->pc
90#else 103#else
91#define PC_REG regs->ip 104#define PC_REG regs->ip
92#endif 105#endif
93 106
94enum {BACKTRACE_BUF, COUNTER_BUF, SCHED_TRACE_BUF, GPU_TRACE_BUF, ANNOTATE_BUF, COUNTER2_BUF, WFI_BUF, NUM_GATOR_BUFS}; 107enum {
108 SUMMARY_BUF,
109 BACKTRACE_BUF,
110 NAME_BUF,
111 COUNTER_BUF,
112 BLOCK_COUNTER_BUF,
113 ANNOTATE_BUF,
114 SCHED_TRACE_BUF,
115 GPU_TRACE_BUF,
116 IDLE_BUF,
117 NUM_GATOR_BUFS
118};
95 119
96/****************************************************************************** 120/******************************************************************************
97 * Globals 121 * Globals
@@ -101,17 +125,13 @@ static unsigned long userspace_buffer_size;
101static unsigned long gator_backtrace_depth; 125static unsigned long gator_backtrace_depth;
102 126
103static unsigned long gator_started; 127static unsigned long gator_started;
128static uint64_t monotonic_started;
104static unsigned long gator_buffer_opened; 129static unsigned long gator_buffer_opened;
105static unsigned long gator_timer_count; 130static unsigned long gator_timer_count;
106static unsigned long gator_response_type; 131static unsigned long gator_response_type;
107static DEFINE_MUTEX(start_mutex); 132static DEFINE_MUTEX(start_mutex);
108static DEFINE_MUTEX(gator_buffer_mutex); 133static DEFINE_MUTEX(gator_buffer_mutex);
109 134
110bool event_based_sampling;
111#if defined(__arm__) && (GATOR_PERF_PMU_SUPPORT)
112DEFINE_PER_CPU(struct perf_event *, pevent_ebs);
113#endif
114
115static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait); 135static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait);
116static struct timer_list gator_buffer_wake_up_timer; 136static struct timer_list gator_buffer_wake_up_timer;
117static LIST_HEAD(gator_events); 137static LIST_HEAD(gator_events);
@@ -125,10 +145,10 @@ static bool buffer_check_space(int cpu, int buftype, int bytes);
125static int contiguous_space_available(int cpu, int bufytpe); 145static int contiguous_space_available(int cpu, int bufytpe);
126static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x); 146static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x);
127static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long long x); 147static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long long x);
128static void gator_buffer_write_bytes(int cpu, int buftype, char *x, int len); 148static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len);
129static void gator_buffer_write_string(int cpu, int buftype, char *x); 149static void gator_buffer_write_string(int cpu, int buftype, const char *x);
130static void gator_add_trace(int cpu, int buftype, unsigned int address); 150static void gator_add_trace(int cpu, unsigned long address);
131static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs); 151static void gator_add_sample(int cpu, struct pt_regs * const regs);
132static uint64_t gator_get_time(void); 152static uint64_t gator_get_time(void);
133 153
134static uint32_t gator_buffer_size[NUM_GATOR_BUFS]; 154static uint32_t gator_buffer_size[NUM_GATOR_BUFS];
@@ -152,17 +172,20 @@ static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer);
152#include "gator_backtrace.c" 172#include "gator_backtrace.c"
153#include "gator_annotate.c" 173#include "gator_annotate.c"
154#include "gator_fs.c" 174#include "gator_fs.c"
155#include "gator_ebs.c"
156#include "gator_pack.c" 175#include "gator_pack.c"
157 176
158/****************************************************************************** 177/******************************************************************************
159 * Misc 178 * Misc
160 ******************************************************************************/ 179 ******************************************************************************/
161#if defined(__arm__) 180#if defined(__arm__) || defined(__aarch64__)
162u32 gator_cpuid(void) 181u32 gator_cpuid(void)
163{ 182{
164 u32 val; 183 u32 val;
184#if !defined(__aarch64__)
165 asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (val)); 185 asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (val));
186#else
187 asm volatile("mrs %0, midr_el1" : "=r" (val));
188#endif
166 return (val >> 4) & 0xfff; 189 return (val >> 4) & 0xfff;
167} 190}
168#endif 191#endif
@@ -237,7 +260,7 @@ static bool buffer_check_space(int cpu, int buftype, int bytes)
237 return per_cpu(buffer_space_available, cpu)[buftype]; 260 return per_cpu(buffer_space_available, cpu)[buftype];
238} 261}
239 262
240static void gator_buffer_write_bytes(int cpu, int buftype, char *x, int len) 263static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len)
241{ 264{
242 int i; 265 int i;
243 u32 write = per_cpu(gator_buffer_write, cpu)[buftype]; 266 u32 write = per_cpu(gator_buffer_write, cpu)[buftype];
@@ -252,7 +275,7 @@ static void gator_buffer_write_bytes(int cpu, int buftype, char *x, int len)
252 per_cpu(gator_buffer_write, cpu)[buftype] = write; 275 per_cpu(gator_buffer_write, cpu)[buftype] = write;
253} 276}
254 277
255static void gator_buffer_write_string(int cpu, int buftype, char *x) 278static void gator_buffer_write_string(int cpu, int buftype, const char *x)
256{ 279{
257 int len = strlen(x); 280 int len = strlen(x);
258 gator_buffer_write_packed_int(cpu, buftype, len); 281 gator_buffer_write_packed_int(cpu, buftype, len);
@@ -263,22 +286,38 @@ static void gator_buffer_header(int cpu, int buftype)
263{ 286{
264 int frame; 287 int frame;
265 288
266 if (buftype == BACKTRACE_BUF) 289 switch (buftype) {
290 case SUMMARY_BUF:
291 frame = FRAME_SUMMARY;
292 break;
293 case BACKTRACE_BUF:
267 frame = FRAME_BACKTRACE; 294 frame = FRAME_BACKTRACE;
268 else if (buftype == COUNTER_BUF) 295 break;
296 case NAME_BUF:
297 frame = FRAME_NAME;
298 break;
299 case COUNTER_BUF:
269 frame = FRAME_COUNTER; 300 frame = FRAME_COUNTER;
270 else if (buftype == ANNOTATE_BUF) 301 break;
302 case BLOCK_COUNTER_BUF:
303 frame = FRAME_BLOCK_COUNTER;
304 break;
305 case ANNOTATE_BUF:
271 frame = FRAME_ANNOTATE; 306 frame = FRAME_ANNOTATE;
272 else if (buftype == SCHED_TRACE_BUF) 307 break;
308 case SCHED_TRACE_BUF:
273 frame = FRAME_SCHED_TRACE; 309 frame = FRAME_SCHED_TRACE;
274 else if (buftype == GPU_TRACE_BUF) 310 break;
311 case GPU_TRACE_BUF:
275 frame = FRAME_GPU_TRACE; 312 frame = FRAME_GPU_TRACE;
276 else if (buftype == COUNTER2_BUF) 313 break;
277 frame = FRAME_COUNTER2; 314 case IDLE_BUF:
278 else if (buftype == WFI_BUF) 315 frame = FRAME_IDLE;
279 frame = FRAME_WFI; 316 break;
280 else 317 default:
281 frame = -1; 318 frame = -1;
319 break;
320 }
282 321
283 if (per_cpu(gator_buffer, cpu)[buftype]) { 322 if (per_cpu(gator_buffer, cpu)[buftype]) {
284 marshal_frame(cpu, buftype, frame); 323 marshal_frame(cpu, buftype, frame);
@@ -308,10 +347,10 @@ static void buffer_check(int cpu, int buftype)
308 } 347 }
309} 348}
310 349
311static void gator_add_trace(int cpu, int buftype, unsigned int address) 350static void gator_add_trace(int cpu, unsigned long address)
312{ 351{
313 off_t offset = 0; 352 off_t offset = 0;
314 unsigned long cookie = get_address_cookie(cpu, buftype, current, address & ~1, &offset); 353 unsigned long cookie = get_address_cookie(cpu, current, address & ~1, &offset);
315 354
316 if (cookie == NO_COOKIE || cookie == INVALID_COOKIE) { 355 if (cookie == NO_COOKIE || cookie == INVALID_COOKIE) {
317 offset = address; 356 offset = address;
@@ -320,26 +359,29 @@ static void gator_add_trace(int cpu, int buftype, unsigned int address)
320 marshal_backtrace(offset & ~1, cookie); 359 marshal_backtrace(offset & ~1, cookie);
321} 360}
322 361
323static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs) 362static void gator_add_sample(int cpu, struct pt_regs * const regs)
324{ 363{
325 int inKernel = regs ? !user_mode(regs) : 1; 364 bool inKernel;
326 unsigned long exec_cookie = inKernel ? NO_COOKIE : get_exec_cookie(cpu, buftype, current); 365 unsigned long exec_cookie;
327 366
328 if (!regs) 367 if (!regs)
329 return; 368 return;
330 369
370 inKernel = !user_mode(regs);
371 exec_cookie = get_exec_cookie(cpu, current);
372
331 if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, inKernel)) 373 if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, inKernel))
332 return; 374 return;
333 375
334 if (inKernel) { 376 if (inKernel) {
335 kernel_backtrace(cpu, buftype, regs); 377 kernel_backtrace(cpu, regs);
336 } else { 378 } else {
337 // Cookie+PC 379 // Cookie+PC
338 gator_add_trace(cpu, buftype, PC_REG); 380 gator_add_trace(cpu, PC_REG);
339 381
340 // Backtrace 382 // Backtrace
341 if (gator_backtrace_depth) 383 if (gator_backtrace_depth)
342 arm_backtrace_eabi(cpu, buftype, regs, gator_backtrace_depth); 384 arm_backtrace_eabi(cpu, regs, gator_backtrace_depth);
343 } 385 }
344 386
345 marshal_backtrace_footer(); 387 marshal_backtrace_footer();
@@ -351,13 +393,20 @@ static void gator_add_sample(int cpu, int buftype, struct pt_regs * const regs)
351static void gator_timer_interrupt(void) 393static void gator_timer_interrupt(void)
352{ 394{
353 struct pt_regs * const regs = get_irq_regs(); 395 struct pt_regs * const regs = get_irq_regs();
396 gator_backtrace_handler(regs);
397}
398
399void gator_backtrace_handler(struct pt_regs * const regs)
400{
354 int cpu = smp_processor_id(); 401 int cpu = smp_processor_id();
355 402
356 // Output backtrace 403 // Output backtrace
357 gator_add_sample(cpu, BACKTRACE_BUF, regs); 404 gator_add_sample(cpu, regs);
358 405
359 // Collect counters 406 // Collect counters
360 collect_counters(); 407 if (!per_cpu(collecting, cpu)) {
408 collect_counters();
409 }
361} 410}
362 411
363static int gator_running; 412static int gator_running;
@@ -397,8 +446,6 @@ static void gator_timer_offline_dispatch(int cpu)
397 list_for_each_entry(gi, &gator_events, list) 446 list_for_each_entry(gi, &gator_events, list)
398 if (gi->offline_dispatch) 447 if (gi->offline_dispatch)
399 gi->offline_dispatch(cpu); 448 gi->offline_dispatch(cpu);
400
401 gator_event_sampling_offline_dispatch(cpu);
402} 449}
403 450
404static void gator_timer_stop(void) 451static void gator_timer_stop(void)
@@ -436,6 +483,32 @@ static void gator_timer_online(void* unused)
436 } 483 }
437 484
438 gator_hrtimer_online(cpu); 485 gator_hrtimer_online(cpu);
486#if defined(__arm__) || defined(__aarch64__)
487 {
488 const char * core_name = NULL;
489
490 // String lengths must be less than MAXSIZE_CORE_NAME
491 switch (gator_cpuid()) {
492 case ARM1136: core_name = "ARM1136"; break;
493 case ARM1156: core_name = "ARM1156"; break;
494 case ARM1176: core_name = "ARM1176"; break;
495 case ARM11MPCORE: core_name = "ARM11MPCore"; break;
496 case CORTEX_A5: core_name = "Cortex-A5"; break;
497 case CORTEX_A7: core_name = "Cortex-A7"; break;
498 case CORTEX_A8: core_name = "Cortex-A8"; break;
499 case CORTEX_A9: core_name = "Cortex-A9"; break;
500 case CORTEX_A15: core_name = "Cortex-A15"; break;
501 case SCORPION: core_name = "Scorpion"; break;
502 case SCORPIONMP: core_name = "ScorpionMP"; break;
503 case KRAITSIM: core_name = "KraitSIM"; break;
504 case KRAIT: core_name = "Krait"; break;
505 case AARCH64: core_name = "AArch64"; break;
506 default: core_name = "Unknown"; break;
507 }
508
509 marshal_core_name(core_name);
510 }
511#endif
439} 512}
440 513
441// This function runs in interrupt context and may be running on a core other than core 'cpu' 514// This function runs in interrupt context and may be running on a core other than core 'cpu'
@@ -446,8 +519,6 @@ static void gator_timer_online_dispatch(int cpu)
446 list_for_each_entry(gi, &gator_events, list) 519 list_for_each_entry(gi, &gator_events, list)
447 if (gi->online_dispatch) 520 if (gi->online_dispatch)
448 gi->online_dispatch(cpu); 521 gi->online_dispatch(cpu);
449
450 gator_event_sampling_online_dispatch(cpu);
451} 522}
452 523
453int gator_timer_start(unsigned long sample_rate) 524int gator_timer_start(unsigned long sample_rate)
@@ -461,10 +532,6 @@ int gator_timer_start(unsigned long sample_rate)
461 532
462 gator_running = 1; 533 gator_running = 1;
463 534
464 // event based sampling trumps hr timer based sampling
465 if (event_based_sampling)
466 sample_rate = 0;
467
468 if (gator_hrtimer_init(sample_rate, gator_timer_interrupt) == -1) 535 if (gator_hrtimer_init(sample_rate, gator_timer_interrupt) == -1)
469 return -1; 536 return -1;
470 537
@@ -481,8 +548,9 @@ static uint64_t gator_get_time(void)
481 struct timespec ts; 548 struct timespec ts;
482 uint64_t timestamp; 549 uint64_t timestamp;
483 550
484 getnstimeofday(&ts); 551 //getnstimeofday(&ts);
485 timestamp = timespec_to_ns(&ts); 552 do_posix_clock_monotonic_gettime(&ts);
553 timestamp = timespec_to_ns(&ts) - monotonic_started;
486 554
487 return timestamp; 555 return timestamp;
488} 556}
@@ -568,20 +636,15 @@ static void gator_notifier_stop(void)
568 ******************************************************************************/ 636 ******************************************************************************/
569static void gator_summary(void) 637static void gator_summary(void)
570{ 638{
571 uint64_t timestamp, uptime = 0; 639 uint64_t timestamp;
572 struct timespec uptime_ts; 640 struct timespec uptime_ts;
573 void (*m2b)(struct timespec *ts);
574 641
575 timestamp = gator_get_time(); 642 timestamp = gator_get_time();
576 643
577 do_posix_clock_monotonic_gettime(&uptime_ts); 644 do_posix_clock_monotonic_gettime(&uptime_ts);
578 m2b = symbol_get(monotonic_to_bootbased); 645 monotonic_started = timespec_to_ns(&uptime_ts);
579 if (m2b) {
580 m2b(&uptime_ts);
581 uptime = (long long)uptime_ts.tv_sec * 1000000000 + uptime_ts.tv_nsec;
582 }
583 646
584 marshal_summary(timestamp, uptime); 647 marshal_summary(timestamp, monotonic_started);
585} 648}
586 649
587int gator_events_install(struct gator_interface *interface) 650int gator_events_install(struct gator_interface *interface)
@@ -656,8 +719,6 @@ static int gator_start(void)
656 goto power_failure; 719 goto power_failure;
657 if (gator_trace_gpu_start()) 720 if (gator_trace_gpu_start())
658 goto gpu_failure; 721 goto gpu_failure;
659 if (gator_event_sampling_start())
660 goto event_sampling_failure;
661 if (gator_timer_start(gator_timer_count)) 722 if (gator_timer_start(gator_timer_count))
662 goto timer_failure; 723 goto timer_failure;
663 if (gator_notifier_start()) 724 if (gator_notifier_start())
@@ -668,8 +729,6 @@ static int gator_start(void)
668notifier_failure: 729notifier_failure:
669 gator_timer_stop(); 730 gator_timer_stop();
670