aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew Richardson <drew.richardson@arm.com>2012-12-14 12:00:00 -0800
committerDrew Richardson <drew.richardson@arm.com>2014-12-19 15:33:02 -0800
commita01058e248133bb7c1ba0238ab380e4fac924e97 (patch)
tree8fc08c126fcb711fc9a2011eb6314c68d429b800
parentb04e8aefeed42f23955e88c7aa1611e49bdf5909 (diff)
downloadgator-a01058e248133bb7c1ba0238ab380e4fac924e97.tar.gz
gator: Version 5.135.13
Signed-off-by: Drew Richardson <drew.richardson@arm.com>
-rw-r--r--.gitignore1
-rw-r--r--daemon/Android.mk14
-rw-r--r--daemon/CapturedXML.cpp41
-rw-r--r--daemon/CapturedXML.h2
-rw-r--r--daemon/Collector.cpp2
-rw-r--r--daemon/ConfigurationXML.cpp6
-rw-r--r--daemon/Fifo.cpp16
-rw-r--r--daemon/Fifo.h12
-rw-r--r--daemon/LocalCapture.cpp4
-rw-r--r--daemon/Logging.h2
-rw-r--r--daemon/Makefile42
-rw-r--r--daemon/OlySocket.cpp362
-rw-r--r--daemon/OlySocket.h40
-rw-r--r--daemon/OlyUtility.cpp361
-rw-r--r--daemon/OlyUtility.h28
-rw-r--r--daemon/Sender.cpp4
-rw-r--r--daemon/SessionData.cpp1
-rw-r--r--daemon/SessionData.h2
-rw-r--r--daemon/SessionXML.cpp2
-rw-r--r--daemon/StreamlineSetup.cpp2
-rw-r--r--daemon/escape.c63
-rw-r--r--daemon/events-Cortex-A15.xml2
-rw-r--r--daemon/events-Cortex-A53.xml171
-rw-r--r--daemon/events-Cortex-A57.xml171
-rw-r--r--daemon/events-Cortex-A7.xml2
-rw-r--r--daemon/events-Cortex-A9.xml12
-rw-r--r--daemon/events-Linux.xml4
-rw-r--r--daemon/events-Mali-400.xml8
-rw-r--r--daemon/events-Mali-T6xx.xml12
-rw-r--r--daemon/events-Mali-T6xx_hw.xml8
-rw-r--r--daemon/events-ScorpionMP.xml2
-rw-r--r--daemon/main.cpp9
-rw-r--r--driver/gator.h52
-rw-r--r--driver/gator_annotate.c29
-rw-r--r--driver/gator_annotate_kernel.c132
-rw-r--r--driver/gator_backtrace.c36
-rw-r--r--driver/gator_cookies.c108
-rw-r--r--driver/gator_events_armv6.c6
-rw-r--r--driver/gator_events_armv7.c18
-rw-r--r--driver/gator_events_block.c5
-rw-r--r--driver/gator_events_irq.c11
-rw-r--r--driver/gator_events_l2c-310.c18
-rw-r--r--driver/gator_events_mali_400.c1001
-rw-r--r--driver/gator_events_mali_common.c90
-rw-r--r--driver/gator_events_mali_common.h14
-rw-r--r--driver/gator_events_mali_t6xx.c716
-rw-r--r--driver/gator_events_mali_t6xx_hw.c1061
-rw-r--r--driver/gator_events_mali_t6xx_hw_test.c22
-rw-r--r--driver/gator_events_meminfo.c14
-rw-r--r--driver/gator_events_mmaped.c34
-rw-r--r--driver/gator_events_net.c9
-rw-r--r--driver/gator_events_perf_pmu.c77
-rw-r--r--driver/gator_events_sched.c1
-rw-r--r--driver/gator_events_scorpion.c218
-rw-r--r--driver/gator_fs.c58
-rw-r--r--driver/gator_main.c368
-rw-r--r--driver/gator_marshaling.c179
-rw-r--r--driver/gator_pack.c110
-rw-r--r--driver/gator_trace_gpu.c76
-rw-r--r--driver/gator_trace_gpu.h60
-rw-r--r--driver/gator_trace_power.c46
-rw-r--r--driver/gator_trace_sched.c24
62 files changed, 3271 insertions, 2730 deletions
diff --git a/.gitignore b/.gitignore
index 8b85a1b..d13fee9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
daemon/*.o
+daemon/escape
daemon/events.xml
daemon/gatord
daemon/mxml/*.o
diff --git a/daemon/Android.mk b/daemon/Android.mk
index cbaf42d..cc1d542 100644
--- a/daemon/Android.mk
+++ b/daemon/Android.mk
@@ -1,11 +1,11 @@
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-$(shell cd $(LOCAL_PATH);cat events_header.xml events-*\.xml events_footer.xml > events.xml;xxd -i events.xml > events_xml.h;xxd -i configuration.xml > configuration_xml.h)
+XML_H := $(shell cd $(LOCAL_PATH) && make events_xml.h configuration_xml.h)
-LOCAL_CFLAGS += -Wall -O3 -ftree-vectorize -Wno-error=sequence-point
+LOCAL_CFLAGS += -Wall -O3 -mthumb-interwork -fno-exceptions
-LOCAL_SRC_FILES:= \
+LOCAL_SRC_FILES := \
CapturedXML.cpp \
Child.cpp \
Collector.cpp \
@@ -33,9 +33,7 @@ LOCAL_SRC_FILES:= \
LOCAL_C_INCLUDES := $(LOCAL_PATH)
-LOCAL_MODULE:= gatord
-LOCAL_MODULE_TAGS:= optional
-
-LOCAL_LDLIBS := -lz -llog
+LOCAL_MODULE := gatord
+LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
diff --git a/daemon/CapturedXML.cpp b/daemon/CapturedXML.cpp
index 30d984f..cc218d7 100644
--- a/daemon/CapturedXML.cpp
+++ b/daemon/CapturedXML.cpp
@@ -14,8 +14,6 @@
#include "Logging.h"
#include "OlyUtility.h"
-extern void handleException();
-
CapturedXML::CapturedXML() {
}
@@ -111,3 +109,42 @@ void CapturedXML::write(char* path) {
free(xml);
free(file);
}
+
+// whitespace callback utility function used with mini-xml
+const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
+ const char *name;
+
+ name = mxmlGetElement(node);
+
+ if (loc == MXML_WS_BEFORE_OPEN) {
+ // Single indentation
+ if (!strcmp(name, "target") || !strcmp(name, "counters"))
+ return("\n ");
+
+ // Double indentation
+ if (!strcmp(name, "counter"))
+ return("\n ");
+
+ // Avoid a carriage return on the first line of the xml file
+ if (!strncmp(name, "?xml", 4))
+ return(NULL);
+
+ // Default - no indentation
+ return("\n");
+ }
+
+ if (loc == MXML_WS_BEFORE_CLOSE) {
+ // No indentation
+ if (!strcmp(name, "captured"))
+ return("\n");
+
+ // Single indentation
+ if (!strcmp(name, "counters"))
+ return("\n ");
+
+ // Default - no carriage return
+ return(NULL);
+ }
+
+ return(NULL);
+}
diff --git a/daemon/CapturedXML.h b/daemon/CapturedXML.h
index 3f6a4de..3cac576 100644
--- a/daemon/CapturedXML.h
+++ b/daemon/CapturedXML.h
@@ -22,4 +22,6 @@ private:
mxml_node_t* getTree(bool includeTime);
};
+const char * mxmlWhitespaceCB(mxml_node_t *node, int where);
+
#endif //__CAPTURED_XML_H__
diff --git a/daemon/Collector.cpp b/daemon/Collector.cpp
index 25bb934..2e4af0c 100644
--- a/daemon/Collector.cpp
+++ b/daemon/Collector.cpp
@@ -18,8 +18,6 @@
#include "Logging.h"
#include "Sender.h"
-extern void handleException();
-
// Driver initialization independent of session settings
Collector::Collector() {
char text[sizeof(gSessionData->mPerfCounterType[0]) + 30]; // sufficiently large to hold all /dev/gator/events/<types>/<file>
diff --git a/daemon/ConfigurationXML.cpp b/daemon/ConfigurationXML.cpp
index df83697..14c2809 100644
--- a/daemon/ConfigurationXML.cpp
+++ b/daemon/ConfigurationXML.cpp
@@ -14,8 +14,6 @@
#include "OlyUtility.h"
#include "SessionData.h"
-extern void handleException();
-
static const char* ATTR_COUNTER = "counter";
static const char* ATTR_REVISION = "revision";
static const char* ATTR_TITLE = "title";
@@ -171,7 +169,7 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
if (mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION)) gSessionData->mPerfCounterAverageSelection[mIndex] = util->stringToBool(mxmlElementGetAttr(node, ATTR_AVERAGE_SELECTION), false);
gSessionData->mPerfCounterEnabled[mIndex] = true;
- // strncpy does not guarantee a null-termianted string
+ // strncpy does not guarantee a null-terminated string
gSessionData->mPerfCounterType[mIndex][sizeof(gSessionData->mPerfCounterType[mIndex]) - 1] = 0;
gSessionData->mPerfCounterTitle[mIndex][sizeof(gSessionData->mPerfCounterTitle[mIndex]) - 1] = 0;
gSessionData->mPerfCounterName[mIndex][sizeof(gSessionData->mPerfCounterName[mIndex]) - 1] = 0;
@@ -184,8 +182,6 @@ void ConfigurationXML::configurationTag(mxml_node_t *node) {
}
void ConfigurationXML::getDefaultConfigurationXml(const char * & xml, unsigned int & len) {
- // the first line of configuration_xml.h is "unsigned char configuration_xml", but configuration_xml needs to be const static as well
- const static
#include "configuration_xml.h" // defines and initializes char configuration_xml[] and int configuration_xml_len
xml = (const char *)configuration_xml;
len = configuration_xml_len;
diff --git a/daemon/Fifo.cpp b/daemon/Fifo.cpp
index 191536f..4a27452 100644
--- a/daemon/Fifo.cpp
+++ b/daemon/Fifo.cpp
@@ -12,8 +12,6 @@
#include "Fifo.h"
#include "Logging.h"
-extern void handleException();
-
// bufferSize is the amount of data to be filled
// singleBufferSize is the maximum size that may be filled during a single write
// (bufferSize + singleBufferSize) will be allocated
@@ -37,27 +35,29 @@ Fifo::Fifo(int singleBufferSize, int bufferSize) {
Fifo::~Fifo() {
free(mBuffer);
+ sem_destroy(&mWaitForSpaceSem);
+ sem_destroy(&mWaitForDataSem);
}
-int Fifo::numBytesFilled() {
+int Fifo::numBytesFilled() const {
return mWrite - mRead + mRaggedEnd;
}
-char* Fifo::start() {
+char* Fifo::start() const {
return mBuffer;
}
-bool Fifo::isEmpty() {
+bool Fifo::isEmpty() const {
return mRead == mWrite && mRaggedEnd == 0;
}
-bool Fifo::isFull() {
+bool Fifo::isFull() const {
return willFill(0);
}
// Determines if the buffer will fill assuming 'additional' bytes will be added to the buffer
// 'full' means there is less than singleBufferSize bytes available contiguously; it does not mean there are zero bytes available
-bool Fifo::willFill(int additional) {
+bool Fifo::willFill(int additional) const {
if (mWrite > mRead) {
if (numBytesFilled() + additional < mWrapThreshold) {
return false;
@@ -98,7 +98,7 @@ char* Fifo::write(int length) {
}
// This function will stall until data is available
-char* Fifo::read(int* length) {
+char* Fifo::read(int *const length) {
// update the read pointer now that the data has been handled
mRead = mReadCommit;
diff --git a/daemon/Fifo.h b/daemon/Fifo.h
index b460549..e2a5d94 100644
--- a/daemon/Fifo.h
+++ b/daemon/Fifo.h
@@ -15,13 +15,13 @@ class Fifo {
public:
Fifo(int singleBufferSize, int totalBufferSize);
~Fifo();
- int numBytesFilled();
- bool isEmpty();
- bool isFull();
- bool willFill(int additional);
- char* start();
+ int numBytesFilled() const;
+ bool isEmpty() const;
+ bool isFull() const;
+ bool willFill(int additional) const;
+ char* start() const;
char* write(int length);
- char* read(int* length);
+ char* read(int *const length);
private:
int mSingleBufferSize, mWrite, mRead, mReadCommit, mRaggedEnd, mWrapThreshold;
diff --git a/daemon/LocalCapture.cpp b/daemon/LocalCapture.cpp
index f8cd17f..2dd3aff 100644
--- a/daemon/LocalCapture.cpp
+++ b/daemon/LocalCapture.cpp
@@ -17,8 +17,6 @@
#include "Logging.h"
#include "OlyUtility.h"
-extern void handleException();
-
LocalCapture::LocalCapture() {}
LocalCapture::~LocalCapture() {}
@@ -56,7 +54,7 @@ char* LocalCapture::createUniqueDirectory(const char* initialPath, const char* e
handleException();
} else if (initialPath[0] != '/') {
if (getcwd(path, PATH_MAX) == 0) {
- logg->logMessage("Unable to retrive the current working directory");
+ logg->logMessage("Unable to retrieve the current working directory");
}
strncat(path, "/", PATH_MAX - strlen(path) - 1);
strncat(path, initialPath, PATH_MAX - strlen(path) - 1);
diff --git a/daemon/Logging.h b/daemon/Logging.h
index 4247966..37f7dd3 100644
--- a/daemon/Logging.h
+++ b/daemon/Logging.h
@@ -42,4 +42,6 @@ private:
extern Logging* logg;
+extern void handleException();
+
#endif //__LOGGING_H__
diff --git a/daemon/Makefile b/daemon/Makefile
index 5562db7..95d1809 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -8,10 +8,8 @@
# targets it is necessary to add options
# '-marm -march=armv4t -mfloat-abi=soft'.
-ARCH=arm
-
-CPP=$(CROSS_COMPILE)g++
-GCC=$(CROSS_COMPILE)gcc
+CPP = $(CROSS_COMPILE)g++
+GCC = $(CROSS_COMPILE)gcc
# -g produces debugging information
# -O3 maximum optimization
@@ -21,34 +19,40 @@ GCC=$(CROSS_COMPILE)gcc
# -std=c++0x is the planned new c++ standard
# -std=c++98 is the 1998 c++ standard
# -mthumb-interwork is required for interworking to ARM or Thumb stdlibc
-CFLAGS=-O3 -Wall -mthumb-interwork
+CFLAGS = -O3 -Wall -mthumb-interwork -fno-exceptions
+CXXFLAGS = -fno-rtti
ifeq ($(WERROR),1)
CFLAGS += -Werror
endif
# -s strips the binary of debug info
-LDFLAGS=-s
-TARGET=gatord
+LDFLAGS = -s
+TARGET = gatord
C_SRC = $(wildcard mxml/*.c)
-CPP_SRC = $(wildcard *.cpp)
-TGT_OBJS = $(CPP_SRC:%.cpp=%.o) \
- $(C_SRC:%.c=%.o)
+CPP_SRC = $(wildcard *.cpp)
all: $(TARGET)
+events.xml: events_header.xml $(wildcard events-*.xml) events_footer.xml
+ cat $^ > $@
+
+StreamlineSetup.cpp: events_xml.h
+ConfigurationXML.cpp: configuration_xml.h
+
+%_xml.h: %.xml escape
+ ./escape $< > $@
+
%.o: %.c *.h
$(GCC) -c $(CFLAGS) -o $@ $<
%.o: %.cpp *.h
- $(CPP) -c $(CFLAGS) -o $@ $<
+ $(CPP) -c $(CFLAGS) $(CXXFLAGS) -o $@ $<
-$(TARGET): convert $(TGT_OBJS)
- $(CPP) $(LDFLAGS) -o $@ $(TGT_OBJS) -lc -lrt -lpthread
- rm events_xml.h configuration_xml.h
+$(TARGET): $(CPP_SRC:%.cpp=%.o) $(C_SRC:%.c=%.o)
+ $(CPP) $(LDFLAGS) -o $@ $^ -lc -lrt -lpthread
+ rm -f events_xml.h configuration_xml.h
-convert:
- cat events_header.xml events-*\.xml events_footer.xml > events.xml
- xxd -i events.xml > events_xml.h
- xxd -i configuration.xml > configuration_xml.h
+escape: escape.c
+ gcc $^ -o $@
clean:
- rm -f *.o mxml/*.o $(TARGET) events.xml events_xml.h configuration_xml.h
+ rm -f *.o mxml/*.o $(TARGET) escape events.xml events_xml.h configuration_xml.h
diff --git a/daemon/OlySocket.cpp b/daemon/OlySocket.cpp
index a3bf746..6128dc0 100644
--- a/daemon/OlySocket.cpp
+++ b/daemon/OlySocket.cpp
@@ -20,242 +20,240 @@
#ifdef WIN32
#define CLOSE_SOCKET(x) closesocket(x)
-#define SHUTDOWN_RX_TX SD_BOTH
-#define snprintf _snprintf
+#define SHUTDOWN_RX_TX SD_BOTH
+#define snprintf _snprintf
#else
#define CLOSE_SOCKET(x) close(x)
-#define SHUTDOWN_RX_TX SHUT_RDWR
+#define SHUTDOWN_RX_TX SHUT_RDWR
#endif
-extern void handleException();
-
OlySocket::OlySocket(int port, bool multiple) {
#ifdef WIN32
- WSADATA wsaData;
- if (WSAStartup(0x0202, &wsaData) != 0) {
- logg->logError(__FILE__, __LINE__, "Windows socket initialization failed");
- handleException();
- }
+ WSADATA wsaData;
+ if (WSAStartup(0x0202, &wsaData) != 0) {
+ logg->logError(__FILE__, __LINE__, "Windows socket initialization failed");
+ handleException();
+ }
#endif
- if (multiple) {
- createServerSocket(port);
- } else {
- createSingleServerConnection(port);
- }
+ if (multiple) {
+ createServerSocket(port);
+ } else {
+ createSingleServerConnection(port);
+ }
}
OlySocket::OlySocket(int port, char* host) {
- mFDServer = 0;
- createClientSocket(host, port);
+ mFDServer = 0;
+ createClientSocket(host, port);
}
OlySocket::~OlySocket() {
- if (mSocketID > 0) {
- CLOSE_SOCKET(mSocketID);
- }
+ if (mSocketID > 0) {
+ CLOSE_SOCKET(mSocketID);
+ }
}
void OlySocket::shutdownConnection() {
- // Shutdown is primarily used to unblock other threads that are blocking on send/receive functions
- shutdown(mSocketID, SHUTDOWN_RX_TX);
+ // Shutdown is primarily used to unblock other threads that are blocking on send/receive functions
+ shutdown(mSocketID, SHUTDOWN_RX_TX);
}
void OlySocket::closeSocket() {
- // Used for closing an accepted socket but keeping the server socket active
- if (mSocketID > 0) {
- CLOSE_SOCKET(mSocketID);
- mSocketID = -1;
- }
+ // Used for closing an accepted socket but keeping the server socket active
+ if (mSocketID > 0) {
+ CLOSE_SOCKET(mSocketID);
+ mSocketID = -1;
+ }
}
void OlySocket::closeServerSocket() {
- if (CLOSE_SOCKET(mFDServer) != 0) {
- logg->logError(__FILE__, __LINE__, "Failed to close server socket.");
- handleException();
- }
- mFDServer = 0;
+ if (CLOSE_SOCKET(mFDServer) != 0) {
+ logg->logError(__FILE__, __LINE__, "Failed to close server socket.");
+ handleException();
+ }
+ mFDServer = 0;
}
void OlySocket::createClientSocket(char* hostname, int portno) {
#ifdef WIN32
- // TODO: Implement for Windows
+ // TODO: Implement for Windows
#else
- char buf[32];
- struct addrinfo hints, *res, *res0;
-
- snprintf(buf, sizeof(buf), "%d", portno);
- mSocketID = -1;
- memset((void*)&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- if (getaddrinfo(hostname, buf, &hints, &res0)) {
- logg->logError(__FILE__, __LINE__, "Client socket failed to get address info for %s", hostname);
- handleException();
- }
- for (res=res0; res!=NULL; res = res->ai_next) {
- if ( res->ai_family != PF_INET || res->ai_socktype != SOCK_STREAM ) {
- continue;
- }
- mSocketID = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (mSocketID < 0) {
- continue;
- }
- if (connect(mSocketID, res->ai_addr, res->ai_addrlen) < 0) {
- close(mSocketID);
- mSocketID = -1;
- }
- if (mSocketID > 0) {
- break;
- }
- }
- freeaddrinfo(res0);
- if (mSocketID <= 0) {
- logg->logError(__FILE__, __LINE__, "Could not connect to client socket. Ensure ARM Streamline is running.");
- handleException();
- }
+ char buf[32];
+ struct addrinfo hints, *res, *res0;
+
+ snprintf(buf, sizeof(buf), "%d", portno);
+ mSocketID = -1;
+ memset((void*)&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ if (getaddrinfo(hostname, buf, &hints, &res0)) {
+ logg->logError(__FILE__, __LINE__, "Client socket failed to get address info for %s", hostname);
+ handleException();
+ }
+ for (res=res0; res!=NULL; res = res->ai_next) {
+ if ( res->ai_family != PF_INET || res->ai_socktype != SOCK_STREAM ) {
+ continue;
+ }
+ mSocketID = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (mSocketID < 0) {
+ continue;
+ }
+ if (connect(mSocketID, res->ai_addr, res->ai_addrlen) < 0) {
+ close(mSocketID);
+ mSocketID = -1;
+ }
+ if (mSocketID > 0) {
+ break;
+ }
+ }
+ freeaddrinfo(res0);
+ if (mSocketID <= 0) {
+ logg->logError(__FILE__, __LINE__, "Could not connect to client socket. Ensure ARM Streamline is running.");
+ handleException();
+ }
#endif
}
void OlySocket::createSingleServerConnection(int port) {
- createServerSocket(port);
+ createServerSocket(port);
- mSocketID = acceptConnection();
- closeServerSocket();
+ mSocketID = acceptConnection();
+ closeServerSocket();
}
void OlySocket::createServerSocket(int port) {
- // Create socket
- mFDServer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (mFDServer < 0) {
- logg->logError(__FILE__, __LINE__, "Error creating server socket");
- handleException();
- }
-
- // Enable address reuse, another solution would be to create the server socket once and only close it when the object exits
- int on = 1;
- if (setsockopt(mFDServer, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
- logg->logError(__FILE__, __LINE__, "Setting server socket options failed");
- handleException();
- }
-
- // Create sockaddr_in structure, ensuring non-populated fields are zero
- struct sockaddr_in sockaddr;
- memset((void*)&sockaddr, 0, sizeof(struct sockaddr_in));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(port);
- sockaddr.sin_addr.s_addr = INADDR_ANY;
-
- // Bind the socket to an address
- if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
- logg->logError(__FILE__, __LINE__, "Binding of server socket failed.\nIs an instance already running?");
- handleException();
- }
-
- // Listen for connections on this socket
- if (listen(mFDServer, 1) < 0) {
- logg->logError(__FILE__, __LINE__, "Listening of server socket failed");
- handleException();
- }
+ // Create socket
+ mFDServer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (mFDServer < 0) {
+ logg->logError(__FILE__, __LINE__, "Error creating server socket");
+ handleException();
+ }
+
+ // Enable address reuse, another solution would be to create the server socket once and only close it when the object exits
+ int on = 1;
+ if (setsockopt(mFDServer, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) != 0) {
+ logg->logError(__FILE__, __LINE__, "Setting server socket options failed");
+ handleException();
+ }
+
+ // Create sockaddr_in structure, ensuring non-populated fields are zero
+ struct sockaddr_in sockaddr;
+ memset((void*)&sockaddr, 0, sizeof(struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(port);
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+
+ // Bind the socket to an address
+ if (bind(mFDServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
+ logg->logError(__FILE__, __LINE__, "Binding of server socket failed.\nIs an instance already running?");
+ handleException();
+ }
+
+ // Listen for connections on this socket
+ if (listen(mFDServer, 1) < 0) {
+ logg->logError(__FILE__, __LINE__, "Listening of server socket failed");
+ handleException();
+ }
}
// mSocketID is always set to the most recently accepted connection
// The user of this class should maintain the different socket connections, e.g. by forking the process
int OlySocket::acceptConnection() {
- if (mFDServer <= 0) {
- logg->logError(__FILE__, __LINE__, "Attempting multiple connections on a single connection server socket or attempting to accept on a client socket");
- handleException();
- }
-
- // Accept a connection, note that this call blocks until a client connects
- mSocketID = accept(mFDServer, NULL, NULL);
- if (mSocketID < 0) {
- logg->logError(__FILE__, __LINE__, "Socket acceptance failed");
- handleException();
- }
- return mSocketID;
+ if (mFDServer <= 0) {
+ logg->logError(__FILE__, __LINE__, "Attempting multiple connections on a single connection server socket or attempting to accept on a client socket");
+ handleException();
+ }
+
+ // Accept a connection, note that this call blocks until a client connects
+ mSocketID = accept(mFDServer, NULL, NULL);
+ if (mSocketID < 0) {
+ logg->logError(__FILE__, __LINE__, "Socket acceptance failed");
+ handleException();
+ }
+ return mSocketID;
}
void OlySocket::send(char* buffer, int size) {
- if (size <= 0 || buffer == NULL) {
- return;
- }
-
- while (size > 0) {
- int n = ::send(mSocketID, buffer, size, 0);
- if (n < 0) {
- logg->logError(__FILE__, __LINE__, "Socket send error");
- handleException();
- }
- size -= n;
- buffer += n;
- }
+ if (size <= 0 || buffer == NULL) {
+ return;
+ }
+
+ while (size > 0) {
+ int n = ::send(mSocketID, buffer, size, 0);
+ if (n < 0) {
+ logg->logError(__FILE__, __LINE__, "Socket send error");
+ handleException();
+ }
+ size -= n;
+ buffer += n;
+ }
}
// Returns the number of bytes received
int OlySocket::receive(char* buffer, int size) {
- if (size <= 0 || buffer == NULL) {
- return 0;
- }
-
- int bytes = recv(mSocketID, buffer, size, 0);
- if (bytes < 0) {
- logg->logError(__FILE__, __LINE__, "Socket receive error");
- handleException();
- } else if (bytes == 0) {
- logg->logMessage("Socket disconnected");
- return -1;
- }
- return bytes;
+ if (size <= 0 || buffer == NULL) {
+ return 0;
+ }
+
+ int bytes = recv(mSocketID, buffer, size, 0);
+ if (bytes < 0) {
+ logg->logError(__FILE__, __LINE__, "Socket receive error");
+ handleException();
+ } else if (bytes == 0) {
+ logg->logMessage("Socket disconnected");
+ return -1;
+ }
+ return bytes;
}
// Receive exactly size bytes of data. Note, this function will block until all bytes are received
int OlySocket::receiveNBytes(char* buffer, int size) {
- int bytes = 0;
- while (size > 0 && buffer != NULL) {
- bytes = recv(mSocketID, buffer, size, 0);
- if (bytes < 0) {
- logg->logError(__FILE__, __LINE__, "Socket receive error");
- handleException();
- } else if (bytes == 0) {
- logg->logMessage("Socket disconnected");
- return -1;
- }
- buffer += bytes;
- size -= bytes;
- }
- return bytes;
+ int bytes = 0;
+ while (size > 0 && buffer != NULL) {
+ bytes = recv(mSocketID, buffer, size, 0);
+ if (bytes < 0) {
+ logg->logError(__FILE__, __LINE__, "Socket receive error");
+ handleException();
+ } else if (bytes == 0) {
+ logg->logMessage("Socket disconnected");
+ return -1;
+ }
+ buffer += bytes;
+ size -= bytes;
+ }
+ return bytes;
}
// Receive data until a carriage return, line feed, or null is encountered, or the buffer fills
int OlySocket::receiveString(char* buffer, int size) {
- int bytes_received = 0;
- bool found = false;
-
- if (buffer == 0) {
- return 0;
- }
-
- while (!found && bytes_received < size) {
- // Receive a single character
- int bytes = recv(mSocketID, &buffer[bytes_received], 1, 0);
- if (bytes < 0) {
- logg->logError(__FILE__, __LINE__, "Socket receive error");
- handleException();
- } else if (bytes == 0) {
- logg->logMessage("Socket disconnected");
- return -1;
- }
-
- // Replace carriage returns and line feeds with zero
- if (buffer[bytes_received] == '\n' || buffer[bytes_received] == '\r' || buffer[bytes_received] == '\0') {
- buffer[bytes_received] = '\0';
- found = true;
- }
-
- bytes_received++;
- }
-
- return bytes_received;
+ int bytes_received = 0;
+ bool found = false;
+
+ if (buffer == 0) {
+ return 0;
+ }
+
+ while (!found && bytes_received < size) {
+ // Receive a single character
+ int bytes = recv(mSocketID, &buffer[bytes_received], 1, 0);
+ if (bytes < 0) {
+ logg->logError(__FILE__, __LINE__, "Socket receive error");
+ handleException();
+ } else if (bytes == 0) {
+ logg->logMessage("Socket disconnected");
+ return -1;
+ }
+
+ // Replace carriage returns and line feeds with zero
+ if (buffer[bytes_received] == '\n' || buffer[bytes_received] == '\r' || buffer[bytes_received] == '\0') {
+ buffer[bytes_received] = '\0';
+ found = true;
+ }
+
+ bytes_received++;
+ }
+
+ return bytes_received;
}
diff --git a/daemon/OlySocket.h b/daemon/OlySocket.h
index 266a831..b306908 100644
--- a/daemon/OlySocket.h
+++ b/daemon/OlySocket.h
@@ -6,31 +6,31 @@
* published by the Free Software Foundation.
*/
-#ifndef __OLY_SOCKET_H__
-#define __OLY_SOCKET_H__
+#ifndef __OLY_SOCKET_H__
+#define __OLY_SOCKET_H__
#include <string.h>
class OlySocket {
public:
- OlySocket(int port, bool multipleConnections = false);
- OlySocket(int port, char* hostname);
- ~OlySocket();
- int acceptConnection();
- void closeSocket();
- void closeServerSocket();
- void shutdownConnection();
- void send(char* buffer, int size);
- void sendString(const char* string) {send((char*)string, strlen(string));}
- int receive(char* buffer, int size);
- int receiveNBytes(char* buffer, int size);
- int receiveString(char* buffer, int size);
- int getSocketID() {return mSocketID;}
+ OlySocket(int port, bool multipleConnections = false);
+ OlySocket(int port, char* hostname);
+ ~OlySocket();
+ int acceptConnection();
+ void closeSocket();
+ void closeServerSocket();
+ void shutdownConnection();
+ void send(char* buffer, int size);
+ void sendString(const char* string) {send((char*)string, strlen(string));}
+ int receive(char* buffer, int size);
+ int receiveNBytes(char* buffer, int size);
+ int receiveString(char* buffer, int size);
+ int getSocketID() {return mSocketID;}
private:
- int mSocketID, mFDServer;
- void createClientSocket(char* hostname, int port);
- void createSingleServerConnection(int port);
- void createServerSocket(int port);
+ int mSocketID, mFDServer;
+ void createClientSocket(char* hostname, int port);
+ void createSingleServerConnection(int port);
+ void createServerSocket(int port);
};
-#endif //__OLY_SOCKET_H__
+#endif //__OLY_SOCKET_H__
diff --git a/daemon/OlyUtility.cpp b/daemon/OlyUtility.cpp
index adc7aba..df4fe22 100644
--- a/daemon/OlyUtility.cpp
+++ b/daemon/OlyUtility.cpp
@@ -11,10 +11,12 @@
#include <string.h>
#include <ctype.h>
-#ifndef WIN32
+#if defined(WIN32)
+#include <windows.h>
+#elif defined(__linux__)
#include <unistd.h>
-#else
-#include <Windows.h>
+#elif defined(DARWIN)
+#include <mach-o/dyld.h>
#endif
#include "OlyUtility.h"
@@ -22,138 +24,144 @@
OlyUtility* util = NULL;
bool OlyUtility::stringToBool(const char* string, bool defValue) {
- char value[32];
-
- if (string == NULL) {
- return defValue;
- }
-
- strncpy(value, string, sizeof(value));
- if (value[0] == 0) {
- return defValue;
- }
- value[sizeof(value) - 1] = 0; // strncpy does not guarantee a null-terminated string
-
- // Convert to lowercase
- int i = 0;
- while (value[i]) {
- value[i] = tolower(value[i]);
- i++;
- }
-
- if (strcmp(value, "true") == 0 || strcmp(value, "yes") == 0 || strcmp(value, "1") == 0 || strcmp(value, "on") == 0) {
- return true;
- } else if (strcmp(value, "false") == 0 || strcmp(value, "no") == 0 || strcmp(value, "0") == 0 || strcmp(value, "off") == 0) {
- return false;
- } else {
- return defValue;
- }
+ char value[32];
+
+ if (string == NULL) {
+ return defValue;
+ }
+
+ strncpy(value, string, sizeof(value));
+ if (value[0] == 0) {
+ return defValue;
+ }
+ value[sizeof(value) - 1] = 0; // strncpy does not guarantee a null-terminated string
+
+ // Convert to lowercase
+ int i = 0;
+ while (value[i]) {
+ value[i] = tolower(value[i]);
+ i++;
+ }
+
+ if (strcmp(value, "true") == 0 || strcmp(value, "yes") == 0 || strcmp(value, "1") == 0 || strcmp(value, "on") == 0) {
+ return true;
+ } else if (strcmp(value, "false") == 0 || strcmp(value, "no") == 0 || strcmp(value, "0") == 0 || strcmp(value, "off") == 0) {
+ return false;
+ } else {
+ return defValue;
+ }
}
void OlyUtility::stringToLower(char* string) {
- if (string == NULL) {
- return;
- }
-
- while (*string) {
- *string = tolower(*string);
- string++;
- }
+ if (string == NULL) {
+ return;
+ }
+
+ while (*string) {
+ *string = tolower(*string);
+ string++;
+ }
}
// Modifies fullpath with the path part including the trailing path separator
int OlyUtility::getApplicationFullPath(char* fullpath, int sizeOfPath) {
- memset(fullpath, 0, sizeOfPath);
-#ifdef WIN32
- int length = GetModuleFileName(NULL, fullpath, sizeOfPath);
-#else
- int length = readlink("/proc/self/exe", fullpath, sizeOfPath);
+ memset(fullpath, 0, sizeOfPath);
+#if defined(WIN32)
+ int length = GetModuleFileName(NULL, fullpath, sizeOfPath);
+#elif defined(__linux__)
+ int length = readlink("/proc/self/exe", fullpath, sizeOfPath);
+#elif defined(DARWIN)
+ uint32_t length_u = (uint32_t)sizeOfPath;
+ int length = sizeOfPath;
+ if (_NSGetExecutablePath(fullpath, &length_u) == 0) {
+ length = strlen(fullpath);
+ }
#endif
- if (length == sizeOfPath) {
- return -1;
- }
+ if (length == sizeOfPath) {
+ return -1;
+ }
- fullpath[length] = 0;
- fullpath = getPathPart(fullpath);
+ fullpath[length] = 0;
+ fullpath = getPathPart(fullpath);
- return 0;
+ return 0;
}
char* OlyUtility::readFromDisk(const char* file, unsigned int *size, bool appendNull) {
- // Open the file
- FILE* pFile = fopen(file, "rb");
- if (pFile==NULL) {
- return NULL;
- }
-
- // Obtain file size
- fseek(pFile , 0 , SEEK_END);
- unsigned int lSize = ftell(pFile);
- rewind(pFile);
-
- // Allocate memory to contain the whole file
- char* buffer = (char*)malloc(lSize + (int)appendNull);
- if (buffer == NULL) {
- fclose(pFile);
- return NULL;
- }
-
- // Copy the file into the buffer
- if (fread(buffer, 1, lSize, pFile) != lSize) {
- free(buffer);
- fclose(pFile);
- return NULL;
- }
-
- // Terminate
- fclose(pFile);
-
- if (appendNull) {
- buffer[lSize] = 0;
- }
-
- if (size) {
- *size = lSize;
- }
-
- return buffer;
+ // Open the file
+ FILE* pFile = fopen(file, "rb");
+ if (pFile==NULL) {
+ return NULL;
+ }
+
+ // Obtain file size
+ fseek(pFile , 0 , SEEK_END);
+ unsigned int lSize = ftell(pFile);
+ rewind(pFile);
+
+ // Allocate memory to contain the whole file
+ char* buffer = (char*)malloc(lSize + (int)appendNull);
+ if (buffer == NULL) {
+ fclose(pFile);
+ return NULL;
+ }
+
+ // Copy the file into the buffer
+ if (fread(buffer, 1, lSize, pFile) != lSize) {
+ free(buffer);
+ fclose(pFile);
+ return NULL;
+ }
+
+ // Terminate
+ fclose(pFile);
+
+ if (appendNull) {
+ buffer[lSize] = 0;
+ }
+
+ if (size) {
+ *size = lSize;
+ }
+
+ return buffer;
}
int OlyUtility::writeToDisk(const char* path, const char* data) {
- // Open the file
- FILE* pFile = fopen(path, "wb");
- if (pFile == NULL) {
- return -1;
- }
-
- // Write the data to disk
- if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) {
- fclose(pFile);
- return -1;
- }
-
- // Terminate
- fclose(pFile);
- return 0;
+ // Open the file
+ FILE* pFile = fopen(path, "wb");
+ if (pFile == NULL) {
+ return -1;
+ }
+
+ // Write the data to disk
+ if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) {
+ fclose(pFile);
+ return -1;
+ }
+
+ // Terminate
+ fclose(pFile);
+ return 0;
}
int OlyUtility::appendToDisk(const char* path, const char* data) {
- // Open the file
- FILE* pFile = fopen(path, "a");
- if (pFile == NULL) {
- return -1;
- }
-
- // Write the data to disk
- if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) {
- fclose(pFile);
- return -1;
- }
-
- // Terminate
- fclose(pFile);
- return 0;
+ // Open the file
+ FILE* pFile = fopen(path, "a");
+ if (pFile == NULL) {
+ return -1;
+ }
+
+ // Write the data to disk
+ if (fwrite(data, 1, strlen(data), pFile) != strlen(data)) {
+ fclose(pFile);
+ return -1;
+ }
+
+ // Terminate
+ fclose(pFile);
+ return 0;
}
/**
@@ -163,97 +171,58 @@ int OlyUtility::appendToDisk(const char* path, const char* data) {
*/
#define TRANSFER_SIZE 1024
int OlyUtility::copyFile(const char* srcFile, const char* dstFile) {
- char* buffer = (char*)malloc(TRANSFER_SIZE);
- FILE * f_src = fopen(srcFile,"rb");
- if (!f_src) {
- return 0;
- }
- FILE * f_dst = fopen(dstFile,"wb");
- if (!f_dst) {
- fclose(f_src);
- return 0;
- }
- while (!feof(f_src)) {
- int num_bytes_read = fread(buffer, 1, TRANSFER_SIZE, f_src);
- if (num_bytes_read < TRANSFER_SIZE && !feof(f_src)) {
- fclose(f_src);
- fclose(f_dst);
- return 0;
- }
- int num_bytes_written = fwrite(buffer, 1, num_bytes_read, f_dst);
- if (num_bytes_written != num_bytes_read) {
- fclose(f_src);
- fclose(f_dst);
- return 0;
- }
- }
- fclose(f_src);
- fclose(f_dst);
- free(buffer);
- return 1;
+ char* buffer = (char*)malloc(TRANSFER_SIZE);
+ FILE * f_src = fopen(srcFile,"rb");
+ if (!f_src) {
+ return 0;
+ }
+ FILE * f_dst = fopen(dstFile,"wb");
+ if (!f_dst) {
+ fclose(f_src);
+ return 0;
+ }
+ while (!feof(f_src)) {
+ int num_bytes_read = fread(buffer, 1, TRANSFER_SIZE, f_src);
+ if (num_bytes_read < TRANSFER_SIZE && !feof(f_src)) {
+ fclose(f_src);
+ fclose(f_dst);
+ return 0;
+ }
+ int num_bytes_written = fwrite(buffer, 1, num_bytes_read, f_dst);
+ if (num_bytes_written != num_bytes_read) {
+ fclose(f_src);
+ fclose(f_dst);
+ return 0;
+ }
+ }
+ fclose(f_src);
+ fclose(f_dst);
+ free(buffer);
+ return 1;
}
const char* OlyUtility::getFilePart(const char* path) {
- const char* last_sep = strrchr(path, PATH_SEPARATOR);
+ const char* last_sep = strrchr(path, PATH_SEPARATOR);
- // in case path is not a full path
- if (last_sep == NULL) {
- return path;
- }
+ // in case path is not a full path
+ if (last_sep == NULL) {
+ return path;
+ }
- return last_sep++;
+ return last_sep++;
}
// getPathPart may modify the contents of path
// returns the path including the trailing path separator
char* OlyUtility::getPathPart(char* path) {
- char* last_sep = strrchr(path, PATH_SEPARATOR);
+ char* last_sep = strrchr(path, PATH_SEPARATOR);
- // in case path is not a full path
- if (last_sep == NULL) {
- return 0;
- }
- last_sep++;
- *last_sep = 0;
+ // in case path is not a full path
+ if (last_sep == NULL) {
+ return 0;
+ }
+ last_sep++;
+ *last_sep = 0;
- return (path);
-}
-
-// whitespace callback utility function used with mini-xml
-const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
- const char *name;
-
- name = mxmlGetElement(node);
-
- if (loc == MXML_WS_BEFORE_OPEN) {
- // Single indentation
- if (!strcmp(name, "target") || !strcmp(name, "counters"))
- return("\n ");
-
- // Double indentation
- if (!strcmp(name, "counter"))
- return("\n ");
-
- // Avoid a carriage return on the first line of the xml file
- if (!strncmp(name, "?xml", 4))
- return(NULL);
-
- // Default - no indentation
- return("\n");
- }
-
- if (loc == MXML_WS_BEFORE_CLOSE) {
- // No indentation
- if (!strcmp(name, "captured"))
- return("\n");
-
- // Single indentation
- if (!strcmp(name, "counters"))
- return("\n ");
-
- // Default - no carriage return
- return(NULL);
- }
-
- return(NULL);
+ return (path);
}
diff --git a/daemon/OlyUtility.h b/daemon/OlyUtility.h
index 793a733..424c583 100644
--- a/daemon/OlyUtility.h
+++ b/daemon/OlyUtility.h
@@ -11,28 +11,30 @@
#ifdef WIN32
#define PATH_SEPARATOR '\\'
+#define CAIMAN_PATH_MAX MAX_PATH
+#define snprintf _snprintf
#else
+#include <limits.h>
#define PATH_SEPARATOR '/'
+#define CAIMAN_PATH_MAX PATH_MAX
#endif
class OlyUtility {
public:
- OlyUtility() {};
- ~OlyUtility() {};
- bool stringToBool(const char* string, bool defValue);
- void stringToLower(char* string);
- int getApplicationFullPath(char* path, int sizeOfPath);
- char* readFromDisk(const char* file, unsigned int *size = NULL, bool appendNull = true);
- int writeToDisk(const char* path, const char* file);
- int appendToDisk(const char* path, const char* file);
- int copyFile(const char* srcFile, const char* dstFile);
- const char* getFilePart(const char* path);
- char* getPathPart(char* path);
+ OlyUtility() {};
+ ~OlyUtility() {};
+ bool stringToBool(const char* string, bool defValue);
+ void stringToLower(char* string);
+ int getApplicationFullPath(char* path, int sizeOfPath);
+ char* readFromDisk(const char* file, unsigned int *size = NULL, bool appendNull = true);
+ int writeToDisk(const char* path, const char* file);
+ int appendToDisk(const char* path, const char* file);
+ int copyFile(const char* srcFile, const char* dstFile);
+ const char* getFilePart(const char* path);
+ char* getPathPart(char* path);
private:
};
-#include "mxml/mxml.h"
-const char * mxmlWhitespaceCB(mxml_node_t *node, int where);
extern OlyUtility* util;
#endif // OLY_UTILITY_H
diff --git a/daemon/Sender.cpp b/daemon/Sender.cpp
index eba8343..54f2207 100644
--- a/daemon/Sender.cpp
+++ b/daemon/Sender.cpp
@@ -17,8 +17,6 @@
#include "Logging.h"
#include "SessionData.h"
-extern void handleException();
-
Sender::Sender(OlySocket* socket) {
mDataFile = NULL;
mDataSocket = NULL;
@@ -37,7 +35,7 @@ Sender::Sender(OlySocket* socket) {
}
}
- // Send magic sequence - must be done first, afterwhich error messages can be sent
+ // Send magic sequence - must be done first, after which error messages can be sent
char magic[32];
snprintf(magic, 32, "GATOR %i\n", PROTOCOL_VERSION);
mDataSocket->send(magic, strlen(magic));
diff --git a/daemon/SessionData.cpp b/daemon/SessionData.cpp
index 5aa3f11..53a3ea6 100644
--- a/daemon/SessionData.cpp
+++ b/daemon/SessionData.cpp
@@ -10,7 +10,6 @@
#include "SessionData.h"
#include "SessionXML.h"
#include "Logging.h"
-extern void handleException();
SessionData* gSessionData = NULL;
diff --git a/daemon/SessionData.h b/daemon/SessionData.h
index 00a71b1..e0e0b7a 100644
--- a/daemon/SessionData.h
+++ b/daemon/SessionData.h
@@ -13,7 +13,7 @@
#define MAX_STRING_LEN 80
#define MAX_DESCRIPTION_LEN 400
-#define PROTOCOL_VERSION 11
+#define PROTOCOL_VERSION 12
#define PROTOCOL_DEV 1000 // Differentiates development versions (timestamp) from release versions
struct ImageLinkList {
diff --git a/daemon/SessionXML.cpp b/daemon/SessionXML.cpp
index 4c373d8..b2b6c30 100644
--- a/daemon/SessionXML.cpp
+++ b/daemon/SessionXML.cpp
@@ -13,8 +13,6 @@
#include "Logging.h"
#include "OlyUtility.h"
-extern void handleException();
-
static const char* TAG_SESSION = "session";
static const char* TAG_IMAGE = "image";
diff --git a/daemon/StreamlineSetup.cpp b/daemon/StreamlineSetup.cpp
index 3f59eab..d13cf1d 100644
--- a/daemon/StreamlineSetup.cpp
+++ b/daemon/StreamlineSetup.cpp
@@ -22,8 +22,6 @@
#include "StreamlineSetup.h"
#include "ConfigurationXML.h"
-extern void handleException();
-
static const char* TAG_SESSION = "session";
static const char* TAG_REQUEST = "request";
static const char* TAG_CONFIGURATIONS = "configurations";
diff --git a/daemon/escape.c b/daemon/escape.c
new file mode 100644
index 0000000..c0f47f1
--- /dev/null
+++ b/daemon/escape.c
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) ARM Limited 2010-2012. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+static void print_escaped_path(char *path) {
+ if (isdigit(*path)) {
+ printf("__");
+ }
+ for (; *path != '\0'; ++path) {
+ printf("%c", isalnum(*path) ? *path : '_');
+ }
+}
+
+int main(int argc, char *argv[]) {
+ int i;
+ char *path;
+ FILE *in = NULL;
+ int ch;
+ unsigned int len = 0;
+
+ for (i = 1; i < argc && argv[i][0] == '-'; ++i) ;
+ if (i == argc) {
+ fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ path = argv[i];
+
+ errno = 0;
+ if ((in = fopen(path, "r")) == NULL) {
+ fprintf(stderr, "Unable to open '%s': %s\n", path, strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ printf("static const unsigned char ");
+ print_escaped_path(path);
+ printf("[] = {");
+ for (; (ch = fgetc(in)) != EOF; ++len) {
+ if (len != 0) {
+ printf(",");
+ }
+ if (len % 12 == 0) {
+ printf("\n ");
+ }
+ printf(" 0x%.2x", ch);
+ }
+ printf("\n};\nstatic const unsigned int ");
+ print_escaped_path(path);
+ printf("_len = %i;\n", len);
+
+ fclose(in);
+
+ return EXIT_SUCCESS;
+}
diff --git a/daemon/events-Cortex-A15.xml b/daemon/events-Cortex-A15.xml
index 0ec196f..e0bd201 100644
--- a/daemon/events-Cortex-A15.xml
+++ b/daemon/events-Cortex-A15.xml
@@ -65,4 +65,4 @@
<event event="0x7c" title="Instruction" name="ISB" description="Barrier speculatively executed - ISB"/>
<event event="0x7d" title="Instruction" name="DSB" description="Barrier speculatively executed - DSB"/>
<event event="0x7e" title="Instruction" name="DMB" description="Barrier speculatively executed - DMB"/>
- </category>
+ </category>
diff --git a/daemon/events-Cortex-A53.xml b/daemon/events-Cortex-A53.xml
new file mode 100644
index 0000000..3fa9c66
--- /dev/null
+++ b/daemon/events-Cortex-A53.xml
@@ -0,0 +1,171 @@
+ <counter_set name="ARM_Cortex-A53_cnt" count="6"/>
+ <category name="Cortex-A53" counter_set="ARM_Cortex-A53_cnt" per_cpu="yes" supports_event_based_sampling="yes">
+ <!-- 0x11 CPU_CYCLES - Cycle -->
+ <event counter="ARM_Cortex-A53_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <!-- 0x00 SW_INCR - Instruction architecturally executed (condition check pass) - Software increment -->
+ <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
+ <!-- 0x01 L1I_CACHE_REFILL - Level 1 instruction cache refill -->
+ <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"/>
+ <!-- 0x02 L1I_TLB_REFILL - Level 1 instruction TLB refill -->
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
+ <!-- 0x03 L1D_CACHE_REFILL - Level 1 data cache refill -->
+ <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
+ <!-- 0x04 L1D_CACHE - Level 1 data cache access -->
+ <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
+ <!-- 0x05 L1D_TLB_REFILL - Level 1 data TLB refill -->
+ <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
+ <!-- 0x08 INST_RETIRED - Instruction architecturally executed -->
+ <event event="0x08" title="-" name="INST_RETIRED" description="Instruction architecturally executed"/>
+ <!-- 0x09 EXC_TAKEN - Exception taken -->
+ <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
+ <!-- 0x0A EXC_RETURN - Instruction architecturally executed (condition check pass) - Exception return -->
+ <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
+ <!-- 0x0B CID_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to CONTEXTIDR -->
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
+ <!-- 0x10 BR_MIS_PRED - Mispredicted or not predicted branch speculatively executed -->
+ <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
+ <!-- 0x12 BR_PRED - Predictable branch speculatively executed -->
+ <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"/>
+ <!-- 0x13 MEM_ACCESS - Data memory access -->
+ <event event="0x13" title="-" name="MEM_ACCESS" description="Data memory access"/>
+ <!-- 0x14 L1I_CACHE - Level 1 instruction cache access -->
+ <event event="0x14" title="-" name="L1I_CACHE" description="Level 1 instruction cache access"/>
+ <!-- 0x15 L1D_CACHE_WB - Level 1 data cache Write-Back -->
+ <event event="0x15" title="-" name="L1D_CACHE_WB" description="Level 1 data cache Write-Back"/>
+ <!-- 0x16 L2D_CACHE - Level 2 data cache access -->
+ <event event="0x16" title="-" name="L2D_CACHE" description="Level 2 data cache access"/>
+ <!-- 0x17 L2D_CACHE_REFILL - Level 2 data cache refill -->
+ <event event="0x17" title="-" name="L2D_CACHE_REFILL" description="Level 2 data cache refill"/>
+ <!-- 0x18 L2D_CACHE_WB - Level 2 data cache Write-Back -->
+ <event event="0x18" title="-" name="L2D_CACHE_WB" description="Level 2 data cache Write-Back"/>
+ <!-- 0x19 BUS_ACCESS - Bus access -->
+ <event event="0x19" title="-" name="BUS_ACCESS" description="Bus access"/>
+ <!-- 0x1A MEMORY_ERROR - Local memory error -->
+ <event event="0x1A" title="-" name="MEMORY_ERROR" description="Local memory error"/>
+ <!-- 0x1B INST_SPEC - Operation speculatively executed -->
+ <event event="0x1B" title="-" name="INST_SPEC" description="Operation speculatively executed"/>
+ <!-- 0x1C TTBR_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to translation table base -->
+ <event event="0x1C" title="-" name="TTBR_WRITE_RETIRED" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
+ <!-- 0x1D BUS_CYCLES - Bus cycle -->
+ <event event="0x1D" title="-" name="BUS_CYCLES" description="Bus cycle"/>
+ <!-- 0x1E CHAIN - Odd performance counter chain mode -->
+ <event event="0x1E" title="-" name="CHAIN" description="Odd performance counter chain mode"/>
+ <!-- 0x40 L1D_CACHE_LD - Level 1 data cache access - Read -->
+ <event event="0x40" title="-" name="L1D_CACHE_LD" description="Level 1 data cache access - Read"/>
+ <!-- 0x41 L1D_CACHE_ST - Level 1 data cache access - Write -->
+ <event event="0x41" title="-" name="L1D_CACHE_ST" description="Level 1 data cache access - Write"/>
+ <!-- 0x42 L1D_CACHE_REFILL_LD - Level 1 data cache refill - Read -->
+ <event event="0x42" title="-" name="L1D_CACHE_REFILL_LD" description="Level 1 data cache refill - Read"/>
+ <!-- 0x43 L1D_CACHE_REFILL_ST - Level 1 data cache refill - Write -->
+ <event event="0x43" title="-" name="L1D_CACHE_REFILL_ST" description="Level 1 data cache refill - Write"/>
+ <!-- 0x46 L1D_CACHE_WB_VICTIM - Level 1 data cache Write-back - Victim -->
+ <event event="0x46" title="-" name="L1D_CACHE_WB_VICTIM" description="Level 1 data cache Write-back - Victim"/>
+ <!-- 0x47 L1D_CACHE_WB_CLEAN - Level 1 data cache Write-back - Cleaning and coherency -->
+ <event event="0x47" title="-" name="L1D_CACHE_WB_CLEAN" description="Level 1 data cache Write-back - Cleaning and coherency"/>
+ <!-- 0x48 L1D_CACHE_INVAL - Level 1 data cache invalidate -->
+ <event event="0x48" title="-" name="L1D_CACHE_INVAL" description="Level 1 data cache invalidate"/>
+ <!-- 0x4C L1D_TLB_REFILL_LD - Level 1 data TLB refill - Read -->
+ <event event="0x4C" title="-" name="L1D_TLB_REFILL_LD" description="Level 1 data TLB refill - Read"/>
+ <!-- 0x4D L1D_TLB_REFILL_ST - Level 1 data TLB refill - Write -->
+ <event event="0x4D" title="-" name="L1D_TLB_REFILL_ST" description="Level 1 data TLB refill - Write"/>
+ <!-- 0x50 L2D_CACHE_LD - Level 2 data cache access - Read -->
+ <event event="0x50" title="-" name="L2D_CACHE_LD" description="Level 2 data cache access - Read"/>
+ <!-- 0x51 L2D_CACHE_ST - Level 2 data cache access - Write -->
+ <event event="0x51" title="-" name="L2D_CACHE_ST" description="Level 2 data cache access - Write"/>
+ <!-- 0x52 L2D_CACHE_REFILL_LD - Level 2 data cache refill - Read -->
+ <event event="0x52" title="-" name="L2D_CACHE_REFILL_LD" description="Level 2 data cache refill - Read"/>
+ <!-- 0x53 L2D_CACHE_REFILL_ST - Level 2 data cache refill - Write -->
+ <event event="0x53" title="-" name="L2D_CACHE_REFILL_ST" description="Level 2 data cache refill - Write"/>
+ <!-- 0x56 L2D_CACHE_WB_VICTIM - Level 2 data cache Write-back - Victim -->
+ <event event="0x56" title="-" name="L2D_CACHE_WB_VICTIM" description="Level 2 data cache Write-back - Victim"/>
+ <!-- 0x57 L2D_CACHE_WB_CLEAN - Level 2 data cache Write-back - Cleaning and coherency -->
+ <event event="0x57" title="-" name="L2D_CACHE_WB_CLEAN" description="Level 2 data cache Write-back - Cleaning and coherency"/>
+ <!-- 0x58 L2D_CACHE_INVAL - Level 2 data cache invalidate -->
+ <event event="0x58" title="-" name="L2D_CACHE_INVAL" description="Level 2 data cache invalidate"/>
+ <!-- 0x60 BUS_ACCESS_LD - Bus access - Read -->
+ <event event="0x60" title="-" name="BUS_ACCESS_LD" description="Bus access - Read"/>
+ <!-- 0x61 BUS_ACCESS_ST - Bus access - Write -->
+ <event event="0x61" title="-" name="BUS_ACCESS_ST" description="Bus access - Write"/>
+ <!-- 0x62 BUS_ACCESS_SHARED - Bus access - Normal -->
+ <event event="0x62" title="-" name="BUS_ACCESS_SHARED" description="Bus access - Normal"/>
+ <!-- 0x63 BUS_ACCESS_NOT_SHARED - Bus access - Not normal -->
+ <event event="0x63" title="-" name="BUS_ACCESS_NOT_SHARED" description="Bus access - Not normal"/>
+ <!-- 0x64 BUS_ACCESS_NORMAL - Bus access - Normal -->
+ <event event="0x64" title="-" name="BUS_ACCESS_NORMAL" description="Bus access - Normal"/>
+ <!-- 0x65 BUS_ACCESS_PERIPH - Bus access - Peripheral -->
+ <event event="0x65" title="-" name="BUS_ACCESS_PERIPH" description="Bus access - Peripheral"/>
+ <!-- 0x66 MEM_ACCESS_LD - Data memory access - Read -->
+ <event event="0x66" title="-" name="MEM_ACCESS_LD" description="Data memory access - Read"/>
+ <!-- 0x67 MEM_ACCESS_ST - Data memory access - Write -->
+ <event event="0x67" title="-" name="MEM_ACCESS_ST" description="Data memory access - Write"/>
+ <!-- 0x68 UNALIGNED_LD_SPEC - Unaligned access - Read -->
+ <event event="0x68" title="-" name="UNALIGNED_LD_SPEC" description="Unaligned access - Read"/>
+ <!-- 0x69 UNALIGNED_ST_SPEC - Unaligned access - Write -->
+ <event event="0x69" title="-" name="UNALIGNED_ST_SPEC" description="Unaligned access - Write"/>
+ <!-- 0x6A UNALIGNED_LDST_SPEC - Unaligned access -->
+ <event event="0x6A" title="-" name="UNALIGNED_LDST_SPEC" description="Unaligned access"/>
+ <!-- 0x6C LDREX_SPEC - Exclusive operation speculatively executed - LDREX -->
+ <event event="0x6C" title="-" name="LDREX_SPEC" description="Exclusive operation speculatively executed - LDREX"/>
+ <!-- 0x6D STREX_PASS_SPEC - Exclusive instruction speculatively executed - STREX pass -->
+ <event event="0x6D" title="-" name="STREX_PASS_SPEC" description="Exclusive instruction speculatively executed - STREX pass"/>
+ <!-- 0x6E STREX_FAIL_SPEC - Exclusive operation speculatively executed - STREX fail -->
+ <event event="0x6E" title="-" name="STREX_FAIL_SPEC" description="Exclusive operation speculatively executed - STREX fail"/>
+ <!-- 0x70 LD_SPEC - Operation speculatively executed - Load -->
+ <event event="0x70" title="-" name="LD_SPEC" description="Operation speculatively executed - Load"/>
+ <!-- 0x71 ST_SPEC - Operation speculatively executed - Store -->
+ <event event="0x71" title="-" name="ST_SPEC" description="Operation speculatively executed - Store"/>
+ <!-- 0x72 LDST_SPEC - Operation speculatively executed - Load or store -->
+ <event event="0x72" title="-" name="LDST_SPEC" description="Operation speculatively executed - Load or store"/>
+ <!-- 0x73 DP_SPEC - Operation speculatively executed - Integer data processing -->
+ <event event="0x73" title="-" name="DP_SPEC" description="Operation speculatively executed - Integer data processing"/>
+ <!-- 0x74 ASE_SPEC - Operation speculatively executed - Advanced SIMD -->
+ <event event="0x74" title="-" name="ASE_SPEC" description="Operation speculatively executed - Advanced SIMD"/>
+ <!-- 0x75 VFP_SPEC - Operation speculatively executed - VFP -->
+ <event event="0x75" title="-" name="VFP_SPEC" description="Operation speculatively executed - VFP"/>
+ <!-- 0x76 PC_WRITE_SPEC - Operation speculatively executed - Software change of the PC -->
+ <event event="0x76" title="-" name="PC_WRITE_SPEC" description="Operation speculatively executed - Software change of the PC"/>
+ <!-- 0x77 CRYPTO_SPEC - Operation speculatively executed, crypto data processing -->
+ <event event="0x77" title="-" name="CRYPTO_SPEC" description="Operation speculatively executed, crypto data processing"/>
+ <!-- 0x78 BR_IMMED_SPEC - Branch speculatively executed - Immediate branch -->
+ <event event="0x78" title="-" name="BR_IMMED_SPEC" description="Branch speculatively executed - Immediate branch"/>
+ <!-- 0x79 BR_RETURN_SPEC - Branch speculatively executed - Procedure return -->
+ <event event="0x79" title="-" name="BR_RETURN_SPEC" description="Branch speculatively executed - Procedure return"/>
+ <!-- 0x7A BR_INDIRECT_SPEC - Branch speculatively executed - Indirect branch -->
+ <event event="0x7A" title="-" name="BR_INDIRECT_SPEC" description="Branch speculatively executed - Indirect branch"/>
+ <!-- 0x7C ISB_SPEC - Barrier speculatively executed - ISB -->
+ <event event="0x7C" title="-" name="ISB_SPEC" description="Barrier speculatively executed - ISB"/>
+ <!-- 0x7D DSB_SPEC - Barrier speculatively executed - DSB -->
+ <event event="0x7D" title="-" name="DSB_SPEC" description="Barrier speculatively executed - DSB"/>
+ <!-- 0x7E DMB_SPEC - Barrier speculatively executed - DMB -->
+ <event event="0x7E" title="-" name="DMB_SPEC" description="Barrier speculatively executed - DMB"/>
+ <!-- 0x81 EXC_UNDEF - Exception taken, other synchronous -->
+ <event event="0x81" title="-" name="EXC_UNDEF" description="Exception taken, other synchronous"/>
+ <!-- 0x82 EXC_SVC - Exception taken, Supervisor Call -->
+ <event event="0x82" title="-" name="EXC_SVC" description="Exception taken, Supervisor Call"/>
+ <!-- 0x83 EXC_PABORT - Exception taken, Instruction Abort -->
+ <event event="0x83" title="-" name="EXC_PABORT" description="Exception taken, Instruction Abort"/>
+ <!-- 0x84 EXC_DABORT - Exception taken, Data Abort or SError -->
+ <event event="0x84" title="-" name="EXC_DABORT" description="Exception taken, Data Abort or SError"/>
+ <!-- 0x86 EXC_IRQ - Exception taken, IRQ -->
+ <event event="0x86" title="-" name="EXC_IRQ" description="Exception taken, IRQ"/>
+ <!-- 0x87 EXC_FIQ - Exception taken, FIQ -->
+ <event event="0x87" title="-" name="EXC_FIQ" description="Exception taken, FIQ"/>
+ <!-- 0x88 EXC_SMC - Exception taken, Secure Monitor Call -->
+ <event event="0x88" title="-" name="EXC_SMC" description="Exception taken, Secure Monitor Call"/>
+ <!-- 0x8A EXC_HVC - Exception taken, Hypervisor Call -->
+ <event event="0x8A" title="-" name="EXC_HVC" description="Exception taken, Hypervisor Call"/>
+ <!-- 0x8B EXC_TRAP_PABORT - Exception taken, Instruction Abort not taken locally -->
+ <event event="0x8B" title="-" name="EXC_TRAP_PABORT" description="Exception taken, Instruction Abort not taken locally"/>
+ <!-- 0x8C EXC_TRAP_DABORT - Exception taken, Data Abort or SError not taken locally -->
+ <event event="0x8C" title="-" name="EXC_TRAP_DABORT" description="Exception taken, Data Abort or SError not taken locally"/>
+ <!-- 0x8D EXC_TRAP_OTHER - Exception taken – Other traps not taken locally -->
+ <event event="0x8D" title="-" name="EXC_TRAP_OTHER" description="Exception taken – Other traps not taken locally"/>
+ <!-- 0x8E EXC_TRAP_IRQ - Exception taken, IRQ not taken locally -->
+ <event event="0x8E" title="-" name="EXC_TRAP_IRQ" description="Exception taken, IRQ not taken locally"/>
+ <!-- 0x8F EXC_TRAP_FIQ - Exception taken, FIQ not taken locally -->
+ <event event="0x8F" title="-" name="EXC_TRAP_FIQ" description="Exception taken, FIQ not taken locally"/>
+ <!-- 0x90 RC_LD_SPEC - Release consistency instruction speculatively executed – Load Acquire -->
+ <event event="0x90" title="-" name="RC_LD_SPEC" description="Release consistency instruction speculatively executed – Load Acquire"/>
+ <!-- 0x91 RC_ST_SPEC - Release consistency instruction speculatively executed – Store Release -->
+ <event event="0x91" title="-" name="RC_ST_SPEC" description="Release consistency instruction speculatively executed – Store Release"/>
+ </category>
diff --git a/daemon/events-Cortex-A57.xml b/daemon/events-Cortex-A57.xml
new file mode 100644
index 0000000..5db6dc2
--- /dev/null
+++ b/daemon/events-Cortex-A57.xml
@@ -0,0 +1,171 @@
+ <counter_set name="ARM_Cortex-A57_cnt" count="6"/>
+ <category name="Cortex-A57" counter_set="ARM_Cortex-A57_cnt" per_cpu="yes" supports_event_based_sampling="yes">
+ <!-- 0x11 CPU_CYCLES - Cycle -->
+ <event counter="ARM_Cortex-A57_ccnt" title="Clock" name="Cycles" display="hertz" units="Hz" average_selection="yes" description="The number of core clock cycles"/>
+ <!-- 0x00 SW_INCR - Instruction architecturally executed number (condition check pass) - Software increment -->
+ <event event="0x00" title="Software" name="Increment" description="Incremented only on writes to the Software Increment Register"/>
+ <!-- 0x01 L1I_CACHE_REFILL - Level 1 instruction cache refill -->
+ <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"/>
+ <!-- 0x02 L1I_TLB_REFILL - Level 1 instruction TLB refill -->
+ <event event="0x02" title="Cache" name="Inst TLB refill" description="Instruction fetch that causes a TLB refill of at least the level of TLB closest to the processor"/>
+ <!-- 0x03 L1D_CACHE_REFILL - Level 1 data cache refill -->
+ <event event="0x03" title="Cache" name="Data refill" description="Memory Read or Write operation that causes a refill of at least the level of data or unified cache closest to the processor"/>
+ <!-- 0x04 L1D_CACHE - Level 1 data cache access -->
+ <event event="0x04" title="Cache" name="Data access" description="Memory Read or Write operation that causes a cache access to at least the level of data or unified cache closest to the processor"/>
+ <!-- 0x05 L1D_TLB_REFILL - Level 1 data TLB refill -->
+ <event event="0x05" title="Cache" name="Data TLB refill" description="Memory Read or Write operation that causes a TLB refill of at least the level of TLB closest to the processor"/>
+ <!-- 0x08 INST_RETIRED - Instruction architecturally executed -->
+ <event event="0x08" title="-" name="INST_RETIRED" description="Instruction architecturally executed"/>
+ <!-- 0x09 EXC_TAKEN - Exception taken -->
+ <event event="0x09" title="Exception" name="Taken" description="Exceptions taken"/>
+ <!-- 0x0A EXC_RETURN - Instruction architecturally executed (condition check pass) - Exception return -->
+ <event event="0x0a" title="Exception" name="Return" description="Exception return architecturally executed"/>
+ <!-- 0x0B CID_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to CONTEXTIDR -->
+ <event event="0x0b" title="Instruction" name="CONTEXTIDR" description="Instruction that writes to the CONTEXTIDR architecturally executed"/>
+ <!-- 0x10 BR_MIS_PRED - Mispredicted or not predicted branch speculatively executed -->
+ <event event="0x10" title="Branch" name="Mispredicted" description="Branch mispredicted or not predicted"/>
+ <!-- 0x12 BR_PRED - Predictable branch speculatively executed -->
+ <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"/>
+ <!-- 0x13 MEM_ACCESS - Data memory access -->
+ <event event="0x13" title="-" name="MEM_ACCESS" description="Data memory access"/>
+ <!-- 0x14 L1I_CACHE - Level 1 instruction cache access -->
+ <event event="0x14" title="-" name="L1I_CACHE" description="Level 1 instruction cache access"/>
+ <!-- 0x15 L1D_CACHE_WB - Level 1 data cache Write-Back -->
+ <event event="0x15" title="-" name="L1D_CACHE_WB" description="Level 1 data cache Write-Back"/>
+ <!-- 0x16 L2D_CACHE - Level 2 data cache access -->
+ <event event="0x16" title="-" name="L2D_CACHE" description="Level 2 data cache access"/>
+ <!-- 0x17 L2D_CACHE_REFILL - Level 2 data cache refill -->
+ <event event="0x17" title="-" name="L2D_CACHE_REFILL" description="Level 2 data cache refill"/>
+ <!-- 0x18 L2D_CACHE_WB - Level 2 data cache Write-Back -->
+ <event event="0x18" title="-" name="L2D_CACHE_WB" description="Level 2 data cache Write-Back"/>
+ <!-- 0x19 BUS_ACCESS - Bus access -->
+ <event event="0x19" title="-" name="BUS_ACCESS" description="Bus access"/>
+ <!-- 0x1A MEMORY_ERROR - Local memory error -->
+ <event event="0x1A" title="-" name="MEMORY_ERROR" description="Local memory error"/>
+ <!-- 0x1B INST_SPEC - Operation speculatively executed -->
+ <event event="0x1B" title="-" name="INST_SPEC" description="Operation speculatively executed"/>
+ <!-- 0x1C TTBR_WRITE_RETIRED - Instruction architecturally executed (condition check pass) - Write to translation table base -->
+ <event event="0x1C" title="-" name="TTBR_WRITE_RETIRED" description="Instruction architecturally executed (condition check pass) - Write to translation table base"/>
+ <!-- 0x1D BUS_CYCLES - Bus cycle -->
+ <event event="0x1D" title="-" name="BUS_CYCLES" description="Bus cycle"/>
+ <!-- 0x1E CHAIN - Odd performance counter chain mode -->
+ <event event="0x1E" title="-" name="CHAIN" description="Odd performance counter chain mode"/>
+ <!-- 0x40 L1D_CACHE_LD - Level 1 data cache access - Read -->
+ <event event="0x40" title="-" name="L1D_CACHE_LD" description="Level 1 data cache access - Read"/>
+ <!-- 0x41 L1D_CACHE_ST - Level 1 data cache access - Write -->
+ <event event="0x41" title="-" name="L1D_CACHE_ST" description="Level 1 data cache access - Write"/>
+ <!-- 0x42 L1D_CACHE_REFILL_LD - Level 1 data cache refill - Read -->
+ <event event="0x42" title="-" name="L1D_CACHE_REFILL_LD" description="Level 1 data cache refill - Read"/>
+ <!-- 0x43 L1D_CACHE_REFILL_ST - Level 1 data cache refill - Write -->
+ <event event="0x43" title="-" name="L1D_CACHE_REFILL_ST" description="Level 1 data cache refill - Write"/>
+ <!-- 0x46 L1D_CACHE_WB_VICTIM - Level 1 data cache Write-back - Victim -->
+ <event event="0x46" title="-" name="L1D_CACHE_WB_VICTIM" description="Level 1 data cache Write-back - Victim"/>
+ <!-- 0x47 L1D_CACHE_WB_CLEAN - Level 1 data cache Write-back - Cleaning and coherency -->
+ <event event="0x47" title="-" name="L1D_CACHE_WB_CLEAN" description="Level 1 data cache Write-back - Cleaning and coherency"/>
+ <!-- 0x48 L1D_CACHE_INVAL - Level 1 data cache invalidate -->
+ <event event="0x48" title="-" name="L1D_CACHE_INVAL" description="Level 1 data cache invalidate"/>
+ <!-- 0x4C L1D_TLB_REFILL_LD - Level 1 data TLB refill - Read -->
+ <event event="0x4C" title="-" name="L1D_TLB_REFILL_LD" description="Level 1 data TLB refill - Read"/>
+ <!-- 0x4D L1D_TLB_REFILL_ST - Level 1 data TLB refill - Write -->
+ <event event="0x4D" title="-" name="L1D_TLB_REFILL_ST" description="Level 1 data TLB refill - Write"/>
+ <!-- 0x50 L2D_CACHE_LD - Level 2 data cache access - Read -->
+ <event event="0x50" title="-" name="L2D_CACHE_LD" description="Level 2 data cache access - Read"/>
+ <!-- 0x51 L2D_CACHE_ST - Level 2 data cache access - Write -->
+ <event event="0x51" title="-" name="L2D_CACHE_ST" description="Level 2 data cache access - Write"/>
+ <!-- 0x52 L2D_CACHE_REFILL_LD - Level 2 data cache refill - Read -->
+ <event event="0x52" title="-" name="L2D_CACHE_REFILL_LD" description="Level 2 data cache refill - Read"/>
+ <!-- 0x53 L2D_CACHE_REFILL_ST - Level 2 data cache refill - Write -->
+ <event event="0x53" title="-" name="L2D_CACHE_REFILL_ST" description="Level 2 data cache refill - Write"/>
+ <!-- 0x56 L2D_CACHE_WB_VICTIM - Level 2 data cache Write-back - Victim -->
+ <event event="0x56" title="-" name="L2D_CACHE_WB_VICTIM" description="Level 2 data cache Write-back - Victim"/>
+ <!-- 0x57 L2D_CACHE_WB_CLEAN - Level 2 data cache Write-back - Cleaning and coherency -->
+ <event event="0x57" title="-" name="L2D_CACHE_WB_CLEAN" description="Level 2 data cache Write-back - Cleaning and coherency"/>
+ <!-- 0x58 L2D_CACHE_INVAL - Level 2 data cache invalidate -->
+ <event event="0x58" title="-" name="L2D_CACHE_INVAL" description="Level 2 data cache invalidate"/>
+ <!-- 0x60 BUS_ACCESS_LD - Bus access - Read -->
+ <event event="0x60" title="-" name="BUS_ACCESS_LD" description="Bus access - Read"/>
+ <!-- 0x61 BUS_ACCESS_ST - Bus access - Write -->
+ <event event="0x61" title="-" name="BUS_ACCESS_ST" description="Bus access - Write"/>
+ <!-- 0x62 BUS_ACCESS_SHARED - Bus access - Normal -->
+ <event event="0x62" title="-" name="BUS_ACCESS_SHARED" description="Bus access - Normal"/>
+ <!-- 0x63 BUS_ACCESS_NOT_SHARED - Bus access - Not normal -->
+ <event event="0x63" title="-" name="BUS_ACCESS_NOT_SHARED" description="Bus access - Not normal"/>
+ <!-- 0x64 BUS_ACCESS_NORMAL - Bus access - Normal -->
+ <event event="0x64" title="-" name="BUS_ACCESS_NORMAL" description="Bus access - Normal"/>
+ <!-- 0x65 BUS_ACCESS_PERIPH - Bus access - Peripheral -->
+ <event event="0x65" title="-" name="BUS_ACCESS_PERIPH" description="Bus access - Peripheral"/>
+ <!-- 0x66 MEM_ACCESS_LD - Data memory access - Read -->
+ <event event="0x66" title="-" name="MEM_ACCESS_LD" description="Data memory access - Read"/>
+ <!-- 0x67 MEM_ACCESS_ST - Data memory access - Write -->
+ <event event="0x67" title="-" name="MEM_ACCESS_ST" description="Data memory access - Write"/>
+ <!-- 0x68 UNALIGNED_LD_SPEC - Unaligned access - Read -->
+ <event event="0x68" title="-" name="UNALIGNED_LD_SPEC" description="Unaligned access - Read"/>
+ <!-- 0x69 UNALIGNED_ST_SPEC - Unaligned access - Write -->
+ <event event="0x69" title="-" name="UNALIGNED_ST_SPEC" description="Unaligned access - Write"/>
+ <!-- 0x6A UNALIGNED_LDST_SPEC - Unaligned access -->
+ <event event="0x6A" title="-" name="UNALIGNED_LDST_SPEC" description="Unaligned access"/>
+ <!-- 0x6C LDREX_SPEC - Exclusive operation speculatively executed - LDREX -->
+ <event event="0x6C" title="-" name="LDREX_SPEC" description="Exclusive operation speculatively executed - LDREX"/>
+ <!-- 0x6D STREX_PASS_SPEC - Exclusive instruction speculatively executed - STREX pass -->
+ <event event="0x6D" title="-" name="STREX_PASS_SPEC" description="Exclusive instruction speculatively executed - STREX pass"/>
+ <!-- 0x6E STREX_FAIL_SPEC - Exclusive operation speculatively executed - STREX fail -->
+ <event event="0x6E" title="-" name="STREX_FAIL_SPEC" description="Exclusive operation speculatively executed - STREX fail"/>
+ <!-- 0x70 LD_SPEC - Operation speculatively executed - Load -->
+ <event event="0x70" title="-" name="LD_SPEC" description="Operation speculatively executed - Load"/>
+ <!-- 0x71 ST_SPEC - Operation speculatively executed - Store -->
+ <event event="0x71" title="-" name="ST_SPEC" description="Operation speculatively executed - Store"/>
+ <!-- 0x72 LDST_SPEC - Operation speculatively executed - Load or store -->
+ <event event="0x72" title="-" name="LDST_SPEC" description="Operation speculatively executed - Load or store"/>
+ <!-- 0x73 DP_SPEC - Operation speculatively executed - Integer data processing -->
+ <event event="0x73" title="-" name="DP_SPEC" description="Operation speculatively executed - Integer data processing"/>
+ <!-- 0x74 ASE_SPEC - Operation speculatively executed - Advanced SIMD -->
+ <event event="0x74" title="-" name="ASE_SPEC" description="Operation speculatively executed - Advanced SIMD"/>
+ <!-- 0x75 VFP_SPEC - Operation speculatively executed - VFP -->
+ <event event="0x75" title="-" name="VFP_SPEC" description="Operation speculatively executed - VFP"/>
+ <!-- 0x76 PC_WRITE_SPEC - Operation speculatively executed - Software change of the PC -->
+ <event event="0x76" title="-" name="PC_WRITE_SPEC" description="Operation speculatively executed - Software change of the PC"/>
+ <!-- 0x77 CRYPTO_SPEC - Operation speculatively executed, crypto data processing -->
+ <event event="0x77" title="-" name="CRYPTO_SPEC" description="Operation speculatively executed, crypto data processing"/>
+ <!-- 0x78 BR_IMMED_SPEC - Branch speculatively executed - Immediate branch -->
+ <event event="0x78" title="-" name="BR_IMMED_SPEC" description="Branch speculatively executed - Immediate branch"/>
+ <!-- 0x79 BR_RETURN_SPEC - Branch speculatively executed - Procedure return -->
+ <event event="0x79" title="-" name="BR_RETURN_SPEC" description="Branch speculatively executed - Procedure return"/>
+ <!-- 0x7A BR_INDIRECT_SPEC - Branch speculatively executed - Indirect branch -->
+ <event event="0x7A" title="-" name="BR_INDIRECT_SPEC" description="Branch speculatively executed - Indirect branch"/>
+ <!-- 0x7C ISB_SPEC - Barrier speculatively executed - ISB -->
+ <event event="0x7C" title="-" name="ISB_SPEC" description="Barrier speculatively executed - ISB"/>
+ <!-- 0x7D DSB_SPEC - Barrier speculatively executed - DSB -->
+ <event event="0x7D" title="-" name="DSB_SPEC" description="Barrier speculatively executed - DSB"/>
+ <!-- 0x7E DMB_SPEC - Barrier speculatively executed - DMB -->
+ <event event="0x7E" title="-" name="DMB_SPEC" description="Barrier speculatively executed - DMB"/>
+ <!-- 0x81 EXC_UNDEF - Exception taken, other synchronous -->
+ <event event="0x81" title="-" name="EXC_UNDEF" description="Exception taken, other synchronous"/>
+ <!-- 0x82 EXC_SVC - Exception taken, Supervisor Call -->
+ <event event="0x82" title="-" name="EXC_SVC" description="Exception taken, Supervisor Call"/>
+ <!-- 0x83 EXC_PABORT - Exception taken, Instruction Abort -->
+ <event event="0x83" title="-" name="EXC_PABORT" description="Exception taken, Instruction Abort"/>
+ <!-- 0x84 EXC_DABORT - Exception taken, Data Abort or SError -->
+ <event event="0x84" title="-" name="EXC_DABORT" description="Exception taken, Data Abort or SError"/>
+ <!-- 0x86 EXC_IRQ - Exception taken, IRQ -->
+ <event event="0x86" title="-" name="EXC_IRQ" description="Exception taken, IRQ"/>
+ <!-- 0x87 EXC_FIQ - Exception taken, FIQ -->
+ <event event="0x87" title="-" name="EXC_FIQ" description="Exception taken, FIQ"/>
+ <!-- 0x88 EXC_SMC - Exception taken, Secure Monitor Call -->
+ <event event="0x88" title="-" name="EXC_SMC" description="Exception taken, Secure Monitor Call"/>
+ <!-- 0x8A EXC_HVC - Exception taken, Hypervisor Call -->
+ <event event="0x8A" title="-" name="EXC_HVC" description="Exception taken, Hypervisor Call"/>
+ <!-- 0x8B EXC_TRAP_PABORT - Exception taken, Instruction Abort not taken locally -->
+ <event event="0x8B" title="-" name="EXC_TRAP_PABORT" description="Exception taken, Instruction Abort not taken locally"/>
+ <!-- 0x8C EXC_TRAP_DABORT - Exception taken, Data Abort or SError not taken locally -->
+ <event event="0x8C" title="-" name="EXC_TRAP_DABORT" description="Exception taken, Data Abort or SError not taken locally"/>
+ <!-- 0x8D EXC_TRAP_OTHER - Exception taken – Other traps not taken locally -->
+ <event event="0x8D" title="-" name="EXC_TRAP_OTHER" description="Exception taken – Other traps not taken locally"/>
+ <!-- 0x8E EXC_TRAP_IRQ - Exception taken, IRQ not taken locally -->
+ <event event="0x8E" title="-" name="EXC_TRAP_IRQ" description="Exception taken, IRQ not taken locally"/>
+ <!-- 0x8F EXC_TRAP_FIQ - Exception taken, FIQ not taken locally -->
+ <event event="0x8F" title="-" name="EXC_TRAP_FIQ" description="Exception taken, FIQ not taken locally"/>
+ <!-- 0x90 RC_LD_SPEC - Release consistency instruction speculatively executed – Load Acquire -->
+ <event event="0x90" title="-" name="RC_LD_SPEC" description="Release consistency instruction speculatively executed – Load Acquire"/>
+ <!-- 0x91 RC_ST_SPEC - Release consistency instruction speculatively executed – Store Release -->
+ <event event="0x91" title="-" name="RC_ST_SPEC" description="Release consistency instruction speculatively executed – Store Release"/>
+ </category>
diff --git a/daemon/events-Cortex-A7.xml b/daemon/events-Cortex-A7.xml
index 2bd4797..50bba7f 100644
--- a/daemon/events-Cortex-A7.xml
+++ b/daemon/events-Cortex-A7.xml
@@ -41,4 +41,4 @@
<event event="0xC8" title="ETM" name="ETM Ext Out[1]" description=""/>
<event event="0xC9" title="Instruction" name="Pipeline stall" description="Data Write operation that stalls the pipeline because the store buffer is full"/>
<event event="0xCA" title="Memory" name="Snoop" description="Data snooped from other processor. This event counts memory-read operations that read data from another processor within the local cluster, rather than accessing the L2 cache or issuing an external read."/>
- </category>
+ </category>
diff --git a/daemon/events-Cortex-A9.xml b/daemon/events-Cortex-A9.xml
index 7597f78..89d6a19 100644
--- a/daemon/events-Cortex-A9.xml
+++ b/daemon/events-Cortex-A9.xml
@@ -31,9 +31,9 @@
<event event="0x66" title="Pipeline" name="Issue stage no dispatch" description="Counts the number of cycles where the issue stage does not dispatch any instruction because it is empty or cannot dispatch any instructions"/>
<event event="0x67" title="Pipeline" name="Issue stage empty" description="Counts the number of cycles where the issue stage is empty"/>
<event event="0x68" title="Instruction" name="Executed" description="Counts the number of instructions going through the Register Renaming stage. This number is an approximate number of the total number of instructions speculatively executed, and even more approximate of the total number of instructions architecturally executed"/>
- <event event="0x69" title="Cache" name="Data linefills" description="Counts the number of linefills performed on the external AXI bus"/>
- <event event="0x6A" title="Cache" name="Prefetch linefills" description="Counts the number of data linefills caused by prefetcher requests"/>
- <event event="0x6B" title="Cache" name="Prefetch hits" description="Counts the number of cache hits in a line that belongs to a stream followed by the prefetcher"/>
+ <event event="0x69" title="Cache" name="Data linefills" description="Counts the number of linefills performed on the external AXI bus"/>
+ <event event="0x6A" title="Cache" name="Prefetch linefills" description="Counts the number of data linefills caused by prefetcher requests"/>
+ <event event="0x6B" title="Cache" name="Prefetch hits" description="Counts the number of cache hits in a line that belongs to a stream followed by the prefetcher"/>
<event event="0x6E" title="Core" name="Functions" description="Counts the number of procedure returns whose condition codes do not fail, excluding all returns from exception"/>
<event event="0x70" title="Instruction" name="Main execution unit" description="Counts the number of instructions being executed in the main execution pipeline of the processor, the multiply pipeline and arithmetic logic unit pipeline"/>
<event event="0x71" title="Instruction" name="Second execution unit" description="Counts the number of instructions being executed in the processor second execution pipeline (ALU)"/>
@@ -49,9 +49,9 @@
<event event="0x86" title="Stalls" name="DMB" description="Counts the number of stall cycles because of the execution of a DMB memory barrier"/>
<event event="0x8A" title="Clock" name="Integer core" description="Counts the number of cycles during which the integer core clock is enabled"/>
<event event="0x8B" title="Clock" name="Data engine" description="Counts the number of cycles during which the Data Engine clock is enabled"/>
- <event event="0x8C" title="Clock" name="NEON" description="Counts the number of cycles when the NEON SIMD clock is enabled"/>
- <event event="0x8D" title="Memory" name="TLB inst allocations" description="Counts the number of TLB allocations because of Instruction requests"/>
- <event event="0x8E" title="Memory" name="TLB data allocations" description="Counts the number of TLB allocations because of Data requests"/>
+ <event event="0x8C" title="Clock" name="NEON" description="Counts the number of cycles when the NEON SIMD clock is enabled"/>
+ <event event="0x8D" title="Memory" name="TLB inst allocations" description="Counts the number of TLB allocations because of Instruction requests"/>
+ <event event="0x8E" title="Memory" name="TLB data allocations" description="Counts the number of TLB allocations because of Data requests"/>
<event event="0x90" title="Instruction" name="ISB" description="Counts the number of ISB instructions architecturally executed"/>
<event event="0x91" title="Instruction" name="DSB" description="Counts the number of DSB instructions architecturally executed"/>
<event event="0x92" title="Instruction" name="DMB" description="Counts the number of DMB instructions speculatively executed"/>
diff --git a/daemon/events-Linux.xml b/daemon/events-Linux.xml
index b45a122..42baf14 100644
--- a/daemon/events-Linux.xml
+++ b/daemon/events-Linux.xml
@@ -8,8 +8,8 @@
<event counter="Linux_sched_switch" title="Scheduler" name="Switch" per_cpu="yes" description="Context switch events"/>
<event counter="Linux_meminfo_memused" title="Memory" name="Used" display="maximum" units="B" average_selection="yes" description="Total used memory size"/>
<event counter="Linux_meminfo_memfree" title="Memory" name="Free" display="minimum" units="B" average_selection="yes" description="Available memory size"/>
- <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" display="maximum" units="B" average_selection="yes" description="Memory used by buffers"/>
+ <event counter="Linux_meminfo_bufferram" title="Memory" name="Buffer" display="maximum" units="B" average_selection="yes" description="Memory used by OS disk buffers"/>
<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"/>
<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"/>
</category>
-
+
diff --git a/daemon/events-Mali-400.xml b/daemon/events-Mali-400.xml
index 6830d46..cb0b9d5 100644
--- a/daemon/events-Mali-400.xml
+++ b/daemon/events-Mali-400.xml
@@ -30,7 +30,7 @@
<event event="0x1b" title="Mali GPU Vertex Processor" name="Active cycles, PLBU primitive assembly" description="Number of active cycles per frame spent by the MaliGP2 PLBU doing primitive assembly. This does not include scissoring or final output. This includes time spent waiting on the bus."/>
<event event="0x1c" title="Mali GPU Vertex Processor" name="Active cycles, PLBU vertex fetcher" description="Number of active cycles per frame spent by the MaliGP2 PLBU fetching vertex data. This includes time spent waiting on the bus."/>
<event event="0x1e" title="Mali GPU Vertex Processor" name="Active cycles, Bounding-box and command generator" description="Number of active cycles per frame spent by the MaliGP2 PLBU setting up bounding boxes and commands (mainly graphics primitives). This includes time spent waiting on the bus."/>
- <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."/>
+ <event event="0x20" title="Mali GPU Vertex Processor" name="Active cycles, Scissor tile iterator" description="Number of active cycles per frame spent by the MaliGP2 PLBU iterating over tiles to perform scissoring. This includes time spent waiting on the bus."/>
<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."/>
</category>
<category name="Mali-400-FP0" counter_set="ARM_Mali-400_FP0_cnt" per_cpu="no">
@@ -344,10 +344,10 @@
</category>
<category name="Mali-400-SW" counter_set="ARM_Mali-400_SW_cnt" per_cpu="no">
<!-- EGL Counters -->
- <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."/>
+ <event counter="ARM_Mali-400_SW_17" title="Mali EGL Software Counters" name="Blit Time" description="Time spent blitting the framebuffer from video memory to framebuffer."/>
<!-- glDrawElements Counters -->
<event counter="ARM_Mali-400_SW_18" title="glDrawElements Statistics" name="Calls to glDrawElements" description="Number of calls to glDrawElements."/>
- <event counter="ARM_Mali-400_SW_19" title="glDrawElements Statistics" name="Indices to glDrawElements" description="Number of indicies to glDrawElements."/>
+ <event counter="ARM_Mali-400_SW_19" title="glDrawElements Statistics" name="Indices to glDrawElements" description="Number of indices to glDrawElements."/>
<event counter="ARM_Mali-400_SW_20" title="glDrawElements Statistics" name="Transformed by glDrawElements" description="Number of vertices transformed by glDrawElements."/>
<!-- glDrawArrays Counters -->
<event counter="ARM_Mali-400_SW_21" title="glDrawArrays Statistics" name="Calls to glDrawArrays" description="Number of calls to glDrawArrays."/>
@@ -365,7 +365,7 @@
<!-- Buffer Profiling Counters -->
<event counter="ARM_Mali-400_SW_32" title="Buffer Profiling" name="Texture Upload Time (ms)" description="Time spent uploading textures."/>
<event counter="ARM_Mali-400_SW_33" title="Buffer Profiling" name="VBO Upload Time (ms)" description="Time spent uploading vertex buffer objects."/>
- <event counter="ARM_Mali-400_SW_34" title="Buffer Profiling" name="FBO Flushes" description="Number of flushed on framebuffer attachement."/>
+ <event counter="ARM_Mali-400_SW_34" title="Buffer Profiling" name="FBO Flushes" description="Number of flushed on framebuffer attachment."/>
<!-- OpenGL ES 1.1 Emulation -->
<event counter="ARM_Mali-400_SW_35" title="Fixed-function Emulation" name="# Vertex Shaders Generated" description="Number of vertex shaders generated."/>
<event counter="ARM_Mali-400_SW_36" title="Fixed-function Emulation" name="# Fragment Shaders Generated" description="Number of fragment shaders generated."/>
diff --git a/daemon/events-Mali-T6xx.xml b/daemon/events-Mali-T6xx.xml
index 5237e30..3d795de 100644
--- a/daemon/events-Mali-T6xx.xml
+++ b/daemon/events-Mali-T6xx.xml
@@ -1,8 +1,8 @@
-
+
<category name="Mali-T6xx-SW-counters" per_cpu="no">
<event counter="ARM_Mali-T6xx_TOTAL_ALLOC_PAGES" title="Mali Total Alloc Pages" name="Total number of allocated pages" description="Mali total number of allocated pages."/>
</category>
-
+
<category name="Mali-T6xx-PMShader" per_cpu="no">
<event counter="ARM_Mali-T6xx_PM_SHADER_0" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 0" description="Mali PM Shader: PM Shader Core 0."/>
<event counter="ARM_Mali-T6xx_PM_SHADER_1" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 1" description="Mali PM Shader: PM Shader Core 1."/>
@@ -13,23 +13,23 @@
<event counter="ARM_Mali-T6xx_PM_SHADER_6" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 6" description="Mali PM Shader: PM Shader Core 6."/>
<event counter="ARM_Mali-T6xx_PM_SHADER_7" display="average" average_selection="yes" units="%" title="Mali PM Shader" name="PM Shader Core 7" description="Mali PM Shader: PM Shader Core 7."/>
</category>
-
+
<category name="Mali-T6xx-PMTiler" per_cpu="no">
<event counter="ARM_Mali-T6xx_PM_TILER_0" display="average" average_selection="yes" units="%" title="Mali PM Tiler" name="PM Tiler Core 0" description="Mali PM Tiler: PM Tiler Core 0."/>
</category>
-
+
<category name="Mali-T6xx-PML2" per_cpu="no">
<event counter="ARM_Mali-T6xx_PM_L2_0" display="average" average_selection="yes" units="%" title="Mali PM L2" name="PM L2 Core 0" description="Mali PM L2: PM L2 Core 0."/>
<event counter="ARM_Mali-T6xx_PM_L2_1" display="average" average_selection="yes" units="%" title="Mali PM L2" name="PM L2 Core 1" description="Mali PM L2: PM L2 Core 1."/>
</category>
-
+
<category name="Mali-T6xx-MMU_AS" per_cpu="no">
<event counter="ARM_Mali-T6xx_MMU_AS_0" display="average" average_selection="yes" units="%" title="Mali MMU Address Space" name="MMU Address Space 0" description="Mali MMU Address Space 0 usage."/>
<event counter="ARM_Mali-T6xx_MMU_AS_1" display="average" average_selection="yes" units="%" title="Mali MMU Address Space" name="MMU Address Space 1" description="Mali MMU Address Space 1 usage."/>
<event counter="ARM_Mali-T6xx_MMU_AS_2" display="average" average_selection="yes" units="%" title="Mali MMU Address Space" name="MMU Address Space 2" description="Mali MMU Address Space 2 usage."/>
<event counter="ARM_Mali-T6xx_MMU_AS_3" display="average" average_selection="yes" units="%" title="Mali MMU Address Space" name="MMU Address Space 3" description="Mali MMU Address Space 3 usage."/>
</category>
-
+
<category name="Mali-T6xx-MMU_page_fault" per_cpu="no">
<event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_0" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 0" description="Reports the number of newly allocated pages after a MMU page fault in address space 0."/>
<event counter="ARM_Mali-T6xx_MMU_PAGE_FAULT_1" title="Mali MMU Page Fault Add. Space" name="Mali MMU Page Fault Add. Space 1" description="Reports the number of newly allocated pages after a MMU page fault in address space 1."/>
diff --git a/daemon/events-Mali-T6xx_hw.xml b/daemon/events-Mali-T6xx_hw.xml
index 77f7aec..825b668 100644
--- a/daemon/events-Mali-T6xx_hw.xml
+++ b/daemon/events-Mali-T6xx_hw.xml
@@ -1,5 +1,5 @@
- <category name="Mali-T6xx-JobManager" per_cpu="no">
+ <category name="Mali-T6xx-JobManager" per_cpu="no">
<event counter="ARM_Mali-T6xx_MESSAGES_SENT" title="Mali GPU Job Manager" name="Job Manager messages sent" description="Number of JCB messages sent by the Job Manager."/>
<event counter="ARM_Mali-T6xx_MESSAGES_RECEIVED" title="Mali GPU Job Manager" name="Job Manager messages received " description="Number of JCB messages received by the Job Manager."/>
<event counter="ARM_Mali-T6xx_GPU_ACTIVE" title="Mali GPU Job Manager" name="GPU active cycles" description="Number of cycles the GPU was active."/>
@@ -63,7 +63,7 @@
-->
</category>
- <category name="Mali-T6xx-Tiler" per_cpu="no">
+ <category name="Mali-T6xx-Tiler" per_cpu="no">
<!--
<event counter="ARM_Mali-T6xx_JOBS_PROCESSED" title="Mali GPU Tiler" name="Jobs processed" description="Number of jobs processed."/>
-->
@@ -119,7 +119,7 @@
<event counter="ARM_Mali-T6xx_WRBUF_STALL" title="Mali GPU Tiler" name="Write-buffer stalls" description="Number of write-buffer stalls."/>
<event counter="ARM_Mali-T6xx_ACTIVE" title="Mali GPU Tiler" name="Tiler active cycles" description="Number of cycles the tiler is active."/>
- <event counter="ARM_Mali-T6xx_LOADING_DESC" title="Mali GPU Tiler" name="Cycles loading descriptors" description="Number of cycle spent loading descriptors while the tiler frontend is otherwise idle."/>
+ <event counter="ARM_Mali-T6xx_LOADING_DESC" title="Mali GPU Tiler" name="Cycles loading descriptors" description="Number of cycle spent loading descriptors while the tiler frontend is otherwise idle."/>
<event counter="ARM_Mali-T6xx_INDEX_WAIT" title="Mali GPU Tiler" name="Cycles index fetch miss" description="Number of cycles the vertex cache could accept an index, but due to a miss, the index fetcher could not provide one."/>
<event counter="ARM_Mali-T6xx_INDEX_RANGE_WAIT" title="Mali GPU Tiler" name="Cycles index out of range" description="Number of cycles the index fetcher provides an index, but the index is outside the range of currently shaded vertices. Only relevant for fused jobs."/>
@@ -132,7 +132,7 @@
<event counter="ARM_Mali-T6xx_UTLB_STALL" title="Mali GPU Tiler" name="uTLB cycles stall" description="uTLB: Cycles with stall on input AXI address channel."/>
- <event counter="ARM_Mali-T6xx_UTLB_REPLAY_MISS" title="Mali GPU Tiler" name="uTLB replay buffer cache misses" description="uTLB: Number of cache misses on accesses from replay buffer."/>
+ <event counter="ARM_Mali-T6xx_UTLB_REPLAY_MISS" title="Mali GPU Tiler" name="uTLB replay buffer cache misses" description="uTLB: Number of cache misses on accesses from replay buffer."/>
<event counter="ARM_Mali-T6xx_UTLB_REPLAY_FULL" title="Mali GPU Tiler" name="uTLB cycle reply buffer full" description="uTLB: Number of cycles replay buffer is full."/>
<event counter="ARM_Mali-T6xx_UTLB_NEW_MISS" title="Mali GPU Tiler" name="uTLB cache misses on new request" description="uTLB: Number of cache misses on new requests."/>
<event counter="ARM_Mali-T6xx_UTLB_HIT" title="Mali GPU Tiler" name="uTLB cache hits" description="uTLB: Number of cache hits."/>
diff --git a/daemon/events-ScorpionMP.xml b/daemon/events-ScorpionMP.xml
index 42acc64..309f103 100644
--- a/daemon/events-ScorpionMP.xml
+++ b/daemon/events-ScorpionMP.xml
@@ -87,4 +87,4 @@
<event event="0x8d" title="Scorpion" name="EXCEPTIONS_DENORM" description="Scorpion denorm exceptions"/>
<event event="0x8e" title="ScorpionMP" name="NUM_BARRIERS" description="Barriers"/>
<event event="0x8f" title="ScorpionMP" name="BARRIER_CYCLES" description="Barrier cycles"/>
- </category>
+ </category>
diff --git a/daemon/main.cpp b/daemon/main.cpp
index 5bc75ef..894bad7 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -19,6 +19,8 @@
#include <sys/mount.h>
#include <fcntl.h>
#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include "Child.h"
#include "SessionData.h"
#include "OlySocket.h"
@@ -28,7 +30,6 @@
#define DEBUG false
extern Child* child;
-extern void handleException();
int shutdownFilesystem();
static pthread_mutex_t numSessions_mutex;
static int numSessions = 0;
@@ -297,7 +298,10 @@ struct cmdline_t parseCommandLine(int argc, char** argv) {
// Gator data flow: collector -> collector fifo -> sender
int main(int argc, char** argv, char* envp[]) {
+ // Ensure proper signal handling by making gatord the process group leader
+ // e.g. it may not be the group leader when launched as 'sudo gatord'
setsid();
+
gSessionData = new SessionData(); // Global data class
logg = new Logging(DEBUG); // Set up global thread-safe logging
util = new OlyUtility(); // Set up global utility class
@@ -314,9 +318,6 @@ int main(int argc, char** argv, char* envp[]) {
logg->logMessage("setpriority() failed");
}
- // Initialize session data
- gSessionData->initialize();
-
// Parse the command line parameters
struct cmdline_t cmdline = parseCommandLine(argc, argv);
diff --git a/driver/gator.h b/driver/gator.h
index 5a40e17..9a4617b 100644
--- a/driver/gator.h
+++ b/driver/gator.h
@@ -15,7 +15,7 @@
#include <linux/list.h>
#define GATOR_PERF_SUPPORT LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
-#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && defined(CONFIG_HW_PERF_EVENTS)
+#define GATOR_PERF_PMU_SUPPORT GATOR_PERF_SUPPORT && defined(CONFIG_PERF_EVENTS) && (!(defined(__arm__) || defined(__aarch64__)) || defined(CONFIG_HW_PERF_EVENTS))
#define GATOR_NO_PERF_SUPPORT (!(GATOR_PERF_SUPPORT))
#define GATOR_CPU_FREQ_SUPPORT (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) && defined(CONFIG_CPU_FREQ)
@@ -33,22 +33,39 @@
#define SCORPIONMP 0x02d
#define KRAITSIM 0x049
#define KRAIT 0x04d
+#define KRAIT_S4_PRO 0x06f
+#define CORTEX_A53 0xd03
+#define CORTEX_A57 0xd07
#define AARCH64 0xd0f
+#define OTHER 0xfff
+
+#define MAXSIZE_CORE_NAME 32
+
+struct gator_cpu {
+ const int cpuid;
+ const char core_name[MAXSIZE_CORE_NAME];
+ const char * const pmnc_name;
+ const int pmnc_counters;
+ const int ccnt;
+};
+
+extern struct gator_cpu gator_cpus[];
/******************************************************************************
* Filesystem
******************************************************************************/
int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
- char const *name, const struct file_operations *fops, int perm);
+ char const *name,
+ const struct file_operations *fops, int perm);
-struct dentry *gatorfs_mkdir(struct super_block *sb,
- struct dentry *root, char const *name);
+struct dentry *gatorfs_mkdir(struct super_block *sb, struct dentry *root,
+ char const *name);
int gatorfs_create_ulong(struct super_block *sb, struct dentry *root,
- char const *name, unsigned long *val);
+ char const *name, unsigned long *val);
int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root,
- char const *name, unsigned long *val);
+ char const *name, unsigned long *val);
void gator_op_create_files(struct super_block *sb, struct dentry *root);
@@ -77,15 +94,16 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root);
* Events
******************************************************************************/
struct gator_interface {
- int (*create_files)(struct super_block *sb, struct dentry *root);
- int (*start)(void);
- void (*stop)(void);
- int (*online)(int** buffer);
- int (*offline)(int** buffer);
- void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
- void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
- int (*read)(int **buffer);
- int (*read64)(long long **buffer);
+ void (*shutdown)(void); // Complementary function to init
+ int (*create_files)(struct super_block *sb, struct dentry *root);
+ int (*start)(void);
+ void (*stop)(void); // Complementary function to start
+ int (*online)(int **buffer);
+ int (*offline)(int **buffer);
+ void (*online_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
+ void (*offline_dispatch)(int cpu); // called in process context but may not be running on core 'cpu'
+ int (*read)(int **buffer);
+ int (*read64)(long long **buffer);
struct list_head list;
};
@@ -96,8 +114,8 @@ struct gator_interface {
int gator_events_install(struct gator_interface *interface);
int gator_events_get_key(void);
-extern u32 gator_cpuid(void);
+u32 gator_cpuid(void);
-void gator_backtrace_handler(struct pt_regs * const regs);
+void gator_backtrace_handler(struct pt_regs *const regs);
#endif // GATOR_H_
diff --git a/driver/gator_annotate.c b/driver/gator_annotate.c
index f2f0465..42f9951 100644
--- a/driver/gator_annotate.c
+++ b/driver/gator_annotate.c
@@ -44,21 +44,23 @@ static ssize_t annotate_write(struct file *file, char const __user *buf, size_t
return -EINVAL;
}
- // Annotation is not supported in interrupt context
+ // Annotations are not supported in interrupt context
if (in_interrupt()) {
+ printk(KERN_WARNING "gator: Annotations are not supported in interrupt context\n");
return -EINVAL;
}
- // synchronize between cores and with collect_annotations
+ // synchronize between cores and with collect_annotations
spin_lock(&annotate_lock);
- if (!collect_annotations) {
+ if (!collect_annotations) {
// Not collecting annotations, tell the caller everything was written
size = count_orig;
- goto annotate_write_out;
+ goto annotate_write_out;
}
- cpu = 0; // Annotation only uses a single per-cpu buffer as the data must be in order to the engine
+ // Annotation only uses a single per-cpu buffer as the data must be in order to the engine
+ cpu = 0;
if (current == NULL) {
pid = 0;
@@ -129,18 +131,21 @@ static int annotate_release(struct inode *inode, struct file *file)
uint32_t pid = current->pid;
gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, smp_processor_id());
gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
- gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time
- gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size
+ gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0); // time
+ gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0); // size
}
+ // Check and commit; commit is set to occur once buffer is 3/4 full
+ buffer_check(cpu, ANNOTATE_BUF);
+
spin_unlock(&annotate_lock);
return 0;
}
static const struct file_operations annotate_fops = {
- .write = annotate_write,
- .release = annotate_release
+ .write = annotate_write,
+ .release = annotate_release
};
static int gator_annotate_create_files(struct super_block *sb, struct dentry *root)
@@ -156,8 +161,8 @@ static int gator_annotate_start(void)
static void gator_annotate_stop(void)
{
- // the spinlock here will ensure that when this function exits, we are not in the middle of an annotation
- spin_lock(&annotate_lock);
+ // the spinlock here will ensure that when this function exits, we are not in the middle of an annotation
+ spin_lock(&annotate_lock);
collect_annotations = false;
- spin_unlock(&annotate_lock);
+ spin_unlock(&annotate_lock);
}
diff --git a/driver/gator_annotate_kernel.c b/driver/gator_annotate_kernel.c
index bc68fa8..67d2d6c 100644
--- a/driver/gator_annotate_kernel.c
+++ b/driver/gator_annotate_kernel.c
@@ -8,11 +8,13 @@
*/
#define ESCAPE_CODE 0x1c
-#define STRING_ANNOTATION 0x03
+#define STRING_ANNOTATION 0x06
+#define NAME_CHANNEL_ANNOTATION 0x07
+#define NAME_GROUP_ANNOTATION 0x08
#define VISUAL_ANNOTATION 0x04
#define MARKER_ANNOTATION 0x05
-static void kannotate_write(const char* ptr, unsigned int size)
+static void kannotate_write(const char *ptr, unsigned int size)
{
int retval;
int pos = 0;
@@ -27,91 +29,129 @@ static void kannotate_write(const char* ptr, unsigned int size)
}
}
-static void gator_annotate_code(char code)
+void gator_annotate_channel(int channel, const char *str)
{
- int header = ESCAPE_CODE | (code << 8);
- kannotate_write((char*)&header, sizeof(header));
+ int str_size = strlen(str) & 0xffff;
+ long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16) | ((long long)str_size << 48);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
}
-static void gator_annotate_code_str(char code, const char* string)
-{
- int str_size = strlen(string) & 0xffff;
- int header = ESCAPE_CODE | (code << 8) | (str_size << 16);
- kannotate_write((char*)&header, sizeof(header));
- kannotate_write(string, str_size);
-}
+EXPORT_SYMBOL(gator_annotate_channel);
-static void gator_annotate_code_color(char code, int color)
+void gator_annotate(const char *str)
{
- long long header = (ESCAPE_CODE | (code << 8) | 0x00040000 | ((long long)color << 32));
- kannotate_write((char*)&header, sizeof(header));
+ gator_annotate_channel(0, str);
}
-static void gator_annotate_code_color_str(char code, int color, const char* string)
+EXPORT_SYMBOL(gator_annotate);
+
+void gator_annotate_channel_color(int channel, int color, const char *str)
{
- int str_size = (strlen(string) + 4) & 0xffff;
- long long header = ESCAPE_CODE | (code << 8) | (str_size << 16) | ((long long)color << 32);
- kannotate_write((char*)&header, sizeof(header));
- kannotate_write(string, str_size - 4);
+ int str_size = (strlen(str) + 4) & 0xffff;
+ char header[12];
+ header[0] = ESCAPE_CODE;
+ header[1] = STRING_ANNOTATION;
+ *(u32 *)(&header[2]) = channel;
+ *(u16 *)(&header[6]) = str_size;
+ *(u32 *)(&header[8]) = color;
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size - 4);
}
-// String annotation
-void gator_annotate(const char* string)
+EXPORT_SYMBOL(gator_annotate_channel_color);
+
+void gator_annotate_color(int color, const char *str)
{
- gator_annotate_code_str(STRING_ANNOTATION, string);
+ gator_annotate_channel_color(0, color, str);
}
-EXPORT_SYMBOL(gator_annotate);
-// String annotation with color
-void gator_annotate_color(int color, const char* string)
+EXPORT_SYMBOL(gator_annotate_color);
+
+void gator_annotate_channel_end(int channel)
{
- gator_annotate_code_color_str(STRING_ANNOTATION, color, string);
+ long long header = ESCAPE_CODE | (STRING_ANNOTATION << 8) | (channel << 16);
+ kannotate_write((char *)&header, sizeof(header));
}
-EXPORT_SYMBOL(gator_annotate_color);
-// Terminate an annotation
+EXPORT_SYMBOL(gator_annotate_channel_end);
+
void gator_annotate_end(void)
{
- gator_annotate_code(STRING_ANNOTATION);
+ gator_annotate_channel_end(0);
}
+
EXPORT_SYMBOL(gator_annotate_end);
-// Image annotation with optional string
-void gator_annotate_visual(const char* data, unsigned int length, const char* string)
+void gator_annotate_name_channel(int channel, int group, const char* str)
+{
+ int str_size = strlen(str) & 0xffff;
+ char header[12];
+ header[0] = ESCAPE_CODE;
+ header[1] = NAME_CHANNEL_ANNOTATION;
+ *(u32 *)(&header[2]) = channel;
+ *(u32 *)(&header[6]) = group;
+ *(u16 *)(&header[10]) = str_size;
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
+}
+
+EXPORT_SYMBOL(gator_annotate_name_channel);
+
+void gator_annotate_name_group(int group, const char* str)
+{
+ int str_size = strlen(str) & 0xffff;
+ long long header = ESCAPE_CODE | (NAME_GROUP_ANNOTATION << 8) | (group << 16) | ((long long)str_size << 48);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
+}
+
+EXPORT_SYMBOL(gator_annotate_name_group);
+
+void gator_annotate_visual(const char *data, unsigned int length, const char *str)
{
- int str_size = strlen(string) & 0xffff;
+ int str_size = strlen(str) & 0xffff;
int visual_annotation = ESCAPE_CODE | (VISUAL_ANNOTATION << 8) | (str_size << 16);
- kannotate_write((char*)&visual_annotation, sizeof(visual_annotation));
- kannotate_write(string, str_size);
- kannotate_write((char*)&length, sizeof(length));
+ kannotate_write((char *)&visual_annotation, sizeof(visual_annotation));
+ kannotate_write(str, str_size);
+ kannotate_write((char *)&length, sizeof(length));
kannotate_write(data, length);
}
+
EXPORT_SYMBOL(gator_annotate_visual);
-// Marker annotation
void gator_annotate_marker(void)
{
- gator_annotate_code(MARKER_ANNOTATION);
+ int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8);
+ kannotate_write((char *)&header, sizeof(header));
}
+
EXPORT_SYMBOL(gator_annotate_marker);
-// Marker annotation with a string
-void gator_annotate_marker_str(const char* string)
+void gator_annotate_marker_str(const char *str)
{
- gator_annotate_code_str(MARKER_ANNOTATION, string);
+ int str_size = strlen(str) & 0xffff;
+ int header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size);
}
+
EXPORT_SYMBOL(gator_annotate_marker_str);
-// Marker annotation with a color
void gator_annotate_marker_color(int color)
{
- gator_annotate_code_color(MARKER_ANNOTATION, color);
+ long long header = (ESCAPE_CODE | (MARKER_ANNOTATION << 8) | 0x00040000 | ((long long)color << 32));
+ kannotate_write((char *)&header, sizeof(header));
}
+
EXPORT_SYMBOL(gator_annotate_marker_color);
-// Marker annotation with a string and color
-void gator_annotate_marker_color_str(int color, const char* string)
+void gator_annotate_marker_color_str(int color, const char *str)
{
- gator_annotate_code_color_str(MARKER_ANNOTATION, color, string);
+ int str_size = (strlen(str) + 4) & 0xffff;
+ long long header = ESCAPE_CODE | (MARKER_ANNOTATION << 8) | (str_size << 16) | ((long long)color << 32);
+ kannotate_write((char *)&header, sizeof(header));
+ kannotate_write(str, str_size - 4);
}
+
EXPORT_SYMBOL(gator_annotate_marker_color_str);
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index 2173d8a..e6125b3 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -11,20 +11,28 @@
* EABI backtrace stores {fp,lr} on the stack.
*/
struct frame_tail_eabi {
- unsigned long fp; // points to prev_lr
+ unsigned long fp; // points to prev_lr
unsigned long lr;
};
-static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth)
+static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth)
{
-#if defined(__arm__)
+#if defined(__arm__) || defined(__aarch64__)
struct frame_tail_eabi *tail;
struct frame_tail_eabi *next;
struct frame_tail_eabi *ptrtail;
struct frame_tail_eabi buftail;
+#if defined(__arm__)
unsigned long fp = regs->ARM_fp;
unsigned long sp = regs->ARM_sp;
unsigned long lr = regs->ARM_lr;
+ const int frame_offset = 4;
+#else
+ unsigned long fp = regs->regs[29];
+ unsigned long sp = regs->sp;
+ unsigned long lr = regs->regs[30];
+ const int frame_offset = 0;
+#endif
int is_user_mode = user_mode(regs);
if (!is_user_mode) {
@@ -39,9 +47,9 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
return;
}
- tail = (struct frame_tail_eabi *)(fp - 4);
+ tail = (struct frame_tail_eabi *)(fp - frame_offset);
- while (depth-- && tail && !((unsigned long) tail & 3)) {
+ while (depth-- && tail && !((unsigned long)tail & 3)) {
/* Also check accessibility of one struct frame_tail beyond */
if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi)))
return;
@@ -53,10 +61,10 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
gator_add_trace(cpu, lr);
/* frame pointers should progress back up the stack, towards higher addresses */
- next = (struct frame_tail_eabi *)(lr - 4);
+ next = (struct frame_tail_eabi *)(lr - frame_offset);
if (tail >= next || lr == 0) {
fp = ptrtail[0].fp;
- next = (struct frame_tail_eabi *)(fp - 4);
+ next = (struct frame_tail_eabi *)(fp - frame_offset);
/* check tail is valid */
if (tail >= next || fp == 0) {
return;
@@ -68,7 +76,7 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in
#endif
}
-#if defined(__arm__)
+#if defined(__arm__) || defined(__aarch64__)
static int report_trace(struct stackframe *frame, void *d)
{
struct module *mod;
@@ -78,7 +86,7 @@ static int report_trace(struct stackframe *frame, void *d)
if (*depth) {
mod = __module_address(addr);
if (mod) {
- cookie = get_cookie(cpu, current, NULL, mod, true);
+ cookie = get_cookie(cpu, current, mod->name, false);
addr = addr - (unsigned long)mod->module_core;
}
marshal_backtrace(addr & ~1, cookie);
@@ -91,9 +99,9 @@ static int report_trace(struct stackframe *frame, void *d)
// Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile
// #define GATOR_KERNEL_STACK_UNWINDING
-static void kernel_backtrace(int cpu, struct pt_regs * const regs)
+static void kernel_backtrace(int cpu, struct pt_regs *const regs)
{
-#if defined(__arm__)
+#if defined(__arm__) || defined(__aarch64__)
#ifdef GATOR_KERNEL_STACK_UNWINDING
int depth = gator_backtrace_depth;
#else
@@ -102,10 +110,16 @@ static void kernel_backtrace(int cpu, struct pt_regs * const regs)
struct stackframe frame;
if (depth == 0)
depth = 1;
+#if defined(__arm__)
frame.fp = regs->ARM_fp;
frame.sp = regs->ARM_sp;
frame.lr = regs->ARM_lr;
frame.pc = regs->ARM_pc;
+#else
+ frame.fp = regs->regs[29];
+ frame.sp = regs->sp;
+ frame.pc = regs->pc;
+#endif
walk_stackframe(&frame, report_trace, &depth);
#else
marshal_backtrace(PC_REG & ~1, NO_COOKIE);
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c
index b2ed686..bb401bb 100644
--- a/driver/gator_cookies.c
+++ b/driver/gator_cookies.c
@@ -7,7 +7,7 @@
*
*/
-#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */
+#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */
#define TRANSLATE_SIZE 256
#define MAX_COLLISIONS 2
@@ -20,28 +20,29 @@ static DEFINE_PER_CPU(uint64_t *, cookie_keys);
static DEFINE_PER_CPU(uint32_t *, cookie_values);
static DEFINE_PER_CPU(int, translate_buffer_read);
static DEFINE_PER_CPU(int, translate_buffer_write);
-static DEFINE_PER_CPU(void * *, translate_buffer);
+static DEFINE_PER_CPU(void **, translate_buffer);
-static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt);
+static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq);
static void wq_cookie_handler(struct work_struct *unused);
DECLARE_WORK(cookie_work, wq_cookie_handler);
static struct timer_list app_process_wake_up_timer;
static void app_process_wake_up_handler(unsigned long unused_data);
-static uint32_t cookiemap_code(uint64_t value64) {
+static uint32_t cookiemap_code(uint64_t value64)
+{
uint32_t value = (uint32_t)((value64 >> 32) + value64);
uint32_t cookiecode = (value >> 24) & 0xff;
cookiecode = cookiecode * 31 + ((value >> 16) & 0xff);
cookiecode = cookiecode * 31 + ((value >> 8) & 0xff);
cookiecode = cookiecode * 31 + ((value >> 0) & 0xff);
- cookiecode &= (COOKIEMAP_ENTRIES-1);
+ cookiecode &= (COOKIEMAP_ENTRIES - 1);
return cookiecode * MAX_COLLISIONS;
}
-static uint32_t gator_chksum_crc32(char *data)
+static uint32_t gator_chksum_crc32(const char *data)
{
register unsigned long crc;
- unsigned char *block = data;
+ const unsigned char *block = data;
int i, length = strlen(data);
crc = 0xFFFFFFFF;
@@ -57,7 +58,8 @@ static uint32_t gator_chksum_crc32(char *data)
* Pre: [0][1][v][3]..[n-1]
* Post: [v][0][1][3]..[n-1]
*/
-static uint32_t cookiemap_exists(uint64_t key) {
+static uint32_t cookiemap_exists(uint64_t key)
+{
unsigned long x, flags, retval = 0;
int cpu = smp_processor_id();
uint32_t cookiecode = cookiemap_code(key);
@@ -70,8 +72,8 @@ static uint32_t cookiemap_exists(uint64_t key) {
if (keys[x] == key) {
uint32_t value = values[x];
for (; x > 0; x--) {
- keys[x] = keys[x-1];
- values[x] = values[x-1];
+ keys[x] = keys[x - 1];
+ values[x] = values[x - 1];
}
keys[0] = key;
values[0] = value;
@@ -89,30 +91,31 @@ static uint32_t cookiemap_exists(uint64_t key) {
* Pre: [0][1][2][3]..[n-1]
* Post: [v][0][1][2]..[n-2]
*/
-static void cookiemap_add(uint64_t key, uint32_t value) {
+static void cookiemap_add(uint64_t key, uint32_t value)
+{
int cpu = smp_processor_id();
int cookiecode = cookiemap_code(key);
uint64_t *keys = &(per_cpu(cookie_keys, cpu)[cookiecode]);
uint32_t *values = &(per_cpu(cookie_values, cpu)[cookiecode]);
int x;
- for (x = MAX_COLLISIONS-1; x > 0; x--) {
- keys[x] = keys[x-1];
- values[x] = values[x-1];
+ for (x = MAX_COLLISIONS - 1; x > 0; x--) {
+ keys[x] = keys[x - 1];
+ values[x] = values[x - 1];
}
keys[0] = key;
values[0] = value;
}
-static void translate_buffer_write_ptr(int cpu, void * x)
+static void translate_buffer_write_ptr(int cpu, void *x)
{
per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
}
-static void * translate_buffer_read_ptr(int cpu)
+static void *translate_buffer_read_ptr(int cpu)
{
- void * value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
+ void *value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask;
return value;
}
@@ -120,9 +123,9 @@ static void * translate_buffer_read_ptr(int cpu)
static void wq_cookie_handler(struct work_struct *unused)
{
struct task_struct *task;
- struct vm_area_struct *vma;
+ char *text;
int cpu = smp_processor_id();
- unsigned int cookie, commit;
+ unsigned int commit;
mutex_lock(&start_mutex);
@@ -130,8 +133,8 @@ static void wq_cookie_handler(struct work_struct *unused)
commit = per_cpu(translate_buffer_write, cpu);
while (per_cpu(translate_buffer_read, cpu) != commit) {
task = (struct task_struct *)translate_buffer_read_ptr(cpu);
- vma = (struct vm_area_struct *)translate_buffer_read_ptr(cpu);
- cookie = get_cookie(cpu, task, vma, NULL, false);
+ text = (char *)translate_buffer_read_ptr(cpu);
+ get_cookie(cpu, task, text, true);
}
}
@@ -145,7 +148,7 @@ static void app_process_wake_up_handler(unsigned long unused_data)
}
// Retrieve full name from proc/pid/cmdline for java processes on Android
-static int translate_app_process(char** text, int cpu, struct task_struct * task, struct vm_area_struct *vma, bool in_interrupt)
+static int translate_app_process(const char **text, int cpu, struct task_struct *task, bool from_wq)
{
void *maddr;
unsigned int len;
@@ -154,12 +157,12 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
struct page *page = NULL;
struct vm_area_struct *page_vma;
int bytes, offset, retval = 0, ptr;
- char * buf = per_cpu(translate_text, cpu);
+ char *buf = per_cpu(translate_text, cpu);
// Push work into a work queue if in atomic context as the kernel functions below might sleep
// Rely on the in_interrupt variable rather than in_irq() or in_interrupt() kernel functions, as the value of these functions seems
// inconsistent during a context switch between android/linux versions
- if (in_interrupt) {
+ if (!from_wq) {
// Check if already in buffer
ptr = per_cpu(translate_buffer_read, cpu);
while (ptr != per_cpu(translate_buffer_write, cpu)) {
@@ -169,7 +172,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
}
translate_buffer_write_ptr(cpu, (void *)task);
- translate_buffer_write_ptr(cpu, (void *)vma);
+ translate_buffer_write_ptr(cpu, (void *)*text);
mod_timer(&app_process_wake_up_timer, jiffies + 1);
goto out;
@@ -192,7 +195,7 @@ static int translate_app_process(char** text, int cpu, struct task_struct * task
goto outsem;
maddr = kmap(page);
- offset = addr & (PAGE_SIZE-1);
+ offset = addr & (PAGE_SIZE - 1);
bytes = len;
if (bytes > PAGE_SIZE - offset)
bytes = PAGE_SIZE - offset;
@@ -222,26 +225,10 @@ out:
return retval;
}
-static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_area_struct *vma, struct module *mod, bool in_interrupt)
+static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq)
{
unsigned long flags, cookie;
- struct path *path;
uint64_t key;
- char *text;
-
- if (mod) {
- text = mod->name;
- } else {
- if (!vma || !vma->vm_file) {
- return INVALID_COOKIE;
- }
- path = &vma->vm_file->f_path;
- if (!path || !path->dentry) {
- return INVALID_COOKIE;
- }
-
- text = (char*)path->dentry->d_name.name;
- }
key = gator_chksum_crc32(text);
key = (key << 32) | (uint32_t)task->tgid;
@@ -251,8 +238,8 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
return cookie;
}
- if (strcmp(text, "app_process") == 0 && !mod) {
- if (!translate_app_process(&text, cpu, task, vma, in_interrupt))
+ if (strcmp(text, "app_process") == 0) {
+ if (!translate_app_process(&text, cpu, task, from_wq))
return INVALID_COOKIE;
}
@@ -273,24 +260,19 @@ static inline uint32_t get_cookie(int cpu, struct task_struct *task, struct vm_a
static int get_exec_cookie(int cpu, struct task_struct *task)
{
- unsigned long cookie = NO_COOKIE;
struct mm_struct *mm = task->mm;
- struct vm_area_struct *vma;
+ const char *text;
// kernel threads have no address space
if (!mm)
- return cookie;
+ return NO_COOKIE;
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- if (!vma->vm_file)
- continue;
- if (!(vma->vm_flags & VM_EXECUTABLE))
- continue;
- cookie = get_cookie(cpu, task, vma, NULL, true);
- break;
+ if (task && task->mm && task->mm->exe_file) {
+ text = task->mm->exe_file->f_path.dentry->d_name.name;
+ return get_cookie(cpu, task, text, false);
}
- return cookie;
+ return INVALID_COOKIE;
}
static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsigned long addr, off_t *offset)
@@ -298,6 +280,7 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
unsigned long cookie = NO_COOKIE;
struct mm_struct *mm = task->mm;
struct vm_area_struct *vma;
+ const char *text;
if (!mm)
return cookie;
@@ -307,7 +290,8 @@ static unsigned long get_address_cookie(int cpu, struct task_struct *task, unsig
continue;
if (vma->vm_file) {
- cookie = get_cookie(cpu, task, vma, NULL, true);
+ text = vma->vm_file->f_path.dentry->d_name.name;
+ cookie = get_cookie(cpu, task, text, false);
*offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start;
} else {
/* must be an anonymous map */
@@ -328,14 +312,14 @@ static int cookies_initialize(void)
uint32_t crc, poly;
int i, j, cpu, size, err = 0;
- int translate_buffer_size = 512; // must be a power of 2
+ int translate_buffer_size = 512; // must be a power of 2
translate_buffer_mask = translate_buffer_size / sizeof(per_cpu(translate_buffer, 0)[0]) - 1;
for_each_present_cpu(cpu) {
per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu;
size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint64_t);
- per_cpu(cookie_keys, cpu) = (uint64_t*)kmalloc(size, GFP_KERNEL);
+ per_cpu(cookie_keys, cpu) = (uint64_t *)kmalloc(size, GFP_KERNEL);
if (!per_cpu(cookie_keys, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
@@ -343,14 +327,14 @@ static int cookies_initialize(void)
memset(per_cpu(cookie_keys, cpu), 0, size);
size = COOKIEMAP_ENTRIES * MAX_COLLISIONS * sizeof(uint32_t);
- per_cpu(cookie_values, cpu) = (uint32_t*)kmalloc(size, GFP_KERNEL);
+ per_cpu(cookie_values, cpu) = (uint32_t *)kmalloc(size, GFP_KERNEL);
if (!per_cpu(cookie_values, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
}
memset(per_cpu(cookie_values, cpu), 0, size);
- per_cpu(translate_buffer, cpu) = (void * *)kmalloc(translate_buffer_size, GFP_KERNEL);
+ per_cpu(translate_buffer, cpu) = (void **)kmalloc(translate_buffer_size, GFP_KERNEL);
if (!per_cpu(translate_buffer, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
@@ -368,7 +352,7 @@ static int cookies_initialize(void)
// build CRC32 table
poly = 0x04c11db7;
- gator_crc32_table = (uint32_t*)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL);
+ gator_crc32_table = (uint32_t *)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL);
for (i = 0; i < 256; i++) {
crc = i;
for (j = 8; j > 0; j--) {
diff --git a/driver/gator_events_armv6.c b/driver/gator_events_armv6.c
index 5f989ba..ee36dd0 100644
--- a/driver/gator_events_armv6.c
+++ b/driver/gator_events_armv6.c
@@ -93,7 +93,7 @@ int gator_events_armv6_create_files(struct super_block *sb, struct dentry *root)
return 0;
}
-static int gator_events_armv6_online(int** buffer)
+static int gator_events_armv6_online(int **buffer)
{
unsigned int cnt, len = 0, cpu = smp_processor_id();
u32 pmnc;
@@ -104,7 +104,7 @@ static int gator_events_armv6_online(int** buffer)
/* initialize PMNC, reset overflow, D bit, C bit and P bit. */
armv6_pmnc_write(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
- PMCR_C | PMCR_P);
+ PMCR_C | PMCR_P);
/* configure control register */
for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
@@ -141,7 +141,7 @@ static int gator_events_armv6_online(int** buffer)
return len;
}
-static int gator_events_armv6_offline(int** buffer)
+static int gator_events_armv6_offline(int **buffer)
{
unsigned int cnt;
diff --git a/driver/gator_events_armv7.c b/driver/gator_events_armv7.c
index 590421d..212b17b 100644
--- a/driver/gator_events_armv7.c
+++ b/driver/gator_events_armv7.c
@@ -22,7 +22,7 @@
#define PMNC_E (1 << 0) /* Enable all counters */
#define PMNC_P (1 << 1) /* Reset all counters */
#define PMNC_C (1 << 2) /* Cycle counter reset */
-#define PMNC_MASK 0x3f /* Mask for writable bits */
+#define PMNC_MASK 0x3f /* Mask for writable bits */
// ccnt reg
#define CCNT_REG (1 << 31)
@@ -63,7 +63,7 @@ inline u32 armv7_ccnt_read(u32 reset_value)
local_irq_save(flags);
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); // read
- asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval));// new value
+ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (newval)); // new value
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
local_irq_restore(flags);
@@ -82,7 +82,7 @@ inline u32 armv7_cntn_read(unsigned int cnt, u32 reset_value)
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (den)); // disable
asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (sel)); // select
asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (oldval)); // read
- asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval));// new value
+ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (newval)); // new value
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (den)); // enable
local_irq_restore(flags);
@@ -143,7 +143,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
if (i == 0) {
snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name);
} else {
- snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i-1);
+ snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i - 1);
}
dir = gatorfs_mkdir(sb, root, buf);
if (!dir) {
@@ -159,7 +159,7 @@ static int gator_events_armv7_create_files(struct super_block *sb, struct dentry
return 0;
}
-static int gator_events_armv7_online(int** buffer)
+static int gator_events_armv7_online(int **buffer)
{
unsigned int cnt, len = 0, cpu = smp_processor_id();
@@ -214,11 +214,11 @@ static int gator_events_armv7_online(int** buffer)
return len;
}
-static int gator_events_armv7_offline(int** buffer)
+static int gator_events_armv7_offline(int **buffer)
{
- // disbale all counters, including PMCCNTR; overflow IRQs will not be signaled
+ // disable all counters, including PMCCNTR; overflow IRQs will not be signaled
armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
-
+
return 0;
}
@@ -298,7 +298,7 @@ int gator_events_armv7_init(void)
return -1;
}
- pmnc_counters++; // CNT[n] + CCNT
+ pmnc_counters++; // CNT[n] + CCNT
for (cnt = CCNT; cnt < CNTMAX; cnt++) {
pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_events_block.c b/driver/gator_events_block.c
index b18c3ca..f512b13 100644
--- a/driver/gator_events_block.c
+++ b/driver/gator_events_block.c
@@ -119,7 +119,7 @@ static int gator_events_block_read(int **buffer)
if (block_rq_wr_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_WR])) > 0) {
atomic_sub(value, &blockCnt[BLOCK_RQ_WR]);
blockGet[len++] = block_rq_wr_key;
- blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
+ blockGet[len++] = 0; // indicates to Streamline that value bytes were written now, not since the last message
blockGet[len++] = block_rq_wr_key;
blockGet[len++] = value;
data += value;
@@ -127,7 +127,7 @@ static int gator_events_block_read(int **buffer)
if (block_rq_rd_enabled && (value = atomic_read(&blockCnt[BLOCK_RQ_RD])) > 0) {
atomic_sub(value, &blockCnt[BLOCK_RQ_RD]);
blockGet[len++] = block_rq_rd_key;
- blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
+ blockGet[len++] = 0; // indicates to Streamline that value bytes were read now, not since the last message
blockGet[len++] = block_rq_rd_key;
blockGet[len++] = value;
data += value;
@@ -156,4 +156,5 @@ int gator_events_block_init(void)
return gator_events_install(&gator_events_block_interface);
}
+
gator_events_init(gator_events_block_init);
diff --git a/driver/gator_events_irq.c b/driver/gator_events_irq.c
index 435bc86..1221372 100644
--- a/driver/gator_events_irq.c
+++ b/driver/gator_events_irq.c
@@ -21,8 +21,8 @@ static ulong softirq_key;
static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt);
static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet);
-GATOR_DEFINE_PROBE(irq_handler_exit, TP_PROTO(int irq,
- struct irqaction *action, int ret))
+GATOR_DEFINE_PROBE(irq_handler_exit,
+ TP_PROTO(int irq, struct irqaction *action, int ret))
{
unsigned long flags;
@@ -71,10 +71,10 @@ static int gator_events_irq_create_files(struct super_block *sb, struct dentry *
return 0;
}
-static int gator_events_irq_online(int** buffer)
+static int gator_events_irq_online(int **buffer)
{
int len = 0, cpu = smp_processor_id();
- unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
+ unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
// synchronization with the irq_exit functions is not necessary as the values are being reset
if (hardirq_enabled) {
@@ -136,7 +136,7 @@ static void gator_events_irq_stop(void)
static int gator_events_irq_read(int **buffer)
{
- unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
+ unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
int len, value;
int cpu = smp_processor_id();
@@ -185,4 +185,5 @@ int gator_events_irq_init(void)
return gator_events_install(&gator_events_irq_interface);
}
+
gator_events_init(gator_events_irq_init);
diff --git a/driver/gator_events_l2c-310.c b/driver/gator_events_l2c-310.c
index bd1c48a..197af04 100644
--- a/driver/gator_events_l2c-310.c
+++ b/driver/gator_events_l2c-310.c
@@ -26,8 +26,6 @@ static int l2c310_buffer[L2C310_COUNTERS_NUM * 2];
static void __iomem *l2c310_base;
-
-
static void gator_events_l2c310_reset_counters(void)
{
u32 val = readl(l2c310_base + L2X0_EVENT_CNT_CTRL);
@@ -37,9 +35,8 @@ static void gator_events_l2c310_reset_counters(void)
writel(val, l2c310_base + L2X0_EVENT_CNT_CTRL);
}
-
static int gator_events_l2c310_create_files(struct super_block *sb,
- struct dentry *root)
+ struct dentry *root)
{
int i;
@@ -52,11 +49,11 @@ static int gator_events_l2c310_create_files(struct super_block *sb,
if (WARN_ON(!dir))
return -1;
gatorfs_create_ulong(sb, dir, "enabled",
- &l2c310_counters[i].enabled);
+ &l2c310_counters[i].enabled);
gatorfs_create_ulong(sb, dir, "event",
- &l2c310_counters[i].event);
+ &l2c310_counters[i].event);
gatorfs_create_ro_ulong(sb, dir, "key",
- &l2c310_counters[i].key);
+ &l2c310_counters[i].key);
}
return 0;
@@ -73,7 +70,7 @@ static int gator_events_l2c310_start(void)
/* Counter event sources */
for (i = 0; i < L2C310_COUNTERS_NUM; i++)
writel((l2c310_counters[i].event & 0xf) << 2,
- l2c310_base + l2x0_event_cntx_cfg[i]);
+ l2c310_base + l2x0_event_cntx_cfg[i]);
gator_events_l2c310_reset_counters();
@@ -105,10 +102,10 @@ static int gator_events_l2c310_read(int **buffer)
if (l2c310_counters[i].enabled) {
l2c310_buffer[len++] = l2c310_counters[i].key;
l2c310_buffer[len++] = readl(l2c310_base +
- l2x0_event_cntx_val[i]);
+ l2x0_event_cntx_val[i]);
}
}
-
+
/* l2c310 counters are saturating, not wrapping in case of overflow */
gator_events_l2c310_reset_counters();
@@ -176,4 +173,5 @@ int gator_events_l2c310_init(void)
return gator_events_install(&gator_events_l2c310_interface);
}
+
gator_events_init(gator_events_l2c310_init);
diff --git a/driver/gator_events_mali_400.c b/driver/gator_events_mali_400.c
index 65eeb4f..34a73c8 100644
--- a/driver/gator_events_mali_400.c
+++ b/driver/gator_events_mali_400.c
@@ -52,81 +52,81 @@
#define NUM_FP_UNITS (4)
enum counters {
- /* Timeline activity */
- ACTIVITY_VP = 0,
- ACTIVITY_FP0,
- ACTIVITY_FP1,
- ACTIVITY_FP2,
- ACTIVITY_FP3,
-
- /* L2 cache counters */
- COUNTER_L2_C0,
- COUNTER_L2_C1,
-
- /* Vertex processor counters */
- COUNTER_VP_C0,
- COUNTER_VP_C1,
-
- /* Fragment processor counters */
- COUNTER_FP0_C0,
- COUNTER_FP0_C1,
- COUNTER_FP1_C0,
- COUNTER_FP1_C1,
- COUNTER_FP2_C0,
- COUNTER_FP2_C1,
- COUNTER_FP3_C0,
- COUNTER_FP3_C1,
-
- /* EGL Software Counters */
- COUNTER_EGL_BLIT_TIME,
-
- /* GLES Software Counters */
- COUNTER_GLES_DRAW_ELEMENTS_CALLS,
- COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
- COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
- COUNTER_GLES_DRAW_ARRAYS_CALLS,
- COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
- COUNTER_GLES_DRAW_POINTS,
- COUNTER_GLES_DRAW_LINES,
- COUNTER_GLES_DRAW_LINE_LOOP,
- COUNTER_GLES_DRAW_LINE_STRIP,
- COUNTER_GLES_DRAW_TRIANGLES,
- COUNTER_GLES_DRAW_TRIANGLE_STRIP,
- COUNTER_GLES_DRAW_TRIANGLE_FAN,
- COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
- COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
- COUNTER_GLES_UPLOAD_TEXTURE_TIME,
- COUNTER_GLES_UPLOAD_VBO_TIME,
- COUNTER_GLES_NUM_FLUSHES,
- COUNTER_GLES_NUM_VSHADERS_GENERATED,
- COUNTER_GLES_NUM_FSHADERS_GENERATED,
- COUNTER_GLES_VSHADER_GEN_TIME,
- COUNTER_GLES_FSHADER_GEN_TIME,
- COUNTER_GLES_INPUT_TRIANGLES,
- COUNTER_GLES_VXCACHE_HIT,
- COUNTER_GLES_VXCACHE_MISS,
- COUNTER_GLES_VXCACHE_COLLISION,
- COUNTER_GLES_CULLED_TRIANGLES,
- COUNTER_GLES_CULLED_LINES,
- COUNTER_GLES_BACKFACE_TRIANGLES,
- COUNTER_GLES_GBCLIP_TRIANGLES,
- COUNTER_GLES_GBCLIP_LINES,
- COUNTER_GLES_TRIANGLES_DRAWN,
- COUNTER_GLES_DRAWCALL_TIME,
- COUNTER_GLES_TRIANGLES_COUNT,
- COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
- COUNTER_GLES_STRIP_TRIANGLES_COUNT,
- COUNTER_GLES_FAN_TRIANGLES_COUNT,
- COUNTER_GLES_LINES_COUNT,
- COUNTER_GLES_INDEPENDENT_LINES_COUNT,
- COUNTER_GLES_STRIP_LINES_COUNT,
- COUNTER_GLES_LOOP_LINES_COUNT,
-
- COUNTER_FILMSTRIP,
- COUNTER_FREQUENCY,
- COUNTER_VOLTAGE,
-
- NUMBER_OF_EVENTS
+ /* Timeline activity */
+ ACTIVITY_VP = 0,
+ ACTIVITY_FP0,
+ ACTIVITY_FP1,
+ ACTIVITY_FP2,
+ ACTIVITY_FP3,
+
+ /* L2 cache counters */
+ COUNTER_L2_C0,
+ COUNTER_L2_C1,
+
+ /* Vertex processor counters */
+ COUNTER_VP_C0,
+ COUNTER_VP_C1,
+
+ /* Fragment processor counters */
+ COUNTER_FP0_C0,
+ COUNTER_FP0_C1,
+ COUNTER_FP1_C0,
+ COUNTER_FP1_C1,
+ COUNTER_FP2_C0,
+ COUNTER_FP2_C1,
+ COUNTER_FP3_C0,
+ COUNTER_FP3_C1,
+
+ /* EGL Software Counters */
+ COUNTER_EGL_BLIT_TIME,
+
+ /* GLES Software Counters */
+ COUNTER_GLES_DRAW_ELEMENTS_CALLS,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_ARRAYS_CALLS,
+ COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_POINTS,
+ COUNTER_GLES_DRAW_LINES,
+ COUNTER_GLES_DRAW_LINE_LOOP,
+ COUNTER_GLES_DRAW_LINE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLES,
+ COUNTER_GLES_DRAW_TRIANGLE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLE_FAN,
+ COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
+ COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
+ COUNTER_GLES_UPLOAD_TEXTURE_TIME,
+ COUNTER_GLES_UPLOAD_VBO_TIME,
+ COUNTER_GLES_NUM_FLUSHES,
+ COUNTER_GLES_NUM_VSHADERS_GENERATED,
+ COUNTER_GLES_NUM_FSHADERS_GENERATED,
+ COUNTER_GLES_VSHADER_GEN_TIME,
+ COUNTER_GLES_FSHADER_GEN_TIME,
+ COUNTER_GLES_INPUT_TRIANGLES,
+ COUNTER_GLES_VXCACHE_HIT,
+ COUNTER_GLES_VXCACHE_MISS,
+ COUNTER_GLES_VXCACHE_COLLISION,
+ COUNTER_GLES_CULLED_TRIANGLES,
+ COUNTER_GLES_CULLED_LINES,
+ COUNTER_GLES_BACKFACE_TRIANGLES,
+ COUNTER_GLES_GBCLIP_TRIANGLES,
+ COUNTER_GLES_GBCLIP_LINES,
+ COUNTER_GLES_TRIANGLES_DRAWN,
+ COUNTER_GLES_DRAWCALL_TIME,
+ COUNTER_GLES_TRIANGLES_COUNT,
+ COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
+ COUNTER_GLES_STRIP_TRIANGLES_COUNT,
+ COUNTER_GLES_FAN_TRIANGLES_COUNT,
+ COUNTER_GLES_LINES_COUNT,
+ COUNTER_GLES_INDEPENDENT_LINES_COUNT,
+ COUNTER_GLES_STRIP_LINES_COUNT,
+ COUNTER_GLES_LOOP_LINES_COUNT,
+
+ COUNTER_FILMSTRIP,
+ COUNTER_FREQUENCY,
+ COUNTER_VOLTAGE,
+
+ NUMBER_OF_EVENTS
};
#define FIRST_ACTIVITY_EVENT ACTIVITY_VP
@@ -153,7 +153,7 @@ static unsigned long counter_key[NUMBER_OF_EVENTS];
/* The data we have recorded */
static u32 counter_data[NUMBER_OF_EVENTS];
/* The address to sample (or 0 if samples are sent to us) */
-static u32* counter_address[NUMBER_OF_EVENTS];
+static u32 *counter_address[NUMBER_OF_EVENTS];
/* An array used to return the data we recorded
* as key,value pairs hence the *2
@@ -169,13 +169,12 @@ static int trace_registered;
*/
static u32 get_difference(u32 start, u32 end)
{
- if (start - end >= 0)
- {
- return start - end;
- }
+ if (start - end >= 0) {
+ return start - end;
+ }
- // Mali counters are unsigned 32 bit values that wrap.
- return (4294967295u - end) + start;
+ // Mali counters are unsigned 32 bit values that wrap.
+ return (4294967295u - end) + start;
}
/**
@@ -183,8 +182,8 @@ static u32 get_difference(u32 start, u32 end)
*/
static inline int is_activity_counter(unsigned int event_id)
{
- return (event_id >= FIRST_ACTIVITY_EVENT &&
- event_id <= LAST_ACTIVITY_EVENT);
+ return (event_id >= FIRST_ACTIVITY_EVENT &&
+ event_id <= LAST_ACTIVITY_EVENT);
}
/**
@@ -192,7 +191,7 @@ static inline int is_activity_counter(unsigned int event_id)
*/
static inline int is_hw_counter(unsigned int event_id)
{
- return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
+ return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
}
#if GATOR_MALI_INTERFACE_STYLE == 2
@@ -201,7 +200,7 @@ static inline int is_hw_counter(unsigned int event_id)
*/
static inline int is_sw_counter(unsigned int event_id)
{
- return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
+ return (event_id >= FIRST_SW_COUNTER && event_id <= LAST_SW_COUNTER);
}
#endif
@@ -209,209 +208,204 @@ static inline int is_sw_counter(unsigned int event_id)
/*
* The Mali DDK uses s64 types to contain software counter values, but gator
* can only use a maximum of 32 bits. This function scales a software counter
- * to an appopriate range.
+ * to an appropriate range.
*/
static u32 scale_sw_counter_value(unsigned int event_id, signed long long value)
{
- u32 scaled_value;
-
- switch (event_id) {
- case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
- case COUNTER_GLES_UPLOAD_VBO_TIME:
- scaled_value = (u32)div_s64(value, 1000000);
- break;
- default:
- scaled_value = (u32)value;
- break;
- }
-
- return scaled_value;
+ u32 scaled_value;
+
+ switch (event_id) {
+ case COUNTER_GLES_UPLOAD_TEXTURE_TIME:
+ case COUNTER_GLES_UPLOAD_VBO_TIME:
+ scaled_value = (u32)div_s64(value, 1000000);
+ break;
+ default:
+ scaled_value = (u32)value;
+ break;
+ }
+
+ return scaled_value;
}
#endif
/* Probe for continuously sampled counter */
-#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
-GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32* addr))
+#if 0 //WE_DONT_CURRENTLY_USE_THIS_SO_SUPPRESS_WARNING
+GATOR_DEFINE_PROBE(mali_sample_address, TP_PROTO(unsigned int event_id, u32 *addr))
{
- /* Turning on too many pr_debug statements in frequently called functions
- * can cause stability and/or performance problems
- */
- //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr);
- if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) {
- counter_address[event_id] = addr;
- }
+ /* Turning on too many pr_debug statements in frequently called functions
+ * can cause stability and/or performance problems
+ */
+ //pr_debug("gator: mali_sample_address %d %d\n", event_id, addr);
+ if (event_id >= ACTIVITY_VP && event_id <= COUNTER_FP3_C1) {
+ counter_address[event_id] = addr;
+ }
}
#endif
/* Probe for hardware counter events */
GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value))
{
- /* Turning on too many pr_debug statements in frequently called functions
- * can cause stability and/or performance problems
- */
- //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value);
- if (is_hw_counter(event_id)) {
- counter_data[event_id] = value;
- }
+ /* Turning on too many pr_debug statements in frequently called functions
+ * can cause stability and/or performance problems
+ */
+ //pr_debug("gator: mali_hw_counter %d %d\n", event_id, value);
+ if (is_hw_counter(event_id)) {
+ counter_data[event_id] = value;
+ }
}
#if GATOR_MALI_INTERFACE_STYLE == 2
GATOR_DEFINE_PROBE(mali_sw_counter, TP_PROTO(unsigned int event_id, signed long long value))
{
- if (is_sw_counter(event_id)) {
- counter_data[event_id] = scale_sw_counter_value(event_id, value);
- }
+ if (is_sw_counter(event_id)) {
+ counter_data[event_id] = scale_sw_counter_value(event_id, value);
+ }
}
#endif /* GATOR_MALI_INTERFACE_STYLE == 2 */
-
#if GATOR_MALI_INTERFACE_STYLE == 3
-GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters))
+GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters))
{
- u32 i;
-
- /* Copy over the values for those counters which are enabled. */
- for(i=FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++)
- {
- if(counter_enabled[i])
- {
- counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]);
- }
- }
+ u32 i;
+
+ /* Copy over the values for those counters which are enabled. */
+ for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
+ if (counter_enabled[i]) {
+ counter_data[i] = (u32)(counters[i - FIRST_SW_COUNTER]);
+ }
+ }
}
#endif /* GATOR_MALI_INTERFACE_STYLE == 3 */
-static int create_files(struct super_block *sb, struct dentry *root) {
- struct dentry *dir;
- int event;
- int n_fp = NUM_FP_UNITS;
-
- const char* mali_name = gator_mali_get_mali_name();
-
- /*
- * Create the filesystem entries for vertex processor, fragement processor
- * and L2 cache timeline and hardware counters. Software counters get
- * special handling after this block.
- */
- for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++)
- {
- char buf[40];
-
- /*
- * We can skip this event if it's for a non-existent fragment
- * processor.
- */
- if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0)) ||
- (((event - COUNTER_FP0_C0)/2 >= n_fp)))
- {
- continue;
- }
-
- /* Otherwise, set up the filesystem entry for this event. */
- switch (event) {
- case ACTIVITY_VP:
- snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name);
- break;
- case ACTIVITY_FP0:
- case ACTIVITY_FP1:
- case ACTIVITY_FP2:
- case ACTIVITY_FP3:
- snprintf(buf, sizeof buf, "ARM_%s_FP%d_active",
- mali_name, event - ACTIVITY_FP0);
- break;
- case COUNTER_L2_C0:
- case COUNTER_L2_C1:
- snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d",
- mali_name, event - COUNTER_L2_C0);
- break;
- case COUNTER_VP_C0:
- case COUNTER_VP_C1:
- snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d",
- mali_name, event - COUNTER_VP_C0);
- break;
- case COUNTER_FP0_C0:
- case COUNTER_FP0_C1:
- case COUNTER_FP1_C0:
- case COUNTER_FP1_C1:
- case COUNTER_FP2_C0:
- case COUNTER_FP2_C1:
- case COUNTER_FP3_C0:
- case COUNTER_FP3_C1:
- snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d", mali_name,
- (event - COUNTER_FP0_C0) / 2, (event - COUNTER_FP0_C0) % 2);
- break;
- default:
- printk("gator: trying to create file for non-existent counter (%d)\n", event);
- continue;
- }
-
- dir = gatorfs_mkdir(sb, root, buf);
-
- if (!dir) {
- return -1;
- }
-
- gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
-
- /* Only create an event node for counters that can change what they count */
- if (event >= COUNTER_L2_C0) {
- gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
- }
-
- gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
- }
-
- /* Now set up the software counter entries */
- for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++)
- {
- char buf[40];
-
- snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event);
-
- dir = gatorfs_mkdir(sb, root, buf);
-
- if (!dir) {
- return -1;
- }
-
- gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
- gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
- }
-
- /* Now set up the special counter entries */
- for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++)
- {
- char buf[40];
-
- switch(event) {
- case COUNTER_FILMSTRIP:
- snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name);
- break;
-
- case COUNTER_FREQUENCY:
- snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name);
- break;
-
- case COUNTER_VOLTAGE:
- snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name);
- break;
-
- default:
- break;
- }
-
- dir = gatorfs_mkdir(sb, root, buf);
-
- if (!dir) {
- return -1;
- }
-
- gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
- gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
- gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
- }
-
- return 0;
+static int create_files(struct super_block *sb, struct dentry *root)
+{
+ struct dentry *dir;
+ int event;
+ int n_fp = NUM_FP_UNITS;
+
+ const char *mali_name = gator_mali_get_mali_name();
+
+ /*
+ * Create the filesystem entries for vertex processor, fragment processor
+ * and L2 cache timeline and hardware counters. Software counters get
+ * special handling after this block.
+ */
+ for (event = FIRST_ACTIVITY_EVENT; event <= LAST_HW_COUNTER; event++) {
+ char buf[40];
+
+ /*
+ * We can skip this event if it's for a non-existent fragment
+ * processor.
+ */
+ if (((event - ACTIVITY_FP0 >= n_fp) && (event < COUNTER_L2_C0))
+ || (((event - COUNTER_FP0_C0) / 2 >= n_fp))) {
+ continue;
+ }
+
+ /* Otherwise, set up the filesystem entry for this event. */
+ switch (event) {
+ case ACTIVITY_VP:
+ snprintf(buf, sizeof buf, "ARM_%s_VP_active", mali_name);
+ break;
+ case ACTIVITY_FP0:
+ case ACTIVITY_FP1:
+ case ACTIVITY_FP2:
+ case ACTIVITY_FP3:
+ snprintf(buf, sizeof buf, "ARM_%s_FP%d_active",
+ mali_name, event - ACTIVITY_FP0);
+ break;
+ case COUNTER_L2_C0:
+ case COUNTER_L2_C1:
+ snprintf(buf, sizeof buf, "ARM_%s_L2_cnt%d",
+ mali_name, event - COUNTER_L2_C0);
+ break;
+ case COUNTER_VP_C0:
+ case COUNTER_VP_C1:
+ snprintf(buf, sizeof buf, "ARM_%s_VP_cnt%d",
+ mali_name, event - COUNTER_VP_C0);
+ break;
+ case COUNTER_FP0_C0:
+ case COUNTER_FP0_C1:
+ case COUNTER_FP1_C0:
+ case COUNTER_FP1_C1:
+ case COUNTER_FP2_C0:
+ case COUNTER_FP2_C1:
+ case COUNTER_FP3_C0:
+ case COUNTER_FP3_C1:
+ snprintf(buf, sizeof buf, "ARM_%s_FP%d_cnt%d",
+ mali_name, (event - COUNTER_FP0_C0) / 2,
+ (event - COUNTER_FP0_C0) % 2);
+ break;
+ default:
+ printk("gator: trying to create file for non-existent counter (%d)\n", event);
+ continue;
+ }
+
+ dir = gatorfs_mkdir(sb, root, buf);
+
+ if (!dir) {
+ return -1;
+ }
+
+ gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
+
+ /* Only create an event node for counters that can change what they count */
+ if (event >= COUNTER_L2_C0) {
+ gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
+ }
+
+ gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
+ }
+
+ /* Now set up the software counter entries */
+ for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++) {
+ char buf[40];
+
+ snprintf(buf, sizeof(buf), "ARM_%s_SW_%d", mali_name, event);
+
+ dir = gatorfs_mkdir(sb, root, buf);
+
+ if (!dir) {
+ return -1;
+ }
+
+ gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
+ gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
+ }
+
+ /* Now set up the special counter entries */
+ for (event = FIRST_SPECIAL_COUNTER; event <= LAST_SPECIAL_COUNTER; event++) {
+ char buf[40];
+
+ switch (event) {
+ case COUNTER_FILMSTRIP:
+ snprintf(buf, sizeof(buf), "ARM_%s_Filmstrip_cnt0", mali_name);
+ break;
+
+ case COUNTER_FREQUENCY:
+ snprintf(buf, sizeof(buf), "ARM_%s_Frequency", mali_name);
+ break;
+
+ case COUNTER_VOLTAGE:
+ snprintf(buf, sizeof(buf), "ARM_%s_Voltage", mali_name);
+ break;
+
+ default:
+ break;
+ }
+
+ dir = gatorfs_mkdir(sb, root, buf);
+
+ if (!dir) {
+ return -1;
+ }
+
+ gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);
+ gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
+ gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);
+ }
+
+ return 0;
}
/*
@@ -426,312 +420,311 @@ static mali_profiling_get_counters_type *mali_get_counters = NULL;
*/
static int is_any_sw_counter_enabled(void)
{
- unsigned int i;
+ unsigned int i;
- for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++)
- {
- if (counter_enabled[i])
- {
- return 1; /* At least one counter is enabled */
- }
- }
+ for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
+ if (counter_enabled[i]) {
+ return 1; /* At least one counter is enabled */
+ }
+ }
- return 0; /* No s/w counters enabled */
+ return 0; /* No s/w counters enabled */
}
-static void mali_counter_initialize(void)
+static void mali_counter_initialize(void)
{
- /* If a Mali driver is present and exporting the appropriate symbol
- * then we can request the HW counters (of which there are only 2)
- * be configured to count the desired events
- */
- mali_profiling_set_event_type *mali_set_hw_event;
- mali_osk_fb_control_set_type *mali_set_fb_event;
- mali_profiling_control_type *mali_control;
-
- mali_set_hw_event = symbol_get(_mali_profiling_set_event);
-
- if (mali_set_hw_event) {
- int i;
-
- pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event);
-
- for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
- if (counter_enabled[i]) {
- mali_set_hw_event(i, counter_event[i]);
- } else {
- mali_set_hw_event(i, 0xFFFFFFFF);
- }
- }
-
- symbol_put(_mali_profiling_set_event);
- } else {
- printk("gator: mali online _mali_profiling_set_event symbol not found\n");
- }
-
- mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
-
- if (mali_set_fb_event) {
- pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
-
- mali_set_fb_event(0,(counter_enabled[COUNTER_FILMSTRIP]?1:0));
-
- symbol_put(_mali_osk_fb_control_set);
- } else {
- printk("gator: mali online _mali_osk_fb_control_set symbol not found\n");
- }
-
- /* Generic control interface for Mali DDK. */
- mali_control = symbol_get(_mali_profiling_control);
- if (mali_control) {
- /* The event attribute in the XML file keeps the actual frame rate. */
- unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff;
- unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff;
-
- pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control);
-
- mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled()?1:0));
- mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP]?1:0));
- mali_control(FBDUMP_CONTROL_RATE, rate);
- mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor);
-
- pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP]?1:0), rate);
-
- symbol_put(_mali_profiling_control);
- } else {
- printk("gator: mali online _mali_profiling_control symbol not found\n");
- }
-
- mali_get_counters = symbol_get(_mali_profiling_get_counters);
- if (mali_get_counters){
- pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters);
- counter_prev[COUNTER_L2_C0] = 0;
- counter_prev[COUNTER_L2_C1] = 0;
- }
- else{
- pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined");
- }
+ /* If a Mali driver is present and exporting the appropriate symbol
+ * then we can request the HW counters (of which there are only 2)
+ * be configured to count the desired events
+ */
+ mali_profiling_set_event_type *mali_set_hw_event;
+ mali_osk_fb_control_set_type *mali_set_fb_event;
+ mali_profiling_control_type *mali_control;
+
+ mali_set_hw_event = symbol_get(_mali_profiling_set_event);
+
+ if (mali_set_hw_event) {
+ int i;
+
+ pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);
+
+ for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
+ if (counter_enabled[i]) {
+ mali_set_hw_event(i, counter_event[i]);
+ } else {
+ mali_set_hw_event(i, 0xFFFFFFFF);
+ }
+ }
+
+ symbol_put(_mali_profiling_set_event);
+ } else {
+ printk("gator: mali online _mali_profiling_set_event symbol not found\n");
+ }
+
+ mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
+
+ if (mali_set_fb_event) {
+ pr_debug("gator: mali online _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
+
+ mali_set_fb_event(0, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0));
+
+ symbol_put(_mali_osk_fb_control_set);
+ } else {
+ printk("gator: mali online _mali_osk_fb_control_set symbol not found\n");
+ }
+
+ /* Generic control interface for Mali DDK. */
+ mali_control = symbol_get(_mali_profiling_control);
+ if (mali_control) {
+ /* The event attribute in the XML file keeps the actual frame rate. */
+ unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff;
+ unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff;
+
+ pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control);
+
+ mali_control(SW_EVENTS_ENABLE, (is_any_sw_counter_enabled() ? 1 : 0));
+ mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0));
+ mali_control(FBDUMP_CONTROL_RATE, rate);
+ mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor);
+
+ pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0), rate);
+
+ symbol_put(_mali_profiling_control);
+ } else {
+ printk("gator: mali online _mali_profiling_control symbol not found\n");
+ }
+
+ mali_get_counters = symbol_get(_mali_profiling_get_counters);
+ if (mali_get_counters) {
+ pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters);
+ counter_prev[COUNTER_L2_C0] = 0;
+ counter_prev[COUNTER_L2_C1] = 0;
+ } else {
+ pr_debug("gator WARNING: mali _mali_profiling_get_counters symbol not defined");
+ }
}
-static void mali_counter_deinitialize(void)
+static void mali_counter_deinitialize(void)
{
- mali_profiling_set_event_type *mali_set_hw_event;
- mali_osk_fb_control_set_type *mali_set_fb_event;
- mali_profiling_control_type *mali_control;
+ mali_profiling_set_event_type *mali_set_hw_event;
+ mali_osk_fb_control_set_type *mali_set_fb_event;
+ mali_profiling_control_type *mali_control;
+
+ mali_set_hw_event = symbol_get(_mali_profiling_set_event);
- mali_set_hw_event = symbol_get(_mali_profiling_set_event);
+ if (mali_set_hw_event) {
+ int i;
- if (mali_set_hw_event) {
- int i;
-
- pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n",mali_set_hw_event);
- for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
- mali_set_hw_event(i, 0xFFFFFFFF);
- }
-
- symbol_put(_mali_profiling_set_event);
- } else {
- printk("gator: mali offline _mali_profiling_set_event symbol not found\n");
- }
+ pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);
+ for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++) {
+ mali_set_hw_event(i, 0xFFFFFFFF);
+ }
- mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
+ symbol_put(_mali_profiling_set_event);
+ } else {
+ printk("gator: mali offline _mali_profiling_set_event symbol not found\n");
+ }
- if (mali_set_fb_event) {
- pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
+ mali_set_fb_event = symbol_get(_mali_osk_fb_control_set);
- mali_set_fb_event(0,0);
+ if (mali_set_fb_event) {
+ pr_debug("gator: mali offline _mali_osk_fb_control_set symbol @ %p\n", mali_set_fb_event);
- symbol_put(_mali_osk_fb_control_set);
- } else {
- printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n");
- }
+ mali_set_fb_event(0, 0);
- /* Generic control interface for Mali DDK. */
- mali_control = symbol_get(_mali_profiling_control);
+ symbol_put(_mali_osk_fb_control_set);
+ } else {
+ printk("gator: mali offline _mali_osk_fb_control_set symbol not found\n");
+ }
- if (mali_control) {
- pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event);
+ /* Generic control interface for Mali DDK. */
+ mali_control = symbol_get(_mali_profiling_control);
- /* Reset the DDK state - disable counter collection */
- mali_control(SW_EVENTS_ENABLE, 0);
+ if (mali_control) {
+ pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_set_fb_event);
- mali_control(FBDUMP_CONTROL_ENABLE, 0);
+ /* Reset the DDK state - disable counter collection */
+ mali_control(SW_EVENTS_ENABLE, 0);
- symbol_put(_mali_profiling_control);
- } else {
- printk("gator: mali offline _mali_profiling_control symbol not found\n");
- }
+ mali_control(FBDUMP_CONTROL_ENABLE, 0);
- if (mali_get_counters){
- symbol_put(_mali_profiling_get_counters);
- }
+ symbol_put(_mali_profiling_control);
+ } else {
+ printk("gator: mali offline _mali_profiling_control symbol not found\n");
+ }
+
+ if (mali_get_counters) {
+ symbol_put(_mali_profiling_get_counters);
+ }
}
-static int start(void) {
- // register tracepoints
- if (GATOR_REGISTER_TRACE(mali_hw_counter)) {
- printk("gator: mali_hw_counter tracepoint failed to activate\n");
- return -1;
- }
+static int start(void)
+{
+ // register tracepoints
+ if (GATOR_REGISTER_TRACE(mali_hw_counter)) {
+ printk("gator: mali_hw_counter tracepoint failed to activate\n");
+ return -1;
+ }
#if GATOR_MALI_INTERFACE_STYLE == 1
- /* None. */
+ /* None. */
#elif GATOR_MALI_INTERFACE_STYLE == 2
- /* For patched Mali driver. */
- if (GATOR_REGISTER_TRACE(mali_sw_counter)) {
- printk("gator: mali_sw_counter tracepoint failed to activate\n");
- return -1;
- }
+ /* For patched Mali driver. */
+ if (GATOR_REGISTER_TRACE(mali_sw_counter)) {
+ printk("gator: mali_sw_counter tracepoint failed to activate\n");
+ return -1;
+ }
#elif GATOR_MALI_INTERFACE_STYLE == 3
/* For Mali drivers with built-in support. */
- if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
- printk("gator: mali_sw_counters tracepoint failed to activate\n");
- return -1;
- }
+ if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
+ printk("gator: mali_sw_counters tracepoint failed to activate\n");
+ return -1;
+ }
#else
#error Unknown GATOR_MALI_INTERFACE_STYLE option.
#endif
- trace_registered = 1;
+ trace_registered = 1;
- mali_counter_initialize();
- return 0;
+ mali_counter_initialize();
+ return 0;
}
-static void stop(void) {
- unsigned int cnt;
+static void stop(void)
+{
+ unsigned int cnt;
- pr_debug("gator: mali stop\n");
+ pr_debug("gator: mali stop\n");
- if (trace_registered) {
- GATOR_UNREGISTER_TRACE(mali_hw_counter);
+ if (trace_registered) {
+ GATOR_UNREGISTER_TRACE(mali_hw_counter);
#if GATOR_MALI_INTERFACE_STYLE == 1
- /* None. */
+ /* None. */
#elif GATOR_MALI_INTERFACE_STYLE == 2
- /* For patched Mali driver. */
- GATOR_UNREGISTER_TRACE(mali_sw_counter);
+ /* For patched Mali driver. */
+ GATOR_UNREGISTER_TRACE(mali_sw_counter);
#elif GATOR_MALI_INTERFACE_STYLE == 3
- /* For Mali drivers with built-in support. */
- GATOR_UNREGISTER_TRACE(mali_sw_counters);
+ /* For Mali drivers with built-in support. */
+ GATOR_UNREGISTER_TRACE(mali_sw_counters);
#else
#error Unknown GATOR_MALI_INTERFACE_STYLE option.
#endif
- pr_debug("gator: mali timeline tracepoint deactivated\n");
-
- trace_registered = 0;
- }
+ pr_debug("gator: mali timeline tracepoint deactivated\n");
+
+ trace_registered = 0;
+ }
- for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
- counter_enabled[cnt] = 0;
- counter_event[cnt] = 0;
- counter_address[cnt] = NULL;
- }
+ for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
+ counter_enabled[cnt] = 0;
+ counter_event[cnt] = 0;
+ counter_address[cnt] = NULL;
+ }
- mali_counter_deinitialize();
+ mali_counter_deinitialize();
}
-static int read(int **buffer) {
- int cnt, len = 0;
-
- if (smp_processor_id()) return 0;
-
- // Read the L2 C0 and C1 here.
- if (counter_enabled[COUNTER_L2_C0] || counter_enabled[COUNTER_L2_C1] ) {
- u32 src0 = 0;
- u32 val0 = 0;
- u32 src1 = 0;
- u32 val1 = 0;
-
- // Poke the driver to get the counter values
- if (mali_get_counters){
- mali_get_counters(&src0, &val0, &src1, &val1);
- }
-
- if (counter_enabled[COUNTER_L2_C0])
- {
- // Calculate and save src0's counter val0
- counter_dump[len++] = counter_key[COUNTER_L2_C0];
- counter_dump[len++] = get_difference(val0, counter_prev[COUNTER_L2_C0]);
- }
-
- if (counter_enabled[COUNTER_L2_C1])
- {
- // Calculate and save src1's counter val1
- counter_dump[len++] = counter_key[COUNTER_L2_C1];
- counter_dump[len++] = get_difference(val1, counter_prev[COUNTER_L2_C1]);
- }
-
- // Save the previous values for the counters.
- counter_prev[COUNTER_L2_C0] = val0;
- counter_prev[COUNTER_L2_C1] = val1;
- }
-
- // Process other (non-timeline) counters.
- for (cnt = COUNTER_VP_C0; cnt <= LAST_SW_COUNTER; cnt++) {
- if (counter_enabled[cnt]) {
- counter_dump[len++] = counter_key[cnt];
- counter_dump[len++] = counter_data[cnt];
-
- counter_data[cnt] = 0;
- }
- }
-
- /*
- * Add in the voltage and frequency counters if enabled. Note that, since these are
- * actually passed as events, the counter value should not be cleared.
- */
- cnt = COUNTER_FREQUENCY;
- if (counter_enabled[cnt]) {
- counter_dump[len++] = counter_key[cnt];
- counter_dump[len++] = counter_data[cnt];
- }
-
- cnt = COUNTER_VOLTAGE;
- if (counter_enabled[cnt]) {
- counter_dump[len++] = counter_key[cnt];
- counter_dump[len++] = counter_data[cnt];
- }
-
-
- if (buffer) {
- *buffer = (int*) counter_dump;
- }
-
- return len;
+static int read(int **buffer)
+{
+ int cnt, len = 0;
+
+ if (smp_processor_id())
+ return 0;
+
+ // Read the L2 C0 and C1 here.
+ if (counter_enabled[COUNTER_L2_C0] || counter_enabled[COUNTER_L2_C1]) {
+ u32 src0 = 0;
+ u32 val0 = 0;
+ u32 src1 = 0;
+ u32 val1 = 0;
+
+ // Poke the driver to get the counter values
+ if (mali_get_counters) {
+ mali_get_counters(&src0, &val0, &src1, &val1);
+ }
+
+ if (counter_enabled[COUNTER_L2_C0]) {
+ // Calculate and save src0's counter val0
+ counter_dump[len++] = counter_key[COUNTER_L2_C0];
+ counter_dump[len++] = get_difference(val0, counter_prev[COUNTER_L2_C0]);
+ }
+
+ if (counter_enabled[COUNTER_L2_C1]) {
+ // Calculate and save src1's counter val1
+ counter_dump[len++] = counter_key[COUNTER_L2_C1];
+ counter_dump[len++] = get_difference(val1, counter_prev[COUNTER_L2_C1]);
+ }
+
+ // Save the previous values for the counters.
+ counter_prev[COUNTER_L2_C0] = val0;
+ counter_prev[COUNTER_L2_C1] = val1;
+ }
+
+ // Process other (non-timeline) counters.
+ for (cnt = COUNTER_VP_C0; cnt <= LAST_SW_COUNTER; cnt++) {
+ if (counter_enabled[cnt]) {
+ counter_dump[len++] = counter_key[cnt];
+ counter_dump[len++] = counter_data[cnt];
+
+ counter_data[cnt] = 0;
+ }
+ }
+
+ /*
+ * Add in the voltage and frequency counters if enabled. Note that, since these are
+ * actually passed as events, the counter value should not be cleared.
+ */
+ cnt = COUNTER_FREQUENCY;
+ if (counter_enabled[cnt]) {
+ counter_dump[len++] = counter_key[cnt];
+ counter_dump[len++] = counter_data[cnt];
+ }
+
+ cnt = COUNTER_VOLTAGE;
+ if (counter_enabled[cnt]) {
+ counter_dump[len++] = counter_key[cnt];
+ counter_dump[len++] = counter_data[cnt];
+ }
+
+ if (buffer) {
+ *buffer = (int *)counter_dump;
+ }
+
+ return len;
}
static struct gator_interface gator_events_mali_interface = {
- .create_files = create_files,
- .start = start,
- .stop = stop,
- .read = read,
+ .create_files = create_files,
+ .start = start,
+ .stop = stop,
+ .read = read,
};
-extern void gator_events_mali_log_dvfs_event(unsigned int frequency_mhz, unsigned int voltage_mv) {
+extern void gator_events_mali_log_dvfs_event(unsigned int frequency_mhz, unsigned int voltage_mv)
+{
counter_data[COUNTER_FREQUENCY] = frequency_mhz;
counter_data[COUNTER_VOLTAGE] = voltage_mv;
}
int gator_events_mali_init(void)
{
- unsigned int cnt;
+ unsigned int cnt;
- pr_debug("gator: mali init\n");
+ pr_debug("gator: mali init\n");
- for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
- counter_enabled[cnt] = 0;
- counter_event[cnt] = 0;
- counter_key[cnt] = gator_events_get_key();
- counter_address[cnt] = NULL;
- counter_data[cnt] = 0;
- }
+ for (cnt = FIRST_ACTIVITY_EVENT; cnt < NUMBER_OF_EVENTS; cnt++) {
+ counter_enabled[cnt] = 0;
+ counter_event[cnt] = 0;
+ counter_key[cnt] = gator_events_get_key();
+ counter_address[cnt] = NULL;
+ counter_data[cnt] = 0;
+ }
- trace_registered = 0;
+ trace_registered = 0;
- return gator_events_install(&gator_events_mali_interface);
+ return gator_events_install(&gator_events_mali_interface);
}
gator_events_init(gator_events_mali_init);
diff --git a/driver/gator_events_mali_common.c b/driver/gator_events_mali_common.c
index 62e441c..2186eee 100644
--- a/driver/gator_events_mali_common.c
+++ b/driver/gator_events_mali_common.c
@@ -10,69 +10,65 @@
static u32 gator_mali_get_id(void)
{
- return MALI_SUPPORT;
+ return MALI_SUPPORT;
}
-extern const char* gator_mali_get_mali_name(void)
+extern const char *gator_mali_get_mali_name(void)
{
- u32 id = gator_mali_get_id();
+ u32 id = gator_mali_get_id();
- switch (id) {
- case MALI_T6xx:
- return "Mali-T6xx";
- case MALI_400:
- return "Mali-400";
- default:
- pr_debug("gator: Mali-T6xx: unknown Mali ID (%d)\n", id);
- return "Mali-Unknown";
- }
+ switch (id) {
+ case MALI_T6xx:
+ return "Mali-T6xx";
+ case MALI_400:
+ return "Mali-400";
+ default:
+ pr_debug("gator: Mali-T6xx: unknown Mali ID (%d)\n", id);
+ return "Mali-Unknown";
+ }
}
-extern int gator_mali_create_file_system(const char* mali_name, const char* event_name, struct super_block *sb, struct dentry *root, mali_counter *counter)
+extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter)
{
- int err;
- char buf[255];
- struct dentry *dir;
+ int err;
+ char buf[255];
+ struct dentry *dir;
- /* If the counter name is empty ignore it*/
- if (strlen(event_name) != 0)
- {
- /* Set up the filesystem entry for this event. */
- snprintf(buf, sizeof(buf), "ARM_%s_%s", mali_name, event_name);
+ /* If the counter name is empty ignore it */
+ if (strlen(event_name) != 0) {
+ /* Set up the filesystem entry for this event. */
+ snprintf(buf, sizeof(buf), "ARM_%s_%s", mali_name, event_name);
- dir = gatorfs_mkdir(sb, root, buf);
+ dir = gatorfs_mkdir(sb, root, buf);
- if (dir == NULL)
- {
- pr_debug("gator: Mali-T6xx: error creating file system for: %s (%s)", event_name, buf);
- return -1;
- }
+ if (dir == NULL) {
+ pr_debug("gator: Mali-T6xx: error creating file system for: %s (%s)", event_name, buf);
+ return -1;
+ }
- err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled);
- if (err != 0)
- {
- pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ulong for: %s (%s)", event_name, buf);
- return -1;
- }
- err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key);
- if (err != 0)
- {
- pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf);
- return -1;
- }
- }
+ err = gatorfs_create_ulong(sb, dir, "enabled", &counter->enabled);
+ if (err != 0) {
+ pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ulong for: %s (%s)", event_name, buf);
+ return -1;
+ }
+ err = gatorfs_create_ro_ulong(sb, dir, "key", &counter->key);
+ if (err != 0) {
+ pr_debug("gator: Mali-T6xx: error calling gatorfs_create_ro_ulong for: %s (%s)", event_name, buf);
+ return -1;
+ }
+ }
- return 0;
+ return 0;
}
extern void gator_mali_initialise_counters(mali_counter counters[], unsigned int n_counters)
{
- unsigned int cnt;
+ unsigned int cnt;
- for (cnt = 0; cnt < n_counters; cnt++) {
- mali_counter *counter = &counters[cnt];
+ for (cnt = 0; cnt < n_counters; cnt++) {
+ mali_counter *counter = &counters[cnt];
- counter->key = gator_events_get_key();
- counter->enabled = 0;
- }
+ counter->key = gator_events_get_key();
+ counter->enabled = 0;
+ }
}
diff --git a/driver/gator_events_mali_common.h b/driver/gator_events_mali_common.h
index 2c9457f..8e33edf 100644
--- a/driver/gator_events_mali_common.h
+++ b/driver/gator_events_mali_common.h
@@ -35,8 +35,8 @@
* Runtime state information for a counter.
*/
typedef struct {
- unsigned long key; /* 'key' (a unique id set by gatord and returned by gator.ko) */
- unsigned long enabled; /* counter enable state */
+ unsigned long key; /* 'key' (a unique id set by gatord and returned by gator.ko) */
+ unsigned long enabled; /* counter enable state */
} mali_counter;
/*
@@ -45,7 +45,7 @@ typedef struct {
typedef void mali_profiling_set_event_type(unsigned int, unsigned int);
typedef void mali_osk_fb_control_set_type(unsigned int, unsigned int);
typedef void mali_profiling_control_type(unsigned int, unsigned int);
-typedef void mali_profiling_get_counters_type(unsigned int*, unsigned int*, unsigned int*, unsigned int*);
+typedef void mali_profiling_get_counters_type(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
/*
* Driver entry points for functions called directly by gator.
@@ -53,14 +53,14 @@ typedef void mali_profiling_get_counters_type(unsigned int*, unsigned int*, unsi
extern void _mali_profiling_set_event(unsigned int, unsigned int);
extern void _mali_osk_fb_control_set(unsigned int, unsigned int);
extern void _mali_profiling_control(unsigned int, unsigned int);
-extern void _mali_profiling_get_counters(unsigned int*, unsigned int*, unsigned int*, unsigned int*);
+extern void _mali_profiling_get_counters(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
/**
* Returns a name which identifies the GPU type (eg Mali-400, Mali-T6xx).
*
* @return The name as a constant string.
*/
-extern const char* gator_mali_get_mali_name(void);
+extern const char *gator_mali_get_mali_name(void);
/**
* Creates a filesystem entry under /dev/gator relating to the specified event name and key, and
@@ -75,10 +75,10 @@ extern const char* gator_mali_get_mali_name(void);
*
* @return 0 if entry point was created, non-zero if not.
*/
-extern int gator_mali_create_file_system(const char* mali_name, const char* event_name, struct super_block *sb, struct dentry *root, mali_counter *counter);
+extern int gator_mali_create_file_system(const char *mali_name, const char *event_name, struct super_block *sb, struct dentry *root, mali_counter *counter);
/**
- * Initialises the counter array.
+ * Initializes the counter array.
*
* @param keys The array of counters
* @param n_counters The number of entries in each of the arrays.
diff --git a/driver/gator_events_mali_t6xx.c b/driver/gator_events_mali_t6xx.c
index f8f868e..1b3a53d 100644
--- a/driver/gator_events_mali_t6xx.c
+++ b/driver/gator_events_mali_t6xx.c
@@ -17,7 +17,6 @@
#include "linux/mali_linux_trace.h"
-
#include "gator_events_mali_common.h"
/*
@@ -27,7 +26,6 @@
#error MALI_SUPPORT set to an invalid device code: expecting MALI_T6xx
#endif
-
/* Counters for Mali-T6xx:
*
* - Timeline events
@@ -43,72 +41,66 @@
*/
/* Timeline (start/stop) activity */
-static const char* timeline_event_names [] =
-{
- "PM_SHADER_0",
- "PM_SHADER_1",
- "PM_SHADER_2",
- "PM_SHADER_3",
- "PM_SHADER_4",
- "PM_SHADER_5",
- "PM_SHADER_6",
- "PM_SHADER_7",
- "PM_TILER_0",
- "PM_L2_0",
- "PM_L2_1",
- "MMU_AS_0",
- "MMU_AS_1",
- "MMU_AS_2",
- "MMU_AS_3"
+static const char *timeline_event_names[] = {
+ "PM_SHADER_0",
+ "PM_SHADER_1",
+ "PM_SHADER_2",
+ "PM_SHADER_3",
+ "PM_SHADER_4",
+ "PM_SHADER_5",
+ "PM_SHADER_6",
+ "PM_SHADER_7",
+ "PM_TILER_0",
+ "PM_L2_0",
+ "PM_L2_1",
+ "MMU_AS_0",
+ "MMU_AS_1",
+ "MMU_AS_2",
+ "MMU_AS_3"
};
-enum
-{
- PM_SHADER_0 = 0,
- PM_SHADER_1,
- PM_SHADER_2,
- PM_SHADER_3,
- PM_SHADER_4,
- PM_SHADER_5,
- PM_SHADER_6,
- PM_SHADER_7,
- PM_TILER_0,
- PM_L2_0,
- PM_L2_1,
- MMU_AS_0,
- MMU_AS_1,
- MMU_AS_2,
- MMU_AS_3
+enum {
+ PM_SHADER_0 = 0,
+ PM_SHADER_1,
+ PM_SHADER_2,
+ PM_SHADER_3,
+ PM_SHADER_4,
+ PM_SHADER_5,
+ PM_SHADER_6,
+ PM_SHADER_7,
+ PM_TILER_0,
+ PM_L2_0,
+ PM_L2_1,
+ MMU_AS_0,
+ MMU_AS_1,
+ MMU_AS_2,
+ MMU_AS_3
};
/* The number of shader blocks in the enum above */
#define NUM_PM_SHADER (8)
/* Software Counters */
-static const char* software_counter_names [] =
-{
- "MMU_PAGE_FAULT_0",
- "MMU_PAGE_FAULT_1",
- "MMU_PAGE_FAULT_2",
- "MMU_PAGE_FAULT_3"
+static const char *software_counter_names[] = {
+ "MMU_PAGE_FAULT_0",
+ "MMU_PAGE_FAULT_1",
+ "MMU_PAGE_FAULT_2",
+ "MMU_PAGE_FAULT_3"
};
-enum
-{
- MMU_PAGE_FAULT_0 = 0,
- MMU_PAGE_FAULT_1,
- MMU_PAGE_FAULT_2,
- MMU_PAGE_FAULT_3
+enum {
+ MMU_PAGE_FAULT_0 = 0,
+ MMU_PAGE_FAULT_1,
+ MMU_PAGE_FAULT_2,
+ MMU_PAGE_FAULT_3
};
/* Software Counters */
-static const char* accumulators_names [] =
-{
- "TOTAL_ALLOC_PAGES"
+static const char *accumulators_names[] = {
+ "TOTAL_ALLOC_PAGES"
};
-enum
-{
- TOTAL_ALLOC_PAGES = 0
+enum {
+ TOTAL_ALLOC_PAGES = 0
};
#define FIRST_TIMELINE_EVENT (0)
@@ -153,49 +145,46 @@ static struct timespec prev_timestamp;
*/
static inline long get_duration_us(const struct timespec *start, const struct timespec *end)
{
- long event_duration_us = (end->tv_nsec - start->tv_nsec)/1000;
- event_duration_us += (end->tv_sec - start->tv_sec) * 1000000;
+ long event_duration_us = (end->tv_nsec - start->tv_nsec) / 1000;
+ event_duration_us += (end->tv_sec - start->tv_sec) * 1000000;
- return event_duration_us;
+ return event_duration_us;
}
static void record_timeline_event(unsigned int timeline_index, unsigned int type)
{
- struct timespec event_timestamp;
- struct timespec *event_start = &timeline_event_starttime[timeline_index];
-
- switch(type)
- {
- case ACTIVITY_START:
- /* Get the event time... */
- getnstimeofday(&event_timestamp);
-
- /* Remember the start time if the activity is not already started */
- if(event_start->tv_sec == 0)
- {
- *event_start = event_timestamp; /* Structure copy */
- }
- break;
-
- case ACTIVITY_STOP:
- /* if the counter was started... */
- if(event_start->tv_sec != 0)
- {
- /* Get the event time... */
- getnstimeofday(&event_timestamp);
-
- /* Accumulate the duration in us */
- timeline_data[timeline_index] += get_duration_us(event_start, &event_timestamp);
-
- /* Reset the start time to indicate the activity is stopped. */
- event_start->tv_sec = 0;
- }
- break;
-
- default:
- /* Other activity events are ignored. */
- break;
- }
+ struct timespec event_timestamp;
+ struct timespec *event_start = &timeline_event_starttime[timeline_index];
+
+ switch (type) {
+ case ACTIVITY_START:
+ /* Get the event time... */
+ getnstimeofday(&event_timestamp);
+
+ /* Remember the start time if the activity is not already started */
+ if (event_start->tv_sec == 0) {
+ *event_start = event_timestamp; /* Structure copy */
+ }
+ break;
+
+ case ACTIVITY_STOP:
+ /* if the counter was started... */
+ if (event_start->tv_sec != 0) {
+ /* Get the event time... */
+ getnstimeofday(&event_timestamp);
+
+ /* Accumulate the duration in us */
+ timeline_data[timeline_index] += get_duration_us(event_start, &event_timestamp);
+
+ /* Reset the start time to indicate the activity is stopped. */
+ event_start->tv_sec = 0;
+ }
+ break;
+
+ default:
+ /* Other activity events are ignored. */
+ break;
+ }
}
/*
@@ -204,68 +193,62 @@ static void record_timeline_event(unsigned int timeline_index, unsigned int type
GATOR_DEFINE_PROBE(mali_pm_status, TP_PROTO(unsigned int event_id, unsigned long long value))
{
-#define SHADER_PRESENT_LO 0x100 /* (RO) Shader core present bitmap, low word */
-#define TILER_PRESENT_LO 0x110 /* (RO) Tiler core present bitmap, low word */
-#define L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */
+#define SHADER_PRESENT_LO 0x100 /* (RO) Shader core present bitmap, low word */
+#define TILER_PRESENT_LO 0x110 /* (RO) Tiler core present bitmap, low word */
+#define L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */
#define BIT_AT(value, pos) ((value >> pos) & 1)
- static unsigned long long previous_shader_bitmask = 0;
- static unsigned long long previous_tiler_bitmask = 0;
- static unsigned long long previous_l2_bitmask = 0;
-
- switch (event_id)
- {
- case SHADER_PRESENT_LO:
- {
- unsigned long long changed_bitmask = previous_shader_bitmask ^ value;
- int pos;
-
- for (pos = 0; pos < NUM_PM_SHADER; ++pos)
- {
- if (BIT_AT(changed_bitmask, pos))
- {
- record_timeline_event(PM_SHADER_0 + pos, BIT_AT(value, pos) ? ACTIVITY_START : ACTIVITY_STOP);
- }
- }
-
- previous_shader_bitmask = value;
- break;
- }
-
- case TILER_PRESENT_LO:
- {
- unsigned long long changed = previous_tiler_bitmask ^ value;
-
- if (BIT_AT(changed, 0))
- {
- record_timeline_event(PM_TILER_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
- }
-
- previous_tiler_bitmask = value;
- break;
- }
-
- case L2_PRESENT_LO:
- {
- unsigned long long changed = previous_l2_bitmask ^ value;
-
- if (BIT_AT(changed, 0))
- {
- record_timeline_event(PM_L2_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
- }
- if (BIT_AT(changed, 4))
- {
- record_timeline_event(PM_L2_1, BIT_AT(value, 4) ? ACTIVITY_START : ACTIVITY_STOP);
- }
-
- previous_l2_bitmask = value;
- break;
- }
-
- default:
- /* No other blocks are supported at present */
- break;
- }
+ static unsigned long long previous_shader_bitmask = 0;
+ static unsigned long long previous_tiler_bitmask = 0;
+ static unsigned long long previous_l2_bitmask = 0;
+
+ switch (event_id) {
+ case SHADER_PRESENT_LO:
+ {
+ unsigned long long changed_bitmask = previous_shader_bitmask ^ value;
+ int pos;
+
+ for (pos = 0; pos < NUM_PM_SHADER; ++pos) {
+ if (BIT_AT(changed_bitmask, pos)) {
+ record_timeline_event(PM_SHADER_0 + pos, BIT_AT(value, pos) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+ }
+
+ previous_shader_bitmask = value;
+ break;
+ }
+
+ case TILER_PRESENT_LO:
+ {
+ unsigned long long changed = previous_tiler_bitmask ^ value;
+
+ if (BIT_AT(changed, 0)) {
+ record_timeline_event(PM_TILER_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+
+ previous_tiler_bitmask = value;
+ break;
+ }
+
+ case L2_PRESENT_LO:
+ {
+ unsigned long long changed = previous_l2_bitmask ^ value;
+
+ if (BIT_AT(changed, 0)) {
+ record_timeline_event(PM_L2_0, BIT_AT(value, 0) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+ if (BIT_AT(changed, 4)) {
+ record_timeline_event(PM_L2_1, BIT_AT(value, 4) ? ACTIVITY_START : ACTIVITY_STOP);
+ }
+
+ previous_l2_bitmask = value;
+ break;
+ }
+
+ default:
+ /* No other blocks are supported at present */
+ break;
+ }
#undef SHADER_PRESENT_LO
#undef TILER_PRESENT_LO
@@ -275,278 +258,255 @@ GATOR_DEFINE_PROBE(mali_pm_status, TP_PROTO(unsigned int event_id, unsigned long
GATOR_DEFINE_PROBE(mali_page_fault_insert_pages, TP_PROTO(int event_id, unsigned long value))
{
- /* We add to the previous since we may receive many tracepoints in one sample period */
- sw_counter_data[MMU_PAGE_FAULT_0 + event_id] += value;
+ /* We add to the previous since we may receive many tracepoints in one sample period */
+ sw_counter_data[MMU_PAGE_FAULT_0 + event_id] += value;
}
GATOR_DEFINE_PROBE(mali_mmu_as_in_use, TP_PROTO(int event_id))
{
- record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_START);
+ record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_START);
}
GATOR_DEFINE_PROBE(mali_mmu_as_released, TP_PROTO(int event_id))
{
- record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_STOP);
+ record_timeline_event(MMU_AS_0 + event_id, ACTIVITY_STOP);
}
GATOR_DEFINE_PROBE(mali_total_alloc_pages_change, TP_PROTO(long long int event_id))
{
- accumulators_data[TOTAL_ALLOC_PAGES] = event_id;
+ accumulators_data[TOTAL_ALLOC_PAGES] = event_id;
}
static int create_files(struct super_block *sb, struct dentry *root)
{
- int event;
- /*
- * Create the filesystem for all events
- */
- int counter_index = 0;
- const char* mali_name = gator_mali_get_mali_name();
-
- for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++)
- {
- if (gator_mali_create_file_system(mali_name, timeline_event_names[counter_index], sb, root, &counters[event]) != 0)
- {
- return -1;
- }
- counter_index++;
- }
- counter_index = 0;
- for (event = FIRST_SOFTWARE_COUNTER; event < FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS; event++)
- {
- if (gator_mali_create_file_system(mali_name, software_counter_names[counter_index], sb, root, &counters[event]) != 0)
- {
- return -1;
- }
- counter_index++;
- }
- counter_index = 0;
- for (event = FIRST_ACCUMULATOR; event < FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS; event++)
- {
- if (gator_mali_create_file_system(mali_name, accumulators_names[counter_index], sb, root, &counters[event]) != 0)
- {
- return -1;
- }
- counter_index++;
- }
-
- return 0;
+ int event;
+ /*
+ * Create the filesystem for all events
+ */
+ int counter_index = 0;
+ const char *mali_name = gator_mali_get_mali_name();
+
+ for (event = FIRST_TIMELINE_EVENT; event < FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS; event++) {
+ if (gator_mali_create_file_system(mali_name, timeline_event_names[counter_index], sb, root, &counters[event]) != 0) {
+ return -1;
+ }
+ counter_index++;
+ }
+ counter_index = 0;
+ for (event = FIRST_SOFTWARE_COUNTER; event < FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS; event++) {
+ if (gator_mali_create_file_system(mali_name, software_counter_names[counter_index], sb, root, &counters[event]) != 0) {
+ return -1;
+ }
+ counter_index++;
+ }
+ counter_index = 0;
+ for (event = FIRST_ACCUMULATOR; event < FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS; event++) {
+ if (gator_mali_create_file_system(mali_name, accumulators_names[counter_index], sb, root, &counters[event]) != 0) {
+ return -1;
+ }
+ counter_index++;
+ }
+
+ return 0;
}
static int register_tracepoints(void)
{
- if (GATOR_REGISTER_TRACE(mali_pm_status))
- {
- pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_page_fault_insert_pages))
- {
- pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_mmu_as_in_use))
- {
- pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_mmu_as_released))
- {
- pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint failed to activate\n");
- return 0;
- }
-
- if (GATOR_REGISTER_TRACE(mali_total_alloc_pages_change))
- {
- pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint failed to activate\n");
- return 0;
- }
-
- pr_debug("gator: Mali-T6xx: start\n");
- pr_debug("gator: Mali-T6xx: mali_pm_status probe is at %p\n", &probe_mali_pm_status);
- pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages probe is at %p\n", &probe_mali_page_fault_insert_pages);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use probe is at %p\n", &probe_mali_mmu_as_in_use);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_released probe is at %p\n", &probe_mali_mmu_as_released);
- pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change probe is at %p\n", &probe_mali_total_alloc_pages_change);
-
- return 1;
+ if (GATOR_REGISTER_TRACE(mali_pm_status)) {
+ pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_page_fault_insert_pages)) {
+ pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_mmu_as_in_use)) {
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_mmu_as_released)) {
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint failed to activate\n");
+ return 0;
+ }
+
+ if (GATOR_REGISTER_TRACE(mali_total_alloc_pages_change)) {
+ pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint failed to activate\n");
+ return 0;
+ }
+
+ pr_debug("gator: Mali-T6xx: start\n");
+ pr_debug("gator: Mali-T6xx: mali_pm_status probe is at %p\n", &probe_mali_pm_status);
+ pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages probe is at %p\n", &probe_mali_page_fault_insert_pages);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use probe is at %p\n", &probe_mali_mmu_as_in_use);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_released probe is at %p\n", &probe_mali_mmu_as_released);
+ pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change probe is at %p\n", &probe_mali_total_alloc_pages_change);
+
+ return 1;
}
static int start(void)
{
- unsigned int cnt;
-
- /* Clean all data for the next capture */
- for (cnt = 0; cnt < NUMBER_OF_TIMELINE_EVENTS; cnt++)
- {
- timeline_event_starttime[cnt].tv_sec = timeline_event_starttime[cnt].tv_nsec = 0;
- timeline_data[cnt] = 0;
- }
-
- for (cnt = 0; cnt < NUMBER_OF_SOFTWARE_COUNTERS; cnt++)
- {
- sw_counter_data[cnt] = 0;
- }
-
- for (cnt = 0; cnt < NUMBER_OF_ACCUMULATORS; cnt++)
- {
- accumulators_data[cnt] = 0;
- }
-
- /* Register tracepoints */
- if (register_tracepoints() == 0)
- {
- return -1;
- }
-
- /*
- * Set the first timestamp for calculating the sample interval. The first interval could be quite long,
- * since it will be the time between 'start' and the first 'read'.
- * This means that timeline values will be divided by a big number for the first sample.
- */
- getnstimeofday(&prev_timestamp);
-
- return 0;
+ unsigned int cnt;
+
+ /* Clean all data for the next capture */
+ for (cnt = 0; cnt < NUMBER_OF_TIMELINE_EVENTS; cnt++) {
+ timeline_event_starttime[cnt].tv_sec = timeline_event_starttime[cnt].tv_nsec = 0;
+ timeline_data[cnt] = 0;
+ }
+
+ for (cnt = 0; cnt < NUMBER_OF_SOFTWARE_COUNTERS; cnt++) {
+ sw_counter_data[cnt] = 0;
+ }
+
+ for (cnt = 0; cnt < NUMBER_OF_ACCUMULATORS; cnt++) {
+ accumulators_data[cnt] = 0;
+ }
+
+ /* Register tracepoints */
+ if (register_tracepoints() == 0) {
+ return -1;
+ }
+
+ /*
+ * Set the first timestamp for calculating the sample interval. The first interval could be quite long,
+ * since it will be the time between 'start' and the first 'read'.
+ * This means that timeline values will be divided by a big number for the first sample.
+ */
+ getnstimeofday(&prev_timestamp);
+
+ return 0;
}
static void stop(void)
{
- pr_debug("gator: Mali-T6xx: stop\n");
+ pr_debug("gator: Mali-T6xx: stop\n");
- /*
- * It is safe to unregister traces even if they were not successfully
- * registered, so no need to check.
- */
- GATOR_UNREGISTER_TRACE(mali_pm_status);
- pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint deactivated\n");
+ /*
+ * It is safe to unregister traces even if they were not successfully
+ * registered, so no need to check.
+ */
+ GATOR_UNREGISTER_TRACE(mali_pm_status);
+ pr_debug("gator: Mali-T6xx: mali_pm_status tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_page_fault_insert_pages);
- pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_page_fault_insert_pages);
+ pr_debug("gator: Mali-T6xx: mali_page_fault_insert_pages tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_mmu_as_in_use);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_mmu_as_in_use);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_in_use tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_mmu_as_released);
- pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_mmu_as_released);
+ pr_debug("gator: Mali-T6xx: mali_mmu_as_released tracepoint deactivated\n");
- GATOR_UNREGISTER_TRACE(mali_total_alloc_pages_change);
- pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint deactivated\n");
+ GATOR_UNREGISTER_TRACE(mali_total_alloc_pages_change);
+ pr_debug("gator: Mali-T6xx: mali_total_alloc_pages_change tracepoint deactivated\n");
}
static int read(int **buffer)
{
- int cnt;
- int len = 0;
- long sample_interval_us = 0;
- struct timespec read_timestamp;
-
- if (smp_processor_id()!=0)
- {
- return 0;
- }
-
- /* Get the start of this sample period. */
- getnstimeofday(&read_timestamp);
-
- /*
- * Calculate the sample interval if the previous sample time is valid.
- * We use tv_sec since it will not be 0.
- */
- if(prev_timestamp.tv_sec != 0) {
- sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp);
- }
-
- /* Structure copy. Update the previous timestamp. */
- prev_timestamp = read_timestamp;
-
- /*
- * Report the timeline counters (ACTIVITY_START/STOP)
- */
- for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++)
- {
- mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int index = cnt - FIRST_TIMELINE_EVENT;
- unsigned int value;
-
- /* If the activity is still running, reset its start time to the start of this sample period
- * to correct the count. Add the time up to the end of the sample onto the count. */
- if(timeline_event_starttime[index].tv_sec != 0) {
- const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp);
- timeline_data[index] += event_duration;
- timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */
- }
-
- if(sample_interval_us != 0) {
- /* Convert the counter to a percent-of-sample value */
- value = (timeline_data[index] * 100) / sample_interval_us;
- } else {
- pr_debug("gator: Mali-T6xx: setting value to zero\n");
- value = 0;
- }
-
- /* Clear the counter value ready for the next sample. */
- timeline_data[index] = 0;
-
- counter_dump[len++] = counter->key;
- counter_dump[len++] = value;
- }
- }
-
- /* Report the software counters */
- for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int index = cnt - FIRST_SOFTWARE_COUNTER;
- counter_dump[len++] = counter->key;
- counter_dump[len++] = sw_counter_data[index];
- /* Set the value to zero for the next time */
- sw_counter_data[index] = 0;
- }
- }
-
- /* Report the accumulators */
- for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int index = cnt - FIRST_ACCUMULATOR;
- counter_dump[len++] = counter->key;
- counter_dump[len++] = accumulators_data[index];
- /* Do not zero the accumulator */
- }
- }
-
- /* Update the buffer */
- if (buffer)
- {
- *buffer = (int*) counter_dump;
- }
-
- return len;
+ int cnt;
+ int len = 0;
+ long sample_interval_us = 0;
+ struct timespec read_timestamp;
+
+ if (smp_processor_id() != 0) {
+ return 0;
+ }
+
+ /* Get the start of this sample period. */
+ getnstimeofday(&read_timestamp);
+
+ /*
+ * Calculate the sample interval if the previous sample time is valid.
+ * We use tv_sec since it will not be 0.
+ */
+ if (prev_timestamp.tv_sec != 0) {
+ sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp);
+ }
+
+ /* Structure copy. Update the previous timestamp. */
+ prev_timestamp = read_timestamp;
+
+ /*
+ * Report the timeline counters (ACTIVITY_START/STOP)
+ */
+ for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++) {
+ mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int index = cnt - FIRST_TIMELINE_EVENT;
+ unsigned int value;
+
+ /* If the activity is still running, reset its start time to the start of this sample period
+ * to correct the count. Add the time up to the end of the sample onto the count. */
+ if (timeline_event_starttime[index].tv_sec != 0) {
+ const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp);
+ timeline_data[index] += event_duration;
+ timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */
+ }
+
+ if (sample_interval_us != 0) {
+ /* Convert the counter to a percent-of-sample value */
+ value = (timeline_data[index] * 100) / sample_interval_us;
+ } else {
+ pr_debug("gator: Mali-T6xx: setting value to zero\n");
+ value = 0;
+ }
+
+ /* Clear the counter value ready for the next sample. */
+ timeline_data[index] = 0;
+
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = value;
+ }
+ }
+
+ /* Report the software counters */
+ for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int index = cnt - FIRST_SOFTWARE_COUNTER;
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = sw_counter_data[index];
+ /* Set the value to zero for the next time */
+ sw_counter_data[index] = 0;
+ }
+ }
+
+ /* Report the accumulators */
+ for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int index = cnt - FIRST_ACCUMULATOR;
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = accumulators_data[index];
+ /* Do not zero the accumulator */
+ }
+ }
+
+ /* Update the buffer */
+ if (buffer) {
+ *buffer = (int *)counter_dump;
+ }
+
+ return len;
}
static struct gator_interface gator_events_mali_t6xx_interface = {
- .create_files = create_files,
- .start = start,
- .stop = stop,
- .read = read
+ .create_files = create_files,
+ .start = start,
+ .stop = stop,
+ .read = read
};
extern int gator_events_mali_t6xx_init(void)
{
- pr_debug("gator: Mali-T6xx: sw_counters init\n");
+ pr_debug("gator: Mali-T6xx: sw_counters init\n");
- gator_mali_initialise_counters(counters, NUMBER_OF_EVENTS);
+ gator_mali_initialise_counters(counters, NUMBER_OF_EVENTS);
- return gator_events_install(&gator_events_mali_t6xx_interface);
+ return gator_events_install(&gator_events_mali_t6xx_interface);
}
gator_events_init(gator_events_mali_t6xx_init);
diff --git a/driver/gator_events_mali_t6xx_hw.c b/driver/gator_events_mali_t6xx_hw.c
index d4945c7..72498c8 100644
--- a/driver/gator_events_mali_t6xx_hw.c
+++ b/driver/gator_events_mali_t6xx_hw.c
@@ -26,7 +26,7 @@
* Mali-T6xx
*/
typedef struct kbase_device *kbase_find_device_type(int);
-typedef kbase_context *kbase_create_context_type(kbase_device*);
+typedef kbase_context *kbase_create_context_type(kbase_device *);
typedef void kbase_destroy_context_type(kbase_context *);
typedef void *kbase_va_alloc_type(kbase_context *, u32);
typedef void kbase_va_free_type(kbase_context *, void *);
@@ -36,32 +36,41 @@ typedef mali_error kbase_instr_hwcnt_clear_type(kbase_context *);
typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *);
typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *);
-static kbase_find_device_type * kbase_find_device_symbol;
-static kbase_create_context_type * kbase_create_context_symbol;
-static kbase_va_alloc_type * kbase_va_alloc_symbol;
-static kbase_instr_hwcnt_enable_type * kbase_instr_hwcnt_enable_symbol;
-static kbase_instr_hwcnt_clear_type * kbase_instr_hwcnt_clear_symbol;
-static kbase_instr_hwcnt_dump_irq_type * kbase_instr_hwcnt_dump_irq_symbol;
-static kbase_instr_hwcnt_dump_complete_type * kbase_instr_hwcnt_dump_complete_symbol;
-static kbase_instr_hwcnt_disable_type * kbase_instr_hwcnt_disable_symbol;
-static kbase_va_free_type * kbase_va_free_symbol;
-static kbase_destroy_context_type * kbase_destroy_context_symbol;
-
-/** The interval between reads, in ns. */
-static const int READ_INTERVAL_NSEC = 1000000;
-
+static kbase_find_device_type *kbase_find_device_symbol;
+static kbase_create_context_type *kbase_create_context_symbol;
+static kbase_va_alloc_type *kbase_va_alloc_symbol;
+static kbase_instr_hwcnt_enable_type *kbase_instr_hwcnt_enable_symbol;
+static kbase_instr_hwcnt_clear_type *kbase_instr_hwcnt_clear_symbol;
+static kbase_instr_hwcnt_dump_irq_type *kbase_instr_hwcnt_dump_irq_symbol;
+static kbase_instr_hwcnt_dump_complete_type *kbase_instr_hwcnt_dump_complete_symbol;
+static kbase_instr_hwcnt_disable_type *kbase_instr_hwcnt_disable_symbol;
+static kbase_va_free_type *kbase_va_free_symbol;
+static kbase_destroy_context_type *kbase_destroy_context_symbol;
+
+/** The interval between reads, in ns.
+ *
+ * Earlier we introduced
+ * a 'hold off for 1ms after last read' to resolve MIDBASE-2178 and MALINE-724.
+ * However, the 1ms hold off is too long if no context switches occur as there is a race
+ * between this value and the tick of the read clock in gator which is also 1ms. If we 'miss' the
+ * current read, the counter values are effectively 'spread' over 2ms and the values seen are half
+ * what they should be (since Streamline averages over sample time). In the presence of context switches
+ * this spread can vary and markedly affect the counters. Currently there is no 'proper' solution to
+ * this, but empirically we have found that reducing the minimum read interval to 950us causes the
+ * counts to be much more stable.
+ */
+static const int READ_INTERVAL_NSEC = 950000;
#if GATOR_TEST
#include "gator_events_mali_t6xx_hw_test.c"
#endif
/* Blocks for HW counters */
-enum
-{
- JM_BLOCK = 0,
- TILER_BLOCK,
- SHADER_BLOCK,
- MMU_BLOCK
+enum {
+ JM_BLOCK = 0,
+ TILER_BLOCK,
+ SHADER_BLOCK,
+ MMU_BLOCK
};
/* Counters for Mali-T6xx:
@@ -75,271 +84,270 @@ enum
*/
/* Hardware Counters */
-static const char* const hardware_counter_names [] =
-{
- /* Job Manager */
- "",
- "",
- "",
- "",
- "MESSAGES_SENT",
- "MESSAGES_RECEIVED",
- "GPU_ACTIVE", /* 6 */
- "IRQ_ACTIVE",
- "JS0_JOBS",
- "JS0_TASKS",
- "JS0_ACTIVE",
- "",
- "JS0_WAIT_READ",
- "JS0_WAIT_ISSUE",
- "JS0_WAIT_DEPEND",
- "JS0_WAIT_FINISH",
- "JS1_JOBS",
- "JS1_TASKS",
- "JS1_ACTIVE",
- "",
- "JS1_WAIT_READ",
- "JS1_WAIT_ISSUE",
- "JS1_WAIT_DEPEND",
- "JS1_WAIT_FINISH",
- "JS2_JOBS",
- "JS2_TASKS",
- "JS2_ACTIVE",
- "",
- "JS2_WAIT_READ",
- "JS2_WAIT_ISSUE",
- "JS2_WAIT_DEPEND",
- "JS2_WAIT_FINISH",
- "JS3_JOBS",
- "JS3_TASKS",
- "JS3_ACTIVE",
- "",
- "JS3_WAIT_READ",
- "JS3_WAIT_ISSUE",
- "JS3_WAIT_DEPEND",
- "JS3_WAIT_FINISH",
- "JS4_JOBS",
- "JS4_TASKS",
- "JS4_ACTIVE",
- "",
- "JS4_WAIT_READ",
- "JS4_WAIT_ISSUE",
- "JS4_WAIT_DEPEND",
- "JS4_WAIT_FINISH",
- "JS5_JOBS",
- "JS5_TASKS",
- "JS5_ACTIVE",
- "",
- "JS5_WAIT_READ",
- "JS5_WAIT_ISSUE",
- "JS5_WAIT_DEPEND",
- "JS5_WAIT_FINISH",
- "JS6_JOBS",
- "JS6_TASKS",
- "JS6_ACTIVE",
- "",
- "JS6_WAIT_READ",
- "JS6_WAIT_ISSUE",
- "JS6_WAIT_DEPEND",
- "JS6_WAIT_FINISH",
-
- /*Tiler*/
- "",
- "",
- "",
- "JOBS_PROCESSED",
- "TRIANGLES",
- "QUADS",
- "POLYGONS",
- "POINTS",
- "LINES",
- "VCACHE_HIT",
- "VCACHE_MISS",
- "FRONT_FACING",
- "BACK_FACING",
- "PRIM_VISIBLE",
- "PRIM_CULLED",
- "PRIM_CLIPPED",
- "LEVEL0",
- "LEVEL1",
- "LEVEL2",
- "LEVEL3",
- "LEVEL4",
- "LEVEL5",
- "LEVEL6",
- "LEVEL7",
- "COMMAND_1",
- "COMMAND_2",
- "COMMAND_3",
- "COMMAND_4",
- "COMMAND_4_7",
- "COMMAND_8_15",
- "COMMAND_16_63",
- "COMMAND_64",
- "COMPRESS_IN",
- "COMPRESS_OUT",
- "COMPRESS_FLUSH",
- "TIMESTAMPS",
- "PCACHE_HIT",
- "PCACHE_MISS",
- "PCACHE_LINE",
- "PCACHE_STALL",
- "WRBUF_HIT",
- "WRBUF_MISS",
- "WRBUF_LINE",
- "WRBUF_PARTIAL",
- "WRBUF_STALL",
- "ACTIVE",
- "LOADING_DESC",
- "INDEX_WAIT",
- "INDEX_RANGE_WAIT",
- "VERTEX_WAIT",
- "PCACHE_WAIT",
- "WRBUF_WAIT",
- "BUS_READ",
- "BUS_WRITE",
- "",
- "",
- "",
- "",
- "",
- "UTLB_STALL",
- "UTLB_REPLAY_MISS",
- "UTLB_REPLAY_FULL",
- "UTLB_NEW_MISS",
- "UTLB_HIT",
-
- /* Shader Core */
- "",
- "",
- "",
- "SHADER_CORE_ACTIVE",
- "FRAG_ACTIVE",
- "FRAG_PRIMATIVES",
- "FRAG_PRIMATIVES_DROPPED",
- "FRAG_CYCLE_DESC",
- "FRAG_CYCLES_PLR",
- "FRAG_CYCLES_VERT",
- "FRAG_CYCLES_TRISETUP",
- "FRAG_CYCLES_RAST",
- "FRAG_THREADS",
- "FRAG_DUMMY_THREADS",
- "FRAG_QUADS_RAST",
- "FRAG_QUADS_EZS_TEST",
- "FRAG_QUADS_EZS_KILLED",
- "FRAG_QUADS_LZS_TEST",
- "FRAG_QUADS_LZS_KILLED",
- "FRAG_CYCLE_NO_TILE",
- "FRAG_NUM_TILES",
- "FRAG_TRANS_ELIM",
- "COMPUTE_ACTIVE",
- "COMPUTE_TASKS",
- "COMPUTE_THREADS",
- "COMPUTE_CYCLES_DESC",
- "TRIPIPE_ACTIVE",
- "ARITH_WORDS",
- "ARITH_CYCLES_REG",
- "ARITH_CYCLES_L0",
- "ARITH_FRAG_DEPEND",
- "LS_WORDS",
- "LS_ISSUES",
- "LS_RESTARTS",
- "LS_REISSUES_MISS",
- "LS_REISSUES_VD",
- "LS_REISSUE_ATTRIB_MISS",
- "LS_NO_WB",
- "TEX_WORDS",
- "TEX_BUBBLES",
- "TEX_WORDS_L0",
- "TEX_WORDS_DESC",
- "TEX_THREADS",
- "TEX_RECIRC_FMISS",
- "TEX_RECIRC_DESC",
- "TEX_RECIRC_MULTI",
- "TEX_RECIRC_PMISS",
- "TEX_RECIRC_CONF",
- "LSC_READ_HITS",
- "LSC_READ_MISSES",
- "LSC_WRITE_HITS",
- "LSC_WRITE_MISSES",
- "LSC_ATOMIC_HITS",
- "LSC_ATOMIC_MISSES",
- "LSC_LINE_FETCHES",
- "LSC_DIRTY_LINE",
- "LSC_SNOOPS",
- "AXI_TLB_STALL",
- "AXI_TLB_MIESS",
- "AXI_TLB_TRANSACTION",
- "LS_TLB_MISS",
- "LS_TLB_HIT",
- "AXI_BEATS_READ",
- "AXI_BEATS_WRITTEN",
-
- /*L2 and MMU */
- "",
- "",
- "",
- "",
- "MMU_TABLE_WALK",
- "MMU_REPLAY_MISS",
- "MMU_REPLAY_FULL",
- "MMU_NEW_MISS",
- "MMU_HIT",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "UTLB_STALL",
- "UTLB_REPLAY_MISS",
- "UTLB_REPLAY_FULL",
- "UTLB_NEW_MISS",
- "UTLB_HIT",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "L2_WRITE_BEATS",
- "L2_READ_BEATS",
- "L2_ANY_LOOKUP",
- "L2_READ_LOOKUP",
- "L2_SREAD_LOOKUP",
- "L2_READ_REPLAY",
- "L2_READ_SNOOP",
- "L2_READ_HIT",
- "L2_CLEAN_MISS",
- "L2_WRITE_LOOKUP",
- "L2_SWRITE_LOOKUP",
- "L2_WRITE_REPLAY",
- "L2_WRITE_SNOOP",
- "L2_WRITE_HIT",
- "L2_EXT_READ_FULL",
- "L2_EXT_READ_HALF",
- "L2_EXT_WRITE_FULL",
- "L2_EXT_WRITE_HALF",
- "L2_EXT_READ",
- "L2_EXT_READ_LINE",
- "L2_EXT_WRITE",
- "L2_EXT_WRITE_LINE",
- "L2_EXT_WRITE_SMALL",
- "L2_EXT_BARRIER",
- "L2_EXT_AR_STALL",
- "L2_EXT_R_BUF_FULL",
- "L2_EXT_RD_BUF_FULL",
- "L2_EXT_R_RAW",
- "L2_EXT_W_STALL",
- "L2_EXT_W_BUF_FULL",
- "L2_EXT_R_W_HAZARD",
- "L2_TAG_HAZARD",
- "L2_SNOOP_FULL",
- "L2_REPLAY_FULL"
+static const char *const hardware_counter_names[] = {
+ /* Job Manager */
+ "",
+ "",
+ "",
+ "",
+ "MESSAGES_SENT",
+ "MESSAGES_RECEIVED",
+ "GPU_ACTIVE", /* 6 */
+ "IRQ_ACTIVE",
+ "JS0_JOBS",
+ "JS0_TASKS",
+ "JS0_ACTIVE",
+ "",
+ "JS0_WAIT_READ",
+ "JS0_WAIT_ISSUE",
+ "JS0_WAIT_DEPEND",
+ "JS0_WAIT_FINISH",
+ "JS1_JOBS",
+ "JS1_TASKS",
+ "JS1_ACTIVE",
+ "",
+ "JS1_WAIT_READ",
+ "JS1_WAIT_ISSUE",
+ "JS1_WAIT_DEPEND",
+ "JS1_WAIT_FINISH",
+ "JS2_JOBS",
+ "JS2_TASKS",
+ "JS2_ACTIVE",
+ "",
+ "JS2_WAIT_READ",
+ "JS2_WAIT_ISSUE",
+ "JS2_WAIT_DEPEND",
+ "JS2_WAIT_FINISH",
+ "JS3_JOBS",
+ "JS3_TASKS",
+ "JS3_ACTIVE",
+ "",
+ "JS3_WAIT_READ",
+ "JS3_WAIT_ISSUE",
+ "JS3_WAIT_DEPEND",
+ "JS3_WAIT_FINISH",
+ "JS4_JOBS",
+ "JS4_TASKS",
+ "JS4_ACTIVE",
+ "",
+ "JS4_WAIT_READ",
+ "JS4_WAIT_ISSUE",
+ "JS4_WAIT_DEPEND",
+ "JS4_WAIT_FINISH",
+ "JS5_JOBS",
+ "JS5_TASKS",
+ "JS5_ACTIVE",
+ "",
+ "JS5_WAIT_READ",
+ "JS5_WAIT_ISSUE",
+ "JS5_WAIT_DEPEND",
+ "JS5_WAIT_FINISH",
+ "JS6_JOBS",
+ "JS6_TASKS",
+ "JS6_ACTIVE",
+ "",
+ "JS6_WAIT_READ",
+ "JS6_WAIT_ISSUE",
+ "JS6_WAIT_DEPEND",
+ "JS6_WAIT_FINISH",
+
+ /*Tiler */
+ "",
+ "",
+ "",
+ "JOBS_PROCESSED",
+ "TRIANGLES",
+ "QUADS",
+ "POLYGONS",
+ "POINTS",
+ "LINES",
+ "VCACHE_HIT",
+ "VCACHE_MISS",
+ "FRONT_FACING",
+ "BACK_FACING",
+ "PRIM_VISIBLE",
+ "PRIM_CULLED",
+ "PRIM_CLIPPED",
+ "LEVEL0",
+ "LEVEL1",
+ "LEVEL2",
+ "LEVEL3",
+ "LEVEL4",
+ "LEVEL5",
+ "LEVEL6",
+ "LEVEL7",
+ "COMMAND_1",
+ "COMMAND_2",
+ "COMMAND_3",
+ "COMMAND_4",
+ "COMMAND_4_7",
+ "COMMAND_8_15",
+ "COMMAND_16_63",
+ "COMMAND_64",
+ "COMPRESS_IN",
+ "COMPRESS_OUT",
+ "COMPRESS_FLUSH",
+ "TIMESTAMPS",
+ "PCACHE_HIT",
+ "PCACHE_MISS",
+ "PCACHE_LINE",
+ "PCACHE_STALL",
+ "WRBUF_HIT",
+ "WRBUF_MISS",
+ "WRBUF_LINE",
+ "WRBUF_PARTIAL",
+ "WRBUF_STALL",
+ "ACTIVE",
+ "LOADING_DESC",
+ "INDEX_WAIT",
+ "INDEX_RANGE_WAIT",
+ "VERTEX_WAIT",
+ "PCACHE_WAIT",
+ "WRBUF_WAIT",
+ "BUS_READ",
+ "BUS_WRITE",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "UTLB_STALL",
+ "UTLB_REPLAY_MISS",
+ "UTLB_REPLAY_FULL",
+ "UTLB_NEW_MISS",
+ "UTLB_HIT",
+
+ /* Shader Core */
+ "",
+ "",
+ "",
+ "SHADER_CORE_ACTIVE",
+ "FRAG_ACTIVE",
+ "FRAG_PRIMATIVES",
+ "FRAG_PRIMATIVES_DROPPED",
+ "FRAG_CYCLE_DESC",
+ "FRAG_CYCLES_PLR",
+ "FRAG_CYCLES_VERT",
+ "FRAG_CYCLES_TRISETUP",
+ "FRAG_CYCLES_RAST",
+ "FRAG_THREADS",
+ "FRAG_DUMMY_THREADS",
+ "FRAG_QUADS_RAST",
+ "FRAG_QUADS_EZS_TEST",
+ "FRAG_QUADS_EZS_KILLED",
+ "FRAG_QUADS_LZS_TEST",
+ "FRAG_QUADS_LZS_KILLED",
+ "FRAG_CYCLE_NO_TILE",
+ "FRAG_NUM_TILES",
+ "FRAG_TRANS_ELIM",
+ "COMPUTE_ACTIVE",
+ "COMPUTE_TASKS",
+ "COMPUTE_THREADS",
+ "COMPUTE_CYCLES_DESC",
+ "TRIPIPE_ACTIVE",
+ "ARITH_WORDS",
+ "ARITH_CYCLES_REG",
+ "ARITH_CYCLES_L0",
+ "ARITH_FRAG_DEPEND",
+ "LS_WORDS",
+ "LS_ISSUES",
+ "LS_RESTARTS",
+ "LS_REISSUES_MISS",
+ "LS_REISSUES_VD",
+ "LS_REISSUE_ATTRIB_MISS",
+ "LS_NO_WB",
+ "TEX_WORDS",
+ "TEX_BUBBLES",
+ "TEX_WORDS_L0",
+ "TEX_WORDS_DESC",
+ "TEX_THREADS",
+ "TEX_RECIRC_FMISS",
+ "TEX_RECIRC_DESC",
+ "TEX_RECIRC_MULTI",
+ "TEX_RECIRC_PMISS",
+ "TEX_RECIRC_CONF",
+ "LSC_READ_HITS",
+ "LSC_READ_MISSES",
+ "LSC_WRITE_HITS",
+ "LSC_WRITE_MISSES",
+ "LSC_ATOMIC_HITS",
+ "LSC_ATOMIC_MISSES",
+ "LSC_LINE_FETCHES",
+ "LSC_DIRTY_LINE",
+ "LSC_SNOOPS",
+ "AXI_TLB_STALL",
+ "AXI_TLB_MIESS",
+ "AXI_TLB_TRANSACTION",
+ "LS_TLB_MISS",
+ "LS_TLB_HIT",
+ "AXI_BEATS_READ",
+ "AXI_BEATS_WRITTEN",
+
+ /*L2 and MMU */
+ "",
+ "",
+ "",
+ "",
+ "MMU_TABLE_WALK",
+ "MMU_REPLAY_MISS",
+ "MMU_REPLAY_FULL",
+ "MMU_NEW_MISS",
+ "MMU_HIT",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "UTLB_STALL",
+ "UTLB_REPLAY_MISS",
+ "UTLB_REPLAY_FULL",
+ "UTLB_NEW_MISS",
+ "UTLB_HIT",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "L2_WRITE_BEATS",
+ "L2_READ_BEATS",
+ "L2_ANY_LOOKUP",
+ "L2_READ_LOOKUP",
+ "L2_SREAD_LOOKUP",
+ "L2_READ_REPLAY",
+ "L2_READ_SNOOP",
+ "L2_READ_HIT",
+ "L2_CLEAN_MISS",
+ "L2_WRITE_LOOKUP",
+ "L2_SWRITE_LOOKUP",
+ "L2_WRITE_REPLAY",
+ "L2_WRITE_SNOOP",
+ "L2_WRITE_HIT",
+ "L2_EXT_READ_FULL",
+ "L2_EXT_READ_HALF",
+ "L2_EXT_WRITE_FULL",
+ "L2_EXT_WRITE_HALF",
+ "L2_EXT_READ",
+ "L2_EXT_READ_LINE",
+ "L2_EXT_WRITE",
+ "L2_EXT_WRITE_LINE",
+ "L2_EXT_WRITE_SMALL",
+ "L2_EXT_BARRIER",
+ "L2_EXT_AR_STALL",
+ "L2_EXT_R_BUF_FULL",
+ "L2_EXT_RD_BUF_FULL",
+ "L2_EXT_R_RAW",
+ "L2_EXT_W_STALL",
+ "L2_EXT_W_BUF_FULL",
+ "L2_EXT_R_W_HAZARD",
+ "L2_TAG_HAZARD",
+ "L2_SNOOP_FULL",
+ "L2_REPLAY_FULL"
};
#define NUMBER_OF_HARDWARE_COUNTERS (sizeof(hardware_counter_names) / sizeof(hardware_counter_names[0]))
@@ -402,19 +410,19 @@ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2];
*/
static int init_symbols(void)
{
- int error_count = 0;
- SYMBOL_GET(kbase_find_device, error_count);
- SYMBOL_GET(kbase_create_context, error_count);
- SYMBOL_GET(kbase_va_alloc, error_count);
- SYMBOL_GET(kbase_instr_hwcnt_enable, error_count);
- SYMBOL_GET(kbase_instr_hwcnt_clear, error_count);
- SYMBOL_GET(kbase_instr_hwcnt_dump_irq, error_count);
- SYMBOL_GET(kbase_instr_hwcnt_dump_complete, error_count);
- SYMBOL_GET(kbase_instr_hwcnt_disable, error_count);
- SYMBOL_GET(kbase_va_free, error_count);
- SYMBOL_GET(kbase_destroy_context, error_count);
-
- return error_count;
+ int error_count = 0;
+ SYMBOL_GET(kbase_find_device, error_count);
+ SYMBOL_GET(kbase_create_context, error_count);
+ SYMBOL_GET(kbase_va_alloc, error_count);
+ SYMBOL_GET(kbase_instr_hwcnt_enable, error_count);
+ SYMBOL_GET(kbase_instr_hwcnt_clear, error_count);
+ SYMBOL_GET(kbase_instr_hwcnt_dump_irq, error_count);
+ SYMBOL_GET(kbase_instr_hwcnt_dump_complete, error_count);
+ SYMBOL_GET(kbase_instr_hwcnt_disable, error_count);
+ SYMBOL_GET(kbase_va_free, error_count);
+ SYMBOL_GET(kbase_destroy_context, error_count);
+
+ return error_count;
}
/**
@@ -422,16 +430,16 @@ static int init_symbols(void)
*/
static void clean_symbols(void)
{
- SYMBOL_CLEANUP(kbase_find_device);
- SYMBOL_CLEANUP(kbase_create_context);
- SYMBOL_CLEANUP(kbase_va_alloc);
- SYMBOL_CLEANUP(kbase_instr_hwcnt_enable);
- SYMBOL_CLEANUP(kbase_instr_hwcnt_clear);
- SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_irq);
- SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_complete);
- SYMBOL_CLEANUP(kbase_instr_hwcnt_disable);
- SYMBOL_CLEANUP(kbase_va_free);
- SYMBOL_CLEANUP(kbase_destroy_context);
+ SYMBOL_CLEANUP(kbase_find_device);
+ SYMBOL_CLEANUP(kbase_create_context);
+ SYMBOL_CLEANUP(kbase_va_alloc);
+ SYMBOL_CLEANUP(kbase_instr_hwcnt_enable);
+ SYMBOL_CLEANUP(kbase_instr_hwcnt_clear);
+ SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_irq);
+ SYMBOL_CLEANUP(kbase_instr_hwcnt_dump_complete);
+ SYMBOL_CLEANUP(kbase_instr_hwcnt_disable);
+ SYMBOL_CLEANUP(kbase_va_free);
+ SYMBOL_CLEANUP(kbase_destroy_context);
}
/**
@@ -442,17 +450,15 @@ static void clean_symbols(void)
*
* Note that this function has been separated out here to allow it to be tested.
*/
-static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns)
+static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time_s, s32 *next_read_time_ns)
{
/* If the current ns count rolls over a second, roll the next read time too. */
- if(current_time->tv_sec != *prev_time_s)
- {
+ if (current_time->tv_sec != *prev_time_s) {
*next_read_time_ns = *next_read_time_ns - NSEC_PER_SEC;
}
/* Abort the read if the next read time has not arrived. */
- if(current_time->tv_nsec < *next_read_time_ns)
- {
+ if (current_time->tv_nsec < *next_read_time_ns) {
return 0;
}
@@ -465,154 +471,146 @@ static int is_read_scheduled(const struct timespec *current_time, u32* prev_time
static int start(void)
{
- kbase_uk_hwcnt_setup setup;
- mali_error err;
- int cnt;
- u16 bitmask[] = {0, 0, 0, 0};
-
- /* Setup HW counters */
- num_hardware_counters_enabled = 0;
-
- if(NUMBER_OF_HARDWARE_COUNTERS != 256)
- {
- pr_debug("Unexpected number of hardware counters defined: expecting 256, got %d\n", NUMBER_OF_HARDWARE_COUNTERS);
- }
-
- /* Calculate enable bitmasks based on counters_enabled array */
- for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- int block = GET_HW_BLOCK(cnt);
- int enable_bit = GET_COUNTER_OFFSET(cnt) / 4;
- bitmask[block] |= (1 << enable_bit);
- pr_debug("gator: Mali-T6xx: hardware counter %s selected [%d]\n", hardware_counter_names[cnt], cnt);
- num_hardware_counters_enabled++;
- }
- }
-
- /* Create a kbase context for HW counters */
- if (num_hardware_counters_enabled > 0)
- {
- if(init_symbols() > 0)
- {
- clean_symbols();
- /* No Mali driver code entrypoints found - not a fault. */
- return 0;
- }
-
- kbdevice = kbase_find_device_symbol(-1);
-
- /* If we already got a context, fail */
- if (kbcontext) {
- pr_debug("gator: Mali-T6xx: error context already present\n");
- goto out;
- }
-
- /* kbcontext will only be valid after all the Mali symbols are loaded successfully */
- kbcontext = kbase_create_context_symbol(kbdevice);
- if (!kbcontext)
- {
- pr_debug("gator: Mali-T6xx: error creating kbase context\n");
- goto out;
- }
-
- /*
- * The amount of memory needed to store the dump (bytes)
- * DUMP_SIZE = number of core groups
- * * number of blocks (always 8 for midgard)
- * * number of counters per block (always 64 for midgard)
- * * number of bytes per counter (always 4 in midgard)
- * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4
- */
- kernel_dump_buffer = kbase_va_alloc_symbol(kbcontext, 2048);
- if (!kernel_dump_buffer)
- {
- pr_debug("gator: Mali-T6xx: error trying to allocate va\n");
- goto destroy_context;
- }
-
- setup.dump_buffer = (uintptr_t)kernel_dump_buffer;
- setup.jm_bm = bitmask[JM_BLOCK];
- setup.tiler_bm = bitmask[TILER_BLOCK];
- setup.shader_bm = bitmask[SHADER_BLOCK];
- setup.mmu_l2_bm = bitmask[MMU_BLOCK];
- /* These counters do not exist on Mali-T60x */
- setup.l3_cache_bm = 0;
-
- /* Use kbase API to enable hardware counters and provide dump buffer */
- err = kbase_instr_hwcnt_enable_symbol(kbcontext, &setup);
- if (err != MALI_ERROR_NONE)
- {
- pr_debug("gator: Mali-T6xx: can't setup hardware counters\n");
- goto free_buffer;
- }
- pr_debug("gator: Mali-T6xx: hardware counters enabled\n");
- kbase_instr_hwcnt_clear_symbol(kbcontext);
- pr_debug("gator: Mali-T6xx: hardware counters cleared \n");
-
- kbase_device_busy = false;
- }
-
- return 0;
-
- free_buffer:
- kbase_va_free_symbol(kbcontext, kernel_dump_buffer);
-
- destroy_context:
- kbase_destroy_context_symbol(kbcontext);
-
- out:
- clean_symbols();
- return -1;
+ kbase_uk_hwcnt_setup setup;
+ mali_error err;
+ int cnt;
+ u16 bitmask[] = { 0, 0, 0, 0 };
+
+ /* Setup HW counters */
+ num_hardware_counters_enabled = 0;
+
+ if (NUMBER_OF_HARDWARE_COUNTERS != 256) {
+ pr_debug("Unexpected number of hardware counters defined: expecting 256, got %d\n", NUMBER_OF_HARDWARE_COUNTERS);
+ }
+
+ /* Calculate enable bitmasks based on counters_enabled array */
+ for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ int block = GET_HW_BLOCK(cnt);
+ int enable_bit = GET_COUNTER_OFFSET(cnt) / 4;
+ bitmask[block] |= (1 << enable_bit);
+ pr_debug("gator: Mali-T6xx: hardware counter %s selected [%d]\n", hardware_counter_names[cnt], cnt);
+ num_hardware_counters_enabled++;
+ }
+ }
+
+ /* Create a kbase context for HW counters */
+ if (num_hardware_counters_enabled > 0) {
+ if (init_symbols() > 0) {
+ clean_symbols();
+ /* No Mali driver code entrypoints found - not a fault. */
+ return 0;
+ }
+
+ kbdevice = kbase_find_device_symbol(-1);
+
+ /* If we already got a context, fail */
+ if (kbcontext) {
+ pr_debug("gator: Mali-T6xx: error context already present\n");
+ goto out;
+ }
+
+ /* kbcontext will only be valid after all the Mali symbols are loaded successfully */
+ kbcontext = kbase_create_context_symbol(kbdevice);
+ if (!kbcontext) {
+ pr_debug("gator: Mali-T6xx: error creating kbase context\n");
+ goto out;
+ }
+
+ /*
+ * The amount of memory needed to store the dump (bytes)
+ * DUMP_SIZE = number of core groups
+ * * number of blocks (always 8 for midgard)
+ * * number of counters per block (always 64 for midgard)
+ * * number of bytes per counter (always 4 in midgard)
+ * For a Mali-T6xx with a single core group = 1 * 8 * 64 * 4
+ */
+ kernel_dump_buffer = kbase_va_alloc_symbol(kbcontext, 2048);
+ if (!kernel_dump_buffer) {
+ pr_debug("gator: Mali-T6xx: error trying to allocate va\n");
+ goto destroy_context;
+ }
+
+ setup.dump_buffer = (uintptr_t)kernel_dump_buffer;
+ setup.jm_bm = bitmask[JM_BLOCK];
+ setup.tiler_bm = bitmask[TILER_BLOCK];
+ setup.shader_bm = bitmask[SHADER_BLOCK];
+ setup.mmu_l2_bm = bitmask[MMU_BLOCK];
+ /* These counters do not exist on Mali-T60x */
+ setup.l3_cache_bm = 0;
+
+ /* Use kbase API to enable hardware counters and provide dump buffer */
+ err = kbase_instr_hwcnt_enable_symbol(kbcontext, &setup);
+ if (err != MALI_ERROR_NONE) {
+ pr_debug("gator: Mali-T6xx: can't setup hardware counters\n");
+ goto free_buffer;
+ }
+ pr_debug("gator: Mali-T6xx: hardware counters enabled\n");
+ kbase_instr_hwcnt_clear_symbol(kbcontext);
+ pr_debug("gator: Mali-T6xx: hardware counters cleared \n");
+
+ kbase_device_busy = false;
+ }
+
+ return 0;
+
+free_buffer:
+ kbase_va_free_symbol(kbcontext, kernel_dump_buffer);
+
+destroy_context:
+ kbase_destroy_context_symbol(kbcontext);
+
+out:
+ clean_symbols();
+ return -1;
}
-static void stop(void) {
- unsigned int cnt;
- kbase_context *temp_kbcontext;
+static void stop(void)
+{
+ unsigned int cnt;
+ kbase_context *temp_kbcontext;
- pr_debug("gator: Mali-T6xx: stop\n");
+ pr_debug("gator: Mali-T6xx: stop\n");
- /* Set all counters as disabled */
- for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
- counters[cnt].enabled = 0;
- }
+ /* Set all counters as disabled */
+ for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
+ counters[cnt].enabled = 0;
+ }
- /* Destroy the context for HW counters */
- if (num_hardware_counters_enabled > 0 && kbcontext != NULL)
- {
- /*
- * Set the global variable to NULL before destroying it, because
- * other function will check this before using it.
- */
- temp_kbcontext = kbcontext;
- kbcontext = NULL;
+ /* Destroy the context for HW counters */
+ if (num_hardware_counters_enabled > 0 && kbcontext != NULL) {
+ /*
+ * Set the global variable to NULL before destroying it, because
+ * other function will check this before using it.
+ */
+ temp_kbcontext = kbcontext;
+ kbcontext = NULL;
- kbase_instr_hwcnt_disable_symbol(temp_kbcontext);
- kbase_va_free_symbol(temp_kbcontext, kernel_dump_buffer);
- kbase_destroy_context_symbol(temp_kbcontext);
+ kbase_instr_hwcnt_disable_symbol(temp_kbcontext);
+ kbase_va_free_symbol(temp_kbcontext, kernel_dump_buffer);
+ kbase_destroy_context_symbol(temp_kbcontext);
- pr_debug("gator: Mali-T6xx: hardware counters stopped\n");
+ pr_debug("gator: Mali-T6xx: hardware counters stopped\n");
- clean_symbols();
- }
+ clean_symbols();
+ }
}
-static int read(int **buffer) {
- int cnt;
- int len = 0;
- u32 value = 0;
- mali_bool success;
+static int read(int **buffer)
+{
+ int cnt;
+ int len = 0;
+ u32 value = 0;
+ mali_bool success;
struct timespec current_time;
static u32 prev_time_s = 0;
static s32 next_read_time_ns = 0;
- if (smp_processor_id()!=0)
- {
- return 0;
- }
+ if (smp_processor_id() != 0) {
+ return 0;
+ }
getnstimeofday(&current_time);
@@ -620,114 +618,105 @@ static int read(int **buffer) {
* Discard reads unless a respectable time has passed. This reduces the load on the GPU without sacrificing
* accuracy on the Streamline display.
*/
- if(!is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns))
- {
+ if (!is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns)) {
return 0;
}
- /*
- * Report the HW counters
- * Only process hardware counters if at least one of the hardware counters is enabled.
- */
- if (num_hardware_counters_enabled > 0)
- {
- const unsigned int vithar_blocks[] = {
- 0x700, /* VITHAR_JOB_MANAGER, Block 0 */
- 0x400, /* VITHAR_TILER, Block 1 */
- 0x000, /* VITHAR_SHADER_CORE, Block 2 */
- 0x500 /* VITHAR_MEMORY_SYSTEM, Block 3 */
- };
-
- if (!kbcontext)
- {
- return -1;
- }
-
- /* Mali symbols can be called safely since a kbcontext is valid */
- if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE)
- {
- kbase_device_busy = false;
-
- if (success == MALI_TRUE)
- {
- for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++)
- {
- const mali_counter *counter = &counters[cnt];
- if (counter->enabled)
- {
- const int block = GET_HW_BLOCK(cnt);
- const int counter_offset = GET_COUNTER_OFFSET(cnt);
- const u32 *counter_block = (u32 *)((uintptr_t)kernel_dump_buffer + vithar_blocks[block]);
- const u32 *counter_address = counter_block + counter_offset;
-
- value = *counter_address;
-
- if(block == SHADER_BLOCK){
- /* (counter_address + 0x000) has already been accounted-for above. */
- value += *(counter_address + 0x100);
- value += *(counter_address + 0x200);
- value += *(counter_address + 0x300);
- }
-
- counter_dump[len++] = counter->key;
- counter_dump[len++] = value;
- }
- }
- }
- }
-
- if (! kbase_device_busy)
- {
- kbase_device_busy = true;
- kbase_instr_hwcnt_dump_irq_symbol(kbcontext);
- }
- }
-
- /* Update the buffer */
- if (buffer) {
- *buffer = (int*) counter_dump;
- }
-
- return len;
+ /*
+ * Report the HW counters
+ * Only process hardware counters if at least one of the hardware counters is enabled.
+ */
+ if (num_hardware_counters_enabled > 0) {
+ const unsigned int vithar_blocks[] = {
+ 0x700, /* VITHAR_JOB_MANAGER, Block 0 */
+ 0x400, /* VITHAR_TILER, Block 1 */
+ 0x000, /* VITHAR_SHADER_CORE, Block 2 */
+ 0x500 /* VITHAR_MEMORY_SYSTEM, Block 3 */
+ };
+
+ if (!kbcontext) {
+ return -1;
+ }
+
+ /* Mali symbols can be called safely since a kbcontext is valid */
+ if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE) {
+ kbase_device_busy = false;
+
+ if (success == MALI_TRUE) {
+ for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) {
+ const mali_counter *counter = &counters[cnt];
+ if (counter->enabled) {
+ const int block = GET_HW_BLOCK(cnt);
+ const int counter_offset = GET_COUNTER_OFFSET(cnt);
+ const u32 *counter_block = (u32 *) ((uintptr_t)kernel_dump_buffer + vithar_blocks[block]);
+ const u32 *counter_address = counter_block + counter_offset;
+
+ value = *counter_address;
+
+ if (block == SHADER_BLOCK) {
+ /* (counter_address + 0x000) has already been accounted-for above. */
+ value += *(counter_address + 0x100);
+ value += *(counter_address + 0x200);
+ value += *(counter_address + 0x300);
+ }
+
+ counter_dump[len++] = counter->key;
+ counter_dump[len++] = value;
+ }
+ }
+ }
+ }
+
+ if (!kbase_device_busy) {
+ kbase_device_busy = true;
+ kbase_instr_hwcnt_dump_irq_symbol(kbcontext);
+ }
+ }
+
+ /* Update the buffer */
+ if (buffer) {
+ *buffer = (int *)counter_dump;
+ }
+
+ return len;
}
static int create_files(struct super_block *sb, struct dentry *root)
{
- unsigned int event;
- /*
- * Create the filesystem for all events
- */
- int counter_index = 0;
- const char* mali_name = gator_mali_get_mali_name();
-
- for (event = 0; event < NUMBER_OF_HARDWARE_COUNTERS; event++)
- {
- if (gator_mali_create_file_system(mali_name, hardware_counter_names[counter_index], sb, root, &counters[event]) != 0)
- return -1;
- counter_index++;
- }
-
- return 0;
+ unsigned int event;
+ /*
+ * Create the filesystem for all events
+ */
+ int counter_index = 0;
+ const char *mali_name = gator_mali_get_mali_name();
+
+ for (event = 0; event < NUMBER_OF_HARDWARE_COUNTERS; event++) {
+ if (gator_mali_create_file_system(mali_name, hardware_counter_names[counter_index], sb, root, &counters[event]) != 0)
+ return -1;
+ counter_index++;
+ }
+
+ return 0;
}
static struct gator_interface gator_events_mali_t6xx_interface = {
- .create_files = create_files,
- .start = start,
- .stop = stop,
- .read = read
+ .create_files = create_files,
+ .start = start,
+ .stop = stop,
+ .read = read
};
int gator_events_mali_t6xx_hw_init(void)
{
- pr_debug("gator: Mali-T6xx: sw_counters init\n");
+ pr_debug("gator: Mali-T6xx: sw_counters init\n");
#if GATOR_TEST
- test_all_is_read_scheduled();
+ test_all_is_read_scheduled();
#endif
- gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS);
+ gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS);
- return gator_events_install(&gator_events_mali_t6xx_interface);
+ return gator_events_install(&gator_events_mali_t6xx_interface);
}
gator_events_init(gator_events_mali_t6xx_hw_init);
diff --git a/driver/gator_events_mali_t6xx_hw_test.c b/driver/gator_events_mali_t6xx_hw_test.c
index 61ec336..eb77110 100644
--- a/driver/gator_events_mali_t6xx_hw_test.c
+++ b/driver/gator_events_mali_t6xx_hw_test.c
@@ -11,7 +11,7 @@
* Test functions for mali_t600_hw code.
*/
-static int is_read_scheduled(const struct timespec *current_time, u32* prev_time_s, s32* next_read_time_ns);
+static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time_s, s32 *next_read_time_ns);
static int test_is_read_scheduled(u32 s, u32 ns, u32 prev_s, s32 next_ns, int expected_result, s32 expected_next_ns)
{
@@ -22,14 +22,12 @@ static int test_is_read_scheduled(u32 s, u32 ns, u32 prev_s, s32 next_ns, int ex
current_time.tv_sec = s;
current_time.tv_nsec = ns;
- if(is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns) != expected_result)
- {
+ if (is_read_scheduled(&current_time, &prev_time_s, &next_read_time_ns) != expected_result) {
printk("Failed do_read(%u, %u, %u, %d): expected %d\n", s, ns, prev_s, next_ns, expected_result);
return 0;
}
- if(next_read_time_ns != expected_next_ns)
- {
+ if (next_read_time_ns != expected_next_ns) {
printk("Failed: next_read_ns expected=%d, actual=%d\n", expected_next_ns, next_read_time_ns);
return 0;
}
@@ -42,16 +40,16 @@ static void test_all_is_read_scheduled(void)
const int HIGHEST_NS = 999999999;
int n_tests_passed = 0;
- printk("gator: running tests on %s\n", __FILE__);
+ printk("gator: running tests on %s\n", __FILE__);
- n_tests_passed += test_is_read_scheduled(0,0,0,0, 1, READ_INTERVAL_NSEC); /* Null time */
- n_tests_passed += test_is_read_scheduled(100,1000,0,0, 1, READ_INTERVAL_NSEC + 1000); /* Initial values */
+ n_tests_passed += test_is_read_scheduled(0, 0, 0, 0, 1, READ_INTERVAL_NSEC); /* Null time */
+ n_tests_passed += test_is_read_scheduled(100, 1000, 0, 0, 1, READ_INTERVAL_NSEC + 1000); /* Initial values */
- n_tests_passed += test_is_read_scheduled(100, HIGHEST_NS, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500);
- n_tests_passed += test_is_read_scheduled(101, 0001, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500 - NSEC_PER_SEC);
- n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500 - NSEC_PER_SEC, 1, 600 + READ_INTERVAL_NSEC);
+ n_tests_passed += test_is_read_scheduled(100, HIGHEST_NS, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500);
+ n_tests_passed += test_is_read_scheduled(101, 0001, 100, HIGHEST_NS + 500, 0, HIGHEST_NS + 500 - NSEC_PER_SEC);
+ n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500 - NSEC_PER_SEC, 1, 600 + READ_INTERVAL_NSEC);
- n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500, 1, 600 + READ_INTERVAL_NSEC);
+ n_tests_passed += test_is_read_scheduled(101, 600, 100, HIGHEST_NS + 500, 1, 600 + READ_INTERVAL_NSEC);
printk("gator: %d tests passed\n", n_tests_passed);
}
diff --git a/driver/gator_events_meminfo.c b/driver/gator_events_meminfo.c
index b962641..fd063b2 100644
--- a/driver/gator_events_meminfo.c
+++ b/driver/gator_events_meminfo.c
@@ -31,22 +31,25 @@ static struct timer_list meminfo_wake_up_timer;
static void meminfo_wake_up_handler(unsigned long unused_data);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
-GATOR_DEFINE_PROBE(mm_page_free_direct, TP_PROTO(struct page *page, unsigned int order)) {
+GATOR_DEFINE_PROBE(mm_page_free_direct, TP_PROTO(struct page *page, unsigned int order))
#else
-GATOR_DEFINE_PROBE(mm_page_free, TP_PROTO(struct page *page, unsigned int order)) {
+GATOR_DEFINE_PROBE(mm_page_free, TP_PROTO(struct page *page, unsigned int order))
#endif
+{
mem_event++;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
-GATOR_DEFINE_PROBE(mm_pagevec_free, TP_PROTO(struct page *page, int cold)) {
+GATOR_DEFINE_PROBE(mm_pagevec_free, TP_PROTO(struct page *page, int cold))
#else
-GATOR_DEFINE_PROBE(mm_page_free_batched, TP_PROTO(struct page *page, int cold)) {
+GATOR_DEFINE_PROBE(mm_page_free_batched, TP_PROTO(struct page *page, int cold))
#endif
+{
mem_event++;
}
-GATOR_DEFINE_PROBE(mm_page_alloc, TP_PROTO(struct page *page, unsigned int order, gfp_t gfp_flags, int migratetype)) {
+GATOR_DEFINE_PROBE(mm_page_alloc, TP_PROTO(struct page *page, unsigned int order, gfp_t gfp_flags, int migratetype))
+{
mem_event++;
}
@@ -233,4 +236,5 @@ int gator_events_meminfo_init(void)
return gator_events_install(&gator_events_meminfo_interface);
}
+
gator_events_init(gator_events_meminfo_init);
diff --git a/driver/gator_events_mmaped.c b/driver/gator_events_mmaped.c
index 1be6e66..c4cb44f 100644
--- a/driver/gator_events_mmaped.c
+++ b/driver/gator_events_mmaped.c
@@ -45,7 +45,7 @@ static s64 prev_time;
/* Adds mmaped_cntX directories and enabled, event, and key files to /dev/gator/events */
static int gator_events_mmaped_create_files(struct super_block *sb,
- struct dentry *root)
+ struct dentry *root)
{
int i;
@@ -58,11 +58,11 @@ static int gator_events_mmaped_create_files(struct super_block *sb,
if (WARN_ON(!dir))
return -1;
gatorfs_create_ulong(sb, dir, "enabled",
- &mmaped_counters[i].enabled);
+ &mmaped_counters[i].enabled);
gatorfs_create_ulong(sb, dir, "event",
- &mmaped_counters[i].event);
+ &mmaped_counters[i].event);
gatorfs_create_ro_ulong(sb, dir, "key",
- &mmaped_counters[i].key);
+ &mmaped_counters[i].key);
}
return 0;
@@ -73,7 +73,7 @@ static int gator_events_mmaped_start(void)
#ifdef TODO
for (i = 0; i < MMAPED_COUNTERS_NUM; i++)
writel(mmaped_counters[i].event,
- mmaped_base + COUNTERS_CONFIG_OFFSET[i]);
+ mmaped_base + COUNTERS_CONFIG_OFFSET[i]);
writel(ENABLED, COUNTERS_CONTROL_OFFSET);
#endif
@@ -102,7 +102,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
int result = 0;
switch (counter) {
- case 0: /* sort-of-sine */
+ case 0: /* sort-of-sine */
{
static int t = 0;
int x;
@@ -123,7 +123,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
result = 1922 - result;
}
break;
- case 1: /* triangle */
+ case 1: /* triangle */
{
static int v, d = 1;
@@ -139,7 +139,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
result = v;
}
break;
- case 2: /* PWM signal */
+ case 2: /* PWM signal */
{
static int t, dc, x;
@@ -149,7 +149,7 @@ static int mmaped_simulate(int counter, int delta_in_us)
if (x / 1000000 != (x + delta_in_us) / 1000000)
dc = (dc + 100000) % 1000000;
x += delta_in_us;
-
+
result = t < dc ? 0 : 10;
}
break;
@@ -173,7 +173,7 @@ static int gator_events_mmaped_read(int **buffer)
if (smp_processor_id())
return 0;
-#ifndef TODO
+#ifndef TODO
getnstimeofday(&ts);
time = timespec_to_ns(&ts);
delta_in_us = (int)(time - prev_time) / 1000;
@@ -184,15 +184,16 @@ static int gator_events_mmaped_read(int **buffer)
if (mmaped_counters[i].enabled) {
mmaped_buffer[len++] = mmaped_counters[i].key;
#ifdef TODO
- mmaped_buffer[len++] = readl(mmaped_base +
- COUNTERS_VALUE_OFFSET[i]);
+ mmaped_buffer[len++] =
+ readl(mmaped_base + COUNTERS_VALUE_OFFSET[i]);
#else
- mmaped_buffer[len++] = mmaped_simulate(
- mmaped_counters[i].event, delta_in_us);
+ mmaped_buffer[len++] =
+ mmaped_simulate(mmaped_counters[i].event,
+ delta_in_us);
#endif
}
}
-
+
if (buffer)
*buffer = mmaped_buffer;
@@ -214,7 +215,7 @@ int __init gator_events_mmaped_init(void)
#ifdef TODO
mmaped_base = ioremap(COUNTERS_PHYS_ADDR, SZ_4K);
if (!mmaped_base)
- return -ENOMEM;
+ return -ENOMEM;
#endif
for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
@@ -224,4 +225,5 @@ int __init gator_events_mmaped_init(void)
return gator_events_install(&gator_events_mmaped_interface);
}
+
gator_events_init(gator_events_mmaped_init);
diff --git a/driver/gator_events_net.c b/driver/gator_events_net.c
index 31cc3ef..b6ce06a 100644
--- a/driver/gator_events_net.c
+++ b/driver/gator_events_net.c
@@ -26,7 +26,8 @@ static int netGet[TOTALNET * 4];
static struct timer_list net_wake_up_timer;
// Must be run in process context as the kernel function dev_get_stats() can sleep
-static void get_network_stats(struct work_struct *wsptr) {
+static void get_network_stats(struct work_struct *wsptr)
+{
int rx = 0, tx = 0;
struct net_device *dev;
@@ -43,6 +44,7 @@ static void get_network_stats(struct work_struct *wsptr) {
rx_total = rx;
tx_total = tx;
}
+
DECLARE_WORK(wq_get_stats, get_network_stats);
static void net_wake_up_handler(unsigned long unused_data)
@@ -129,7 +131,7 @@ static int gator_events_net_read(int **buffer)
if (netrx_enabled && last_rx_delta != rx_delta) {
last_rx_delta = rx_delta;
netGet[len++] = netrx_key;
- netGet[len++] = 0; // indicates to Streamline that rx_delta bytes were transmitted now, not since the last message
+ netGet[len++] = 0; // indicates to Streamline that rx_delta bytes were transmitted now, not since the last message
netGet[len++] = netrx_key;
netGet[len++] = rx_delta;
}
@@ -137,7 +139,7 @@ static int gator_events_net_read(int **buffer)
if (nettx_enabled && last_tx_delta != tx_delta) {
last_tx_delta = tx_delta;
netGet[len++] = nettx_key;
- netGet[len++] = 0; // indicates to Streamline that tx_delta bytes were transmitted now, not since the last message
+ netGet[len++] = 0; // indicates to Streamline that tx_delta bytes were transmitted now, not since the last message
netGet[len++] = nettx_key;
netGet[len++] = tx_delta;
}
@@ -165,4 +167,5 @@ int gator_events_net_init(void)
return gator_events_install(&gator_events_net_interface);
}
+
gator_events_init(gator_events_net_init);
diff --git a/driver/gator_events_perf_pmu.c b/driver/gator_events_perf_pmu.c
index e025155..ce3a40f 100644
--- a/driver/gator_events_perf_pmu.c
+++ b/driver/gator_events_perf_pmu.c
@@ -45,7 +45,7 @@ static int gator_events_perf_pmu_create_files(struct super_block *sb, struct den
if (i == 0) {
snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name);
} else {
- snprintf(buf, sizeof buf, "%s_cnt%d", pmnc_name, i-1);
+ snprintf(buf, sizeof buf, "%s_cnt%d", pmnc_name, i - 1);
}
dir = gatorfs_mkdir(sb, root, buf);
if (!dir) {
@@ -80,13 +80,13 @@ static void dummy_handler(struct perf_event *event, struct perf_sample_data *dat
// Required as perf_event_create_kernel_counter() requires an overflow handler, even though all we do is poll
}
-static int gator_events_perf_pmu_online(int** buffer)
+static int gator_events_perf_pmu_online(int **buffer)
{
int cnt, len = 0, cpu = smp_processor_id();
// read the counters and toss the invalid data, return zero instead
for (cnt = 0; cnt < pmnc_counters; cnt++) {
- struct perf_event * ev = per_cpu(pevent, cpu)[cnt];
+ struct perf_event *ev = per_cpu(pevent, cpu)[cnt];
if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
ev->pmu->read(ev);
per_cpu(perfPrev, cpu)[cnt] = per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count);
@@ -140,7 +140,7 @@ static void gator_events_perf_pmu_online_dispatch(int cpu)
static void gator_events_perf_pmu_offline_dispatch(int cpu)
{
int cnt;
- struct perf_event * pe;
+ struct perf_event *pe;
for (cnt = 0; cnt < pmnc_counters; cnt++) {
pe = NULL;
@@ -177,7 +177,7 @@ static int gator_events_perf_pmu_start(void)
for_each_present_cpu(cpu) {
for (cnt = 0; cnt < pmnc_counters; cnt++) {
per_cpu(pevent, cpu)[cnt] = NULL;
- if (!pmnc_enabled[cnt]) // Skip disabled counters
+ if (!pmnc_enabled[cnt]) // Skip disabled counters
continue;
per_cpu(perfPrev, cpu)[cnt] = 0;
@@ -233,7 +233,7 @@ static int gator_events_perf_pmu_read(int **buffer)
int cpu = smp_processor_id();
for (cnt = 0; cnt < pmnc_counters; cnt++) {
- struct perf_event * ev = per_cpu(pevent, cpu)[cnt];
+ struct perf_event *ev = per_cpu(pevent, cpu)[cnt];
if (ev != NULL && ev->state == PERF_EVENT_STATE_ACTIVE) {
ev->pmu->read(ev);
per_cpu(perfCurr, cpu)[cnt] = local64_read(&ev->count);
@@ -268,62 +268,21 @@ static struct gator_interface gator_events_perf_pmu_interface = {
int gator_events_perf_pmu_init(void)
{
unsigned int cnt;
-
- switch (gator_cpuid()) {
- case ARM1136:
- case ARM1156:
- case ARM1176:
- pmnc_name = "ARM_ARM11";
- pmnc_counters = 3;
- ccnt = 2;
- break;
- case ARM11MPCORE:
- pmnc_name = "ARM_ARM11MPCore";
- pmnc_counters = 3;
- break;
- case CORTEX_A5:
- pmnc_name = "ARM_Cortex-A5";
- pmnc_counters = 2;
- break;
- case CORTEX_A7:
- pmnc_name = "ARM_Cortex-A7";
- pmnc_counters = 4;
- break;
- case CORTEX_A8:
- pmnc_name = "ARM_Cortex-A8";
- pmnc_counters = 4;
- break;
- case CORTEX_A9:
- pmnc_name = "ARM_Cortex-A9";
- pmnc_counters = 6;
- break;
- case CORTEX_A15:
- pmnc_name = "ARM_Cortex-A15";
- pmnc_counters = 6;
- break;
- case SCORPION:
- pmnc_name = "Scorpion";
- pmnc_counters = 4;
- break;
- case SCORPIONMP:
- pmnc_name = "ScorpionMP";
- pmnc_counters = 4;
- break;
- case KRAITSIM:
- case KRAIT:
- pmnc_name = "Krait";
- pmnc_counters = 4;
- break;
- case AARCH64:
- pmnc_name = "ARM_AArch64";
- // Copied from A15, get the correct number
- pmnc_counters = 6;
- break;
- default:
+ const u32 cpuid = gator_cpuid();
+
+ for (cnt = 0; gator_cpus[cnt].cpuid != 0; ++cnt) {
+ if (gator_cpus[cnt].cpuid == cpuid) {
+ pmnc_name = gator_cpus[cnt].pmnc_name;
+ pmnc_counters = gator_cpus[cnt].pmnc_counters;
+ ccnt = gator_cpus[cnt].ccnt;
+ break;
+ }
+ }
+ if (gator_cpus[cnt].cpuid == 0) {
return -1;
}
- pmnc_counters++; // CNT[n] + CCNT
+ pmnc_counters++; // CNT[n] + CCNT
for (cnt = 0; cnt < CNTMAX; cnt++) {
pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_events_sched.c b/driver/gator_events_sched.c
index 9bed364..ba6744d 100644
--- a/driver/gator_events_sched.c
+++ b/driver/gator_events_sched.c
@@ -111,4 +111,5 @@ int gator_events_sched_init(void)
return gator_events_install(&gator_events_sched_interface);
}
+
gator_events_init(gator_events_sched_init);
diff --git a/driver/gator_events_scorpion.c b/driver/gator_events_scorpion.c
index ed0d8de..5ffc63a 100644
--- a/driver/gator_events_scorpion.c
+++ b/driver/gator_events_scorpion.c
@@ -20,8 +20,8 @@ static int pmnc_counters;
#define PMNC_C (1 << 2) /* Cycle counter reset */
#define PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
#define PMNC_X (1 << 4) /* Export to ETM */
-#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
-#define PMNC_MASK 0x3f /* Mask for writable bits */
+#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug */
+#define PMNC_MASK 0x3f /* Mask for writable bits */
// ccnt reg
#define CCNT_REG (1 << 31)
@@ -37,95 +37,95 @@ static unsigned long pmnc_key[CNTMAX];
static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt);
enum scorpion_perf_types {
- SCORPION_ICACHE_EXPL_INV = 0x4c,
- SCORPION_ICACHE_MISS = 0x4d,
- SCORPION_ICACHE_ACCESS = 0x4e,
- SCORPION_ICACHE_CACHEREQ_L2 = 0x4f,
- SCORPION_ICACHE_NOCACHE_L2 = 0x50,
- SCORPION_HIQUP_NOPED = 0x51,
- SCORPION_DATA_ABORT = 0x52,
- SCORPION_IRQ = 0x53,
- SCORPION_FIQ = 0x54,
- SCORPION_ALL_EXCPT = 0x55,
- SCORPION_UNDEF = 0x56,
- SCORPION_SVC = 0x57,
- SCORPION_SMC = 0x58,
- SCORPION_PREFETCH_ABORT = 0x59,
- SCORPION_INDEX_CHECK = 0x5a,
- SCORPION_NULL_CHECK = 0x5b,
- SCORPION_EXPL_ICIALLU = 0x5c,
- SCORPION_IMPL_ICIALLU = 0x5d,
- SCORPION_NONICIALLU_BTAC_INV = 0x5e,
- SCORPION_ICIMVAU_IMPL_ICIALLU = 0x5f,
- SCORPION_SPIPE_ONLY_CYCLES = 0x60,
- SCORPION_XPIPE_ONLY_CYCLES = 0x61,
- SCORPION_DUAL_CYCLES = 0x62,
- SCORPION_DISPATCH_ANY_CYCLES = 0x63,
- SCORPION_FIFO_FULLBLK_CMT = 0x64,
- SCORPION_FAIL_COND_INST = 0x65,
- SCORPION_PASS_COND_INST = 0x66,
- SCORPION_ALLOW_VU_CLK = 0x67,
- SCORPION_VU_IDLE = 0x68,
- SCORPION_ALLOW_L2_CLK = 0x69,
- SCORPION_L2_IDLE = 0x6a,
- SCORPION_DTLB_IMPL_INV_SCTLR_DACR = 0x6b,
- SCORPION_DTLB_EXPL_INV = 0x6c,
- SCORPION_DTLB_MISS = 0x6d,
- SCORPION_DTLB_ACCESS = 0x6e,
- SCORPION_ITLB_MISS = 0x6f,
- SCORPION_ITLB_IMPL_INV = 0x70,
- SCORPION_ITLB_EXPL_INV = 0x71,
- SCORPION_UTLB_D_MISS = 0x72,
- SCORPION_UTLB_D_ACCESS = 0x73,
- SCORPION_UTLB_I_MISS = 0x74,
- SCORPION_UTLB_I_ACCESS = 0x75,
- SCORPION_UTLB_INV_ASID = 0x76,
- SCORPION_UTLB_INV_MVA = 0x77,
- SCORPION_UTLB_INV_ALL = 0x78,
- SCORPION_S2_HOLD_RDQ_UNAVAIL = 0x79,
- SCORPION_S2_HOLD = 0x7a,
- SCORPION_S2_HOLD_DEV_OP = 0x7b,
- SCORPION_S2_HOLD_ORDER = 0x7c,
- SCORPION_S2_HOLD_BARRIER = 0x7d,
- SCORPION_VIU_DUAL_CYCLE = 0x7e,
- SCORPION_VIU_SINGLE_CYCLE = 0x7f,
- SCORPION_VX_PIPE_WAR_STALL_CYCLES = 0x80,
- SCORPION_VX_PIPE_WAW_STALL_CYCLES = 0x81,
- SCORPION_VX_PIPE_RAW_STALL_CYCLES = 0x82,
- SCORPION_VX_PIPE_LOAD_USE_STALL = 0x83,
- SCORPION_VS_PIPE_WAR_STALL_CYCLES = 0x84,
- SCORPION_VS_PIPE_WAW_STALL_CYCLES = 0x85,
- SCORPION_VS_PIPE_RAW_STALL_CYCLES = 0x86,
- SCORPION_EXCEPTIONS_INV_OPERATION = 0x87,
- SCORPION_EXCEPTIONS_DIV_BY_ZERO = 0x88,
- SCORPION_COND_INST_FAIL_VX_PIPE = 0x89,
- SCORPION_COND_INST_FAIL_VS_PIPE = 0x8a,
- SCORPION_EXCEPTIONS_OVERFLOW = 0x8b,
- SCORPION_EXCEPTIONS_UNDERFLOW = 0x8c,
- SCORPION_EXCEPTIONS_DENORM = 0x8d,
+ SCORPION_ICACHE_EXPL_INV = 0x4c,
+ SCORPION_ICACHE_MISS = 0x4d,
+ SCORPION_ICACHE_ACCESS = 0x4e,
+ SCORPION_ICACHE_CACHEREQ_L2 = 0x4f,
+ SCORPION_ICACHE_NOCACHE_L2 = 0x50,
+ SCORPION_HIQUP_NOPED = 0x51,
+ SCORPION_DATA_ABORT = 0x52,
+ SCORPION_IRQ = 0x53,
+ SCORPION_FIQ = 0x54,
+ SCORPION_ALL_EXCPT = 0x55,
+ SCORPION_UNDEF = 0x56,
+ SCORPION_SVC = 0x57,
+ SCORPION_SMC = 0x58,
+ SCORPION_PREFETCH_ABORT = 0x59,
+ SCORPION_INDEX_CHECK = 0x5a,
+ SCORPION_NULL_CHECK = 0x5b,
+ SCORPION_EXPL_ICIALLU = 0x5c,
+ SCORPION_IMPL_ICIALLU = 0x5d,
+ SCORPION_NONICIALLU_BTAC_INV = 0x5e,
+ SCORPION_ICIMVAU_IMPL_ICIALLU = 0x5f,
+ SCORPION_SPIPE_ONLY_CYCLES = 0x60,
+ SCORPION_XPIPE_ONLY_CYCLES = 0x61,
+ SCORPION_DUAL_CYCLES = 0x62,
+ SCORPION_DISPATCH_ANY_CYCLES = 0x63,
+ SCORPION_FIFO_FULLBLK_CMT = 0x64,
+ SCORPION_FAIL_COND_INST = 0x65,
+ SCORPION_PASS_COND_INST = 0x66,
+ SCORPION_ALLOW_VU_CLK = 0x67,
+ SCORPION_VU_IDLE = 0x68,
+ SCORPION_ALLOW_L2_CLK = 0x69,
+ SCORPION_L2_IDLE = 0x6a,
+ SCORPION_DTLB_IMPL_INV_SCTLR_DACR = 0x6b,
+ SCORPION_DTLB_EXPL_INV = 0x6c,
+ SCORPION_DTLB_MISS = 0x6d,
+ SCORPION_DTLB_ACCESS = 0x6e,
+ SCORPION_ITLB_MISS = 0x6f,
+ SCORPION_ITLB_IMPL_INV = 0x70,
+ SCORPION_ITLB_EXPL_INV = 0x71,
+ SCORPION_UTLB_D_MISS = 0x72,
+ SCORPION_UTLB_D_ACCESS = 0x73,
+ SCORPION_UTLB_I_MISS = 0x74,
+ SCORPION_UTLB_I_ACCESS = 0x75,
+ SCORPION_UTLB_INV_ASID = 0x76,
+ SCORPION_UTLB_INV_MVA = 0x77,
+ SCORPION_UTLB_INV_ALL = 0x78,
+ SCORPION_S2_HOLD_RDQ_UNAVAIL = 0x79,
+ SCORPION_S2_HOLD = 0x7a,
+ SCORPION_S2_HOLD_DEV_OP = 0x7b,
+ SCORPION_S2_HOLD_ORDER = 0x7c,
+ SCORPION_S2_HOLD_BARRIER = 0x7d,
+ SCORPION_VIU_DUAL_CYCLE = 0x7e,
+ SCORPION_VIU_SINGLE_CYCLE = 0x7f,
+ SCORPION_VX_PIPE_WAR_STALL_CYCLES = 0x80,
+ SCORPION_VX_PIPE_WAW_STALL_CYCLES = 0x81,
+ SCORPION_VX_PIPE_RAW_STALL_CYCLES = 0x82,
+ SCORPION_VX_PIPE_LOAD_USE_STALL = 0x83,
+ SCORPION_VS_PIPE_WAR_STALL_CYCLES = 0x84,
+ SCORPION_VS_PIPE_WAW_STALL_CYCLES = 0x85,
+ SCORPION_VS_PIPE_RAW_STALL_CYCLES = 0x86,
+ SCORPION_EXCEPTIONS_INV_OPERATION = 0x87,
+ SCORPION_EXCEPTIONS_DIV_BY_ZERO = 0x88,
+ SCORPION_COND_INST_FAIL_VX_PIPE = 0x89,
+ SCORPION_COND_INST_FAIL_VS_PIPE = 0x8a,
+ SCORPION_EXCEPTIONS_OVERFLOW = 0x8b,
+ SCORPION_EXCEPTIONS_UNDERFLOW = 0x8c,
+ SCORPION_EXCEPTIONS_DENORM = 0x8d,
#ifdef CONFIG_ARCH_MSM_SCORPIONMP
- SCORPIONMP_NUM_BARRIERS = 0x8e,
- SCORPIONMP_BARRIER_CYCLES = 0x8f,
+ SCORPIONMP_NUM_BARRIERS = 0x8e,
+ SCORPIONMP_BARRIER_CYCLES = 0x8f,
#else
- SCORPION_BANK_AB_HIT = 0x8e,
- SCORPION_BANK_AB_ACCESS = 0x8f,
- SCORPION_BANK_CD_HIT = 0x90,
- SCORPION_BANK_CD_ACCESS = 0x91,
- SCORPION_BANK_AB_DSIDE_HIT = 0x92,
- SCORPION_BANK_AB_DSIDE_ACCESS = 0x93,
- SCORPION_BANK_CD_DSIDE_HIT = 0x94,
- SCORPION_BANK_CD_DSIDE_ACCESS = 0x95,
- SCORPION_BANK_AB_ISIDE_HIT = 0x96,
- SCORPION_BANK_AB_ISIDE_ACCESS = 0x97,
- SCORPION_BANK_CD_ISIDE_HIT = 0x98,
- SCORPION_BANK_CD_ISIDE_ACCESS = 0x99,
- SCORPION_ISIDE_RD_WAIT = 0x9a,
- SCORPION_DSIDE_RD_WAIT = 0x9b,
- SCORPION_BANK_BYPASS_WRITE = 0x9c,
- SCORPION_BANK_AB_NON_CASTOUT = 0x9d,
- SCORPION_BANK_AB_L2_CASTOUT = 0x9e,
- SCORPION_BANK_CD_NON_CASTOUT = 0x9f,
- SCORPION_BANK_CD_L2_CASTOUT = 0xa0,
+ SCORPION_BANK_AB_HIT = 0x8e,
+ SCORPION_BANK_AB_ACCESS = 0x8f,
+ SCORPION_BANK_CD_HIT = 0x90,
+ SCORPION_BANK_CD_ACCESS = 0x91,
+ SCORPION_BANK_AB_DSIDE_HIT = 0x92,
+ SCORPION_BANK_AB_DSIDE_ACCESS = 0x93,
+ SCORPION_BANK_CD_DSIDE_HIT = 0x94,
+ SCORPION_BANK_CD_DSIDE_ACCESS = 0x95,
+ SCORPION_BANK_AB_ISIDE_HIT = 0x96,
+ SCORPION_BANK_AB_ISIDE_ACCESS = 0x97,
+ SCORPION_BANK_CD_ISIDE_HIT = 0x98,
+ SCORPION_BANK_CD_ISIDE_ACCESS = 0x99,
+ SCORPION_ISIDE_RD_WAIT = 0x9a,
+ SCORPION_DSIDE_RD_WAIT = 0x9b,
+ SCORPION_BANK_BYPASS_WRITE = 0x9c,
+ SCORPION_BANK_AB_NON_CASTOUT = 0x9d,
+ SCORPION_BANK_AB_L2_CASTOUT = 0x9e,
+ SCORPION_BANK_CD_NON_CASTOUT = 0x9f,
+ SCORPION_BANK_CD_L2_CASTOUT = 0xa0,
#endif
MSM_MAX_EVT
};
@@ -209,8 +209,8 @@ static const struct scorp_evt sc_evt[] = {
{SCORPION_EXCEPTIONS_DENORM, 0x8c000000, 4, 0x5f},
#ifdef CONFIG_ARCH_MSM_SCORPIONMP
- {SCORPIONMP_NUM_BARRIERS, 0x80000e00, 3, 0x59},
- {SCORPIONMP_BARRIER_CYCLES, 0x800e0000, 3, 0x5a},
+ {SCORPIONMP_NUM_BARRIERS, 0x80000e00, 3, 0x59},
+ {SCORPIONMP_BARRIER_CYCLES, 0x800e0000, 3, 0x5a},
#else
{SCORPION_BANK_AB_HIT, 0x80000001, 3, 0x58},
{SCORPION_BANK_AB_ACCESS, 0x80000100, 3, 0x59},
@@ -375,8 +375,8 @@ static void scorpion_write_vlpm(u32 val)
}
struct scorpion_access_funcs {
- u32 (*read) (void);
- void (*write) (u32);
+ u32(*read)(void);
+ void (*write)(u32);
};
struct scorpion_access_funcs scor_func[] = {
@@ -395,7 +395,7 @@ static void scorpion_pre_vlpm(void)
u32 venum_new_val;
u32 fp_new_val;
- /* CPACR Enable CP10 access*/
+ /* CPACR Enable CP10 access */
asm volatile("mrc p15, 0, %0, c1, c0, 2" : "=r" (venum_orig_val));
venum_new_val = venum_orig_val | 0x00300000;
asm volatile("mcr p15, 0, %0, c1, c0, 2" : : "r" (venum_new_val));
@@ -407,9 +407,9 @@ static void scorpion_pre_vlpm(void)
static void scorpion_post_vlpm(void)
{
- /* Restore FPEXC*/
+ /* Restore FPEXC */
asm volatile("mcr p10, 7, %0, c8, c0, 0" : : "r" (fp_orig_val));
- /* Restore CPACR*/
+ /* Restore CPACR */
asm volatile("mcr p15, 0, %0, c1, c0, 2" : : "r" (venum_orig_val));
}
@@ -464,7 +464,8 @@ static inline void scorpion_pmnc_write_evtsel(unsigned int cnt, u32 val)
u32 zero = 0;
struct scorp_evt evtinfo;
// extract evtinfo.grp and evtinfo.tevt_type_act from val
- if (get_scorpion_evtinfo(val, &evtinfo) == 0) return;
+ if (get_scorpion_evtinfo(val, &evtinfo) == 0)
+ return;
asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (evtinfo.evt_type_act));
asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (zero));
scorpion_evt_setup(evtinfo.grp, val);
@@ -482,7 +483,7 @@ static void scorpion_pmnc_reset_counter(unsigned int cnt)
asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val));
if (pmnc_enabled[cnt] != 0)
- scorpion_pmnc_enable_counter(cnt);
+ scorpion_pmnc_enable_counter(cnt);
} else if (cnt >= CNTMAX) {
pr_err("gator: CPU%u resetting wrong PMNC counter %d\n", smp_processor_id(), cnt);
@@ -490,10 +491,10 @@ static void scorpion_pmnc_reset_counter(unsigned int cnt)
scorpion_pmnc_disable_counter(cnt);
if (scorpion_pmnc_select_counter(cnt) == cnt)
- asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
+ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
if (pmnc_enabled[cnt] != 0)
- scorpion_pmnc_enable_counter(cnt);
+ scorpion_pmnc_enable_counter(cnt);
}
}
@@ -507,14 +508,14 @@ static int gator_events_scorpion_create_files(struct super_block *sb, struct den
if (i == 0) {
snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name);
} else {
- snprintf(buf, sizeof buf, "%s_cnt%d", pmnc_name, i-1);
+ snprintf(buf, sizeof buf, "%s_cnt%d", pmnc_name, i - 1);
}
dir = gatorfs_mkdir(sb, root, buf);
if (!dir) {
return -1;
}
gatorfs_create_ulong(sb, dir, "enabled", &pmnc_enabled[i]);
- gatorfs_create_ro_ulong(sb, dir, "key", &pmnc_key[i]);
+ gatorfs_create_ro_ulong(sb, dir, "key", &pmnc_key[i]);
if (i > 0) {
gatorfs_create_ulong(sb, dir, "event", &pmnc_event[i]);
}
@@ -523,7 +524,7 @@ static int gator_events_scorpion_create_files(struct super_block *sb, struct den
return 0;
}
-static int gator_events_scorpion_online(int** buffer)
+static int gator_events_scorpion_online(int **buffer)
{
unsigned int cnt, len = 0, cpu = smp_processor_id();
@@ -562,13 +563,10 @@ static int gator_events_scorpion_online(int** buffer)
// read the counters and toss the invalid data, return zero instead
for (cnt = 0; cnt < pmnc_counters; cnt++) {
if (pmnc_enabled[cnt]) {
- int value;
if (cnt == CCNT) {
- value = scorpion_ccnt_read();
+ scorpion_ccnt_read();
} else if (scorpion_pmnc_select_counter(cnt) == cnt) {
- value = scorpion_cntn_read();
- } else {
- value = 0;
+ scorpion_cntn_read();
}
scorpion_pmnc_reset_counter(cnt);
@@ -583,7 +581,7 @@ static int gator_events_scorpion_online(int** buffer)
return len;
}
-static int gator_events_scorpion_offline(int** buffer)
+static int gator_events_scorpion_offline(int **buffer)
{
scorpion_pmnc_write(scorpion_pmnc_read() & ~PMNC_E);
return 0;
@@ -657,7 +655,7 @@ int gator_events_scorpion_init(void)
return -1;
}
- pmnc_counters++; // CNT[n] + CCNT
+ pmnc_counters++; // CNT[n] + CCNT
for (cnt = CCNT; cnt < CNTMAX; cnt++) {
pmnc_enabled[cnt] = 0;
diff --git a/driver/gator_fs.c b/driver/gator_fs.c
index 81b0d5b..9ff118b 100644
--- a/driver/gator_fs.c
+++ b/driver/gator_fs.c
@@ -35,8 +35,8 @@ static struct inode *gatorfs_get_inode(struct super_block *sb, int mode)
}
static const struct super_operations s_ops = {
- .statfs = simple_statfs,
- .drop_inode = generic_delete_inode,
+ .statfs = simple_statfs,
+ .drop_inode = generic_delete_inode,
};
ssize_t gatorfs_str_to_user(char const *str, char __user *buf, size_t count, loff_t *offset)
@@ -104,19 +104,21 @@ static int default_open(struct inode *inode, struct file *filp)
}
static const struct file_operations ulong_fops = {
- .read = ulong_read_file,
- .write = ulong_write_file,
- .open = default_open,
+ .read = ulong_read_file,
+ .write = ulong_write_file,
+ .open = default_open,
};
static const struct file_operations ulong_ro_fops = {
- .read = ulong_read_file,
- .open = default_open,
+ .read = ulong_read_file,
+ .open = default_open,
};
static struct dentry *__gatorfs_create_file(struct super_block *sb,
- struct dentry *root, char const *name, const struct file_operations *fops,
- int perm)
+ struct dentry *root,
+ char const *name,
+ const struct file_operations *fops,
+ int perm)
{
struct dentry *dentry;
struct inode *inode;
@@ -135,10 +137,10 @@ static struct dentry *__gatorfs_create_file(struct super_block *sb,
}
int gatorfs_create_ulong(struct super_block *sb, struct dentry *root,
- char const *name, unsigned long *val)
+ char const *name, unsigned long *val)
{
struct dentry *d = __gatorfs_create_file(sb, root, name,
- &ulong_fops, 0644);
+ &ulong_fops, 0644);
if (!d)
return -EFAULT;
@@ -147,10 +149,10 @@ int gatorfs_create_ulong(struct super_block *sb, struct dentry *root,
}
int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root,
- char const *name, unsigned long *val)
+ char const *name, unsigned long *val)
{
struct dentry *d = __gatorfs_create_file(sb, root, name,
- &ulong_ro_fops, 0444);
+ &ulong_ro_fops, 0444);
if (!d)
return -EFAULT;
@@ -165,15 +167,15 @@ static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t coun
}
static const struct file_operations atomic_ro_fops = {
- .read = atomic_read_file,
- .open = default_open,
+ .read = atomic_read_file,
+ .open = default_open,
};
int gatorfs_create_ro_atomic(struct super_block *sb, struct dentry *root,
- char const *name, atomic_t *val)
+ char const *name, atomic_t *val)
{
struct dentry *d = __gatorfs_create_file(sb, root, name,
- &atomic_ro_fops, 0444);
+ &atomic_ro_fops, 0444);
if (!d)
return -EFAULT;
@@ -182,7 +184,7 @@ int gatorfs_create_ro_atomic(struct super_block *sb, struct dentry *root,
}
int gatorfs_create_file(struct super_block *sb, struct dentry *root,
- char const *name, const struct file_operations *fops)
+ char const *name, const struct file_operations *fops)
{
if (!__gatorfs_create_file(sb, root, name, fops, 0644))
return -EFAULT;
@@ -190,7 +192,8 @@ int gatorfs_create_file(struct super_block *sb, struct dentry *root,
}
int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
- char const *name, const struct file_operations *fops, int perm)
+ char const *name,
+ const struct file_operations *fops, int perm)
{
if (!__gatorfs_create_file(sb, root, name, fops, perm))
return -EFAULT;
@@ -198,7 +201,7 @@ int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
}
struct dentry *gatorfs_mkdir(struct super_block *sb,
- struct dentry *root, char const *name)
+ struct dentry *root, char const *name)
{
struct dentry *dentry;
struct inode *inode;
@@ -256,28 +259,29 @@ static int gatorfs_fill_super(struct super_block *sb, void *data, int silent)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
static int gatorfs_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+ int flags, const char *dev_name, void *data,
+ struct vfsmount *mnt)
{
return get_sb_single(fs_type, flags, data, gatorfs_fill_super, mnt);
}
#else
static struct dentry *gatorfs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+ int flags, const char *dev_name, void *data)
{
return mount_nodev(fs_type, flags, data, gatorfs_fill_super);
}
#endif
static struct file_system_type gatorfs_type = {
- .owner = THIS_MODULE,
- .name = "gatorfs",
+ .owner = THIS_MODULE,
+ .name = "gatorfs",
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
- .get_sb = gatorfs_get_sb,
+ .get_sb = gatorfs_get_sb,
#else
- .mount = gatorfs_mount,
+ .mount = gatorfs_mount,
#endif
- .kill_sb = kill_litter_super,
+ .kill_sb = kill_litter_super,
};
int __init gatorfs_register(void)
diff --git a/driver/gator_main.c b/driver/gator_main.c
index 309c6c2..9e031c1 100644
--- a/driver/gator_main.c
+++ b/driver/gator_main.c
@@ -7,7 +7,7 @@
*
*/
-static unsigned long gator_protocol_version = 11;
+static unsigned long gator_protocol_version = 12;
#include <linux/slab.h>
#include <linux/cpu.h>
@@ -60,12 +60,12 @@ static unsigned long gator_protocol_version = 11;
#define SUMMARY_BUFFER_SIZE (1*1024)
#define BACKTRACE_BUFFER_SIZE (128*1024)
#define NAME_BUFFER_SIZE (64*1024)
-#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
+#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
#define BLOCK_COUNTER_BUFFER_SIZE (128*1024)
-#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
+#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
#define SCHED_TRACE_BUFFER_SIZE (128*1024)
-#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
-#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
+#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
+#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
#define NO_COOKIE 0U
#define INVALID_COOKIE ~0U
@@ -94,7 +94,6 @@ static unsigned long gator_protocol_version = 11;
#define MAXSIZE_PACK32 5
#define MAXSIZE_PACK64 10
-#define MAXSIZE_CORE_NAME 32
#if defined(__arm__)
#define PC_REG regs->ARM_pc
@@ -121,6 +120,7 @@ enum {
* Globals
******************************************************************************/
static unsigned long gator_cpu_cores;
+// Size of the largest buffer. Effectively constant, set in gator_op_create_files
static unsigned long userspace_buffer_size;
static unsigned long gator_backtrace_depth;
@@ -148,15 +148,23 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len);
static void gator_buffer_write_string(int cpu, int buftype, const char *x);
static void gator_add_trace(int cpu, unsigned long address);
-static void gator_add_sample(int cpu, struct pt_regs * const regs);
+static void gator_add_sample(int cpu, struct pt_regs *const regs);
static uint64_t gator_get_time(void);
+// Size of the buffer, must be a power of 2. Effectively constant, set in gator_op_setup.
static uint32_t gator_buffer_size[NUM_GATOR_BUFS];
+// gator_buffer_size - 1, bitwise and with pos to get offset into the array. Effectively constant, set in gator_op_setup.
static uint32_t gator_buffer_mask[NUM_GATOR_BUFS];
+// Read position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are read by userspace in userspace_buffer_read
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_read);
+// Write position in the buffer. Initialized to zero in gator_op_setup and incremented after bytes are written to the buffer
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_write);
+// Commit position in the buffer. Initialized to zero in gator_op_setup and incremented after a frame is ready to be read by userspace
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], gator_buffer_commit);
+// If set to false, decreases the number of bytes returned by buffer_bytes_available. Set in buffer_check_space if no space is remaining. Initialized to true in gator_op_setup
+// This means that if we run out of space, continue to report that no space is available until bytes are read by userspace
static DEFINE_PER_CPU(int[NUM_GATOR_BUFS], buffer_space_available);
+// The buffer. Allocated in gator_op_setup
static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer);
/******************************************************************************
@@ -177,9 +185,125 @@ static DEFINE_PER_CPU(char *[NUM_GATOR_BUFS], gator_buffer);
/******************************************************************************
* Misc
******************************************************************************/
-#if defined(__arm__) || defined(__aarch64__)
+
+struct gator_cpu gator_cpus[] = {
+ {
+ .cpuid = ARM1136,
+ .core_name = "ARM1136",
+ .pmnc_name = "ARM_ARM11",
+ .pmnc_counters = 3,
+ .ccnt = 2,
+ },
+ {
+ .cpuid = ARM1156,
+ .core_name = "ARM1156",
+ .pmnc_name = "ARM_ARM11",
+ .pmnc_counters = 3,
+ .ccnt = 2,
+ },
+ {
+ .cpuid = ARM1176,
+ .core_name = "ARM1176",
+ .pmnc_name = "ARM_ARM11",
+ .pmnc_counters = 3,
+ .ccnt = 2,
+ },
+ {
+ .cpuid = ARM11MPCORE,
+ .core_name = "ARM11MPCore",
+ .pmnc_name = "ARM_ARM11MPCore",
+ .pmnc_counters = 3,
+ },
+ {
+ .cpuid = CORTEX_A5,
+ .core_name = "Cortex-A5",
+ .pmnc_name = "ARM_Cortex-A5",
+ .pmnc_counters = 2,
+ },
+ {
+ .cpuid = CORTEX_A7,
+ .core_name = "Cortex-A7",
+ .pmnc_name = "ARM_Cortex-A7",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = CORTEX_A8,
+ .core_name = "Cortex-A8",
+ .pmnc_name = "ARM_Cortex-A8",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = CORTEX_A9,
+ .core_name = "Cortex-A9",
+ .pmnc_name = "ARM_Cortex-A9",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = CORTEX_A15,
+ .core_name = "Cortex-A15",
+ .pmnc_name = "ARM_Cortex-A15",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = SCORPION,
+ .core_name = "Scorpion",
+ .pmnc_name = "Scorpion",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = SCORPIONMP,
+ .core_name = "ScorpionMP",
+ .pmnc_name = "ScorpionMP",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = KRAITSIM,
+ .core_name = "KraitSIM",
+ .pmnc_name = "Krait",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = KRAIT,
+ .core_name = "Krait",
+ .pmnc_name = "Krait",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = KRAIT_S4_PRO,
+ .core_name = "Krait S4 Pro",
+ .pmnc_name = "Krait",
+ .pmnc_counters = 4,
+ },
+ {
+ .cpuid = CORTEX_A53,
+ .core_name = "Cortex-A53",
+ .pmnc_name = "ARM_Cortex-A53",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = CORTEX_A57,
+ .core_name = "Cortex-A57",
+ .pmnc_name = "ARM_Cortex-A57",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = AARCH64,
+ .core_name = "AArch64",
+ .pmnc_name = "ARM_AArch64",
+ .pmnc_counters = 6,
+ },
+ {
+ .cpuid = OTHER,
+ .core_name = "Other",
+ .pmnc_name = "Other",
+ .pmnc_counters = 6,
+ },
+ {}
+};
+
u32 gator_cpuid(void)
{
+#if defined(__arm__) || defined(__aarch64__)
u32 val;
#if !defined(__aarch64__)
asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (val));
@@ -187,8 +311,10 @@ u32 gator_cpuid(void)
asm volatile("mrs %0, midr_el1" : "=r" (val));
#endif
return (val >> 4) & 0xfff;
-}
+#else
+ return OTHER;
#endif
+}
static void gator_buffer_wake_up(unsigned long data)
{
@@ -198,7 +324,7 @@ static void gator_buffer_wake_up(unsigned long data)
/******************************************************************************
* Commit interface
******************************************************************************/
-static bool buffer_commit_ready(int* cpu, int* buftype)
+static bool buffer_commit_ready(int *cpu, int *buftype)
{
int cpu_x, x;
for_each_present_cpu(cpu_x) {
@@ -265,7 +391,7 @@ static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int le
int i;
u32 write = per_cpu(gator_buffer_write, cpu)[buftype];
u32 mask = gator_buffer_mask[buftype];
- char* buffer = per_cpu(gator_buffer, cpu)[buftype];
+ char *buffer = per_cpu(gator_buffer, cpu)[buftype];
for (i = 0; i < len; i++) {
buffer[write] = x[i];
@@ -282,55 +408,27 @@ static void gator_buffer_write_string(int cpu, int buftype, const char *x)
gator_buffer_write_bytes(cpu, buftype, x, len);
}
-static void gator_buffer_header(int cpu, int buftype)
-{
- int frame;
-
- switch (buftype) {
- case SUMMARY_BUF:
- frame = FRAME_SUMMARY;
- break;
- case BACKTRACE_BUF:
- frame = FRAME_BACKTRACE;
- break;
- case NAME_BUF:
- frame = FRAME_NAME;
- break;
- case COUNTER_BUF:
- frame = FRAME_COUNTER;
- break;
- case BLOCK_COUNTER_BUF:
- frame = FRAME_BLOCK_COUNTER;
- break;
- case ANNOTATE_BUF:
- frame = FRAME_ANNOTATE;
- break;
- case SCHED_TRACE_BUF:
- frame = FRAME_SCHED_TRACE;
- break;
- case GPU_TRACE_BUF:
- frame = FRAME_GPU_TRACE;
- break;
- case IDLE_BUF:
- frame = FRAME_IDLE;
- break;
- default:
- frame = -1;
- break;
- }
-
- if (per_cpu(gator_buffer, cpu)[buftype]) {
- marshal_frame(cpu, buftype, frame);
- }
-}
-
static void gator_commit_buffer(int cpu, int buftype)
{
+ int type_length, commit, length, byte;
+
if (!per_cpu(gator_buffer, cpu)[buftype])
return;
+ // post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload
+ type_length = gator_response_type ? 1 : 0;
+ commit = per_cpu(gator_buffer_commit, cpu)[buftype];
+ length = per_cpu(gator_buffer_write, cpu)[buftype] - commit;
+ if (length < 0) {
+ length += gator_buffer_size[buftype];
+ }
+ length = length - type_length - sizeof(int);
+ for (byte = 0; byte < sizeof(int); byte++) {
+ per_cpu(gator_buffer, cpu)[buftype][(commit + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF;
+ }
+
per_cpu(gator_buffer_commit, cpu)[buftype] = per_cpu(gator_buffer_write, cpu)[buftype];
- gator_buffer_header(cpu, buftype);
+ marshal_frame(cpu, buftype);
// had to delay scheduling work as attempting to schedule work during the context switch is illegal in kernel versions 3.5 and greater
mod_timer(&gator_buffer_wake_up_timer, jiffies + 1);
@@ -359,7 +457,7 @@ static void gator_add_trace(int cpu, unsigned long address)
marshal_backtrace(offset & ~1, cookie);
}
-static void gator_add_sample(int cpu, struct pt_regs * const regs)
+static void gator_add_sample(int cpu, struct pt_regs *const regs)
{
bool inKernel;
unsigned long exec_cookie;
@@ -392,11 +490,11 @@ static void gator_add_sample(int cpu, struct pt_regs * const regs)
******************************************************************************/
static void gator_timer_interrupt(void)
{
- struct pt_regs * const regs = get_irq_regs();
+ struct pt_regs *const regs = get_irq_regs();
gator_backtrace_handler(regs);
}
-void gator_backtrace_handler(struct pt_regs * const regs)
+void gator_backtrace_handler(struct pt_regs *const regs)
{
int cpu = smp_processor_id();
@@ -412,11 +510,11 @@ void gator_backtrace_handler(struct pt_regs * const regs)
static int gator_running;
// This function runs in interrupt context and on the appropriate core
-static void gator_timer_offline(void* unused)
+static void gator_timer_offline(void *unused)
{
struct gator_interface *gi;
int i, len, cpu = smp_processor_id();
- int* buffer;
+ int *buffer;
gator_trace_sched_offline();
gator_trace_power_offline();
@@ -444,8 +542,8 @@ static void gator_timer_offline_dispatch(int cpu)
struct gator_interface *gi;
list_for_each_entry(gi, &gator_events, list)
- if (gi->offline_dispatch)
- gi->offline_dispatch(cpu);
+ if (gi->offline_dispatch)
+ gi->offline_dispatch(cpu);
}
static void gator_timer_stop(void)
@@ -464,11 +562,11 @@ static void gator_timer_stop(void)
}
// This function runs in interrupt context and on the appropriate core
-static void gator_timer_online(void* unused)
+static void gator_timer_online(void *unused)
{
struct gator_interface *gi;
int len, cpu = smp_processor_id();
- int* buffer;
+ int *buffer;
gator_trace_power_online();
@@ -485,25 +583,15 @@ static void gator_timer_online(void* unused)
gator_hrtimer_online(cpu);
#if defined(__arm__) || defined(__aarch64__)
{
- const char * core_name = NULL;
-
- // String lengths must be less than MAXSIZE_CORE_NAME
- switch (gator_cpuid()) {
- case ARM1136: core_name = "ARM1136"; break;
- case ARM1156: core_name = "ARM1156"; break;
- case ARM1176: core_name = "ARM1176"; break;
- case ARM11MPCORE: core_name = "ARM11MPCore"; break;
- case CORTEX_A5: core_name = "Cortex-A5"; break;
- case CORTEX_A7: core_name = "Cortex-A7"; break;
- case CORTEX_A8: core_name = "Cortex-A8"; break;
- case CORTEX_A9: core_name = "Cortex-A9"; break;
- case CORTEX_A15: core_name = "Cortex-A15"; break;
- case SCORPION: core_name = "Scorpion"; break;
- case SCORPIONMP: core_name = "ScorpionMP"; break;
- case KRAITSIM: core_name = "KraitSIM"; break;
- case KRAIT: core_name = "Krait"; break;
- case AARCH64: core_name = "AArch64"; break;
- default: core_name = "Unknown"; break;
+ const char *core_name = "Unknown";
+ const u32 cpuid = gator_cpuid();
+ int i;
+
+ for (i = 0; gator_cpus[i].cpuid != 0; ++i) {
+ if (gator_cpus[i].cpuid == cpuid) {
+ core_name = gator_cpus[i].core_name;
+ break;
+ }
}
marshal_core_name(core_name);
@@ -517,8 +605,8 @@ static void gator_timer_online_dispatch(int cpu)
struct gator_interface *gi;
list_for_each_entry(gi, &gator_events, list)
- if (gi->online_dispatch)
- gi->online_dispatch(cpu);
+ if (gi->online_dispatch)
+ gi->online_dispatch(cpu);
}
int gator_timer_start(unsigned long sample_rate)
@@ -563,16 +651,16 @@ static int __cpuinit gator_hotcpu_notify(struct notifier_block *self, unsigned l
long cpu = (long)hcpu;
switch (action) {
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- smp_call_function_single(cpu, gator_timer_offline, NULL, 1);
- gator_timer_offline_dispatch(cpu);
- break;
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
- gator_timer_online_dispatch(cpu);
- smp_call_function_single(cpu, gator_timer_online, NULL, 1);
- break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ smp_call_function_single(cpu, gator_timer_offline, NULL, 1);
+ gator_timer_offline_dispatch(cpu);
+ break;
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ gator_timer_online_dispatch(cpu);
+ smp_call_function_single(cpu, gator_timer_online, NULL, 1);
+ break;
}
return NOTIFY_OK;
@@ -589,24 +677,24 @@ static int gator_pm_notify(struct notifier_block *nb, unsigned long event, void
int cpu;
switch (event) {
- case PM_HIBERNATION_PREPARE:
- case PM_SUSPEND_PREPARE:
- unregister_hotcpu_notifier(&gator_hotcpu_notifier);
- unregister_scheduler_tracepoints();
- on_each_cpu(gator_timer_offline, NULL, 1);
- for_each_online_cpu(cpu) {
- gator_timer_offline_dispatch(cpu);
- }
- break;
- case PM_POST_HIBERNATION:
- case PM_POST_SUSPEND:
- for_each_online_cpu(cpu) {
- gator_timer_online_dispatch(cpu);
- }
- on_each_cpu(gator_timer_online, NULL, 1);
- register_scheduler_tracepoints();
- register_hotcpu_notifier(&gator_hotcpu_notifier);
- break;
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ unregister_hotcpu_notifier(&gator_hotcpu_notifier);
+ unregister_scheduler_tracepoints();
+ on_each_cpu(gator_timer_offline, NULL, 1);
+ for_each_online_cpu(cpu) {
+ gator_timer_offline_dispatch(cpu);
+ }
+ break;
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ for_each_online_cpu(cpu) {
+ gator_timer_online_dispatch(cpu);
+ }
+ on_each_cpu(gator_timer_online, NULL, 1);
+ register_scheduler_tracepoints();
+ register_hotcpu_notifier(&gator_hotcpu_notifier);
+ break;
}
return NOTIFY_OK;
@@ -676,6 +764,15 @@ static int gator_init(void)
return 0;
}
+static void gator_exit(void)
+{
+ struct gator_interface *gi;
+
+ list_for_each_entry(gi, &gator_events, list)
+ if (gi->shutdown)
+ gi->shutdown();
+}
+
static int gator_start(void)
{
unsigned long cpu, i;
@@ -684,7 +781,7 @@ static int gator_start(void)
// Initialize the buffer with the frame type and core
for_each_present_cpu(cpu) {
for (i = 0; i < NUM_GATOR_BUFS; i++) {
- gator_buffer_header(cpu, i);
+ marshal_frame(cpu, i);
}
}
@@ -741,8 +838,8 @@ annotate_failure:
cookies_failure:
// stop all events
list_for_each_entry(gi, &gator_events, list)
- if (gi->stop)
- gi->stop();
+ if (gi->stop)
+ gi->stop();
events_failure:
return -1;
@@ -758,13 +855,13 @@ static void gator_stop(void)
gator_trace_gpu_stop();
// stop all interrupt callback reads before tearing down other interfaces
- gator_notifier_stop(); // should be called before gator_timer_stop to avoid re-enabling the hrtimer after it has been offlined
+ gator_notifier_stop(); // should be called before gator_timer_stop to avoid re-enabling the hrtimer after it has been offlined
gator_timer_stop();
// stop all events
list_for_each_entry(gi, &gator_events, list)
- if (gi->stop)
- gi->stop();
+ if (gi->stop)
+ gi->stop();
}
/******************************************************************************
@@ -941,8 +1038,8 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t co
}
static const struct file_operations enable_fops = {
- .read = enable_read,
- .write = enable_write,
+ .read = enable_read,
+ .write = enable_write,
};
static int userspace_buffer_open(struct inode *inode, struct file *file)
@@ -978,10 +1075,10 @@ static int userspace_buffer_release(struct inode *inode, struct file *file)
}
static ssize_t userspace_buffer_read(struct file *file, char __user *buf,
- size_t count, loff_t *offset)
+ size_t count, loff_t *offset)
{
int retval = -EINVAL;
- int commit = 0, length, length1, length2, read, byte, type_length;
+ int commit = 0, length1, length2, read;
char *buffer1;
char *buffer2 = NULL;
int cpu, buftype;
@@ -1026,13 +1123,6 @@ static ssize_t userspace_buffer_read(struct file *file, char __user *buf,
length2 = commit;
}
- // post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload
- type_length = gator_response_type ? 1 : 0;
- length = length1 + length2 - type_length - sizeof(int);
- for (byte = 0; byte < sizeof(int); byte++) {
- per_cpu(gator_buffer, cpu)[buftype][(read + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF;
- }
-
/* start, middle or end */
if (length1 > 0) {
if (copy_to_user(&buf[0], buffer1, length1)) {
@@ -1059,15 +1149,14 @@ out:
}
const struct file_operations gator_event_buffer_fops = {
- .open = userspace_buffer_open,
- .release = userspace_buffer_release,
- .read = userspace_buffer_read,
+ .open = userspace_buffer_open,
+ .release = userspace_buffer_release,
+ .read = userspace_buffer_read,
};
static ssize_t depth_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
- return gatorfs_ulong_to_user(gator_backtrace_depth, buf, count,
- offset);
+ return gatorfs_ulong_to_user(gator_backtrace_depth, buf, count, offset);
}
static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
@@ -1090,8 +1179,8 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou
}
static const struct file_operations depth_fops = {
- .read = depth_read,
- .write = depth_write
+ .read = depth_read,
+ .write = depth_write
};
void gator_op_create_files(struct super_block *sb, struct dentry *root)
@@ -1105,7 +1194,7 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root)
for_each_present_cpu(cpu) {
gator_cpu_cores++;
}
- userspace_buffer_size = BACKTRACE_BUFFER_SIZE;
+ userspace_buffer_size = BACKTRACE_BUFFER_SIZE;
gator_response_type = 1;
gatorfs_create_file(sb, root, "enable", &enable_fops);
@@ -1123,8 +1212,8 @@ void gator_op_create_files(struct super_block *sb, struct dentry *root)
// Linux Events
dir = gatorfs_mkdir(sb, root, "events");
list_for_each_entry(gi, &gator_events, list)
- if (gi->create_files)
- gi->create_files(sb, dir);
+ if (gi->create_files)
+ gi->create_files(sb, dir);
// Power interface
gator_trace_power_create_files(sb, dir);
@@ -1153,6 +1242,7 @@ static void __exit gator_module_exit(void)
{
del_timer_sync(&gator_buffer_wake_up_timer);
tracepoint_synchronize_unregister();
+ gator_exit();
gatorfs_unregister();
}
diff --git a/driver/gator_marshaling.c b/driver/gator_marshaling.c
index a84b280..b2efdd2 100644
--- a/driver/gator_marshaling.c
+++ b/driver/gator_marshaling.c
@@ -7,49 +7,52 @@
*
*/
-static void marshal_summary(long long timestamp, long long uptime) {
+static void marshal_summary(long long timestamp, long long uptime)
+{
int cpu = 0;
gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
buffer_check(cpu, SUMMARY_BUF);
}
-static bool marshal_cookie_header(char* text) {
+static bool marshal_cookie_header(const char *text)
+{
int cpu = smp_processor_id();
- return buffer_check_space(cpu, NAME_BUF, strlen(text) + 2*MAXSIZE_PACK32);
+ return buffer_check_space(cpu, NAME_BUF, strlen(text) + 3 * MAXSIZE_PACK32);
}
-static void marshal_cookie(int cookie, char* text) {
+static void marshal_cookie(int cookie, const char *text)
+{
int cpu = smp_processor_id();
- // TODO(dreric01) How long can the string be?
- if (buffer_check_space(cpu, NAME_BUF, 2*MAXSIZE_PACK32)) {
- gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
- gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
- gator_buffer_write_string(cpu, NAME_BUF, text);
- }
+ // buffer_check_space already called by marshal_cookie_header
+ gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_COOKIE);
+ gator_buffer_write_packed_int(cpu, NAME_BUF, cookie);
+ gator_buffer_write_string(cpu, NAME_BUF, text);
buffer_check(cpu, NAME_BUF);
}
-static void marshal_thread_name(int pid, char* name) {
+static void marshal_thread_name(int pid, char *name)
+{
unsigned long flags, cpu;
local_irq_save(flags);
cpu = smp_processor_id();
- if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 2*MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
+ if (buffer_check_space(cpu, NAME_BUF, TASK_COMM_LEN + 3 * MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
gator_buffer_write_packed_int(cpu, NAME_BUF, MESSAGE_THREAD_NAME);
gator_buffer_write_packed_int64(cpu, NAME_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
gator_buffer_write_string(cpu, NAME_BUF, name);
}
- local_irq_restore(flags);
buffer_check(cpu, NAME_BUF);
+ local_irq_restore(flags);
}
-static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel) {
+static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel)
+{
int cpu = smp_processor_id();
- if (buffer_check_space(cpu, BACKTRACE_BUF, gator_backtrace_depth*2*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
- gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
+ gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
return true;
@@ -61,13 +64,15 @@ static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inK
return false;
}
-static void marshal_backtrace(unsigned long address, int cookie) {
+static void marshal_backtrace(unsigned long address, int cookie)
+{
int cpu = smp_processor_id();
- gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
+ gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
}
-static void marshal_backtrace_footer(void) {
+static void marshal_backtrace_footer(void)
+{
int cpu = smp_processor_id();
gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, MESSAGE_END_BACKTRACE);
@@ -75,30 +80,31 @@ static void marshal_backtrace_footer(void) {
buffer_check(cpu, BACKTRACE_BUF);
}
-static bool marshal_event_header(void) {
+static bool marshal_event_header(void)
+{
unsigned long flags, cpu = smp_processor_id();
bool retval = false;
-
+
local_irq_save(flags);
if (buffer_check_space(cpu, BLOCK_COUNTER_BUF, MAXSIZE_PACK32 + MAXSIZE_PACK64)) {
- gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
+ gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, 0); // key of zero indicates a timestamp
gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, gator_get_time());
retval = true;
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, BLOCK_COUNTER_BUF);
+ local_irq_restore(flags);
return retval;
}
-static void marshal_event(int len, int* buffer) {
+static void marshal_event(int len, int *buffer)
+{
unsigned long i, flags, cpu = smp_processor_id();
if (len <= 0)
return;
-
+
// length must be even since all data is a (key, value) pair
if (len & 0x1) {
pr_err("gator: invalid counter data detected and discarded");
@@ -106,27 +112,26 @@ static void marshal_event(int len, int* buffer) {
}
// events must be written in key,value pairs
+ local_irq_save(flags);
for (i = 0; i < len; i += 2) {
- local_irq_save(flags);
- if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2*MAXSIZE_PACK32)) {
- local_irq_restore(flags);
+ if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK32)) {
break;
}
gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i]);
gator_buffer_write_packed_int(cpu, BLOCK_COUNTER_BUF, buffer[i + 1]);
- local_irq_restore(flags);
}
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, BLOCK_COUNTER_BUF);
+ local_irq_restore(flags);
}
-static void marshal_event64(int len, long long* buffer64) {
+static void marshal_event64(int len, long long *buffer64)
+{
unsigned long i, flags, cpu = smp_processor_id();
if (len <= 0)
return;
-
+
// length must be even since all data is a (key, value) pair
if (len & 0x1) {
pr_err("gator: invalid counter data detected and discarded");
@@ -134,48 +139,47 @@ static void marshal_event64(int len, long long* buffer64) {
}
// events must be written in key,value pairs
+ local_irq_save(flags);
for (i = 0; i < len; i += 2) {
- local_irq_save(flags);
- if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2*MAXSIZE_PACK64)) {
- local_irq_restore(flags);
+ if (!buffer_check_space(cpu, BLOCK_COUNTER_BUF, 2 * MAXSIZE_PACK64)) {
break;
}
gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i]);
gator_buffer_write_packed_int64(cpu, BLOCK_COUNTER_BUF, buffer64[i + 1]);
- local_irq_restore(flags);
}
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, BLOCK_COUNTER_BUF);
+ local_irq_restore(flags);
}
#if GATOR_CPU_FREQ_SUPPORT
-static void marshal_event_single(int core, int key, int value) {
+static void marshal_event_single(int core, int key, int value)
+{
unsigned long flags, cpu;
-
+
local_irq_save(flags);
cpu = smp_processor_id();
- if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, COUNTER_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int64(cpu, COUNTER_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, COUNTER_BUF, core);
gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, COUNTER_BUF);
+ local_irq_restore(flags);
}
#endif
-static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid) {
+static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_START);
gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
@@ -183,39 +187,39 @@ static void marshal_sched_gpu_start(int unit, int core, int tgid, int pid) {
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, GPU_TRACE_BUF);
+ local_irq_restore(flags);
}
-static void marshal_sched_gpu_stop(int unit, int core) {
+static void marshal_sched_gpu_stop(int unit, int core)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[GPU_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, GPU_TRACE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, MESSAGE_GPU_STOP);
gator_buffer_write_packed_int64(cpu, GPU_TRACE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, GPU_TRACE_BUF);
+ local_irq_restore(flags);
}
-static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state) {
+static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_SWITCH);
gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, tgid);
@@ -223,49 +227,88 @@ static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, SCHED_TRACE_BUF);
+ local_irq_restore(flags);
}
-static void marshal_sched_trace_exit(int tgid, int pid) {
+static void marshal_sched_trace_exit(int tgid, int pid)
+{
unsigned long cpu = smp_processor_id(), flags;
if (!per_cpu(gator_buffer, cpu)[SCHED_TRACE_BUF])
return;
local_irq_save(flags);
- if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, SCHED_TRACE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, MESSAGE_SCHED_EXIT);
gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, SCHED_TRACE_BUF);
+ local_irq_restore(flags);
}
#if GATOR_CPU_FREQ_SUPPORT
-static void marshal_idle(int core, int state) {
+static void marshal_idle(int core, int state)
+{
unsigned long flags, cpu;
-
+
local_irq_save(flags);
cpu = smp_processor_id();
- if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2*MAXSIZE_PACK32)) {
+ if (buffer_check_space(cpu, IDLE_BUF, MAXSIZE_PACK64 + 2 * MAXSIZE_PACK32)) {
gator_buffer_write_packed_int(cpu, IDLE_BUF, state);
gator_buffer_write_packed_int64(cpu, IDLE_BUF, gator_get_time());
gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
}
- local_irq_restore(flags);
-
// Check and commit; commit is set to occur once buffer is 3/4 full
buffer_check(cpu, IDLE_BUF);
+ local_irq_restore(flags);
}
#endif
-static void marshal_frame(int cpu, int buftype, int frame) {
+static void marshal_frame(int cpu, int buftype)
+{
+ int frame;
+
+ if (!per_cpu(gator_buffer, cpu)[buftype]) {
+ return;
+ }
+
+ switch (buftype) {
+ case SUMMARY_BUF:
+ frame = FRAME_SUMMARY;
+ break;
+ case BACKTRACE_BUF:
+ frame = FRAME_BACKTRACE;
+ break;
+ case NAME_BUF:
+ frame = FRAME_NAME;
+ break;
+ case COUNTER_BUF:
+ frame = FRAME_COUNTER;
+ break;
+ case BLOCK_COUNTER_BUF:
+ frame = FRAME_BLOCK_COUNTER;
+ break;
+ case ANNOTATE_BUF:
+ frame = FRAME_ANNOTATE;
+ break;
+ case SCHED_TRACE_BUF:
+ frame = FRAME_SCHED_TRACE;
+ break;
+ case GPU_TRACE_BUF:
+ frame = FRAME_GPU_TRACE;
+ break;
+ case IDLE_BUF:
+ frame = FRAME_IDLE;
+ break;
+ default:
+ frame = -1;
+ break;
+ }
+
// add response type
if (gator_response_type > 0) {
gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
@@ -280,7 +323,8 @@ static void marshal_frame(int cpu, int buftype, int frame) {
}
#if defined(__arm__) || defined(__aarch64__)
-static void marshal_core_name(const char* name) {
+static void marshal_core_name(const char *name)
+{
int cpu = smp_processor_id();
unsigned long flags;
local_irq_save(flags);
@@ -288,8 +332,7 @@ static void marshal_core_name(const char* name) {
gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
gator_buffer_write_string(cpu, NAME_BUF, name);
}
- local_irq_restore(flags);
-
buffer_check(cpu, NAME_BUF);
+ local_irq_restore(flags);
}
#endif
diff --git a/driver/gator_pack.c b/driver/gator_pack.c
index 5ad53db..119746b 100644
--- a/driver/gator_pack.c
+++ b/driver/gator_pack.c
@@ -21,23 +21,23 @@ static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x)
} else if ((x & 0xffffc000) == 0) {
int write2 = (write + 2) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) & 0x7f;
+ buffer[write1] = (x >> 7) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write2;
} else if ((x & 0xffe00000) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write3;
} else if ((x & 0xf0000000) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
int write4 = (write + 4) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write4;
} else {
int write2 = (write + 2) & mask;
@@ -45,10 +45,10 @@ static void gator_buffer_write_packed_int(int cpu, int buftype, unsigned int x)
int write4 = (write + 4) & mask;
int write5 = (write + 5) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) & 0x0f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) & 0x0f;
per_cpu(gator_buffer_write, cpu)[buftype] = write5;
}
}
@@ -67,23 +67,23 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
} else if ((x & 0xffffffffffffc000LL) == 0) {
int write2 = (write + 2) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) & 0x7f;
+ buffer[write1] = (x >> 7) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write2;
} else if ((x & 0xffffffffffe00000LL) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write3;
} else if ((x & 0xfffffffff0000000LL) == 0) {
int write2 = (write + 2) & mask;
int write3 = (write + 3) & mask;
int write4 = (write + 4) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write4;
} else if ((x & 0xfffffff800000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -91,10 +91,10 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write4 = (write + 4) & mask;
int write5 = (write + 5) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write5;
} else if ((x & 0xfffffc0000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -103,11 +103,11 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write5 = (write + 5) & mask;
int write6 = (write + 6) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write6;
} else if ((x & 0xfffe000000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -117,12 +117,12 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write6 = (write + 6) & mask;
int write7 = (write + 7) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write7;
} else if ((x & 0xff00000000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -133,13 +133,13 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write7 = (write + 7) & mask;
int write8 = (write + 8) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) | 0x80;
- buffer[write7] = (x>>49) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) | 0x80;
+ buffer[write7] = (x >> 49) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write8;
} else if ((x & 0x8000000000000000LL) == 0) {
int write2 = (write + 2) & mask;
@@ -151,14 +151,14 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write8 = (write + 8) & mask;
int write9 = (write + 9) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) | 0x80;
- buffer[write7] = (x>>49) | 0x80;
- buffer[write8] = (x>>56) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) | 0x80;
+ buffer[write7] = (x >> 49) | 0x80;
+ buffer[write8] = (x >> 56) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write9;
} else {
int write2 = (write + 2) & mask;
@@ -171,15 +171,15 @@ static void gator_buffer_write_packed_int64(int cpu, int buftype, unsigned long
int write9 = (write + 9) & mask;
int write10 = (write + 10) & mask;
buffer[write0] = x | 0x80;
- buffer[write1] = (x>>7) | 0x80;
- buffer[write2] = (x>>14) | 0x80;
- buffer[write3] = (x>>21) | 0x80;
- buffer[write4] = (x>>28) | 0x80;
- buffer[write5] = (x>>35) | 0x80;
- buffer[write6] = (x>>42) | 0x80;
- buffer[write7] = (x>>49) | 0x80;
- buffer[write8] = (x>>56) | 0x80;
- buffer[write9] = (x>>63) & 0x7f;
+ buffer[write1] = (x >> 7) | 0x80;
+ buffer[write2] = (x >> 14) | 0x80;
+ buffer[write3] = (x >> 21) | 0x80;
+ buffer[write4] = (x >> 28) | 0x80;
+ buffer[write5] = (x >> 35) | 0x80;
+ buffer[write6] = (x >> 42) | 0x80;
+ buffer[write7] = (x >> 49) | 0x80;
+ buffer[write8] = (x >> 56) | 0x80;
+ buffer[write9] = (x >> 63) & 0x7f;
per_cpu(gator_buffer_write, cpu)[buftype] = write10;
}
}
diff --git a/driver/gator_trace_gpu.c b/driver/gator_trace_gpu.c
index 0511d71..9fc488b 100644
--- a/driver/gator_trace_gpu.c
+++ b/driver/gator_trace_gpu.c
@@ -27,7 +27,6 @@
#define EVENT_TYPE_SUSPEND 3
#define EVENT_TYPE_RESUME 4
-
/* Note whether tracepoints have been registered */
static int mali_timeline_trace_registered;
static int mali_job_slots_trace_registered;
@@ -49,34 +48,33 @@ static int gpu_trace_registered;
*/
enum {
EVENT_CHANNEL_SOFTWARE = 0,
- EVENT_CHANNEL_VP0 = 1,
- EVENT_CHANNEL_FP0 = 5,
- EVENT_CHANNEL_FP1,
- EVENT_CHANNEL_FP2,
- EVENT_CHANNEL_FP3,
- EVENT_CHANNEL_FP4,
- EVENT_CHANNEL_FP5,
- EVENT_CHANNEL_FP6,
- EVENT_CHANNEL_FP7,
- EVENT_CHANNEL_GPU = 21
+ EVENT_CHANNEL_VP0 = 1,
+ EVENT_CHANNEL_FP0 = 5,
+ EVENT_CHANNEL_FP1,
+ EVENT_CHANNEL_FP2,
+ EVENT_CHANNEL_FP3,
+ EVENT_CHANNEL_FP4,
+ EVENT_CHANNEL_FP5,
+ EVENT_CHANNEL_FP6,
+ EVENT_CHANNEL_FP7,
+ EVENT_CHANNEL_GPU = 21
};
/**
* These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel
*/
enum {
- EVENT_REASON_SINGLE_GPU_NONE = 0,
- EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
+ EVENT_REASON_SINGLE_GPU_NONE = 0,
+ EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
};
-
GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned int d2, unsigned int d3, unsigned int d4))
{
unsigned int component, state;
// do as much work as possible before disabling interrupts
- component = (event_id >> 16) & 0xFF; // component is an 8-bit field
- state = (event_id >> 24) & 0xF; // state is a 4-bit field
+ component = (event_id >> 16) & 0xFF; // component is an 8-bit field
+ state = (event_id >> 24) & 0xF; // state is a 4-bit field
switch (state) {
case EVENT_TYPE_START:
@@ -101,7 +99,7 @@ GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned
if (component == EVENT_CHANNEL_GPU) {
unsigned int reason = (event_id & 0xffff);
- if(reason == EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE) {
+ if (reason == EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE) {
gator_events_mali_log_dvfs_event(d0, d1);
}
}
@@ -118,11 +116,10 @@ GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigne
{
unsigned int component, state, unit;
- component = (event_id >> 16) & 0xFF; // component is an 8-bit field
- state = (event_id >> 24) & 0xF; // state is a 4-bit field
+ component = (event_id >> 16) & 0xFF; // component is an 8-bit field
+ state = (event_id >> 24) & 0xF; // state is a 4-bit field
- switch (component)
- {
+ switch (component) {
case 0:
unit = GPU_UNIT_FP;
break;
@@ -136,9 +133,8 @@ GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigne
unit = GPU_UNIT_NONE;
}
- if (unit != GPU_UNIT_NONE)
- {
- switch(state) {
+ if (unit != GPU_UNIT_NONE) {
+ switch (state) {
case EVENT_TYPE_START:
marshal_sched_gpu_start(unit, 0, tgid, (pid != 0 ? pid : tgid));
break;
@@ -175,27 +171,27 @@ int gator_trace_gpu_start(void)
gpu_trace_registered = mali_timeline_trace_registered = mali_job_slots_trace_registered = 0;
#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
- if (!GATOR_REGISTER_TRACE(mali_timeline_event)) {
- mali_timeline_trace_registered = 1;
- }
+ if (!GATOR_REGISTER_TRACE(mali_timeline_event)) {
+ mali_timeline_trace_registered = 1;
+ }
#endif
#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx)
- if (!GATOR_REGISTER_TRACE(mali_job_slots_event)) {
- mali_job_slots_trace_registered = 1;
- }
+ if (!GATOR_REGISTER_TRACE(mali_job_slots_event)) {
+ mali_job_slots_trace_registered = 1;
+ }
#endif
- if (!mali_timeline_trace_registered) {
- if (GATOR_REGISTER_TRACE(gpu_activity_start)) {
- return 0;
- }
- if (GATOR_REGISTER_TRACE(gpu_activity_stop)) {
- GATOR_UNREGISTER_TRACE(gpu_activity_start);
- return 0;
- }
- gpu_trace_registered = 1;
- }
+ if (!mali_timeline_trace_registered) {
+ if (GATOR_REGISTER_TRACE(gpu_activity_start)) {
+ return 0;
+ }
+ if (GATOR_REGISTER_TRACE(gpu_activity_stop)) {
+ GATOR_UNREGISTER_TRACE(gpu_activity_start);
+ return 0;
+ }
+ gpu_trace_registered = 1;
+ }
return 0;
}
diff --git a/driver/gator_trace_gpu.h b/driver/gator_trace_gpu.h
index 894289b..efb47c6 100644
--- a/driver/gator_trace_gpu.h
+++ b/driver/gator_trace_gpu.h
@@ -28,50 +28,50 @@
*/
TRACE_EVENT(gpu_activity_start,
- TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *p),
+ TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *p),
- TP_ARGS(gpu_unit, gpu_core, p),
+ TP_ARGS(gpu_unit, gpu_core, p),
- TP_STRUCT__entry(
- __field( int, gpu_unit )
- __field( int, gpu_core )
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- ),
+ TP_STRUCT__entry(
+ __field(int, gpu_unit)
+ __field(int, gpu_core)
+ __array(char, comm, TASK_COMM_LEN)
+ __field(pid_t, pid)
+ ),
- TP_fast_assign(
- __entry->gpu_unit = gpu_unit;
- __entry->gpu_core = gpu_core;
- memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
- __entry->pid = p->pid;
- ),
+ TP_fast_assign(
+ __entry->gpu_unit = gpu_unit;
+ __entry->gpu_core = gpu_core;
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ ),
- TP_printk("unit=%d core=%d comm=%s pid=%d",
- __entry->gpu_unit, __entry->gpu_core, __entry->comm, __entry->pid)
-);
+ TP_printk("unit=%d core=%d comm=%s pid=%d",
+ __entry->gpu_unit, __entry->gpu_core, __entry->comm,
+ __entry->pid)
+ );
/*
* Tracepoint for calling GPU unit stop activity on core
*/
TRACE_EVENT(gpu_activity_stop,
- TP_PROTO(int gpu_unit, int gpu_core),
+ TP_PROTO(int gpu_unit, int gpu_core),
- TP_ARGS(gpu_unit, gpu_core),
+ TP_ARGS(gpu_unit, gpu_core),
- TP_STRUCT__entry(
- __field( int, gpu_unit )
- __field( int, gpu_core )
- ),
+ TP_STRUCT__entry(
+ __field(int, gpu_unit)
+ __field(int, gpu_core)
+ ),
- TP_fast_assign(
- __entry->gpu_unit = gpu_unit;
- __entry->gpu_core = gpu_core;
- ),
+ TP_fast_assign(
+ __entry->gpu_unit = gpu_unit;
+ __entry->gpu_core = gpu_core;
+ ),
- TP_printk("unit=%d core=%d",
- __entry->gpu_unit, __entry->gpu_core)
-);
+ TP_printk("unit=%d core=%d", __entry->gpu_unit, __entry->gpu_core)
+ );
#endif /* _TRACE_GPU_H */
diff --git a/driver/gator_trace_power.c b/driver/gator_trace_power.c
index b1687e1..79fa13c 100644
--- a/driver/gator_trace_power.c
+++ b/driver/gator_trace_power.c
@@ -9,8 +9,19 @@
#include <linux/cpufreq.h>
#include <trace/events/power.h>
+
+#if defined(__arm__)
+
#include <asm/mach-types.h>
+#define implements_wfi() (!machine_is_omap3_beagle())
+
+#else
+
+#define implements_wfi() false
+
+#endif
+
// cpu_frequency and cpu_idle trace points were introduced in Linux kernel v2.6.38
// the now deprecated power_frequency trace point was available prior to 2.6.38, but only for x86
#if GATOR_CPU_FREQ_SUPPORT
@@ -61,9 +72,9 @@ GATOR_DEFINE_PROBE(cpu_idle, TP_PROTO(unsigned int state, unsigned int cpu))
return;
}
- if (!machine_is_omap3_beagle()) {
+ if (implements_wfi()) {
if (state == PWR_EVENT_EXIT) {
- // transition from wfi to non-wfi
+ // transition from wfi to non-wfi
marshal_idle(cpu, WFI_EXIT);
} else {
// transition from non-wfi to wfi
@@ -149,10 +160,29 @@ void gator_trace_power_init(void)
}
}
#else
-static int gator_trace_power_create_files(struct super_block *sb, struct dentry *root) {return 0;}
-static void gator_trace_power_online(void) {}
-static void gator_trace_power_offline(void) {}
-static int gator_trace_power_start(void) {return 0;}
-static void gator_trace_power_stop(void) {}
-void gator_trace_power_init(void) {}
+static int gator_trace_power_create_files(struct super_block *sb, struct dentry *root)
+{
+ return 0;
+}
+
+static void gator_trace_power_online(void)
+{
+}
+
+static void gator_trace_power_offline(void)
+{
+}
+
+static int gator_trace_power_start(void)
+{
+ return 0;
+}
+
+static void gator_trace_power_stop(void)
+{
+}
+
+void gator_trace_power_init(void)
+{
+}
#endif
diff --git a/driver/gator_trace_sched.c b/driver/gator_trace_sched.c
index 9ddb822..d0336f9 100644
--- a/driver/gator_trace_sched.c
+++ b/driver/gator_trace_sched.c
@@ -13,7 +13,7 @@
#define SCHED_SWITCH 1
#define SCHED_PROCESS_EXIT 2
-#define TASK_MAP_ENTRIES 1024 /* must be power of 2 */
+#define TASK_MAP_ENTRIES 1024 /* must be power of 2 */
#define TASK_MAX_COLLISIONS 2
static DEFINE_PER_CPU(uint64_t *, taskname_keys);
@@ -26,14 +26,14 @@ enum {
STATE_WAIT_ON_MUTEX,
};
-void emit_pid_name(struct task_struct* task)
+void emit_pid_name(struct task_struct *task)
{
bool found = false;
char taskcomm[TASK_COMM_LEN + 3];
unsigned long x, cpu = smp_processor_id();
uint64_t *keys = &(per_cpu(taskname_keys, cpu)[(task->pid & 0xFF) * TASK_MAX_COLLISIONS]);
uint64_t value;
-
+
value = gator_chksum_crc32(task->comm);
value = (value << 32) | (uint32_t)task->pid;
@@ -64,7 +64,6 @@ void emit_pid_name(struct task_struct* task)
}
}
-
static void collect_counters(void)
{
int *buffer, len;
@@ -84,7 +83,7 @@ static void collect_counters(void)
}
}
-static void probe_sched_write(int type, struct task_struct* task, struct task_struct* old_task)
+static void probe_sched_write(int type, struct task_struct *task, struct task_struct *old_task)
{
int cookie = 0, state = 0;
int cpu = smp_processor_id();
@@ -141,7 +140,14 @@ GATOR_DEFINE_PROBE(sched_process_exit, TP_PROTO(struct task_struct *p))
probe_sched_write(SCHED_PROCESS_EXIT, p, 0);
}
-static int register_scheduler_tracepoints(void) {
+static void do_nothing(void *info)
+{
+ // Intentionally do nothing
+ (void)info;
+}
+
+static int register_scheduler_tracepoints(void)
+{
// register tracepoints
if (GATOR_REGISTER_TRACE(sched_switch))
goto fail_sched_switch;
@@ -149,6 +155,10 @@ static int register_scheduler_tracepoints(void) {
goto fail_sched_process_exit;
pr_debug("gator: registered tracepoints\n");
+ // Now that the scheduler tracepoint is registered, force a context switch
+ // on all cpus to capture what is currently running.
+ on_each_cpu(do_nothing, NULL, 0);
+
return 0;
// unregister tracepoints on error
@@ -166,7 +176,7 @@ int gator_trace_sched_start(void)
for_each_present_cpu(cpu) {
size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t);
- per_cpu(taskname_keys, cpu) = (uint64_t*)kmalloc(size, GFP_KERNEL);
+ per_cpu(taskname_keys, cpu) = (uint64_t *)kmalloc(size, GFP_KERNEL);
if (!per_cpu(taskname_keys, cpu))
return -1;
memset(per_cpu(taskname_keys, cpu), 0, size);